home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power GUI Programming with VisualAge C++
/
powergui.iso
/
powergui
/
shipapp
/
genprags
/
genprags.cmd
next >
Wrap
OS/2 REXX Batch file
|
1996-10-29
|
10KB
|
314 lines
/*-----------------------------------------------------------------------
genprags.lx - The primary purpose of this macro is to
generate the alloc_text pragmas for initialization,
termination, and static functions. If you have a command line
REXX interpreter available, you can copy this file to genprags.cmd
and run it from the command line. If this option is available it
is recommended since this program can take a while and will lock
up the edit session while it is running as a macro.
The macro functions by generating and parsing the
assembler code (-Fa) for all specified files. Static
functions are identified because they have a PROC
statement with no cooresponding PUBLIC statement.
The static functions identified in this manner are
searched for various tokens to determine the segment
they should be placed in and the appropriate
alloc_text pragmas generated.
Requires as inout:
wildCardFileName - files to process of the form '*.cpp'
Generates as output:
initprag.h
Copyright (C) 1994, Law, Leong, Love, Olson, Tsuji.
Copyright (c) 1997 John Wiley & Sons, Inc.
-----------------------------------------------------------------------*/
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
/* set up to run as either a macro or a command file */
parse upper source osname . me
me = strip(me)
lastDot = lastPos('.', me)
if substr(me, lastDot) = ".LX" then do
isMacro = 1
end
else do
isMacro = 0
end
if isMacro = 1 then do
/* insure that message and messageline are on */
'extract messageLine into messageLineSetting'
'extract messages into messagesSetting'
'set messages on'
'set messageLine on'
end
/*
Read and parse arguments
*/
PARSE UPPER ARG wildCardFileName '(' optionsUpper
kDebug = 0 /* set to 1 for debug info */
if pos("DEBUG", optionsUpper) > 0 then kDebug = 1
wildCardFileName = strip(wildCardFileName)
if wildCardFileName = "" then
wildCardFileName = "*.CPP"
/*
Initialize constants
*/
publicString = "public"
procString = "proc"
extrnString = "extrn"
kStaticWord = "static"
rootDirectory = directory()
assemblerFile = rootDirectory"\genprag$.asm"
objectFile = rootDirectory"\genprag$.obj"
OutFile = rootDirectory"\genprag$.out"
pragmaFile = rootDirectory"\genprag$.h"
filteredPragmaFile = rootDirectory"\initprag.h"
InitSegment = "InitSegment"
TermSegment = "TermSegment"
StaticSegment = "StaticSegment"
/*
check for file already in ring
*/
if isMacro = 1 then do
'EXTRACT DOCLIST'
if doclist \= '' then
'EXTRACT DOCNUM INTO SAVEDOCNUM'
else
savedocnum = 0
do while doclist \= ''
parse var doclist docnum doclist
'GODOC DOCNUM 'docnum
if rc <= 1 then do
'EXTRACT NAME into currentDocName'
if translate(currentDocName) = translate(filteredPragmaFile) then
'qquit'
end
end
if savedocnum \= 0 then
'GODOC DOCNUM 'savedocnum
end
if stream(pragmaFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'pragmaFile
/*
Write a prolog to the output file
*/
rc = lineOut(pragmaFile, "// Generated by "me )
rc = lineOut(pragmaFile, "// Arguments were "wildCardFileName )
rc = lineOut(pragmaFile, " " )
/*
Collect a list of the files to process
*/
cppFiles. = 0
if kDebug = 1 then
call sayErr 'wildCardFileName='wildCardFileName
rc=SysFileTree(wildCardFileName,'cppFiles','FO','*****')
/*
Process each CPP file
*/
do fileNumber=1 TO cppFiles.0
call refreshDisplay
call sayErr "Processing file "fileNumber" of "cppFiles.0" ("cppFiles.fileNumber")"
/* Erase the assembler file and create the next one */
if stream(assemblerFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'assemblerFile
iccOptions = "-c -Ft- -O+ -W2 -Q+ -Gm+ -Gd+"
if 0 \= osCmd( '@ICC' iccOptions '-Fa'assemblerFile '-Fo'objectFile cppFiles.fileNumber' > 'outFile ) then do
call sayErr "ICC failed"
if isMacro = 1 then
'lx 'outFile
else
call osCmd 'type 'outFile
exit 1
end
/*
Build a table of public symbols from the assembler file.
*/
filePublics. = 0
call SysFileSearch publicString, assemblerFile, 'filePublics', 'C'
if kDebug = 1 then do
call sayErr "FilePublics.0 = "filePublics.0
call refreshDisplay
end
publicList. = 0
do j=1 to filePublics.0
filePublics.j = translate(filePublics.j, ' ', '09'x) /* remove tabs */
parse var filePublics.j publicKeyword function
if kDebug = 1 then
call sayErr "PUBLIC: " publicKeyword function
/* We want the statements of the form */
/* public __functionName */
/* but not segment declarations and such. */
if strip(publicKeyword) = publicString then do
publicList.0 = publicList.0 + 1
currentPublic = publicList.0
publicList.currentPublic = strip(function)
end /* if */
end /* do */
/*
Build a table of procedures ("proc", both public & static).
*/
fileProcs. = 0
call SysFileSearch procString, assemblerFile, 'fileProcs', 'C'
procList. = 0
do j=1 to fileProcs.0
fileProcs.j = translate(fileProcs.j, ' ', '09'x)
parse value fileProcs.j with fileProcs.j ";" comment
/* The following logic attempts to eliminate lines that get
included that are not "proc" statements (e.g. lines with
words like "process").
*/
if words(fileProcs.j) = 2 & word(fileProcs.j,2) = procString then do
procList.0 = procList.0 + 1
currentProc = procList.0
procList.currentProc = strip(word(fileProcs.j,1))
if kDebug = 1 then
call sayErr "PROC: "fileProcs.j
end /* if */
end /* do */
/*
Flag the functions in the procList as being PUBLIC or
STATIC (STATICS are in the procList but not the publicList).
*/
staticsFound = 0
do j=1 to procList.0
found = 0
do k=1 to publicList.0 while found = 0
if procList.j = publicList.k then do
found = 1
procList.j.scope = publicString
end
end /* do */
/* Not found in public list so must be a static */
if found = 0 then do
procList.j.scope = kStaticWord
staticsFound = 1
end /* if */
end /* do */
/*
Determine the alloc_text pragmas for functions meeting
one of the criteria.
*/
if staticsFound = 1 then do
/* Determine the File Name and write an #ifdef for it */
cppOffset = pos('.', cppFiles.fileNumber)
lastSlash = lastPos('\', cppFiles.fileNumber)
cppNameLength = cppOffset - lastSlash -1
cppFileName = substr(cppFiles.fileNumber, lastSlash+1, cppNameLength)
rc = lineOut(pragmaFile, "#ifdef _"||translate(cppFileName)||"_CPP_")
/* Now dump out the segment definitions for Statics */
do procNumber=1 to procList.0
if procList.procNumber.scope = kStaticWord then do
writePragma = 1
outBuffer = "#pragma alloc_text("
/* Do not write out Exception Functions because */
/* they are in EH_CODE already. */
if pos("__dftdt", procList.procNumber) > 0 | ,
pos("__dftbdt", procList.procNumber) > 0 then
writePragma = 0
if pos("__dftct", procList.procNumber) > 0 then
outBuffer = outbuffer||StaticSegment
/* Write out Initialization functions */
else if pos("__sinit", procList.procNumber) > 0 then
outBuffer = outbuffer||InitSegment
/* Write out termination functions */
else if pos("__sterm", procList.procNumber) > 0 then
outBuffer = outbuffer||TermSegment
else
outBuffer = outbuffer||StaticSegment
outBuffer = outBuffer||"," procList.procNumber||")"
if writePragma = 1 then
rc = lineOut(pragmaFile, outBuffer)
end
end /* do procNumber */
rc = lineOut(pragmaFile, "#endif")
rc = lineOut(pragmaFile, "")
end /* do staticsExist */
end /* do fileNumber */
rc = stream(pragmaFile, 'C', 'close')
/*
Use CPPFILT on the pragma file
*/
call oscmd '@CPPFILT /q' pragmaFile ' > ' filteredPragmaFile
/* cleanup temporary files */
if kDebug = 0 then do
if stream(assemblerFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'assemblerFile
if stream(objectFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'objectFile
if stream(outFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'OutFile
if stream(pragmaFile,'C','QUERY EXIST')<>'' then
call osCmd '@DEL 'pragmaFile
end
/* restore previous settings and view the results if a macro */
if isMacro = 1 then do
'set messageLine 'messageLineSetting
'set messages 'messagesSetting
'lx 'filteredPragmaFile
end
exit 0
/* Utility function to call a system function */
oscmd:
parse arg theCmd
if pos('@', theCmd) \= 1 | kDebug \= 0 then
call sayErr theCmd
if pos('@', theCmd) = 1 then
Address 'CMD' substr(theCmd, 2)
else
Address 'CMD' theCmd
return rc
/* Utility function to write error message */
sayErr:
procedure expose isMacro
parse arg theString
if isMacro = 1 then
'msg 'theString
else
say theString
call refreshDisplay
return
/* Utility function to update the display */
refreshDisplay:
procedure expose isMacro
if isMacro = 1 then
'sshow'
return