@@ -61,7 +61,7 @@ def report(self, format, *args):
6161
6262 def initblacklists (self ):
6363 self .blacklistnames = self .makeblacklistnames ()
64- self .blacklisttypes = ["unknown" ] + self .makeblacklisttypes ()
64+ self .blacklisttypes = ["unknown" , "-" ] + self .makeblacklisttypes ()
6565
6666 def makeblacklistnames (self ):
6767 return []
@@ -73,7 +73,103 @@ def initrepairinstructions(self):
7373 self .repairinstructions = self .makerepairinstructions ()
7474
7575 def makerepairinstructions (self ):
76- return []
76+ """Parse the repair file into repair instructions.
77+
78+ The file format is simple:
79+ 1) use \ to split a long logical line in multiple physical lines
80+ 2) everything after the first # on a line is ignored (as comment)
81+ 3) empty lines are ignored
82+ 4) remaining lines must have exactly 3 colon-separated fields:
83+ functionpattern : argumentspattern : argumentsreplacement
84+ 5) all patterns use shell style pattern matching
85+ 6) an empty functionpattern means the same as *
86+ 7) the other two fields are each comma-separated lists of triples
87+ 8) a triple is a space-separated list of 1-3 words
88+ 9) a triple with less than 3 words is padded at the end with "*" words
89+ 10) when used as a pattern, a triple matches the type, name, and mode
90+ of an argument, respectively
91+ 11) when used as a replacement, the words of a triple specify
92+ replacements for the corresponding words of the argument,
93+ with "*" as a word by itself meaning leave the original word
94+ (no other uses of "*" is allowed)
95+ 12) the replacement need not have the same number of triples
96+ as the pattern
97+ """
98+ f = self .openrepairfile ()
99+ if not f : return []
100+ print "Reading repair file" , `f.name` , "..."
101+ list = []
102+ lineno = 0
103+ while 1 :
104+ line = f .readline ()
105+ if not line : break
106+ lineno = lineno + 1
107+ startlineno = lineno
108+ while line [- 2 :] == '\\ \n ' :
109+ line = line [:- 2 ] + ' ' + f .readline ()
110+ lineno = lineno + 1
111+ i = string .find (line , '#' )
112+ if i >= 0 : line = line [:i ]
113+ words = map (string .strip , string .splitfields (line , ':' ))
114+ if words == ['' ]: continue
115+ if len (words ) <> 3 :
116+ print "Line" , startlineno ,
117+ print ": bad line (not 3 colon-separated fields)"
118+ print `line`
119+ continue
120+ [fpat , pat , rep ] = words
121+ if not fpat : fpat = "*"
122+ if not pat :
123+ print "Line" , startlineno ,
124+ print "Empty pattern"
125+ print `line`
126+ continue
127+ patparts = map (string .strip , string .splitfields (pat , ',' ))
128+ repparts = map (string .strip , string .splitfields (rep , ',' ))
129+ patterns = []
130+ for p in patparts :
131+ if not p :
132+ print "Line" , startlineno ,
133+ print "Empty pattern part"
134+ print `line`
135+ continue
136+ pattern = string .split (p )
137+ if len (pattern ) > 3 :
138+ print "Line" , startlineno ,
139+ print "Pattern part has > 3 words"
140+ print `line`
141+ pattern = pattern [:3 ]
142+ else :
143+ while len (pattern ) < 3 :
144+ pattern .append ("*" )
145+ patterns .append (pattern )
146+ replacements = []
147+ for p in repparts :
148+ if not p :
149+ print "Line" , startlineno ,
150+ print "Empty replacement part"
151+ print `line`
152+ continue
153+ replacement = string .split (p )
154+ if len (replacement ) > 3 :
155+ print "Line" , startlineno ,
156+ print "Pattern part has > 3 words"
157+ print `line`
158+ replacement = replacement [:3 ]
159+ else :
160+ while len (replacement ) < 3 :
161+ replacement .append ("*" )
162+ replacements .append (replacement )
163+ list .append ((fpat , patterns , replacements ))
164+ return list
165+
166+ def openrepairfile (self , filename = "REPAIR" ):
167+ try :
168+ return open (filename , "r" )
169+ except IOError , msg :
170+ print `filename` , ":" , msg
171+ print "Cannot open repair file -- assume no repair needed"
172+ return None
77173
78174 def initfiles (self ):
79175 self .specmine = 0
@@ -90,11 +186,13 @@ def initpaths(self):
90186
91187 def initpatterns (self ):
92188 self .head_pat = "^pascal[ \t ]+" # XXX Mac specific!
93- self .tail_pat = "[);]"
94- self .whole_pat = "\(<type>[a-zA-Z0-9_]+\)[ \t \n ]+" + \
95- "\(<name>[a-zA-Z0-9_]+\)[ \t \n ]*(\(<args>[^()]*\))"
189+ self .tail_pat = "[;={}]"
190+ self .type_pat = "pascal[ \t \n ]+\(<type>[a-zA-Z0-9_]+\)[ \t \n ]+"
191+ self .name_pat = "\(<name>[a-zA-Z0-9_]+\)[ \t \n ]*"
192+ self .args_pat = "(\(<args>\([^(;=)]+\|([^(;=)]*)\)*\))"
193+ self .whole_pat = self .type_pat + self .name_pat + self .args_pat
96194 self .sym_pat = "^[ \t ]*\(<name>[a-zA-Z0-9_]+\)[ \t ]*=" + \
97- "[ \t ]*\(<defn>[-0-9'\" ][^\t \n ,}]*\),?"
195+ "[ \t ]*\(<defn>[-0-9'\" ][^\t \n ,; }]*\),?"
98196 self .asplit_pat = "^\(<type>.*[^a-zA-Z0-9_]\)\(<name>[a-zA-Z0-9_]+\)$"
99197
100198 def compilepatterns (self ):
@@ -212,12 +310,12 @@ def scan(self):
212310 self .report ("(No interface specifications will be written)" )
213311 else :
214312 self .report ("specfile = %s" , `self.specfile.name` )
215- self .specfile .write ("# Generated from %s\n " % `inputname` )
313+ self .specfile .write ("# Generated from %s\n \n " % `inputname` )
216314 if not self .defsfile :
217315 self .report ("(No symbol definitions will be written)" )
218316 else :
219317 self .report ("defsfile = %s" , `self.defsfile.name` )
220- self .defsfile .write ("# Generated from %s\n " % `inputname` )
318+ self .defsfile .write ("# Generated from %s\n \n " % `inputname` )
221319 self .alreadydone = []
222320 try :
223321 while 1 :
@@ -237,7 +335,7 @@ def dosymdef(self):
237335 self .defsfile .write ("%s = %s\n " % (name , defn ))
238336
239337 def dofuncspec (self ):
240- raw = self .line [ len ( self . head . group ( 0 )):]
338+ raw = self .line
241339 while self .tail .search (raw ) < 0 :
242340 line = self .getline ()
243341 raw = raw + line
@@ -256,7 +354,7 @@ def processrawspec(self, raw):
256354 self .error ("*** %s %s blacklisted" , type , name )
257355 return
258356 arglist = self .extractarglist (args )
259- arglist = self .repairarglist (arglist )
357+ arglist = self .repairarglist (name , arglist )
260358 if self .unmanageable (type , name , arglist ):
261359 ##for arg in arglist:
262360 ## self.report(" %s", `arg`)
@@ -285,18 +383,30 @@ def extractarg(self, part):
285383 type = regsub .gsub ("\*" , " ptr " , type )
286384 type = string .strip (type )
287385 type = regsub .gsub ("[ \t ]+" , "_" , type )
386+ return self .modifyarg (type , name , mode )
387+
388+ def modifyarg (self , type , name , mode ):
288389 if type [:6 ] == "const_" :
289390 type = type [6 :]
290391 elif type [- 4 :] == "_ptr" :
291392 type = type [:- 4 ]
292393 mode = "OutMode"
394+ if type [- 4 :] == "_far" :
395+ type = type [:- 4 ]
293396 return type , name , mode
294397
295- def repairarglist (self , arglist ):
398+ def repairarglist (self , functionname , arglist ):
296399 arglist = arglist [:]
297400 i = 0
298401 while i < len (arglist ):
299- for pattern , replacement in self .repairinstructions :
402+ for item in self .repairinstructions :
403+ if len (item ) == 2 :
404+ pattern , replacement = item
405+ functionpat = "*"
406+ else :
407+ functionpat , pattern , replacement = item
408+ if not fnmatch .fnmatchcase (functionname , functionpat ):
409+ continue
300410 n = len (pattern )
301411 if i + n > len (arglist ): continue
302412 current = arglist [i :i + n ]
@@ -336,12 +446,12 @@ def substituteargs(self, pattern, replacement, old):
336446 def generate (self , type , name , arglist ):
337447 classname , listname = self .destination (type , name , arglist )
338448 if not self .specfile : return
339- self .specfile .write ("\n f = %s(%s, %s,\n " % (classname , type , `name` ))
449+ self .specfile .write ("f = %s(%s, %s,\n " % (classname , type , `name` ))
340450 for atype , aname , amode in arglist :
341451 self .specfile .write (" (%s, %s, %s),\n " %
342452 (atype , `aname` , amode ))
343453 self .specfile .write (")\n " )
344- self .specfile .write ("%s.append(f)\n " % listname )
454+ self .specfile .write ("%s.append(f)\n \n " % listname )
345455
346456 def destination (self , type , name , arglist ):
347457 return "FunctionGenerator" , "functions"
0 commit comments