home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxtmp2.zip / MAKESRC.CMD < prev    next >
OS/2 REXX Batch file  |  1995-01-08  |  70KB  |  1,572 lines

  1. /* ------------------------------------------------------------------ */
  2. /* MAKESRC.CMD - extract the source code from a REXX program based on */
  3. /*               TEMPLATE v2.+                                        */
  4. /*                                                                    */
  5. /* (c) Copyright Bernd Schemmer 1994,1995                             */
  6. /*                                                                    */
  7. /* Author:                                                            */
  8. /*   Bernd Schemmer                                                   */
  9. /*   Baeckerweg 48                                                    */
  10. /*   D-60316 Frankfurt am Main                                        */
  11. /*   Germany                                                          */
  12. /*   Compuserve: 100104,613                                           */
  13. /*                                                                    */
  14. /* Usage:                                                             */
  15. /*   MAKESRC {sourceFile} {targetDir}                                 */
  16. /*                                                                    */
  17. /* where:                                                             */
  18. /*   sourceFile - source file (No joker allowed!)                     */
  19. /*   targetDir - directory for the target file (def.: \SOURCE}        */
  20. /*               The extension for the target file is always .SRC!    */
  21. /*                                                                    */
  22. /* returns:                                                           */
  23. /*   0 - okay                                                         */
  24. /*   else error                                                       */
  25. /*                                                                    */
  26. /* Notes:                                                             */
  27. /*   This cmd needs the program RXQUEUE.                              */
  28. /*                                                                    */
  29. /* History:                                                           */
  30. /*   03.12.1994 /bs v1.00                                             */
  31. /*   08.01.1995 /bs v1.10                                             */
  32. /*     - first public release                                         */
  33. /*                                                                    */
  34. /* Distribution:                                                      */
  35. /*   This program is part of the TEMPLATE package. See the file       */
  36. /*   README.DOC from this package or the file TEMPLATE.CMD for my     */
  37. /*   distribution and using policy.                                   */
  38. /*   If you need further help, you may write me a message.            */
  39. /*                                                                    */
  40. /* Based on TEMPLATE.CMD v2.52, TEMPLATE is (c) 1995 Bernd Schemmer,  */
  41. /* Baeckerweg 48, D-60316 Frankfurt, Germany, Compuserve: 100104,613  */
  42. /*                                                                    */
  43. /* ------------------------------------------------------------------ */
  44.  
  45.                         /* init all global stems                      */
  46. parse value '' with prog. global. screen. I!.
  47.  
  48. /* ------------------------------------------------------------------ */
  49. /*** change the following values to your need                       ***/
  50.  
  51.          global.__Version = 1.10         /* Version of YOUR program   */
  52.  
  53.        global.__SignOnMsg = 1   /* set to 0 if you do not want the    */
  54.                                 /* program start and end messages     */
  55.  
  56.          global.__NeedCID = 0   /* set to 1 if you need CID support   */
  57.  
  58.       global.__NeedColors = 1   /* set to 1 if you want colored msgs  */
  59.  
  60.   global.__NeedPatchCheck = 1   /* set to 1 if you want the program   */
  61.                                 /* to search for a patched version of */
  62.                                 /* this program                       */
  63.  
  64. /***                End of variables to change                      ***/
  65. /*      HINT: The further program code is in the function MAIN        */
  66.  
  67. /***        End of Part 1 of the source code of TEMPLATE.CMD        ***/
  68.  
  69.  
  70. /***       Start of Part 2 of the source code of TEMPLATE.CMD       ***/
  71.  
  72. /*************** DO NOT CHANGE THE FOLLOWING LINES ********************/
  73.  
  74.                         /* names of the global variables, which all   */
  75.                         /* procedures must know                       */
  76. exposeList = 'prog. screen. I!. global. exposeList '
  77.  
  78.                         /* init all global stems                      */
  79. parse value '' with prog. screen. I!.
  80.  
  81.                         /* get the number of the first line with      */
  82.                         /* user code                                  */
  83. call I!.__GetUserCode
  84.  
  85. /* ------------------------------------------------------------------ */
  86. /* install the error handler                                          */
  87.  
  88.                         /* break errors (CTRL-C)                      */
  89.   CALL ON HALT        NAME I!.__UserAbort
  90.                         /* syntax errors                              */
  91.   SIGNAL ON SYNTAX    NAME I!.__ErrorAbort
  92.                         /* using of not initialisized variables       */
  93.   SIGNAL ON NOVALUE   NAME I!.__ErrorAbort
  94.                         /*                                            */
  95.   SIGNAL ON FAILURE   NAME I!.__ErrorAbort
  96.                         /*                                            */
  97.   SIGNAL ON ERROR     NAME I!.__ErrorAbort
  98.                         /*                                            */
  99.   SIGNAL ON NOTREADY  NAME I!.__ErrorAbort
  100.  
  101. /* ------------------------------------------------------------------ */
  102. /* init the variables                                                 */
  103.  
  104.   parse arg I!.__RealParameter
  105.  
  106.   prog.__QParm = '/SILENT'
  107.  
  108.                         /* check for the parameter /SILENT            */
  109.   if pos( prog.__QParm, translate( I!.__RealParameter ) ) <> 0 then
  110.   do
  111.     parse var I!.__RealParameter prog.__Param (prog.__QParm) I!.__rest
  112.     prog.__Param = prog.__Param I!.__Rest
  113.     prog.__QuietMode = 1
  114.   end /* if pos( ... */
  115.   else
  116.     prog.__Param = I!.__RealParameter
  117.   call I!.__InitVars
  118.  
  119. /* ------------------------------------------------------------------ */
  120. /* show program start message                                         */
  121.  
  122.   if global.__SignOnMsg = 1 then
  123.   do
  124.     screen.__CurColor = screen.__SignOnColor
  125.     call Log prog.__Name || " " || global.__version || " started on " || ,
  126.          date() || ' at ' || time() || ' ...'
  127.     screen.__CurColor = screen.__NormalColor
  128.   end /* if global.__SignOnMsg = 1 then */
  129.  
  130. /* ------------------------------------------------------------------ */
  131.  
  132.                         /* check if there is a patched version of     */
  133.                         /* this program                               */
  134.   if global.__NeedPatchCheck <> 0 then
  135.     call I!.__CheckPatch
  136.  
  137. /* ------------------------------------------------------------------ */
  138.                         /* check for a help parameter                 */
  139.   if pos( translate( word( prog.__Param,1 ) ), ,
  140.           '/?/H/HELP/-?-H-HELP' ) <> 0 then
  141.   do
  142.     prog.__exitCode = 253
  143.  
  144.     call I!.__CallUserProc 1, 'ShowUsage'
  145.  
  146.     SIGNAL I!.__programEnd
  147.  
  148.   end /* pos( translate( ... */
  149.  
  150. /* ------------------------------------------------------------------ */
  151.  
  152.                         /* call the main procedure                    */
  153.   call I!.__CallUserProc 2, 'main' prog.__Param
  154.                         /* set prog.__ExitCode to the return          */
  155.                         /* code of the function main, if any          */
  156.                         /* returned                                   */
  157.   if symbol( 'I!.__UserProcRC' ) = 'VAR' then
  158.     prog.__ExitCode = I!.__UserProcRC
  159.  
  160. /* ------------------------------------------------------------------ */
  161. /* house keeping                                                      */
  162.  
  163. I!.__ProgramEnd:
  164.  
  165.                                 /* call exit routines                 */
  166.   do while strip( prog.__exitRoutines ) <> ''
  167.     I!.__CurExitRoutine = word( prog.__ExitRoutines,1 )
  168.  
  169.                         /* delete the name of the routine from the    */
  170.                         /* list to avoid endless loops!               */
  171.     prog.__ExitRoutines = substr( prog.__ExitRoutines , ,
  172.                           Pos( I!.__CurExitRoutine, ,
  173.                                prog.__ExitRoutines ) + ,
  174.                           length( I!.__CurExitRoutine ) )
  175.  
  176.     call I!.__CallUserProc 1, I!.__CurExitRoutine
  177.  
  178.   end /* do while strip( prog.__ExitRoutines ) <> '' */
  179.  
  180.                                 /* reset the current directory        */
  181.   if symbol( 'prog.__CurDir' ) = 'VAR' then
  182.     call directory prog.__CurDir
  183.  
  184.   if global.__SignOnMsg = 1 then
  185.   do
  186.                                 /* check if the exit code is decimal  */
  187.     if dataType( prog.__ExitCode, "W" ) then
  188.     do
  189.                                 /* convert exit code to hexadecimal   */
  190.       if prog.__ExitCode < 0 then
  191.         prog.__ExitCode = 65536 + prog.__ExitCode
  192.       prog.__hexExitCode = " ('" || D2X( prog.__ExitCode ) || "'x)"
  193.     end /* if .. */
  194.     else
  195.       prog.__hexExitCode = ''
  196.  
  197.                                 /* show program end message           */
  198.     screen.__CurColor = screen.__SignOnColor
  199.     call Log prog.__Name || " " || global.__Version || " ended on " || ,
  200.          date() || ' at ' || time() || ' with RC = ' || ,
  201.          prog.__ExitCode || prog.__hexExitCode
  202.  
  203.     screen.__CurColor = screen.__NormalColor
  204.   end /* if global.__SignOnMsg = 1 then */
  205.  
  206. EXIT prog.__ExitCode
  207.  
  208. /* ------------------------------------------------------------------ */
  209. /*-function: call a user defined routine                              */
  210. /*           (avoid errors if the routine is not defined)             */
  211. /*                                                                    */
  212. /*-call:     I!.__CallUserProc errorAction, procName {prcoParameter}  */
  213. /*                                                                    */
  214. /*-where:    errorAction - action, if procName is not defined         */
  215. /*                         0: do nothing (only set the RC)            */
  216. /*                         1: show a warning and set the RC           */
  217. /*                         2: abort the program                       */
  218. /*           procName - name of the procedure                         */
  219. /*           procParameter - parameter for the procedure              */
  220. /*                                                                    */
  221. /*-returns:  1 - ok                                                   */
  222. /*           0 - procname not found                                   */
  223. /*                                                                    */
  224. /*-output:   I!.__UserProcRC - Returncode of the called procedure     */
  225. /*                             (uninitialisied if the proedure didn't */
  226. /*                             reeturn a value)                       */
  227. /*                                                                    */
  228. I!.__CallUserProc: PROCEDURE expose (exposeList) result rc sigl
  229.   parse arg I!.__ErrorAction , I!.__procName I!.__procParameter
  230.  
  231.   I!.__thisRC = 0
  232.   drop I!.__UserProcRC
  233.  
  234.   iLine =  'call ' I!.__procName
  235.  
  236.   if I!.__procParameter <> '' then
  237.   do
  238.     if pos( '"' , I!.__procParameter ) = 0 then
  239.       iLine = iLine || ' "' I!.__procParameter '"'
  240.     else
  241.       iLine = iLine || " '" I!.__procParameter "'"
  242.   end /* if I!.__procParameter <> '' then */
  243.  
  244. /*  I!.__MaxLength = 263 */
  245.   if length( iLine ) > 263 then
  246.     call ShowError global.__ErrorExitCode ,,
  247.          'To many parameters defined for the call of the routine "' || ,
  248.          I!.__procName || '" (The max. length for the parameter is ' || ,
  249.          263 - length( I!.__procName ) -11 || ')'
  250. /*  drop I!.__maxLength */
  251.  
  252. /*** DO NOT CHANGE, ADD OR DELETE ONE OF THE FOLLOWING FOUR LINES!! ***/
  253.   SIGNAL I!.__CallUserProc1
  254. I!.__CallUserProc1:
  255.   I!.__InterpretCMDLine = sigl + 3
  256.   interpret iLine
  257. /*** DO NOT CHANGE, ADD OR DELETE ONE OF THE PRECEEDING FOUR LINES! ***/
  258.  
  259.   I!.__thisRC = 1
  260.   if symbol( 'RESULT' ) = 'VAR' then
  261.     I!.__UserProcRC = value( 'RESULT' )
  262.  
  263. I!.__CallUserProc2:
  264.  
  265.   if I!.__ThisRC = 0 then
  266.     select
  267.       when I!.__ErrorAction = 0 then
  268.         nop
  269.       when I!.__ErrorAction = 1 then
  270.         call ShowWarning 'Can not find the routine "' || ,
  271.                          I!.__procName || '"'
  272.       when I!.__ErrorAction = 2 then
  273.         call ShowError global.__ErrorExitCode , ,
  274.                        'Can not find the routine "' || I!.__procName || '"'
  275.     end /* select */
  276.  
  277. RETURN I!.__thisRC
  278.  
  279. /* ------------------------------------------------------------------ */
  280. /*-function: set the variables for the logfile handling               */
  281. /*                                                                    */
  282. /*-call:     I!.__SetLogVars                                          */
  283. /*                                                                    */
  284. /*-input:    prog.__Param - parameter for the program                 */
  285. /*                                                                    */
  286. /*-output:   prog.__LogFile     - name of the logfile (or NUL)        */
  287. /*           prog.__LogSTDERR   - string to direct STDERR into the    */
  288. /*                                logfile                             */
  289. /*           prog.__LogSTDOUT   - string to direct STDOUT into the    */
  290. /*                                logfile                             */
  291. /*           prog.__LogAll      - string to direct STDOUT and STDERR  */
  292. /*                                into the logfile                    */
  293. /*           prog.__LogFileParm - string to inherit the logfile       */
  294. /*                                parameter to a child CMD            */
  295. /*           prog.__Param       - program parameter without the       */
  296. /*                                logfile parameter                   */
  297. /*                                                                    */
  298. /*-returns:  ''                                                       */
  299. /*                                                                    */
  300. I!.__SetLogVars: PROCEDURE expose (exposeList)
  301.   parse var prog.__Param prog.__param "/L:" logFileName " " rest
  302.  
  303.   prog.__param= prog.__Param rest
  304.  
  305.                         /* avoid an error if the drive is not ready   */
  306.   SIGNAL OFF NOTREADY
  307.   if logFileName <> '' then
  308.   do
  309.                         /* check if we can write to the logfile       */
  310.     logStatus = stream( logFileName, 'c', 'OPEN WRITE')
  311.     if logStatus <> 'READY:' then
  312.     do
  313.       prog.__LogFile = 'NUL'
  314.       prog.__LogFileParm = ''
  315.  
  316.       call ShowWarning 'Can not write to the logfile "' || logFileName || ,
  317.                        '", the status of the logfile is "' || ,
  318.                        logStatus || ,
  319.                        '". Now using the NUL device for logging'
  320.     end /* if logStatus <> 'READY' then */
  321.     else
  322.     do
  323.                         /* close the logfile                          */
  324.       call stream logFileName, 'c', 'CLOSE'
  325.  
  326.                         /* get the full name (incl. the path) of the  */
  327.                         /* logfile                                    */
  328.       prog.__LogFile = stream( logFileName, 'c', 'QUERY EXIST' )
  329.  
  330.       prog.__LogFileParm = '/L:' || prog.__LogFile
  331.     end /* else */
  332.   end /* if prog.__LogFile <> '' then */
  333.   else
  334.     prog.__LogFile = 'NUL'
  335.  
  336.   prog.__LogFile = translate( prog.__LogFile )
  337.  
  338.                         /* variable to direct STDOUT of an OS/2       */
  339.                         /* program into the logfile                   */
  340.   prog.__LogSTDOUT = ' 1>>' || prog.__LogFile
  341.  
  342.                         /* variable to direct STDERR of an OS/2       */
  343.                         /* program into the logfile                   */
  344.   prog.__LogSTDERR = ' 2>>' || prog.__LogFile
  345.  
  346.                         /* variable to direct STDOUT and STDERR of    */
  347.                         /* an OS/2 program into the log file          */
  348.       prog.__LogALL = ' 2>>' || prog.__LogFile || ' 1>>&2'
  349.  
  350. RETURN ''
  351.  
  352. /* ------------------------------------------------------------------ */
  353. /*-function: check some environment variables                         */
  354. /*                                                                    */
  355. /*-call:     I!.__CheckEnvVars                                        */
  356. /*                                                                    */
  357. /*-where:    -                                                        */
  358. /*                                                                    */
  359. /*-returns:  ''                                                       */
  360. /*                                                                    */
  361. I!.__CheckEnvVars: PROCEDURE expose (exposeList)
  362.  
  363.                     /* check if we should show the debug information  */
  364.   global.__verbose = value( 'verbose' ,, prog.__env )
  365.  
  366.                     /* check if we should not use colors              */
  367.   testV = translate( value( 'ANSI' ,, prog.__env ) )
  368.   if testV = "OFF" | testV = 0 then
  369.     screen. = ''
  370.  
  371.                     /* check if we should not use sounds              */
  372.   testV = translate( value( 'SOUND' ,, prog.__env ) )
  373.   if testV = "OFF" | testV = 0 then
  374.     prog.__noSound = 1
  375.  
  376. RETURN ''
  377.  
  378. /* ------------------------------------------------------------------ */
  379. /*-function:  convert a file or directory name to OS conventions      */
  380. /*            by adding a leading and trailing quote or double quote  */
  381. /*                                                                    */
  382. /*-call:      convertNameToOS dir_or_file_name                        */
  383. /*                                                                    */
  384. /*-where:     dir_or_file_name = name to convert                      */
  385. /*                                                                    */
  386. /*-returns:   converted file or directory name                        */
  387. /*                                                                    */
  388. ConvertNameToOS: PROCEDURE expose (exposeList)
  389.   parse arg fn
  390.  
  391.   if pos( '"', fn ) = 0 then
  392.     fn = '"' || fn || '"'
  393.   else if pos( "'", fn ) = 0 then
  394.     fn = "'" || fn || "'"
  395.  
  396. RETURN fn
  397.  
  398. /* ------------------------------------------------------------------ */
  399. /*-function: flush the default REXX queue                             */
  400. /*                                                                    */
  401. /*-call:     FlushQueue                                               */
  402. /*                                                                    */
  403. /*-returns:  ''                                                       */
  404. /*                                                                    */
  405. FlushQueue: PROCEDURE expose (exposeList)
  406.   do while( QUEUED() <> 0 )
  407.     pull i
  408.   end /* do while( QUEUED() <> 0 ) */
  409. RETURN ''
  410.  
  411. /* ------------------------------------------------------------------ */
  412. /*-function: include a file if it exists                              */
  413. /*                                                                    */
  414. /*-call:     TryInclude( IncludeFile )                                */
  415. /*                                                                    */
  416. /*-where:    IncludeFile = name of the file to include                */
  417. /*                                                                    */
  418. /*-output:   prog.__rc = 0 - include file executed                    */
  419. /*           else: file not found                                     */
  420. /*                                                                    */
  421. /*-returns:  ''                                                       */
  422. /*                                                                    */
  423. /*-Note:     You do not need the 'call' keyword to use this routine.  */
  424. /*                                                                    */
  425. TryInclude:
  426.   parse arg I!.__TryIncludeFile
  427.  
  428.   prog.__rc = 1
  429.  
  430.   if I!.__TryIncludeFile <> '' then
  431.     if stream( I!.__TryIncludeFile, 'c', 'QUERY EXIST' ) <> '' then
  432.     do
  433.       prog.__rc = 0
  434.       call Include I!.__TryIncludeFile
  435.     end /* if stream( ... */
  436.   drop I!.__TryIncludeFile
  437. RETURN ''
  438.  
  439. /* ------------------------------------------------------------------ */
  440. /*-function: include a file                                           */
  441. /*                                                                    */
  442. /*-call:     Include( IncludeFile )                                   */
  443. /*                                                                    */
  444. /*-where:    IncludeFile = name of the file to include                */
  445. /*                                                                    */
  446. /*-returns:  ''                                                       */
  447. /*                                                                    */
  448. /*-Note:     You do not need the 'call' keyword to use this routine.  */
  449. /*                                                                    */
  450. Include:
  451.   parse upper arg I!.__IncFileName
  452.  
  453.                         /* check if the include file exists           */
  454.   if stream( I!.__IncFileName, 'c', 'QUERY EXIST') = '' then
  455.     call ShowError global.__ErrorExitCode, ,
  456.                    'Can not find the include file "' || ,
  457.                    I!.__IncFileName || '"'
  458.  
  459.                         /* read and interpret the include file        */
  460.   do I!.__IncLineNO = 1 while lines( I!.__IncFileName ) <> 0
  461.     I!.__IncCurLine = ''
  462.                         /* save the absolute position of the start of */
  463.                         /* this line for the error handler            */
  464.     I!.__IncCurLinePos = stream(I!.__IncFileName,'c','SEEK +0')
  465.  
  466.                         /* handle multi line statements               */
  467.     do forever
  468.       I!.__IncCurLine = I!.__IncCurLine ,
  469.                         strip( lineIn( I!.__IncFileName ) )
  470.  
  471.       if right( I!.__IncCurLine,1 ) = ',' then
  472.       do
  473.                         /* statement continues on the next line       */
  474.         if lines( I!.__IncFileName ) = 0 then
  475.           call ShowError global.__ErrorExitCode ,,
  476.             'Unexpected EOF detected while reading the include file "' ||,
  477.             I!.__IncFileName || '"'
  478.         else
  479.           I!.__IncCurLine = substr( I!.__IncCurLine,1, ,
  480.                                     length( I!.__IncCurLine )-1 )
  481.       end /* if right( ... */
  482.       else
  483.         leave
  484.     end /* do forever */
  485.  
  486.     I!.__IncActive = 1
  487.     interpret I!.__IncCurLine
  488.     I!.__IncActive = 0
  489.  
  490.   end /* do I!.__IncLineNO = 1 while lines( I!.__IncFileName ) <> 0 ) */
  491.  
  492.                         /* close the include file!                    */
  493.   call stream I!.__IncFileName 'c' 'CLOSE'
  494.  
  495. RETURN ''
  496.  
  497. /* ------------------------------------------------------------------ */
  498. /*-function: init color variables                                     */
  499. /*                                                                    */
  500. /*-call:     I!.__InitColorVars                                       */
  501. /*                                                                    */
  502. /*-returns:  ''                                                       */
  503. /*                                                                    */
  504. I!.__InitColorVars: PROCEDURE expose (exposeList)
  505.  
  506.   if global.__NeedColors = 1 then
  507.   do
  508.                         /* delete rest of the line                    */
  509.        screen.__DelEOL = '1B'x || '[K'
  510.  
  511.                         /* save the cursor position                   */
  512.       screen.__SavePos = '1B'x || '[s'
  513.  
  514.                         /* restore the cursor position                */
  515.       screen.__RestPos = '1B'x || '[u'
  516.  
  517.                         /* define color attributes                    */
  518.       screen.__AttrOff = '1B'x || '[0;m'
  519.     screen.__Highlight = '1B'x || '[1;m'
  520.        screen.__normal = '1B'x || '[2;m'
  521.         screen.__blink = '1B'x || '[5;m'
  522.        screen.__invers = '1B'x || '[7;m'
  523.     screen.__invisible = '1B'x || '[8;m'
  524.  
  525.                         /* define foreground color variables          */
  526.       screen.__fgBlack = '1B'x || '[30;m'
  527.         screen.__fgRed = '1B'x || '[31;m'
  528.       screen.__fgGreen = '1B'x || '[32;m'
  529.      screen.__fgYellow = '1B'x || '[33;m'
  530.        screen.__fgBlue = '1B'x || '[34;m'
  531.    screen.__fgMagnenta = '1B'x || '[35;m'
  532.        screen.__fgCyan = '1B'x || '[36;m'
  533.       screen.__fgWhite = '1B'x || '[37;m'
  534.  
  535.                         /* define background color variables          */
  536.       screen.__bgBlack = '1B'x || '[40;m'
  537.         screen.__bgRed = '1B'x || '[41;m'
  538.       screen.__bgGreen = '1B'x || '[42;m'
  539.      screen.__bgYellow = '1B'x || '[43;m'
  540.        screen.__bgBlue = '1B'x || '[44;m'
  541.    screen.__bgMagnenta = '1B'x || '[45;m'
  542.        screen.__bgCyan = '1B'x || '[46;m'
  543.       screen.__bgWhite = '1B'x || '[47;m'
  544.  
  545.                         /* define color variables                     */
  546.     screen.__ErrorColor = screen.__AttrOff || screen.__Highlight || ,
  547.                           screen.__FGYellow || screen.__bgRed
  548.    screen.__NormalColor = screen.__AttrOff ||                       ,
  549.                           screen.__fgWhite || screen.__bgBlack
  550.     screen.__DebugColor = screen.__AttrOff || screen.__Highlight || ,
  551.                           screen.__fgBlue || screen.__bgWhite
  552.    screen.__PromptColor = screen.__AttrOff || screen.__Highlight || ,
  553.                           screen.__fgYellow || screen.__bgMagnenta
  554.  
  555. /* +++++++++++++++ DO NOT USE THE FOLLOWING COLORS! +++++++++++++++++ */
  556.    screen.__SignOnColor = screen.__AttrOff || screen.__Highlight || ,
  557.                           screen.__fggreen || screen.__bgBlack
  558.     screen.__PatchColor = screen.__AttrOff || screen.__Highlight || ,
  559.                           screen.__fgcyan || screen.__bgRed
  560. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  561.  
  562.                             /* set the default color                  */
  563.    screen.__CurColor = screen.__NormalColor
  564.  
  565.   end /* if global.__NeedColors = 1 then */
  566.   else
  567.   do
  568.                         /* init all color variables with ''           */
  569.     screen. = ''
  570.   end /* else */
  571.  
  572. RETURN ''
  573.  
  574. /* ------------------------------------------------------------------ */
  575. /*-function: init the stem prog.                                      */
  576. /*                                                                    */
  577. /*-call:     I!.__InitProgStem                                        */
  578. /*                                                                    */
  579. /*-returns:  ''                                                       */
  580. /*                                                                    */
  581. /*-Note:     DO NOT ADD ANY CODE TO THIS ROUTINE!                     */
  582. /*                                                                    */
  583. I!.__InitProgStem: PROCEDURE expose (exposeList)
  584.                         /* get drive, path and name of this program   */
  585.   parse upper source . . prog.__FullName
  586.         prog.__Drive = filespec( "drive", prog.__FullName )
  587.          prog.__Path = filespec( "path",  prog.__FullName )
  588.          prog.__Name = filespec( "name",  prog.__FullName )
  589.           prog.__Env = 'OS2ENVIRONMENT'
  590.        prog.__CurDir = translate( directory() )
  591.                         /* version of TEMPLATE.CMD                    */
  592.       prog.__Version = 'V2.52'
  593.      prog.__ExitCode = 0
  594.     prog.__UserAbort = 1        /* allow user aborts                  */
  595.  prog.__ExitRoutines = ''       /* list of routines to execute at     */
  596.                                 /* program end                        */
  597.   prog.__ScreenCols = 80
  598.   prog.__ScreenRows = 25
  599.  
  600.   if I!.__CallUserProc( 0, 'SysTextScreenSize' ) = 1 then
  601.     if symbol( 'I!.__UserProcRC' ) = 'VAR' then
  602.       parse var I!.__UserProcRC prog.__ScreenRows prog.__ScreenCols
  603.  
  604. RETURN ''
  605.  
  606. /* ------------------------------------------------------------------ */
  607. /*-function: init the variables for CID programs (only if the value   */
  608. /*           of the variable global.__NeedCID is 1)                   */
  609. /*                                                                    */
  610. /*-call:     I!.__InitCIDVars                                         */
  611. /*                                                                    */
  612. /*-returns:  ''                                                       */
  613. /*                                                                    */
  614. /*-Note:     DO NOT ADD ANY CODE TO THIS ROUTINE!                     */
  615. /*           Returncodes as defined by LCU 2.0                        */
  616. /*                                                                    */
  617. I!.__InitCIDVars: PROCEDURE expose (exposeList) exposeList CIDRC.
  618.  
  619.   if global.__NeedCID = 1 then
  620.   do
  621.                         /* define return codes for CID programs       */
  622.     CIDRC.__successful_program_termination  = C2D('0000'x, 2);
  623.     CIDRC.__successful_log_warning_message  = C2D('0004'x, 2);
  624.     CIDRC.__successful_log_error_Message    = C2D('0008'x, 2);
  625.     CIDRC.__successful_log_severe_error     = C2D('0012'x, 2);
  626.  
  627.     CIDRC.__data_resource_not_found         = C2D('0800'x, 2);
  628.     CIDRC.__data_resource_already_in_use    = C2D('0804'x, 2);
  629.     CIDRC.__data_resource_Noauthorization   = C2D('0808'x, 2);
  630.     CIDRC.__data_path_not_found             = C2D('0812'x, 2);
  631.     CIDRC.__product_not_configured          = C2D('0816'x, 2);
  632.  
  633.     CIDRC.__storage_medium_exception        = C2D('1200'x, 2);
  634.     CIDRC.__device_Not_Ready                = C2D('1204'x, 2);
  635.     CIDRC.__not_enough_diskspace            = C2D('1208'x, 2);
  636.  
  637.     CIDRC.__incorrect_program_invocation    = C2D('1600'x, 2);
  638.     CIDRC.__unexpected_condition            = C2D('1604'x, 2);
  639.  
  640.     CIDRC.__successfull_reboot              = C2D('FE00'x, 2);
  641.     CIDRC.__successfull_reboot_with_warning = C2D('FE04'x, 2);
  642.     CIDRC.__successfull_reboot_with_errmsg  = C2D('FE08'x, 2);
  643.     CIDRC.__successfull_reboot_with_server_errMsg = C2D('FE12'x, 2);
  644.  
  645.  
  646.                         /* xx = next state of the program             */
  647. /*    CIDRC.__successfull_reboot_with_callback = C2D('FFxx'x, 2);     */
  648.  
  649.                         /* define exit code values                    */
  650.     global.__ErrorExitCode = CIDRC.__unexpected_condition
  651.        global.__OKExitCode = CIDRC.__successful_program_termination
  652.  
  653.                         /* add the stem CIDRC. to the exposeList      */
  654.     exposeList = exposeList || ' CIDRC. '
  655.   end /* if global.__NeedCID = 1 then */
  656.  
  657. RETURN ''
  658.  
  659. /* ------------------------------------------------------------------ */
  660. /*-function: init program vars                                        */
  661. /*                                                                    */
  662. /*-call:     I!.__InitVars                                            */
  663. /*                                                                    */
  664. /*-returns:  ''                                                       */
  665. /*                                                                    */
  666. /*-Note:     DO NOT ADD ANY CODE TO THIS ROUTINE!                     */
  667. /*                                                                    */
  668. I!.__InitVars:
  669.  
  670.                         /* define exit code values                    */
  671.   global.__ErrorExitCode = 255
  672.      global.__OKExitCode = 0
  673.  
  674.                         /* define the stem prog.                      */
  675.   call I!.__InitProgStem
  676.  
  677.                         /* define the color variables                 */
  678.   call I!.__InitColorVars
  679.  
  680.                         /* define the variables for CID programs      */
  681.   call I!.__InitCIDVars
  682.  
  683.                         /* check some environment variables           */
  684.   call I!.__CheckEnvVars
  685.  
  686.                         /* check if there is a logfile parameter      */
  687.   call I!.__SetLogVars
  688.  
  689.                         /* init the program exit code                 */
  690.   prog.__ExitCode = global.__OKExitCode
  691.  
  692. RETURN ''
  693.  
  694. /***        End of Part 2 of the source code of TEMPLATE.CMD        ***/
  695.  
  696. /***       Start of Part 3 of the source code of TEMPLATE.CMD       ***/
  697.  
  698. /* ------------------------------------------------------------------ */
  699. /*-function:  load a dll                                              */
  700. /*                                                                    */
  701. /*-call:                                                              */
  702. /*   thisRC = LoadDll( registerFunction, dllName, entryPoint,         */
  703. /*                     ,{deRegisterFunction},{checkFunction}          */
  704. /*                     ,{IgnoreRxFuncAddRC},{RegisterErrorRC}         */
  705. /*                     ,{errorAction}                                 */
  706. /*                                                                    */
  707. /*-where:                                                             */
  708. /*     registerFunction = name of the dll init function               */
  709. /*                        (e.g. "SysLoadFuncs")                       */
  710. /*              dllName = name of the dll                             */
  711. /*                        (e.g. "REXXUTIL")                           */
  712. /*           entryPoint = entryPoint for the dll init function        */
  713. /*                        (e.g. "SysLoadFuncs")                       */
  714. /*   deRegisterFunction = name of the dll exit function               */
  715. /*                        (e.g. "SysDropFuncs")                       */
  716. /*                        If this parameter is entered, the           */
  717. /*                        deRegisterFunction is automaticly called    */
  718. /*                        at program end if the loading of the dll    */
  719. /*                        was successfull.                            */
  720. /*        checkFunction = function which must be loaded if the dll is */
  721. /*                        loaded (def.: none -> always load the dll)  */
  722. /*                        Note:                                       */
  723. /*                        Do not use the registerFunction for this    */
  724. /*                        parameter! A good candidate for this        */
  725. /*                        parameter is the deRegisterFunction.        */
  726. /*    IgnoreRxFuncAddRC = 1: ignore the rc from rxFuncAdd             */
  727. /*                        0: do not ignore the rc from rxFuncAdd      */
  728. /*                        (def.: 0)                                   */
  729. /*       RegisterErroRC = returncode of the dll init function         */
  730. /*                        indicating a load error                     */
  731. /*                        (def. none, -> ignore the returncode of the */
  732. /*                         dll init function)                         */
  733. /*           actionCode = 1: abort program if loading failed          */
  734. /*                        0: do not abort program if loading failed   */
  735. /*                        (def.: 1)                                   */
  736. /*                                                                    */
  737. /*-returns:                                                           */
  738. /*   0 - loading failed                                               */
  739. /*   1 - dll loaded                                                   */
  740. /*   2 - dll already loaded                                           */
  741. /*                                                                    */
  742. /*-Note:                                                              */
  743. /*   See the routine MAIN for some examples for using LoadDLL.        */
  744. /*   LoadDLL can only handle dlls with an init function to register   */
  745. /*   the further routines in the dll (like the function SysLoadFuncs  */
  746. /*   in the dll REXXUTIL).                                            */
  747. /*                                                                    */
  748. LoadDll:  PROCEDURE expose (exposeList)
  749.   parse arg registerFunction , ,
  750.             dllName , ,
  751.             entryPoint , ,
  752.             deRegisterFunction , ,
  753.             checkFunction , ,
  754.             ignoreRXFuncAddRC, ,
  755.             registerErrorRC, ,
  756.             errorAction
  757.  
  758.                         /* check the neccessary parameters            */
  759.   if entryPoint = '' | dllName = '' | registerFunction = '' then
  760.     call ShowError global.__ErrorExitCode, 'Invalid call to LOADDLL'
  761.  
  762.   if ignoreRXFuncAddRC = '' then
  763.     ignoreRXFuncAddRc = 0
  764.  
  765.   if errorAction = '' then
  766.     errorAction = 1
  767.  
  768.   I!.__LoadDLLRc = 0
  769.                         /* if the 'checkFunction' is missing, we      */
  770.                         /* assume that the dll is not loaded          */
  771.   if ( CheckFunction <> '' ) then
  772.   do
  773.                         /* check if the dll is loaded                 */
  774.     dllNotLoaded = rxFuncQuery( CheckFunction )
  775.   end /* if checkFunction <> '' then */
  776.   else
  777.     dllNotLoaded = 1
  778.  
  779.   if dllNotLoaded then
  780.   do
  781.                         /* load the dll and register the init         */
  782.                         /* function of the dll                        */
  783.     rxFuncAddRC = rxFuncAdd( RegisterFunction, dllName, entryPoint )
  784.  
  785.     if \ rxFuncAddRC | ignoreRxFuncAddRC then
  786.     do
  787.  
  788.       if I!.__CallUserProc( 0, RegisterFunction ) = 0 then
  789.         I!.__DllInitRC = 'ERROR'
  790.       else
  791.         I!.__DllInitRC = 0
  792.  
  793.       if ( registerErrorRC <> '' & I!.__DLLInitRC = registerErrorRC ) | ,
  794.          ( I!.__DllInitRC = 'ERROR' ) then
  795.       do
  796.         nop
  797.       end /* if ( registerErrorRC <> '' & ... */
  798.       else
  799.       do
  800.                         /* add the dll deregister function to the     */
  801.                         /* program exit routine list                  */
  802.         if DeRegisterFunction <> '' then
  803.           if \ rxFuncQuery( DeRegisterFunction ) then
  804.             prog.__ExitRoutines = prog.__ExitRoutines || ' ' || ,
  805.                                   DeRegisterFunction
  806.  
  807.         I!.__LoadDLLRc = 1
  808.       end /* else */
  809.     end /* if \ rxFuncAddRC | ignoreRxFuncAddRC then */
  810.   end /* if dllNotLoaded then */
  811.   else
  812.   do
  813.                         /* dll is already loaded                      */
  814.     I!.__LoadDLLRc = 2
  815.  
  816.   end /* else */
  817.  
  818.   if errorAction = 1 & I!.__LoadDLLRC = 0 then
  819.     call ShowError global.__ErrorExitCode, 'Can not load the dll "' || ,
  820.                                            dllName || '"'
  821.  
  822. RETURN I!.__LoadDLLRc
  823.  
  824. /* ------------------------------------------------------------------ */
  825. /*-function: show a string with word wrapping                         */
  826. /*                                                                    */
  827. /*-call:     showString Prefix, thisString                            */
  828. /*                                                                    */
  829. /*-where:                                                             */
  830. /*           Prefix = prefix for the first line (e.g. "*-*" or "#" to */
  831. /*                    use # leading blanks, # = 1 ... n )             */
  832. /*           thisString - string to print                             */
  833. /*                                                                    */
  834. /*-returns:  ''                                                       */
  835. /*                                                                    */
  836. ShowString: PROCEDURE EXPOSE (exposeList)
  837.   parse arg Prefix, StringToShow
  838.  
  839.   maxLineLength = prog.__ScreenCols-4
  840.  
  841.   if datatype( prefix, 'W' ) = 1 then
  842.     prefix = copies( ' ' , prefix )
  843.  
  844.   maxWordLength = maxLineLength - length( prefix )
  845.  
  846.   thisRC = 0
  847.   SE.thisString = ''
  848.  
  849.   do i = 1 to words( StringToShow)
  850.     printString = 0
  851.  
  852.     SE.thisString = SE.thisString || word( StringToShow, i ) || ' '
  853.  
  854.     if length( SE.thisString ) + ,
  855.        length( word( StringToShow, i+1 ) ) > maxLineLength then
  856.       printString = 1
  857.  
  858.     if printString = 1 | i = words( StringToShow ) then
  859.     do
  860.       if length( prefix || SE.ThisString ) > prog.__ScreenCols then
  861.       do
  862.         do until SE.thisString = ''
  863.           parse var SE.thisString SE.thisString1 =(maxWordLength) ,
  864.                                   SE.thisString
  865.           call log left( prefix || SE.thisString1, prog.__ScreenCols )
  866.           prefix = copies( ' ', length( prefix ) )
  867.         end /* do until SE.thisString = '' */
  868.       end /* if length( ... */
  869.       else
  870.         call Log left( prefix || SE.thisString, prog.__ScreenCols )
  871.  
  872.       SE.thisString = ''
  873.       prefix = copies( ' ', length( prefix ) )
  874.     end /* if length( ... */
  875.  
  876.   end /* do i = 1 to words( StringToShow */
  877.  
  878. RETURN ''
  879.  
  880. /* ------------------------------------------------------------------ */
  881. /*-function: show a warning message                                   */
  882. /*                                                                    */
  883. /*-call:     showWarning message                                      */
  884. /*                                                                    */
  885. /*-where:    warningMessage - warning Message                         */
  886. /*                                                                    */
  887. /*-returns:  ''                                                       */
  888. /*                                                                    */
  889. ShowWarning: PROCEDURE expose (exposeList)
  890.   parse arg warningMessage
  891.  
  892.   screen.__CurColor = screen.__ErrorColor
  893.  
  894.   warningMessage = warningMessage || '!'
  895.  
  896.   call Log ''
  897.   call I!.__LogSeparator
  898.   call ShowString ' Warning: ', warningMessage
  899.   call I!.__LogSeparator
  900.  
  901.   screen.__CurColor = screen.__NormalColor
  902.   call Log ''
  903.  
  904. RETURN ''
  905.  
  906. /* ------------------------------------------------------------------ */
  907. /*-function: show an error message and end the program                */
  908. /*                                                                    */
  909. /*-call:     ShowError exitCode, errorMessage                         */
  910. /*                                                                    */
  911. /*-where:    ExitCode - no of the error (= program exit code)         */
  912. /*           errorMessage - error Message                             */
  913. /*                                                                    */
  914. /*-returns:  nothing                                                  */
  915. /*                                                                    */
  916. /*-Note:     THIS ROUTINE WILL NOT COME BACK!!!                       */
  917. /*                                                                    */
  918. ShowError: PROCEDURE expose (exposeList)
  919.   parse arg prog.__ExitCode, prog.__errorMessage
  920.  
  921.   prog.__I!QuietMode = prog.__QuietMode
  922.                         /* turn quiet mode off                        */
  923.   prog.__QuietMode = ''
  924.  
  925.   screen.__CurColor = screen.__ErrorColor
  926.  
  927.   prog.__errorMessage = prog.__errorMessage || '!'
  928.  
  929.   call Log ''
  930.   call I!.__LogSeparator
  931.   call Log left(' Error ' || prog.__ExitCode  || ' detected! ' || ,
  932.       'The error message is: ',prog.__ScreenCols )
  933.   call ShowString 1, prog.__errorMessage
  934.  
  935.   call I!.__LogSeparator
  936.   call Log ''
  937.                         /* restore quiet mode status                  */
  938.   prog.__QuietMode = prog.__I!QuietMode
  939.  
  940.   if prog.__NoSound <> 1 then
  941.   do
  942.     call beep 537,300
  943.     call beep 237,300
  944.     call beep 537,300
  945.   end /* if prog.__NoSound <> 1 then */
  946.  
  947. SIGNAL I!.__ProgramEnd
  948.  
  949. RETURN
  950.  
  951. /* ------------------------------------------------------------------ */
  952. /*-function: log a debug message and clear the rest of the line       */
  953. /*                                                                    */
  954. /*-call:     logDebugMsg message                                      */
  955. /*                                                                    */
  956. /*-where:    message - message to show                                */
  957. /*                                                                    */
  958. /*-returns:  ''                                                       */
  959. /*                                                                    */
  960. /*-Note:     You do not need the 'call' keyword to use this routine.  */
  961. /*                                                                    */
  962. LogDebugMsg: PROCEDURE expose (exposeList)
  963.   if global.__verbose <> '' then
  964.   do
  965.     parse arg debugMessage
  966.     screen.__CurColor = screen.__DebugColor
  967.     call Log '+++' debugMessage
  968.     screen.__CurColor = screen.__NormalColor
  969.   end /* if global.__verbose <> '' then */
  970. RETURN ''
  971.  
  972. /* ------------------------------------------------------------------ */
  973. /*-function: write a separator line to the screen and to the logfile  */
  974. /*                                                                    */
  975. /*-call:     I!.__LogSeparator                                        */
  976. /*                                                                    */
  977. /*-returns:  ''                                                       */
  978. /*                                                                    */
  979. I!.__LogSeparator: PROCEDURE expose (exposeList)
  980.   call Log ' ' || left('-', prog.__ScreenCols-2, '-' ) || ' '
  981. RETURN
  982.  
  983. /* ------------------------------------------------------------------ */
  984. /*-function: log a message and clear the rest of the line             */
  985. /*                                                                    */
  986. /*-call:     log message                                              */
  987. /*                                                                    */
  988. /*-where:    message - message to show                                */
  989. /*                                                                    */
  990. /*-returns:  ''                                                       */
  991. /*                                                                    */
  992. /*-Note:     You do not need the 'call' keyword to use this routine.  */
  993. /*                                                                    */
  994. Log: PROCEDURE expose (exposeList)
  995.   parse arg message
  996.  
  997.   logMessage = message
  998.   do i = 1 to words( prog.__LogExcludeWords )
  999.     curWord = word( prog.__LogExcludeWords, i )
  1000.     curLength = length( curWord )
  1001.     do until j = 0
  1002.       j = Pos( curWord, logMessage )
  1003.       if j <> 0 then
  1004.         logMessage = delstr( logMessage, j, curLength )
  1005.     end /* do until j = 0 */
  1006.   end /* do i = 1 to words( prog.__LogExcludeWords ) */
  1007.  
  1008.   if prog.__QuietMode = '' then
  1009.   do
  1010.     if length( logMessage) = prog.__ScreenCols  then
  1011.       call charout prog.__STDOUT, screen.__CurColor || ,
  1012.                                   message || screen.__AttrOff
  1013.     else
  1014.       call lineOut prog.__STDOUT, screen.__CurColor || ,
  1015.                                   message || screen.__AttrOff ||,
  1016.                                   screen.__DelEOL
  1017.   end /* if prog.__Quietmode = '' then */
  1018.  
  1019.   if symbol( 'prog.__LogFile' ) = 'VAR' then                 /* v2.52 */
  1020.     if prog.__LogFile <> '' then
  1021.     do
  1022.       call lineout prog.__LogFile, logMessage
  1023.  
  1024.                                 /* close the logfile                  */
  1025.       rc = stream( prog.__LogFile, 'c', 'CLOSE')
  1026.     end /* if prog.__LogFile <> '' then */
  1027.  
  1028. RETURN ''
  1029.  
  1030. /* ------------------------------------------------------------------ */
  1031. /*-function: check if there is a patched version of this program      */
  1032. /*                                                                    */
  1033. /*-call:     I!.__CheckPatch                                          */
  1034. /*                                                                    */
  1035. /*-returns:  ''                                                       */
  1036. /*                                                                    */
  1037. /*-Note:     I!.__RealParameter must contain the parameters for       */
  1038. /*           this program.                                            */
  1039. /*           The variables prog.__Path and prog.__Name must be set!   */
  1040. /*           This procedure ends the program with an EXIT command!    */
  1041. /*                                                                    */
  1042. I!.__CheckPatch: PROCEDURE expose (exposeList)
  1043.  
  1044.                         /* get the drive with patch cmd files         */
  1045.   patchDrive = translate( value( 'patchDrive',, prog.__Env) )
  1046.  
  1047.   if patchDrive <> '' & patchDrive <> prog.__Drive then
  1048.   do
  1049.  
  1050.     patchedVersion = patchDrive || prog.__Path || prog.__Name
  1051.  
  1052.                         /* check if a patched program version exists  */
  1053.  
  1054.     if stream( patchedVersion, 'c', 'QUERY EXISTS') <> "" then
  1055.     do
  1056.       cmdLine= patchedVersion || " " || I!.__Realparameter
  1057.  
  1058.       screen.__CurColor = screen.__PatchColor
  1059.       call Log left( ' Calling patched version ' patchedVersion || ,
  1060.                ' ...', prog.__ScreenCols )
  1061.       screen.__CurColor = screen.__AttrOff
  1062.       call I!.__LogSeparator
  1063.  
  1064.       'cmd /c ' cmdLine
  1065.  
  1066.       screen.__CurColor = screen.__AttrOff
  1067.       call I!.__LogSeparator
  1068.       screen.__CurColor = screen.__PatchColor
  1069.       call Log left( ' ... the patched version endet with RC = ' || ,
  1070.            rc, prog.__ScreenCols )
  1071.  
  1072.       exit rc
  1073.     end /* if stream( ... */
  1074.   end /* if patchDrive <> '' */
  1075. RETURN ''
  1076.  
  1077. /* ------------------------------------------------------------------ */
  1078. /*-function: error handler for unexpected errors                      */
  1079. /*                                                                    */
  1080. /*-call:     DO NOT CALL THIS ROUTINE BY HAND!!!                      */
  1081. /*                                                                    */
  1082. /*-returns:  nothing                                                  */
  1083. /*                                                                    */
  1084. /*-input:    I!.__IncActive:                                          */
  1085. /*             if 1 the error occured while executing an include file */
  1086. /*             statement. In this case the following variables are    */
  1087. /*             also used (Note that this variables are automaticly    */
  1088. /*             set by the routine INCLUDE()):                         */
  1089. /*               I!.__IncLineNo                                       */
  1090. /*                 Line no. of the include file                       */
  1091. /*               I!.__IncFileName:                                    */
  1092. /*                 Name of the include file                           */
  1093. /*               I!.__IncCurLinePos:                                  */
  1094. /*                 Fileposition of the first char of the line causing */
  1095. /*                 the error                                          */
  1096. /*                                                                    */
  1097. /*-Note:     THIS FUNCTION ABORTS THE PROGRAM WITH A JUMP TO THE      */
  1098. /*           LABEL I!.__PROGRAMEND!!!                                 */
  1099. /*                                                                    */
  1100. I!.__ErrorAbort:
  1101.                         /* check if the error occured in the error    */
  1102.                         /* handler                                    */
  1103.   if I!.__errorLineNo = sigl then
  1104.   do
  1105.     call beep 637,300; call beep 437,300; call beep 637,300
  1106.  
  1107.     call charout 'STDERR:',,                                 /* v2.52 */
  1108.                                                             '0D0A'x  ,
  1109.        'Fatal Error: Error in the error handler detected!'  '0D0A'x  ,
  1110.                                                             '0D0A'x  ,
  1111.        'Linenumber:       ' || sigl ||                      '0D0A'x  ,
  1112.        'Errorname:        ' || condition('C')               '0D0A'x  ,
  1113.        'Errordescription: ' || condition('D')               '0D0A'x  ,
  1114.                                                             '0D0A'x  ,
  1115.        'The program exit routines were not called!'         '0D0A'x  ,
  1116.        'Check if "(EXPOSELIST)" is included in the ' || ,
  1117.        'expose lists of all procedures!'                    '0D0A'x
  1118.  
  1119.     call beep 637,300 ; call beep 437,300 ; call beep 637,300
  1120.     exit 255
  1121.  
  1122.   end /* if I!.__errorLineNo = sigl then */
  1123.  
  1124.                         /* get the number of the line causing the     */
  1125.                         /* error                                      */
  1126.   I!.__errorLineNo = sigl
  1127.  
  1128.                         /* get the name of this error                 */
  1129.   I!.__ErrorName = condition('C')
  1130.  
  1131.                         /* get further information for this error     */
  1132.                         /* if available                               */
  1133.   I!.__ErrorCondition = condition('D')
  1134.   if I!.__ErrorCondition <> '' then
  1135.     I!.__ErrorCondition = ' (Desc.: "' || I!.__ErrorCondition || '")'
  1136.  
  1137.   if datatype( prog.__ScreenCols, 'W' ) <> 1 then
  1138.     prog.__ScreenCols = 80
  1139.  
  1140.  
  1141.   if SYMBOL( 'prog.__Name' ) <> 'VAR' | value( 'prog.__Name' ) = '' then
  1142.     if I!.__errorLineNO < I!.__FirstUserCodeLine then
  1143.       I!.__pName = '**Runtimte**'
  1144.     else
  1145.       I!.__pName = '***???***'
  1146.   else
  1147.     i!.__pName = prog.__Name
  1148.  
  1149.                         /* reInstall the error handler                */
  1150.                                                              /* v2.52 */
  1151.   INTERPRET  'SIGNAL ON ' value(condition('C')) ' NAME I!.__ErrorAbort'
  1152.  
  1153.                         /* check, if we should ignore the error       */
  1154.   if value( 'sigl' ) = value( 'I!.__InterpretCMDLine' ) then
  1155.     SIGNAL I!.__CallUserProc2
  1156.  
  1157.   screen.__CurColor = screen.__ErrorColor
  1158.  
  1159.   prog.__I!QuietMode = prog.__QuietMode
  1160.                         /* turn quiet mode off                        */
  1161.   prog.__QuietMode = ''
  1162.  
  1163.                         /* init variables for printing the line       */
  1164.                         /* causing the error to the screen            */
  1165.   I!.__ThisSRCLine = ''
  1166.   I!.__ThisPrefix = ' *-* '
  1167.  
  1168.   call Log ''
  1169.   call I!.__LogSeparator
  1170.   call ShowString ' ' || I!.__pName || ' - ', I!.__ErrorName || ,
  1171.                   I!.__ErrorCondition || ' error detected!'
  1172.  
  1173.                         /* check, if the RC is meaningfull for this   */
  1174.                         /* error                                      */
  1175.   if pos( I!.__ErrorName, 'ERROR FAILURE SYNTAX' ) <> 0 then
  1176.   do
  1177.     if datatype(rc, "W") = 1 then
  1178.       if I!.__ErrorName = 'SYNTAX' then
  1179.          if rc > 0 & rc < 100 then
  1180.             call Log left( ' The error code is ' || rc || ,
  1181.                            ', the REXX error message is: ' || ,
  1182.                            errorText( rc ), ,
  1183.                            prog.__ScreenCols )
  1184.          else
  1185.            call log left( ' The error code ' || rc || ,
  1186.                           ', this error code is unknown.',,
  1187.                           prog.__ScreenCols )
  1188.       else
  1189.         call Log left( ' The RC is ' || rc || '.', prog.__ScreenCols )
  1190.   end /* if pos( ... */
  1191.  
  1192.   if value( 'I!.__IncActive' ) = 1 then
  1193.   do
  1194.                 /* error occured while interpreting an include file   */
  1195.     call ShowString 1, 'The error occured while executing the line ' || ,
  1196.                        I!.__IncLineNo || ' of the include file "' || ,
  1197.                        I!.__IncFileName || '".'
  1198.  
  1199.                         /* reset the file pointer of the include file */
  1200.                         /* to the start of the line causing the error */
  1201.     dummy = stream( I!.__IncFileName, 'c', 'SEEK =' || ,
  1202.                                                I!.__IncCurLinePos )
  1203.  
  1204.     I!.__SrcAvailable = stream( I!.__IncFileName, ,
  1205.                                    'c', 'QUERY EXIST' ) <> ''
  1206.   end
  1207.   else
  1208.   do
  1209.     call ShowString 1, 'The error occured in line ' ||,
  1210.                        I!.__errorLineNo || '.'
  1211.  
  1212.     I!.__thisLineNo = I!.__errorLineNo
  1213.  
  1214.                 /* error occured in this file                         */
  1215.                 /* check if the sourcecode is available               */
  1216.     SIGNAL ON SYNTAX   NAME I!.__NoSourceCode
  1217.     I!.__inMacroSpace = 1
  1218.     I!.__SrcAvailable = 0
  1219.     if sourceLine( I!.__errorLineNo ) <> '' then
  1220.       I!.__SrcAvailable = 1
  1221.  
  1222.     SIGNAL ON SYNTAX NAME I!.__ErrorAbort
  1223.     I!.__inMacroSpace = 0
  1224.  
  1225.   end /* else */
  1226.  
  1227.                         /* print the statement causing the error to   */
  1228.                         /* the screen                                 */
  1229.   if I!.__SrcAvailable = 1 then
  1230.   do
  1231.     call Log left( " The line reads: ", prog.__ScreenCols )
  1232.     I!.__InterpretVar = 0
  1233.  
  1234.                 /* read the line causing the error                    */
  1235.     call I!.__GetSourceLine
  1236.  
  1237.     I!.__FirstToken = strip(word( I!.__ThisSRCLine,1))
  1238.     if translate( I!.__FirstToken ) = 'INTERPRET' then
  1239.     do
  1240.       parse var I!.__ThisSRCLine (I!.__FirstToken) ,
  1241.                 I!.__interpretValue
  1242.       I!.__InterpretVar = 1
  1243.     end /* if I!.__thisLineNo = I!.__errorLineNo */
  1244.  
  1245.                         /* handle multi line statements               */
  1246.     do forever
  1247.       call ShowString I!.__ThisPrefix, I!.__ThisSRCLine
  1248.  
  1249.       if right( strip( I!.__ThisSRCLine),1 ) <> ',' then
  1250.         leave
  1251.  
  1252.       I!.__ThisPrefix = 5
  1253.  
  1254.       call I!.__GetSourceLine
  1255.  
  1256.     end /* do forever */
  1257.  
  1258.     if I!.__InterpretVar = 1 then
  1259.     do
  1260.       I!.__interpretValue = strip( word(I!.__interpretValue,1) )
  1261.  
  1262.       if symbol( I!.__interpretValue ) = 'VAR' then
  1263.       do
  1264.         call Log left( '', prog.__ScreenCols )
  1265.         call Log left( ' The value of "' || I!.__interpretValue || ,
  1266.                        '" is:', prog.__ScreenCols )
  1267.         call ShowString ' >V> ', value( I!.__interpretValue )
  1268.       end /* if symbol( I!.__interpretValue ) = 'VAR' then */
  1269.  
  1270.     end /* if I!.__InterpretVar = 1 */
  1271.  
  1272.   end /* if I!.__SrcAvailable = 1 then do */
  1273.   else
  1274.     call Log left( ' The sourcecode for this line is not available',,
  1275.                    prog.__ScreenCols )
  1276.  
  1277. I!.__NoSourceCode:
  1278.   SIGNAL ON SYNTAX NAME I!.__ErrorAbort
  1279.  
  1280.   if I!.__inMacroSpace = 1 then
  1281.   do
  1282.     parse source . . I!.__thisProgName
  1283.  
  1284.     if fileSpec( 'drive', I!.__thisProgName ) = '' then
  1285.       call ShowString 1, ' The sourcecode for this line is not' || ,
  1286.                          ' available because the program is in' || ,
  1287.                          ' the macro space.'
  1288.     else
  1289.       call ShowString 1, ' The sourcecode for this line is not' || ,
  1290.                          ' available because the program is unreadable.'
  1291.  
  1292.   end /* if I!.__inMacroSpace = 1 then */
  1293.  
  1294.   call I!.__LogSeparator
  1295.   call Log ''
  1296.  
  1297.   prog.__ExitCode = global.__ErrorExitCode
  1298.  
  1299.   if prog.__NoSound <> 1 then
  1300.   do
  1301.     call beep 137,300;  call beep 337,300;  call beep 137,300
  1302.   end /* if prog.__NoSound <> 1 then */
  1303.  
  1304.   if global.__verbose = 'DEBUG' then
  1305.   do
  1306.                         /* enter interactive debug mode               */
  1307.     trace ?a
  1308.     nop
  1309.   end /* if global.__verbose = 'DEBUG' then */
  1310.  
  1311.                         /* restore quiet mode status                  */
  1312.   prog.__QuietMode = prog.__I!QuietMode
  1313.  
  1314. SIGNAL I!.__programEnd
  1315.  
  1316. /* ------------------------------------------------------------------ */
  1317. /*-function: get the sourceline causing an error (subroutine of       */
  1318. /*           I!.__ErrorAbort)                                         */
  1319. /*                                                                    */
  1320. /*-call:     DO NOT CALL THIS IN YOUR CODE!!!                         */
  1321. /*                                                                    */
  1322. /*-returns:  ''                                                       */
  1323. /*                                                                    */
  1324. /*-Note:     -                                                        */
  1325. /*                                                                    */
  1326. I!.__GetSourceLine:
  1327.   if I!.__IncActive = 1 then
  1328.     I!.__ThisSRCLine = lineIn( I!.__IncFileName )
  1329.   else
  1330.   do
  1331.     I!.__ThisSRCLine = sourceLine( I!.__ThisLineNo )
  1332.     I!.__ThisLineNo = I!.__ThisLineNo + 1
  1333.   end /* else */
  1334. RETURN ''
  1335.  
  1336. /* ------------------------------------------------------------------ */
  1337. /*-function: error handler for user breaks                            */
  1338. /*                                                                    */
  1339. /*-call:     DO NOT CALL THIS ROUTINE BY HAND!!!                      */
  1340. /*                                                                    */
  1341. /*-returns:  nothing                                                  */
  1342. /*                                                                    */
  1343. /*-Note:     THIS FUNCTION ABORTS THE PROGRAM WITH A JUMP TO THE      */
  1344. /*           LABEL I!.__PROGRAMEND IF prog.__UserAbort IS NOT 0!!!    */
  1345. /*                                                                    */
  1346. /*           In exit routines you may test if the variable            */
  1347. /*           prog.__ExitCode is 254 to check if the program           */
  1348. /*           was aborted by the user.                                 */
  1349. /*                                                                    */
  1350. I!.__UserAbort:
  1351.                         /* reinstall the error handler                */
  1352.  
  1353.   CALL ON HALT        NAME I!.__UserAbort
  1354.  
  1355.                         /* check if user aborts are allowed           */
  1356.   if prog.__UserAbort = 0 then
  1357.     RETURN              /* CTRL-BREAK not allowed                     */
  1358.  
  1359.   prog.__I!QuietMode = prog.__QuietMode
  1360.  
  1361.                         /* turn quiet mode off                        */
  1362.   prog.__QuietMode = ''
  1363.  
  1364.   call Log ''
  1365.  
  1366.   screen.__CurColor = screen.__ErrorColor
  1367.   call I!.__LogSeparator
  1368.   call Log left( ' Program aborted by the user', prog.__ScreenCols )
  1369.   call I!.__LogSeparator
  1370.   screen.__CurColor = screen.__NormalColor
  1371.  
  1372.   prog.__ExitCode = 254
  1373.  
  1374.                         /* restore quiet mode status                  */
  1375.   prog.__QuietMode = prog.__I!QuietMode
  1376.  
  1377. SIGNAL I!.__ProgramEnd
  1378.  
  1379. /* ------------------------------------------------------------------ */
  1380. /*-function: get the no. of the first line with the user code         */
  1381. /*                                                                    */
  1382. /*-call:     DO NOT CALL THIS ROUTINE BY HAND!!!                      */
  1383. /*                                                                    */
  1384. /*-returns:  nothing                                                  */
  1385. /*                                                                    */
  1386. /*                                                                    */
  1387. I!.__GetUserCode:
  1388. /*** DO NOT CHANGE, ADD OR DELETE ONE OF THE FOLLOWING FOUR LINES!! ***/
  1389.   SIGNAL I!.__GetUserCode1
  1390. I!.__GetUserCode1:
  1391.   I!.__FirstUserCodeLine = sigl + 4
  1392. /*** DO NOT CHANGE, ADD OR DELETE ONE OF THE PRECEEDING FOUR LINES! ***/
  1393. RETURN
  1394.  
  1395. /********************** End of Runtime Routines ***********************/
  1396. /**********************************************************************/
  1397.  
  1398. /***        End of Part 3 of the source code of TEMPLATE.CMD        ***/
  1399.  
  1400.  
  1401. /***       Start of Part 4 of the source code of TEMPLATE.CMD       ***/
  1402.  
  1403. /* ------------------------------------------------------------------ */
  1404. /*-function: main procedure of the program                            */
  1405. /*                                                                    */
  1406. /*-call:     called by the runtime system with:                       */
  1407. /*           => call main parameter_of_the_program <=                 */
  1408. /*                                                                    */
  1409. /*-returns:  nothing                                                  */
  1410. /*                                                                    */
  1411. Main: PROCEDURE expose (exposeList)
  1412.  
  1413. /* ----------------------------- */
  1414.                         /* turn some error checking off               */
  1415.   SIGNAL OFF ERROR
  1416.  
  1417. /* ----------------------------- */
  1418.                         /* strings which should not be written in the */
  1419.                         /* log file                                   */
  1420.   prog.__LogExcludeWords = screen.__fgYellow screen.__highlight screen.__AttrOff
  1421.  
  1422.                         /* get the parameter of the program           */
  1423.   parse arg sourceFile TargetDir .
  1424.  
  1425.                         /* check the parameter                        */
  1426.   if sourceFile = '' then
  1427.     call ShowError global.__ErrorExitCode ,,
  1428.                    'Parameter "sourceFile" missing'
  1429.  
  1430.   if pos( '*', sourceFile ) + pos( '?', sourceFile ) <> 0 then
  1431.     call ShowError global.__ErrorExitCode ,,
  1432.                    'You can not use joker chars in the sourcefile parameter'
  1433.  
  1434.   if stream( sourceFile, 'c', 'QUERY EXIST' ) = '' then
  1435.     call ShowError global.__ErrorExitCode ,,
  1436.                    'The sourcefile "' || sourceFile || '" does not exist'
  1437.   else
  1438.     sourceFile = stream( sourceFile, 'c', 'QUERY EXIST' )
  1439.  
  1440.   extPos = pos( '.CMD', translate( sourceFile ) )
  1441.   if extPos = 0 then
  1442.     call ShowError global.__ErrorExitCode ,,
  1443.          'MAKESRC can only convert .CMD files'
  1444.  
  1445.   if targetDir = '' then
  1446.     targetDir = directory()
  1447.  
  1448.   if right( targetDir, 1 ) = '\' then
  1449.     targetDir = dbrright( targetDir,1 )
  1450.  
  1451.   if directory( targetDir ) = '' then
  1452.     call ShowError global.__ErrorExitCode ,,
  1453.          'The target directory "' || targetDir || '" does not exist'
  1454.   else
  1455.     targetDir = directory()
  1456.  
  1457.   targetFile = targetDir || '\' || fileSpec( "name" ,,
  1458.                                    substr( sourceFile,1,extPos ) || 'SRC' )
  1459.  
  1460.   if translate( targetFile ) = translate( sourceFile ) then
  1461.     call ShowError global.__ErrorExitCode ,,
  1462.                    'The target file can not be equal to the source file'
  1463.  
  1464.   call directory prog.__curDir
  1465.  
  1466.   call log ' Extracting the source code of the file '
  1467.   call log '  ' || AddColor1( '"', sourceFile )
  1468.   call log ' to the file '
  1469.   call log '  ' || AddColor1( '"', targetFile )
  1470.  
  1471.                                 /* read the source file               */
  1472.   call stream sourceFile, 'c', 'OPEN'
  1473.   i0 = chars( sourceFile )
  1474.   tempFile = charIn( sourceFile, 1, i0 )
  1475.   call stream sourceFile, 'c', 'CLOSE'
  1476.  
  1477.   targetCreated = 0
  1478.   if i0 <> 0 then
  1479.   do
  1480.     i1 = pos( 'End ' || 'of' || ' Part 1', tempFile )
  1481.     if i1 <> 0 then
  1482.     do
  1483.       i1 = pos( '***' || '/', tempFile, i1 ) +5
  1484.  
  1485.       i2 = pos( 'End ' || 'of' || ' Part 3', tempFile )
  1486.       if i2 <> 0 then
  1487.       do
  1488.         i2 = pos( '***' || '/', tempFile, i2 ) +6
  1489.  
  1490.         if i2 <> 0 & i1 <> 0 then
  1491.         do
  1492.                                 /* delete the old file if it exists   */
  1493.           if stream( targetFile, 'c', 'QUERY EXIST' ) <> '' then
  1494.           do
  1495.             'attrib -r ' targetFile prog.__LogAll
  1496.             'del ' targetFile prog.__LogAll
  1497.             if rc <> 0 then
  1498.               call ShowError global.__ErrorExitCode ,,
  1499.                    'OS Error ' || rc || ' deleting the old target file "' || ,
  1500.                    targetfile || '"'
  1501.           end /* if stream( targetFile ... */
  1502.  
  1503.                         /* write the first part in the targetfile     */
  1504.           call charOut targetFile, substr( tempFile, 1, i1 )
  1505.  
  1506.                     /* the second part of the source file is the      */
  1507.                     /* runtime system not needed in the targetfile    */
  1508.  
  1509.                         /* write the third part in the targetfile     */
  1510.           call CharOut targetFile, substr( tempFile, i2 )
  1511.  
  1512.           call stream targetFile, 'c', 'CLOSE'
  1513.  
  1514.           targetCreated = 1
  1515.         end /* if i1 <> 0 & i2 <> 0 then */
  1516.       end /* if i2 <> 0 then */
  1517.     end /* if i1 <> 0 then */
  1518.   end /* if i0 <> 0 then */
  1519.  
  1520.   if targetCreated <> 1 then
  1521.     call ShowError global.__ErrorExitCode ,,
  1522.          'Error: The format of the sourcefile is invalid'
  1523.  
  1524.   prog.__ExitCode = global.__OKExitCode
  1525.  
  1526. /* ------------------------------ */
  1527.  
  1528. RETURN
  1529.  
  1530. /* ------------------------------------------------------------------ */
  1531.  
  1532. /*** INSERT FURTHER SUBROUTINES HERE ***/
  1533.  
  1534.  
  1535. /* ------------------------------------------------------------------ */
  1536. /* Function: add quote chars and color codes to a string              */
  1537. /*                                                                    */
  1538. /* call:     AddColor1( quoteChar ,myString )                         */
  1539. /*                                                                    */
  1540. /* where:    quoteChar - leading and trailing character for the       */
  1541. /*                       converted string (may be ommited)            */
  1542. /*           myString - string to convert                             */
  1543. /*                                                                    */
  1544. /* returns:  converted string                                         */
  1545. /*                                                                    */
  1546. AddColor1: PROCEDURE expose (exposeList)
  1547.   parse arg quoteChar, myString
  1548.  
  1549. return quoteChar || screen.__fgYellow || screen.__highlight || ,
  1550.        myString || ,
  1551.        screen.__AttrOff || quoteChar
  1552.  
  1553. /* ------------------------------------------------------------------ */
  1554. /*-function: Show the invocation syntax                               */
  1555. /*                                                                    */
  1556. /*-call:     called by the runtime system with                        */
  1557. /*           => call ShowUsage <=                                     */
  1558. /*                                                                    */
  1559. /*-where:    -                                                        */
  1560. /*                                                                    */
  1561. /*-returns:  ''                                                       */
  1562. /*                                                                    */
  1563. ShowUsage:
  1564.   call log 'Usage: MAKESRC {sourceFile} {targetDir}'
  1565. RETURN ''
  1566.  
  1567. /***        End of Part 4 of the source code of TEMPLATE.CMD        ***/
  1568.  
  1569. /**********************************************************************/   
  1570.  
  1571.  
  1572.