home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
makemsg.zip
/
makemsg.cmd
Wrap
OS/2 REXX Batch file
|
2002-04-26
|
10KB
|
260 lines
/* $Id: makemsg.cmd,v 1.2 2002/04/26 23:09:44 smilcke Exp $ */
/* SCCSID = src/dev/mme/tropez/makemsg.cmd, tropez, c.basedd 97/07/17 */
/****************************************************************************
* *
* Copyright (c) IBM Corporation 1994 - 1997. *
* *
* The following IBM OS/2 source code is provided to you solely for the *
* the purpose of assisting you in your development of OS/2 device drivers. *
* You may use this code in accordance with the IBM License Agreement *
* provided in the IBM Device Driver Source Kit for OS/2. *
* *
****************************************************************************/
/**@internal src/dev/mme/tropez/makemsg.cmd, tropez, c.basedd
* Converts the driver message file (eg "logmsg.in") to the following:
* logmsg.hpp - message number definitions
* logmsg.cpp - message text
* logmsg.tsf - input to the TRCUST utility,
* TRCUST generates a .TFF file, used to format
* the system trace formatter TRACEFMT.EXE.
* @version 1.5
* @context Ring-3 REXX application interpreter.
* @notes
* Sample logmsg.in line:
*
* trace num=1 symbol=MIDISTREAM_Dispatch_NoteOn text="Dispatch: chan %x note %d On"
*
* Sample .TSF output:
*
* trace tp=@static, minor = 1 ,
* desc = MIDISTREAM_Dispatch_NoteOn ,
* fmt= "Dispatch: chan %w note %w On"
*
* ### Need to use Procedures... getting into trouble with
* ### walking on local vbls.
* @history
*/
/* Load up REXX extensions. */
CALL RXFUNCADD 'sysloadfuncs','rexxutil','sysloadfuncs'
call sysloadfuncs
Parse Arg inFile msgDataFile msgNumHdrFile
if (msgNumHdrFile='') Then msgNumHdrFile = 'logmsg.hpp'
if (msgDataFile='') Then msgDataFile = 'logmsg.cpp'
tsfFile = 'logmsg.tsf'
rc = SysFileDelete( msgNumHdrFile );
rc = SysFileDelete( msgDataFile );
rc = SysFileDelete( tsfFile );
szMsgClassName.1 = 'ERROR'
szMsgClassName.2 = 'STATUS'
szMsgClassName.3 = 'TRACE'
szMsgClassName.nMembers = 3
szMsgArray.1 = "PSZ apszErrorMessage[]" ;
szMsgArray.2 = "PSZ apszStatusMessage[]" ;
szMsgArray.3 = "PSZ apszTraceMessage[]" ;
szMsgArray.4 = "USHORT ausTraceDataLen[]" ;
szMsgArray.nMembers = 4
inFile = Strip( inFile );
If Lines( inFile ) = 0 Then Say "MAKEMSG: Problem opening input file:" directory()"\"inFile
rc = WriteTopsOfFiles();
Trace 'o'
Do j = 1 to szMsgClassName.nMembers
rc = XlateMsgClass( j );
If rc <> 0 Then Return 1;
End;
Return 0
WriteTopsOfFiles:
/*--- Top of the generated .hpp file ---*/
Do i = 1 to szMsgArray.nMembers
call lineout msgNumHdrFile , "extern" szMsgArray.i ";"
End;
/*--- Top of the generated .cpp file ---*/
call lineout msgDataFile , '#ifndef OS2_INCLUDED'
call lineout msgDataFile , 'extern "C" {'
call lineout msgDataFile , ' #define INCL_NOPMAPI'
call lineout msgDataFile , ' #include <os2.h>'
call lineout msgDataFile , '}'
call lineout msgDataFile , '#endif'
/*--- Top of generated .TSF file ---*/
call lineout tsfFile , 'MODNAME=bt8x8.sys'
call lineout tsfFile , 'MAJOR=255'
Return 0;
XlateMsgClass: /* Function entry point. */
Arg msgClassNum
msgClass = szMsgClassName.msgClassNum
msg.lastNum = 0; /* Initialize. */
lineNum = 0; /* Initialize. */
Linein( inFile, 1, 0 ); /* Reset to start of file. */
Do i=0 to 255 /* Can't get stem vbl to work, must iterate. */
msg.defined.i = FALSE; /* Initialize. */
End;
/* 1. Collect up all the messages from the input file. */
do while lines( inFile ) <> 0
lineText = linein( inFile );
lineNum = lineNum + 1
if Word( lineText, 1 ) = ";" then iterate;
if Word( lineText, 1 ) = "" then iterate;
parse value lineText with msg.type "num=" msg.num "symbol=" msg.sym "text=" msg.txt
msg.type = translate( strip( msg.type ) );
if (msg.type <> 'ERROR') & (msg.type <> 'TRACE') & (msg.type <> 'STATUS') then do
say "Line" lineNum || ": expecting <error, trace, status> keyword or comment, found:"
say "Line" lineNum || ":" lineText
return 1;
End;
if msg.type <> msgClass then iterate;
msg.num = strip( msg.num );
msg.sym = strip( msg.sym );
msg.txt = strip( msg.txt );
i = msg.num;
if datatype(i) <> 'NUM' then do
say "Line" lineNum || ": Expecting a numeric value for a 'num=', found:"
say " " i
return 1
end
if words(msg.sym) <> 1 then do
say "Line" lineNum || ": Expecting a single token for 'symbol=', found :"
say " " msg.sym
return 1
end
if msg.defined.i = 'TRUE' then do
say "Line" lineNum || ": redefining" msg.type "number" i
return 1;
end;
msg.i.txt = msg.txt
msg.i.sym = msg.sym
msg.defined.i = TRUE;
if i > msg.lastNum then msg.lastNum = i;
end;
/* 2. Write out the .HPP and .CPP files. */
call lineout msgDataFile , szMsgArray.msgClassNum "= {"
do i = 0 to msg.lastNum
/* If msg number 'i' is defined, then print it out. */
if msg.defined.i <> TRUE then do
call lineout msgDataFile , ' (PSZ) "",'
end
else do
call lineout msgNumHdrFile , "const int" msg.i.sym "=" i ";"
call lineout msgDataFile , " (PSZ) " || msg.i.txt || ","
if msgClass = 'TRACE' then do;
call lineout tsfFile , 'trace tp=@static, minor=' || i
call lineout tsfFile , ' desc="' || msg.i.sym || '"'
cmdLine = msg.i.txt
call lineout tsfFile , ' fmt=' || xlateTSF()
end;
end;
end;
call lineout msgDataFile , "}; //" szMsgArray.msgClassNum
Return 0;
/* end TranslateMsgClass */
xlateTSF: /* Function entry point. */
/* Translate a single formatting line from "ddprintf()" format to TSF format.
Entry: formatting string in global "cmdLine".
Exit: returns translated string
*/
/* ### Parse argument into "rest" instead of command line. */
/* Loop initialization. */
first = ''; /* First part of tranlated string returned here. */
rest = cmdLine; /* Untranslated remainder in 'rest' */
szTSFLine = ''; /* Result is built up here. */
szRC = 'Not 0'; /* Return code. */
Do Until szRC = '0'
trace 'o'
szRC = Do1( rest );
trace 'o'
if szRC = 'E' then Do;
Say 'Error: Parsing line:' cmdLine
Return 1
End;
/* Good return from Do1(). Translated part of string in 'first',
untranslated part in 'rest'. Concat the xlate'd phrase to what
we've already accumulated. */
szTSFLine = szTSFLine || first
End;
Return szTSFLine ;
End;
/*
; Translates the first '%' formatting commmand encountered into .TSF format.
; Returns results in globals vbls 'first' and 'rest', and returns a character
; as a return code.
;
;On exit
; 'first' will contain the translated string, up to & including the first '%' phrase.
; 'rest' will contain the remainder of the formatting string that needs to be translated.
; 'rest' is empty string if nothing more remains to be translated.
;
;Returns string
; 'E' when input string doesn't parse
; '0' when nothing translated
; '1' when translating a word (short) formatting parm
; '2' when translating a word (short) formatting parm
; '4' when translating a double (long) formatting parm
; '8' when translating a quad formatting parm
*/
Do1:
/* ### need check here for arg terminated with '%' */
parse arg with 1 first '%' rest
if rest = '' then return '0';
/* say '<' || first '> <' || rest || '>' */
/* Here, found a '%'. 'rest' starts with chars following '%'.
Start by eating any '%0' sequence - can't generate leading 0 format. */
if substr( rest, 1, 1) = '0' then rest = substr( rest, 2 );
/* Is next char an upper or lower 'L' for 'long int' ?. */
if Verify( substr(rest, 1, 1), 'Ll' ) = 0 then do;
if Verify( substr(rest, 2, 1), 'dDxX' ) = 0 then do;
first = first || '%d'
rest = substr( rest, 3 ); /* strip off the format ctl chars. */
return '4'
end
else return 'E';
end;
/* Have now handled leading '0', leading 'l' or 'L'. Now check for
remaining cases. */
if Verify( substr(rest, 1, 1), 'dDxX' ) = 0 then do;
first = first || '%w'
rest = substr( rest, 2 ); /* strip off the format ctl chars. */
return '2'
end
else if Verify( substr(rest, 1, 1), 'bB' ) = 0 then do;
first = first || '%b'
rest = substr( rest, 2 ); /* strip off the format ctl chars. */
return '1'
end
else if Verify( substr(rest, 1, 1), 'qQ' ) = 0 then do;
first = first || '%q'
rest = substr( rest, 2 ); /* strip off the format ctl chars. */
return '8'
end
else return 'E';