home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / makemsg.zip / makemsg.cmd
OS/2 REXX Batch file  |  2002-04-26  |  10KB  |  260 lines

  1. /* $Id: makemsg.cmd,v 1.2 2002/04/26 23:09:44 smilcke Exp $ */
  2.  
  3. /* SCCSID = src/dev/mme/tropez/makemsg.cmd, tropez, c.basedd 97/07/17 */
  4. /****************************************************************************
  5.  *                                                                          *
  6.  * Copyright (c) IBM Corporation 1994 - 1997.                               *
  7.  *                                                                          *
  8.  * The following IBM OS/2 source code is provided to you solely for the     *
  9.  * the purpose of assisting you in your development of OS/2 device drivers. *
  10.  * You may use this code in accordance with the IBM License Agreement       *
  11.  * provided in the IBM Device Driver Source Kit for OS/2.                   *
  12.  *                                                                          *
  13.  ****************************************************************************/
  14. /**@internal src/dev/mme/tropez/makemsg.cmd, tropez, c.basedd
  15.  *  Converts the driver message file (eg "logmsg.in") to the following:
  16.  *      logmsg.hpp   - message number definitions
  17.  *      logmsg.cpp   - message text
  18.  *      logmsg.tsf   - input to the TRCUST utility,
  19.  *                     TRCUST generates a .TFF file, used to format
  20.  *                     the system trace formatter TRACEFMT.EXE.
  21.  * @version 1.5
  22.  * @context Ring-3 REXX application interpreter.
  23.  * @notes
  24.  *  Sample logmsg.in line:
  25.  *
  26.  *      trace num=1 symbol=MIDISTREAM_Dispatch_NoteOn text="Dispatch: chan %x note %d On"
  27.  *
  28.  *  Sample .TSF output:
  29.  *
  30.  *      trace tp=@static, minor = 1 ,
  31.  *            desc = MIDISTREAM_Dispatch_NoteOn ,
  32.  *            fmt= "Dispatch: chan %w note %w On"
  33.  *
  34.  *  ### Need to use Procedures...  getting into trouble with
  35.  *  ### walking on local vbls.
  36.  * @history
  37.  */
  38.  
  39. /* Load up REXX extensions. */
  40. CALL RXFUNCADD 'sysloadfuncs','rexxutil','sysloadfuncs'
  41. call sysloadfuncs
  42.  
  43. Parse Arg inFile msgDataFile msgNumHdrFile
  44.  
  45. if (msgNumHdrFile='') Then msgNumHdrFile = 'logmsg.hpp'
  46. if (msgDataFile='') Then msgDataFile = 'logmsg.cpp'
  47. tsfFile = 'logmsg.tsf'
  48. rc = SysFileDelete( msgNumHdrFile );
  49. rc = SysFileDelete( msgDataFile );
  50. rc = SysFileDelete( tsfFile );
  51.  
  52. szMsgClassName.1      = 'ERROR'
  53. szMsgClassName.2      = 'STATUS'
  54. szMsgClassName.3      = 'TRACE'
  55. szMsgClassName.nMembers = 3
  56.  
  57. szMsgArray.1          = "PSZ apszErrorMessage[]" ;
  58. szMsgArray.2          = "PSZ apszStatusMessage[]" ;
  59. szMsgArray.3          = "PSZ apszTraceMessage[]" ;
  60. szMsgArray.4          = "USHORT ausTraceDataLen[]" ;
  61. szMsgArray.nMembers   = 4
  62.  
  63. inFile = Strip( inFile );
  64. If Lines( inFile ) = 0 Then Say "MAKEMSG:  Problem opening input file:" directory()"\"inFile
  65.  
  66. rc = WriteTopsOfFiles();
  67. Trace 'o'
  68. Do j = 1 to szMsgClassName.nMembers
  69.    rc = XlateMsgClass( j );
  70.    If rc <> 0 Then Return 1;
  71. End;
  72. Return 0
  73.  
  74. WriteTopsOfFiles:
  75.  
  76.    /*--- Top of the generated .hpp file ---*/
  77.    Do i = 1 to szMsgArray.nMembers
  78.       call lineout msgNumHdrFile , "extern" szMsgArray.i ";"
  79.    End;
  80.  
  81.    /*--- Top of the generated .cpp file ---*/
  82.    call lineout msgDataFile , '#ifndef OS2_INCLUDED'
  83.    call lineout msgDataFile , 'extern "C" {'
  84.    call lineout msgDataFile , '   #define INCL_NOPMAPI'
  85.    call lineout msgDataFile , '   #include <os2.h>'
  86.    call lineout msgDataFile , '}'
  87.    call lineout msgDataFile , '#endif'
  88.  
  89.    /*--- Top of generated .TSF file ---*/
  90.    call lineout tsfFile , 'MODNAME=bt8x8.sys'
  91.    call lineout tsfFile , 'MAJOR=255'
  92.  
  93.    Return 0;
  94.  
  95.  
  96. XlateMsgClass:      /* Function entry point. */
  97.    Arg msgClassNum
  98.    msgClass = szMsgClassName.msgClassNum
  99.  
  100.    msg.lastNum = 0;                     /* Initialize. */
  101.    lineNum = 0;                         /* Initialize. */
  102.    Linein( inFile, 1, 0 );              /* Reset to start of file. */
  103.    Do i=0 to 255                        /* Can't get stem vbl to work, must iterate. */
  104.       msg.defined.i = FALSE;            /* Initialize. */
  105.    End;
  106.  
  107.    /* 1. Collect up all the messages from the input file. */
  108.  
  109.    do while lines( inFile ) <> 0
  110.       lineText = linein( inFile );
  111.       lineNum = lineNum + 1
  112.       if Word( lineText, 1 ) = ";" then iterate;
  113.       if Word( lineText, 1 ) = "" then iterate;
  114.       parse value lineText with msg.type "num=" msg.num "symbol=" msg.sym "text=" msg.txt
  115.       msg.type = translate( strip( msg.type ) );
  116.       if (msg.type <> 'ERROR') & (msg.type <> 'TRACE') & (msg.type <> 'STATUS') then do
  117.             say "Line" lineNum || ": expecting <error, trace, status> keyword or comment, found:"
  118.             say "Line" lineNum || ":" lineText
  119.             return 1;
  120.       End;
  121.  
  122.       if msg.type <> msgClass then iterate;
  123.  
  124.       msg.num = strip( msg.num );
  125.       msg.sym = strip( msg.sym );
  126.       msg.txt = strip( msg.txt );
  127.       i = msg.num;
  128.       if datatype(i) <> 'NUM' then do
  129.          say "Line" lineNum || ": Expecting a numeric value for a 'num=', found:"
  130.          say "        " i
  131.          return 1
  132.       end
  133.       if words(msg.sym) <> 1 then do
  134.          say "Line" lineNum || ": Expecting a single token for 'symbol=', found :"
  135.          say "        " msg.sym
  136.          return 1
  137.       end
  138.       if msg.defined.i = 'TRUE' then do
  139.          say "Line" lineNum || ": redefining" msg.type "number" i
  140.          return 1;
  141.       end;
  142.       msg.i.txt = msg.txt
  143.       msg.i.sym = msg.sym
  144.       msg.defined.i = TRUE;
  145.       if i > msg.lastNum then msg.lastNum = i;
  146.  
  147.    end;
  148.  
  149.    /* 2.  Write out the .HPP and .CPP files. */
  150.  
  151.    call lineout msgDataFile , szMsgArray.msgClassNum "= {"
  152.    do i = 0 to msg.lastNum
  153.       /* If msg number 'i' is defined, then print it out. */
  154.       if msg.defined.i <> TRUE then do
  155.          call lineout msgDataFile , '   (PSZ) "",'
  156.       end
  157.       else do
  158.          call lineout msgNumHdrFile , "const int" msg.i.sym "=" i ";"
  159.          call lineout msgDataFile , "   (PSZ) " || msg.i.txt || ","
  160.          if msgClass = 'TRACE' then do;
  161.             call lineout tsfFile , 'trace tp=@static, minor=' || i
  162.             call lineout tsfFile , '      desc="' || msg.i.sym || '"'
  163.             cmdLine = msg.i.txt
  164.             call lineout tsfFile , '      fmt=' || xlateTSF()
  165.          end;
  166.       end;
  167.    end;
  168.    call lineout msgDataFile , "};  //" szMsgArray.msgClassNum
  169.    Return 0;
  170. /* end TranslateMsgClass */
  171.  
  172.  
  173. xlateTSF:       /* Function entry point. */
  174.    /* Translate a single formatting line from "ddprintf()" format to TSF format.
  175.       Entry:  formatting string in global "cmdLine".
  176.       Exit:   returns translated string
  177.     */
  178.    /* ### Parse argument into "rest" instead of command line. */
  179.  
  180.    /* Loop initialization. */
  181.    first = '';                     /* First part of tranlated string returned here. */
  182.    rest = cmdLine;                 /* Untranslated remainder in 'rest' */
  183.    szTSFLine = '';                 /* Result is built up here. */
  184.    szRC = 'Not 0';                 /* Return code. */
  185.    Do Until szRC = '0'
  186.       trace 'o'
  187.       szRC = Do1( rest );
  188.       trace 'o'
  189.       if szRC = 'E' then Do;
  190.          Say 'Error:  Parsing line:' cmdLine
  191.          Return 1
  192.       End;
  193.  
  194.       /* Good return from Do1().  Translated part of string in 'first',
  195.          untranslated part in 'rest'.  Concat the xlate'd phrase to what
  196.          we've already accumulated. */
  197.       szTSFLine = szTSFLine || first
  198.    End;
  199.  
  200.    Return szTSFLine ;
  201. End;
  202.  
  203. /*
  204. ;  Translates the first '%' formatting commmand encountered into .TSF format.
  205. ;  Returns results in globals vbls 'first' and 'rest', and returns a character
  206. ;  as a return code.
  207. ;
  208. ;On exit
  209. ;  'first' will contain the translated string, up to & including the first '%' phrase.
  210. ;  'rest' will contain the remainder of the formatting string that needs to be translated.
  211. ;  'rest' is empty string if nothing more remains to be translated.
  212. ;
  213. ;Returns string
  214. ;   'E'   when input string doesn't parse
  215. ;   '0'   when nothing translated
  216. ;   '1'   when translating a word (short) formatting parm
  217. ;   '2'   when translating a word (short) formatting parm
  218. ;   '4'   when translating a double (long) formatting parm
  219. ;   '8'   when translating a quad formatting parm
  220. */
  221. Do1:
  222.    /* ### need check here for arg terminated with '%' */
  223.    parse arg with 1 first '%' rest
  224.    if rest = '' then return '0';
  225.    /* say '<' || first '> <' || rest || '>' */
  226.  
  227.    /* Here, found a '%'.  'rest' starts with chars following '%'.
  228.       Start by eating any '%0' sequence - can't generate leading 0 format. */
  229.    if substr( rest, 1, 1) = '0' then rest = substr( rest, 2 );
  230.  
  231.    /* Is next char an upper or lower 'L' for 'long int' ?. */
  232.    if Verify( substr(rest, 1, 1), 'Ll' ) = 0 then do;
  233.       if Verify( substr(rest, 2, 1), 'dDxX' ) = 0 then do;
  234.          first = first || '%d'
  235.          rest = substr( rest, 3 );      /* strip off the format ctl chars. */
  236.          return '4'
  237.       end
  238.       else return 'E';
  239.    end;
  240.  
  241.    /* Have now handled leading '0', leading 'l' or 'L'.  Now check for
  242.       remaining cases. */
  243.    if Verify( substr(rest, 1, 1), 'dDxX' ) = 0 then do;
  244.       first = first || '%w'
  245.       rest = substr( rest, 2 );      /* strip off the format ctl chars. */
  246.       return '2'
  247.    end
  248.    else if Verify( substr(rest, 1, 1), 'bB' ) = 0 then do;
  249.       first = first || '%b'
  250.       rest = substr( rest, 2 );      /* strip off the format ctl chars. */
  251.       return '1'
  252.    end
  253.    else if Verify( substr(rest, 1, 1), 'qQ' ) = 0 then do;
  254.       first = first || '%q'
  255.       rest = substr( rest, 2 );      /* strip off the format ctl chars. */
  256.       return '8'
  257.    end
  258.    else return 'E';
  259.  
  260.