In a few places in the compression appendix there was a :
[dwarf-doc.git] / dwarf5 / tools / fileio.py
1
2 # All the little classes used in storing latex source data.
3 # Copyright 2012 DWARF Debugging Information Format Committee
4
5 import sys
6
7 def isIdStart(c):
8   if isIndivid(c) == "y":
9     return "n"
10   if  ord(c) >= ord('a') and ord(c) <= ord('z'):
11     return "y"
12   if  ord(c) >= ord('A') and ord(c) <= ord('Z'):
13     return "y"
14   # It is tex/latex, so backslash starts a word.
15   if c == "\\":
16     return "y"
17   if c == "_":
18     return "y"
19   return "n"
20
21 def isIdNext(c):
22   if isIndivid(c) == "y":
23     return "n"
24   if  ord(c) >= ord('a') and ord(c) <= ord('z'):
25     return "y"
26   if  ord(c) >= ord('A') and ord(c) <= ord('Z'):
27     return "y"
28   if  ord(c) >= ord('0') and ord(c) <= ord('9'):
29     return "y"
30   # This is so we allow the colon in our tags
31   # Unfortunately, this gives trouble if we have a
32   # : at the end of a DW* name on input.
33   if c == ":":
34     return "y"
35   if c == "\\":
36     return "y"
37   if c == "-":
38     return "y"
39   if c == "_":
40     return "y"
41   return "n"
42 def isIndivid(c):
43   if c == "[":
44     return "y"
45   if c == "]":
46     return "y"
47   if c == "{":
48     return "y"
49   if c == "}":
50     return "y"
51   if c == " ":
52     return "y"
53   if c == "\t":
54     return "y"
55   return "n"
56
57 class dwtoken:
58   def __init__(self):
59     self._tex = []
60     self._underbar = []
61     self._std = []
62     self._label = []
63     # Class is "id", "ind","other","none"
64     self._class = "none"
65   def insertid(self,string):
66     self._class =  "id"
67     self._tex = list(string)
68     self._underbar = self._tex
69     self._std = self._tex
70     self._label = self._tex
71   def setIndivid(self,c):
72     self._tex = [c]
73     self._underbar = [c]
74     self._std = [c]
75     self._label = [c]
76     self._class =  "ind"
77   def setInitialIdChar(self,c):
78     self._tex = [c]
79     self._class =  "id"
80   def setNextIdChar(self,c):
81     self._tex += [c]
82
83   def setInitialOther(self,c):
84     self._tex = [c]
85     self._underbar = [c]
86     self._std = [c]
87     self._label = [c]
88     self._class =  "other"
89   def setNextOther(self,c):
90     self._tex += [c]
91     self._underbar += [c]
92     self._std += [c]
93     self._label += [c]
94     self._class =  "other"
95   def finishUpId(self):
96     """ This transforms the strings from the input form into
97         the internal forms we want.
98     """
99     self._underbar = []
100     self._std = []
101     self._label = []
102     n = 0
103     # Drop \-
104     while int(n) < len(self._tex):
105       c = self._tex[n]
106       if n < (len (self._tex) - 1) and c == "\\" and self._tex[n+1] == "-":
107         n = n +2
108         continue
109       self._underbar += [c]
110       n = n +1
111     # Drop \ from \_
112     n = 0
113     while int(n) < len(self._underbar):
114       c = self._underbar[n]
115       if n < (len (self._underbar) - 1) and c == "\\" and self._underbar[n+1] == "_":
116         n = n +1
117         continue
118       self._std += [c]
119       n = n +1
120     # Drop  underbar
121     n = 0
122     while int(n) < len(self._std):
123       c = self._std[n]
124       if  c == "_":
125         n = n +1
126         continue
127       self._label += [c]
128       n = n +1
129
130   def dwprintquotedshortform(self,d):
131       print "'",self.shortform(d),"'",
132   def shortform(self,d):
133       return ''.join(d)
134   def dwprint(self):
135     if self._class == "ind":
136       print self._class, 
137       self.dwprintquotedshortform(self._tex)
138       print ""
139     else:
140       # This prints the token with end-line oddly.
141       print self._class, 
142       self.dwprintquotedshortform(self._tex)
143       self.dwprintquotedshortform(self._underbar)
144       self.dwprintquotedshortform(self._std)
145       self.dwprintquotedshortform(self._label)
146       print ""
147   def dwwrite(self,outfile):
148     for x in self._tex:
149       outfile.write(x)
150
151 class  dwline:
152   """using an input line, create a list of tokens for the line.
153      Legal class transitions in tokenize() are:
154      none->other
155      none->id
156      none->ind
157      other->ind
158      other->id
159      id->ind
160      id->other
161   """
162   def __init__(self):
163     # list of dwtoken.
164     self._toks = []
165
166   
167   def tokenize(self,rec):
168     """using an input line, create a list of tokens for the line.
169        Legal class transitions in tokenize() are:
170        none->other
171        none->id
172        none->ind
173        other->ind
174        other->id
175        id->ind
176        id->other
177     """
178     dwclass = "none"
179     combotok = dwtoken()
180     for c in rec:
181       if c == "\n" or c == "\r":
182           # Just drop these for now. Allowing them
183           # would not be harmful.
184           continue
185       elif dwclass == "none" or dwclass == "ind":
186         if isIndivid(c) == "y":
187           a = dwtoken()
188           a.setIndivid(c);
189           self._toks += [a]
190           continue
191         if isIdStart(c) == "y":
192           combotok.setInitialIdChar(c)
193           dwclass = "id"
194           continue
195         # is "other"
196         combotok.setInitialOther(c)
197         dwclass = "other"
198         continue
199       elif dwclass == "id": 
200         if isIdNext(c) == "y":
201           combotok.setNextIdChar(c)
202           continue
203         if isIndivid(c) == "y":
204           combotok.finishUpId()
205           self._toks += [combotok]
206           combotok = dwtoken()
207           a = dwtoken()
208           a.setIndivid(c);
209           dwclass = "ind"
210           self._toks += [a]
211           continue
212         # Other class input, other starts here.
213         combotok.finishUpId()
214         self._toks += [combotok]
215         combotok = dwtoken()
216         combotok.setInitialOther(c);
217         dwclass = "other"
218         continue
219       elif dwclass == "other":
220         if isIndivid(c) == "y":
221           self._toks += [combotok]
222           combotok = dwtoken()
223           a = dwtoken()
224           a.setIndivid(c);
225           dwclass = "ind"
226           self._toks += [a]
227           continue
228         if isIdStart(c) == "y":
229           self._toks += [combotok]
230           combotok = dwtoken()
231           combotok.setInitialIdChar(c);
232           dwclass = "id"
233           continue
234         combotok.setNextOther(c);
235         continue
236       # Else case impossible.
237      
238     #Finish up final non-empty other or id token
239     if dwclass == "id":
240       combotok.finishUpId()
241       self._toks += [combotok]
242       dwclass = "none"
243     if dwclass == "other":
244       self._toks += [combotok]
245       dwclass = "none"
246   def dwprint(self,linenum):
247     print "Number of tokens in line ",linenum," : ",len(self._toks)
248     if len(self._toks) == 0:
249       #Just print an empty line.
250       print ""
251     else:
252       for t in self._toks:
253         t.dwprint()
254   def dwwrite(self, outfile, linenum):
255     for t in self._toks:
256       t.dwwrite(outfile)
257     outfile.write("\n")
258   def dwtransformline(self,callfunc):
259     toks = callfunc(self._toks)
260     self._toks = toks
261     
262
263 class dwfile:
264   def __init__(self,name):
265     # list of dwline.
266     self._name = name
267     # Name of the file.
268     self._lines = []
269     try:
270       file = open(name,"r");
271     except IOError, message:
272       print >> sys.stderr , "File could not be opened: ", name
273       sys.exit(1)
274     while 1:
275       try:
276         rec = file.readline()
277       except EOFError:
278         break
279       if len(rec) < 1:
280         # eof
281         break
282
283       aline = dwline()
284       aline.tokenize(rec)
285       self._lines += [aline]
286
287   def dwprint(self):
288     print "Number of lines in ", self._name, ":  ",len(self._lines)
289     lnum = 1
290     for l in self._lines:
291        l.dwprint(lnum)
292        lnum = lnum + 1
293   def dwwrite(self):
294     # The lnum is just for debugging messages.
295
296     outname = self._name + ".out"
297     print outname
298     try:
299       outfile = open(outname,"w");
300     except IOError, message:
301       print >> sys.stderr , "Output File could not be opened: ", name
302       sys.exit(1)
303     lnum = 1
304     for l in self._lines:
305       l.dwwrite(outfile,lnum)
306       lnum = lnum + 1
307   def dwtransformline(self,callfunc):
308     for l in self._lines:
309       l.dwtransformline(callfunc)
310     
311
312
313 class dwfiles:
314   def __init__(self):
315     # list of dwfile.
316     self._files = []
317
318   def addFile(self,name):
319     f = dwfile(name)
320     self._files += [f]
321     
322   def dwprint(self):
323     print "Number of files: ",len(self._files);
324     for f in self._files:
325       f.dwprint()
326   def dwwrite(self):
327     for f in self._files:
328       f.dwwrite()
329   def dwtransformline(self,callfunc):
330     for f in self._files:
331       f.dwtransformline(callfunc)
332
333
334 def readFilelist(filelist):
335   dwf = dwfiles()
336   for f in filelist:
337     dwf.addFile(f)
338   return dwf
339