BuildLevel.cmd
From EDM2
Written by Roman Stangl
/***********************************************************************\ * BuildLevel.cmd * * Copyright (C) by Stangl Roman, 1996, 1997 * * * * This Code may be freely distributed, provided the Copyright isn't * * removed. * * * * BuildLevel.cmd * * Batch file to replace the DESCRIPTION statement in a * * module's (EXE or DLL) with one the OS/2 BLDLEVEL * * command is able to read. * * Syntax: BuildLevel ModuleDefinitionFile Headerfile * * e.g. BuildLevel PC2.def PC2.h * * * \***********************************************************************/ /* static char _VERSION_[]="BuildLevel.cmd - V2.00"; */ Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs' Call SysLoadFuncs /* Trap CTRL+BRK processing to avoid data corruption */ Signal On HALT NAME SignalHandler /* OS/2 return code */ ReturnCode=1 /* 1st command line argument (1 *.DEF file) */ DefinitionFile="" /* As the contents of the 1st command line argument file get changed, we make a temporary copy to read from and write the new contents to the original file */ DefinitionCopy="$Temp$" /* 2nd command line argument (1 *.H* file) */ HeaderFile="" /* Name of the binary module which gets filled from the NAME (for *.EXE) or LIBRARY (for *.DLL) statement */ ModuleName="" /* Description statement which gets constructed from the header (*.H*) file to replace/add the DESCRIPTION statement in the *.DEF file */ Description="" Description_Header="Description '" Description_Trailer="'" /* The build level part of the DESCRIPTION statement is built from the following substrings */ BldLevel="" BldLevel_Header="$@#" BldLevel_Vendor="" BldLevel_Version="" BldLevel_Info="" BldLevel_Trailer="@#" /*--------------------------------------------------------------------------------------*\ * Main entry point. * * Req: * * none * * Returns: * * ReturnCode .... Error code (0 if no error) * \*--------------------------------------------------------------------------------------*/ /* Get the DefinitionFile (*.DEF) we want to check the BLDLEVEL and the Header file (*.H*) where the required BLDLEVEL data is defined in */ Parse Arg DefinitionFile HeaderFile . Do While (DefinitionFile\="" & HeaderFile\="") /* We have valid command line arguments, so first see if the Header file contents are ok for us */ ReturnCode=ParseHeaderFile() If ReturnCode\=0 Then Leave /* Parse the definition file (*.DEF) for the module name, to see if we got a valid file */ ReturnCode=ParseDefinitionFile() If ReturnCode\=0 Then Leave /* Copy the definition file, because we're going to change the original */ Command="@copy "||DefinitionFile||" "||DefinitionCopy||" /v >NUL" Command Command="@del "||DefinitionFile||" >NUL 2>&1" Command If (rc\=0) Then Do ReturnCode=2 Leave End /* Build DESCRIPTION statement for *.DEF file */ BldLevel=BldLevel_Header||BldLevel_Vendor||":"||BldLevel_Version||" ("||ModuleName||")#@"||BldLevel_Info Description=Description_Header||BldLevel||Description_Trailer /* Copy the module definition file to be able to change the contents of the original one. In case of an error copy back the original one */ ReturnCode=ModifyDefinitionFile() If ReturnCode\=0 Then Do Command="@copy "||DefinitionCopy||" "||DefinitionFile||" /v >NUL" Command Command="@del "||DefinitionCopy||" >NUL 2>&1" Command Leave End /* Exit with success */ Command="@del "||DefinitionCopy||" >NUL 2>&1" Command ReturnCode=0 Leave End /* Exit to commandline */ If (ReturnCode\=0) Then Do Say "" Say "Error "||ReturnCode||" modifying "||DefinitionFile||", no changes made" Say "" End Else Do Say "" Say "Module definition file "||DefinitionFile||" successfully modified" Say "" End Return ReturnCode /*--------------------------------------------------------------------------------------*\ * Parse a C/C++ header file to test that the macros we build the BLDLEVEL information * * from (BLDLEVEL_VENDOR, BLDLEVEL_VERSION, BLDLEVEL_INFO) are defined. * * Req: * * none * * Returns: * * ReturnCode .... Error code (0 if no error) * \*--------------------------------------------------------------------------------------*/ ParseHeaderFile: LinesLeft=2 /* Read ahead 1st line */ CurrentLine=LineIn(HeaderFile, 1, 1) /* Do while there are lines in the file */ Do While(LinesLeft>0) /* Parse for constructs of the form: #define BLDLEVEL_Macro "Value" Comment */ /* Kill that ... tabs */ CurrentLine=Translate(CurrentLine, ' ', X2C(9)) Parse Var CurrentLine Define Macro '"' Value '"' . Parse Upper Var Define Define Define=Space(Define, 0) Parse Upper Var Macro Macro Macro=Space(Macro, 0) /* Test for the macros we expect */ If (Define="#DEFINE") Then Do Select When (Macro="BLDLEVEL_VENDOR") Then Do BldLevel_Vendor=Value End When (Macro="BLDLEVEL_VERSION") Then Do BldLevel_Version=Value End When (Macro="BLDLEVEL_INFO") Then Do BldLevel_Info=Value End Otherwise End End CurrentLine=LineIn(HeaderFile) /* As Lines() returns 0 after having read the last line we have to ensure that this last line will be processed too */ If (Lines(HeaderFile)=0) Then LinesLeft=LinesLeft-1 End If (BldLevel_Vendor\="" & BldLevel_Version\="" & BldLevel_Info\="") Then Return 0 Else Return 10 /*--------------------------------------------------------------------------------------*\ * Parse a C/C++ module definition file to test if this file is used to build a OS/2 * * EXE or DLL file and if it contains a DESCRIPTION line. * * Req: * * none * * Returns: * * ReturnCode .... Error code (0 if no error) * \*--------------------------------------------------------------------------------------*/ ParseDefinitionFile: /* Read ahead 1st line */ Command=Stream(DefinitionFile, 'C', 'OPEN READ') LinesLeft=2 CurrentLine=LineIn(DefinitionFile) /* Do while there are lines in the file */ Do While(LinesLeft>0) /* Parse for constructs of the form: NAME/LIBRARY ModuleName Options */ /* Kill that ... tabs */ CurrentLine=Translate(CurrentLine, ' ', X2C(9)) Parse Var CurrentLine Statement Module Options Parse Upper Var Statement Statement Statement=Space(Statement, 0) Module=Space(Module, 0) If (Module\="") Then Do If (Statement="NAME") Then ModuleName=Module||".exe" If (Statement="LIBRARY") Then ModuleName=Module||".dll" End /* See if there is a DESCRIPTION statement */ Parse Var CurrentLine Statement Options Parse Upper Var Statement Statement Statement=Space(Statement, 0) If (Statement="DESCRIPTION") Then DescriptionStatement=Options CurrentLine=LineIn(DefinitionFile) /* As Lines() returns 0 after having read the last line we have to ensure that this last line will be processed too */ If (Lines(DefinitionFile)=0) Then LinesLeft=LinesLeft-1 End /* Close the stream */ Command=Stream(DefinitionFile, 'C', 'CLOSE') If (ModuleName\="" & DescriptionStatement\="") Then Return 0 Else Return 20 /*--------------------------------------------------------------------------------------*\ * Parse a C/C++ module definition file to modify the DESCRIPTION statement into a form * * that is readable by BLDLEVEL (the original gets discarded). * * Req: * * none * * Returns: * * ReturnCode .... Error code (0 if no error) * \*--------------------------------------------------------------------------------------*/ ModifyDefinitionFile: /* Read and write ahead 1st line */ Command=Stream(DefinitionFile, 'C', 'OPEN WRITE') If (Command="ERROR") Then Return 30 Command=Stream(DefinitionCopy, 'C', 'OPEN READ') If (Command="ERROR") Then Return 31 LinesLeft=2 CurrentLine=LineIn(DefinitionCopy) /* Do while there are lines in the file */ Do While(LinesLeft>0) /* Parse for constructs of the form: DESCRIPTION Options */ /* Kill that ... tabs */ CurrentLine=Translate(CurrentLine, ' ', X2C(9)) Parse Var CurrentLine Statement Options Parse Upper Var Statement Statement Statement=Space(Statement, 0) If (Statement="DESCRIPTION") Then Do Command=LineOut(DefinitionFile, Description) End Else Do Command=LineOut(DefinitionFile, CurrentLine) End CurrentLine=LineIn(DefinitionCopy) /* As Lines() returns 0 after having read the last line we have to ensure that this last line will be processed too */ If (Lines(DefinitionCopy)=0) Then LinesLeft=LinesLeft-1 End /* Close the streams */ Command=Stream(DefinitionFile, 'C', 'CLOSE') Command=Stream(DefinitionCopy, 'C', 'CLOSE') Return 0 /*--------------------------------------------------------------------------------------*\ * Signal Handler that avoids interruption and just tells user that CTRL+BRK is not * * allowed currently. * * Req: * * none * * Returns: * * none * \*--------------------------------------------------------------------------------------*/ SignalHandler: Say " CTRL+BRK currently disabled"
Return to the "Adding BLDLEVEL information to executables article.