/****************************** Module Header ******************************* * * Module Name: recompile.e * * Copyright (c) Netlabs EPM Distribution Project 2002 * * $Id$ * * =========================================================================== * * This file is part of the Netlabs EPM Distribution package and is free * software. You can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * Netlabs EPM Distribution. This library is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * ****************************************************************************/ ; Recompile .e macros to linkable .ex files ; ; Main definitions: ; ; RecompileNew Recompiles all changed user macros. Creates .ex files ; = Recompile in myepm\ex. Eventually restarts EPM, if required. ; This is the main command for compilation of E macros. ; ; Etpm Calls the ETPM compiler for an E macro file. Creates an ; .ex file in either myepm\ex or the passed dir. Works on ; epm.e if no arg was specified. Accepts a basename or = ; as the current file as arg. ; ; Relink Compiles an .e file and relinks the resulted .ex file if ; it was linked before. ; ; RecompileEpm Compiles epm.e to myepm\ex\epm.ex and restarts EPM. ; That's similar to mc /etpm epm/restart. Unused. ; ; RecompileAll Compiles all macros, independant if changed or not. ; Creates .ex files in myepm\ex and restarts EPM. Unused. compile if not defined( SMALL) -- If compiled separately EA_comment 'Linkable commands for macro compilation.' define INCLUDING_FILE = 'RECOMPILE.E' include 'stdconst.e' const tryinclude 'mycnf.e' const compile if not defined( NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' compile endif ; --------------------------------------------------------------------------- const compile if not defined( RECOMPILE_RESTART_NAMES) -- These basenames require restart of EPM: -- EPM: obviously -- RECOMPILE: as tests showed -- FILE -- FILELIST -- STDCTRL -- MENU RECOMPILE_RESTART_NAMES = 'EPM RECOMPILE FILE FILELIST STDCTRL MENU' compile endif ; --------------------------------------------------------------------------- defc PostRelink parse arg Basename --dprintf( 'PostRelink called') -- Refresh menu if module is linked and defines a menu if upcase( rightstr( Basename, 4)) = 'MENU' & length( Basename) > 4 then 'RefreshMenu' endif -- Refresh keyset if module is linked and defines keys if upcase( rightstr( Basename, 4)) = 'KEYS' & length( Basename) > 4 then 'ReloadKeyset' endif ; --------------------------------------------------------------------------- ; Syntax: Relink [[][.e]] ; ; Compiles the module, unlinks it and links it again. A fast way to ; recompile/reload a macro under development without leaving the editor. ; Note that the unlink is necessary in case the module is already linked, ; else the link will merely reinitialize the previous version. ; ; Link module only, if it was linked before. ; ; If modulename is omitted, the current filename is assumed. ; New: Path and extension for modulename are not required. defc Relink do once = 1 to 1 Args = arg( 1) if IsNum( Args) then -- Handle number as arg n = Args FullPathName = GetAVar( 'linkfilename.'n) Basename = GetFileSpec( 'B', FullPathName) EFile = GetFileSpec( 'DPB', FullPathName)'.e' else -- Handle filename as Arg EFile = Args call Parse_Filename( EFile) endif -- No EFile, no Arg if EFile = '' then -- Get current filename Ext = GetFileSpec( 'E', .filename) if upcase( Ext) <> 'E' then 'SayError Relink: "'.filename'" is not an .E file.' leave endif EFile = .filename -- Save if changed if .modify then 'Save' if rc then leave endif endif endif -- Find linked .ex file FullExFile = FindLinkedExFile( EFile) if FullExFile = '' then 'SayError Relink: "'.filename'" is not linked.' leave endif -- In the following FullExFile is linked Basename = GetFileSpec( 'B', FullExFile) FullEFile = FindEFile( Basename) -- Compile 'Etpm' FullEFile if rc then leave endif -- Unlink and link ExFile 'UnLink' FullExFile if rc < 0 then leave endif 'Link' Basename -- Execute PostRelink hook if rc >= 0 then 'PostRelink' Basename endif enddo ; --------------------------------------------------------------------------- ; Syntax: etpm [[][.e] [[][[.ex]]] ; etpm compiles EPM.E to EPM.EX in \ex ; etpm tree.e compiles TREE.E to TREE.EX in \ex ; etpm tree compiles TREE.E to TREE.EX in \ex ; etpm tree.ex compiles TREE.E to TREE.EX in \ex ; etpm = compiles current file to an .ex file in \ex ; etpm = = compiles current file to an .ex file in the same dir ; o Uses the /v option to list all included files. ; o Doesn't respect options from the commandline, like /v or /e . ; o For external files outside of myepm\macros, netlabs\macros or the ; project trees, a full .e filename should be specified. Then the dir ; is changed before calling etpm.exe to make includes of the compiling ; file work. ; o If the current dir is one of netlabs\macros, epmbbs\macros or ; myepm\macros or starts with netlabs\project or myepm\project, the dir ; is changed to \ for compilation to not prefer files of the current ; dir and for writing full .e include filenames to the .log file. ; o The output file .ex goes usually to myepm\ex. If that file exists in ; myepm\autolink, that file is overwritten. If that file exists in the ; project tree, it goes to myepm\project\. ; o If the command line is longer than 229 chars, a temporary .cmd file is ; written and executed. This is much slower than calling etpm directly. defc Et, Etpm do once = 1 to 1 -- Parse args rest = strip( arg( 1)) if leftstr( rest, 1) = '"' then parse value rest with '"'EFile'"' rest else parse value rest with EFile rest endif if leftstr( rest, 1) = '"' then parse value rest with '"'ExFile'"' . else parse value rest with ExFile . endif if EFile = '' then EFile = 'epm.e' endif if pos( '=', EFile) then call Parse_Filename( EFile, .filename) endif if pos( '=', ExFile) then call Parse_Filename( ExFile, .filename) endif -- Call proc, LogFile and EtpmErrorMsg are not used here LogFile = '' EtpmErrorMsg = '' call Etpm( EFile, ExFile, LogFile, EtpmErrorMsg) enddo ; --------------------------------------------------------------------------- defproc Etpm( EFile, var ExFile, var LogFile, var EtpmErrorMsg) universal nepmd_hini --dprintf( 'Etpm: EFile = 'EFile', ExFile = 'ExFile', LogFile = 'LogFile) otherrc = '' cmdrc = '' etpmrc = '' PrevDir = directory() do once = 1 to 1 Basename = GetFileSpec( 'B', EFile) DestDir = GetExFileDestDir( Basename) -- Ensure that EFile with extensions e or ex has .e appended Ext = GetFileSpec( 'E', EFile) if wordpos( upcase( Ext), 'E EX') then EFile = GetFileSpec( 'DPB', EFile)'.e' endif -- Get FullEFile if pos( '\', EFile) then FullEFile = EFile else --FullEFile = GetUserNetlabsFile( EFile, 'macros') FullEFile = FindEFile( EFile) if FullEFile = '' then otherrc = 2 'SayError Error: 'EFile' not found on disk.' leave endif endif FullEFile = NepmdQueryFullName( FullEFile) -- Change to the dir of EFile to avoid a .cmd file. For EFiles from -- NEPMD macros dirs or from a NEPMD project tree, the dir is changed -- to \ to not prefer files of the current dir and for writing full .e -- include filenames to the .log file. DirToChange = EtpmFindDirToChange( FullEFile) if DirToChange <> '' then 'cd 'EnquoteFileSpec( DirToChange) endif --dprintf( 'Etpm: FullEFile = 'FullEFile', DirToChange = 'DirToChange', changed to dir = 'directory()) If ExFile = '' then -- ExFile not specified: Use Basename'.ex' ExFile = DestDir'\'Basename'.ex' elseif NepmdDirExists( ExFile) then -- If dir specified for ExFile, append Basename'.ex' DestDir = ExFile ExFile = DestDir'\'Basename'.ex' else -- Ensure that ExFile has .ex appended Ext = GetFileSpec( 'E', ExFile) if wordpos( upcase( Ext), 'E EX') then ExFile = GetFileSpec( 'DPB', ExFile)'.ex' else ExFile = ExFile'.ex' endif -- Ensure that ExFile includes a path if not pos( '\', ExFile) then ExFile = DestDir'\'ExFile endif endif ExFile = NepmdQueryFullName( ExFile) -- Create LogFile in the dir of the ExFile, if not specified if LogFile = '' then LogFile = ChangeExt( ExFile, 'log') else -- Ensure that LogFile has .log appended Ext = GetFileSpec( 'E', LogFile) if upcase( Ext) <> 'LOG' then LogFile = LogFile'.log' endif -- Ensure that LogFile includes a path if not pos( '\', LogFile) then LogFile = GetFileSpec( 'DP', ExFile)'\'LogFile endif LogFile = NepmdQueryFullName( LogFile) endif Params = '/v 'EnquoteFileSpec( EFile) EnquoteFileSpec( ExFile)' /e 'EnquoteFileSpec( LogFile) Os2Cmd = 'etpm 'Params --dprintf( 'Etpm: Os2Cmd = 'Os2Cmd) -- Always delete previous etpmrc key first -- setprofile seem to returns rc, therefore call is prepended call setprofile( nepmd_hini, 'Install', 'etpmrc', '') -- Check for length of quietshell arg and for external file fUseCmdFile = 0 if length( Os2Cmd) > 229 then fUseCmdFile = 1 endif CompilingMsg = 'Etpm: 'COMPILING__MSG EFile'...' if not fUseCmdFile then -- This is the faster version 'SayHint 'CompilingMsg --dprintf( 'Old Etpm: Os2Cmd = 'Os2Cmd) quietshell Os2Cmd etpmrc = rc --dprintf( 'Etpm: rc = 'etpmrc', ExFile = 'ExFile', 'NepmdQueryPathInfo( ExFile, 'MTIME')) else -- Create CmdFile to allow for longer lines (1023 instead of 229) -- or for extended EPMPATH CmdFile = GetTmpPath()'nepmd\etpmcomp.cmd' --dprintf( 'Etpm: CmdFile = 'CmdFile', Params = 'Params) DeleteFile( CmdFile) 'xcom e /c 'CmdFile if rc <> -282 then -- sayerror( 'New file') 'SayError 'ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)'.' return endif .autosave = 0 -- The returned rc from quietshell is the rc from executing cmd, -- not the rc from etpm. Therefore the etpmrc is written to IniFile. IniFile = NepmdQueryInstValue( 'INIT') insertline "/**/" insertline "CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'" insertline "CALL SysLoadFuncs" -- Execute etpm insertline "'"Os2Cmd"'" -- Write rc to NEPMD.INI insertline "CALL SysIni '"IniFile"', 'Install', 'etpmrc', rc'00'x" --insertline "'@DEL "CmdFile"'" -- Delete itself insertline "EXIT" 'xcom s' 'xcom q' -- Execute CmdFile Cmd = 'cmd /c 'CmdFile 'SayHint 'CompilingMsg quietshell Cmd cmdrc = rc if cmdrc then 'SayError Error 'cmdrc' from: quietshell 'Cmd leave else -- Read ini key for etpmrc etpmrc = queryprofile( nepmd_hini, 'Install', 'etpmrc') endif endif --dprintf( 'etpmrc = 'etpmrc) -- Check rc EtpmErrorMsg = '' -- Init if etpmrc = 0 then EtpmErrorMsg = COMP_COMPLETED__MSG': 'EFile'.' elseif etpmrc = -2 then EtpmErrorMsg = CANT_FIND_PROG__MSG' ETPM.' elseif etpmrc = 41 then EtpmErrorMsg = CANT_OPEN_TEMP__MSG '"'LogFile'".' elseif Exist( LogFile) then EtpmErrorMsg = Ec_Position_On_Error( LogFile) else EtpmErrorMsg = 'rc = 'etpmrc' for "etpm 'Params'".' endif EtpmErrorMsg = 'Etpm: 'EtpmErrorMsg if EtpmErrorMsg <> '' then if etpmrc then -- Repeat CompilingMsg, but this time with writing to the MsgBox 'SayError 'CompilingMsg 'SayError 'EtpmErrorMsg else 'SayHint 'EtpmErrorMsg endif endif enddo -- Change dir back 'cd 'EnquoteFileSpec( PrevDir) if otherrc <> '' then rc = otherrc elseif cmdrc <> '' then rc = cmdrc elseif etpmrc <> '' then rc = etpmrc else 'Sayerror Etpm: rc not set.' rc = -1 endif return ; --------------------------------------------------------------------------- ; Determine the etpm compile dir to avoid a .cmd file defproc EtpmFindDirToChange( FullEFile) DirToChange = '' EFileDir = NepmdQueryFullName( FullEFile'\..') NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') NepmdUserDir = Get_Env( 'NEPMD_USERDIR') NetlabsDir = NepmdRootDir'\netlabs' EpmbbsDir = NepmdRootDir'\epmbbs' UserMacrosDir = NepmdUserDir'\macros' NetlabsProjectDir = NepmdUserDir'\project' UserProjectDir = NepmdUserDir'\project' --dprintf( 'EtpmFindDirToChange: EFileDir = 'EFileDir) if pos( upcase( NetlabsDir), upcase( EFileDir)) = 1 | pos( upcase( EpmbbsDir), upcase( EFileDir)) = 1 | upcase( UserMacrosDir) = upcase( EFileDir) | pos( upcase( NetlabsProjectDir), upcase( EFileDir)) = 1 | pos( upcase( UserProjectDir), upcase( EFileDir)) = 1 then -- Don't make the netlabs dir (or other NEPMD dirs) the current dir -- to prefer other files, change to the root of that dir instead DirToChange = GetFileSpec( 'D', EFileDir)'\' --dprintf( 'EtpmFindDirToChange: 1) DirToChange = 'DirToChange) else -- Change to other than NEPMD dir to allow for inclusion of more -- files by the compiled file without extending EPMPATH DirToChange = EFileDir --dprintf( 'EtpmFindDirToChange: 2) DirToChange = 'DirToChange) endif return DirToChange ; --------------------------------------------------------------------------- ; Returns a ';'-separated list of all used macro files from an ETPM /v log. ; Each macro file is appended by a ';' for easy parsing. ; NEPMD .e files are returned without a path. For external .e files the ; path is prepended. For external .e files, the Etpm proc changes into the ; path of the first .e filename. This path is then missed in the log file, ; but it is prepended here. ; The length of the returned list for compiling epm.e is currently 435 of ; 1600. The var length is checked here and in case of an overflow, rc = 8 ; is set. defproc GetEFilesFromEtpmLog( EtpmLogFile) do once = 1 to 1 EFiles = '' -- Check if already loaded getfileid startfid fLogFileLoaded = 0 getfileid logfid, EtpmLogFile if logfid then fLogFileLoaded = 1 activatefile logfid else 'xcom e 'EtpmLogFile if rc then -- Unexpected error or new .Untitled file 'SayError GetEFilesFromEtpmLog: 'ERROR_LOADING__MSG EtpmLogFile leave endif endif UpEpmPath = upcase( Get_Env( 'EPMPATH')) MainEFile = '' MainEFileDir = '' DirToChange = '' do l = 4 to .last -- start at line 4 to omit the ' compiling ...' line parse value textline( l) with 'compiling 'FullEFile if FullEFile = '' then iterate endif if MainEFile = '' then MainEFile = FullEFile MainEFileDir = NepmdQueryFullName( MainEFile'\..') DirToChange = EtpmFindDirToChange( MainEFile) endif -- Prepend DirToChange for included files if path is missing if not pos( '\', FullEFile) & DirToChange <> '' then FullEFile = strip( DirToChange, 'T', '\')'\'FullEFile endif fEFileIsExternal = 0 EFileDir = NepmdQueryFullName( FullEFile'\..') if not pos( ';'upcase( EFileDir)';', ';'UpEpmPath';') then fEFileIsExternal = 1 endif if fEFileIsExternal then EFile = FullEFile else -- strip path EFile = GetFileSpec( 'N', FullEFile) endif if length( EFiles) + length( EFile';') > 1600 then rc = 8 -- ERROR_NOT_ENOUGH_MEMORY 'Sayerror GetEFilesFromEtpmLog: Length of EFiles would get > 1600, rc = 'rc'.' else EFiles = EFiles''EFile';' endif enddo if not fLogFileLoaded then -- Quit LogFile 'xcom q' endif pActivatefile( startfid) enddo return EFiles ; --------------------------------------------------------------------------- ; Load file containing error, called by etpm. ; This handles the /v output of etpm as well. defproc Ec_Position_On_Error( LogFile) EtpmErrorMsg = '' -- Init do once = 1 to 1 'xcom e 'LogFile if rc then -- Unexpected error. 'SayError Ec_Position_On_Error: 'ERROR_LOADING__MSG LogFile if rc = -282 then -- sayerror( 'New file') 'xcom q' endif return endif MsgLine = 4 do l = 4 to .last next = textline( l) if substr( next, 1, 10) = 'compiling ' then -- ignore else EtpmErrorMsg = next MsgLine = l leave endif enddo if MsgLine < .last then parse value textline( .last) with 'col= ' Col parse value textline( .last - 1) with 'line= ' Line parse value textline( .last - 2) with 'filename=' Filename Col = strip( Col) Line = strip( Line) Filename = strip( Filename) 'xcom q' if EtpmErrorMsg = '' | Filename = '' then EtpmErrorMsg = 'No error found in 'LogFile'. Error from calling cmd?' leave endif EtpmErrorMsg = EtpmErrorMsg' on ('Line','Col') in 'Filename 'e 'Filename -- not xcom here, respect user's window style if Line <> '' and Col <> '' then .cursory = Min( .windowheight % 2, .last) if Col > 0 then 'PostMe GoTo' Line Col else Line = Line - 1 Col = length( textline( Line)) 'PostMe GoTo' Line Col endif endif endif enddo return EtpmErrorMsg ; --------------------------------------------------------------------------- ; Check for a modified file in ring. If not, compile EPM.E, position cursor ; on errorline or restart on success. Quite fast! ; Because of defc Etpm is used, EPM.EX is created in \ex. ; Because of defc Restart is used, current directory will be kept. defc RecompileEpm do once = 1 to 1 if isadefc( 'CheckAllRingsModify') then SetCheckModifyOptions( '*nepmd*', 'E') 'CheckAllRingsModify' CheckRc = rc if CheckRc then leave endif endif if rc then leave endif -- Ensure that myepm\ex exists NepmdUserDir = Get_Env( 'NEPMD_USERDIR') call MakeTree( NepmdUserDir'\ex') 'Etpm epm' if rc then leave endif 'Restart' enddo ; --------------------------------------------------------------------------- ; Recompile all required files. defc RecompileAll 'RecompileNew reset' 'RecompileNew' ; --------------------------------------------------------------------------- ; Syntax: Recompile[New] [RESET] | [CHECKONLY] [NOMSG] [NOMSGBOX] ; Checks all known compilable .e files for changes. Compares dateimes with ; the netlabs files and with the last checked datetimes. If files need to be ; recompiled, the md5 checksums of the .ex files are compared with those of ; the netlabs .ex files. Many .ex files can be relinked, but some require a ; restart of EPM. This is done automatically. A message box pops up after ; relink resp. restart. Additionally a .log file is created that lists the ; results. defc RecompileNew, Recompile universal vepm_pointer universal epmrestartpending universal appendrecompilelog universal nepmd_hini fCancel = 0 do once = 1 to 1 -- Following E files are tryincluded. When the user has added one of these -- since last check, that one is not listed in -- \NEPMD\User\ExFiles\\EFiles. Therefore it has to be checked -- additionally. -- Optional E files for every E file listed in a .LST file: OptEFiles = '' -- Optional E files tryincluded in EPM.E only: --OptEpmEFiles = 'mykeyset.e;' OptEpmEFiles = '' -- Optional E files linked in INIT.E: OptLinkEFiles = 'mystuff.e;' -- Determine CheckOnly or Reset mode: disable file operations then fCheckOnly = (wordpos( 'CHECKONLY', upcase( arg( 1))) > 0) fReset = (wordpos( 'RESET' , upcase( arg( 1))) > 0) fNoMsgBox = (wordpos( 'NOMSGBOX' , upcase( arg( 1))) > 0) fNoMsg = (wordpos( 'NOMSG' , upcase( arg( 1))) > 0) KeyPathExFiles = '\NEPMD\Var\ExFiles' KeyPathEFiles = '\NEPMD\Var\EFiles' if fReset then call DeleteConfigTree( KeyPathExFiles) call DeleteConfigTree( KeyPathEFiles) if not fNoMsg then 'SayError RecompileNew: All RecompileNew entries deleted from NEPMD.INI.' endif rc = 0 fCancel = 1 leave -- once endif parse value DateTime() with Date Time if not fCheckOnly & not fReset then if .modify then 'Save' endif if isadefc( 'CheckAllRingsModify') then SetCheckModifyOptions( '*nepmd*', 'E') 'CheckAllRingsModify' CheckRc = rc --dprintf( 'RecompileNew: CheckAllRingsModify returns 'rc) if CheckRc then leave endif endif if rc then 'SayError RecompileNew: Modified file.' fCancel = 1 leave -- once endif endif mouse_setpointer WAIT_POINTER NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') NepmdUserDir = Get_Env( 'NEPMD_USERDIR') UserDirName = GetFileSpec( 'N', NepmdUserDir) call MakeTree( NepmdUserDir'\ex') CompileDir = NepmdUserDir'\ex\tmp' LogFile = NepmdUserDir'\ex\recompilenew.log' fRestartEpm = 0 fFoundMd5Exe = '?' Md5Exe = '' DiffExe = '' DiffOpt = '' cError = 0 cWarning = 0 cEqual = 0 cRecompile = 0 cDelete = 0 cRelink = 0 -- Handle case when an .E file that needs a restart (EPM.E or RECOMPILE.E) -- was successfully compiled, but a previous restart wasn't executed, because -- the E compiler found an error. if epmrestartpending = 1 then -- Restart EPM and reset universal fRestartEpm = 1 epmrestartpending = 0 endif -- When the E compiler found an error, the RECOMPILENEW.LOG file should -- not be deleted before the next run. Then the logs will be appended. -- Note that this won't have an effect after an EPM restart. if appendrecompilelog = 1 then -- Append to log and reset universal WriteLog( LogFile, '') WriteLog( LogFile, copies( '=', 71)) appendrecompilelog = 0 else -- Write new log if Exist( LogFile) then call DeleteFile( LogFile) endif endif if fCheckOnly then WriteLog( LogFile, '"RecompileNew CheckOnly" started at' Date Time', no .EX file will be replaced.') else WriteLog( LogFile, '"RecompileNew" started at' Date Time'.') endif WriteLog( LogFile, '') WriteLog( LogFile, 'Checking existing user .EX files and included .E files...') WriteLog( LogFile, 'I = information') WriteLog( LogFile, 'W = warning') WriteLog( LogFile, '= = equal .E file') WriteLog( LogFile, 'R = relinked/recompiled/new') WriteLog( LogFile, 'D = deleted') WriteLog( LogFile, 'E = error') -- Reset Check values of all saved .e files next = '' do while NepmdGetNextConfigKey( nepmd_hini, KeyPathEFiles, 'C', next) EFile = next call NepmdWriteConfigValue( nepmd_hini, KeyPathEFiles'\'EFile'\CheckDone', 0) enddo if fFoundMd5Exe = '?' then -- Search for MD5.EXE only once to give an error message next = FindTool( 'md5sum') Basename = '(General tool)' fHeaderWritten = 0 if next = '' then fFoundMd5Exe = 0 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E MD5SUM.EXE, MD5SUML.EXE or MD5.EXE not found in PATH or EPMTOOLSPATH') cError = cError + 1 else fFoundMd5Exe = 1 Md5Exe = next endif endif SetAVar( 'recompile.md5exe', Md5Exe) -- Init DiffExe and DiffOpt if DiffExe = '' then DiffExe = FindTool( 'diff') DiffOpt = '' endif if DiffExe <> '' then DiffOpt = '-u -I "\$\(Date\|Revision\|Author\|HeadURL\|Id\).*$"' endif SetAVar( 'recompile.diffexe', DiffExe) SetAVar( 'recompile.diffopt', DiffOpt) -- Create temp. CompileDir CompileDir = NepmdUserDir'\ex\tmp' if Exist( CompileDir) then NepmdDeleteTree( CompileDir) endif if not Exist( CompileDir) then call MakeTree( CompileDir) if not Exist( CompileDir) then 'SayError CallEtpm: Cannot find or create CompileDir "'CompileDir'".' rc = 3 fCancel = 1 leave endif endif -- Find source files tmpfid = FindCompileFiles() -- Clean-up orphaned config keys call RecompileCleanup( tmpfid) -- Check if current file is an .e file and is included by RecompileNew Counters = cError cWarning cEqual cRecompile cDelete cRelink call RecompileProcessCurEFile( tmpfid, LogFile, fHeaderWritten, Counters) parse value Counters with cError cWarning cEqual cRecompile cDelete cRelink if rc then fCancel = 1 leave endif do l = 1 to tmpfid.last getline next, l, tmpfid if next = '' then iterate endif -- Get Basename, FullMainEFile and MainEFile fMainEFileIsExternal = 0 if pos( '\', next) then fMainEFileIsExternal = 1 Basename = GetFileSpec( 'B', next) FullMainEFile = next else Basename = next FullMainEFile = FindEFile( next) endif FullMainEFile = NepmdQueryFullName( FullMainEFile) if FullMainEFile = '' then MainEFile = next'.e' else MainEFile = GetFileSpec( 'N', FullMainEFile) endif fSuppressMainEFileWarning = 0 if wordpos( lowcase( GetFileSpec( 'B', MainEFile)), 'nepmdlib') then fSuppressMainEFileWarning = 1 endif fCompileExFile = 0 fReplaceExFile = 0 fDeleteExFile = 0 fCopiedExFile = 0 fExFileCurrentNetlabsDifferent = 1 -- Current/Netlabs fExFileNetlabsDifferent = 1 -- Compiled/Netlabs fExFileCurrentDifferent = 1 -- Compiled/Current fHeaderWritten = 0 fRelinkUnlinked = 0 fEFileExists = 0 NewExFile = '' NewExFileTime = '' EtpmLogFile = '' NewEFileList = '' AddEFileList = '' KeyPath = KeyPathExFiles'\'lowcase( Basename) KeyPathLastCheckTime = KeyPath'\LastCheckTime' KeyPathTime = KeyPath'\Time' -- Time = date time of the active .ex file KeyPathEFileList = KeyPath'\EFiles' -- EFiles = base.ext;base.ext;... LastCheckTime = QueryConfigKey( KeyPathLastCheckTime) SavedExFileTime = QueryConfigKey( KeyPathTime) SavedEFileList = QueryConfigKey( KeyPathEFileList) NetlabsExFile = NepmdRootDir'\netlabs\ex\'Basename'.ex' NetlabsExFileTime = NepmdQueryPathInfo( NetlabsExFile, 'MTIME') CurExFile = FindExFile( Basename) CurExFileTime = NepmdQueryPathInfo( CurExFile, 'MTIME') -------------------------------- -- 1) Check if CurExFile exists do once1 = 1 to 1 if CurExFile <> '' then leave endif CurExFile = Basename fReplaceExFile = 1 enddo -- once1 if fCancel then leave endif -------------------------------- -- 2) When .EX file times are different, compile and compare them do once2 = 1 to 1 if CurExFileTime = '' then leave endif if SavedExFileTime <> CurExFileTime then fCompileExFile = 1 endif enddo -- once2 if fCancel then leave endif -------------------------------- -- 3) Check if .E file exists do once3 = 1 to 1 if FullMainEFile = '' & not fMainEFileIsExternal then fEFileExists = 0 if not fSuppressMainEFileWarning then cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .E file "'MainEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' not found in EPMMACROPATH') endif leave elseif Exist( FullMainEFile) then fEFileExists = 1 else fEFileExists = 0 if not fSuppressMainEFileWarning then cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .E file "'FullMainEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' not found on disk') endif endif enddo -- once3 if not fEFileExists then iterate endif if fCancel then leave endif -------------------------------- -- 4) Compare current .EX file with Netlabs .EX file and delete it if equal do once4 = 1 to 1 -- Omit this if ETPM should be called already if fReplaceExFile then leave endif -- Check if Netlabs .EX file exists if not Exist( NetlabsExFile) then if SavedExFileTime = '' then -- Recompile it and get times etc. fCompileExFile = 1 endif leave endif if NetlabsExFileTime = '' then leave endif if upcase( CurExFile) = upcase( NetlabsExFile) then -- if same pathnames leave endif if fFoundMd5Exe <> 1 then leave endif fExFileCurrentNetlabsDifferent = (Md5Comp( CurExFile, NetlabsExFile) <> 0) md5rc = rc if md5rc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E MD5Comp returned rc = 'md5rc' on comparing current .EX file "'CurExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' with Netlabs .EX file "'NetlabsExFile'"') endif delrc = '' -- If CurExFile = NetlabsExFile if not fExFileCurrentNetlabsDifferent then -- equal WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I current .EX file "'CurExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is equal to Netlabs .EX file') if not fCheckOnly then -- linked() and unlink won't work if a full filename was specified -- and if that linked file doesn't exist anymore. fCurExFileWasLinked = 0 if linked( CurExFile) >= 0 then --WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' linked before deletion: "'CurExFile'"') fCurExFileWasLinked = 1 endif if wordpos( upcase( Basename), RECOMPILE_RESTART_NAMES) then -- These EX files are in use, they can't be unlinked, -- therefore EPM must be restarted fRestartEpm = 1 endif -- Unlink works only for an existing .ex file. Therefore unlink -- must come before delete. if not fRestartEpm then if fCurExFileWasLinked then -- unlink works only if EX file exists 'Unlink' CurExFile fRelinkUnlinked = 1 endif endif -- After unlinking file.ex, DeleteFile is not available at this time CurLogFile = ChangeStr( '.ex', CurExFile, '.log') if isadefproc( 'DeleteFile') then call DeleteFile( CurExFile) delrc = rc call DeleteFile( CurLogFile) else quietshell 'del' CurExFile delrc = rc quietshell 'del' CurLogFile endif if delrc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E cannot delete current .EX file "'CurExFile'", rc = 'rc) fCompileExFile = 0 else cDelete = cDelete + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'D deleted current .EX file "'CurExFile'"') fCompileExFile = 0 endif if not fRestartEpm then -- Check if old file is linked. Using Basename here would check -- for the wrong file when it didn't exist before if fCurExFileWasLinked | fRelinkUnlinked then -- < 0 means error or not linked if not fRelinkUnlinked then -- maybe already unlinked 'Unlink' CurExFile if rc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E current .EX file not unlinked') endif endif 'Link' Basename if rc >= 0 then cRelink = cRelink + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' relinked .EX file') 'PostRelink' Basename endif endif endif endif -- not fCheckOnly endif -- If CurExFile <> NetlabsExFile or if error from deletion if fExFileCurrentNetlabsDifferent | (not fExFileCurrentNetlabsDifferent & delrc) then if LastCheckTime < Max( CurExFileTime, NetlabsExFileTime) then fCompileExFile = 1 endif if CurExFileTime < NetlabsExFileTime then cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W current .EX file "'CurExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is older than and different from Netlabs .EX file') elseif CurExFileTime > NetlabsExFileTime then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I current .EX file "'CurExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is newer than and different from Netlabs .EX file') -- present endif endif enddo -- once4 if fCancel then leave endif -------------------------------- -- 5) Check .E files and compare current .E files with Netlabs .E files or with last check do once5 = 1 to 1 -- Omit this if ETPM should be called already if fReplaceExFile then leave endif if SavedEFileList = '' then -- Compile and get .e files from log, in 6) fCompileExFile = 1 leave endif -- Append optional E files (user may have added them since last check) orest = OptEFiles do while orest <> '' parse value orest with next';'orest if pos( ';'upcase( next)';', ';'upcase( SavedEFileList''AddEFileList)) = 0 then AddEFileList = AddEFileList''next';' endif enddo if upcase( Basename) = 'EPM' then orest = OptEpmEFiles do while orest <> '' parse value orest with next';'orest if pos( ';'upcase( next)';', ';'upcase( SavedEFileList''AddEFileList)) = 0 then AddEFileList = AddEFileList''next';' endif enddo endif -- Compare .e files EFileList = SavedEFileList''AddEFileList NewEFileList = '' fAfterEtpm = 0 Counters = cError cWarning cEqual cRecompile cDelete cRelink Flags = fAfterEtpm fCompileExFile call RecompileCompareEFiles( Basename, LogFile, fHeaderWritten, Counters, Flags, EFileList, NewEFileList, OptEFiles) parse value Counters with cError cWarning cEqual cRecompile cDelete cRelink parse value Flags with fAfterEtpm fCompileExFile enddo -- once5 if fCancel then leave endif -------------------------------- -- 6) Run Etpm and compare compiled .E files with Netlabs .E files do once6 = 1 to 1 --dprintf( '6) MainEFile = 'MainEFile) -- Process this if .EX file should be replaced or if .EX files should be compared if not fReplaceExFile & not fCompileExFile then leave endif if fMainEFileIsExternal then EtpmEFile = FullMainEFile else EtpmEFile = MainEFile endif NewExFile = CompileDir'\'Basename'.ex' EtpmLogFile = '' EtpmErrorMsg = '' --dprintf( '6) call Etpm( 'EtpmEFile', 'NewExFile', 'EtpmLogFile', 'EtpmErrorMsg')') -- Compare basenames and popup a msgbox if different SrcBasename = GetFileSpec( 'B', MainEFile) DestBasename = GetFileSpec( 'B', NewExFile) SrcName = GetFileSpec( 'N', FullMainEFile) DestName = GetFileSpec( 'N', NewExFile) if upcase( SrcBasename) <> upcase( DestBasename) then Title = 'RecompileNew' Text = '' Text = Text || 'Compiling 'SrcName' -> 'DestName\n\n if FullMainEFile = '' then -- This is now already checked in 3) Text = Text || 'Source file is not set.' Text = Text || ' That should not happen.'\n\n elseif NewExFile = '' then Text = Text || 'Target file is not set.' Text = Text || ' That should not happen.'\n\n else Text = Text || 'Basenames are different.' Text = Text || ' That should not happen.' Text = Text || ' Check the value of the config key'\n\n Text = Text || '\NEPMD\Var\ExFiles\'DestBasename'\EFiles'\n\n Text = Text || 'Remove it with'\n\n Text = Text || 'DeleteConfigTree \NEPMD\Var\ExFiles\'DestBasename'\'\n\n endif Text = Text || 'Cannot continue.' rcx = WinMessageBox( Title, Text, MB_CANCEL + MB_ERROR + MB_DEFBUTTON1 + MB_MOVEABLE) fCancel = 1 leave -- once6 endif call Etpm( EtpmEFile, NewExFile, EtpmLogFile, EtpmErrorMsg) etpmrc = rc --dprintf( '6) call Etpm( 'EtpmEFile', 'NewExFile', 'EtpmLogFile', 'EtpmErrorMsg')') --dprintf( '* rc = 'rc', EtpmErrorMsg = 'EtpmErrorMsg', Basename = 'Basename) if etpmrc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E ETPM returned rc =' rc) if EtpmErrorMsg <> '' then WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' 'EtpmErrorMsg) endif -- Handle the case when an .E file that needs a restart (EPM.E or RECOMPILE.E) -- was successfully compiled, but a restart won't be executed, because -- the E compiler found an error. if fRestartEpm then epmrestartpending = 1 endif -- When the E compiler found an error, the RECOMPILENEW.LOG file should -- not be deleted before the next run. Then the logs will be appended. -- Note that this won't have an effect after an EPM restart. appendrecompilelog = 1 mouse_setpointer vepm_pointer rc = etpmrc fCancel = 1 leave -- once6 endif NewEFileList = lowcase( GetEFilesFromEtpmLog( EtpmLogFile)) if rc = 8 then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W Length of EFileList > 1600, rc = 8') elseif rc then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W rc from GetEFilesFromEtpmLog = 'rc) elseif length( NewEFileList) > 1000 then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W Length of EFileList is 'length( NewEFileList)' of 1600') endif --dprintf( '6) EFileList = 'NewEFileList) -- Compare .e files EFileList = NewEFileList fAfterEtpm = 1 Counters = cError cWarning cEqual cRecompile cDelete cRelink Flags = fAfterEtpm fCompileExFile call RecompileCompareEFiles( Basename, LogFile, fHeaderWritten, Counters, Flags, EFileList, NewEFileList, OptEFiles) parse value Counters with cError cWarning cEqual cRecompile cDelete cRelink parse value Flags with fAfterEtpm fCompileExFile if fCancel then leave endif -- Get time of NewExFile NewExFileTime = NepmdQueryPathInfo( NewExFile, 'MTIME') enddo -- once6 if fCancel then leave endif -------------------------------- -- 7) Compare .EX files do once7 = 1 to 1 if not fCompileExFile then leave endif if not fExFileCurrentNetlabsDifferent then -- determined in 4) leave endif if not fFoundMd5Exe then leave endif if CurExFile = '' then -- if a new file leave endif fExFileCurrentDifferent = (Md5Comp( NewExFile, CurExFile) <> 0) md5rc = rc if md5rc then -- error cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E MD5Comp returned rc = 'md5rc' on comparing "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' with current .EX file "'CurExFile'"') elseif CurExFile = '' then -- new fReplaceExFile = 1 elseif fExFileCurrentDifferent then -- different fReplaceExFile = 1 if NetlabsExFileTime <> '' then fExFileNetlabsDifferent = (Md5Comp( NewExFile, NetlabsExFile) <> 0) md5rc = rc if md5rc then -- error cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E MD5Comp returned rc = 'md5rc' on comparing "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' with Netlabs .EX file "'NetlabsExFile'"') elseif fExFileNetlabsDifferent then -- different if not fCheckOnly then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current and Netlabs .EX file') else cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current and Netlabs .EX file') endif else -- equal if upcase( CurExFile) <> upcase( NetlabsExFile) then if not fCheckOnly then fDeleteExFile = 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current but equal to Netlabs .EX file') else cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current but equal to Netlabs .EX file') endif endif endif else if not fCheckOnly then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current .EX file') else cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is different from current .EX file') endif endif else -- equal -- Don't report this. This would be also added in case of a recompile. -- That makes the messages after 'RecompileNew reset' equal to those for -- 'RecompileNew' after it. /* -- Omit this if it's the only entry if fHeaderWritten then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .EX file "'NewExFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is equal to current .EX file') endif */ endif enddo -- once7 if fCancel then leave endif -------------------------------- -- 8) Replace .EX file do once8 = 1 to 1 if not fReplaceExFile then leave endif -- Don't unlink, delete or copy if Checkonly is active if fCheckOnly then leave endif DestDir = GetExFileDestDir( NewExFile) if fDeleteExFile then -- Unlink works only for an existing .ex file. Therefore unlink -- must come before delete. if not fRestartEpm then if linked( CurExFile) >= 0 then -- unlink works only if EX file exists 'UnLink' CurExFile fRelinkUnlinked = 1 endif endif -- After unlinking file.ex, DeleteFile is not available at this time CurLogFile = ChangeStr( '.ex', CurExFile, '.log') if isadefproc( 'DeleteFile') then call DeleteFile( CurExFile) call DeleteFile( CurLogFile) else quietshell 'del' CurExFile quietshell 'del' CurLogFile endif if rc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E cannot delete .EX file "'CurExFile'", rc = 'rc) else cDelete = cDelete + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'D deleted .EX file "'CurExFile'"') endif else -- Check DestDir before copying if DestDir = '' then Title = 'RecompileNew' Text = '' Text = Text || 'The copy target is empty.'\n\n Text = Text || 'Cannot continue.' rcx = WinMessageBox( Title, Text, MB_CANCEL + MB_ERROR + MB_DEFBUTTON1 + MB_MOVEABLE) fCancel = 1 leave -- once8 endif --dprintf( '8) copy' NewExFile' -> 'DestDir) quietshell 'copy' NewExFile DestDir if rc then cError = cError + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'E cannot copy .EX file to "'DestDir'", rc = 'rc) else fCopiedExFile = 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'R copied .EX file to "'DestDir'"') endif --dprintf( '8) copy' EtpmLogFile' -> 'DestDir) quietshell 'copy' EtpmLogFile DestDir cRecompile = cRecompile + 1 endif if wordpos( upcase( Basename), RECOMPILE_RESTART_NAMES) then -- These EX files are in use, they can't be unlinked, -- therefore EPM must be restarted fRestartEpm = 1 endif if not fRestartEpm then -- Check if old file is linked. Using Basename here would check -- for the wrong file when it didn't exist before if linked( CurExFile) >= 0 | fRelinkUnlinked then -- < 0 means error or not linked if not fRelinkUnlinked then -- may already be unlinked 'UnLink' CurExFile endif 'Link' Basename if rc >= 0 then cRelink = cRelink + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' relinked .EX file') 'PostRelink' Basename endif else -- Link optional linkable file after compile and copy if pos( ';'upcase( Basename'.e')';', ';'upcase( OptLinkEFiles)) > 0 then 'Link' Basename if rc >= 0 then cRelink = cRelink + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' linked .EX file') 'PostRelink' Basename endif endif endif endif enddo -- once8 if fCancel then leave endif -------------------------------- -- 9) Write .EX file config keys -- Don't write new times and files if ExFile needs to be replaced, -- but Checkonly is active do once9 = 1 to 1 if fCheckOnly & fReplaceExFile then leave endif -- Check value of NewEFileList. First item must be DestBasename'.e' parse value KeyPathEFileList with '\NEPMD\Var\ExFiles\'ThisBase'\' parse value NewEFileList with FirstEFile';' FirstEFile = GetFileSpec( 'N', FirstEFile) if lowcase( ThisBase)'.e' <> lowcase( FirstEFile) then Title = 'RecompileNew' Text = '' Text = Text || 'The config key'\n\n Text = Text || KeyPathEFileList\n\n Text = Text || 'is not written, because the intended value is wrong.' Text = Text || ' It doesn''t start with 'lowcase( ThisBase)'.e;'\n\n Text = Text || NewEFileList\n\n Text = Text || 'Cannot continue.' rcx = WinMessageBox( Title, Text, MB_CANCEL + MB_ERROR + MB_DEFBUTTON1 + MB_MOVEABLE) fCancel = 1 leave -- once9 endif if NewExFileTime <> '' then WriteConfigKey( KeyPathLastCheckTime, NewExFileTime) if fCheckOnly then -- nop elseif fCopiedExFile then WriteConfigKey( KeyPathTime, NewExFileTime) elseif fDeleteExFile then WriteConfigKey( KeyPathTime, NetlabsExFileTime) elseif fCompileExFile then WriteConfigKey( KeyPathTime, CurExFileTime) endif endif if NewEFileList <> '' then WriteConfigKey( KeyPathEFileList, NewEFileList) endif enddo -- once9 if fCancel then leave endif -------------------------------- enddo -- l if fCancel then leave endif WriteLog( LogFile, copies( '-', 71)) WriteLog( LogFile, 'SUMMARY:') WriteLog( LogFile, ' 'cRecompile' file(s) recompiled') WriteLog( LogFile, ' 'cDelete' file(s) deleted') WriteLog( LogFile, ' therefrom') WriteLog( LogFile, ' 'cRelink' file(s) relinked') WriteLog( LogFile, ' 'cError' error(s)') WriteLog( LogFile, ' 'cWarning' warning(s)') WriteLog( LogFile, ' 'cEqual' equal .E file(s)') if fRestartEpm then WriteLog( LogFile, ' restart') endif WriteLog( LogFile, '') if fCheckOnly then if cWarning > 0 then Text = cWarning 'warning(s), no file replaced. Correct that before the next EPM start!' else Text = 'No warnings, everything looks ok.' endif else if fRestartEpm then Text = cRecompile 'file(s) recompiled and' cDelete 'file(s) deleted,' cWarning 'warning(s), restart.' else Text = cRecompile 'file(s) recompiled and' cDelete 'file(s) deleted, therefrom' cRelink' file(s) relinked,' cWarning 'warning(s).' endif endif WriteLog( LogFile, Text) if not fNoMsg then 'SayError RecompileNew: 'Text' See "'LogFile'".' endif if cEqual > 0 then WriteLog( LogFile, cEqual 'equal .E file(s). These user files may be safely deleted.') endif WriteLog( LogFile, '') WriteLog( LogFile, 'OTHER .E/.EX FILES:') WriteLog( LogFile, ' To include them here, append basenames or full .E filenames to') WriteLog( LogFile, ' 'upcase( UserDirName)'\EX\MACROADD.LST.') WriteLog( LogFile, '') if cWarning > 0 then -- Check if LogFile already loaded getfileid logfid, LogFile if logfid <> '' then -- Quit LogFile getfileid fid activatefile logfid .modify = 0 'xcom q' if fid <> logfid then activatefile fid endif endif endif if cWarning > 0 then ret = 1 else ret = 0 endif call NepmdDeleteTree( CompileDir) -- Message box MsgArgs = cError cWarning cRecompile cDelete cRelink fRestartEpm fCheckOnly MsgCmd = 'RecompileNewMsgBox' MsgArgs if fCheckOnly then if not fNoMsgBox then MsgCmd endif elseif fRestartEpm then if not fNoMsgBox then -- Open message box after restart. This is read by RestoreLastRing. KeyPath = '\NEPMD\Var\RestoreLastRing\AfterRestoreCmd' WriteConfigKey( KeyPath, MsgCmd) endif -- Restart 'PostMe PostMe Restart' else if not fNoMsgBox then MsgCmd endif endif rc = ret enddo -- once mouse_setpointer vepm_pointer ; --------------------------------------------------------------------------- ; Removes orphaned config keys. Needs .compilefiles from a FindCompileFiles ; calls. This is compared with \NEPMD\Var\ExFiles and \NEPMD\Var\EFiles. defproc RecompileCleanup( tmpfid) universal nepmd_hini getfileid startfid activatefile tmpfid -- Remove all entries in \NEPMD\Var\ExFiles for those no line in -- .compilefiles exists. KeyPathExFiles = '\NEPMD\Var\ExFiles' KeyPathEFiles = '\NEPMD\Var\EFiles' Basename = '' getsearch SavedSearch display -14 do while NepmdGetNextConfigKey( nepmd_hini, KeyPathExFiles, 'C', Basename) -- Search Basename in .compilefiles 'xcom l /(^|\\)'Basename'($| |\.e)/xct' lrc = rc -- Remove ExFiles\ tree if not found in .compilefiles if lrc then --dprintf( 'call NepmdDeleteConfigTree( nepmd_hini, 'KeyPathExFiles'\'Basename'\)') call NepmdDeleteConfigTree( nepmd_hini, KeyPathExFiles'\'Basename'\') endif enddo display 14 setsearch SavedSearch -- For \NEPMD\Var\EFiles it is checked if an entry in -- \NEPMD\Var\ExFiles\\EFiles exists. If not, the config tree -- is removed. EFile = '' do while NepmdGetNextConfigKey( nepmd_hini, KeyPathEFiles, 'C', EFile) -- Search EFile in ExFiles\*\EFiles fFound = 0 Basename = '' do while NepmdGetNextConfigKey( nepmd_hini, KeyPathExFiles, 'C', Basename) EFileList = NepmdQueryConfigValue( nepmd_hini, KeyPathExFiles'\'Basename'\EFiles') -- Search name (incl. .e) in EFileList if pos( ';'EFile';', ';'EFileList';') then fFound = 1 leave endif -- Search full pathname in EFileList if pos( '\'EFile';', EFileList';') then fFound = 1 leave endif enddo -- Remove EFiles\.e tree if not found in ExFiles\*\EFiles if not fFound then --dprintf( 'call NepmdDeleteConfigTree( nepmd_hini, 'KeyPathEFiles'\'EFile'\)') call NepmdDeleteConfigTree( nepmd_hini, KeyPathEFiles'\'EFile'\') endif enddo setsearch SavedSearch activatefile startfid return ; --------------------------------------------------------------------------- ; BasenameList can be a ;-separated list. A trailing ; is optional. ; Example: Filename1;Filename2 or Filename1 defc EditMacroListFile NepmdUserDir = Get_Env( 'NEPMD_USERDIR') ListFile = NepmdUserDir'\ex\macroadd.lst' TemplateFile = GetUserNetlabsFile( 'macroaddlst.tpl', 'install') if Exist( ListFile) then 'Edit 'EnquoteFileSpec( ListFile) else CreateFileFromTemplate( ListFile, TemplateFile) endif ; --------------------------------------------------------------------------- ; Basenames can be a ;-separated list. A trailing ; is optional. ; Example: Filename1;Filename2 or Filename1 defproc AddToMacroListFile( Basenames) rc = 0 NepmdUserDir = Get_Env( 'NEPMD_USERDIR') ListFile = NepmdUserDir'\ex\macroadd.lst' getfileid startfid fListFileLoaded = 0 getfileid listfid, ListFile if listfid then fListFileLoaded = 1 activatefile listfid else 'EditMacroListFile' if rc <> 0 & rc <> -282 then -- if error, -282 = sayerror( "New file") return endif rc = 0 getfileid listfid .visible = 0 .autosave = 0 endif --dprintf( 'listfid = 'listfid', ListFile = 'ListFile', fListFileLoaded = 'fListFileLoaded) bottom .col = 1 Rest = Basenames do while Rest <> '' parse value Rest with Basename';'Rest Rest = strip( Rest) insertline Basename enddo activatefile listfid .modify = 0 'xcom s' if not fListFileLoaded then -- Quit ListFile 'xcom q' endif pActivatefile( startfid) return ; --------------------------------------------------------------------------- ; Basenames can be a ;-separated list. A trailing ; is optional. ; Example: Filename1;Filename2 or Filename1 defproc DeleteFromMacroListFile( Basenames) NepmdUserDir = Get_Env( 'NEPMD_USERDIR') ListFile = NepmdUserDir'\ex\macroadd.lst' 'xcom e /d' ListFile if rc = -282 then -- if error, -282 = sayerror( "New file") .modify = 0 'xcom q' rc = -282 endif if rc <> 0 then return endif getfileid fid .visible = 0 getsearch savedsearch Rest = Basenames rcx = 0 lrc = 0 do while Rest <> '' parse value Rest with Basename';'Rest Rest = strip( Rest) display -14 'xcom l '\1'^'Basename'$'\1'f+tcx' display 14 lrc = rc if lrc then rcx = lrc iterate endif deleteline enddo setsearch savedsearch -- Quit ListFile activatefile fid .modify = 0 'xcom s' 'xcom q' rc = rcx return ; --------------------------------------------------------------------------- ; This determines if current file should be added to macroadd.lst. defproc RecompileProcessCurEFile( tmpfid, LogFile, var fHeaderWritten, var Counters) universal nepmd_hini rc = 0 parse value Counters with cError cWarning cEqual cRecompile cDelete cRelink do once = 1 to 1 if tmpfid = '' then leave endif fFoundInSrcFiles = 0 -- Check extension CurName = GetFileSpec( 'N', .filename) CurExt = GetFileSpec( 'E', .filename) CurBasename = GetFileSpec( 'B', .filename) --dprintf( 'RecompileProcessCurEFile: .filename = '.filename', CurExt = 'CurExt) if upcase( CurExt) <> 'E' then --dprintf( ' RecompileProcessCurEFile: 1) CurExt not e') leave endif -- FindCompileFiles was already called. --dprintf( ' RecompileProcessCurEFile: tmpfid.filename = 'tmpfid.filename) do l = 1 to tmpfid.last getline next, l, tmpfid if next = '' then iterate endif if next = lowcase( CurBasename) then fFoundInSrcFiles = 1 --dprintf( ' RecompileProcessCurEFile: 4) Found 'CurBasename' in .compilefiles and in EPMPATH') leave elseif next = lowcase( .filename) then fFoundInSrcFiles = 1 --dprintf( ' RecompileProcessCurEFile: 5) Found '.filename' in .compilefiles') leave endif enddo if fFoundInSrcFiles then leave endif -- Check if file exists as 'netlabs\macros\'CurName -- Then it's included by another file, because all netlabs files are -- used, except obsolete.e. NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') if Exist( NepmdRootDir'\netlabs\macros\'lowcase( CurName)) & lowcase( CurName) <> 'obsolete.e' then leave endif -- Check if current file is found in EPMPATH fFoundInEpmPath = 0 if pos( ';'lowcase( NepmdQueryFullName( .filename'\..'))';', ';'lowcase( Get_Env( 'EPMPATH'))';') then fFoundInEpmPath = 1 --dprintf( ' RecompileProcessCurEFile: 'CurName' found in EPMPATH') endif --dprintf( ' RecompileProcessCurEFile: EPMPATH = 'Get_Env( 'EPMPATH')) if fFoundInEpmPath then Addname = lowcase( CurBasename) else Addname = lowcase( .filename) endif -- Ask to add Addname to macroadd.lst Title = 'RecompileNew' Text = '' Text = Text || Addname\n\n Text = Text || 'The current file is not known to RecompileNew.'\n\n Text = Text || 'Add only separately compilable files. Included files' Text = Text || ' should not be added.'\n\n Text = Text || 'Should it be added to MACROADD.LST?' rcx = WinMessageBox( Title, Text, MB_YESNOCANCEL + MB_QUERY + MB_DEFBUTTON1 + MB_MOVEABLE) if rcx = MBID_YES then WriteBasenameLog( LogFile, Addname, fHeaderWritten, 'I .E file "'Addname'"') WriteBasenameLog( LogFile, Addname, fHeaderWritten, ' not included by RecompileNew') --dprintf( ' RecompileProcessCurEFile: AddToMacroListFile( 'Addname')') AddToMacroListFile( Addname) WriteBasenameLog( LogFile, Addname, fHeaderWritten, 'I .E file "'Addname'"') WriteBasenameLog( LogFile, Addname, fHeaderWritten, ' added to macroadd.lst') -- Refresh list call FindCompileFiles() rc = 0 elseif rcx = MBID_NO then WriteBasenameLog( LogFile, Addname, fHeaderWritten, 'W .E file "'Addname'"') WriteBasenameLog( LogFile, Addname, fHeaderWritten, ' not included by RecompileNew') cWarning = cWarning + 1 rc = 0 else sayerror 0 rc = 99 endif enddo Counters = cError cWarning cEqual cRecompile cDelete cRelink return ; --------------------------------------------------------------------------- defproc RecompileCompareEFiles( Basename, LogFile, var fHeaderWritten, var Counters, var Flags, EFileList, var NewEFileList) OptEFiles = arg( 8) parse value Counters with cError cWarning cEqual cRecompile cDelete cRelink parse value Flags with fAfterEtpm fCompileExFile LastCheckTime = '' CurExFile = '' CurExFileTime = '' NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') KeyPathExFiles = '\NEPMD\Var\ExFiles' KeyPathEFiles = '\NEPMD\Var\EFiles' if not fAfterEtpm then KeyPathLastCheckTime = KeyPathExFiles'\'lowcase( Basename)'\LastCheckTime' LastCheckTime = QueryConfigKey( KeyPathLastCheckTime) CurExFile = FindExFile( Basename) CurExFileTime = NepmdQueryPathInfo( CurExFile, 'MTIME') endif Md5Exe = GetAVar( 'recompile.md5exe') DiffExe = GetAVar( 'recompile.diffexe') DiffOpt = GetAVar( 'recompile.diffopt') erest = EFileList do while erest <> '' -- For every EFile of EFileList... parse value erest with next';'erest -- Read Dir and prepend it if found Dir = QueryConfigKey( KeyPathEFiles'\'GetFileSpec( 'B', next)'.e\Dir') if Dir then next = Dir'\'GetFileSpec( 'B', next)'.e' endif fEFileIsExternal = 0 if pos( '\', next) then fEFileIsExternal = 1 EFile = GetFileSpec( 'N', next) FullEFile = next if not Exist( FullEFile) then FullEFile = '' endif else EFile = next -- Get full pathname and time of EFile FullEFile = NepmdSearchPath( next, 'EPMMACROPATH') endif NetlabsEFileTime = '' EFileTime = '' EFileCheck = '' KeyPathEFile = KeyPathEFiles'\'lowcase( EFile) KeyPathEFileTime = KeyPathEFile'\Time' -- Time = date time KeyPathEFileCheck = KeyPathEFile'\Check' -- Check = fDifferent KeyPathEFileCheckDone = KeyPathEFile'\CheckDone' KeyPathEFileDir = KeyPathEFile'\Dir' SavedEFileTime = QueryConfigKey( KeyPathEFileTime) SavedEFileCheck = QueryConfigKey( KeyPathEFileCheck) SavedEFileCheckDone = QueryConfigKey( KeyPathEFileCheckDone) if fAfterEtpm then if SavedEFileCheckDone > 0 then -- Already processed, no need to do the checks here again iterate -- next EFile endif endif if fEFileIsExternal then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is an external file') endif -- Get full pathname and time of EFile and check if it's the Netlabs file if FullEFile = '' then -- EFile was deleted and previously added to EFiles if not fAfterEtpm then fCompileExFile = 1 endif WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .E file "'EFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' was deleted since last check') iterate -- next EFile endif EFileTime = NepmdQueryPathInfo( FullEFile, 'MTIME') EFileTimeRc = rc if EFileTimeRc then iterate -- next EFile endif if not fAfterEtpm then NewEFileList = NewEFileList''EFile';' endif if SavedEFileCheckDone > 0 then -- Already processed, no need to check the following here again iterate -- next EFile endif do once = 1 to 1 -- Get pathname and time of NetlabsEFile NetlabsEFile = NepmdRootDir'\netlabs\macros\'EFile NetlabsEFileTime = NepmdQueryPathInfo( NetlabsEFile, 'MTIME') NetlabsEFileTimeRc = rc -- Process this also for files without a corresponding NetlabsEFile, -- e.g. for mystuff.e if not fAfterEtpm then fEFileInNetlabsTree = (pos( upcase( NepmdRootDir'\netlabs'), upcase( FullEFile)) > 0) -- This was added for the case that an included myepm .e file -- was deleted. Then the netlabs .e file is included instead -- and the .ex file should be recompiled. Without this block, -- the deletion won't be recognized. if fEFileInNetlabsTree & SavedEFileTime <> NetlabsEFileTime then fCompileExFile = 1 leave endif -- Compare time of EFile with LastCheckTime and CurExFileTime. -- If EFile is the Netlabs file, process this only if previous -- EFile was newer then NetlabsEFile. This may happen after -- deletion of a newer user EFile. if not (fEFileInNetlabsTree & SavedEFileTime <= NetlabsEFileTime) then if EFileTime > max( LastCheckTime, CurExFileTime) then fCompileExFile = 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is newer than last check') leave elseif (SavedEFileTime = '') & (pos( ';'upcase( EFile)';', ';'upcase( OptEFiles)) > 0) then --WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' 'Basename' - .E file "'FullEFile'" is an optional file and probably not included') elseif EFileTime <> SavedEFileTime then fCompileExFile = 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is newer or older compared to last check of this .E file') leave endif endif endif -- Compare time of (maybe user's) EFile with netlabs EFile to give a warning if older if NetlabsEFileTimeRc then leave endif if EFileTime < NetlabsEFileTime then if EFileTime = SavedEFileTime & wordpos( SavedEFileCheck, '0 1') then fDifferent = SavedEFileCheck else fDifferent = Md5Comp( FullEFile, NetlabsEFile, DiffExe, DiffOpt) endif EFileCheck = fDifferent if fDifferent then cWarning = cWarning + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'W .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is older than and different from Netlabs .E file') else cEqual = cEqual + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, '= .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is older than and equal to Netlabs .E file') endif elseif EFileTime > NetlabsEFileTime then if EFileTime = SavedEFileTime & wordpos( SavedEFileCheck, '0 1') then fDifferent = SavedEFileCheck else fDifferent = Md5Comp( FullEFile, NetlabsEFile, DiffExe, DiffOpt) endif EFileCheck = fDifferent if fDifferent then WriteBasenameLog( LogFile, Basename, fHeaderWritten, 'I .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is newer than and different from Netlabs .E file') else cEqual = cEqual + 1 WriteBasenameLog( LogFile, Basename, fHeaderWritten, '= .E file "'FullEFile'"') WriteBasenameLog( LogFile, Basename, fHeaderWritten, ' is newer than and equal to Netlabs .E file') endif else EFileCheck = 0 endif enddo -- once WriteConfigKey( KeyPathEFileTime, EFileTime) WriteConfigKey( KeyPathEFileCheck, EFileCheck) if fAfterEtpm then WriteConfigKey( KeyPathEFileCheckDone, 6) if fEFileIsExternal then --dprintf( '6) Dir written for 'FullEFile) WriteConfigKey( KeyPathEFileDir, NepmdQueryFullName( FullEFile'\..')) else -- Ensure that \Dir key is removed DeleteConfigKey( KeyPathEFileDir) endif else WriteConfigKey( KeyPathEFileCheckDone, 5) endif enddo -- while erest <> '' Counters = cError cWarning cEqual cRecompile cDelete cRelink Flags = fAfterEtpm fCompileExFile --dprintf( Basename': 'EFileList' -> 'NewEFileList) return ; --------------------------------------------------------------------------- ; Writes all to-be-compiled .e files to a hidden file. Either full filenames ; or basenames are added. All entries are unique. ; Ignores .ex files starting with '_' or '.' defproc FindCompileFiles rc = 0 NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') NepmdUserDir = Get_Env( 'NEPMD_USERDIR') NetlabsMacrosDir = NepmdRootDir'\netlabs\macros' UserMacrosDir = NepmdUserDir'\macros' KeyPathEFiles = '\NEPMD\Var\EFiles' getfileid startfid -- Eventually reuse old .compilefiles getfileid tmpfid, '.compilefiles' if tmpfid then tmpfid.visible = 0 tmpfid.autosave = 0 if tmpfid.last > 0 then -- Delete all call pSet_Mark( 1, tmpfid.last, 1, length( textline( tmpfid.last)), 'CHAR', tmpfid) tmpfid.line = 1 tmpfid.col = 1 if marktype() then deletemark endif deleteline 1, tmpfid endif tmpfid.modify = 0 else -- Create new .compilefiles tmpfid = LoadHiddenFile( '.compilefiles') deleteline 1, tmpfid tmpfid.modify = 0 endif if tmpfid = '' then rc = 2 return endif fUnique = 1 -- 1) myepm\macros\mystuff.e UserMacrosDir = NepmdUserDir'\macros' EFile = UserMacrosDir'\mystuff.e' if Exist( EFile) then Basename = GetFileSpec( 'B', EFile) EFile = Basename -- Append EFile to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) endif -- 2) myepm\ex Handle = '' -- Always create a new handle next = '' UserExDir = NepmdUserDir'\ex' do while NepmdGetNextFile( UserExDir'\*.ex', Handle, next) -- Ignore .ex files starting with '_' or '.' Name = GetFileSpec( 'N', next) if wordpos( leftstr( Name, 1), '_ .') then iterate endif Basename = lowcase( GetFileSpec( 'B', next)) Dir = QueryConfigKey( KeyPathEFiles'\'Basename'.e\Dir') if Dir then EFile = Dir'\'Basename'.e' else EFile = Basename endif -- Append Basename to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) enddo -- 3) myepm\autolink Handle = '' -- Always create a new handle next = '' UserAutoLinkDir = NepmdUserDir'\autolink' do while NepmdGetNextFile( UserAutoLinkDir'\*.ex', Handle, next) -- Ignore .ex files starting with '_' or '.' Name = GetFileSpec( 'N', next) if wordpos( leftstr( Name, 1), '_ .') then iterate endif Basename = lowcase( GetFileSpec( 'B', next)) Dir = QueryConfigKey( KeyPathEFiles'\'Basename'.e\Dir') if Dir then EFile = Dir'\'Basename'.e' else EFile = Basename endif -- Append Basename to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) enddo -- 4) netlabs\ex Handle = '' -- Always create a new handle next = '' NetlabsExDir = NepmdRootDir'\netlabs\ex' do while NepmdGetNextFile( NetlabsExDir'\*.ex', Handle, next) -- Ignore .ex files starting with '_' or '.' Name = GetFileSpec( 'N', next) if wordpos( leftstr( Name, 1), '_ .') then iterate endif Basename = lowcase( GetFileSpec( 'B', next)) EFile = Basename -- Append Basename to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) enddo -- 5) myepm\project\ Handle = '' -- Always create a new handle next = '' UserProjectDir = NepmdUserDir'\project' do while NepmdGetNextDir( UserProjectDir'\*', Handle, next) Projectname = lowcase( GetFileSpec( 'N', next)) EFile = next'\'Projectname'.e' if Exist( EFile) then -- Append EFile to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) endif enddo -- 6) netlabs\project\ Handle = '' -- Always create a new handle next = '' NetlabsProjectDir = NepmdRootDir'\netlabs\project' do while NepmdGetNextDir( NetlabsProjectDir'\*', Handle, next) Projectname = lowcase( GetFileSpec( 'N', next)) EFile = next'\'Projectname'.e' if Exist( EFile) then -- Append EFile to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) endif enddo -- 7) Basenames in .lst files ListFileList = GetUserNetlabsFile( 'exfiles.lst', 'ex')';' || GetUserNetlabsFile( 'actions.lst', 'ex')';' || NepmdUserDir'\ex\macroadd.lst;' || NepmdUserDir'\autolink\autolink.lst' RestList = ListFileList do while RestList <> '' parse value RestList with ListFile ';' RestList if not Exist( ListFile) then leave endif display -2 getfileid start2fid -- Load ListFile 'xcom e /d' ListFile if rc <> 0 then leave endif getfileid listfid .visible = 0 -- Read lines do l = 1 to .last Line = textline( l) StrippedLine = strip( Line) -- Ignore comments, lines starting with ';' at column 1 are comments if substr( Line, 1, 1) = ';' then iterate -- Ignore empty lines elseif StrippedLine = '' then iterate endif EFile = StrippedLine -- Either a basename or a full .e filename EFile = StripQuotesFileSpec( EFile) -- Append EFile to .compilefiles call AppendHiddenFile( tmpfid, EFile, fUnique) enddo -- l -- Quit ListFile activatefile listfid .modify = 0 'xcom q' pActivateFile( start2fid) display 2 enddo -- Sort all SortOptions = '' rc = Sort( 1, tmpfid.last, 1, 40, tmpfid, SortOptions) tmpfid.modify = 0 activatefile startfid return tmpfid ; --------------------------------------------------------------------------- ; Returns FullName of ExFile when found, else nothing. ; Doesn't search in current dir. The path of ExFile is stripped to get its ; name. defproc FindExFile( ExFile) UserDir = Get_Env( 'NEPMD_USERDIR') NetlabsDir = Get_Env( 'NEPMD_ROOTDIR')'\netlabs' AutolinkDir = UserDir'\autolink' UserProjectDir = UserDir'\project' NetlabsProjectDir = NetlabsDir'\project' FullExFile = '' -- Strip path and ensure that extension is 'ex' Ext = GetFileSpec( 'E', ExFile) if wordpos( upcase( Ext), 'EX E') then ExFile = GetFileSpec( 'B', ExFile)'.ex' else ExFile = GetFileSpec( 'N', ExFile)'.ex' endif ExFileBasename = GetFileSpec( 'B', ExFile) UpExFileBasename = upcase( ExFileBasename) do once = 1 to 1 -- Search ExFile in autolink if Exist( AutolinkDir'\'ExFile) then FullExFile = AutolinkDir'\'ExFile leave endif -- Search ExFile in user projects DirMask = UserProjectDir'\*' Handle = '' -- Always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpExFileBasename <> upcase( ProjectName) then iterate endif CheckFile = UserProjectDir'\'ProjectName'\'ExFile if Exist( CheckFile) then FullExFile = CheckFile NepmdGetNextClose( Handle) leave endif enddo if FullExFile <> '' then leave endif -- Search ExFile in netlabs projects DirMask = NetlabsProjectDir'\*' Handle = '' -- always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpExFileBasename <> upcase( ProjectName) then iterate endif CheckFile = NetlabsProjectDir'\'ProjectName'\'ExFile if Exist( CheckFile) then FullExFile = CheckFile NepmdGetNextClose( Handle) leave endif enddo if FullExFile <> '' then leave endif -- Search ExFile in EPMEXPATH FullExFile = NepmdSearchPath( ExFile, 'EPMEXPATH') enddo return FullExFile ; --------------------------------------------------------------------------- ; Returns FullName of EFile when found, else nothing. ; Doesn't search in current dir. defproc FindEFile( EFile) UserDir = Get_Env( 'NEPMD_USERDIR') NetlabsDir = Get_Env( 'NEPMD_ROOTDIR')'\netlabs' UserProjectDir = UserDir'\project' NetlabsProjectDir = NetlabsDir'\project' FullEFile = '' -- Strip path and ensure that extension is 'e' Ext = GetFileSpec( 'E', EFile) if wordpos( upcase( Ext), 'E EX') then EFile = GetFileSpec( 'B', EFile)'.e' else EFile = GetFileSpec( 'N', EFile)'.e' endif EFileBasename = GetFileSpec( 'B', EFile) UpEFileBasename = upcase( EFileBasename) do once = 1 to 1 -- autolink is for .ex files only -- Search EFile in user projects DirMask = UserProjectDir'\*' Handle = '' -- Always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpEFileBasename <> upcase( ProjectName) then iterate endif CheckFile = UserProjectDir'\'ProjectName'\'EFile if Exist( CheckFile) then FullEFile = CheckFile NepmdGetNextClose( Handle) leave endif enddo if FullEFile <> '' then leave endif -- Search EFile in netlabs projects DirMask = NetlabsProjectDir'\*' Handle = '' -- always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpEFileBasename <> upcase( ProjectName) then iterate endif CheckFile = NetlabsProjectDir'\'ProjectName'\'EFile if Exist( CheckFile) then FullEFile = CheckFile NepmdGetNextClose( Handle) leave endif enddo if FullEFile <> '' then leave endif -- Search EFile in EPMMACROPATH FullEFile = NepmdSearchPath( EFile, 'EPMMACROPATH') enddo return FullEFile ; --------------------------------------------------------------------------- ; Determines destination dir for an ExFile recompilation. ; Doesn't search in current dir. The path of ExFile is stripped to get its ; name. defproc GetExFileDestDir( ExFile) UserDir = Get_Env( 'NEPMD_USERDIR') NetlabsDir = Get_Env( 'NEPMD_ROOTDIR')'\netlabs' AutolinkDir = UserDir'\autolink' UserProjectDir = UserDir'\project' NetlabsProjectDir = NetlabsDir'\project' DestDir = '' -- Strip path and get corresponding EFile with extension 'e' Ext = GetFileSpec( 'E', ExFile) if wordpos( upcase( Ext), 'EX E') then ExFile = GetFileSpec( 'B', ExFile)'.ex' EFile = GetFileSpec( 'B', ExFile)'.e' else ExFile = GetFileSpec( 'N', ExFile)'.ex' EFile = GetFileSpec( 'N', ExFile)'.e' endif EFileBasename = GetFileSpec( 'B', EFile) UpEFileBasename = upcase( EFileBasename) do once = 1 to 1 -- Search ExFile in autolink if Exist( AutolinkDir'\'ExFile) then DestDir = AutolinkDir leave endif -- Search EFile in user projects DirMask = UserProjectDir'\*' Handle = '' -- Always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpEFileBasename <> upcase( ProjectName) then iterate endif CheckFile = UserProjectDir'\'ProjectName'\'EFile if Exist( CheckFile) then DestDir = UserProjectDir'\'ProjectName NepmdGetNextClose( Handle) leave endif enddo if DestDir <> '' then leave endif -- Search EFile in netlabs projects DirMask = NetlabsProjectDir'\*' Handle = '' -- always create a new handle NextDir = '' do while NepmdGetNextDir( DirMask, Handle, NextDir) ProjectName = GetFileSpec( 'N', NextDir) if UpEFileBasename <> upcase( ProjectName) then iterate endif CheckFile = NetlabsProjectDir'\'ProjectName'\'EFile if Exist( CheckFile) then DestDir = NetlabsProjectDir'\'ProjectName NepmdGetNextClose( Handle) leave endif enddo if DestDir <> '' then leave endif -- Use UserDir'\ex' DestDir = UserDir'\ex' enddo return DestDir ; --------------------------------------------------------------------------- defproc FindLinkedExFile( ExFile) do once = 1 to 1 FullExFile = '' -- Strip path and ensure that extension is 'ex' Ext = GetFileSpec( 'E', ExFile) if wordpos( upcase( Ext), 'EX E') then ExFile = GetFileSpec( 'B', ExFile)'.ex' else ExFile = GetFileSpec( 'N', ExFile)'.ex' endif -- Return empty if ExFile is not linked if not linked( ExFile) then leave endif -- In the following ExFile is linked if pos( ':\', ExFile) then -- Found: full filename specified FullExFile = ExFile leave endif -- Check the array of linked filenames LastLinkNum = GetAVar( 'linknum.last') if LastLinkNum = '' then LastLinkNum = 0 endif do n = 0 to LastLinkNum Fullname = GetAVar( 'linkfilename.'n) if upcase( GetFileSpec( 'N', Fullname)) = upcase( ExFile) then -- Found: previously linked by the 'Link' command FullExFile = Fullname leave endif enddo enddo return FullExFile ; --------------------------------------------------------------------------- ; This is the same def as AppendFile of FILE.E. Using this def here allows ; for unlinking of FILE.EX by RecompileNew. compile if not defined( EPM_EDIT_LOGAPPEND) const EPM_EDIT_LOGAPPEND = 5496 compile endif defproc AppendLogFile( OutFile, Text) TextZ = Text\0 OutFileZ = OutFile\0 call windowmessage( 1, getpminfo( EPMINFO_EDITFRAME), EPM_EDIT_LOGAPPEND, ltoa( offset( OutFileZ)''selector( OutFileZ), 10), ltoa( offset( TextZ)''selector( TextZ), 10)) return ; --------------------------------------------------------------------------- defproc WriteLog( LogFile, Msg) LineEnd = \13\10 -- Break long lines if Msg = '' then -- Msg must not be empty for verify IndLen = 0 else IndLen = verify( Msg, ' ', 'N') - 1 endif Indent = copies( ' ', IndLen) MaxLen = 71 Rest = Msg Msg = '' do while Rest <> '' if length( Rest) <= MaxLen then Msg = Msg''Rest Rest = '' leave endif Next = strip( leftstr( Rest, MaxLen), 'T') ch = substr( Rest, MaxLen + 1, 1) if ch == ' ' then -- Split at this char Msg = Msg''Next''LineEnd Rest = Indent''strip( substr( Rest, MaxLen + 2)) else -- Find the last space char in Next p = lastpos( ' ', Next) if p > 0 then Next = strip( leftstr( Rest, p - 1), 'T') -- Split at this char Msg = Msg''Next''LineEnd Rest = Indent''strip( substr( Rest, p + 1)) else Msg = Msg''Rest Rest = '' endif endif enddo call AppendLogFile( LogFile, Msg''LineEnd) return ; --------------------------------------------------------------------------- defproc WriteBasenameLog( LogFile, Basename, var fHeaderWritten, Msg) if fHeaderWritten = 0 then WriteLog( LogFile, copies( '-', 71)) WriteLog( LogFile, Basename) fHeaderWritten = 1 endif WriteLog( LogFile, Msg) return ; --------------------------------------------------------------------------- ; Compare .EX and .E macro files from with those from the NETLABS ; tree. defc CheckEpmMacros NepmdUserDir = Get_Env( 'NEPMD_USERDIR') call MakeTree( NepmdUserDir) call MakeTree( NepmdUserDir'\ex') call MakeTree( NepmdUserDir'\macros') call MakeTree( NepmdUserDir'\autolink') 'RecompileNew CheckOnly' ; --------------------------------------------------------------------------- ; Show a MsgBox with the result of RecompileNew, submitted as arg( 1). ; Syntax: RecompileNewMsgBox cError cWarning cRecompile cDelete cRelink fRestart fCheckOnly ; Todo: use different text for fCheckOnly = 1, cRecompile > 0, cRelink > 0 defc RecompileNewMsgBox NepmdUserDir = Get_Env( 'NEPMD_USERDIR') UserDirName = GetFileSpec( 'N', NepmdUserDir) LogFile = NepmdUserDir'\ex\recompilenew.log' parse arg cError cWarning cRecompile cDelete cRelink fRestart fCheckOnly -- Build RestartList for fRestart RestartListIndent = \9 MaxItemsPerLine = 3 ItemSep = ',' RestartList = RestartListIndent'EPM.EX' ItemsOnThisLine = 1 do w = 1 to words( RECOMPILE_RESTART_NAMES) next = upcase( word( RECOMPILE_RESTART_NAMES, w)) parse value next with next'.'ext next = next'.EX' if wordpos( next, RestartList) > 0 then iterate endif if ItemsOnThisLine >= MaxItemsPerLine then RestartList = RestartList''\n''RestartListIndent''next endif if w = words( RECOMPILE_RESTART_NAMES) then ItemSep = ' or' endif if ItemsOnThisLine + 1 >= MaxItemsPerLine then -- Line break RestartList = RestartList''ItemSep' 'next ItemsOnThisLine = 0 else -- Append to line if ItemsOnThisLine = 0 then RestartList = RestartList''ItemSep\n RestartList = RestartList''RestartListIndent''next else RestartList = RestartList''ItemSep' 'next endif ItemsOnThisLine = ItemsOnThisLine + 1 endif enddo Bul = \7 Text = '' if fCheckOnly then Text = Text || 'RecompileNew CHECKONLY:'\n\n else Text = Text || 'RecompileNew:'\n\n Text = Text || ' 'Bul\9''cRecompile' file(s) recompiled'\n Text = Text || ' 'Bul\9''cDelete' file(s) deleted'\n if fRestart then Text = Text || ' 'Bul\9'EPM restarted because recompilation of'\n Text = Text || RestartList\n\n else -- EPM/PM? bug: the doubled \n at the end adds 1 additional space after cRelink: Text = Text || ' 'Bul\9''cRelink' file(s) relinked'\n\n endif endif if cError > 0 then Text = Text || 'Errors(s) occurred during comparison of 'upcase( UserDirName)' files' Text = Text || ' with NETLABS files. See log file' Text = Text || ' 'upcase( UserDirName)'\EX\RECOMPILENEW.LOG'\n\n Text = Text || 'Do you want to load the log file now?' Style = MB_OKCANCEL + MB_ERROR + MB_DEFBUTTON1 + MB_MOVEABLE elseif cWarning > 0 then Text = Text || 'Warning(s) occurred during comparison of 'upcase( UserDirName)' files' Text = Text || ' with NETLABS files. See log file' Text = Text || ' 'upcase( UserDirName)'\EX\RECOMPILENEW.LOG'\n\n Text = Text || 'In order to use all the newly installed NETLABS files,' Text = Text || ' delete or rename the listed 'upcase( UserDirName)' files, that produced' Text = Text || ' a warning. A good idea would be to rename' Text = Text || ' your 'upcase( UserDirName)'\MACROS and 'upcase( UserDirName)'\EX' Text = Text || ' directories before the next EPM start.'\n\n Text = Text || 'Only when you have added your own macros:'\n Text = Text || 'After that, merge your own additions with the new' Text = Text || ' versions of the macros in NETLABS\MACROS.' Text = Text || ' (They can be left in your 'upcase( UserDirName)'\MACROS dir, if there''s' Text = Text || ' no name clash.) Then Recompile your macros. This can be' Text = Text || ' done easily with NEPMD''s RecompileNew command.'\n\n Text = Text || 'Do you want to load the log file now?' Style = MB_OKCANCEL + MB_WARNING + MB_DEFBUTTON1 + MB_MOVEABLE else Text = Text || 'No warning(s) occurred during comparison of 'upcase( UserDirName)' files' Text = Text || ' with NETLABS files.'\n\n Text = Text || 'If you have added own macro files to your MYEPM tree,' Text = Text || ' then they are newer than the files in the NETLABS tree.' Text = Text || ' Apparently no old MYEPM files are used.'\n\n Text = Text || 'Do you want to load the log file now?' Style = MB_OKCANCEL + MB_INFORMATION + MB_DEFBUTTON1 + MB_MOVEABLE endif Title = 'Checked .E and .EX files from 'upcase( UserDirName)' tree' rcx = WinMessageBox( Title, Text, Style) if rcx = MBID_OK then -- check if old LogFile already in ring getfileid logfid, LogFile if logfid <> '' then -- discard previously loaded LogFile from ring getfileid curfid if curfid = logfid then -- quit current file 'xcom quit' else -- temporarily switch to old LogFile and quit it activatefile logfid 'xcom quit' activatefile curfid endif endif 'e 'LogFile endif