Quantcast
Channel: VFPX
Viewing all articles
Browse latest Browse all 3798

Updated Wiki: FoxBin2Prg Internals and Configuration

$
0
0
Tha purpose of FoxBin2Prg is to facilitate the Diff and Merge of Visual FoxPro 9 binaries, which are not natively supported by any source control tool. Traditionally FoxPro comes with a tool named SccText.prg who can make a text representation exporting the source code contained in FoxPro tables with a DBF structure. An enhanced version is available on VFPx named SccTextX, but like his ancestor, have some design limitations, as:
  • It doesn't generate PRG like code
  • It doesn't permit modification of the txa (text) files generated
  • Scctext's txa (text) files generated can't be used for merge with SCM tools
  • Timestamps and ZOrder fields generate a lot of unnecesary differences all over the text file

FoxBin2Prg is designed to bring a solution for all of this, and a few more things, which makes tx2 (text) files with PRG-style and enhances compatibility with SCCAPI (SourceSafe) and other SCM tools, like PlasticSCM, Git, Subversion, and the like.

Special remark on Merge operation is made, because it is the most difficult and more used operation when working with SCM tools, and this require that generated text files can be manipulated manually or automatically.


This are the FoxBin2Prg.cfg configuration file settings and there meaning



FoxBin2Prg.cfg keywords and DefaultsDescription
extension: xx2 FoxBin2Prg extensions ends in '2' (pj2, vc2, sc2, etc), but you can change that. For example you can change pj2 to pja using this: extension: pj2=pja for making it SourceSafe compatible
DontShowProgress: 0 By default, a progress bar is shown when processing multiple-files
DontShowErrors: 0 By default, show message errors in a modal messagebox. Specify "1" if don't want
NoTimestamps: 1 By default, timestamp fields are cleared, because a lot of differencies are generated on binaries and tx2 files with Timestamps activated. This timestamp field is part of the vcx, scx and other Foxpro binary source code files
Debug: 0 By default, don't generate individual <file>.Log with process hints. Activate with "1" to find prossible error causes
ExtraBackupLevels: 1 By default, 1 .BAK file is created. With this setting you can make more .N.BAK, or none at all with 0
ClearUniqueID: 0 0=Keep UniqueID, 1=Clear Unique ID. Very useful for Diff and Merge, because a lot of differencies are generated on binaries and tx2 files with UniqueID activated
OptimizeByFilestamp: 1 0=Don't optimize (always regenerate), 1=Optimize (regenerate only when destination filestamp es older)
XXX_Conversion_Support: N Where N is: 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge)
PJX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
VCX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
SCX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
FRX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
LBX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
MNX_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
DBC_Conversion_Support: 2 Default value is 2 - Bidirectional (tx2 and bin) support activated
DBF_Conversion_Support: 1 Default value is 1 - just tx2 support activated. The support for regenerating DBFs structures are disabled by default to not overrite data accidentally. When activating bidirectional supoort (2), keep in mind that Data is not restored, just the structure and indexes!. Use with care.



FoxBin2Prg Internals


ZOrder

In TX2 files and starting from v1.19.12, the ZOrder, that determines the order on which objects are instantiated and which one is on top, is maintained in a more intuitive and optimal way compared to traditional stored numerical values.
TX2 files keep lists of objects and there metadata in a special OBJECTDATA tag, in which the order of the list is the ZOrder of the object, like this example:

DEFINE CLASS cnt_controls AS container 		&& "cnt_controls" class description
 	*< CLASSDATA: Baseclass="container" Timestamp="" Scale="Pixels" Uniqueid="" />

	*-- OBJECTDATA items order determines ZOrder 
	*< OBJECTDATA: ObjPath="Check2" UniqueID="" Timestamp="" />
	*< OBJECTDATA: ObjPath="Check4" UniqueID="" Timestamp="" />
	*< OBJECTDATA: ObjPath="Label_h" UniqueID="" Timestamp="" />
	*< OBJECTDATA: ObjPath="Textbox_h" UniqueID="" Timestamp="" />
	*< OBJECTDATA: ObjPath="Check1" UniqueID="" Timestamp="" />
	*< OBJECTDATA: ObjPath="Check3" UniqueID="" Timestamp="" />


This way, you can rearrange the items to alter there ZOrder, and this does auto-renumbering when regenerating binaries.

PAM Section

Ths section is generated for classes and forms, it is delimited with the <DefinedPropArrayMethod> tag, and have the definition of Properties, Arrays and Methods, with there comments, like this example:

DEFINE CLASS c1 AS custom OLEPUBLIC		&& Description of "c1" class
	*<DefinedPropArrayMethod>
		*m: emptymethod_with_comments	&& This method have no code, just comments. Let's see what happens!
		*m: mymethod			&& My Method
		*p: prop1			&& My prop 1
		*p: special_prop_with_cr
		*p: special_prop_with_crlf	&& Should have CR+LF
		*a: array_1_d[1,0]		&& 1 dimension array (1)
		*a: array_2_d[1,2]		&& 2 dimension array (1,2)
		*p: _memberdata			&& XML Metadata for customizable properties
	*</DefinedPropArrayMethod>


Starting from v1.19.21 arrays don't need to be preceded with "^" symbol, and methods don't need to be preceded with "*" symbol, whick makes this section more easy to maintain.


Property Ordering

On TX2 files is easy, ordering for methods and properties is done in alphabetical way, like scctext does with methods. This makes comparisons easier and with less differences.

On binaries, property ordering is a very different thing. No documentation is available about this, so the only guideline is trying to make it as FoxPro does, but this is not always possible because there are two extreme cases, and variants between the them:

1) The best and easy one, is when defining a class (or control) with his properties: In this case, each class have a phisical record on the scx/vcx table, and all the properties of it are keep toghether, so this ordering can be easily duplicated (look at "TESTS\DATOS_READONLY\f_form_aa.scx file" on foxbin2prg project and open it as a table to see the class per record)

2) The worst and most difficult case, is when there is a container with controls subclassed, and properties are changed on the instance: In this case FoxPro makes a big and unique list of properties of all objects in just one phisical record, so there is no way to know which property corresponds to which class. For this case, I've made a unique list composed of all properties of all classes, ordered according to most common orderings (look at "TESTS\DATOS_READONLY\f_form_aa2.scx file" on foxbin2prg project and open it as a table to see all the properties of all the classes of the same earlier example, in just one record)

For theese two cases, and starting from v1.19.22, I've created several props_* files with ordering by class for the 1st case, and a list with all in it (props_all.txt) for the second case, so in case of any problems, rearranging some props will be an easy thing.

Warning: Theese props_* files are necessary in the foxbin2prg install directory. It's recommended to use the EXE version that have all files included and is faster.

Several Unit Tests (in TESTS directory) are made to make the best effort to cover the most typical use cases. There is also an Excel spreedsheet with the compilation of properties of each class with the order that FoxPro uses internally, and a tab with the all-in-one order for the worst case.


Timestamps and UniqueIds

Timestamp field are used in VFP to track changes with 3rd party tools and UniqueId is used to identify classes inside binaries, but, AFAIK, they are not used by VFP itself. There are 2 switches, enabled by default, that are used to clear this values (ClearUniqueId and NoTimestamps), so no differences are shown for this values constantly changing.
Starting from v1.19.23 this values are just cleared on tx2 files, and regenerated on the binaries, as well the sccdata field, because this way there are no differences when opening/closing certain files, as a PJX, which by default fill some of this fields even if no modifications are made, which causes that SCM tools detect those changes. Having them prefilled, then no changes are detected.


DBF/DB2 Convertion Hooks

From version v1.19.19 there is a new property "run_AfterCreateTable" and from version v1.19.24 "run_AfterCreate_DB2". The purpose of both properties is to allow the execution of an external program each time a DBF is converted to DB2 or a DB2 is converted to DBF.
The main purpose of FoxBin2Prg is to be used for Diff and Merge with a SCM tool, so in this scenario the data is not needed, but there are use cases where exporting, importing or manipulating data is needed while making the conversions, and for those cases are this properties.

This is a sample program:

*-- DEMO HOOK FOR PROCESSING DBFs AND DB2
LOCAL oFB AS 'c_foxbin2prg' OF 'c:\desa\foxbin2prg\foxbin2prg.prg'
oFB = NEWOBJECT( 'c_foxbin2prg', 'c:\desa\foxbin2prg\foxbin2prg.prg' )
oFB.DBF_Conversion_Support	= 2
oFB.run_AfterCreateTable 	= 'p_AfterCreateTable'
oFB.run_AfterCreate_DB2 	= 'p_AfterCreate_DB2'
oFB.Ejecutar( 'C:\DESA\foxbin2prg\TESTS\DATOS_TEST\fb2p_dbc.dc2' )
oFB.Ejecutar( 'C:\DESA\foxbin2prg\TESTS\DATOS_TEST\fb2p_dbf.db2' )
oFB.Ejecutar( 'C:\DESA\foxbin2prg\TESTS\DATOS_TEST\fb2p_dbf.dbf' )
oFB	= NULL
RETURN


PROCEDURE p_AfterCreateTable
	LPARAMETERS lnDataSessionID, tc_OutputFile, toTable
	MESSAGEBOX( 'Actual Datasession: ' + TRANSFORM(SET("Datasession")) + CHR(13) ;
		+ 'lnDataSessionID: ' + TRANSFORM(lnDataSessionID) )
	*-- You can fill the table <tc_OutputFile> here.
	INSERT INTO fb2p_dbf (nombre,edad,depto) VALUES ('Fer', 45, 'dpto')
ENDPROC


PROCEDURE p_AfterCreate_DB2
	LPARAMETERS lnDataSessionID, tc_OutputFile, toTable
	MESSAGEBOX( 'Actual Datasession: ' + TRANSFORM(SET("Datasession")) + CHR(13) ;
		+ 'lnDataSessionID: ' + TRANSFORM(lnDataSessionID) )
	*-- You can export the data here.
	STRTOFILE( nombre + STR(edad,3) + depto, 'c:\temp\data.txt', 1)
ENDPROC




Viewing all articles
Browse latest Browse all 3798

Trending Articles