*--------------------------------------------------------------------------------------------------- * Módulo.........: FOXBIN2PRG.PRG - PARA VISUAL FOXPRO 9.0 * Autor..........: Fernando D. Bozzo (mailto:fdbozzo@gmail.com) * Fecha creación.: 04/11/2013 * * LICENCIA: * Esta obra está sujeta a la licencia Reconocimiento-CompartirIgual 4.0 Internacional de Creative Commons. * Para ver una copia de esta licencia, visite http://creativecommons.org/licenses/by-sa/4.0/deed.es_ES. * * LICENCE: * This work is licensed under the Creative Commons Attribution 4.0 International License. * To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/. * *--------------------------------------------------------------------------------------------------- * DESCRIPCIÓN....: CONVIERTE EL ARCHIVO VCX/SCX/PJX INDICADO A UN "PRG HÍBRIDO" PARA POSTERIOR RECONVERSIÓN. * * EL PRG HÍBRIDO ES UN PRG CON ALGUNAS SECCIONES BINARIAS (OLE DATA, ETC) * * EL OBJETIVO ES PODER USARLO COMO REEMPLAZO DEL SCCTEXT.PRG, PODER HACER MERGE * DEL CÓDIGO DIRECTAMENTE SOBRE ESTE NUEVO PRG Y GUARDARLO EN UNA HERRAMIENTA DE SCM * COMO CVS O SIMILAR SIN NECESIDAD DE GUARDAR LOS BINARIOS ORIGINALES. * * EXTENSIONES GENERADAS: VC2, SC2, PJ2 (...o VCA, SCA, PJA con archivo conf.) * * CONFIGURACIÓN: SI SE CREA UN ARCHIVO FOXBIN2PRG.CFG, SE PUEDEN CAMBIAR LAS EXTENSIONES * PARA PODER USARLO CON SOURCESAFE PONIENDO LAS EQUIVALENCIAS ASÍ: * * extension: VC2=VCA * extension: SC2=SCA * extension: PJ2=PJA * * USO/USE: * DO FOXBIN2PRG.PRG WITH "\FILE.VCX" && Genera "\FILE.VC2" (BIN TO PRG CONVERSION) * DO FOXBIN2PRG.PRG WITH "\FILE.VC2" && Genera "\FILE.VCX" (PRG TO BIN CONVERSION) * * DO FOXBIN2PRG.PRG WITH "\FILE.SCX" && Genera "\FILE.SC2" (BIN TO PRG CONVERSION) * DO FOXBIN2PRG.PRG WITH "\FILE.SC2" && Genera "\FILE.SCX" (PRG TO BIN CONVERSION) * * DO FOXBIN2PRG.PRG WITH "\FILE.PJX" && Genera "\FILE.PJ2" (BIN TO PRG CONVERSION) * DO FOXBIN2PRG.PRG WITH "\FILE.PJ2" && Genera "\FILE.PJX" (PRG TO BIN CONVERSION) * *--------------------------------------------------------------------------------------------------- * * 04/11/2013 FDBOZZO v1.0 Creación inicial de las clases y soporte de los archivos VCX/SCX/PJX * 22/11/2013 FDBOZZO v1.1 Corrección de bugs * 23/11/2013 FDBOZZO v1.2 Corrección de bugs, limpieza de código y refactorización * 24/11/2013 FDBOZZO v1.3 Corrección de bugs, limpieza de código y refactorización * 27/11/2013 FDBOZZO v1.4 Agregado soporte comodines *.VCX, configuración de extensiones (vca), parámetro p/log * 27/11/2013 FDBOZZO v1.5 Arreglo bug que no generaba form completo * 01/12/2013 FDBOZZO v1.6 Refactorización completa generación BIN y PRG, cambio de algoritmos, arreglo de bugs, Unit Testing con FoxUnit * 02/12/2013 FDBOZZO v1.7 Arreglo bug "Name", barra de progreso, agregado mensaje de ayuda si se llama sin parámetros, verificación y logueo de archivos READONLY con debug activa * 03/12/2013 FDBOZZO v1.8 Arreglo bug "Name" (otra vez), sort encapsulado y reutilizado para versiones TEXTO y BIN por seguridad * 06/12/2013 FDBOZZO v1.9 Arreglo bug pérdida de propiedades causado por una mejora anterior * 06/12/2013 FDBOZZO v1.10 Arreglo del bug de mezcla de métodos de una clase con la siguiente * 07/12/2013 FDBOZZO v1.11 Arreglo del bug de _amembers detectado por Edgar K.con la clase BlowFish.vcx (http://www.tortugaproductiva.galeon.com/docs/blowfish/index.html) * 07/12/2013 FDBOZZO v1.12 Agregado soporte preliminar de conversión de reportes y etiquetas (FRX/LBX) * 08/12/2013 FDBOZZO v1.13 Arreglo bug "Error 1924, TOREG is not an object" * 15/12/2013 FDBOZZO v1.14 Arreglo de bug AutoCenter y registro COMMENT en regeneración de forms * 08/12/2013 FDBOZZO v1.15 Agregado soporte preliminar de conversión de tablas, índices y bases de datos (DBF,CDX,DBC) * 18/12/2013 FDBOZZO v1.16 Agregado soporte para menús (MNX) * 03/01/2014 FDBOZZO v1.17 Agregado Unit Testing de menús y arreglo de las incidencias del menu * 05/01/2013 FDBOZZO v1.18 Agregado soporte para generar estructuras TEXTO de DBFs anteriores a VFP 9, pero los binarios a VFP 9 // Arreglado bug de datos faltantes en campos de vistas // Arreglado bug mnx * * *--------------------------------------------------------------------------------------------------- * * 23/11/2013 Luis Martínez REPORTE BUG scx v1.4: En algunos forms solo se generaba el dataenvironment (arreglado en v.1.5) * 27/11/2013 Fidel Charny REPORTE BUG vcx v1.5: Error en el guardado de ciertas propiedades de array (arreglado en v.1.6) * 02/12/2013 Fidel Charny REPORTE BUG scx v1.6: Se pierden algunas propiedades y no muestra picture si "Name" no es la última (arreglado en v.1.7) * 03/12/2013 Fidel Charny REPORTE BUG scx v1.7: Se siguen perdiendo algunas propiedades por implementación defectuosa del arreglo anterior (arreglado en v.1.8) * 03/12/2013 Fidel Charny REPORTE BUG scx v1.8: Se siguen perdiendo algunas propiedades por implementación defectuosa de una mejora anterior (arreglado en v.1.9) * 06/12/2013 Fidel Charny REPORTE BUG scx v1.9: Cuando hay métodos que tienen el mismo nombre, aparecen mezclados en objetos a los que no corresponden (arreglado en v.1.10) * 07/12/2013 Edgar Kummers REPORTE BUG vcx v1.10: Cuando se parsea una clase con un _memberdata largo, se parsea mal y se corrompe el valor (arreglado en v.1.11) * 08/12/2013 Fidel Charny REPORTE BUG frx v1.12: Cuando se convierten algunos reportes da "Error 1924, TOREG is not an object" (arreglado en v.1.13) * 14/12/2013 Arturo Ramos REPORTE BUG scx v1.13: La regeneración de los forms (SCX) no respeta la propiedad AutoCenter, estando pero no funcionando. (arreglado en v.1.14) * 14/12/2013 Fidel Charny REPORTE BUG scx v1.13: La regeneración de los forms (SCX) no regenera el último registro COMMENT (arreglado en v.1.14) * 01/01/2014 Fidel Charny REPORTE BUG mnx v1.16: El menú no siempre respeta la posición original LOCATION y a veces se genera mal el MNX (se arregla en v1.17) * 05/01/2014 Fidel Charny REPORTE BUG mnx v1.17: Se genera cláusula "DO" o llamada Command cuando no Procedure ni Command que llamar // Diferencia de Case en NAME (se arregla en v1.18) * * *--------------------------------------------------------------------------------------------------- * TRAMIENTOS ESPECIALES DE ASIGNACIONES DE PROPIEDADES: * PROPIEDAD ARREGLO Y EJEMPLO *------------------------- -------------------------------------------------------------------------------------- * _memberdata Se separan las definiciones en lineas para evitar una sola muy larga * *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tc_InputFile (v! IN ) Nombre completo (fullpath) del archivo a convertir * tcType_na ( ) Por ahora se mantiene por compatibilidad con SCCTEXT.PRG * tcTextName_na ( ) Por ahora se mantiene por compatibilidad con SCCTEXT.PRG * tlGenText_na ( ) Por ahora se mantiene por compatibilidad con SCCTEXT.PRG * tcDontShowErrors (v? IN ) '1' para NO mostrar errores con MESSAGEBOX * tcDebug (v? IN ) '1' para depurar en el sitio donde ocurre el error (solo modo desarrollo) * tcDontShowProgress (v? IN ) '1' para NO mostrar la ventana de progreso * tcOriginalFileName (v? IN ) Sirve para los casos en los que inputFile es un nombre temporal y se quiere generar * el nombre correcto dentro de la versión texto (por ej: en los PJ2 y las cabeceras) * * Ej: DO FOXBIN2PRG.PRG WITH "C:\DESA\INTEGRACION\LIBRERIA.VCX" *--------------------------------------------------------------------------------------------------- LPARAMETERS tc_InputFile, tcType_na, tcTextName_na, tlGenText_na, tcDontShowErrors, tcDebug, tcDontShowProgress, tcOriginalFileName *-- Internacionalización / Internationalization *-- Fin / End *-- NO modificar! / Do NOT change! #DEFINE C_CMT_I '*--' #DEFINE C_CMT_F '--*' #DEFINE C_METADATA_I '*< CLASSDATA:' #DEFINE C_METADATA_F '/>' #DEFINE C_LEN_METADATA_I LEN(C_METADATA_I) #DEFINE C_OLE_I '*< OLE:' #DEFINE C_OLE_F '/>' #DEFINE C_LEN_OLE_I LEN(C_OLE_I) #DEFINE C_DEFINED_PAM_I '*' #DEFINE C_DEFINED_PAM_F '*' #DEFINE C_LEN_DEFINED_PAM_I LEN(C_DEFINED_PAM_I) #DEFINE C_LEN_DEFINED_PAM_F LEN(C_DEFINED_PAM_F) #DEFINE C_END_OBJECT_I '*< END OBJECT:' #DEFINE C_END_OBJECT_F '/>' #DEFINE C_LEN_END_OBJECT_I LEN(C_END_OBJECT_I) #DEFINE C_FB2PRG_META_I '*< FOXBIN2PRG:' #DEFINE C_FB2PRG_META_F '/>' #DEFINE C_DEFINE_CLASS 'DEFINE CLASS' #DEFINE C_ENDDEFINE 'ENDDEFINE' #DEFINE C_TEXT 'TEXT' #DEFINE C_ENDTEXT 'ENDTEXT' #DEFINE C_PROCEDURE 'PROCEDURE' #DEFINE C_ENDPROC 'ENDPROC' #DEFINE C_WITH 'WITH' #DEFINE C_ENDWITH 'ENDWITH' #DEFINE C_SRV_HEAD_I '*' #DEFINE C_SRV_HEAD_F '*' #DEFINE C_SRV_DATA_I '*' #DEFINE C_SRV_DATA_F '*' #DEFINE C_DEVINFO_I '*' #DEFINE C_DEVINFO_F '*' #DEFINE C_BUILDPROJ_I '*' #DEFINE C_BUILDPROJ_F '*' #DEFINE C_PROJPROPS_I '*' #DEFINE C_PROJPROPS_F '*' #DEFINE C_FILE_META_I '*< FileMetadata:' #DEFINE C_FILE_META_F '/>' #DEFINE C_FILE_CMTS_I '*' #DEFINE C_FILE_CMTS_F '*' #DEFINE C_FILE_EXCL_I '*' #DEFINE C_FILE_EXCL_F '*' #DEFINE C_FILE_TXT_I '*' #DEFINE C_FILE_TXT_F '*' #DEFINE C_FB2P_VALUE_I '' #DEFINE C_FB2P_VALUE_F '' #DEFINE C_LEN_FB2P_VALUE_I LEN(C_FB2P_VALUE_I) #DEFINE C_LEN_FB2P_VALUE_F LEN(C_FB2P_VALUE_F) #DEFINE C_VFPDATA_I '' #DEFINE C_VFPDATA_F '' #DEFINE C_MEMBERDATA_I C_VFPDATA_I #DEFINE C_MEMBERDATA_F C_VFPDATA_F #DEFINE C_LEN_MEMBERDATA_I LEN(C_MEMBERDATA_I) #DEFINE C_LEN_MEMBERDATA_F LEN(C_MEMBERDATA_F) #DEFINE C_DATA_I '' #DEFINE C_TAG_REPORTE 'Reportes' #DEFINE C_TAG_REPORTE_I '<' + C_TAG_REPORTE + '>' #DEFINE C_TAG_REPORTE_F '' #DEFINE C_DBF_HEAD_I '' #DEFINE C_LEN_DBF_HEAD_I LEN(C_DBF_HEAD_I) #DEFINE C_LEN_DBF_HEAD_F LEN(C_DBF_HEAD_F) #DEFINE C_CDX_I '' #DEFINE C_CDX_F '' #DEFINE C_LEN_CDX_I LEN(C_CDX_I) #DEFINE C_LEN_CDX_F LEN(C_CDX_F) #DEFINE C_LEN_INDEX_I LEN(C_INDEX_I) #DEFINE C_LEN_INDEX_F LEN(C_INDEX_F) #DEFINE C_DATABASE_I '' #DEFINE C_DATABASE_F '' #DEFINE C_STORED_PROC_I '' #DEFINE C_TABLE_I '' #DEFINE C_TABLE_F '
' #DEFINE C_TABLES_I '' #DEFINE C_TABLES_F '' #DEFINE C_VIEW_I '' #DEFINE C_VIEW_F '' #DEFINE C_VIEWS_I '' #DEFINE C_VIEWS_F '' #DEFINE C_FIELD_I '' #DEFINE C_FIELD_F '' #DEFINE C_FIELDS_I '' #DEFINE C_FIELDS_F '' #DEFINE C_CONNECTION_I '' #DEFINE C_CONNECTION_F '' #DEFINE C_CONNECTIONS_I '' #DEFINE C_CONNECTIONS_F '' #DEFINE C_RELATION_I '' #DEFINE C_RELATION_F '' #DEFINE C_RELATIONS_I '' #DEFINE C_RELATIONS_F '' #DEFINE C_INDEX_I '' #DEFINE C_INDEX_F '' #DEFINE C_INDEXES_I '' #DEFINE C_INDEXES_F '' #DEFINE C_PROC_CODE_I '*' #DEFINE C_PROC_CODE_F '*' #DEFINE C_SETUPCODE_I '*' #DEFINE C_SETUPCODE_F '*' #DEFINE C_CLEANUPCODE_I '*' #DEFINE C_CLEANUPCODE_F '*' #DEFINE C_MENUCODE_I '*' #DEFINE C_MENUCODE_F '*' #DEFINE C_MENUTYPE_I '*' #DEFINE C_MENUTYPE_F '' #DEFINE C_MENULOCATION_I '*' #DEFINE C_MENULOCATION_F '' *-- #DEFINE C_TAB CHR(9) #DEFINE C_CR CHR(13) #DEFINE C_LF CHR(10) #DEFINE CR_LF C_CR + C_LF #DEFINE C_MPROPHEADER REPLICATE( CHR(1), 517 ) *-- Fin / End *-- From FOXPRO.H *-- File Object Type Property #DEFINE FILETYPE_DATABASE "d" && Database (.DBC) #DEFINE FILETYPE_FREETABLE "D" && Free table (.DBF) #DEFINE FILETYPE_QUERY "Q" && Query (.QPR) #DEFINE FILETYPE_FORM "K" && Form (.SCX) #DEFINE FILETYPE_REPORT "R" && Report (.FRX) #DEFINE FILETYPE_LABEL "B" && Label (.LBX) #DEFINE FILETYPE_CLASSLIB "V" && Class Library (.VCX) #DEFINE FILETYPE_PROGRAM "P" && Program (.PRG) #DEFINE FILETYPE_APILIB "L" && API Library (.FLL) #DEFINE FILETYPE_APPLICATION "Z" && Application (.APP) #DEFINE FILETYPE_MENU "M" && Menu (.MNX) #DEFINE FILETYPE_TEXT "T" && Text (.TXT, .H., etc.) #DEFINE FILETYPE_OTHER "x" && Other file types not enumerated above *-- Server Object Instancing Property #DEFINE SERVERINSTANCE_SINGLEUSE 1 && Single use server #DEFINE SERVERINSTANCE_NOTCREATABLE 2 && Instances creatable only inside Visual FoxPro #DEFINE SERVERINSTANCE_MULTIUSE 3 && Multi-use server *-- Fin / End ******************************************************************************************************************* *-- INTERNACIONALIZACIÓN / INTERNATIONALIZATION ******************************************************************************************************************* #IF .T. &&VERSION(3) == "34" && Español (Spanish) [NO FUNCIONA MÁS ESTO :( ] #DEFINE C_FOXBIN2PRG_JUST_VFP_9_LOC '¡FOXBIN2PRG es solo para Visual FoxPro 9.0!' #DEFINE C_FOXBIN2PRG_WARN_CAPTION_LOC 'FOXBIN2PRG: ¡ATENCIÓN!' #DEFINE FOXBIN2PRG_INFO_SINTAX_LOC 'FOXBIN2PRG [cType_ND cTextName_ND cGenText_ND cNoMostrarErrores cDebug]' + CR_LF + CR_LF ; + 'Ejemplo para generar los TXT de todos los VCX de "c:\desa\clases", sin mostrar ventana de error y generando archivo LOG: ' + CR_LF ; + ' FOXBIN2PRG "c:\desa\clases\*.vcx" "0" "0" "0" "1" "1"' + CR_LF + CR_LF ; + 'Ejemplo para generar los VCX de todos los TXT de "c:\desa\clases", sin mostrar ventana de error y sin LOG: ' + CR_LF ; + ' FOXBIN2PRG "c:\desa\clases\*.vc2" "0" "0" "0" "1" "0"' #DEFINE ASTERISK_EXT_NOT_ALLOWED_LOC 'No se admiten extensiones * o ? porque es peligroso (se pueden pisar binarios con archivo xx2 vacíos).' #DEFINE C_PROCESSING_LOC 'Procesando archivo ' #DEFINE C_FILE_DOESNT_EXIST_LOC "El archivo no existe:" #DEFINE C_SOURCEFILE_LOC "Archivo origen: " #DEFINE C_PROCESS_PROGRESS_LOC "Avance del proceso: " #DEFINE C_CONVERTER_UNLOAD_LOC "Descarga del conversor" #DEFINE C_CONVERTING_FILE_LOC "Convirtiendo archivo " #DEFINE C_BACKUP_OF_LOC "Backup de: " #DEFINE C_ONLY_SETNAME_AND_GETNAME_RECOGNIZED_LOC 'Operación no reconocida. Solo re reconoce SETNAME y GETNAME.' #DEFINE C_BACKLINK_CANT_UPDATE_BL_LOC 'No se pudo actualizar el backlink' #DEFINE C_BACKLINK_OF_TABLE_LOC 'de la tabla' #ELSE && English #DEFINE C_FOXBIN2PRG_JUST_VFP_9_LOC 'FOXBIN2PRG is only for Visual FoxPro 9.0!' #DEFINE C_FOXBIN2PRG_WARN_CAPTION_LOC 'FOXBIN2PRG: WARNING!' #DEFINE FOXBIN2PRG_INFO_SINTAX_LOC 'FOXBIN2PRG [cType_NA cTextName_NA cGenText_NA cDontShowErrors cDebug]' + CR_LF + CR_LF ; + 'Example to generate TXT of all VCX of "c:\desa\clases", without showing error window and generating LOG file: ' + CR_LF ; + ' FOXBIN2PRG "c:\desa\clases\*.vcx" "0" "0" "0" "1" "1"' + CR_LF + CR_LF ; + 'Example to generate TXT of all VCX of "c:\desa\clases", without showing error window and without LOG file: ' + CR_LF ; + ' FOXBIN2PRG "c:\desa\clases\*.vc2" "0" "0" "0" "1" "0"' #DEFINE ASTERISK_EXT_NOT_ALLOWED_LOC '* and ? extensions are not allowed because is dangerous (binaries can be overwriten with xx2 empty files)' #DEFINE C_PROCESSING_LOC 'Processing file ' #DEFINE C_FILE_DOESNT_EXIST_LOC "File doesn't exist:" #DEFINE C_SOURCEFILE_LOC "Source file: " #DEFINE C_PROCESS_PROGRESS_LOC "Process Progress: " #DEFINE C_CONVERTER_UNLOAD_LOC "Converter unload" #DEFINE C_CONVERTING_FILE_LOC "Converting file " #DEFINE C_BACKUP_OF_LOC "Backup of: " #DEFINE C_ONLY_SETNAME_AND_GETNAME_RECOGNIZED_LOC 'Operation not recognized. Only SETNAME and GETNAME allowed.' #DEFINE C_BACKLINK_CANT_UPDATE_BL_LOC 'Could not update backlink' #DEFINE C_BACKLINK_OF_TABLE_LOC 'of table' #ENDIF ******************************************************************************************************************* PUBLIC goCnv AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' LOCAL lnResp goCnv = CREATEOBJECT("c_foxbin2prg") lnResp = goCnv.ejecutar( tc_InputFile, tcType_na, tcTextName_na, tlGenText_na, tcDontShowErrors, tcDebug ; , '', NULL, NULL, .F., tcOriginalFileName ) ADDPROPERTY(_SCREEN, 'ExitCode', lnResp) IF _VFP.STARTMODE <= 1 RETURN lnResp ENDIF *-- Muy útil para procesos batch que capturan el código de error DECLARE ExitProcess IN Win32API INTEGER ExitCode IF NOT EMPTY(lnResp) ExitProcess(1) ENDIF QUIT ******************************************************************************************************************* DEFINE CLASS c_foxbin2prg AS CUSTOM #IF .F. LOCAL THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] *-- n_FB2PRG_Version = 1.18 *-- c_Foxbin2prg_FullPath = '' c_CurDir = '' c_InputFile = '' c_OriginalFileName = '' c_LogFile = '' c_TextLog = '' c_OutputFile = '' c_Type = '' lFileMode = .F. l_Debug = .F. l_Test = .F. l_ShowErrors = .F. l_ShowProgress = .T. l_MethodSort_Enabled = .T. && Para Unit Testing se puede cambiar a .F. para buscar diferencias l_PropSort_Enabled = .T. && Para Unit Testing se puede cambiar a .F. para buscar diferencias l_ReportSort_Enabled = .T. && Para Unit Testing se puede cambiar a .F. para buscar diferencias nClassTimeStamp = '' o_Conversor = NULL o_Frm_Avance = NULL o_FSO = NULL c_VC2 = 'VC2' && VCX c_SC2 = 'SC2' && SCX c_PJ2 = 'PJ2' && PJX c_FR2 = 'FR2' && FRX c_LB2 = 'LB2' && LBX c_DB2 = 'DB2' && DBF c_DC2 = 'DC2' && DBC c_MN2 = 'MN2' && MNX PROCEDURE INIT SET DELETED ON SET DATE YMD SET HOURS TO 24 SET CENTURY ON SET SAFETY OFF SET TABLEPROMPT OFF SET POINT TO '.' SET SEPARATOR TO ',' THIS.c_Foxbin2prg_FullPath = SUBSTR( SYS(16), AT( 'C_FOXBIN2PRG.INIT', SYS(16) ) + LEN('C_FOXBIN2PRG.INIT') + 1 ) THIS.c_CurDir = SYS(5) + CURDIR() THIS.o_FSO = NEWOBJECT("Scripting.FileSystemObject") ENDPROC PROCEDURE DESTROY TRY LOCAL lcFileCDX lcFileCDX = FORCEPATH( "TABLABIN.CDX", JUSTPATH(THIS.c_InputFile) ) IF FILE( lcFileCDX ) ERASE ( lcFileCDX ) ENDIF THIS.writeLog_Flush() CATCH ENDTRY ENDPROC PROCEDURE doBackup *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toEx (@? IN ) Objeto Exception con información del error * tlRelanzarError (v? IN ) Indica si se debe relanzar el error * tcBakFile_1 (@? OUT) Nombre del archivo backup 1 (vcx,scx,pjx,frx,lbx,dbf,dbc,mnx,vc2,sc2,pj2,etc) * tcBakFile_2 (@? OUT) Nombre del archivo backup 2 (vct,sct,pjt,frt,lbt,fpt,dct,mnt,etc) * tcBakFile_3 (@? OUT) Nombre del archivo backup 1 (vcx,scx,pjx,cdx,dcx,etc) *--------------------------------------------------------------------------------------------------- LPARAMETERS toEx, tlRelanzarError, tcBakFile_1, tcBakFile_2, tcBakFile_3 #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lcNext_Bak, lcExt_1, lcExt_2, lcExt_3 STORE '' TO tcBakFile_1, tcBakFile_2, tcBakFile_3 lcNext_Bak = THIS.getNext_BAK( THIS.c_OutputFile ) lcExt_1 = JUSTEXT( THIS.c_OutputFile ) tcBakFile_1 = FORCEEXT(THIS.c_OutputFile, lcExt_1 + lcNext_Bak) DO CASE CASE INLIST( lcExt_1, THIS.c_PJ2, THIS.c_VC2, THIS.c_SC2, THIS.c_FR2 ; , THIS.c_LB2, THIS.c_DB2, THIS.c_DC2, THIS.c_MN2 ) *-- Extensiones TEXTO CASE lcExt_1 = 'DBF' *-- DBF lcExt_2 = 'FPT' lcExt_3 = 'CDX' tcBakFile_2 = FORCEEXT(THIS.c_OutputFile, lcExt_2 + lcNext_Bak) tcBakFile_3 = FORCEEXT(THIS.c_OutputFile, lcExt_3 + lcNext_Bak) CASE lcExt_1 = 'DBC' *-- DBC lcExt_2 = 'DCT' lcExt_3 = 'DCX' tcBakFile_2 = FORCEEXT(THIS.c_OutputFile, lcExt_2 + lcNext_Bak) tcBakFile_3 = FORCEEXT(THIS.c_OutputFile, lcExt_3 + lcNext_Bak) OTHERWISE *-- PJX, VCX, SCX, FRX, LBX, MNX lcExt_2 = LEFT(lcExt_1,2) + 'T' tcBakFile_2 = FORCEEXT(THIS.c_OutputFile, lcExt_2 + lcNext_Bak) ENDCASE IF NOT EMPTY(lcExt_1) AND FILE( FORCEEXT(THIS.c_OutputFile, lcExt_1) ) *-- LOG DO CASE CASE EMPTY(lcExt_2) THIS.writeLog( C_BACKUP_OF_LOC + FORCEEXT(THIS.c_OutputFile,lcExt_1) ) CASE EMPTY(lcExt_3) THIS.writeLog( C_BACKUP_OF_LOC + FORCEEXT(THIS.c_OutputFile,lcExt_1) + '/' + lcExt_2 ) OTHERWISE THIS.writeLog( C_BACKUP_OF_LOC + FORCEEXT(THIS.c_OutputFile,lcExt_1) + '/' + lcExt_2 + '/' + lcExt_3 ) ENDCASE *-- COPIA BACKUP COPY FILE ( FORCEEXT(THIS.c_OutputFile, lcExt_1) ) TO ( tcBakFile_1 ) IF NOT EMPTY(lcExt_2) AND FILE( FORCEEXT(THIS.c_OutputFile, lcExt_2) ) COPY FILE ( FORCEEXT(THIS.c_OutputFile, lcExt_2) ) TO ( tcBakFile_2 ) ENDIF IF NOT EMPTY(lcExt_3) AND FILE( FORCEEXT(THIS.c_OutputFile, lcExt_3) ) COPY FILE ( FORCEEXT(THIS.c_OutputFile, lcExt_3) ) TO ( tcBakFile_3 ) ENDIF ENDIF CATCH TO toEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF IF tlRelanzarError THROW ENDIF ENDTRY RETURN ENDPROC PROCEDURE ejecutar *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tc_InputFile (!v IN ) Nombre del archivo de entrada * tcType_na (?v IN ) NO DISPONIBLE. Se mantiene por compatibilidad con SourceSafe * tcTextName_na (?v IN ) NO DISPONIBLE. Se mantiene por compatibilidad con SourceSafe * tlGenText_na (?v IN ) NO DISPONIBLE. Se mantiene por compatibilidad con SourceSafe * tcDontShowErrors (?v IN ) '1' para no mostrar mensajes de error (MESSAGEBOX) * tcDebug (?v IN ) '1' para habilitar modo debug (SOLO DESARROLLO) * tcDontShowProgress (?v IN ) '1' para inhabilitar la barra de progreso * toModulo (?@ OUT) Referencia de objeto del módulo generado (para Unit Testing) * toEx (?@ OUT) Objeto con información del error * tlRelanzarError (?v IN ) Indica si el error debe relanzarse o no * tcOriginalFileName (v? IN ) Sirve para los casos en los que inputFile es un nombre temporal y se quiere generar * el nombre correcto dentro de la versión texto (por ej: en los PJ2 y las cabeceras) *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tc_InputFile, tcType_na, tcTextName_na, tlGenText_na, tcDontShowErrors, tcDebug, tcDontShowProgress ; , toModulo, toEx AS EXCEPTION, tlRelanzarError, tcOriginalFileName TRY LOCAL I, lcPath, lnResp, lcFileSpec, lcFile, laFiles(1,5), laConfig(1), lcConfigFile, lcExt ; , llExisteConfig, lcConfData, lnFileCount ; , loEx AS EXCEPTION ; , loFSO AS Scripting.FileSystemObject lnResp = 0 SET DELETED ON SET DATE YMD SET HOURS TO 24 SET CENTURY ON SET SAFETY OFF SET TABLEPROMPT OFF IF _VFP.STARTMODE > 0 SET ESCAPE OFF ENDIF loFSO = THIS.o_FSO DO CASE CASE VERSION(5) < 900 *-- '¡FOXBIN2PRG es solo para Visual FoxPro 9.0!' MESSAGEBOX( C_FOXBIN2PRG_JUST_VFP_9_LOC, 0+64+4096, C_FOXBIN2PRG_WARN_CAPTION_LOC, 60000 ) lnResp = 1 CASE EMPTY(tc_InputFile) *-- (Ejemplo de sintaxis y uso) MESSAGEBOX( FOXBIN2PRG_INFO_SINTAX_LOC, 0+64+4096, 'FOXBIN2PRG: SINTAXIS INFO', 60000 ) lnResp = 1 OTHERWISE *-- Ejecución normal THIS.l_ShowProgress = NOT (TRANSFORM(tcDontShowProgress)=='1') THIS.l_ShowErrors = NOT (TRANSFORM(tcDontShowErrors) == '1') THIS.l_Debug = (TRANSFORM(tcDebug)=='1' OR FILE(FORCEEXT(THIS.c_Foxbin2prg_FullPath,'LOG'))) IF THIS.l_ShowProgress THIS.o_Frm_Avance = CREATEOBJECT("frm_avance") ENDIF *-- Configuración lcConfigFile = FORCEEXT( THIS.c_Foxbin2prg_FullPath, 'CFG' ) llExisteConfig = FILE( lcConfigFile ) IF llExisteConfig FOR I = 1 TO ALINES( laConfig, FILETOSTR( lcConfigFile ), 1+4 ) IF LOWER( LEFT( laConfig(I), 10 ) ) == 'extension:' lcConfData = ALLTRIM( SUBSTR( laConfig(I), 11 ) ) lcExt = 'c_' + ALLTRIM( GETWORDNUM( lcConfData, 1, '=' ) ) IF PEMSTATUS( THIS, lcExt, 5 ) THIS.ADDPROPERTY( lcExt, UPPER( ALLTRIM( GETWORDNUM( lcConfData, 2, '=' ) ) ) ) ENDIF ENDIF ENDFOR ENDIF *-- Evaluación de FileSpec de entrada DO CASE CASE '*' $ JUSTEXT( tc_InputFile ) OR '?' $ JUSTEXT( tc_InputFile ) IF THIS.l_ShowErrors MESSAGEBOX( ASTERISK_EXT_NOT_ALLOWED_LOC, 0+48+4096, 'FOXBIN2PRG: ERROR!!', 60000 ) ELSE ERROR ASTERISK_EXT_NOT_ALLOWED_LOC ENDIF CASE '*' $ JUSTSTEM( tc_InputFile ) *-- SE QUIEREN TODOS LOS ARCHIVOS DE UNA EXTENSIÓN lcFileSpec = FULLPATH( tc_InputFile ) CD (JUSTPATH(lcFileSpec)) THIS.c_LogFile = ADDBS( JUSTPATH( lcFileSpec ) ) + STRTRAN( JUSTFNAME( lcFileSpec ), '*', '_ALL' ) + '.LOG' IF THIS.l_Debug IF FILE( THIS.c_LogFile ) ERASE ( THIS.c_LogFile ) ENDIF THIS.writeLog( THIS.c_Foxbin2prg_FullPath + ' - FileSpec: ' + EVL(tc_InputFile,'') ) IF llExisteConfig THIS.writeLog( 'ConfigFile: ' + lcConfigFile ) ENDIF ENDIF lnFileCount = ADIR( laFiles, lcFileSpec, '', 1 ) IF THIS.l_ShowProgress THIS.o_Frm_Avance.nMAX_VALUE = lnFileCount ENDIF FOR I = 1 TO lnFileCount lcFile = FORCEPATH( laFiles(I,1), JUSTPATH( lcFileSpec ) ) THIS.o_Frm_Avance.lbl_TAREA.CAPTION = C_PROCESSING_LOC + lcFile + '...' THIS.o_Frm_Avance.nVALUE = I IF THIS.l_ShowProgress THIS.o_Frm_Avance.SHOW() ENDIF IF FILE( lcFile ) lnResp = THIS.Convertir( lcFile, toModulo, toEx, tlRelanzarError, tcOriginalFileName ) ENDIF ENDFOR OTHERWISE *-- UN ARCHIVO INDIVIDUAL IF FILE(tc_InputFile) CD (JUSTPATH(tc_InputFile)) THIS.c_LogFile = tc_InputFile + '.LOG' IF THIS.l_Debug IF FILE( THIS.c_LogFile ) ERASE ( THIS.c_LogFile ) ENDIF THIS.writeLog( THIS.c_Foxbin2prg_FullPath + ' - FileSpec: ' + EVL(tc_InputFile,'') ) ENDIF lnResp = THIS.Convertir( tc_InputFile, toModulo, toEx, tlRelanzarError, tcOriginalFileName ) ENDIF ENDCASE ENDCASE CATCH TO toEx IF llExisteConfig THIS.writeLog( 'ERROR: ' + TRANSFORM(toEx.ERRORNO) + ', ' + toEx.MESSAGE + CR_LF ; + toEx.PROCEDURE + ', line ' + TRANSFORM(toEx.LINENO) + CR_LF ; + toEx.DETAILS ) ENDIF IF tlRelanzarError THROW ENDIF FINALLY IF VARTYPE(THIS.o_Frm_Avance) = "O" THIS.o_Frm_Avance.HIDE() THIS.o_Frm_Avance.RELEASE() STORE NULL TO THIS.o_Frm_Avance ENDIF CD (JUSTPATH(THIS.c_CurDir)) *SET PATH TO (lcPath) ENDTRY RETURN lnResp ENDPROC PROCEDURE Convertir *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tc_InputFile (!v IN ) Nombre del archivo de entrada * toModulo (?@ OUT) Referencia de objeto del módulo generado (para Unit Testing) * toEx (?@ OUT) Objeto con información del error * tlRelanzarError (?v IN ) Indica si el error debe relanzarse o no * tcOriginalFileName (v? IN ) Sirve para los casos en los que inputFile es un nombre temporal y se quiere generar * el nombre correcto dentro de la versión texto (por ej: en los PJ2 y las cabeceras) *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tc_InputFile, toModulo, toEx AS EXCEPTION, tlRelanzarError, tcOriginalFileName TRY LOCAL lnCodError, lcErrorInfo, laDirFile(1,5), lcExtension ; , loFSO AS Scripting.FileSystemObject lnCodError = 0 WITH THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' loFSO = THIS.o_FSO .c_InputFile = FULLPATH( tc_InputFile ) IF ADIR( laDirFile, .c_InputFile, '', 1 ) = 0 ERROR 'No se encontró el archivo [' + .c_InputFile + ']' ENDIF .c_InputFile = loFSO.GetAbsolutePathName( FORCEPATH( laDirFile(1,1), JUSTPATH(.c_InputFile) ) ) IF NOT EMPTY(tcOriginalFileName) tcOriginalFileName = loFSO.GetAbsolutePathName( tcOriginalFileName ) ENDIF .c_OriginalFileName = EVL( tcOriginalFileName, .c_InputFile ) THIS.writeLog( 'c_InputFile=' + .c_InputFile ) .o_Conversor = NULL IF NOT FILE(.c_InputFile) ERROR C_FILE_DOESNT_EXIST_LOC + ' [' + .c_InputFile + ']' ENDIF IF FILE( .c_InputFile + '.ERR' ) TRY ERASE ( .c_InputFile + '.ERR' ) CATCH ENDTRY ENDIF lcExtension = UPPER( JUSTEXT(.c_InputFile) ) DO CASE CASE lcExtension = 'VCX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_VC2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_vcx_a_prg' ) CASE lcExtension = 'SCX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_SC2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_scx_a_prg' ) CASE lcExtension = 'PJX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_PJ2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_pjx_a_prg' ) CASE lcExtension = 'FRX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_FR2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_frx_a_prg' ) CASE lcExtension = 'LBX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_LB2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_frx_a_prg' ) CASE lcExtension = 'DBF' .c_OutputFile = FORCEEXT( .c_InputFile, .c_DB2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_dbf_a_prg' ) CASE lcExtension = 'DBC' .c_OutputFile = FORCEEXT( .c_InputFile, .c_DC2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_dbc_a_prg' ) CASE lcExtension = 'MNX' .c_OutputFile = FORCEEXT( .c_InputFile, .c_MN2 ) .o_Conversor = CREATEOBJECT( 'c_conversor_mnx_a_prg' ) CASE lcExtension = .c_VC2 .c_OutputFile = FORCEEXT( .c_InputFile, 'VCX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_vcx' ) CASE lcExtension = .c_SC2 .c_OutputFile = FORCEEXT( .c_InputFile, 'SCX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_scx' ) CASE lcExtension = .c_PJ2 .c_OutputFile = FORCEEXT( .c_InputFile, 'PJX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_pjx' ) CASE lcExtension = .c_FR2 .c_OutputFile = FORCEEXT( .c_InputFile, 'FRX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_frx' ) CASE lcExtension = .c_LB2 .c_OutputFile = FORCEEXT( .c_InputFile, 'LBX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_frx' ) CASE lcExtension = .c_DB2 .c_OutputFile = FORCEEXT( .c_InputFile, 'DBF' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_dbf' ) CASE lcExtension = .c_DC2 .c_OutputFile = FORCEEXT( .c_InputFile, 'DBC' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_dbc' ) CASE lcExtension = .c_MN2 .c_OutputFile = FORCEEXT( .c_InputFile, 'MNX' ) .o_Conversor = CREATEOBJECT( 'c_conversor_prg_a_mnx' ) OTHERWISE ERROR 'El archivo [' + .c_InputFile + '] no está soportado' ENDCASE .c_Type = UPPER(JUSTEXT(.c_OutputFile)) .o_Conversor.c_InputFile = .c_InputFile .o_Conversor.c_OutputFile = .c_OutputFile .o_Conversor.c_LogFile = .c_LogFile .o_Conversor.l_Debug = .l_Debug .o_Conversor.l_Test = .l_Test .o_Conversor.n_FB2PRG_Version = .n_FB2PRG_Version .o_Conversor.l_MethodSort_Enabled = .l_MethodSort_Enabled .o_Conversor.l_PropSort_Enabled = .l_PropSort_Enabled .o_Conversor.l_ReportSort_Enabled = .l_ReportSort_Enabled .o_Conversor.c_OriginalFileName = tcOriginalFileName .o_Conversor.c_Foxbin2prg_FullPath = .c_Foxbin2prg_FullPath *-- .o_Conversor.Convertir( @toModulo, .F., THIS ) .c_TextLog = .c_TextLog + CR_LF + .o_Conversor.c_TextLog && Recojo el LOG que haya generado el conversor .normalizarCapitalizacionArchivos() ENDWITH && THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' CATCH TO toEx lnCodError = toEx.ERRORNO lcErrorInfo = THIS.Exception2Str(toEx) + CR_LF + CR_LF + C_SOURCEFILE_LOC + THIS.c_InputFile TRY STRTOFILE( lcErrorInfo, THIS.c_InputFile + '.ERR' ) CATCH TO loEx2 ENDTRY IF THIS.l_Debug IF _VFP.STARTMODE = 0 SET STEP ON ENDIF THIS.writeLog( lcErrorInfo ) ENDIF IF THIS.l_Debug AND THIS.l_ShowErrors MESSAGEBOX( lcErrorInfo, 0+16+4096, 'FOXBIN2PRG: ERROR!!', 60000 ) ENDIF IF tlRelanzarError && Usado en Unit Testing THROW ENDIF FINALLY loFSO = NULL THIS.o_Conversor = NULL THIS.writeLog_Flush() ENDTRY RETURN lnCodError ENDPROC PROCEDURE get_PROGRAM_HEADER LOCAL lcText lcText = '' *-- Cabecera del PRG e inicio de DEF_CLASS TEXT TO lcText ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 *-------------------------------------------------------------------------------------------------------------------------------------------------------- * (ES) AUTOGENERADO - ¡¡ATENCIÓN!! - ¡¡NO PENSADO PARA EJECUTAR!! USAR SOLAMENTE PARA INTEGRAR CAMBIOS Y ALMACENAR CON HERRAMIENTAS SCM!! * (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!! *-------------------------------------------------------------------------------------------------------------------------------------------------------- <> Version="<>" SourceFile="<>" Generated="<>" <> (Solo para binarios VFP 9 / Only for VFP 9 binaries) * ENDTEXT RETURN lcText ENDPROC PROCEDURE getNext_BAK *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tc_OutputFilename (!v IN ) Nombre del archivo de salida a crear el backup *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tcOutputFileName LOCAL lcNext_Bak, I lcNext_Bak = '' FOR I = 0 TO 99 IF I = 0 IF NOT FILE( tcOutputFileName + '.BAK' ) lcNext_Bak = '.BAK' EXIT ENDIF ELSE IF NOT FILE( tcOutputFileName + '.' + PADL(I,2,'0') + '.BAK' ) lcNext_Bak = '.' + PADL(I,2,'0') + '.BAK' EXIT ENDIF ENDIF ENDFOR lcNext_Bak = EVL( lcNext_Bak, '.100.BAK' ) && Para que no quede nunca vacío RETURN lcNext_Bak ENDPROC ******************************************************************************************************************* PROCEDURE normalizarCapitalizacionArchivos TRY LOCAL lcPath, lcEXE_CAPS, lcOutputFile ; , loFSO AS Scripting.FileSystemObject lcPath = JUSTPATH(THIS.c_Foxbin2prg_FullPath) lcEXE_CAPS = FORCEPATH( 'filename_caps.exe', lcPath ) loFSO = THIS.o_FSO IF FILE(lcEXE_CAPS) THIS.writeLog( '* Se ha encontrado el programa de capitalización de nombres [' + lcEXE_CAPS + ']' ) ELSE *-- No existe el programa de capitalización, así que no se capitalizan los nombres. THIS.writeLog( '* No se ha encontrado el programa de capitalización de nombres [' + lcEXE_CAPS + ']' ) EXIT ENDIF THIS.RenameFile( THIS.c_OutputFile, lcEXE_CAPS, loFSO ) DO CASE CASE THIS.c_Type = 'PJX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'PJT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'VCX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'VCT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'SCX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'SCT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'FRX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'FRT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'LBX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'LBT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'DBF' IF FILE( FORCEEXT(THIS.c_OutputFile,'FPT') ) THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'FPT'), lcEXE_CAPS, loFSO ) ENDIF IF FILE( FORCEEXT(THIS.c_OutputFile,'CDX') ) THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'CDX'), lcEXE_CAPS, loFSO ) ENDIF CASE THIS.c_Type = 'DBC' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'DCX'), lcEXE_CAPS, loFSO ) THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'DCT'), lcEXE_CAPS, loFSO ) CASE THIS.c_Type = 'MNX' THIS.RenameFile( FORCEEXT(THIS.c_OutputFile,'MNT'), lcEXE_CAPS, loFSO ) ENDCASE ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE RenameFile LPARAMETERS tcFileName, tcEXE_CAPS, toFSO AS Scripting.FileSystemObject LOCAL lcLog, laFile(1,5) THIS.writeLog( '- Se ha solicitado capitalizar el archivo [' + tcFileName + ']' ) lcLog = '' DO (tcEXE_CAPS) WITH tcFileName, '', 'F', lcLog, .T. IF ADIR( laFile, tcFileName, '', 1 ) > 0 AND laFile(1,1) <> JUSTFNAME(tcFileName) toFSO.MoveFile( FORCEPATH( laFile(1,1), JUSTPATH(tcFileName) ), tcFileName ) THIS.writeLog( ' => Se renombrará a [' + tcFileName + ']' ) ELSE THIS.writeLog( ' => No se renombrará a [' + tcFileName + '] porque ya estaba correcto.' ) ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE writeLog LPARAMETERS tcText TRY THIS.c_TextLog = THIS.c_TextLog + TTOC(DATETIME(),3) + ' ' + EVL(tcText,'') + CR_LF CATCH ENDTRY ENDPROC ******************************************************************************************************************* PROCEDURE writeLog_Flush IF THIS.l_Debug AND NOT EMPTY(THIS.c_TextLog) STRTOFILE( THIS.c_TextLog + CR_LF, THIS.c_LogFile, 1 ) THIS.c_TextLog = '' ENDIF ENDPROC ******************************************************************************************************************* HIDDEN PROCEDURE Exception2Str LPARAMETERS toEx AS EXCEPTION LOCAL lcError lcError = 'Error ' + TRANSFORM(toEx.ERRORNO) + ', ' + toEx.MESSAGE + CR_LF ; + toEx.PROCEDURE + ', ' + TRANSFORM(toEx.LINENO) + CR_LF ; + toEx.LINECONTENTS + CR_LF + CR_LF ; + EVL(toEx.USERVALUE,'') RETURN lcError ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS frm_avance AS FORM HEIGHT = 79 WIDTH = 628 SHOWWINDOW = 2 DOCREATE = .T. AUTOCENTER = .T. BORDERSTYLE = 2 CAPTION = C_PROCESS_PROGRESS_LOC CONTROLBOX = .F. BACKCOLOR = RGB(255,255,255) nMAX_VALUE = 100 nVALUE = 0 NAME = "FRM_AVANCE" ADD OBJECT shp_base AS SHAPE WITH ; TOP = 40, ; LEFT = 12, ; HEIGHT = 21, ; WIDTH = 601, ; CURVATURE = 15, ; NAME = "shp_base" ADD OBJECT shp_avance AS SHAPE WITH ; TOP = 40, ; LEFT = 12, ; HEIGHT = 21, ; WIDTH = 36, ; CURVATURE = 15, ; BACKCOLOR = RGB(255,255,128), ; BORDERCOLOR = RGB(255,0,0), ; NAME = "shp_Avance" ADD OBJECT lbl_TAREA AS LABEL WITH ; BACKSTYLE = 0, ; CAPTION = ".", ; HEIGHT = 17, ; LEFT = 12, ; TOP = 20, ; WIDTH = 604, ; NAME = "lbl_Tarea" PROCEDURE nvalue_assign LPARAMETERS vNewVal WITH THIS .nVALUE = m.vNewVal .shp_avance.WIDTH = m.vNewVal * .shp_base.WIDTH / .nMAX_VALUE ENDWITH ENDPROC PROCEDURE INIT THIS.nVALUE = 0 ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_base AS SESSION #IF .F. LOCAL THIS AS c_conversor_base OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] l_Debug = .F. l_Test = .F. c_InputFile = '' c_OutputFile = '' lFileMode = .T. nClassTimeStamp = '' n_FB2PRG_Version = 1.0 c_Foxbin2prg_FullPath = '' c_Type = '' c_CurDir = '' c_LogFile = '' c_TextLog = '' l_MethodSort_Enabled = .T. l_PropSort_Enabled = .T. l_ReportSort_Enabled = .T. c_OriginalFileName = '' oFSO = NULL ******************************************************************************************************************* PROCEDURE INIT SET DELETED ON SET DATE YMD SET HOURS TO 24 SET CENTURY ON SET SAFETY OFF SET TABLEPROMPT OFF PUBLIC C_FB2PRG_CODE C_FB2PRG_CODE = '' && Contendrá todo el código generado THIS.c_CurDir = SYS(5) + CURDIR() THIS.oFSO = CREATEOBJECT( "Scripting.FileSystemObject") ENDPROC ******************************************************************************************************************* PROCEDURE DESTROY C_FB2PRG_CODE = '' USE IN (SELECT("TABLABIN")) THIS.writeLog( C_CONVERTER_UNLOAD_LOC ) ENDPROC ******************************************************************************************************************* PROCEDURE analizarAsignacion_TAG_Indicado *-- DETALLES: Este método está pensado para leer los tags FB2P_VALUE y MEMBERDATA, que tienen esta sintaxis: * * _memberdata = * * && XML Metadata for customizable properties * * Este es un valor especial * *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcPropName (!v IN ) Nombre de la propiedad * tcValue (!v IN ) Valor (o inicio del valor) de la propiedad * taProps (!@ IN ) El array con las líneas del código donde buscar * tnProp_Count (!@ IN ) Cantidad de líneas de código * I (!@ IN ) Línea actualmente evaluada * tcTAG_I (!v IN ) TAG de inicio * tcTAG_F (!v IN ) TAG de fin * tnLEN_TAG_I (!v IN ) Longitud del tag de inicio * tnLEN_TAG_F (!v IN ) Longitud del tag de fin *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tcPropName, tcValue, taProps, tnProp_Count, I, tcTAG_I, tcTAG_F, tnLEN_TAG_I, tnLEN_TAG_F EXTERNAL ARRAY taProps LOCAL llBloqueEncontrado, loEx AS EXCEPTION TRY IF LEFT( tcValue, tnLEN_TAG_I) == tcTAG_I llBloqueEncontrado = .T. LOCAL lcLine, lnArrayCols *-- Propiedad especial IF tcTAG_F $ tcValue && El fin de tag está "inline" THIS.desnormalizarValorPropiedad( @tcPropName, @tcValue, '' ) EXIT ENDIF tcValue = '' lnArrayCols = ALEN(taProps,2) FOR I = I + 1 TO tnProp_Count IF lnArrayCols = 0 lcLine = LTRIM( taProps(I), 0, ' ', CHR(9) ) && Quito espacios y TABS de la izquierda ELSE lcLine = LTRIM( taProps(I,1), 0, ' ', CHR(9) ) && Quito espacios y TABS de la izquierda ENDIF DO CASE CASE LEFT( lcLine, tnLEN_TAG_F ) == tcTAG_F *-- tcValue = tcTAG_I + SUBSTR( tcValue, 3 ) + tcTAG_F THIS.desnormalizarValorPropiedad( @tcPropName, @tcValue, '' ) I = I + 1 EXIT CASE tcTAG_F $ lcLine *-- Data-Data-Data- tcValue = tcTAG_I + SUBSTR( tcValue, 3 ) + LEFT( lcLine, AT( tcTAG_F, lcLine )-1 ) + tcTAG_F THIS.desnormalizarValorPropiedad( @tcPropName, @tcValue, '' ) I = I + 1 EXIT OTHERWISE *-- Data tcValue = tcValue + CR_LF + lcLine ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE buscarObjetoDelMetodoPorNombre LPARAMETERS tcNombreObjeto, toClase *-- Caso 1: Un método de un objeto de la clase *-- buscarObjetoDelMetodoPorNombre( 'command1', loClase ) *-- Caso 2: Un método de un objeto heredado que no está definido en esta librería *-- buscarObjetoDelMetodoPorNombre( 'cnt_descripcion.Cntlista.cmgAceptarCancelar.cmdCancelar', loClase ) #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnObjeto, I, X, N, lcRutaDelNombre ; , loObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' STORE 0 TO N, lnObjeto *-- El método puede pertenecer a esta clase, a un objeto de esta clase, *-- o a un objeto heredado que no está definido en esta clase, sino en otra, *-- y para la cual la ruta a buscar es parcial. *-- Por ejemplo, el caso 2 puede que el objeto que hay sea 'cnt_descripcion.Cntlista' *-- y el botón sea heredado, pero se le haya redefinido su método Click aquí. FOR X = OCCURS( '.', tcNombreObjeto + '.' ) TO 1 STEP -1 N = N + 1 lcRutaDelNombre = LEFT( tcNombreObjeto, RAT( '.', tcNombreObjeto + '.', N ) - 1 ) FOR I = 1 TO toClase._AddObject_Count loObjeto = toClase._AddObjects(I) *-- Busco tanto el [nombre] del método como [class.nombre]+[nombre] del método IF LOWER(loObjeto._Nombre) == LOWER(toClase._ObjName) + '.' + lcRutaDelNombre ; OR LOWER(loObjeto._Nombre) == lcRutaDelNombre lnObjeto = I EXIT ENDIF ENDFOR IF lnObjeto > 0 EXIT ENDIF ENDFOR CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lnObjeto ENDPROC ******************************************************************************************************************* FUNCTION comprobarExpresionValida LPARAMETERS tcAsignacion, tnCodError, tcExpNormalizada LOCAL llError, loEx AS EXCEPTION TRY tcExpNormalizada = NORMALIZE( tcAsignacion ) CATCH TO loEx llError = .T. tnCodError = loEx.ERRORNO ENDTRY RETURN NOT llError ENDFUNC PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toModulo (@! OUT) Objeto generado de clase correspondiente con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toModulo, toEx AS EXCEPTION, toFoxbin2prg #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF THIS.writeLog( '' ) THIS.writeLog( C_CONVERTING_FILE_LOC + THIS.c_OutputFile + '...' ) ENDPROC PROCEDURE decode_SpecialCodes_1_31 *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcText (@! IN ) Decodifica los primeros 31 caracteres ASCII de {nCode} a CHR(nCode) *--------------------------------------------------------------------------------------------------- LPARAMETERS tcText LOCAL I FOR I = 0 TO 31 tcText = STRTRAN( tcText, '{' + TRANSFORM(I) + '}', CHR(I) ) ENDFOR RETURN tcText ENDPROC ******************************************************************************************************************* PROCEDURE desnormalizarAsignacion LPARAMETERS tcAsignacion LOCAL lcPropName, lcValor, lnCodError, lcExpNormalizada, lnPos, lcComentario THIS.get_SeparatedPropAndValue( @tcAsignacion, @lcPropName, @lcValor ) lcComentario = '' THIS.desnormalizarValorPropiedad( @lcPropName, @lcValor, @lcComentario ) tcAsignacion = lcPropName + ' = ' + lcValor RETURN tcAsignacion ENDPROC ******************************************************************************************************************* PROCEDURE desnormalizarValorPropiedad LPARAMETERS tcProp, tcValue, tcComentario LOCAL lnCodError, lnPos, lcValue tcComentario = '' *-- Ajustes de algunos casos especiales DO CASE CASE tcProp == '_memberdata' *-- Me quedo con lo importante y quito los CHR(0) y longitud que a veces agrega al inicio lcValue = '' FOR I = 1 TO OCCURS( '/>', tcValue ) TEXT TO lcValue TEXTMERGE ADDITIVE NOSHOW FLAGS 1+2 PRETEXT 1+2 <', I, 1+4 )>> ENDTEXT ENDFOR TEXT TO tcValue TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> ENDTEXT tcValue = C_MPROPHEADER + STR( LEN(tcValue), 8 ) + tcValue CASE LEFT( tcValue, C_LEN_FB2P_VALUE_I ) == C_FB2P_VALUE_I *-- Valor especial Fox con cabecera CHR(1): Debo agregarla y desnormalizar el valor tcValue = STRTRAN( STRTRAN( STREXTRACT( tcValue, C_FB2P_VALUE_I, C_FB2P_VALUE_F, 1, 1 ), ' ', C_CR ), ' ', C_LF ) tcValue = C_MPROPHEADER + STR( LEN(tcValue), 8 ) + tcValue ENDCASE RETURN tcValue ENDFUNC ******************************************************************************************************************* PROCEDURE desnormalizarValorXML LPARAMETERS tcValor *-- DESNORMALIZA EL TEXTO INDICADO, EXPANDIENDO LOS SÍMBOLOS XML ESPECIALES. LOCAL lnPos, lnPos2, lnAscii tcValor = STRTRAN(tcValor, CHR(38)+'gt;', '>') && > tcValor = STRTRAN(tcValor, CHR(38)+'lt;', '<') && < tcValor = STRTRAN(tcValor, CHR(38)+'quot;', CHR(34)) && " tcValor = STRTRAN(tcValor, CHR(38)+'apos;', CHR(39)) && ' tcValor = STRTRAN(tcValor, CHR(38)+'amp;', CHR(38)) && & *-- Obtengo los Hex DO WHILE .T. lnPos = AT( CHR(38)+'#x', tcValor ) IF lnPos = 0 EXIT ENDIF lnPos2 = lnPos + 1 + AT( ';', SUBSTR( tcValor, lnPos + 2, 4 ) ) lnAscii = EVALUATE( '0' + SUBSTR( tcValor, lnPos + 3, lnPos2 - lnPos - 3 ) ) tcValor = STUFF(tcValor, lnPos, lnPos2 - lnPos + 1, CHR(lnAscii)) && ASCII ENDDO *-- Obtengo los Dec DO WHILE .T. lnPos = AT( CHR(38)+'#', tcValor ) IF lnPos = 0 EXIT ENDIF lnPos2 = lnPos + 1 + AT( ';', SUBSTR( tcValor, lnPos + 2, 4 ) ) lnAscii = EVALUATE( SUBSTR( tcValor, lnPos + 2, lnPos2 - lnPos - 2 ) ) tcValor = STUFF(tcValor, lnPos, lnPos2 - lnPos + 1, CHR(lnAscii)) && ASCII ENDDO RETURN tcValor ENDPROC ******************************************************************************************************************* PROCEDURE encode_SpecialCodes_1_31 LPARAMETERS tcText LOCAL I FOR I = 0 TO 31 tcText = STRTRAN( tcText, CHR(I), '{' + TRANSFORM(I) + '}' ) ENDFOR RETURN tcText ENDPROC ******************************************************************************************************************* HIDDEN PROCEDURE Exception2Str LPARAMETERS toEx AS EXCEPTION LOCAL lcError lcError = 'Error ' + TRANSFORM(toEx.ERRORNO) + ', ' + toEx.MESSAGE + CHR(13) + CHR(13) ; + toEx.PROCEDURE + ', ' + TRANSFORM(toEx.LINENO) + CHR(13) + CHR(13) ; + toEx.LINECONTENTS RETURN lcError ENDPROC ******************************************************************************************************************* PROCEDURE fileTypeCode LPARAMETERS tcExtension tcExtension = UPPER(tcExtension) RETURN ICASE( tcExtension = 'DBC', 'd' ; , tcExtension = 'DBF', 'D' ; , tcExtension = 'QPR', 'Q' ; , tcExtension = 'SCX', 'K' ; , tcExtension = 'FRX', 'R' ; , tcExtension = 'LBX', 'B' ; , tcExtension = 'VCX', 'V' ; , tcExtension = 'PRG', 'P' ; , tcExtension = 'FLL', 'L' ; , tcExtension = 'APP', 'Z' ; , tcExtension = 'EXE', 'Z' ; , tcExtension = 'MNX', 'M' ; , tcExtension = 'TXT', 'T' ; , tcExtension = 'FPW', 'T' ; , tcExtension = 'H', 'T' ; , 'x' ) ENDPROC FUNCTION GetTimeStamp *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tnTimeStamp (v! IN ) Timestamp en formato numérico *--------------------------------------------------------------------------------------------------- LPARAMETERS tnTimeStamp *-- CONVIERTE UN DATO TIMESTAMP NUMERICO USADO POR LOS ARCHIVOS SCX/VCX/etc. EN TIPO DATETIME TRY LOCAL lcTimeStamp,lnYear,lnMonth,lnDay,lnHour,lnMinutes,lnSeconds,lcTime,lnHour,ltTimeStamp,lnResto ; ,lcTimeStamp_Ret, laDir[1,5], loEx AS EXCEPTION lcTimeStamp_Ret = '' IF EMPTY(tnTimeStamp) IF THIS.lFileMode IF ADIR(laDir,THIS.c_InputFile)=0 EXIT ENDIF *-- Esto fuerza la conversión a formato 12 hs, que no me interesa. *lcTime=laDir[1,4] *lnHour=VAL(lcTime) *IF lnHour<12 * lcTime=ALLTRIM(STR(IIF(lnHour=0,12,lnHour),2))+SUBSTR(lcTime,3)+" AM" *ELSE * lcTime=ALLTRIM(STR(IIF(lnHour=12,24,lnHour)-12,2))+SUBSTR(lcTime,3)+" PM" *ENDIF *IF VAL(lcTime)<10 * lcTime="0"+lcTime *ENDIF *lcTimeStamp_Ret = DTOC(laDir[1,3])+" "+lcTime ltTimeStamp = EVALUATE( '{^' + DTOC(laDir(1,3)) + ' ' + TRANSFORM(laDir(1,4)) + '}' ) *-- En mi arreglo, si la hora pasada tiene 32 segundos o más, redondeo al siguiente minuto, ya que *-- la descodificación posterior de GetTimeStamp tiene ese margen de error. IF SEC(m.ltTimeStamp) >= 32 ltTimeStamp = m.ltTimeStamp + 28 ENDIF lcTimeStamp_Ret = TTOC( ltTimeStamp ) EXIT ENDIF tnTimeStamp = THIS.nClassTimeStamp IF EMPTY(tnTimeStamp) EXIT ENDIF ENDIF *-- YYYY YYYM MMMD DDDD HHHH HMMM MMMS SSSS lnResto = tnTimeStamp lnYear = INT( lnResto / 2**25 + 1980) lnResto = lnResto % 2**25 lnMonth = INT( lnResto / 2**21 ) lnResto = lnResto % 2**21 lnDay = INT( lnResto / 2**16 ) lnResto = lnResto % 2**16 lnHour = INT( lnResto / 2**11 ) lnResto = lnResto % 2**11 lnMinutes = INT( lnResto / 2**5 ) lnResto = lnResto % 2**5 lnSeconds = lnResto lcTimeStamp = STR(lnYear,4) + "/" + STR(lnMonth,2) + "/" + STR(lnDay,2) + " " ; + STR(lnHour,2) + ":" + STR(lnMinutes,2) + ":" + STR(lnSeconds,2) ltTimeStamp = EVALUATE( "{^" + lcTimeStamp + "}" ) lcTimeStamp_Ret = TTOC( ltTimeStamp ) CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lcTimeStamp_Ret ENDPROC PROCEDURE get_SeparatedLineAndComment *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcLine (@! IN/OUT) Línea a separar del comentario * tcComment (@? OUT) Comentario *--------------------------------------------------------------------------------------------------- LPARAMETERS tcLine, tcComment LOCAL ln_AT_Cmt tcComment = '' IF '&'+'&' $ tcLine ln_AT_Cmt = AT( '&'+'&', tcLine) tcComment = LTRIM( SUBSTR( tcLine, ln_AT_Cmt + 2 ) ) tcLine = RTRIM( LEFT( tcLine, ln_AT_Cmt - 1 ), 0, ' ', CHR(9) ) && Quito espacios y TABS ENDIF RETURN ENDPROC PROCEDURE get_SeparatedPropAndValue *-- Devuelve el valor separado de la propiedad. *-- Si se indican más de 3 parámetros, evalúa el valor completo a través de las líneas de código *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (!@ IN ) Array con las posiciones de inicio/fin de los bloques de exclusion * tnBloquesExclusion (!@ IN ) Cantidad de bloques de exclusión * toModulo (?@ OUT) Objeto con toda la información del módulo analizado *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tcAsignacion, tcPropName, tcValue, toClase, taCodeLines, tnCodeLines, I LOCAL ln_AT_Cmt STORE '' TO tcPropName, tcValue *-- EVALUAR UNA ASIGNACIÓN ESPECÍFICA INLINE IF '=' $ tcAsignacion ln_AT_Cmt = AT( '=', tcAsignacion) tcPropName = ALLTRIM( LEFT( tcAsignacion, ln_AT_Cmt - 2 ), 0, ' ', CHR(9) ) && Quito espacios y TABS tcValue = ALLTRIM( SUBSTR( tcAsignacion, ln_AT_Cmt + 2 ) ) IF PCOUNT() > 3 *-- EVALUAR UNA ASIGNACIÓN QUE PUEDE SER MULTILÍNEA (memberdata, fb2p_value, etc) DO CASE CASE THIS.analizarAsignacion_TAG_Indicado( @tcPropName, @tcValue, @taCodeLines, tnCodeLines, @I ; , C_FB2P_VALUE_I, C_FB2P_VALUE_F, C_LEN_FB2P_VALUE_I, C_LEN_FB2P_VALUE_F ) *-- FB2P_VALUE CASE THIS.analizarAsignacion_TAG_Indicado( @tcPropName, @tcValue, @taCodeLines, tnCodeLines, @I ; , C_MEMBERDATA_I, C_MEMBERDATA_F, C_LEN_MEMBERDATA_I, C_LEN_MEMBERDATA_F ) *-- MEMBERDATA OTHERWISE *-- Propiedad normal THIS.desnormalizarValorPropiedad( @tcPropName, @tcValue, '' ) ENDCASE ENDIF ENDIF RETURN ENDPROC ************************************************************************************************ PROCEDURE get_ValueFromNullTerminatedValue LPARAMETERS tcNullTerminatedValue LOCAL lcValue, lnNullPos lnNullPos = AT(CHR(0), tcNullTerminatedValue ) IF lnNullPos = 0 lcValue = CHRTRAN( tcNullTerminatedValue, ['], ["] ) ELSE lcValue = CHRTRAN( LEFT( tcNullTerminatedValue, lnNullPos - 1 ), ['], ["] ) ENDIF RETURN lcValue ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toModulo ENDPROC ******************************************************************************************************************* PROCEDURE lineaExcluida LPARAMETERS tn_Linea, tnBloquesExclusion, taBloquesExclusion EXTERNAL ARRAY taBloquesExclusion LOCAL X, llExcluida FOR X = 1 TO tnBloquesExclusion IF BETWEEN( tn_Linea, taBloquesExclusion(X,1), taBloquesExclusion(X,2) ) llExcluida = .T. EXIT ENDIF ENDFOR RETURN llExcluida ENDPROC ******************************************************************************************************************* PROCEDURE lineIsOnlyCommentAndNoMetadata LPARAMETERS tcLine, tcComment LOCAL lllineIsOnlyCommentAndNoMetadata, ln_AT_Cmt THIS.get_SeparatedLineAndComment( @tcLine, @tcComment ) DO CASE CASE LEFT(tcLine,2) == '*<' tcComment = tcLine CASE EMPTY(tcLine) OR LEFT(tcLine, 1) == '*' OR LEFT(tcLine + ' ', 5) == 'NOTE ' && Vacía o Comentarios lllineIsOnlyCommentAndNoMetadata = .T. ENDCASE RETURN lllineIsOnlyCommentAndNoMetadata ENDPROC ******************************************************************************************************************* PROCEDURE normalizarAsignacion LPARAMETERS tcAsignacion, tcComentario LOCAL lcPropName, lcValor, lnCodError, lcExpNormalizada, lnPos THIS.get_SeparatedPropAndValue( @tcAsignacion, @lcPropName, @lcValor ) tcComentario = '' THIS.normalizarValorPropiedad( @lcPropName, @lcValor, @tcComentario ) tcAsignacion = lcPropName + ' = ' + lcValor RETURN tcAsignacion ENDPROC ******************************************************************************************************************* PROCEDURE normalizarValorPropiedad LPARAMETERS tcProp, tcValue, tcComentario LOCAL lcValue, I tcComentario = '' *-- Ajustes de algunos casos especiales DO CASE CASE tcProp == '_memberdata' lcValue = '' FOR I = 1 TO OCCURS( '/>', tcValue ) TEXT TO lcValue TEXTMERGE ADDITIVE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> <', I, 1+4 )>> ENDTEXT ENDFOR TEXT TO tcValue TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <<>> ENDTEXT CASE LEFT( tcValue, C_LEN_FB2P_VALUE_I ) == C_FB2P_VALUE_I *-- Valor especial Fox con cabecera CHR(1): Debo quitarla y normalizar el valor tcValue = C_FB2P_VALUE_I ; + STRTRAN( STRTRAN( STRTRAN( STRTRAN( ; STREXTRACT( tcValue, C_FB2P_VALUE_I, C_FB2P_VALUE_F, 1, 1 ) ; , CR_LF, ' +10;' ), C_CR, ' ' ), C_LF, ' ' ), ' +10;', CR_LF ) ; + C_FB2P_VALUE_F ENDCASE RETURN tcValue ENDPROC ******************************************************************************************************************* PROCEDURE normalizarValorXML LPARAMETERS tcValor *-- NORMALIZA EL TEXTO INDICADO, COMPRIMIENDO LOS SÍMBOLOS XML ESPECIALES. tcValor = STRTRAN(tcValor, CHR(38), CHR(38) + 'amp;') && reemplaza & por & && tcValor = STRTRAN(tcValor, CHR(39), CHR(38) + 'apos;') && reemplaza ' por ' && tcValor = STRTRAN(tcValor, CHR(34), CHR(38) + 'quot;') && reemplaza " por " && tcValor = STRTRAN(tcValor, '<', CHR(38) + 'lt;') && reemplaza < por < && tcValor = STRTRAN(tcValor, '>', CHR(38) + 'gt;') && reemplaza > por > && tcValor = STRTRAN(tcValor, CHR(13)+CHR(10), CHR(10)) && reeemplaza CR+LF por LF tcValor = CHRTRAN(tcValor, CHR(13), CHR(10)) && reemplaza CR por LF RETURN tcValor ENDPROC ******************************************************************************************************************* FUNCTION RowTimeStamp(ltDateTime) * Generate a FoxPro 3.0-style row timestamp *-- CONVIERTE UN DATO TIPO DATETIME EN TIMESTAMP NUMERICO USADO POR LOS ARCHIVOS SCX/VCX/etc. LOCAL lcTimeValue, tnTimeStamp IF VARTYPE(m.ltDateTime) <> 'T' m.ltDateTime = DATETIME() ENDIF tnTimeStamp = ( YEAR(m.ltDateTime) - 1980) * 2^25 ; + MONTH(m.ltDateTime) * 2^21 ; + DAY(m.ltDateTime) * 2^16 ; + HOUR(m.ltDateTime) * 2^11 ; + MINUTE(m.ltDateTime) * 2^5 ; + SEC(m.ltDateTime) RETURN INT(tnTimeStamp) ENDFUNC ******************************************************************************************************************* PROCEDURE sortPropsAndValues_SetAndGetSCXPropNames *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcOperation (!v IN ) Operación a realizar ("SETNAME" o "GETNAME") * tcPropName (!v IN ) Nombre de la propiedad *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tcOperation, tcPropName LOCAL lcPropName, lnPropType lcPropName = tcPropName tcOperation = UPPER(EVL(tcOperation,'')) lnPropType = 0 && System property DO CASE CASE tcOperation == 'GETNAME' lcPropName = SUBSTR(tcPropName,5) CASE NOT tcOperation == 'SETNAME' ERROR C_ONLY_SETNAME_AND_GETNAME_RECOGNIZED_LOC CASE lcPropName == 'ButtonCount' lcPropName = 'A005' + lcPropName CASE lcPropName == 'ColumnCount' lcPropName = 'A010' + lcPropName CASE lcPropName == 'Value' lcPropName = 'A015' + lcPropName CASE lcPropName == 'Comment' lcPropName = 'A020' + lcPropName CASE lcPropName == 'ControlSource' lcPropName = 'A025' + lcPropName CASE lcPropName == 'DataSession' lcPropName = 'A030' + lcPropName CASE lcPropName == 'DeleteMark' lcPropName = 'A035' + lcPropName CASE lcPropName == 'ScaleMode' lcPropName = 'A040' + lcPropName CASE lcPropName == 'Tag' lcPropName = 'A045' + lcPropName CASE lcPropName == 'Top' lcPropName = 'A050' + lcPropName CASE lcPropName == 'Left' lcPropName = 'A055' + lcPropName CASE lcPropName == 'Height' lcPropName = 'A060' + lcPropName CASE lcPropName == 'Width' lcPropName = 'A065' + lcPropName CASE lcPropName == 'MaxLength' lcPropName = 'A070' + lcPropName CASE lcPropName == 'Alias' lcPropName = 'A075' + lcPropName CASE lcPropName == 'BufferModeOverride' lcPropName = 'A080' + lcPropName CASE lcPropName == 'Order' lcPropName = 'A085' + lcPropName CASE lcPropName == 'OrderDirection' lcPropName = 'A090' + lcPropName CASE lcPropName == 'CursorSource' lcPropName = 'A095' + lcPropName CASE lcPropName == 'Exclusive' lcPropName = 'A100' + lcPropName CASE lcPropName == 'Filter' lcPropName = 'A105' + lcPropName CASE lcPropName == 'Panel' lcPropName = 'A110' + lcPropName CASE lcPropName == 'ReadOnly' lcPropName = 'A115' + lcPropName CASE lcPropName == 'RecordSource' lcPropName = 'A120' + lcPropName CASE lcPropName == 'RecordSourceType' lcPropName = 'A125' + lcPropName CASE lcPropName == 'NoDataOnLoad' lcPropName = 'A130' + lcPropName CASE lcPropName == 'OpenViews' lcPropName = 'A135' + lcPropName CASE lcPropName == 'AutoOpenTables' lcPropName = 'A140' + lcPropName CASE lcPropName == 'AutoCloseTables' lcPropName = 'A145' + lcPropName CASE lcPropName == 'InitialSelectedAlias' lcPropName = 'A150' + lcPropName CASE lcPropName == 'DataSource' lcPropName = 'A155' + lcPropName CASE lcPropName == 'DataSourceType ' lcPropName = 'A160' + lcPropName CASE lcPropName == 'Desktop' lcPropName = 'A165' + lcPropName CASE lcPropName == 'ShowWindow' lcPropName = 'A170' + lcPropName CASE lcPropName == 'ScrollBars' lcPropName = 'A175' + lcPropName CASE lcPropName == 'ShowInTaskBar' lcPropName = 'A180' + lcPropName CASE lcPropName == 'DoCreate' lcPropName = 'A185' + lcPropName CASE lcPropName == 'Tag' lcPropName = 'A190' + lcPropName CASE lcPropName == 'OLEDragMode' lcPropName = 'A195' + lcPropName CASE lcPropName == 'OLEDragPicture' lcPropName = 'A200' + lcPropName CASE lcPropName == 'OLEDropMode' lcPropName = 'A205' + lcPropName CASE lcPropName == 'OLEDropEffects' lcPropName = 'A210' + lcPropName CASE lcPropName == 'ShowTips' lcPropName = 'A215' + lcPropName CASE lcPropName == 'BufferMode' lcPropName = 'A220' + lcPropName CASE lcPropName == 'AutoCenter' lcPropName = 'A225' + lcPropName CASE lcPropName == 'AutoSize' lcPropName = 'A230' + lcPropName CASE lcPropName == 'WordWrap' lcPropName = 'A235' + lcPropName CASE lcPropName == 'Picture' lcPropName = 'A240' + lcPropName CASE lcPropName == 'BackStyle' lcPropName = 'A245' + lcPropName CASE lcPropName == 'BorderStyle' lcPropName = 'A250' + lcPropName CASE lcPropName == 'BorderWidth' lcPropName = 'A255' + lcPropName CASE lcPropName == 'Caption' lcPropName = 'A260' + lcPropName CASE lcPropName == 'ControlBox' lcPropName = 'A265' + lcPropName CASE lcPropName == 'Closable' lcPropName = 'A270' + lcPropName CASE lcPropName == 'Curvature' lcPropName = 'A275' + lcPropName CASE lcPropName == 'FontBold' lcPropName = 'A280' + lcPropName CASE lcPropName == 'FontCondense' lcPropName = 'A285' + lcPropName CASE lcPropName == 'FontExtend' lcPropName = 'A290' + lcPropName CASE lcPropName == 'FontItalic' lcPropName = 'A295' + lcPropName CASE lcPropName == 'FontName' lcPropName = 'A300' + lcPropName CASE lcPropName == 'FontOutline' lcPropName = 'A305' + lcPropName CASE lcPropName == 'FontShadow' lcPropName = 'A310' + lcPropName CASE lcPropName == 'FontSize' lcPropName = 'A315' + lcPropName CASE lcPropName == 'FontStrikethru' lcPropName = 'A320' + lcPropName CASE lcPropName == 'FontUnderline' lcPropName = 'A325' + lcPropName CASE lcPropName == 'HalfHeightCaption' lcPropName = 'A330' + lcPropName CASE lcPropName == 'Margin' lcPropName = 'A335' + lcPropName CASE lcPropName == 'MaxButton' lcPropName = 'A340' + lcPropName CASE lcPropName == 'MinButton' lcPropName = 'A345' + lcPropName CASE lcPropName == 'Movable' lcPropName = 'A350' + lcPropName CASE lcPropName == 'MaxHeight' lcPropName = 'A355' + lcPropName CASE lcPropName == 'MaxWidth' lcPropName = 'A360' + lcPropName CASE lcPropName == 'MinHeight' lcPropName = 'A365' + lcPropName CASE lcPropName == 'MinWidth' lcPropName = 'A370' + lcPropName CASE lcPropName == 'MaxTop' lcPropName = 'A375' + lcPropName CASE lcPropName == 'MaxLeft' lcPropName = 'A380' + lcPropName CASE lcPropName == 'MDIForm' lcPropName = 'A385' + lcPropName CASE lcPropName == 'MousePointer' lcPropName = 'A390' + lcPropName CASE lcPropName == 'MouseIcon' lcPropName = 'A395' + lcPropName CASE lcPropName == 'Visible' lcPropName = 'A400' + lcPropName CASE lcPropName == 'ClipControls' lcPropName = 'A405' + lcPropName CASE lcPropName == 'DrawMode' lcPropName = 'A410' + lcPropName CASE lcPropName == 'DrawStyle' lcPropName = 'A415' + lcPropName CASE lcPropName == 'DrawWidth' lcPropName = 'A420' + lcPropName CASE lcPropName == 'FillStyle' lcPropName = 'A425' + lcPropName CASE lcPropName == 'Enabled' lcPropName = 'A430' + lcPropName CASE lcPropName == 'Icon' lcPropName = 'A435' + lcPropName CASE lcPropName == 'KeyPreview' lcPropName = 'A440' + lcPropName CASE lcPropName == 'TabIndex' lcPropName = 'A445' + lcPropName CASE lcPropName == 'TabStop' lcPropName = 'A450' + lcPropName CASE lcPropName == 'TitleBar' lcPropName = 'A455' + lcPropName CASE lcPropName == 'WindowType' lcPropName = 'A460' + lcPropName CASE lcPropName == 'WindowState' lcPropName = 'A465' + lcPropName CASE lcPropName == 'LockScreen' lcPropName = 'A470' + lcPropName CASE lcPropName == 'AlwaysOnTop' lcPropName = 'A475' + lcPropName CASE lcPropName == 'AlwaysOnBottom' lcPropName = 'A480' + lcPropName CASE lcPropName == 'SizeBox' lcPropName = 'A485' + lcPropName CASE lcPropName == 'SpecialEffect' lcPropName = 'A490' + lcPropName CASE lcPropName == 'ZoomBox' lcPropName = 'A495' + lcPropName CASE lcPropName == 'ZOrderSet' lcPropName = 'A500' + lcPropName CASE lcPropName == 'HelpContextID' lcPropName = 'A505' + lcPropName CASE lcPropName == 'WhatsThisHelpID' lcPropName = 'A510' + lcPropName CASE lcPropName == 'WhatsThisHelp' lcPropName = 'A515' + lcPropName CASE lcPropName == 'WhatsThisButton' lcPropName = 'A520' + lcPropName CASE lcPropName == 'RightToLeft' lcPropName = 'A525' + lcPropName CASE lcPropName == 'DefOleLCID' lcPropName = 'A530' + lcPropName CASE lcPropName == 'MacDesktop' lcPropName = 'A535' + lcPropName CASE lcPropName == 'ColorSource' lcPropName = 'A540' + lcPropName CASE lcPropName == 'ForeColor' lcPropName = 'A545' + lcPropName CASE lcPropName == 'DisableForeColor' lcPropName = 'A550' + lcPropName CASE lcPropName == 'BackColor' lcPropName = 'A555' + lcPropName CASE lcPropName == 'FillColor' lcPropName = 'A560' + lcPropName CASE lcPropName == 'HScrollSmallChange' lcPropName = 'A565' + lcPropName CASE lcPropName == 'VScrollSmallChange' lcPropName = 'A570' + lcPropName CASE lcPropName == 'ContinuousScroll' lcPropName = 'A575' + lcPropName CASE lcPropName == 'Themes' lcPropName = 'A580' + lcPropName CASE lcPropName == 'BindControls' lcPropName = 'A585' + lcPropName CASE lcPropName == 'AllowOutput' lcPropName = 'A590' + lcPropName CASE lcPropName == 'Dockable' lcPropName = 'A595' + lcPropName CASE lcPropName == 'Name' lnPropType = 1 && System "Name" property lcPropName = 'A999' + lcPropName OTHERWISE lnPropType = 2 && User property lcPropName = 'A998' + lcPropName ENDCASE RETURN lcPropName ENDPROC ******************************************************************************************************************* PROCEDURE sortPropsAndValues * KNOWLEDGE BASE: * 02/12/2013 FDBOZZO Fidel Charny me pasó un ejemplo donde se pierden propiedades físicamente * si se ordenan alfabéticamente en un ADD OBJECT. Pierde "picture" y otras más. * Pareciera que la última debe ser "Name". *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taPropsAndValues (!@ IN ) El array con las propiedades y valores del objeto o clase * tnPropsAndValues_Count (!v IN ) Cantidad de propiedades * tnSortType (!v IN ) Tipo de sort: * 0=Solo separar propiedades de clase y de objetos (.) * 1=Sort completo de propiedades (para la versión TEXTO) * 2=Sort completo de propiedades con "Name" al final (para la versión BIN) *-------------------------------------------------------------------------------------------------------------- LPARAMETERS taPropsAndValues, tnPropsAndValues_Count, tnSortType EXTERNAL ARRAY taPropsAndValues TRY LOCAL I, X, lnArrayCols, laPropsAndValues(1,2), lcPropName lnArrayCols = ALEN( taPropsAndValues, 2 ) DIMENSION laPropsAndValues( tnPropsAndValues_Count, lnArrayCols ) ACOPY( taPropsAndValues, laPropsAndValues ) WITH THIS AS c_conversor_base OF 'FOXBIN2PRG.PRG' IF m.tnSortType >= 1 * CON SORT: * - A las que no tienen '.' les pongo 'A' por delante, y al resto 'B' por delante para que queden al final FOR I = 1 TO m.tnPropsAndValues_Count IF '.' $ laPropsAndValues(I,1) *IF m.tnSortType = 2 AND JUSTEXT( laPropsAndValues(I,1) ) == 'Name' * laPropsAndValues(I,1) = JUSTSTEM( laPropsAndValues(I,1) ) + '.' + CHR(255) + 'Name' *ENDIF *laPropsAndValues(I,1) = 'B' + laPropsAndValues(I,1) IF m.tnSortType = 2 laPropsAndValues(I,1) = 'B' + JUSTSTEM(laPropsAndValues(I,1)) + '.' ; + .sortPropsAndValues_SetAndGetSCXPropNames( 'SETNAME', JUSTEXT(laPropsAndValues(I,1)) ) ELSE laPropsAndValues(I,1) = 'B' + laPropsAndValues(I,1) ENDIF ELSE *IF m.tnSortType = 2 AND laPropsAndValues(I,1) == 'Name' * laPropsAndValues(I,1) = CHR(255) + 'Name' *ENDIF *laPropsAndValues(I,1) = 'A' + laPropsAndValues(I,1) IF m.tnSortType = 2 laPropsAndValues(I,1) = .sortPropsAndValues_SetAndGetSCXPropNames( 'SETNAME', laPropsAndValues(I,1) ) ELSE laPropsAndValues(I,1) = 'A' + laPropsAndValues(I,1) ENDIF ENDIF ENDFOR IF .l_PropSort_Enabled ASORT( laPropsAndValues, 1, -1, 0, 1) ENDIF FOR I = 1 TO m.tnPropsAndValues_Count *taPropsAndValues(I,1) = SUBSTR( laPropsAndValues(I,1), 2 ) && Quitar el carácter agregado *-- Quitar caracteres agregados antes del SORT IF '.' $ laPropsAndValues(I,1) IF m.tnSortType = 2 taPropsAndValues(I,1) = JUSTSTEM( SUBSTR( laPropsAndValues(I,1), 2 ) ) + '.' ; + .sortPropsAndValues_SetAndGetSCXPropNames( 'GETNAME', JUSTEXT(laPropsAndValues(I,1)) ) ELSE taPropsAndValues(I,1) = SUBSTR( laPropsAndValues(I,1), 2 ) ENDIF ELSE IF m.tnSortType = 2 taPropsAndValues(I,1) = .sortPropsAndValues_SetAndGetSCXPropNames( 'GETNAME', laPropsAndValues(I,1) ) ELSE taPropsAndValues(I,1) = SUBSTR( laPropsAndValues(I,1), 2 ) ENDIF ENDIF taPropsAndValues(I,2) = laPropsAndValues(I,2) IF lnArrayCols >= 3 taPropsAndValues(I,3) = laPropsAndValues(I,3) ENDIF *DO CASE *CASE m.tnSortType <> 2 * *-- Saltear *CASE taPropsAndValues(I,1) == CHR(255) + 'Name' * taPropsAndValues(I,1) = 'Name' *CASE JUSTEXT( taPropsAndValues(I,1) ) == CHR(255) + 'Name' * taPropsAndValues(I,1) = JUSTSTEM( taPropsAndValues(I,1) ) + '.Name' *ENDCASE ENDFOR ELSE && m.tnSortType = 0 *-- SIN SORT: Creo 2 arrays, el bueno y el temporal, y al terminar agrego el temporal al bueno. *-- Debo separar las props.normales de las de los objetos (ocurre cuando es un ADD OBJECT) X = 0 *-- PRIMERO las que no tienen punto FOR I = 1 TO m.tnPropsAndValues_Count IF EMPTY( laPropsAndValues(I,1) ) LOOP ENDIF IF NOT '.' $ laPropsAndValues(I,1) X = X + 1 taPropsAndValues(X,1) = laPropsAndValues(I,1) taPropsAndValues(X,2) = laPropsAndValues(I,2) IF lnArrayCols >= 3 taPropsAndValues(X,3) = laPropsAndValues(I,3) ENDIF ENDIF ENDFOR *-- LUEGO las demás props. FOR I = 1 TO m.tnPropsAndValues_Count IF EMPTY( laPropsAndValues(I,1) ) LOOP ENDIF IF '.' $ laPropsAndValues(I,1) X = X + 1 taPropsAndValues(X,1) = laPropsAndValues(I,1) taPropsAndValues(X,2) = laPropsAndValues(I,2) IF lnArrayCols >= 3 taPropsAndValues(X,3) = laPropsAndValues(I,3) ENDIF ENDIF ENDFOR ENDIF ENDWITH && THIS AS C_CONVERSOR_BASE OF 'FOXBIN2PRG.PRG' *-- VER ESTO SI HACE FALTA, SOBRE LO DE PONER LOS METODOS AL FINAL Y ADAPTAR *-- Agregar propiedades primero *FOR I = 1 TO m.tnPropsAndValues_Count * *-- SI HACE FALTA QUE LOS MÉTODOS ESTÉN AL FINAL, DESCOMENTAR ESTO (Y EL DE MÁS ARRIBA) * *IF LEFT(taPropsAndValues(I), 1) == '*' && Only Reserved3 have this * * lcMethods = m.lcMethods + m.taPropsAndValues(I,1) + ' = ' + m.taPropsAndValues(I,2) + CR_LF * * LOOP * *ENDIF * tcSortedMemo = m.tcSortedMemo + m.laPropsAndValues(I,1) + ' = ' + m.laPropsAndValues(I,2) + CR_LF *ENDFOR *-- Agregar métodos al final *tcSortedMemo = m.tcSortedMemo + m.lcMethods CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE writeLog LPARAMETERS tcText TRY THIS.c_TextLog = THIS.c_TextLog + TTOC(DATETIME(),3) + ' ' + EVL(tcText,'') + CR_LF CATCH ENDTRY ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_bin AS c_conversor_base #IF .F. LOCAL THIS AS c_conversor_prg_a_bin OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ******************************************************************************************************************* PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toModulo (@! OUT) Objeto generado de clase correspondiente con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toModulo, toEx AS EXCEPTION, toFoxbin2prg #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF DODEFAULT( @toModulo, @toEx ) ENDPROC ******************************************************************************************************************* FUNCTION get_ValueByName_FromListNamesWithValues *-- ASIGNO EL VALOR DEL ARRAY DE DATOS Y VALORES PARA LA PROPIEDAD INDICADA LPARAMETERS tcPropName, tcValueType, taPropsAndValues LOCAL lnPos, luPropValue lnPos = ASCAN( taPropsAndValues, tcPropName, 1, 0, 1, 1+2+4+8) IF lnPos = 0 OR EMPTY( taPropsAndValues( lnPos, 2 ) ) *-- Valores no encontrados o vacíos luPropValue = '' ELSE luPropValue = taPropsAndValues( lnPos, 2 ) ENDIF DO CASE CASE tcValueType = 'I' luPropValue = CAST( luPropValue AS INTEGER ) CASE tcValueType = 'N' luPropValue = CAST( luPropValue AS DOUBLE ) CASE tcValueType = 'T' luPropValue = CAST( luPropValue AS DATETIME ) CASE tcValueType = 'D' luPropValue = CAST( luPropValue AS DATE ) CASE tcValueType = 'E' luPropValue = EVALUATE( luPropValue ) OTHERWISE && Asumo 'C' para lo demás luPropValue = luPropValue ENDCASE RETURN luPropValue ENDFUNC ******************************************************************************************************************* PROCEDURE get_ListNamesWithValuesFrom_InLine_MetadataTag *-- OBTENGO EL ARRAY DE DATOS Y VALORES DE LA LINEA DE METADATOS INDICADA *-- NOTA: Los valores NO PUEDEN contener comillas dobles en su valor, ya que generaría un error al parsearlos. *-- Ejemplo: *< FileMetadata: Type="V" Cpid="1252" Timestamp="1131901580" ID="1129207528" ObjRev="544" /> *< OLE: Nombre="frm_form.Pageframe1.Page1.Cnt_controles_h.Olecontrol1" Parent="frm_form.Pageframe1.Page1.Cnt_controles_h" ObjName="Olecontrol1" Checksum="1685567300" Value="0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPg...ADAP7AAAA==" /> *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcLineWithMetadata (@! IN ) Línea con metadatos y un tag de metadatos * taPropsAndValues (@! OUT) Array a devolver con las propiedades y valores encontrados * tnPropsAndValues_Count (@! OUT) Cantidad de propiedades encontradas * tcLeftTag (v! IN ) TAG de inicio de los metadatos * tcRightTag (v! IN ) TAG de fin de los metadatos *-------------------------------------------------------------------------------------------------------------- LPARAMETERS tcLineWithMetadata, taPropsAndValues, tnPropsAndValues_Count, tcLeftTag, tcRightTag EXTERNAL ARRAY taPropsAndValues LOCAL lcMetadatos, I, X, lnEqualSigns, lcNextVar, lcStr, lcVirtualMeta, lnPos1, lnPos2, lnLastPos, lnCantComillas STORE '' TO lcVirtualMeta STORE 0 TO lnPos1, lnPos2, lnLastPos, tnPropsAndValues_Count, I, X lcMetadatos = ALLTRIM( STREXTRACT( tcLineWithMetadata, tcLeftTag, tcRightTag, 1, 1) ) lnCantComillas = OCCURS( '"', lcMetadatos ) IF lnCantComillas % 2 <> 0 && Valido que las comillas "" sean pares ERROR "Error de datos: No se puede parsear porque las comillas no son pares en la línea [" + lcMetadatos + "]" ENDIF lnLastPos = 1 DIMENSION taPropsAndValues( lnCantComillas / 2, 2 ) *------------------------------------------------------------------------------------- * IMPORTANTE!! * ------------ * SI SE SEPARAN LAS IGUALDADES CON ESPACIOS, ÉSTAS DEJAN DE RECONOCERSE!! (prop = "valor" en vez de prop="valor") * TENER EN CUENTA AL GENERAR EL TEXTO O AL MODIFICARLO MANUALMENTE AL MERGEAR *------------------------------------------------------------------------------------- FOR I = 1 TO lnCantComillas STEP 2 X = X + 1 * Type="V" Cpid="1252" * ^ ^ => Posiciones del par de comillas dobles lnPos1 = AT( '"', lcMetadatos, I ) lnPos2 = AT( '"', lcMetadatos, I + 1 ) * Type="V" Cpid="1252" * ^ ^ ^ => LastPos, lnPos1 y lnPos2 taPropsAndValues(X,1) = ALLTRIM( GETWORDNUM( SUBSTR( lcMetadatos, lnLastPos, lnPos1 - lnLastPos ), 1, '=' ) ) taPropsAndValues(X,2) = SUBSTR( lcMetadatos, lnPos1 + 1, lnPos2 - lnPos1 - 1 ) lnLastPos = lnPos2 + 1 ENDFOR RETURN ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeExclusion LPARAMETERS taCodeLines, tnCodeLines, ta_ID_Bloques, taBloquesExclusion, tnBloquesExclusion * LOS BLOQUES DE EXCLUSIÓN SON AQUELLOS QUE TIENEN TEXT/ENDTEXT OF #IF .F./#ENDIF Y SE USAN PARA NO BUSCAR * INSTRUCCIONES COMO "DEFINE CLASS" O "PROCEDURE" EN LOS MISMOS. *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código de texto donde buscar * tnCodeLines (?@ IN ) Cantidad de líneas de código * ta_ID_Bloques (?@ IN ) Array de pares de identificadores (2 cols). Ej: '#IF .F.','#ENDI' ; 'TEXT','ENDTEXT' ; etc * taBloquesExclusion (?@ OUT) Array con las posiciones de los bloques (2 cols). Ej: 3,14 ; 23,58 ; etc * tnBloquesExclusion (?@ OUT) Cantidad de bloques de exclusión *-------------------------------------------------------------------------------------------------------------- EXTERNAL ARRAY ta_ID_Bloques, taBloquesExclusion TRY LOCAL lnBloques, I, X, lnPrimerID, lnLen_IDFinBQ DIMENSION taBloquesExclusion(1,2) STORE 0 TO tnBloquesExclusion, lnPrimerID, I, X, lnLen_IDFinBQ IF tnCodeLines > 1 IF EMPTY(ta_ID_Bloques) DIMENSION ta_ID_Bloques(2,2) ta_ID_Bloques(1,1) = '#IF .F.' ta_ID_Bloques(1,2) = '#ENDI' ta_ID_Bloques(2,1) = C_TEXT ta_ID_Bloques(2,2) = C_ENDTEXT ENDIF *-- Búsqueda del ID de inicio de bloque FOR I = 1 TO tnCodeLines lcLine = LTRIM( STRTRAN( STRTRAN( CHRTRAN( taCodeLines(I), CHR(9), ' ' ), ' ', ' ' ), ' ', ' ' ) ) && Reduzco los espacios. Ej: '#IF .F. && cmt' ==> '#IF .F.&&cmt' IF THIS.lineIsOnlyCommentAndNoMetadata( @lcLine ) LOOP ENDIF lnPrimerID = ASCAN( ta_ID_Bloques, lcLine, 1, 0, 1, 1+8 ) IF lnPrimerID > 0 && Se ha identificado un ID de bloque excluyente tnBloquesExclusion = tnBloquesExclusion + 1 lnLen_IDFinBQ = LEN( ta_ID_Bloques(lnPrimerID,2) ) DIMENSION taBloquesExclusion(tnBloquesExclusion,2) taBloquesExclusion(tnBloquesExclusion,1) = I * Búsqueda del ID de fin de bloque FOR I = I + 1 TO tnCodeLines lcLine = LTRIM( STRTRAN( STRTRAN( CHRTRAN( taCodeLines(I), CHR(9), ' ' ), ' ', ' ' ), ' ', ' ' ) ) && Reduzco los espacios. Ej: '#IF .F. && cmt' ==> '#IF .F.&&cmt' IF THIS.lineIsOnlyCommentAndNoMetadata( @lcLine ) LOOP ENDIF IF LEFT( lcLine, lnLen_IDFinBQ ) == ta_ID_Bloques(lnPrimerID,2) && Fin de bloque encontrado (#ENDI, ENDTEXT, etc) taBloquesExclusion(tnBloquesExclusion,2) = I EXIT ENDIF ENDFOR *-- Validación IF EMPTY(taBloquesExclusion(tnBloquesExclusion,2)) ERROR 'No se ha encontrado el marcador de fin [' + ta_ID_Bloques(lnPrimerID,2) ; + '] que cierra al marcador de inicio [' + ta_ID_Bloques(lnPrimerID,1) ; + '] de la línea ' + TRANSFORM(taBloquesExclusion(tnBloquesExclusion,1)) ENDIF ENDIF ENDFOR ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_FoxBin2Prg *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toModulo, tcLine, taCodeLines, I, tnCodeLines LOCAL llBloqueEncontrado, laPropsAndValues(1,2), lnPropsAndValues_Count IF LEFT( tcLine + ' ', LEN(C_FB2PRG_META_I) + 1 ) == C_FB2PRG_META_I + ' ' llBloqueEncontrado = .T. *-- Metadatos del módulo THIS.get_ListNamesWithValuesFrom_InLine_MetadataTag( @tcLine, @laPropsAndValues, @lnPropsAndValues_Count, C_FB2PRG_META_I, C_FB2PRG_META_F ) toModulo._Version = THIS.get_ValueByName_FromListNamesWithValues( 'Version', 'N', @laPropsAndValues ) toModulo._SourceFile = THIS.get_ValueByName_FromListNamesWithValues( 'SourceFile', 'C', @laPropsAndValues ) ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE createProject CREATE TABLE (THIS.c_OutputFile) ; ( NAME M ; , TYPE C(1) ; , ID N(10) ; , TIMESTAMP N(10) ; , OUTFILE M ; , HOMEDIR M ; , EXCLUDE L ; , MAINPROG L ; , SAVECODE L ; , DEBUG L ; , ENCRYPT L ; , NOLOGO L ; , CMNTSTYLE N(1) ; , OBJREV N(5) ; , DEVINFO M ; , SYMBOLS M ; , OBJECT M ; , CKVAL N(6) ; , CPID N(5) ; , OSTYPE C(4) ; , OSCREATOR C(4) ; , COMMENTS M ; , RESERVED1 M ; , RESERVED2 M ; , SCCDATA M ; , LOCAL L ; , KEY C(32) ; , USER M ) USE (THIS.c_OutputFile) ALIAS TABLABIN AGAIN SHARED ENDPROC ******************************************************************************************************************* PROCEDURE createProject_RecordHeader LPARAMETERS toProject #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF INSERT INTO TABLABIN ; ( NAME ; , TYPE ; , TIMESTAMP ; , OUTFILE ; , HOMEDIR ; , SAVECODE ; , DEBUG ; , ENCRYPT ; , NOLOGO ; , CMNTSTYLE ; , OBJREV ; , DEVINFO ; , OBJECT ; , RESERVED1 ; , RESERVED2 ; , LOCAL ; , KEY ) ; VALUES ; ( UPPER(THIS.c_OutputFile) ; , 'H' ; , 0 ; , '' + CHR(0) ; , toProject._HomeDir + CHR(0) ; , toProject._SaveCode ; , toProject._Debug ; , toProject._Encrypted ; , toProject._NoLogo ; , toProject._CmntStyle ; , 260 ; , toProject.getRowDeviceInfo() ; , toProject._HomeDir + CHR(0) ; , UPPER(THIS.c_OutputFile) ; , toProject._ServerHead.getRowServerInfo() ; , .T. ; , UPPER( JUSTSTEM( THIS.c_OutputFile) ) ) ENDPROC ******************************************************************************************************************* PROCEDURE createClasslib CREATE TABLE (THIS.c_OutputFile) ; ( PLATFORM C(8) ; , UNIQUEID C(10) ; , TIMESTAMP N(10) ; , CLASS M ; , CLASSLOC M ; , BASECLASS M ; , OBJNAME M ; , PARENT M ; , PROPERTIES M ; , PROTECTED M ; , METHODS M ; , OBJCODE M NOCPTRANS ; , OLE M ; , OLE2 M ; , RESERVED1 M ; , RESERVED2 M ; , RESERVED3 M ; , RESERVED4 M ; , RESERVED5 M ; , RESERVED6 M ; , RESERVED7 M ; , RESERVED8 M ; , USER M ) USE (THIS.c_OutputFile) ALIAS TABLABIN AGAIN SHARED ENDPROC ******************************************************************************************************************* PROCEDURE createClasslib_RecordHeader INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , RESERVED1 ) ; VALUES ; ( 'COMMENT' ; , 'Class' ; , 'VERSION = 3.00' ) ENDPROC ******************************************************************************************************************* PROCEDURE createForm CREATE TABLE (THIS.c_OutputFile) ; ( PLATFORM C(8) ; , UNIQUEID C(10) ; , TIMESTAMP N(10) ; , CLASS M ; , CLASSLOC M ; , BASECLASS M ; , OBJNAME M ; , PARENT M ; , PROPERTIES M ; , PROTECTED M ; , METHODS M ; , OBJCODE M NOCPTRANS ; , OLE M ; , OLE2 M ; , RESERVED1 M ; , RESERVED2 M ; , RESERVED3 M ; , RESERVED4 M ; , RESERVED5 M ; , RESERVED6 M ; , RESERVED7 M ; , RESERVED8 M ; , USER M ) USE (THIS.c_OutputFile) ALIAS TABLABIN AGAIN SHARED ENDPROC ******************************************************************************************************************* PROCEDURE createForm_RecordHeader INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , RESERVED1 ) ; VALUES ; ( 'COMMENT' ; , 'Screen' ; , 'VERSION = 3.00' ) ENDPROC ******************************************************************************************************************* PROCEDURE createReport CREATE TABLE (THIS.c_OutputFile) ; ( 'PLATFORM' C(8) ; , 'UNIQUEID' C(10) ; , 'TIMESTAMP' N(10) ; , 'OBJTYPE' N(2) ; , 'OBJCODE' N(3) ; , 'NAME' M ; , 'EXPR' M ; , 'VPOS' N(9,3) ; , 'HPOS' N(9,3) ; , 'HEIGHT' N(9,3) ; , 'WIDTH' N(9,3) ; , 'STYLE' M ; , 'PICTURE' M ; , 'ORDER' M NOCPTRANS ; , 'UNIQUE' L ; , 'COMMENT' M ; , 'ENVIRON' L ; , 'BOXCHAR' C(1) ; , 'FILLCHAR' C(1) ; , 'TAG' M ; , 'TAG2' M NOCPTRANS ; , 'PENRED' N(5) ; , 'PENGREEN' N(5) ; , 'PENBLUE' N(5) ; , 'FILLRED' N(5) ; , 'FILLGREEN' N(5) ; , 'FILLBLUE' N(5) ; , 'PENSIZE' N(5) ; , 'PENPAT' N(5) ; , 'FILLPAT' N(5) ; , 'FONTFACE' M ; , 'FONTSTYLE' N(3) ; , 'FONTSIZE' N(3) ; , 'MODE' N(3) ; , 'RULER' N(1) ; , 'RULERLINES' N(1) ; , 'GRID' L ; , 'GRIDV' N(2) ; , 'GRIDH' N(2) ; , 'FLOAT' L ; , 'STRETCH' L ; , 'STRETCHTOP' L ; , 'TOP' L ; , 'BOTTOM' L ; , 'SUPTYPE' N(1) ; , 'SUPREST' N(1) ; , 'NOREPEAT' L ; , 'RESETRPT' N(2) ; , 'PAGEBREAK' L ; , 'COLBREAK' L ; , 'RESETPAGE' L ; , 'GENERAL' N(3) ; , 'SPACING' N(3) ; , 'DOUBLE' L ; , 'SWAPHEADER' L ; , 'SWAPFOOTER' L ; , 'EJECTBEFOR' L ; , 'EJECTAFTER' L ; , 'PLAIN' L ; , 'SUMMARY' L ; , 'ADDALIAS' L ; , 'OFFSET' N(3) ; , 'TOPMARGIN' N(3) ; , 'BOTMARGIN' N(3) ; , 'TOTALTYPE' N(2) ; , 'RESETTOTAL' N(2) ; , 'RESOID' N(3) ; , 'CURPOS' L ; , 'SUPALWAYS' L ; , 'SUPOVFLOW' L ; , 'SUPRPCOL' N(1) ; , 'SUPGROUP' N(2) ; , 'SUPVALCHNG' L ; , 'SUPEXPR' M ; , 'USER' M ) USE (THIS.c_OutputFile) ALIAS TABLABIN AGAIN SHARED ENDPROC ******************************************************************************************************************* PROCEDURE createMenu CREATE TABLE (THIS.c_OutputFile) ; ( 'OBJTYPE' Numeric(2) ; , 'OBJCODE' Numeric(2) ; , 'NAME' MEMO ; , 'PROMPT' MEMO ; , 'COMMAND' MEMO ; , 'MESSAGE' MEMO ; , 'PROCTYPE' Numeric(1) ; , 'PROCEDURE' MEMO ; , 'SETUPTYPE' Numeric(1) ; , 'SETUP' MEMO ; , 'CLEANTYPE' Numeric(1) ; , 'CLEANUP' MEMO ; , 'MARK' CHARACTER(1) ; , 'KEYNAME' MEMO ; , 'KEYLABEL' MEMO ; , 'SKIPFOR' MEMO ; , 'NAMECHANGE' Logical ; , 'NUMITEMS' Numeric(2) ; , 'LEVELNAME' CHARACTER(10) ; , 'ITEMNUM' CHARACTER(3) ; , 'COMMENT' MEMORY(4) ; , 'LOCATION' Numeric(2) ; , 'SCHEME' Numeric(2) ; , 'SYSRES' Numeric(1) ; , 'RESNAME' MEMORY(4) ) USE (THIS.c_OutputFile) ALIAS TABLABIN AGAIN SHARED ENDPROC ******************************************************************************************************************* PROCEDURE emptyRecord LOCAL loReg SCATTER MEMO BLANK NAME loReg RETURN loReg ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toModulo ENDPROC ******************************************************************************************************************* PROCEDURE classProps2Memo *-- ARMA EL MEMO DE PROPERTIES CON LAS PROPIEDADES Y SUS VALORES LPARAMETERS toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF *-- ESTRUCTURA A ANALIZAR: Propiedades normales, con CR codificado () y con CR+LF () #IF .F. HEIGHT = 2.73 NAME = "c1" prop1 = .F. && Mi prop 1 prop_especial_cr = Este es el valor 1 Este el 2 Y Este bajo Shift_Enter el 3 prop_especial_crlf = Este es el valor 1 Este el 2 Y Este bajo Shift_Enter el 3 WIDTH = 27.40 _MEMBERDATA = && XML Metadata for customizable properties #ENDIF *-- Fin: ESTRUCTURA A ANALIZAR: TRY LOCAL lcDefinedPAM, lnPos, lnPos2, laProps(1,2), lcLine, lcPropName, lcValue, I, lcAsignacion, lcMemo ; , laPropsAndValues(1,2), lnPropsAndValues_Count lcMemo = '' IF toClase._Prop_Count > 0 DIMENSION laPropsAndValues( toClase._Prop_Count, 3 ) ACOPY( toClase._Props, laPropsAndValues ) lnPropsAndValues_Count = toClase._Prop_Count *-- REORDENO LAS PROPIEDADES THIS.sortPropsAndValues( @laPropsAndValues, lnPropsAndValues_Count, 2 ) *-- ARMO EL MEMO A DEVOLVER FOR I = 1 TO lnPropsAndValues_Count lcMemo = lcMemo + laPropsAndValues(I,1) + ' = ' + laPropsAndValues(I,2) + CR_LF ENDFOR ENDIF && laProps > 0 CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lcMemo ENDPROC ******************************************************************************************************************* PROCEDURE objectProps2Memo *-- ARMA EL MEMO DE PROPERTIES CON LAS PROPIEDADES Y SUS VALORES LPARAMETERS toObjeto, toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' ; , toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL lcMemo, I, laPropsAndValues(1,2), lcPropName, lcValue lcMemo = '' IF toObjeto._Prop_Count > 0 DIMENSION laPropsAndValues( toObjeto._Prop_Count, 2 ) ACOPY( toObjeto._Props, laPropsAndValues ) *-- REORDENO LAS PROPIEDADES THIS.sortPropsAndValues( @laPropsAndValues, toObjeto._Prop_Count, 2 ) *-- ARMO EL MEMO A DEVOLVER FOR I = 1 TO toObjeto._Prop_Count lcMemo = lcMemo + laPropsAndValues(I,1) + ' = ' + laPropsAndValues(I,2) + CR_LF ENDFOR ENDIF RETURN lcMemo ENDPROC ******************************************************************************************************************* PROCEDURE classMethods2Memo LPARAMETERS toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL lcMemo, I, X, lcNombreObjeto ; , loProcedure AS CL_PROCEDURE OF 'FOXBIN2PRG.PRG' lcMemo = '' *-- Recorrer los métodos FOR I = 1 TO toClase._Procedure_Count loProcedure = NULL loProcedure = toClase._Procedures(I) IF '.' $ loProcedure._Nombre *-- cboNombre.InteractiveChange ==> No debe acortarse por ser método modificado de combobox heredado de la clase *-- cntDatos.txtEdad.Valid ==> Debe acortarse si cntDatos es un objeto existente lcNombreObjeto = LEFT( loProcedure._Nombre, AT('.', loProcedure._Nombre) - 1 ) IF THIS.buscarObjetoDelMetodoPorNombre( lcNombreObjeto, toClase ) = 0 TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <> ENDTEXT ELSE TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <> ENDTEXT ENDIF ELSE TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <> ENDTEXT ENDIF *-- Incluir las líneas del método FOR X = 1 TO loProcedure._ProcLine_Count TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <> ENDTEXT ENDFOR TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <> <<>> ENDTEXT ENDFOR loProcedure = NULL RELEASE loProcedure RETURN lcMemo ENDPROC ******************************************************************************************************************* PROCEDURE objectMethods2Memo LPARAMETERS toObjeto, toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' ; , toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL lcMemo, I, X, lcNombreObjeto ; , loProcedure AS CL_PROCEDURE OF 'FOXBIN2PRG.PRG' lcMemo = '' *-- Recorrer los métodos FOR I = 1 TO toObjeto._Procedure_Count loProcedure = NULL loProcedure = toObjeto._Procedures(I) TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <> ENDTEXT *-- Incluir las líneas del método FOR X = 1 TO loProcedure._ProcLine_Count TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <> ENDTEXT ENDFOR TEXT TO lcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <> <<>> ENDTEXT ENDFOR loProcedure = NULL RELEASE loProcedure RETURN lcMemo ENDPROC ******************************************************************************************************************* PROCEDURE getClassPropertyComment *-- Devuelve el comentario (columna 2 del array toClase._Props) de la propiedad indicada, *-- buscándola en la columna 2 por su nombre. LPARAMETERS tcPropName AS STRING, toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL I, lcComentario lcComentario = '' FOR I = 1 TO toClase._Prop_Count IF RTRIM( GETWORDNUM( toClase._Props(I,1), 1, '=' ) ) == tcPropName lcComentario = toClase._Props( I, 2 ) EXIT ENDIF ENDFOR RETURN lcComentario ENDPROC ******************************************************************************************************************* PROCEDURE getClassMethodComment LPARAMETERS tcMethodName AS STRING, toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL I, lcComentario ; , loProcedure AS CL_PROCEDURE OF 'FOXBIN2PRG.PRG' lcComentario = '' FOR I = 1 TO toClase._Procedure_Count loProcedure = toClase._Procedures(I) IF loProcedure._Nombre == tcMethodName lcComentario = loProcedure._Comentario EXIT ENDIF ENDFOR RETURN lcComentario ENDPROC ******************************************************************************************************************* PROCEDURE getTextFrom_BIN_FileStructure TRY LOCAL lcStructure, lnSelect lnSelect = SELECT() SELECT 0 USE (THIS.c_InputFile) AGAIN SHARED ALIAS _TABLABIN COPY STRUCTURE EXTENDED TO ( FORCEPATH( '_FRX_STRUC.DBF', ADDBS( SYS(2023) ) ) ) **** CONTINUAR SI ES NECESARIO - SIN USO POR AHORA CATCH TO loEx THROW FINALLY USE IN (SELECT("_TABLABIN")) SELECT (lnSelect) ENDTRY RETURN lcStructure ENDPROC ******************************************************************************************************************* PROCEDURE defined_PAM2Memo LPARAMETERS toClase RETURN toClase._Defined_PAM ENDPROC ******************************************************************************************************************* PROCEDURE strip_Dimensions LPARAMETERS tcSeparatedCommaVars LOCAL lnPos1, lnPos2, I FOR I = OCCURS( '[', tcSeparatedCommaVars ) TO 1 STEP -1 lnPos1 = AT( '[', tcSeparatedCommaVars, I ) lnPos2 = AT( ']', tcSeparatedCommaVars, I ) tcSeparatedCommaVars = STUFF( tcSeparatedCommaVars, lnPos1, lnPos2 - lnPos1 + 1, '' ) ENDFOR ENDPROC ******************************************************************************************************************* PROCEDURE hiddenAndProtected_PAM LPARAMETERS toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL lcMemo, I, lcPAM, lcComentario lcMemo = '' THIS.Evaluate_PAM( @lcMemo, toClase._ProtectedProps, 'property', 'protected' ) THIS.Evaluate_PAM( @lcMemo, toClase._HiddenProps, 'property', 'hidden' ) THIS.Evaluate_PAM( @lcMemo, toClase._ProtectedMethods, 'method', 'protected' ) THIS.Evaluate_PAM( @lcMemo, toClase._HiddenMethods, 'method', 'hidden' ) RETURN lcMemo ENDPROC ******************************************************************************************************************* PROCEDURE Evaluate_PAM LPARAMETERS tcMemo AS STRING, tcPAM AS STRING, tcPAM_Type AS STRING, tcPAM_Visibility AS STRING LOCAL lcPAM, I FOR I = 1 TO OCCURS( ',', tcPAM + ',' ) lcPAM = ALLTRIM( GETWORDNUM( tcPAM, I, ',' ) ) IF NOT EMPTY(lcPAM) IF EVL(tcPAM_Visibility, 'normal') == 'hidden' lcPAM = lcPAM + '^' ENDIF TEXT TO tcMemo ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> <<>> ENDTEXT ENDIF ENDFOR ENDPROC ******************************************************************************************************************* PROCEDURE insert_Object LPARAMETERS toClase, toObjeto IF NOT THIS.l_Test *-- Inserto el objeto INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , TIMESTAMP ; , CLASS ; , CLASSLOC ; , BASECLASS ; , OBJNAME ; , PARENT ; , PROPERTIES ; , PROTECTED ; , METHODS ; , OLE ; , OLE2 ; , RESERVED1 ; , RESERVED2 ; , RESERVED3 ; , RESERVED4 ; , RESERVED5 ; , RESERVED6 ; , RESERVED7 ; , RESERVED8 ; , USER) ; VALUES ; ( 'WINDOWS' ; , toObjeto._UniqueID ; , toObjeto._TimeStamp ; , toObjeto._Class ; , toObjeto._ClassLib ; , toObjeto._BaseClass ; , toObjeto._ObjName ; , toObjeto._Parent ; , THIS.objectProps2Memo( toObjeto, toClase ) ; , '' ; , THIS.objectMethods2Memo( toObjeto, toClase ) ; , toObjeto._Ole ; , toObjeto._Ole2 ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , toObjeto._User ) ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE insert_AllObjects *-- Recorro primero los objetos con ZOrder definido, y luego los demás *-- NOTA: Como consecuencia de una integración de código, puede que se hayan agregado objetos nuevos (desconocidos), *-- pero todo lo demás tiene un ZOrder definido, que es el número de registro original * 100. LPARAMETERS toClase #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL N, X, lcObjName, loObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' IF toClase._AddObject_Count > 0 N = 0 *-- Armo array con el orden Z de los objetos DIMENSION laObjNames( toClase._AddObject_Count, 2 ) FOR X = 1 TO toClase._AddObject_Count loObjeto = toClase._AddObjects( X ) laObjNames( X, 1 ) = loObjeto._Nombre laObjNames( X, 2 ) = loObjeto._ZOrder ENDFOR ASORT( laObjNames, 2, -1, 0, 1 ) *-- Escribo los objetos en el orden Z FOR X = 1 TO toClase._AddObject_Count lcObjName = laObjNames( X, 1 ) FOR EACH loObjeto IN toClase._AddObjects FOXOBJECT *-- Verifico que sea el objeto que corresponde IF loObjeto._WriteOrder = 0 AND loObjeto._Nombre == lcObjName N = N + 1 loObjeto._WriteOrder = N THIS.insert_Object( toClase, loObjeto ) EXIT ENDIF ENDFOR ENDFOR *-- Recorro los objetos Desconocidos FOR EACH loObjeto IN toClase._AddObjects FOXOBJECT IF loObjeto._WriteOrder = 0 THIS.insert_Object( toClase, loObjeto ) ENDIF ENDFOR ENDIF && toClase._AddObject_Count > 0 CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE set_Line LPARAMETERS tcLine, taCodeLines, I tcLine = LTRIM( taCodeLines(I), 0, ' ', CHR(9) ) ENDPROC ******************************************************************************************************************* PROCEDURE analizarLineasDeProcedure LPARAMETERS toClase, toObjeto, tcLine, taCodeLines, I, tnCodeLines, tcProcedureAbierto, tc_Comentario ; , taBloquesExclusion, tnBloquesExclusion EXTERNAL ARRAY taCodeLines #IF .F. LOCAL toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llEsProcedureDeClase, loProcedure AS CL_PROCEDURE OF 'FOXBIN2PRG.PRG' IF '.' $ tcProcedureAbierto AND VARTYPE(toObjeto) = 'O' AND toObjeto._Procedure_Count > 0 loProcedure = toObjeto._Procedures(toObjeto._Procedure_Count) ELSE llEsProcedureDeClase = .T. loProcedure = toClase._Procedures(toClase._Procedure_Count) ENDIF WITH THIS FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) IF NOT .lineaExcluida( I, tnBloquesExclusion, @taBloquesExclusion ) ; AND NOT .lineIsOnlyCommentAndNoMetadata( @tcLine, @tc_Comentario ) DO CASE CASE LEFT( tcLine, 8 ) + ' ' == C_ENDPROC + ' ' && Fin del PROCEDURE tcProcedureAbierto = '' EXIT CASE LEFT( tcLine + ' ', 10 ) == C_ENDDEFINE + ' ' && Fin de bloque (ENDDEFINE) encontrado IF llEsProcedureDeClase ERROR 'Error de anidamiento de estructuras. Se esperaba ENDPROC y se encontró ENDDEFINE en la clase ' ; + toClase._Nombre + ' (' + loProcedure._Nombre + ')' ; + ', línea ' + TRANSFORM(I) + ' del archivo ' + THIS.c_InputFile ELSE ERROR 'Error de anidamiento de estructuras. Se esperaba ENDPROC y se encontró ENDDEFINE en la clase ' ; + toClase._Nombre + ' (' + toObjeto._Nombre + '.' + loProcedure._Nombre + ')' ; + ', línea ' + TRANSFORM(I) + ' del archivo ' + THIS.c_InputFile ENDIF ENDCASE ENDIF *-- Quito 2 TABS de la izquierda (si se puede y si el integrador/desarrollador no la lió quitándolos) DO CASE CASE LEFT( taCodeLines(I),2 ) = C_TAB + C_TAB loProcedure.add_Line( SUBSTR(taCodeLines(I), 3) ) CASE LEFT( taCodeLines(I),1 ) = C_TAB loProcedure.add_Line( SUBSTR(taCodeLines(I), 2) ) OTHERWISE loProcedure.add_Line( taCodeLines(I) ) ENDCASE ENDFOR ENDWITH && THIS CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ADD_OBJECT LPARAMETERS toModulo, toClase, tcLine, I, taCodeLines, tnCodeLines EXTERNAL ARRAY taCodeLines #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' LOCAL toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado IF LEFT( tcLine, 11 ) == 'ADD OBJECT ' *-- Estructura a reconocer: ADD OBJECT 'frm_a.Check1' AS check [WITH] llBloqueEncontrado = .T. LOCAL laPropsAndValues(1,2), lnPropsAndValues_Count, Z, lcProp, lcValue tcLine = CHRTRAN( tcLine, ['], ["] ) IF EMPTY(toClase._Fin_Cab) toClase._Fin_Cab = I-1 toClase._Ini_Cuerpo = I ENDIF toObjeto = NULL toObjeto = CREATEOBJECT('CL_OBJETO') toClase.add_Object( toObjeto ) toObjeto._Nombre = ALLTRIM( CHRTRAN( STREXTRACT(tcLine, 'ADD OBJECT ', ' AS ', 1, 1), ['"], [] ) ) IF '.' $ toObjeto._Nombre toObjeto._ObjName = JUSTEXT( toObjeto._Nombre ) toObjeto._Parent = toClase._ObjName + '.' + JUSTSTEM( toObjeto._Nombre ) ELSE toObjeto._ObjName = toObjeto._Nombre toObjeto._Parent = toClase._ObjName ENDIF toObjeto._Nombre = toObjeto._Parent + '.' + toObjeto._ObjName toObjeto._Class = ALLTRIM( STREXTRACT(tcLine + ' WITH', ' AS ', ' WITH', 1, 1) ) *-- Propiedades del ADD OBJECT WITH THIS FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) IF LEFT( tcLine, C_LEN_END_OBJECT_I) == C_END_OBJECT_I && Fin del ADD OBJECT y METADATOS *< END OBJECT: baseclass = "olecontrol" Uniqueid = "_3X50L3I7V" OLEObject = "C:\WINDOWS\system32\FOXTLIB.OCX" checksum = "4101493921" /> .get_ListNamesWithValuesFrom_InLine_MetadataTag( @tcLine, @laPropsAndValues, @lnPropsAndValues_Count ; , C_END_OBJECT_I, C_END_OBJECT_F ) toObjeto._ClassLib = .get_ValueByName_FromListNamesWithValues( 'ClassLib', 'C', @laPropsAndValues ) toObjeto._BaseClass = .get_ValueByName_FromListNamesWithValues( 'BaseClass', 'C', @laPropsAndValues ) toObjeto._UniqueID = .get_ValueByName_FromListNamesWithValues( 'UniqueID', 'C', @laPropsAndValues ) toObjeto._Ole2 = .get_ValueByName_FromListNamesWithValues( 'OLEObject', 'C', @laPropsAndValues ) toObjeto._ZOrder = .get_ValueByName_FromListNamesWithValues( 'ZOrder', 'I', @laPropsAndValues ) toObjeto._TimeStamp = INT( .RowTimeStamp( .get_ValueByName_FromListNamesWithValues( 'TimeStamp', 'T', @laPropsAndValues ) ) ) IF NOT EMPTY( toObjeto._Ole2 ) && Le agrego "OLEObject = " delante toObjeto._Ole2 = 'OLEObject = ' + toObjeto._Ole2 + CR_LF ENDIF *-- Ubico el objeto ole por su nombre (parent+objname), que no se repite. IF toModulo.existeObjetoOLE( toObjeto._Nombre, @Z ) toObjeto._Ole = toModulo._Ole_Objs(Z)._Value ENDIF EXIT ENDIF IF RIGHT(tcLine, 3) == ', ;' && VALOR INTERMEDIO CON ", ;" *toObjeto.add_Property( .desnormalizarAsignacion( LEFT(tcLine, LEN(tcLine) - 3) ) ) .get_SeparatedPropAndValue( LEFT(tcLine, LEN(tcLine) - 3), @lcProp, @lcValue ) toObjeto.add_Property( @lcProp, @lcValue ) ELSE && VALOR FINAL SIN ", ;" (JUSTO ANTES DEL ) *toObjeto.add_Property( .desnormalizarAsignacion( RTRIM(tcLine) ) ) .get_SeparatedPropAndValue( RTRIM(tcLine), @lcProp, @lcValue ) toObjeto.add_Property( @lcProp, @lcValue ) ENDIF ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_DEFINED_PAM *-- ESTRUCTURA A ANALIZAR: * *m: *metodovacio_con_comentarios && Este método no tiene código, pero tiene comentarios. A ver que pasa! *m: *mimetodo && Mi metodo *p: prop1 && Mi prop 1 *p: prop_especial_cr && *a: ^array_1_d[1,0] && Array 1 dimensión (1) *a: ^array_2_d[1,2] && Array una dimension (1,2) *p: _memberdata && XML Metadata for customizable properties * LPARAMETERS toClase, tcLine, taCodeLines, tnCodeLines, I #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcDefinedPAM, lnPos, lnPos2, lcPAM_Name IF LEFT( tcLine, C_LEN_DEFINED_PAM_I) == C_DEFINED_PAM_I llBloqueEncontrado = .T. lcDefinedPAM = '' WITH THIS FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, C_LEN_DEFINED_PAM_F ) == C_DEFINED_PAM_F I = I + 1 EXIT OTHERWISE lnPos = AT( ' ', tcLine, 1 ) lnPos2 = AT( '&'+'&', tcLine ) IF lnPos2 > 0 *-- Con comentarios lcPAM_Name = RTRIM( SUBSTR( tcLine, lnPos+1, lnPos2 - lnPos - 1 ), 0, ' ', CHR(9) ) lcDefinedPAM = lcDefinedPAM ; + lcPAM_Name + ' ' + SUBSTR( tcLine, lnPos2 + 3 ) ; + CR_LF ELSE *-- Sin comentarios lcPAM_Name = RTRIM( SUBSTR( tcLine, lnPos+1 ), 0, ' ', CHR(9) ) lcDefinedPAM = lcDefinedPAM ; + lcPAM_Name + IIF(ISALPHA(lcPAM_Name), '', ' ') ; + CR_LF ENDIF ENDCASE ENDFOR ENDWITH && THIS toClase._Defined_PAM = lcDefinedPAM I = I - 1 ENDIF CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_DEFINE_CLASS LPARAMETERS toModulo, toClase, tcLine, taCodeLines, I, tnCodeLines, tcProcedureAbierto ; , taBloquesExclusion, tnBloquesExclusion, tc_Comentario EXTERNAL ARRAY taCodeLines, tnBloquesExclusion, taBloquesExclusion #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado IF LEFT(tcLine + ' ', 13) == C_DEFINE_CLASS + ' ' TRY llBloqueEncontrado = .T. LOCAL Z, lcProp, lcValue, loEx AS EXCEPTION ; , llMETADATA_Completed, llPROTECTED_Completed, llHIDDEN_Completed, llDEFINED_PAM_Completed ; , llINCLUDE_Completed, llCLASS_PROPERTY_Completed ; , loObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' STORE '' TO tcProcedureAbierto toClase = CREATEOBJECT('CL_CLASE') toClase._Nombre = ALLTRIM( STREXTRACT( tcLine, 'DEFINE CLASS ', ' AS ', 1, 1 ) ) toClase._ObjName = toClase._Nombre toClase._Definicion = ALLTRIM( tcLine ) IF NOT ' OF ' $ UPPER(tcLine) && Puede no tener "OF libreria.vcx" toClase._Class = ALLTRIM( CHRTRAN( STREXTRACT( tcLine + ' OLEPUBLIC', ' AS ', ' OLEPUBLIC', 1, 1 ), ["'], [] ) ) ELSE toClase._Class = ALLTRIM( CHRTRAN( STREXTRACT( tcLine + ' OF ', ' AS ', ' OF ', 1, 1 ), ["'], [] ) ) ENDIF toClase._ClassLoc = ALLTRIM( CHRTRAN( STREXTRACT( tcLine + ' OLEPUBLIC', ' OF ', ' OLEPUBLIC', 1, 1 ), ["'], [] ) ) toClase._OlePublic = ' OLEPUBLIC' $ UPPER(tcLine) toClase._Comentario = tc_Comentario toClase._Inicio = I toClase._Ini_Cab = I + 1 toModulo.add_Class( toClase ) *-- Ubico el objeto ole por su nombre (parent+objname), que no se repite. IF toModulo.existeObjetoOLE( toClase._Nombre, @Z ) toClase._Ole = toModulo._Ole_Objs(Z)._Value ENDIF * Búsqueda del ID de fin de bloque (ENDDEFINE) WITH THIS FOR I = toClase._Ini_Cab TO tnCodeLines tc_Comentario = '' .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE .lineIsOnlyCommentAndNoMetadata( @tcLine, @tc_Comentario ) LOOP CASE .analizarBloque_PROCEDURE( @toModulo, @toClase, @loObjeto, @tcLine, @taCodeLines, @I, @tnCodeLines ; , @tcProcedureAbierto, @tc_Comentario, @taBloquesExclusion, @tnBloquesExclusion ) *-- OJO: Esta se analiza primero a propósito, solo porque no puede estar detrás de PROTECTED y HIDDEN llCLASS_PROPERTY_Completed = .T. llPROTECTED_Completed = .T. llHIDDEN_Completed = .T. llINCLUDE_Completed = .T. llMETADATA_Completed = .T. llDEFINED_PAM_Completed = .T. CASE NOT llPROTECTED_Completed AND .analizarBloque_PROTECTED( @toClase, @tcLine ) llPROTECTED_Completed = .T. CASE NOT llHIDDEN_Completed AND .analizarBloque_HIDDEN( @toClase, @tcLine ) llHIDDEN_Completed = .T. CASE NOT llINCLUDE_Completed AND .c_Type <> "SCX" AND .analizarBloque_INCLUDE( @toModulo, @toClase, @tcLine, @taCodeLines ; , @I, @tnCodeLines, @tcProcedureAbierto ) llINCLUDE_Completed = .T. CASE NOT llMETADATA_Completed AND .analizarBloque_METADATA( @toClase, @tcLine ) llMETADATA_Completed = .T. CASE NOT llDEFINED_PAM_Completed AND .analizarBloque_DEFINED_PAM( @toClase, @tcLine, @taCodeLines, tnCodeLines, @I ) llDEFINED_PAM_Completed = .T. CASE .analizarBloque_ADD_OBJECT( @toModulo, @toClase, @tcLine, @I, @taCodeLines, @tnCodeLines ) llCLASS_PROPERTY_Completed = .T. llPROTECTED_Completed = .T. llHIDDEN_Completed = .T. llINCLUDE_Completed = .T. llMETADATA_Completed = .T. llDEFINED_PAM_Completed = .T. CASE .analizarBloque_ENDDEFINE( @toClase, @tcLine, @I, @tcProcedureAbierto ) EXIT CASE NOT llCLASS_PROPERTY_Completed AND EMPTY( toClase._Fin_Cab ) *-- Propiedades de la CLASE *-- *-- NOTA: Las propiedades se agregan tal cual, incluso aunque estén separadas en *-- varias líneas (memberdata y fb2p_value), ya que luego se ensamblan en classProps2Memo(). * *toClase.add_Property( THIS.desnormalizarAsignacion( RTRIM(tcLine) ), RTRIM(tc_Comentario) ) .get_SeparatedPropAndValue( RTRIM(tcLine), @lcProp, @lcValue, @toClase, @taCodeLines, tnCodeLines, @I ) toClase.add_Property( @lcProp, @lcValue, RTRIM(tc_Comentario) ) OTHERWISE *-- Las líneas que pasan por aquí deberían estar vacías y ser de relleno del embellecimiento ENDCASE ENDFOR ENDWITH && THIS *-- Validación IF EMPTY( toClase._Fin ) ERROR 'No se ha encontrado el marcador de fin [ENDDEFINE] ' ; + 'que cierra al marcador de inicio [DEFINE CLASS] ' ; + 'de la línea ' + TRANSFORM( toClase._Inicio ) + ' ' ; + 'para el identificador [' + toClase._Nombre + ']' ENDIF toClase._PROPERTIES = THIS.classProps2Memo( toClase ) toClase._PROTECTED = THIS.hiddenAndProtected_PAM( toClase ) toClase._METHODS = THIS.classMethods2Memo( toClase ) toClase._RESERVED1 = IIF( THIS.c_Type = 'SCX', '', 'Class' ) toClase._RESERVED2 = IIF( THIS.c_Type = 'VCX' OR toClase._Nombre == 'Dataenvironment', TRANSFORM( toClase._AddObject_Count + 1 ), '' ) toClase._RESERVED3 = THIS.defined_PAM2Memo( toClase ) toClase._RESERVED4 = toClase._ClassIcon toClase._RESERVED5 = toClase._ProjectClassIcon toClase._RESERVED6 = toClase._Scale toClase._RESERVED7 = toClase._Comentario toClase._RESERVED8 = toClase._includeFile CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ENDDEFINE LPARAMETERS toClase, tcLine, I, tcProcedureAbierto #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado IF LEFT( tcLine + ' ', 10 ) == C_ENDDEFINE + ' ' && Fin de bloque (ENDDEF / ENDPROC) encontrado llBloqueEncontrado = .T. toClase._Fin = I IF EMPTY( toClase._Ini_Cuerpo ) toClase._Ini_Cuerpo = I-1 ENDIF toClase._Fin_Cuerpo = I-1 IF EMPTY( toClase._Fin_Cab ) toClase._Fin_Cab = I-1 ENDIF STORE '' TO tcProcedureAbierto ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_HIDDEN LPARAMETERS toClase, tcLine #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado IF LEFT(tcLine, 7) == 'HIDDEN ' llBloqueEncontrado = .T. toClase._HiddenProps = ALLTRIM( SUBSTR( tcLine, 8 ) ) ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_INCLUDE LPARAMETERS toModulo, toClase, tcLine, taCodeLines, I, tnCodeLines, tcProcedureAbierto LOCAL llBloqueEncontrado #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF IF LEFT(tcLine, 9) == '#INCLUDE ' llBloqueEncontrado = .T. IF THIS.c_Type = 'SCX' toModulo._includeFile = ALLTRIM( CHRTRAN( SUBSTR( tcLine, 10 ), ["'], [] ) ) ELSE toClase._includeFile = ALLTRIM( CHRTRAN( SUBSTR( tcLine, 10 ), ["'], [] ) ) ENDIF ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_METADATA LPARAMETERS toClase, tcLine #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado IF LEFT(tcLine, C_LEN_METADATA_I) == C_METADATA_I && METADATA de la CLASE *< CLASSDATA: Baseclass="custom" Timestamp="2013/11/19 11:51:04" Scale="Foxels" Uniqueid="_3WF0VSTN1" ProjectClassIcon="container.ico" ClassIcon="toolbar.ico" /> LOCAL laPropsAndValues(1,2), lnPropsAndValues_Count llBloqueEncontrado = .T. WITH THIS .get_ListNamesWithValuesFrom_InLine_MetadataTag( @tcLine, @laPropsAndValues, @lnPropsAndValues_Count, C_METADATA_I, C_METADATA_F ) toClase._BaseClass = .get_ValueByName_FromListNamesWithValues( 'BaseClass', 'C', @laPropsAndValues ) toClase._TimeStamp = INT( .RowTimeStamp( .get_ValueByName_FromListNamesWithValues( 'TimeStamp', 'T', @laPropsAndValues ) ) ) toClase._Scale = .get_ValueByName_FromListNamesWithValues( 'Scale', 'C', @laPropsAndValues ) toClase._UniqueID = .get_ValueByName_FromListNamesWithValues( 'UniqueID', 'C', @laPropsAndValues ) toClase._ProjectClassIcon = .get_ValueByName_FromListNamesWithValues( 'ProjectClassIcon', 'C', @laPropsAndValues ) toClase._ClassIcon = .get_ValueByName_FromListNamesWithValues( 'ClassIcon', 'C', @laPropsAndValues ) toClase._Ole2 = .get_ValueByName_FromListNamesWithValues( 'OLEObject', 'C', @laPropsAndValues ) ENDWITH && THIS IF NOT EMPTY( toClase._Ole2 ) && Le agrego "OLEObject = " delante toClase._Ole2 = 'OLEObject = ' + toClase._Ole2 + CR_LF ENDIF ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_OLE_DEF LPARAMETERS toModulo, tcLine, taCodeLines, I, tnCodeLines, tcProcedureAbierto LOCAL llBloqueEncontrado #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' #ENDIF IF LEFT( tcLine + ' ', C_LEN_OLE_I + 1 ) == C_OLE_I + ' ' llBloqueEncontrado = .T. *-- Se encontró una definición de objeto OLE *< OLE: Nombre="frm_d.ole_ImageControl2" parent="frm_d" objname="ole_ImageControl2" checksum="4171274922" value="b64-value" /> LOCAL laPropsAndValues(1,2), lnPropsAndValues_Count ; , loOle AS CL_OLE OF 'FOXBIN2PRG.PRG' loOle = NULL loOle = CREATEOBJECT('CL_OLE') WITH THIS .get_ListNamesWithValuesFrom_InLine_MetadataTag( @tcLine, @laPropsAndValues, @lnPropsAndValues_Count, C_OLE_I, C_OLE_F ) loOle._Nombre = .get_ValueByName_FromListNamesWithValues( 'Nombre', 'C', @laPropsAndValues ) loOle._Parent = .get_ValueByName_FromListNamesWithValues( 'Parent', 'C', @laPropsAndValues ) loOle._ObjName = .get_ValueByName_FromListNamesWithValues( 'ObjName', 'C', @laPropsAndValues ) loOle._CheckSum = .get_ValueByName_FromListNamesWithValues( 'CheckSum', 'C', @laPropsAndValues ) loOle._Value = STRCONV( .get_ValueByName_FromListNamesWithValues( 'Value', 'C', @laPropsAndValues ), 14 ) ENDWITH toModulo.add_OLE( loOle ) IF EMPTY( loOle._Value ) *-- Si el objeto OLE no tiene VALUE, es porque hay otro con el mismo contenido y no se duplicó para preservar espacio. *-- Busco el VALUE del duplicado que se guardó y lo asigno nuevamente FOR Z = 1 TO toModulo._Ole_Obj_count - 1 IF toModulo._Ole_Objs(Z)._CheckSum == loOle._CheckSum AND NOT EMPTY( toModulo._Ole_Objs(Z)._Value ) loOle._Value = toModulo._Ole_Objs(Z)._Value EXIT ENDIF ENDFOR ENDIF loOle = NULL RELEASE loOle ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_PROCEDURE LPARAMETERS toModulo, toClase, toObjeto, tcLine, taCodeLines, I, tnCodeLines, tcProcedureAbierto ; , tc_Comentario, taBloquesExclusion, tnBloquesExclusion #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' LOCAL toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado DO CASE CASE LEFT( tcLine, 20 ) == 'PROTECTED PROCEDURE ' *-- Estructura a reconocer: PROTECTED PROCEDURE nombre_del_procedimiento llBloqueEncontrado = .T. tcProcedureAbierto = ALLTRIM( SUBSTR( tcLine, 21 ) ) THIS.evaluarDefinicionDeProcedure( @toClase, I, @tc_Comentario, tcProcedureAbierto, 'protected', @toObjeto ) CASE LEFT( tcLine, 17 ) == 'HIDDEN PROCEDURE ' *-- Estructura a reconocer: HIDDEN PROCEDURE nombre_del_procedimiento llBloqueEncontrado = .T. tcProcedureAbierto = ALLTRIM( SUBSTR( tcLine, 18 ) ) THIS.evaluarDefinicionDeProcedure( @toClase, I, @tc_Comentario, tcProcedureAbierto, 'hidden', @toObjeto ) CASE LEFT( tcLine, 10 ) == 'PROCEDURE ' *-- Estructura a reconocer: PROCEDURE [objeto.]nombre_del_procedimiento llBloqueEncontrado = .T. tcProcedureAbierto = ALLTRIM( SUBSTR( tcLine, 11 ) ) THIS.evaluarDefinicionDeProcedure( @toClase, I, @tc_Comentario, tcProcedureAbierto, 'normal', @toObjeto ) ENDCASE IF llBloqueEncontrado *-- Evalúo todo el contenido del PROCEDURE THIS.analizarLineasDeProcedure( @toClase, @toObjeto, @tcLine, @taCodeLines, @I, @tnCodeLines, @tcProcedureAbierto ; , @tc_Comentario, @taBloquesExclusion, @tnBloquesExclusion ) ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_PROTECTED LPARAMETERS toClase, tcLine #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' #ENDIF LOCAL llBloqueEncontrado IF LEFT(tcLine, 10) == 'PROTECTED ' llBloqueEncontrado = .T. toClase._ProtectedProps = ALLTRIM( SUBSTR( tcLine, 11 ) ) ENDIF RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE evaluarDefinicionDeProcedure LPARAMETERS toClase, tnX, tc_Comentario, tcProcName, tcProcType, toObjeto *-------------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' ; , toObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lcNombreObjeto, lnObjProc ; , loProcedure AS CL_PROCEDURE OF 'FOXBIN2PRG.PRG' IF EMPTY(toClase._Fin_Cab) toClase._Fin_Cab = tnX-1 toClase._Ini_Cuerpo = tnX ENDIF loProcedure = CREATEOBJECT("CL_PROCEDURE") loProcedure._Nombre = tcProcName loProcedure._ProcType = tcProcType loProcedure._Comentario = tc_Comentario *-- Anoto en HiddenMethods y ProtectedMethods según corresponda DO CASE CASE loProcedure._ProcType == 'hidden' toClase._HiddenMethods = toClase._HiddenMethods + ',' + tcProcName CASE loProcedure._ProcType == 'protected' toClase._ProtectedMethods = toClase._ProtectedMethods + ',' + tcProcName ENDCASE *-- Agrego el objeto Procedimiento a la clase, o a un objeto de la clase. IF '.' $ tcProcName *-- Procedimiento de objeto lcNombreObjeto = LOWER( JUSTSTEM( tcProcName ) ) *-- Busco el objeto al que corresponde el método lnObjProc = THIS.buscarObjetoDelMetodoPorNombre( lcNombreObjeto, toClase ) IF lnObjProc = 0 *-- Procedimiento de clase toClase.add_Procedure( loProcedure ) toObjeto = NULL ELSE *-- Procedimiento de objeto toObjeto = toClase._AddObjects( lnObjProc ) toObjeto.add_Procedure( loProcedure ) ENDIF ELSE *-- Procedimiento de clase toClase.add_Procedure( loProcedure ) ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY STORE NULL TO loProcedure RELEASE loProcedure ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (!@ IN ) Array con las posiciones de inicio/fin de los bloques de exclusion * tnBloquesExclusion (!@ IN ) Cantidad de bloques de exclusión * toModulo (?@ OUT) Objeto con toda la información del módulo analizado * * NOTA: * Como identificador se usa el nombre de clase o de procedimiento, según corresponda. *-------------------------------------------------------------------------------------------------------------- LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toModulo EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, loEx AS EXCEPTION ; , llFoxBin2Prg_Completed, llOLE_DEF_Completed, llINCLUDE_SCX_Completed ; , lc_Comentario, lcProcedureAbierto, lcLine ; , loClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' STORE '' TO lcProcedureAbierto THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 *-- Defino el objeto de módulo y sus propiedades toModulo = NULL toModulo = CREATEOBJECT('CL_MODULO') *-- Búsqueda del ID de inicio de bloque (DEFINE CLASS / PROCEDURE) WITH THIS FOR I = 1 TO tnCodeLines STORE '' TO lc_Comentario .set_Line( @lcLine, @taCodeLines, I ) DO CASE CASE THIS.lineaExcluida( I, tnBloquesExclusion, @taBloquesExclusion ) ; OR .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Excluida, vacía o solo Comentarios CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toModulo, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE NOT llOLE_DEF_Completed AND .analizarBloque_OLE_DEF( @toModulo, @lcLine, @taCodeLines ; , @I, tnCodeLines, @lcProcedureAbierto ) *-- Puede haber varios CASE NOT llINCLUDE_SCX_Completed AND .c_Type = 'SCX' AND .analizarBloque_INCLUDE( @toModulo, @loClase, @lcLine ; , @taCodeLines, @I, tnCodeLines, @lcProcedureAbierto ) * Específico para SCX que lo tiene al inicio llINCLUDE_SCX_Completed = .T. CASE .analizarBloque_DEFINE_CLASS( @toModulo, @loClase, @lcLine, @taCodeLines, @I, tnCodeLines ; , @lcProcedureAbierto, @taBloquesExclusion, @tnBloquesExclusion, @lc_Comentario ) *-- Puede haber varias ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY STORE NULL TO loClase RELEASE loClase ENDTRY RETURN ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_vcx AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_vcx OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toModulo (@! OUT) Objeto generado de clase CL_MODULO con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toModulo, toEx AS EXCEPTION, toFoxbin2prg #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF DODEFAULT( @toModulo, @toEx ) TRY LOCAL lnCodError, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo la librería THIS.createClasslib() *-- Identifico los TEXT/ENDTEXT, #IF .F./#ENDIF THIS.identificarBloquesDeExclusion( @laCodeLines, lnCodeLines, .F., @laBloquesExclusion, @lnBloquesExclusion ) *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo de cada clase THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toModulo ) THIS.escribirArchivoBin( @toModulo ) CATCH TO toEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toModulo *-- Estructura del objeto toModulo generado: *-- ----------------------------------------------------------------------------------------------------------- *-- Version Versión usada para generar la versión PRG analizada *-- SourceFile Nombre original del archivo fuente de la conversión *-- Ole_Obj_Count Cantidad de objetos definidos en el array ole_objs[] *-- Ole_Objs[1] Array de objetos OLE definidos como clases *-- ObjName Nombre del objeto OLE (OLE2) *-- Parent Nombre del objeto Padre *-- CheckSum Suma de verificación *-- Value Valor del campo OLE *-- Clases_Count Array con las posiciones de los addobjects, definicion y propiedades *-- Clases[1] Array con los datos de las clases, definicion, propiedades y métodos *-- Nombre El nombre de la clase (ej: "miClase") *-- ObjName Nombre del objeto *-- Parent Nombre del objeto Padre *-- Class Clase de la que hereda la definición *-- Classloc Librería donde está la definición de la clase *-- Ole Información campo ole *-- Ole2 Información campo ole2 *-- OlePublic Indica si la clase es OLEPublic o no (.T. / .F.) *-- Uniqueid ID único *-- Comentario El comentario de la clase (ej: "&& Mis comentarios") *-- MetaData Información de metadata de la clase (baseclass, timestamp, scale) *-- BaseClass Clase de base de la clase *-- TimeStamp Timestamp de la clase *-- Scale Scale de la clase (pixels, foxels) *-- Definicion La definición de la clase (ej: "AS Custom OF LIBRERIA.VCX") *-- Inicio/Fin Línea de inicio/fin de la clase (DEFINE CLASS/ENDDEFINE) *-- Ini_Cab/Fin_Cab Línea de inicio/fin de la cabecera (def.propiedades, Hidden, Protected, #Include, CLASSDATA, DEFINED_PAM) *-- Ini_Cuerpo/Fin_Cuerpo Línea de inicio/fin del cuerpo (ADD OBJECTs y PROCEDURES) *-- HiddenProps Propiedades definidas como HIDDEN (ocultas) *-- ProtectedProps Propiedades definidas como PROTECTED (protegidas) *-- Defined_PAM Propiedades, eventos o métodos definidos por el usuario *-- IncludeFile Nombre del archivo de inclusión *-- Props_Count Cantidad de propiedades de la clase definicas en el array props[] *-- Props[1,2] Array con todas las propiedades de la clase y sus valores. (col.1=Nombre, col.2=Comentario) *-- AddObject_Count Cantidad de objetos definidos en el array addobjects[] *-- AddObjects[1] Array con las posiciones de los addobjects, definicion y propiedades *-- Nombre Nombre del objeto *-- ObjName Nombre del objeto *-- Parent Nombre del objeto Padre *-- Clase Clase del objeto *-- ClassLib Librería de clases de la que deriva la clase *-- Baseclass Clase de base del objeto *-- Uniqueid ID único *-- Ole Información campo ole *-- Ole2 Información campo ole2 *-- ZOrder Orden Z del objeto *-- Props_Count Cantidad de propiedades del objeto *-- Props[1] Array con todas las propiedades del objeto y sus valores *-- Procedure_count Cantidad de procedimientos definidos en el array procedures[] *-- Procedures[1] Array con las posiciones de los procedures, definicion y comentarios *-- Nombre Nombre del procedure *-- ProcType Tipo de procedimiento (normal, hidden, protected) *-- Comentario Comentario el procedure *-- ProcLine_Count Cantidad de líneas del procedimiento *-- ProcLines[1] Líneas del procedimiento *-- Procedure_count Cantidad de procedimientos definidos en el array procedures[] *-- Procedures[1] Array con las posiciones de los procedures, definicion y comentarios *-- Nombre Nombre del procedure *-- ProcType Tipo de procedimiento (normal, hidden, protected) *-- Comentario Comentario el procedure *-- ProcLine_Count Cantidad de líneas del procedimiento *-- ProcLines[1] Líneas del procedimiento *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lcObjName, lnCodError, I, X, loEx AS EXCEPTION ; , loClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' ; , loObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' ; , loFSO AS Scripting.FileSystemObject loFSO = THIS.oFSO *-- Creo el registro de cabecera THIS.createClasslib_RecordHeader() *-- Recorro las CLASES FOR I = 1 TO toModulo._Clases_Count loClase = toModulo._Clases(I) *-- Inserto la clase INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , TIMESTAMP ; , CLASS ; , CLASSLOC ; , BASECLASS ; , OBJNAME ; , PARENT ; , PROPERTIES ; , PROTECTED ; , METHODS ; , OLE ; , OLE2 ; , RESERVED1 ; , RESERVED2 ; , RESERVED3 ; , RESERVED4 ; , RESERVED5 ; , RESERVED6 ; , RESERVED7 ; , RESERVED8 ; , USER) ; VALUES ; ( 'WINDOWS' ; , loClase._UniqueID ; , loClase._TimeStamp ; , loClase._Class ; , loClase._ClassLoc ; , loClase._BaseClass ; , loClase._ObjName ; , loClase._Parent ; , loClase._PROPERTIES ; , loClase._PROTECTED ; , loClase._METHODS ; , loClase._Ole ; , loClase._Ole2 ; , loClase._RESERVED1 ; , loClase._RESERVED2 ; , loClase._RESERVED3 ; , loClase._ClassIcon ; , loClase._ProjectClassIcon ; , loClase._Scale ; , loClase._Comentario ; , loClase._includeFile ; , loClase._User ) THIS.insert_AllObjects( @loClase ) *-- Inserto el COMMENT INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , TIMESTAMP ; , CLASS ; , CLASSLOC ; , BASECLASS ; , OBJNAME ; , PARENT ; , PROPERTIES ; , PROTECTED ; , METHODS ; , OLE ; , OLE2 ; , RESERVED1 ; , RESERVED2 ; , RESERVED3 ; , RESERVED4 ; , RESERVED5 ; , RESERVED6 ; , RESERVED7 ; , RESERVED8 ; , USER) ; VALUES ; ( 'COMMENT' ; , 'RESERVED' ; , loClase._TimeStamp ; , '' ; , '' ; , '' ; , loClase._ObjName ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , IIF(loClase._OlePublic, 'OLEPublic', '') ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ) ENDFOR && I = 1 TO toModulo._Clases_Count USE IN (SELECT("TABLABIN")) COMPILE CLASSLIB (THIS.c_OutputFile) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_scx AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_scx OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toModulo (@! OUT) Objeto generado de clase CL_MODULO con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toModulo, toEx AS EXCEPTION, toFoxbin2prg #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF DODEFAULT( @toModulo, @toEx ) TRY LOCAL lnCodError, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo el form THIS.createForm() *-- Identifico los TEXT/ENDTEXT, #IF .F./#ENDIF THIS.identificarBloquesDeExclusion( @laCodeLines, lnCodeLines, .F., @laBloquesExclusion, @lnBloquesExclusion ) *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo de cada clase THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toModulo ) THIS.escribirArchivoBin( @toModulo ) CATCH TO toEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toModulo *-- Estructura del objeto toModulo generado: *-- ----------------------------------------------------------------------------------------------------------- *-- Version Versión usada para generar la versión PRG analizada *-- SourceFile Nombre original del archivo fuente de la conversión *-- Ole_Obj_Count Cantidad de objetos definidos en el array ole_objs[] *-- Ole_Objs[1] Array de objetos OLE definidos como clases *-- ObjName Nombre del objeto OLE (OLE2) *-- Parent Nombre del objeto Padre *-- CheckSum Suma de verificación *-- Value Valor del campo OLE *-- Clases_Count Array con las posiciones de los addobjects, definicion y propiedades *-- Clases[1] Array con los datos de las clases, definicion, propiedades y métodos *-- Nombre El nombre de la clase (ej: "miClase") *-- ObjName Nombre del objeto *-- Parent Nombre del objeto Padre *-- Class Clase de la que hereda la definición *-- Classloc Librería donde está la definición de la clase *-- Ole Información campo ole *-- Ole2 Información campo ole2 *-- OlePublic Indica si la clase es OLEPublic o no (.T. / .F.) *-- Uniqueid ID único *-- Comentario El comentario de la clase (ej: "&& Mis comentarios") *-- MetaData Información de metadata de la clase (baseclass, timestamp, scale) *-- BaseClass Clase de base de la clase *-- TimeStamp Timestamp de la clase *-- Scale Scale de la clase (pixels, foxels) *-- Definicion La definición de la clase (ej: "AS Custom OF LIBRERIA.VCX") *-- Inicio/Fin Línea de inicio/fin de la clase (DEFINE CLASS/ENDDEFINE) *-- Ini_Cab/Fin_Cab Línea de inicio/fin de la cabecera (def.propiedades, Hidden, Protected, #Include, CLASSDATA, DEFINED_PAM) *-- Ini_Cuerpo/Fin_Cuerpo Línea de inicio/fin del cuerpo (ADD OBJECTs y PROCEDURES) *-- HiddenProps Propiedades definidas como HIDDEN (ocultas) *-- ProtectedProps Propiedades definidas como PROTECTED (protegidas) *-- Defined_PAM Propiedades, eventos o métodos definidos por el usuario *-- IncludeFile Nombre del archivo de inclusión *-- Props_Count Cantidad de propiedades de la clase definicas en el array props[] *-- Props[1,2] Array con todas las propiedades de la clase y sus valores. (col.1=Nombre, col.2=Comentario) *-- AddObject_Count Cantidad de objetos definidos en el array addobjects[] *-- AddObjects[1] Array con las posiciones de los addobjects, definicion y propiedades *-- Nombre Nombre del objeto *-- ObjName Nombre del objeto *-- Parent Nombre del objeto Padre *-- Clase Clase del objeto *-- ClassLib Librería de clases de la que deriva la clase *-- Baseclass Clase de base del objeto *-- Uniqueid ID único *-- Ole Información campo ole *-- Ole2 Información campo ole2 *-- ZOrder Orden Z del objeto *-- Props_Count Cantidad de propiedades del objeto *-- Props[1] Array con todas las propiedades del objeto y sus valores *-- Procedure_count Cantidad de procedimientos definidos en el array procedures[] *-- Procedures[1] Array con las posiciones de los procedures, definicion y comentarios *-- Nombre Nombre del procedure *-- ProcType Tipo de procedimiento (normal, hidden, protected) *-- Comentario Comentario el procedure *-- ProcLine_Count Cantidad de líneas del procedimiento *-- ProcLines[1] Líneas del procedimiento *-- Procedure_count Cantidad de procedimientos definidos en el array procedures[] *-- Procedures[1] Array con las posiciones de los procedures, definicion y comentarios *-- Nombre Nombre del procedure *-- ProcType Tipo de procedimiento (normal, hidden, protected) *-- Comentario Comentario el procedure *-- ProcLine_Count Cantidad de líneas del procedimiento *-- ProcLines[1] Líneas del procedimiento *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toModulo AS CL_MODULO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lcObjName, lnCodError, loEx AS EXCEPTION ; , loClase AS CL_CLASE OF 'FOXBIN2PRG.PRG' ; , loObjeto AS CL_OBJETO OF 'FOXBIN2PRG.PRG' *-- Creo el registro de cabecera THIS.createForm_RecordHeader() *-- El SCX tiene el INCLUDE en el primer registro IF NOT EMPTY(toModulo._includeFile) REPLACE RESERVED8 WITH toModulo._includeFile ENDIF *-- Recorro las CLASES FOR I = 1 TO toModulo._Clases_Count loClase = toModulo._Clases(I) *-- Inserto la clase INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , TIMESTAMP ; , CLASS ; , CLASSLOC ; , BASECLASS ; , OBJNAME ; , PARENT ; , PROPERTIES ; , PROTECTED ; , METHODS ; , OLE ; , OLE2 ; , RESERVED1 ; , RESERVED2 ; , RESERVED3 ; , RESERVED4 ; , RESERVED5 ; , RESERVED6 ; , RESERVED7 ; , RESERVED8 ; , USER) ; VALUES ; ( 'WINDOWS' ; , loClase._UniqueID ; , loClase._TimeStamp ; , loClase._Class ; , loClase._ClassLoc ; , loClase._BaseClass ; , loClase._ObjName ; , loClase._Parent ; , loClase._PROPERTIES ; , loClase._PROTECTED ; , loClase._METHODS ; , loClase._Ole ; , loClase._Ole2 ; , loClase._RESERVED1 ; , loClase._RESERVED2 ; , loClase._RESERVED3 ; , loClase._ClassIcon ; , loClase._ProjectClassIcon ; , loClase._Scale ; , loClase._Comentario ; , loClase._includeFile ; , loClase._User ) THIS.insert_AllObjects( @loClase ) ENDFOR && I = 1 TO toModulo._Clases_Count *-- Inserto el COMMENT final INSERT INTO TABLABIN ; ( PLATFORM ; , UNIQUEID ; , TIMESTAMP ; , CLASS ; , CLASSLOC ; , BASECLASS ; , OBJNAME ; , PARENT ; , PROPERTIES ; , PROTECTED ; , METHODS ; , OLE ; , OLE2 ; , RESERVED1 ; , RESERVED2 ; , RESERVED3 ; , RESERVED4 ; , RESERVED5 ; , RESERVED6 ; , RESERVED7 ; , RESERVED8 ; , USER) ; VALUES ; ( 'COMMENT' ; , 'RESERVED' ; , 0 ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ; , '' ) USE IN (SELECT("TABLABIN")) COMPILE FORM (THIS.c_OutputFile) CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_pjx AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_pjx OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ******************************************************************************************************************* PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toProject (@! OUT) Objeto generado de clase CL_PROJECT con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toProject, toEx AS EXCEPTION, toFoxbin2prg DODEFAULT( @toProject, @toEx ) #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo solo la cabecera del proyecto THIS.createProject() *-- Identifico los TEXT/ENDTEXT, #IF .F./#ENDIF *THIS.identificarBloquesDeExclusion( @laCodeLines, .F., @laBloquesExclusion, @lnBloquesExclusion ) *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo de cada clase THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toProject ) THIS.escribirArchivoBin( @toProject ) CATCH TO toEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toProject *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL loReg, lnCodError, loEx AS EXCEPTION ; , loServerHead AS CL_PROJ_SRV_HEAD OF 'FOXBIN2PRG.PRG' ; , loFile AS CL_PROJ_FILE OF 'FOXBIN2PRG.PRG' toProject._HomeDir = CHRTRAN( toProject._HomeDir, ['], [] ) *-- Creo solo el registro de cabecera del proyecto THIS.createProject_RecordHeader( toProject ) lcMainProg = '' IF NOT EMPTY(toProject._MainProg) lcMainProg = LOWER( SYS(2014, toProject._MainProg, ADDBS(toProject._HomeDir) ) ) ENDIF *-- Si hay ProjectHook de proyecto, lo inserto IF NOT EMPTY(toProject._ProjectHookLibrary) INSERT INTO TABLABIN ; ( NAME ; , TYPE ; , EXCLUDE ; , KEY ; , RESERVED1 ) ; VALUES ; ( toProject._ProjectHookLibrary + CHR(0) ; , 'W' ; , .T. ; , UPPER(JUSTSTEM(toProject._ProjectHookLibrary)) ; , toProject._ProjectHookClass + CHR(0) ) ENDIF *-- Si hay ICONO de proyecto, lo inserto IF NOT EMPTY(toProject._Icon) INSERT INTO TABLABIN ; ( NAME ; , TYPE ; , LOCAL ; , KEY ) ; VALUES ; ( SYS(2014, toProject._Icon, ADDBS(JUSTPATH(toProject._HomeDir))) + CHR(0) ; , 'i' ; , .T. ; , UPPER(JUSTSTEM(toProject._Icon)) ) ENDIF *-- Agrego los ARCHIVOS FOR EACH loFile IN toProject FOXOBJECT INSERT INTO TABLABIN ; ( NAME ; , TYPE ; , EXCLUDE ; , MAINPROG ; , COMMENTS ; , LOCAL ; , CPID ; , ID ; , TIMESTAMP ; , OBJREV ; , KEY ) ; VALUES ; ( loFile._Name + CHR(0) ; , THIS.fileTypeCode(JUSTEXT(loFile._Name)) ; , loFile._Exclude ; , (loFile._Name == lcMainProg) ; , loFile._Comments ; , .T. ; , loFile._CPID ; , loFile._ID ; , loFile._TimeStamp ; , loFile._ObjRev ; , UPPER(JUSTSTEM(loFile._Name)) ) ENDFOR USE IN (SELECT("TABLABIN")) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toProject *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (!@ IN ) Array con las posiciones de inicio/fin de los bloques de exclusion * tnBloquesExclusion (!@ IN ) Cantidad de bloques de exclusión * toProject (?@ OUT) Objeto con toda la información del proyecto analizado * * NOTA: * Como identificador se usa el nombre de clase o de procedimiento, según corresponda. *-------------------------------------------------------------------------------------------------------------- EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lc_Comentario, lcLine, llBuildProj_Completed, llDevInfo_Completed ; , llServerHead_Completed, llFileComments_Completed, llFoxBin2Prg_Completed ; , llExcludedFiles_Completed, llTextFiles_Completed, llProjectProperties_Completed STORE 0 TO I THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 toProject = CREATEOBJECT('CL_PROJECT') *toProject._HomeDir = ADDBS(JUSTPATH(THIS.c_OutputFile)) WITH THIS FOR I = 1 TO tnCodeLines .set_Line( @lcLine, @taCodeLines, I ) IF .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Vacía o solo Comentarios LOOP ENDIF DO CASE CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE NOT llDevInfo_Completed AND .analizarBloque_DevInfo( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llDevInfo_Completed = .T. CASE NOT llServerHead_Completed AND .analizarBloque_ServerHead( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llServerHead_Completed = .T. CASE .analizarBloque_ServerData( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) *-- Puede haber varios servidores, por eso se siguen valuando CASE NOT llBuildProj_Completed AND .analizarBloque_BuildProj( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llBuildProj_Completed = .T. CASE NOT llFileComments_Completed AND .analizarBloque_FileComments( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llFileComments_Completed = .T. CASE NOT llExcludedFiles_Completed AND .analizarBloque_ExcludedFiles( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llExcludedFiles_Completed = .T. CASE NOT llTextFiles_Completed AND .analizarBloque_TextFiles( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llTextFiles_Completed = .T. CASE NOT llProjectProperties_Completed AND .analizarBloque_ProjectProperties( toProject, @lcLine, @taCodeLines, @I, tnCodeLines ) llProjectProperties_Completed = .T. ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_BuildProj *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcComment, lcMetadatos, luValor ; , laPropsAndValues(1,2), lnPropsAndValues_Count ; , loFile AS CL_PROJ_FILE OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_BUILDPROJ_I) ) == C_BUILDPROJ_I llBloqueEncontrado = .T. STORE NULL TO loProject, loFile WITH THIS FOR I = I + 1 TO tnCodeLines lcComment = '' .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_BUILDPROJ_F) ) == C_BUILDPROJ_F I = I + 1 EXIT CASE .lineIsOnlyCommentAndNoMetadata( @tcLine, @lcComment ) LOOP && Saltear comentarios CASE UPPER( LEFT( tcLine, 14 ) ) == 'BUILD PROJECT ' LOOP CASE UPPER( LEFT( tcLine, 5 ) ) == '.ADD(' * loFile: NAME,TYPE,EXCLUDE,COMMENTS tcLine = CHRTRAN( tcLine, ["] + '[]', "'''" ) && Convierto "[] en ' loFile = CREATEOBJECT('CL_PROJ_FILE') loFile._Name = ALLTRIM( STREXTRACT( tcLine, ['], ['] ) ) *-- Obtengo metadatos de los comentarios de FileMetadata: *< FileMetadata: Type="V" Cpid="1252" Timestamp="1131901580" ID="1129207528" ObjRev="544" /> .get_ListNamesWithValuesFrom_InLine_MetadataTag( @lcComment, @laPropsAndValues ; , @lnPropsAndValues_Count, C_FILE_META_I, C_FILE_META_F ) loFile._Type = .get_ValueByName_FromListNamesWithValues( 'Type', 'C', @laPropsAndValues ) loFile._CPID = .get_ValueByName_FromListNamesWithValues( 'CPID', 'I', @laPropsAndValues ) loFile._TimeStamp = .get_ValueByName_FromListNamesWithValues( 'Timestamp', 'I', @laPropsAndValues ) loFile._ID = .get_ValueByName_FromListNamesWithValues( 'ID', 'I', @laPropsAndValues ) loFile._ObjRev = .get_ValueByName_FromListNamesWithValues( 'ObjRev', 'I', @laPropsAndValues ) toProject.ADD( loFile, loFile._Name ) CASE UPPER( LEFT( tcLine, 10 ) ) == UPPER( '*<.HomeDir' ) toProject._HomeDir = STREXTRACT( tcLine, "'", "'" ) ENDCASE ENDFOR ENDWITH && THIS I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_DevInfo *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado ; , loServerHead AS CL_PROJ_SRV_HEAD OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_DEVINFO_I) ) == C_DEVINFO_I llBloqueEncontrado = .T. FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_DEVINFO_F) ) == C_DEVINFO_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE toProject.setParsedProjInfoLine( @tcLine ) ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ServerHead *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado ; , loServerHead AS CL_PROJ_SRV_HEAD OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_SRV_HEAD_I) ) == C_SRV_HEAD_I llBloqueEncontrado = .T. STORE NULL TO loServerHead, loServerData loServerHead = toProject._ServerHead FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_SRV_HEAD_F) ) == C_SRV_HEAD_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE loServerHead.setParsedHeadInfoLine( @tcLine ) ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ServerData *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado ; , loServerHead AS CL_PROJ_SRV_HEAD OF 'FOXBIN2PRG.PRG' ; , loServerData AS CL_PROJ_SRV_DATA OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_SRV_DATA_I) ) == C_SRV_DATA_I llBloqueEncontrado = .T. STORE NULL TO loServerHead, loServerData loServerHead = toProject._ServerHead loServerData = loServerHead.getServerDataObject() FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_SRV_DATA_F) ) == C_SRV_DATA_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE loServerHead.setParsedInfoLine( loServerData, @tcLine ) ENDCASE ENDFOR loServerHead.add_Server( loServerData ) I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_FileComments *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines EXTERNAL ARRAY toProject #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcFile, lcComment ; , loFile AS CL_PROJ_FILE OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_FILE_CMTS_I) ) == C_FILE_CMTS_I llBloqueEncontrado = .T. FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_FILE_CMTS_F) ) == C_FILE_CMTS_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE lcFile = LOWER( ALLTRIM( STRTRAN( CHRTRAN( NORMALIZE( STREXTRACT( tcLine, ".ITEM(", ")", 1, 1 ) ), ["], [] ), 'lcCurDir+', '', 1, 1, 1) ) ) lcComment = ALLTRIM( CHRTRAN( STREXTRACT( tcLine, "=", "", 1, 2 ), ['], [] ) ) loFile = toProject( lcFile ) loFile._Comments = lcComment loFile = NULL ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ExcludedFiles *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines EXTERNAL ARRAY toProject #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcFile, llExclude ; , loFile AS CL_PROJ_FILE OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_FILE_EXCL_I) ) == C_FILE_EXCL_I llBloqueEncontrado = .T. FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_FILE_EXCL_F) ) == C_FILE_EXCL_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE lcFile = LOWER( ALLTRIM( STRTRAN( CHRTRAN( NORMALIZE( STREXTRACT( tcLine, ".ITEM(", ")", 1, 1 ) ), ["], [] ), 'lcCurDir+', '', 1, 1, 1) ) ) llExclude = EVALUATE( ALLTRIM( CHRTRAN( STREXTRACT( tcLine, "=", "", 1, 2 ), ['], [] ) ) ) loFile = toProject( lcFile ) loFile._Exclude = llExclude loFile = NULL ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_TextFiles *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines EXTERNAL ARRAY toProject #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcFile, lcType ; , loFile AS CL_PROJ_FILE OF 'FOXBIN2PRG.PRG' IF LEFT( tcLine, LEN(C_FILE_TXT_I) ) == C_FILE_TXT_I llBloqueEncontrado = .T. FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_FILE_TXT_F) ) == C_FILE_TXT_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios OTHERWISE lcFile = LOWER( ALLTRIM( STRTRAN( CHRTRAN( NORMALIZE( STREXTRACT( tcLine, ".ITEM(", ")", 1, 1 ) ), ["], [] ), 'lcCurDir+', '', 1, 1, 1) ) ) lcType = ALLTRIM( CHRTRAN( STREXTRACT( tcLine, "=", "", 1, 2 ), ['], [] ) ) loFile = toProject( lcFile ) loFile._Type = lcType loFile = NULL ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_ProjectProperties *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toProject, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toProject AS CL_PROJECT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcLine IF LEFT( tcLine, LEN(C_PROJPROPS_I) ) == C_PROJPROPS_I llBloqueEncontrado = .T. FOR I = I + 1 TO tnCodeLines .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_PROJPROPS_F) ) == C_PROJPROPS_F I = I + 1 EXIT CASE THIS.lineIsOnlyCommentAndNoMetadata( @tcLine ) LOOP && Saltear comentarios CASE LEFT( tcLine ,2 ) == '*<' *--- Se asigna con EVALUATE() tal cual está en el PJ2, pero quitando el marcador *< /> lcLine = STUFF( ALLTRIM( STREXTRACT( tcLine, '*<', '/>' ) ), 2, 0, '_' ) toProject.setParsedProjInfoLine( lcLine ) CASE UPPER( LEFT( tcLine, 9 ) ) == '.SETMAIN(' *-- Cambio "SetMain()" por "_MainProg =" lcLine = '._MainProg = ' + LOWER( STREXTRACT( ALLTRIM( tcLine), '.SetMain(', ')', 1, 1 ) ) toProject.setParsedProjInfoLine( lcLine ) OTHERWISE *--- Se asigna con EVALUATE() tal cual está en el PJ2 lcLine = STUFF( ALLTRIM( tcLine), 2, 0, '_' ) toProject.setParsedProjInfoLine( lcLine ) ENDCASE ENDFOR I = I - 1 ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ENDDEFINE ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_frx AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_frx OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toReport (@! OUT) Objeto generado de clase CL_REPORT con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toReport, toEx AS EXCEPTION, toFoxbin2prg DODEFAULT( @toReport, @toEx ) #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, loEx AS EXCEPTION, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo el reporte THIS.createReport() *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo del reporte THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toReport ) THIS.escribirArchivoBin( @toReport ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toReport *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL loReg, I, lcFieldType, lnFieldLen, lnFieldDec, lnNumCampo, laFieldTypes(1,18) ; , luValor, lnCodError, loEx AS EXCEPTION SELECT TABLABIN AFIELDS( laFieldTypes ) *-- Agrego los registros FOR EACH loReg IN toReport FOXOBJECT *-- Ajuste de los tipos de dato FOR I = 1 TO AMEMBERS(laProps, loReg, 0) lnNumCampo = ASCAN( laFieldTypes, laProps(I), 1, -1, 1, 1+2+4+8 ) IF lnNumCampo = 0 ERROR 'No se encontró el campo [' + laProps(I) + '] en la estructura del archivo ' + DBF("TABLABIN") ENDIF lcFieldType = laFieldTypes(lnNumCampo,2) lnFieldLen = laFieldTypes(lnNumCampo,3) lnFieldDec = laFieldTypes(lnNumCampo,4) luValor = EVALUATE('loReg.' + laProps(I)) DO CASE CASE INLIST(lcFieldType, 'B') && Double ADDPROPERTY( loReg, laProps(I), CAST( luValor AS &lcFieldType. (lnFieldPrec) ) ) CASE INLIST(lcFieldType, 'F', 'N', 'Y') && Float, Numeric, Currency ADDPROPERTY( loReg, laProps(I), CAST( luValor AS &lcFieldType. (lnFieldLen, lnFieldDec) ) ) CASE INLIST(lcFieldType, 'W', 'G', 'M', 'Q', 'V', 'C') && Blob, General, Memo, Varbinary, Varchar, Character ADDPROPERTY( loReg, laProps(I), luValor ) OTHERWISE && Demás tipos ADDPROPERTY( loReg, laProps(I), CAST( luValor AS &lcFieldType. (lnFieldLen) ) ) ENDCASE ENDFOR INSERT INTO TABLABIN FROM NAME loReg loReg = NULL ENDFOR USE IN (SELECT("TABLABIN")) IF THIS.c_Type = 'FRX' COMPILE REPORT (THIS.c_OutputFile) ELSE COMPILE LABEL (THIS.c_OutputFile) ENDIF CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toReport *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (?@ IN ) Sin uso * tnBloquesExclusion (?@ IN ) Sin uso * toReport (?@ OUT) Objeto con toda la información del reporte analizado * * NOTA: * Como identificador se usa el nombre de clase o de procedimiento, según corresponda. *-------------------------------------------------------------------------------------------------------------- EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lc_Comentario, lcLine, llFoxBin2Prg_Completed STORE 0 TO I THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 toReport = NULL toReport = CREATEOBJECT('CL_REPORT') WITH THIS FOR I = 1 TO tnCodeLines .set_Line( @lcLine, @taCodeLines, I ) IF .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Vacía o solo Comentarios LOOP ENDIF DO CASE CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toReport, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE .analizarBloque_Reportes( toReport, @lcLine, @taCodeLines, @I, tnCodeLines ) ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_CDATA_inline *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toReport, tcLine, taCodeLines, I, tnCodeLines, toReg, tcPropName #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcValue, loEx AS EXCEPTION IF LEFT(tcLine, 1 + LEN(tcPropName) + 1 + 9) == '<' + tcPropName + '>' + C_DATA_I llBloqueEncontrado = .T. IF C_DATA_F $ tcLine lcValue = STREXTRACT( tcLine, C_DATA_I, C_DATA_F ) ADDPROPERTY( toReg, tcPropName, lcValue ) EXIT ENDIF *-- Tomo la primera parte del valor lcValue = STREXTRACT( tcLine, C_DATA_I ) *-- Recorro las fracciones del valor FOR I = I + 1 TO tnCodeLines tcLine = taCodeLines(I) IF C_DATA_F $ tcLine && Fin del valor lcValue = lcValue + CR_LF + STREXTRACT( tcLine, '', C_DATA_F ) ADDPROPERTY( toReg, tcPropName, lcValue ) EXIT ELSE && Otra fracción del valor lcValue = lcValue + CR_LF + tcLine ENDIF ENDFOR ENDIF CATCH TO loEx IF loEx.ERRORNO = 1470 && Incorrect property name. loEx.USERVALUE = 'PropName=[' + TRANSFORM(tcPropName) + '], Value=[' + TRANSFORM(lcValue) + ']' ENDIF IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_platform *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toReport, tcLine, taCodeLines, I, tnCodeLines, toReg #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, X, lnPos, lnPos2, lcValue, lnLenPropName, laProps(1) ; , lcComment, lcMetadatos, luValor ; , laPropsAndValues(1,2), lnPropsAndValues_Count IF LOWER( LEFT(tcLine, 10) ) == 'platform="' llBloqueEncontrado = .T. lnLastPos = 1 tcLine = ' ' + tcLine FOR X = 1 TO AMEMBERS( laProps, toReg, 0 ) laProps(X) = ' ' + laProps(X) lnPos = AT( LOWER(laProps(X)) + '="', tcLine ) IF lnPos > 0 lnLenPropName = LEN(laProps(X)) lnPos2 = AT( '"', SUBSTR( tcLine, lnPos + lnLenPropName + 2 ) ) lcValue = SUBSTR( tcLine, lnPos + lnLenPropName + 2, lnPos2 - 1 ) ADDPROPERTY( toReg, laProps(X), lcValue ) ENDIF ENDFOR ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ******************************************************************************************************************* PROCEDURE analizarBloque_Reportes *------------------------------------------------------ *-- Analiza el bloque *------------------------------------------------------ LPARAMETERS toReport, tcLine, taCodeLines, I, tnCodeLines #IF .F. LOCAL toReport AS CL_REPORT OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL llBloqueEncontrado, lcComment, lcMetadatos, luValor ; , laPropsAndValues(1,2), lnPropsAndValues_Count ; , loReg IF LEFT( tcLine, LEN(C_TAG_REPORTE) + 1 ) == '<' + C_TAG_REPORTE + '' llBloqueEncontrado = .T. loReg = THIS.emptyRecord() WITH THIS FOR I = I + 1 TO tnCodeLines lcComment = '' .set_Line( @tcLine, @taCodeLines, I ) DO CASE CASE LEFT( tcLine, LEN(C_TAG_REPORTE_F) ) == C_TAG_REPORTE_F I = I + 1 EXIT CASE .lineIsOnlyCommentAndNoMetadata( @tcLine, @lcComment ) LOOP && Saltear comentarios CASE .analizarBloque_platform( toReport, @tcLine, @taCodeLines, @I, @tnCodeLines, @loReg ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'picture' ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'tag' ) *-- ARREGLO ALGUNOS VALORES CAMBIADOS AL TEXTUALIZAR DO CASE CASE loReg.ObjType == "1" loReg.TAG = THIS.decode_SpecialCodes_1_31( loReg.TAG ) CASE loReg.ObjType == "25" loReg.TAG = SUBSTR(loReg.TAG,3) && Quito el ENTER agregado antes OTHERWISE loReg.TAG = THIS.decode_SpecialCodes_1_31( loReg.TAG ) ENDCASE CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'tag2' ) *-- ARREGLO ALGUNOS VALORES CAMBIADOS AL TEXTUALIZAR loReg.TAG2 = STRCONV( loReg.TAG2,14 ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'penred' ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'style' ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'expr' ) CASE .analizarBloque_CDATA_inline( toReport, @tcLine, @taCodeLines, @I, tnCodeLines, @loReg, 'user' ) ENDCASE ENDFOR ENDWITH && THIS I = I - 1 toReport.ADD( loReg ) ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN llBloqueEncontrado ENDPROC ENDDEFINE && CLASS c_conversor_prg_a_frx AS c_conversor_prg_a_bin ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_dbf OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toTable (@! OUT) Objeto generado de clase CL_TABLE con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toTable, toEx AS EXCEPTION, toFoxbin2prg DODEFAULT( @toTable, @toEx ) #IF .F. LOCAL toTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, loEx AS EXCEPTION, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo del reporte THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toTable ) THIS.escribirArchivoBin( @toTable ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toTable *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lnCodError, loEx AS EXCEPTION LOCAL loField AS CL_DBF_FIELD OF 'FOXBIN2PRG.PRG' LOCAL loIndex AS CL_DBF_INDEX OF 'FOXBIN2PRG.PRG' LOCAL lcCreateTable, lcLongDec, lcFieldDef, lcIndex, ldLastUpdate, lcTempDBC LOCAL loDBFUtils AS CL_DBF_UTILS OF 'FOXBIN2PRG.PRG' loDBFUtils = CREATEOBJECT('CL_DBF_UTILS') STORE 0 TO lnCodError STORE '' TO lcIndex, lcFieldDef ERASE (FORCEEXT(THIS.c_OutputFile, 'DBF')) ERASE (FORCEEXT(THIS.c_OutputFile, 'FPT')) ERASE (FORCEEXT(THIS.c_OutputFile, 'CDX')) IF EMPTY(toTable._Database) lcCreateTable = 'CREATE TABLE "' + THIS.c_OutputFile + '" FREE CodePage=' + toTable._CodePage + ' (' ELSE lcTempDBC = FORCEPATH( '_FB2P', JUSTPATH(THIS.c_OutputFile) ) CREATE DATABASE ( lcTempDBC ) lcCreateTable = 'CREATE TABLE "' + THIS.c_OutputFile + '" CodePage=' + toTable._CodePage + ' (' ENDIF *-- Conformo los campos FOR EACH loField IN toTable._Fields FOXOBJECT lcLongDec = '' *-- Nombre, Tipo lcFieldDef = lcFieldDef + ', ' + loField._Name + ' ' + loField._Type *-- Longitud IF INLIST( loField._Type, 'C', 'N', 'F', 'Q', 'V' ) lcLongDec = lcLongDec + '(' + loField._Width ENDIF *-- Decimales IF INLIST( loField._Type, 'B', 'N', 'F' ) AND loField._Decimals > '0' IF EMPTY(lcLongDec) lcLongDec = lcLongDec + '(' ELSE lcLongDec = lcLongDec + ',' ENDIF lcLongDec = lcLongDec + loField._Decimals ENDIF IF NOT EMPTY(lcLongDec) lcLongDec = lcLongDec + ')' ENDIF lcFieldDef = lcFieldDef + lcLongDec *-- Null lcFieldDef = lcFieldDef + IIF( loField._Null = '.T.', ' NULL', ' NOT NULL' ) *-- NoCPTran IF loField._NoCPTran = '.T.' lcFieldDef = lcFieldDef + ' NOCPTRANS' ENDIF *-- AutoInc IF loField._AutoInc_NextVal <> '0' lcFieldDef = lcFieldDef + ' AUTOINC NEXTVAL ' + loField._AutoInc_NextVal + ' STEP ' + loField._AutoInc_Step ENDIF loField = NULL ENDFOR lcCreateTable = lcCreateTable + SUBSTR(lcFieldDef,3) + ')' &lcCreateTable. *-- Regenero los índices FOR EACH loIndex IN toTable._Indexes FOXOBJECT lcIndex = 'INDEX ON ' + loIndex._Key + ' TAG ' + loIndex._TagName IF loIndex._TagType = 'BINARY' lcIndex = lcIndex + ' BINARY' ELSE lcIndex = lcIndex + ' COLLATE "' + loIndex._Collate + '"' IF NOT EMPTY(loIndex._Filter) lcIndex = lcIndex + ' FOR ' + loIndex._Filter ENDIF lcIndex = lcIndex + ' ' + loIndex._Order IF NOT INLIST(loIndex._TagType, 'NORMAL', 'REGULAR') *-- Si es PRIMARY lo cambio a CANDIDATE y luego lo recodifico lcIndex = lcIndex + ' ' + STRTRAN( loIndex._TagType, 'PRIMARY', 'CANDIDATE' ) ENDIF ENDIF &lcIndex. ENDFOR USE IN (SELECT(JUSTSTEM(THIS.c_OutputFile))) *-- La actualización de la fecha sirve para evitar diferencias al regenerar el DBF ldLastUpdate = EVALUATE( '{^' + toTable._LastUpdate + '}' ) loDBFUtils.write_DBC_BackLink( THIS.c_OutputFile, toTable._Database, ldLastUpdate ) CATCH TO loEx lnCodError = loEx.ERRORNO loEx.USERVALUE = 'lcIndex="' + TRANSFORM(lcIndex) + '"' + CR_LF ; + 'lcFieldDef="' + TRANSFORM(lcFieldDef) + '"' + CR_LF ; + 'lcCreateTable="' + TRANSFORM(lcCreateTable) + '"' IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT(JUSTSTEM(THIS.c_OutputFile))) IF NOT EMPTY(lcTempDBC) CLOSE DATABASES ERASE (FORCEEXT(lcTempDBC,'DBC')) ERASE (FORCEEXT(lcTempDBC,'DCT')) ERASE (FORCEEXT(lcTempDBC,'DCX')) ENDIF ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (?@ IN ) Sin uso * tnBloquesExclusion (?@ IN ) Sin uso * toTable (?@ OUT) Objeto con toda la información de la tabla analizada *-------------------------------------------------------------------------------------------------------------- LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toTable EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lc_Comentario, lcLine, llFoxBin2Prg_Completed, llBloqueTable_Completed STORE 0 TO I THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 toTable = NULL toTable = CREATEOBJECT('CL_DBF_TABLE') WITH THIS FOR I = 1 TO tnCodeLines .set_Line( @lcLine, @taCodeLines, I ) IF .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Vacía o solo Comentarios LOOP ENDIF DO CASE CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toTable, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE NOT llBloqueTable_Completed AND toTable.analizarBloque( @lcLine, @taCodeLines, @I, tnCodeLines ) llBloqueTable_Completed = .T. ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ENDDEFINE && CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_dbc AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_dbc OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toDatabase (@! OUT) Objeto generado de clase CL_DBC con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toDatabase, toEx AS EXCEPTION, toFoxbin2prg DODEFAULT( @toDatabase, @toEx ) #IF .F. LOCAL toDatabase AS CL_DBC OF 'FOXBIN2PRG.PRG' LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, loEx AS EXCEPTION, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion, I STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo la tabla *THIS.createTable() *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo del reporte THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toDatabase ) THIS.escribirArchivoBin( @toDatabase ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE escribirArchivoBin LPARAMETERS toDatabase *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toDatabase AS CL_DBC OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, lcCreateTable, lcLongDec, lcFieldDef, lcIndex, ldLastUpdate lnCodError = 0 STORE '' TO lcIndex, lcFieldDef toDatabase.updateDBC( THIS.c_OutputFile ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lnCodError ENDPROC ******************************************************************************************************************* PROCEDURE identificarBloquesDeCodigo *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (?@ IN ) Sin uso * tnBloquesExclusion (?@ IN ) Sin uso * toDatabase (?@ OUT) Objeto con toda la información de la base de datos analizada * * NOTA: * Como identificador se usa el nombre de clase o de procedimiento, según corresponda. *-------------------------------------------------------------------------------------------------------------- LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toDatabase EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toDatabase AS CL_DBC OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lc_Comentario, lcLine, llFoxBin2Prg_Completed, llBloqueDatabase_Completed STORE 0 TO I THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 toDatabase = NULL toDatabase = CREATEOBJECT('CL_DBC') WITH THIS FOR I = 1 TO tnCodeLines .set_Line( @lcLine, @taCodeLines, I ) IF .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Vacía o solo Comentarios LOOP ENDIF DO CASE CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toDatabase, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE NOT llBloqueDatabase_Completed AND toDatabase.analizarBloque( @lcLine, @taCodeLines, @I, tnCodeLines ) llBloqueDatabase_Completed = .T. ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ENDDEFINE && CLASS c_conversor_prg_a_dbc AS c_conversor_prg_a_bin ******************************************************************************************************************* DEFINE CLASS c_conversor_prg_a_mnx AS c_conversor_prg_a_bin #IF .F. LOCAL THIS AS c_conversor_prg_a_mnx OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] n_MenuType = 0 c_MenuLocation = '' ******************************************************************************************************************* PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toMenu (@! OUT) Objeto generado de clase CL_DBC con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toMenu, toEx AS EXCEPTION, toFoxbin2prg DODEFAULT( @toMenu, @toEx ) #IF .F. LOCAL toMenu AS CL_MENU OF 'FOXBIN2PRG.PRG' LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, loEx AS EXCEPTION, loReg, lcLine, laCodeLines(1), lnCodeLines, lnFB2P_Version, lcSourceFile ; , laBloquesExclusion(1,2), lnBloquesExclusion STORE 0 TO lnCodError, lnCodeLines, lnFB2P_Version STORE '' TO lcLine, lcSourceFile STORE NULL TO loReg, toModulo C_FB2PRG_CODE = FILETOSTR( THIS.c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxbin2prg.doBackup( .F., .T., '', '', '' ) *-- Creo la tabla THIS.createMenu() *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo del reporte THIS.identificarBloquesDeCodigo( @laCodeLines, lnCodeLines, @laBloquesExclusion, lnBloquesExclusion, @toMenu ) THIS.escribirArchivoBin( @toMenu ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT("TABLABIN")) ENDTRY RETURN lnCodError ENDPROC PROCEDURE identificarBloquesDeCodigo *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * taCodeLines (!@ IN ) El array con las líneas del código donde buscar * tnCodeLines (!@ IN ) Cantidad de líneas de código * taBloquesExclusion (?@ IN ) Sin uso * tnBloquesExclusion (?@ IN ) Sin uso * toMenu (?@ OUT) Objeto con toda la información del menú analizado * * NOTA: * Como identificador se usa el nombre de clase o de procedimiento, según corresponda. *-------------------------------------------------------------------------------------------------------------- LPARAMETERS taCodeLines, tnCodeLines, taBloquesExclusion, tnBloquesExclusion, toMenu EXTERNAL ARRAY taCodeLines, taBloquesExclusion #IF .F. LOCAL toMenu AS CL_MENU OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL I, lc_Comentario, lcLine, llFoxBin2Prg_Completed, llBloqueMenu_Completed STORE 0 TO I THIS.c_Type = UPPER(JUSTEXT(THIS.c_OutputFile)) IF tnCodeLines > 1 toMenu = NULL toMenu = CREATEOBJECT('CL_MENU') WITH THIS FOR I = 1 TO tnCodeLines .set_Line( @lcLine, @taCodeLines, I ) IF .lineIsOnlyCommentAndNoMetadata( @lcLine, @lc_Comentario ) && Vacía o solo Comentarios LOOP ENDIF DO CASE CASE NOT llFoxBin2Prg_Completed AND .analizarBloque_FoxBin2Prg( toMenu, @lcLine, @taCodeLines, @I, tnCodeLines ) llFoxBin2Prg_Completed = .T. CASE NOT llBloqueMenu_Completed AND toMenu.analizarBloque( @lcLine, @taCodeLines, @I, tnCodeLines, THIS ) llBloqueMenu_Completed = .T. ENDCASE ENDFOR ENDWITH && THIS ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC PROCEDURE escribirArchivoBin *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toMenu (@! OUT) Objeto generado de clase CL_DBC con la información leida del texto *--------------------------------------------------------------------------------------------------- LPARAMETERS toMenu #IF .F. LOCAL toMenu AS CL_MENU OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lnCodError, lcCreateTable, lcLongDec, lcFieldDef, lcIndex, ldLastUpdate lnCodError = 0 STORE '' TO lcIndex, lcFieldDef toMenu.updateMENU( THIS ) CATCH TO loEx lnCodError = loEx.ERRORNO IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW FINALLY USE IN (SELECT(JUSTSTEM(THIS.c_OutputFile))) ENDTRY RETURN lnCodError ENDPROC ENDDEFINE && CLASS c_conversor_prg_a_mnx AS c_conversor_prg_a_bin ******************************************************************************************************************* DEFINE CLASS c_conversor_bin_a_prg AS c_conversor_base #IF .F. LOCAL THIS AS c_conversor_bin_a_prg OF 'FOXBIN2PRG.PRG' #ENDIF _MEMBERDATA = [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ; + [] ******************************************************************************************************************* PROCEDURE Convertir *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * toModulo (@! OUT) Objeto generado de clase correspondiente con la información leida del texto * toEx (@! OUT) Objeto con información del error * toFoxbin2prg (v! IN ) Referencia al objeto principal *--------------------------------------------------------------------------------------------------- LPARAMETERS toModulo, toEx AS EXCEPTION, toFoxbin2prg #IF .F. LOCAL toFoxbin2prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' #ENDIF DODEFAULT( @toModulo, @toEx ) ENDPROC ******************************************************************************************************************* PROCEDURE get_ADD_OBJECT_METHODS LPARAMETERS toRegObj, toRegClass, tcMethods, taMethods, taCode, tnMethodCount TRY THIS.SortMethod( toRegObj.METHODS, @taMethods, @taCode, '', @tnMethodCount ) *-- Ubico los métodos protegidos y les cambio la definición. *-- Los métodos se deben generar con la ruta completa, porque si no es imposible saber a que objeto corresponden, *-- o si son de la clase. IF tnMethodCount > 0 THEN FOR I = 1 TO tnMethodCount IF EMPTY(toRegObj.PARENT) tcMethodName = toRegObj.OBJNAME + '.' + taMethods(I,1) ELSE DO CASE CASE '.' $ toRegObj.PARENT tcMethodName = SUBSTR(toRegObj.PARENT, AT('.', toRegObj.PARENT) + 1) + '.' + toRegObj.OBJNAME + '.' + taMethods(I,1) CASE LEFT(toRegObj.PARENT + '.', LEN( toRegClass.OBJNAME + '.' ) ) == toRegClass.OBJNAME + '.' tcMethodName = toRegObj.OBJNAME + '.' + taMethods(I,1) OTHERWISE tcMethodName = toRegObj.PARENT + '.' + toRegObj.OBJNAME + '.' + taMethods(I,1) ENDCASE ENDIF *-- Genero el método SIN indentar, ya que se hace luego *tcMethods2 = tcMethods *TEXT TO tcMethods2 ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 * <<'PROCEDURE'>> <> * <> * <<'ENDPROC'>> *ENDTEXT *-- Sustituyo el TEXT/ENDTEXT aquí porque a veces quita espacios de la derecha, y eso es peligroso tcMethods = tcMethods + CR_LF + 'PROCEDURE ' + tcMethodName tcMethods = tcMethods + CR_LF + THIS.IndentarMemo( taCode(taMethods(I,2)) ) tcMethods = tcMethods + CR_LF + 'ENDPROC' ENDFOR ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE get_NombresObjetosOLEPublic LPARAMETERS ta_NombresObjsOle *-- Obtengo los objetos "OLEPublic" SELECT PADR(OBJNAME,100) OBJNAME ; FROM TABLABIN ; WHERE TABLABIN.PLATFORM = "COMMENT" AND TABLABIN.RESERVED2 == "OLEPublic" ; ORDER BY 1 ; INTO ARRAY ta_NombresObjsOle ENDPROC ******************************************************************************************************************* PROCEDURE get_PropsAndCommentsFrom_RESERVED3 *-- Sirve para el memo RESERVED3 *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcMemo (v! IN ) Contenido de un campo MEMO * tlSort (v? IN ) Indica si se deben ordenar alfabéticamente los nombres * taPropsAndComments (@! OUT) Array con las propiedades y comentarios * tnPropsAndComments_Count (@! OUT) Cantidad de propiedades * tcSortedMemo (@? OUT) Contenido del campo memo ordenado *--------------------------------------------------------------------------------------------------- LPARAMETERS tcMemo, tlSort, taPropsAndComments, tnPropsAndComments_Count, tcSortedMemo EXTERNAL ARRAY taPropsAndComments TRY LOCAL laLines(1), I, lnPos, loEx AS EXCEPTION tcSortedMemo = '' tnPropsAndComments_Count = ALINES(laLines, tcMemo, 1+4) IF tnPropsAndComments_Count <= 1 AND EMPTY(laLines) tnPropsAndComments_Count = 0 EXIT ENDIF DIMENSION taPropsAndComments(tnPropsAndComments_Count,2) FOR I = 1 TO tnPropsAndComments_Count lnPos = AT(' ', laLines(I)) && Un espacio separa la propiedad de su comentario (si tiene) IF lnPos = 0 taPropsAndComments(I,1) = laLines(I) taPropsAndComments(I,2) = '' ELSE taPropsAndComments(I,1) = LEFT( laLines(I), lnPos - 1 ) taPropsAndComments(I,2) = SUBSTR( laLines(I), lnPos + 1 ) ENDIF ENDFOR IF tlSort AND THIS.l_PropSort_Enabled ASORT( taPropsAndComments, 1, -1, 0, 1 ) ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE get_PropsAndValuesFrom_PROPERTIES *-- Sirve para el memo PROPERTIES *--------------------------------------------------------------------------------------------------- * KNOWLEDGE BASE: * 29/11/2013 FDBOZZO En un pageframe, si las props.nativas del mismo no están antes que las de * los objetos contenidos, causa un error. Se deben ordenar primero las * props.nativas (sin punto) y luego las de los objetos (con punto) * *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcMemo (v! IN ) Contenido de un campo MEMO * tnSort (v? IN ) Indica si se deben ordenar alfabéticamente los objetos y props (1), o no (0) * taPropsAndValues (@! OUT) Array con las propiedades y comentarios * tnPropsAndValues_Count (@! OUT) Cantidad de propiedades * tcSortedMemo (@? OUT) Contenido del campo memo ordenado *--------------------------------------------------------------------------------------------------- LPARAMETERS tcMemo, tnSort, taPropsAndValues, tnPropsAndValues_Count, tcSortedMemo EXTERNAL ARRAY taPropsAndValues TRY LOCAL laItems(1), I, X, lnLenAcum, lnPosEQ, lcPropName, lnLenVal, lcValue, lcMethods tcSortedMemo = '' tnPropsAndValues_Count = 0 IF NOT EMPTY(m.tcMemo) lnItemCount = ALINES(laItems, m.tcMemo, 0, CR_LF) && Específicamente CR+LF para que no reconozca los CR o LF por separado X = 0 IF lnItemCount <= 1 AND EMPTY(laItems) lnItemCount = 0 EXIT ENDIF *-- 1) OBTENCIÓN Y SEPARACIÓN DE PROPIEDADES Y VALORES *-- Crear un array con los valores especiales que pueden estar repartidos entre varias lineas FOR I = 1 TO m.lnItemCount IF EMPTY( laItems(I) ) LOOP ENDIF X = X + 1 DIMENSION taPropsAndValues(X,2) IF C_MPROPHEADER $ laItems(I) *-- Solo entrará por aquí cuando se evalúe una propiedad de PROPERTIES con un valor especial (largo) lnLenAcum = 0 lnPosEQ = AT( '=', laItems(I) ) lcPropName = LEFT( laItems(I), lnPosEQ - 2 ) lnLenVal = INT( VAL( SUBSTR( laItems(I), lnPosEQ + 2 + 517, 8) ) ) lcValue = SUBSTR( laItems(I), lnPosEQ + 2 + 517 + 8 ) IF LEN( lcValue ) < lnLenVal *-- Como el valor es multi-línea, debo agregarle los CR_LF que le quitó el ALINES() FOR I = I + 1 TO m.lnItemCount lcValue = lcValue + CR_LF + laItems(I) IF LEN( lcValue ) >= lnLenVal EXIT ENDIF ENDFOR lcValue = C_FB2P_VALUE_I + CR_LF + lcValue + CR_LF + C_FB2P_VALUE_F ELSE lcValue = C_FB2P_VALUE_I + lcValue + C_FB2P_VALUE_F ENDIF *-- Es un valor especial, por lo que se encapsula en un marcador especial taPropsAndValues(X,1) = lcPropName taPropsAndValues(X,2) = THIS.normalizarValorPropiedad( lcPropName, lcValue, '' ) ELSE *-- Propiedad normal *-- SI HACE FALTA QUE LOS MÉTODOS ESTÉN AL FINAL, DESCOMENTAR ESTO (Y EL DE MÁS ABAJO) *IF LEFT(laItems(I), 1) == '*' && Only Reserved3 have this * LOOP *ENDIF lnPosEQ = AT( '=', laItems(I) ) taPropsAndValues(X,1) = LEFT( laItems(I), lnPosEQ - 2 ) taPropsAndValues(X,2) = THIS.normalizarValorPropiedad( taPropsAndValues(X,1), LTRIM( SUBSTR( laItems(I), lnPosEQ + 2 ) ), '' ) ENDIF ENDFOR tnPropsAndValues_Count = X lcMethods = '' *-- 2) SORT THIS.sortPropsAndValues( @taPropsAndValues, tnPropsAndValues_Count, tnSort ) *-- Agregar propiedades primero FOR I = 1 TO m.tnPropsAndValues_Count *-- SI HACE FALTA QUE LOS MÉTODOS ESTÉN AL FINAL, DESCOMENTAR ESTO (Y EL DE MÁS ARRIBA) *IF LEFT(taPropsAndValues(I), 1) == '*' && Only Reserved3 have this * lcMethods = m.lcMethods + m.taPropsAndValues(I,1) + ' = ' + m.taPropsAndValues(I,2) + CR_LF * LOOP *ENDIF tcSortedMemo = m.tcSortedMemo + m.taPropsAndValues(I,1) + ' = ' + m.taPropsAndValues(I,2) + CR_LF ENDFOR *-- Agregar métodos al final tcSortedMemo = m.tcSortedMemo + m.lcMethods ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE get_PropsFrom_PROTECTED *-- Sirve para el memo PROTECTED *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) * tcMemo (v! IN ) Contenido de un campo MEMO * tlSort (v? IN ) Indica si se deben ordenar alfabéticamente los nombres * taProtected (@! OUT) Array con las propiedades y comentarios * tnProtected_Count (@! OUT) Cantidad de propiedades * tcSortedMemo (@? OUT) Contenido del campo memo ordenado *--------------------------------------------------------------------------------------------------- LPARAMETERS tcMemo, tlSort, taProtected, tnProtected_Count, tcSortedMemo EXTERNAL ARRAY taProtected tcSortedMemo = '' tnProtected_Count = ALINES(taProtected, tcMemo, 1+4) IF tnProtected_Count <= 1 AND EMPTY(taProtected) tnProtected_Count = 0 ELSE IF tlSort AND THIS.l_PropSort_Enabled ASORT( taProtected, 1, -1, 0, 1 ) ENDIF FOR I = 1 TO tnProtected_Count tcSortedMemo = tcSortedMemo + taProtected(I) + CR_LF ENDFOR ENDIF RETURN ENDPROC ******************************************************************************************************************* PROCEDURE IndentarMemo LPARAMETERS tcMethod, tcIndentation *-- INDENTA EL CÓDIGO DE UN MÉTODO DADO Y QUITA LA CABECERA DE MÉTODO (PROCEDURE/ENDPROC) SI LA ENCUENTRA TRY LOCAL I, X, lcMethod, llProcedure, lnInicio, lnFin, laLineas(1) lcMethod = '' llProcedure = ( LEFT(tcMethod,10) == 'PROCEDURE ' ; OR LEFT(tcMethod,17) == 'HIDDEN PROCEDURE ' ; OR LEFT(tcMethod,20) == 'PROTECTED PROCEDURE ' ) lnInicio = 1 lnFin = ALINES(laLineas, tcMethod) IF VARTYPE(tcIndentation) # 'C' tcIndentation = '' ENDIF *-- Quito las líneas en blanco luego del final del ENDPROC X = 0 FOR I = lnFin TO 1 STEP -1 IF NOT EMPTY(laLineas(I)) && Última línea de código IF LEFT( laLineas(I), 10 ) <> C_ENDPROC ERROR 'Procedimiento sin cerrar. La última línea de código debe ser ENDPROC. [' + laLineas(1) + ']' ENDIF EXIT ENDIF X = X + 1 ENDFOR IF X > 0 lnFin = lnFin - X DIMENSION laLineas(lnFin) ENDIF *-- Si encuentra la cabecera de un PROCEDURE, la saltea IF llProcedure lnInicio = 2 lnFin = lnFin - 1 ENDIF FOR I = lnInicio TO lnFin *-- TEXT/ENDTEXT aquí da error 2044 de recursividad. No usar. lcMethod = lcMethod + CR_LF + tcIndentation + laLineas(I) ENDFOR lcMethod = SUBSTR(lcMethod,3) && Quito el primer ENTER (CR+LF) CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lcMethod ENDPROC ******************************************************************************************************************* PROCEDURE MemoInOneLine( tcMethod ) TRY LOCAL lcLine, I lcLine = '' IF NOT EMPTY(tcMethod) FOR I = 1 TO ALINES(laLines, m.tcMethod, 0) lcLine = lcLine + ', ' + laLines(I) ENDFOR lcLine = SUBSTR(lcLine, 3) ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lcLine ENDPROC ******************************************************************************************************************* PROCEDURE set_MultilineMemoWithAddObjectProperties LPARAMETERS taPropsAndValues, tnPropCount, tcLeftIndentation, tlNormalizeLine EXTERNAL ARRAY taPropsAndValues TRY LOCAL lcLine, I, lcComentarios, laLines(1), lcFinDeLinea_Coma_PuntoComa_CR lcLine = '' lcFinDeLinea = ', ;' + CR_LF IF tnPropCount > 0 IF VARTYPE(tcLeftIndentation) # 'C' tcLeftIndentation = '' ENDIF FOR I = 1 TO tnPropCount lcLine = lcLine + tcLeftIndentation + taPropsAndValues(I,1) + ' = ' + taPropsAndValues(I,2) + lcFinDeLinea ENDFOR *-- Quito el ", ;" final lcLine = tcLeftIndentation + SUBSTR(lcLine, 1 + LEN(tcLeftIndentation), LEN(lcLine) - LEN(tcLeftIndentation) - LEN(lcFinDeLinea)) ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN lcLine ENDPROC ******************************************************************************************************************* PROCEDURE SortMethod LPARAMETERS tcMethod, taMethods, taCode, tcSorted, tnMethodCount *-- 29/10/2013 Fernando D. Bozzo *-- Se tiene en cuenta la posibilidad de que haya un PROC/ENDPROC dentro de un TEXT/ENDTEXT *-- cuando es usado en un generador de código o similar. EXTERNAL ARRAY taMethods, taCode *-- ESTRUCTURA DE LOS ARRAYS CREADOS: *-- taMethods[1,3] *-- Nombre Método *-- Posición Original *-- Tipo (HIDDEN/PROTECTED/NORMAL) *-- taCode[1] *-- Bloque de código del método en su posición original TRY LOCAL lnLineCount, laLine(1), I, lnTextNodes, tcSorted LOCAL loEx AS EXCEPTION DIMENSION taMethods(1,3) STORE '' TO taMethods, m.tcSorted, taCode tnMethodCount = 0 IF NOT EMPTY(m.tcMethod) AND LEFT(m.tcMethod,9) == "ENDPROC"+CHR(13)+CHR(10) tcMethod = SUBSTR(m.tcMethod,10) ENDIF IF NOT EMPTY(m.tcMethod) DIMENSION laLine(1), taMethods(1,3) STORE '' TO laLine, taMethods, taCode STORE 0 TO tnMethodCount, lnTextNodes lnLineCount = ALINES(laLine, m.tcMethod) && NO aplicar nungún formato ni limpieza, que es el CÓDIGO FUENTE *-- Delete beginning empty lines before first "PROCEDURE", that is the first not empty line. FOR I = 1 TO lnLineCount IF NOT EMPTY(laLine(I)) IF I > 1 FOR X = I-1 TO 1 STEP -1 ADEL(laLine, X) ENDFOR lnLineCount = lnLineCount - I + 1 DIMENSION laLine(lnLineCount) ENDIF EXIT ENDIF ENDFOR *-- Delete ending empty lines after last "ENDPROC", that is the last not empty line. FOR I = lnLineCount TO 1 STEP -1 IF EMPTY(laLine(I)) ADEL(laLine, I) ELSE IF I < lnLineCount lnLineCount = I DIMENSION laLine(lnLineCount) ENDIF EXIT ENDIF ENDFOR *-- Analyze and count line methods, get method names and consolidate block code FOR I = 1 TO lnLineCount DO CASE CASE LEFT(laLine(I), 4) == C_TEXT lnTextNodes = lnTextNodes + 1 taCode(tnMethodCount) = taCode(tnMethodCount) + laLine(I) + CR_LF CASE LEFT(laLine(I), 7) == C_ENDTEXT lnTextNodes = lnTextNodes - 1 taCode(tnMethodCount) = taCode(tnMethodCount) + laLine(I) + CR_LF CASE lnTextNodes = 0 AND LEFT(laLine(I), 10) == 'PROCEDURE ' tnMethodCount = tnMethodCount + 1 DIMENSION taMethods(tnMethodCount, 3), taCode(tnMethodCount) taMethods(tnMethodCount, 1) = RTRIM( SUBSTR(laLine(I), 11) ) taMethods(tnMethodCount, 2) = tnMethodCount taMethods(tnMethodCount, 3) = '' taCode(tnMethodCount) = laLine(I) + CR_LF CASE lnTextNodes = 0 AND LEFT(laLine(I), 17) == 'HIDDEN PROCEDURE ' tnMethodCount = tnMethodCount + 1 DIMENSION taMethods(tnMethodCount, 3), taCode(tnMethodCount) taMethods(tnMethodCount, 1) = RTRIM( SUBSTR(laLine(I), 18) ) taMethods(tnMethodCount, 2) = tnMethodCount taMethods(tnMethodCount, 3) = 'HIDDEN ' taCode(tnMethodCount) = laLine(I) + CR_LF CASE lnTextNodes = 0 AND LEFT(laLine(I), 20) == 'PROTECTED PROCEDURE ' tnMethodCount = tnMethodCount + 1 DIMENSION taMethods(tnMethodCount, 3), taCode(tnMethodCount) taMethods(tnMethodCount, 1) = RTRIM( SUBSTR(laLine(I), 21) ) taMethods(tnMethodCount, 2) = tnMethodCount taMethods(tnMethodCount, 3) = 'PROTECTED ' taCode(tnMethodCount) = laLine(I) + CR_LF CASE lnTextNodes = 0 AND LEFT(laLine(I), 7) == 'ENDPROC' taCode(tnMethodCount) = taCode(tnMethodCount) + laLine(I) + CR_LF CASE tnMethodCount = 0 && Skip empty lines before methods begin OTHERWISE && Method Code taCode(tnMethodCount) = taCode(tnMethodCount) + laLine(I) + CR_LF ENDCASE ENDFOR *-- Alphabetical ordering of methods IF THIS.l_MethodSort_Enabled ASORT(taMethods,1,-1,0,1) ENDIF FOR I = 1 TO tnMethodCount m.tcSorted = m.tcSorted + taCode(taMethods(I,2)) ENDFOR ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC && SordMethod ******************************************************************************************************************* PROCEDURE write_ADD_OBJECTS_WithProperties LPARAMETERS toRegObj #IF .F. LOCAL toRegObj AS CL_OBJETO OF 'FOXBIN2PRG.PRG' #ENDIF TRY LOCAL lcMemo, laPropsAndValues(1,2), lnPropsAndValues_Count *-- Defino los objetos a cargar THIS.get_PropsAndValuesFrom_PROPERTIES( toRegObj.PROPERTIES, 1, @laPropsAndValues, @lnPropsAndValues_Count, @lcMemo ) *lcMemo = THIS.set_MultilineMemoWithAddObjectProperties( lcMemo, C_TAB + C_TAB, .T. ) lcMemo = THIS.set_MultilineMemoWithAddObjectProperties( @laPropsAndValues, @lnPropsAndValues_Count, C_TAB + C_TAB, .T. ) IF '.' $ toRegObj.PARENT *-- Este caso: clase.objeto.objeto ==> se quita clase TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> ADD OBJECT '<>.<>' AS <> <<>> ENDTEXT ELSE *-- Este caso: objeto TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> ADD OBJECT '<>' AS <> <<>> ENDTEXT ENDIF IF NOT EMPTY(lcMemo) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <> ; <> ENDTEXT ENDIF TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <><> <<>> ENDTEXT IF NOT EMPTY(toRegObj.CLASSLOC) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 ClassLib="<>" <<>> ENDTEXT ENDIF TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2+4+8 BaseClass="<>" UniqueID="<>" Timestamp="<>" ZOrder="<>" <<>> ENDTEXT *-- Agrego metainformación para objetos OLE IF toRegObj.BASECLASS == 'olecontrol' TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 OLEObject="<> <>PROCEDURE <> * <> * <<>> ENDPROC *ENDTEXT *-- Sustituyo el TEXT/ENDTEXT aquí porque a veces quita espacios de la derecha, y eso es peligroso lcMethods = lcMethods + CR_LF + C_TAB + laMethods(I,3) + C_PROCEDURE + ' ' + laMethods(I,1) lcMethods = lcMethods + CR_LF + THIS.IndentarMemo( laCode(laMethods(I,2)), CHR(9) + CHR(9) ) lcMethods = lcMethods + CR_LF + C_TAB + C_ENDPROC lcMethods = lcMethods + CR_LF ENDFOR C_FB2PRG_CODE = C_FB2PRG_CODE + lcMethods ENDIF RETURN ENDPROC ******************************************************************************************************************* PROCEDURE write_CLASS_METHODS LPARAMETERS tnMethodCount, taMethods, taCode, taProtected, taPropsAndComments *-- DEFINIR MÉTODOS DE LA CLASE *-- Ubico los métodos protegidos y les cambio la definición EXTERNAL ARRAY taMethods, taCode, taProtected, taPropsAndComments TRY LOCAL lcMethod, lnProtectedItem, lnCommentRow, lcProcDef, lcMethods, lcMethods2 STORE '' TO lcMethod, lcProcDef, lcMethods, lcMethods2 IF tnMethodCount > 0 THEN FOR I = 1 TO tnMethodCount lcMethod = CHRTRAN( taMethods(I,1), '^', '' ) lnProtectedItem = ASCAN( taProtected, taMethods(I,1), 1, 0, 0, 0) lnCommentRow = ASCAN( taPropsAndComments, '*' + lcMethod, 1, 0, 1, 8) DO CASE CASE lnProtectedItem = 0 *-- Método común lcProcDef = 'PROCEDURE' CASE taProtected(lnProtectedItem) == taMethods(I,1) *-- Método protegido lcProcDef = 'PROTECTED PROCEDURE' CASE taProtected(lnProtectedItem) == taMethods(I,1) + '^' *-- Método oculto lcProcDef = 'HIDDEN PROCEDURE' ENDCASE *-- Nombre del método TEXT TO lcMethods ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> <> <> ENDTEXT *-- Comentarios del método (si tiene) IF lnCommentRow > 0 AND NOT EMPTY(taPropsAndComments(lnCommentRow,2)) TEXT TO lcMethods ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <<>> && <> ENDTEXT ENDIF *-- Código del método *TEXT TO lcMethods2 ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 * <> * <<>> ENDPROC *ENDTEXT *-- Sustituyo el TEXT/ENDTEXT aquí porque a veces quita espacios de la derecha, y eso es peligroso lcMethods = lcMethods + CR_LF + THIS.IndentarMemo( taCode(taMethods(I,2)), C_TAB + C_TAB ) lcMethods = lcMethods + CR_LF + C_TAB + 'ENDPROC' lcMethods = lcMethods + CR_LF ENDFOR *TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 * <> *ENDTEXT C_FB2PRG_CODE = C_FB2PRG_CODE + C_TAB + lcMethods &&+ CR_LF ENDIF CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE write_CLASS_PROPERTIES LPARAMETERS toRegClass, taPropsAndValues, taPropsAndComments, taProtected EXTERNAL ARRAY taPropsAndValues, taPropsAndComments TRY LOCAL lnPropsAndValues_Count, lcHiddenProp, lcProtectedProp, lcPropsMethodsDefd, lnPropsAndComments_Count, I ; , lcPropName, lnProtectedItem, lcComentarios WITH THIS *-- DEFINIR PROPIEDADES ( HIDDEN, PROTECTED, *DEFINED_PAM ) DIMENSION taProtected(1) STORE '' TO lcHiddenProp, lcProtectedProp, lcPropsMethodsDefd THIS.get_PropsAndValuesFrom_PROPERTIES( toRegClass.PROPERTIES, 1, @taPropsAndValues, @lnPropsAndValues_Count, '' ) THIS.get_PropsAndCommentsFrom_RESERVED3( toRegClass.RESERVED3, .T., @taPropsAndComments, @lnPropsAndComments_Count, '' ) THIS.get_PropsFrom_PROTECTED( toRegClass.PROTECTED, .T., @taProtected, 0, '' ) IF lnPropsAndValues_Count > 0 THEN *-- Recorro las propiedades (campo Properties) para ir conformando *-- las definiciones HIDDEN y PROTECTED FOR I = 1 TO lnPropsAndValues_Count IF EMPTY(taPropsAndValues(I,1)) LOOP ENDIF lnProtectedItem = ASCAN(taProtected, taPropsAndValues(I,1), 1, 0, 0, 0) DO CASE CASE lnProtectedItem = 0 *-- Propiedad común CASE taProtected(lnProtectedItem) == taPropsAndValues(I,1) *-- Propiedad protegida lcProtectedProp = lcProtectedProp + ',' + taPropsAndValues(I,1) CASE taProtected(lnProtectedItem) == taPropsAndValues(I,1) + '^' *-- Propiedad oculta lcHiddenProp = lcHiddenProp + ',' + taPropsAndValues(I,1) ENDCASE ENDFOR THIS.write_DEFINED_PAM( @taPropsAndComments, lnPropsAndComments_Count ) THIS.write_HIDDEN_Properties( @lcHiddenProp ) THIS.write_PROTECTED_Properties( @lcProtectedProp ) *-- Escribo las propiedades de la clase y sus comentarios (los comentarios aquí son redundantes) FOR I = 1 TO ALEN(taPropsAndValues, 1) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> <> = <> ENDTEXT lnComment = ASCAN( taPropsAndComments, taPropsAndValues(I,1), 1, 0, 1, 8) IF lnComment > 0 AND NOT EMPTY(taPropsAndComments(lnComment,2)) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <<>> && <> ENDTEXT ENDIF ENDFOR TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> ENDTEXT ENDIF ENDWITH && THIS CATCH TO loEx IF THIS.l_Debug AND _VFP.STARTMODE = 0 SET STEP ON ENDIF THROW ENDTRY RETURN ENDPROC ******************************************************************************************************************* PROCEDURE write_DEFINED_PAM *-- Escribo propiedades DEFINED (Reserved3) en este formato: * *m: *metodovacio_con_comentarios && Este método no tiene código, pero tiene comentarios. A ver que pasa! *m: *mimetodo && Mi metodo *p: prop1 && Mi prop 1 *p: prop_especial_cr && *a: ^array_1_d[1,0] && Array 1 dimensión (1) *a: ^array_2_d[1,2] && Array una dimension (1,2) *p: _memberdata && XML Metadata for customizable properties * LPARAMETERS taPropsAndComments, tnPropsAndComments_Count IF tnPropsAndComments_Count > 0 LOCAL I, lcPropsMethodsDefd lcPropsMethodsDefd = '' TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> <> ENDTEXT FOR I = 1 TO tnPropsAndComments_Count IF EMPTY(taPropsAndComments(I,1)) LOOP ENDIF lcType = LEFT( taPropsAndComments(I,1), 1 ) lcType = ICASE( lcType == '*', 'm' ; , lcType == '^', 'a' ; , 'p' ) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> *<>: <> ENDTEXT IF NOT EMPTY(taPropsAndComments(I,2)) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <<>> <<'&'>><<'&'>> <> ENDTEXT ENDIF ENDFOR TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> <> ENDTEXT ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE write_DEFINE_CLASS LPARAMETERS ta_NombresObjsOle, toRegClass LOCAL lcOF_Classlib, llOleObject lcOF_Classlib = '' llOleObject = ( ASCAN( ta_NombresObjsOle, toRegClass.OBJNAME, 1, 0, 1, 8) > 0 ) IF NOT EMPTY(toRegClass.CLASSLOC) lcOF_Classlib = 'OF "' + ALLTRIM(toRegClass.CLASSLOC) + '" ' ENDIF *-- DEFINICIÓN DE LA CLASE ( DEFINE CLASS 'className' AS 'classType' [OF 'classLib'] [OLEPUBLIC] ) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<'DEFINE CLASS'>> <> AS <> <> ENDTEXT ENDPROC ******************************************************************************************************************* PROCEDURE write_DEFINE_CLASS_COMMENTS LPARAMETERS toRegClass *-- Comentario de la clase IF NOT EMPTY(toRegClass.RESERVED7) THEN TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 <<>> <<'&'+'&'>> <> ENDTEXT ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE write_ENDDEFINE_SiCorresponde LPARAMETERS tnLastClass IF tnLastClass = 1 TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<'ENDDEFINE'>> <<>> ENDTEXT ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE write_INCLUDE LPARAMETERS toReg *-- #INCLUDE IF NOT EMPTY(toReg.RESERVED8) THEN TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> #INCLUDE "<>" ENDTEXT ENDIF ENDPROC ******************************************************************************************************************* PROCEDURE write_METADATA LPARAMETERS toRegClass *-- Agrego Metadatos de la clase (Baseclass, Timestamp, Scale, Uniqueid) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2+8 <<>> <> Baseclass="<>" Timestamp="<>" Scale="<>" Uniqueid="<>" ENDTEXT IF NOT EMPTY(toRegClass.OLE2) TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2+4+8 OLEObject="<' TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> platform="WINDOWS " uniqueid="<>" timestamp="<>" objtype="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 objcode="<>" name="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 vpos="<>" hpos="<>" height="<>" width="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 order="<>" unique="<>" comment="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 environ="<>" boxchar="<>" fillchar="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 pengreen="<>" penblue="<>" fillred="<>" fillgreen="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 fillblue="<>" pensize="<>" penpat="<>" fillpat="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 fontface="<>" fontstyle="<>" fontsize="<>" mode="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 ruler="<>" rulerlines="<>" grid="<>" gridv="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 gridh="<>" float="<>" stretch="<>" stretchtop="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 top="<>" bottom="<>" suptype="<>" suprest="<>" norepeat="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 resetrpt="<>" pagebreak="<>" colbreak="<>" resetpage="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 general="<>" spacing="<>" double="<>" swapheader="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 swapfooter="<>" ejectbefor="<>" ejectafter="<>" plain="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 summary="<>" addalias="<>" offset="<>" topmargin="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 botmargin="<>" totaltype="<>" resettotal="<>" resoid="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 curpos="<>" supalways="<>" supovflow="<>" suprpcol="<>" <<>> ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1 PRETEXT 1+2 supgroup="<>" supvalchng="<>" supexpr="<>" > ENDTEXT TEXT TO C_FB2PRG_CODE ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 <<>> >]]> <<>> >]]> <<>> >]]> <<>> >]]> <<>>