BuildLevel.cmd

From EDM2
Jump to: navigation, search

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.