wasm-demo/demo/ermis-f/python_m/cur/0200

1040 lines
28 KiB
Plaintext

From: garys at magna.com.au (Gary Stephenson)
Date: Tue, 06 Apr 1999 13:06:35 +1000
Subject: Xbase++ preprocessor implementation in Python
Message-ID: <37097A3A.F772205@magna.com.au>
Content-Length: 28569
X-UID: 200
Attached please find a Python implementation of the Xbase++
preprocessor. It
is not yet a totally perfect rendition, but it is pretty close. By
implication, it should also be a reasonable rendition of the Clipper
preprocessor (though I have not yet tested this).
Oh, and it is *dead slow*! - hundreds of times slower I think! This is
undoubtedly partly due to me being a Python newbie, and I would greatly
appreciate any tips on how I might speed it up a bit. Any tips on how
the code could be improved would be equally welcome, particularly any
Python idioms that I have obviously not yet groked. (Error handling for
example!!)
I could not figure out how to make either KJparsing or TRAP do what I
wanted,
and I haven't yet looked at John Aylcock's stuff (but I intend to!), so
the code is built from scratch around the re module. Any comments as to
the relative (de)merits of this approach are welcomed.
I would like eventually to make this available to the Clipper/Xbase++
community. But I want to present Python in the best possible light - so
I thought it best to first release it here in the hope that it might be
further refined first.
"Why write such a program?" I hear you ask! Several reasons :
- I needed a concrete project to help me get up to speed with Python.
- I want to translate some or all of my Clipper/Xbase++ source to
Python, and I'm hoping this will help (but I'm not quite sure how!).
- the Clipper/Xbase++ preprocessor had always been a bit of a mystery
to me, so I thought this might deepen my understanding of it a bit (it
has!).
- Ditto for regular expressions!
- I have taken the opportunity to make some "improvements". Some
patterns that do not successfully translate under Xbase++, but IMHO
should, do under PRGPP.
- There are some concerns in the Xbase++ community as to
incompatibilities between the Clipper and Xbase++ preprocessors.
Hopefully, this tool might serve to clarify and/or resolve such issues.
- Clipper and Xbase++ are only available on Window$ :-(
- I love programming, the open-source idea, Python and the
Clipper/Xbase++/VO
languages. I would like eventually to see an open-source implementation
of a
such a language. Nuff said.
many tias,
gary
-------------- next part --------------
"""
PRGPP.py - a Python re-implementation of the Xbase++ (Clipper) preprocessor
Released to the public domain 2-Apr-1999,
Provided as-is; use at your own risk; no warranty; no promises; enjoy!
by Gary Stephenson (garys at magna.com.au)
(who is currently underemployed <g>)
"""
import re
import sys
import glob
import string
Identifier = re.compile(r"\s*([A-Za-z_]+[A-Za-z0-9_]*)")
NumLiteral = re.compile(r"\s*([0-9]+(\.[0-9]+)?)")
StringLiteral = re.compile(r"\s*('.*?'|\".*?\")")
LogLiteral = re.compile(r"\s*(\.f\.|\.t\.)",re.I )
Operator = re.compile(r"\s*(\+\+|\+=|\+|--|-=|->|-|\*\*|\*=|\*|/=|/|,|!|\||%|\.not\.|\.or\.|\.and\.|@|:=|:|==|=|>=|>|<=|<)",re.IGNORECASE)
BlockHeader = re.compile(r"\s*\{\s*\|.*\|" )
OpenBrackets = re.compile(r"\s*(\[|\(|{)")
CloseBrackets = re.compile(r"\s*(\]|\)|})")
eol = re.compile(r"\s*$")
comma = re.compile(r"\s*,")
defStmt = re.compile( r"#\s*define\s+(?P<name>\w+)(?P<aft>.*)?", re.IGNORECASE )
ifdef = re.compile( r"#\s*ifdef\s+(?P<name>\w+)", re.IGNORECASE )
ifndef = re.compile( r"#\s*ifndef\s+(?P<name>\w+)", re.IGNORECASE )
elsedef = re.compile( r"#\s*else\s*", re.IGNORECASE )
endif = re.compile( r"#\s*endif\s*", re.IGNORECASE )
include = re.compile( r"#\s*include\s+(?P<filename>.+)",re.IGNORECASE )
undef = re.compile( r"#\s*undef\s+(?P<name>\w+)", re.IGNORECASE )
cmd = re.compile( r"#\s*command\s*(?P<srch>.+)=>(?P<repl>.*)", re.IGNORECASE )
xcmd = re.compile( r"#\s*xcommand\s+(?P<srch>.+)=>(?P<repl>.*)", re.IGNORECASE )
trans = re.compile( r"#\s*trans(late)?\s+(?P<srch>.+)=>(?P<repl>.*)", re.IGNORECASE )
xtrans = re.compile( r"#\s*xtrans(late)?\s+(?P<srch>.+)=>(?P<repl>.*)", re.IGNORECASE )
pragma = re.compile( r"#\s*pragma\s*.+", re.IGNORECASE )
matchLit = re.compile( r"\s*([^\s^\[^\]^<]+)" )
matchGrp = re.compile( r"\s*\[" )
endGrp = re.compile( r"\s*\]" )
matchMrk = re.compile( r"\s*<(.+?)>" )
DumbMrk = re.compile( r"\s*#<(.+)>" )
firstNonWhite = re.compile( r"(\s*)\S" )
defs = { "__XPP__":None }
lineno = 0
curfile = ""
curIndent = ""
def StripComment( ln="" ) :
global curIndent
n = string.find( ln, '//' )
if n <> -1 :
ln = ln[:n]
m = firstNonWhite.match(ln)
if m :
curIndent = m.group(1)
return string.strip( ln )
def splitMatch( str, lft, rght ) :
"Parses the string on balancing delimiters"
j = string.find( str, lft )
if j == -1 :
return ( str,"","" )
bef = str[:j]
i = j + 1
l = len( str )
n = 0
while i < l :
if str[i] == rght :
if n == 0 :
return ( bef, str[j+1:i], str[i+1:] )
n = n - 1
elif str[i] == lft :
n = n + 1
i = i + 1
assert 0, "Unbalanced delimiters detected"
def pseudofunc( key, str, line ) :
i = string.find( str, ")" )
srch = string.split( str[1:i], "," )
str = str[i+1:]
i = string.find( line, key )
bef = line[:i]
line = line[i+2:]
l = len( line )
n = 0
i = 0
while n < l :
c = line[n]
if c == "(" :
i = i + 1
elif c == ")" :
if i == 0 :
break
i = i - 1
n = n + 1
aft = line[n+1:]
subs = string.split( line[:n],"," )
l = len( subs )
assert l==len(srch), "Length mismatch"
for i in xrange( 0,l ) :
str = replace( str, string.strip( string.rstrip( srch[i] ) ) , string.strip( string.rstrip( subs[i] ) ) )
return bef + str + aft
def writeln( hFile ) :
hFile.write( curIndent+tline+"\n" )
def writeBlank() :
if rootfile == curfile :
hOut.write( "\n" )
def readln( hFile ) :
global lineno
while 1 :
s = hFile.readline()
lineno = lineno+1
if not s :
hFile.close()
break
s = StripComment( s )
if not s :
writeBlank()
continue
if s[0] == "*" :
writeBlank()
continue
if s[:2] != "/*" :
break
writeBlank()
while string.rstrip(s)[-2:] != "*/" :
writeBlank()
s = hFile.readline()
lineno = lineno+1
if not s :
hFile.close()
print "Error : Unclosed Multiline Comments"
sys.exit(1)
return s
def readNextLine( hFile ) :
s = readln( hFile )
while s[-1:] == ";" :
s = s[:-1] + " " + readln( hFile )
writeBlank()
return s
def defOmit( hFile ) :
while 1 :
line = readNextLine( hFile )
m = endif.match( line )
if m :
return
m = elsedef.match( line )
if m :
return
m = ifdef.match( line )
if m and not defs.has_key( m.group("name") ) :
defOmit( hFile )
m = ifndef.match( line )
if m and defs.has_key( m.group("name") ) :
defOmit( hFile )
class MatchGroup:
""" see docstring for MatchTree"""
def __init__( self ) :
global curpos
self.trees = []
while 1:
self.trees.append( MatchTree() )
m = matchGrp.match( tline, curpos )
if not m :
break
curpos = m.end()
def __repr__( self ) :
return self.pprint( 0 )
def pprint( self, ind ) :
s = ""
for t in self.trees :
s = s + t.pprint( ind+1 )
return s
def match( self ) :
while 1 :
mtch = 0
for t in self.trees :
if t.match() :
mtch = 1
break
if not mtch :
break
return 1
class MatchTree:
"""
MatchTree -> ( Literal | Marker | MatchGroup )+
MatchGroup -> ( MatchTree )+
MatchTree stores the "syntax tree" for each clause
MatchGroup is a grouping of clauses at the same "level" (i.e. contiguous in the declaration)
tline is the (global) string we are matching to
curpos is the (global) current index into tline, which the match methods increment on success!
"""
def __init__( self ) :
self.tokens = []
self.parse()
def __repr__( self ) :
return self.pprint()
def pprint( self, ind=0 ) :
s = ""
for t in self.tokens :
s = s + t.pprint( ind )
s = s + (" "*ind)+"--------------\n"
return s
def match( self ) :
global curpos
i = curpos
for m in self.tokens :
if not m.match() :
curpos = i
return 0
return 1
def search( self ) :
global curpos
i = curpos
strt = self.tokens[0].search()
if strt != -1 :
for t in self.tokens[1:] :
if not t.match() :
curpos = i
return -1
return strt
def parse( self ) :
global curpos
l = len( tline )
while curpos < l :
m = matchGrp.match( tline, curpos )
if m :
curpos = m.end()
self.tokens.append( MatchGroup() )
state = "G"
continue
m = endGrp.match( tline, curpos )
if m :
curpos = m.end()
return
m = matchMrk.match( tline,curpos )
if m:
body = m.group( 1 )
curpos = m.end()
c = body[0]
if c == "(" :
self.tokens.append( ExtendedMarker( body[1:-1] ) )
elif c == "#" : # single
self.tokens.append( SingleMarker( body[1:] ) )
elif c == "*" : # wild
self.tokens.append( WildMarker( body[1:-1] ) )
elif string.strip( body )[-3:] == "..." : # list
n = string.find( body, "," )
self.tokens.append( ListMarker( string.strip( body[:n] ) ) )
elif string.find( body, ":" ) > 0 : # restricted
self.tokens.append( RestrictedMarker( body ) )
else : # regular
self.tokens.append( RegularMarker( body ) )
state = "M"
continue
m = Identifier.match( tline,curpos )
if m :
self.tokens.append( KeyWord( m.group(1) ) )
curpos = m.end()
continue
m = matchLit.match( tline,curpos )
if m :
self.tokens.append( Literal( m.group(1) ) )
curpos = m.end()
continue
assert 0, "Error - Unable to parse : "+tline[curpos:]
def readExpression( xpos=0, expect="",commaOK = 0 ) :
prevTok = "O"
while xpos < len( tline ) :
m = BlockHeader.match( tline,xpos )
if m :
xpos = readExpression( m.end(), "}" )
prevTok = "B"
continue
m = OpenBrackets.match( tline, xpos )
if m :
c = m.group(1)
if( prevTok != "O" and prevTok != "I" ) :
return xpos
if c == "[" :
bal = "]"
elif c == "{" :
bal = "}"
else : # c == "("
bal = ")"
xpos = readExpression( m.end(), bal, 1 )
prevTok = "X"
continue
m = CloseBrackets.match( tline, xpos )
if m :
if expect :
if m.group(1) != expect :
assert 0, "Unbalanced delimiters"
return m.end()
return xpos
if not commaOK :
m = comma.match( tline,xpos )
if m :
return xpos
m = Operator.match(tline, xpos)
if m :
prevTok = "O"
xpos = m.end()
continue
m = NumLiteral.match(tline, xpos)
if not m :
m = StringLiteral.match(tline, xpos)
if not m :
m = LogLiteral.match(tline, xpos)
if m :
if prevTok != "O" :
return xpos
prevTok = "L"
xpos = m.end()
continue
m = Identifier.match(tline, xpos)
if m :
if prevTok != "O" :
return xpos
prevTok = "I"
xpos = m.end()
continue
print "Error : Unable to parse string : "+tline[xpos:]
sys.exit(1)
return xpos
def ParseExpression() :
global curpos
i = curpos
curpos = readExpression( i )
return tline[i:curpos]
class Literal :
def __init__( self, s ) :
#self.re = re.compile( r"\s*"+re.escape( s )+r"(\b|$)", re.I )
self.re = re.compile( r"\s*"+re.escape( s ), re.I )
assert s
def __repr__( self ) :
return self.pprint()
def pprint( self, ind=0 ) :
return (" ")*ind + "Literal : "+self.re.pattern+"\n"
def match( self ) :
global curpos
m = self.re.match( tline, curpos )
if m :
curpos = m.end()
return 1
return 0
def search( self ) :
global curpos
m = self.re.search( tline, curpos )
if m :
curpos = m.end()
return m.start()
return -1
class KeyWord :
def __init__( self, s ) :
self.re = re.compile( r"\s*\b"+ s +r"(\b|$)", re.I )
assert s
def __repr__( self ) :
return self.pprint()
def pprint( self, ind=0 ) :
return (" ")*ind + "Keyword : "+self.re.pattern+"\n"
def match( self ) :
global curpos
m = self.re.match( tline, curpos )
if m :
curpos = m.end()
return 1
return 0
def search( self ) :
global curpos
m = self.re.search( tline, curpos )
if m :
curpos = m.end()
return m.start()
return -1
class MatchMarker :
def __init__( self, name ) :
self.name = name
self.vals = []
if currentCmd.markers.has_key( name ) :
print "Error - marker name already present : "+name
sys.exit(1)
currentCmd.markers[name] = self
def __repr__( self ) :
return self.pprint()
def pprint( self,ind=0 ) :
assert 0, "Abstract method called"
return ""
def match( self ) :
assert 0, "Abstract method called"
return 0
def getVal( self, i=0, f=None ) :
l = len( self.vals )
if i >= l :
if l :
val = self.vals[l-1]
else :
val =""
else :
val = self.vals[i]
if f :
return apply( f, (val,) )
return val
class RegularMarker( MatchMarker ) :
def __init__( self, name ) :
MatchMarker.__init__( self,name )
def pprint( self, ind=0 ) :
return (" ")*ind + "Regular : "+self.name+"\n"
def match( self ) :
self.vals.append( ParseExpression() )
return 1
class RestrictedMarker( MatchMarker ) :
def __init__( self, body ) :
n = string.find( body, ":" )
name = string.strip( body[:n] )
MatchMarker.__init__( self, name )
self.vals = []
mstr = string.replace( body[n+1:],",","|" )
self.re = re.compile( "\s*("+string.replace( mstr, " ", "" )+")", re.I )
def pprint( self, ind=0 ) :
return (" ")*ind + "Regular : "+self.name+", "+self.re.pattern+"\n"
def match( self ) :
global curpos
m = self.re.match( tline, curpos )
if m :
self.vals.append( m.group( 1 ) )
curpos = m.end()
return 1
return 0
def search( self ) :
global curpos
m = self.re.search( tline, curpos )
if m :
self.vals.append( m.group( 1 ) )
curpos = m.end()
return m.start()
return -1
class WildMarker( MatchMarker ) :
def __init__( self, name ) :
MatchMarker.__init__( self,name )
def pprint( self, ind=0 ) :
return (" ")*ind + "Wild : "+self.name+"\n"
def match( self ) :
global curpos
self.vals.append( tline[curpos:] )
curpos = len( tline )
return 1
class SingleMarker( MatchMarker ) :
def __init__( self, name ) :
MatchMarker.__init__( self,name )
self.re = re.compile( r"\s*([^\s]*)" )
def pprint( self, ind=0 ) :
return (" ")*ind + "Single : "+self.name+"\n"
def match( self ) :
global curpos
m = self.re.match( tline, curpos )
if m :
self.vals.append( m.group(1) )
curpos = m.end()
return 1
return 0
class ExtendedMarker( MatchMarker ) :
def __init__( self, name ) :
MatchMarker.__init__( self,name )
self.reXpr = re.compile("\s*\(")
def pprint( self, ind=0 ) :
return (" ")*ind + "Extended : "+self.name+"\n"
def match( self ) :
global curpos
m = self.reXpr.match( tline, curpos )
if m :
self.vals.append( ParseExpression() )
return 1
m = StringLiteral.match( tline, curpos )
if not m :
m = Identifier.match( tline, curpos )
if m :
self.vals.append( m.group(1) )
curpos = m.end()
return 1
return 0
class ListMarker( MatchMarker ) :
def __init__( self, name ) :
MatchMarker.__init__( self,name )
def pprint( self, ind=0 ) :
return (" ")*ind + "List : "+self.name+"\n"
def match( self ) :
global curpos
val = []
self.vals.append( val )
while 1:
xpos = curpos
curpos = readExpression(curpos)
val.append( tline[xpos:curpos] )
m = comma.match( tline,curpos )
if not m:
break
curpos = m.end()
return 1
def getVal( self, i=0, f=None ) :
l = len( self.vals )
if i >= l :
if l :
val = self.vals[l-1]
else :
val = [""]
else :
val = self.vals[i]
if not val :
val.append("")
if f :
val = map( f, val )
return reduce( lambda x,y : x+","+y, val )
class ResultGroup :
def __init__( self ) :
global curpos
self.markers = []
self.prs = ""
l = len( tline )
while curpos < l :
m = matchGrp.match( tline,curpos )
if m :
self.prs = self.prs + tline[m.start():m.end()-1] + "%s"
curpos = m.end()
self.markers.append( (ResultGroup(),) )
continue
if endGrp.match( tline,curpos ) :
return
Dumb = 0
m = matchMrk.match( tline,curpos )
if not m :
Dumb = 1
m = DumbMrk.match( tline,curpos )
if m :
self.prs = self.prs + tline[curpos:m.start()]
body = m.group(1)
curpos = m.end()
c = body[0]
if Dumb :
mname = body
func = stringify
elif c == '"' :
assert body[-1] == '"', "Invalid match marker : "+body
mname = body[1:-1]
func = normstringify
elif c == "(" :
assert body[-1] == ')', "Invalid match marker : "+body
mname = body[1:-1]
func = smartstringify
elif c == "{" :
assert body[-1] == '}', "Invalid match marker : "+body
mname = body[1:-1]
func = blockify
elif c == "." :
assert body[-1] == '.', "Invalid match marker : "+body
mname = body[1:-1]
func = logify
else : # regular
mname = body
func = lambda s : s
if not currentCmd.markers.has_key( mname ) :
print "Error : match marker not found for "+mname+" at line :",lineno
print tline
print currentCmd.mtree
sys.exit(1)
self.markers.append( (currentCmd.markers[mname],func) )
self.prs = self.prs + "%s"
continue
m = matchLit.match( tline, curpos )
if m :
self.prs = self.prs + tline[m.start():m.end()]
curpos = m.end()
def expand( self, i = 0 ) :
l = []
for m in self.markers :
if len(m) == 2 :
l.append( m[0].getVal( i, m[1] ) )
else :
l.append( m[0].repexpand() )
return self.prs % tuple( l )
def repexpand( self ) : # Note : this should not have any repeating group markers!
maxlen = 0
Result = ""
for m in self.markers :
if len( m[0].vals ) > maxlen :
maxlen = len( m[0].vals )
for i in range( 0, maxlen ) :
Result = Result + self.expand( i )
return Result
class Command :
cmds = []
def __init__( self, srch, repl ) :
global currentCmd,tline,curpos
self.markers = {}
currentCmd = self
curpos = 0
tline = string.strip( srch )
self.mtree = MatchTree()
tline = string.strip( repl )
curpos = 0
self.repl = ResultGroup()
Command.cmds.insert(0,self)
def transform( self ) :
global tline
if self.mtree.match() :
tline = self.repl.expand()
t = self.markers.items()
for (n,m) in t :
m.vals = []
return 1
return 0
class Translate( Command ) :
trns = []
def __init__( self, srch, repl ) :
global currentCmd,tline,curpos
self.markers = {}
currentCmd = self
tline = string.strip( srch )
curpos = 0
self.mtree = MatchTree()
tline = repl
curpos = 0
self.repl = ResultGroup()
Translate.trns.insert(0,self)
def transform( self ) :
global tline
i = self.mtree.search()
if i != -1 :
tline = tline[:i]+ self.repl.expand()+ tline[curpos:]
t = self.markers.items()
for (n,m) in t :
m.vals = []
return 1
return 1
return 0
def stringify( s ) :
if string.lstrip( s )[0] == '"' :
return "'"+s+"'"
return '"'+s+'"'
def normstringify( s ) :
if s :
return '"'+s+'"'
return s
def smartstringify( s ) :
if not s :
return ""
s = string.strip( s )
if s[0] == "(" and s[-1:] == ")" :
return s
return '"'+s+'"'
def blockify( s ) :
if s :
return "{|| "+s+" }"
return ""
def logify( s ) :
if s :
return ".T."
return ".F."
def applydefs() :
global defs,tline
for (frm,to) in defs.items() :
i = string.find( tline, frm )
if i <> -1 :
tline = string.replace( tline, frm, to )
return 1
return 0
def applytrans() :
for c in Translate.trns :
if c.transform() :
return 1
return 0
def applycmds() :
for c in Command.cmds :
if c.transform() :
return 1
return 0
def transform( line ) :
global tline,curpos
tline = line
assert tline, "Empty string before transform"
curpos = 0
while 1 :
if applydefs() :
continue
if applytrans() :
continue
if applycmds() :
continue
break
assert tline, "Empty string after transform"
writeln( hOut )
def PreProcess( cFile ) :
global defs,hOut,lineno,curfile
hFile = open( cFile, "r" )
if not hFile :
print "Error : unable to open "+cFile
sys.exit(1)
savno = lineno
savfile = curfile
curfile = cFile
lineno = 0
while not hFile.closed :
line = readNextLine(hFile)
if not line :
continue
m = defStmt.match( line )
if m :
nam = m.group("name")
if defs.has_key( nam ) :
print "Error : : "+nam+" already defined"
sys.exit(1)
if not m.group("aft") :
defs[nam] = "" # preprocessor const
elif m.group("aft")[0] == "(" : #pseudofunction
defs[nam+"("] = m.group("aft")
else : # symbolic constant
defs[nam] = string.strip( string.rstrip( m.group("aft") ) )
continue
m = ifdef.match( line )
if m :
if not defs.has_key( m.group("name") ) :
defOmit( hFile )
continue
m = ifndef.match( line )
if m :
if defs.has_key( m.group("name") ) :
defOmit( hFile )
continue
m = elsedef.match( line )
if m :
defOmit( hFile )
continue
m = endif.match( line )
if m :
continue
m = include.match( line )
if m :
fname = string.split( m.group("filename"),'"' )[1]
IncludeFile( fname )
continue
m = undef.match( line )
if m :
if defs.has_key( m.group("name") ) :
del defs[ m.group("name") ]
continue
m = xcmd.match( line )
if m :
Command( m.group("srch"),m.group("repl") )
continue
m = cmd.match( line )
if m :
Command( m.group("srch"),m.group("repl") )
continue
m = xtrans.match( line )
if m :
Translate( m.group("srch"),m.group("repl") )
continue
m = trans.match( line )
if m :
Translate( m.group("srch"),m.group("repl") )
continue
m = pragma.match( line )
if m :
continue
transform( line )
hFile.close()
lineno = savno
curfile = savfile
def IncludeFile( fname ) :
import os
if not os.path.exists( fname ) :
if os.environ.has_key("INCLUDE") :
incpaths = string.split( os.environ["INCLUDE"], ";" )
for p in incpaths :
if os.path.exists( p + "\\" + fname ) :
hOut.write( '#line 1 "'+p+"\\"+fname+'"@"'+fname+'"\n' )
fname = p+"\\"+fname
break
else :
print "Error : unable to find : "+fname
sys.exit( 1 )
else :
print "Error : unable to find : "+fname
sys.exit( 1 )
else :
hOut.write( '#line 1 "'+fname+'"@"'+fname+'"\n' )
PreProcess( fname )
if curfile :
hOut.write( "#line "+str(lineno)+' "'+curfile+'"\n' )
def PreProcessPrg( prg, pp=None,std=None ) :
import os
global hOut,curfile,rootfile
if "." not in prg :
prg = prg+".prg"
if not pp :
pp = os.path.splitext(prg)[0]+".ppp"
hOut = open( pp, "w" )
rootfile = prg
print "Preprocessing",prg,"to",pp,"using",std
if std :
IncludeFile( std )
hOut.write( '#line 1 "'+prg+'"\n' )
curfile = prg
PreProcess( prg )
hOut.close()
if __name__ == "__main__" :
import getopt
optlist, args = getopt.getopt( sys.argv[1:], "Uu:" )
if not args or len(args) > 2 :
print "Syntax : PRGPP [-U | -u <std.ch replacement> ] <filename> [ <ppp-name> ] "
else :
if len(args) < 2 :
args.append( None )
if optlist :
if optlist[0][0] == "-U" :
PreProcessPrg( args[0], args[1] )
elif optlist[0][0] == "-u" :
PreProcessPrg( args[0], args[1], optlist[0][1] )
else :
PreProcessPrg( args[0],args[1],"std.ch" )