7ec0a97f6137e39962e470f898176e88ab950426
[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   if c == ":":
32     return "y"
33   if c == "\\":
34     return "y"
35   if c == "-":
36     return "y"
37   if c == "_":
38     return "y"
39   return "n"
40 def isIndivid(c):
41   if c == "[":
42     return "y"
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 == "\t":
52     return "y"
53   return "n"
54
55 class dwtoken:
56   def __init__(self):
57     self._tex = []
58     self._underbar = []
59     self._std = []
60     self._label = []
61     # Class is "id", "ind","other","none"
62     self._class = "none"
63   def setIndivid(self,c):
64     self._tex = [c]
65     self._underbar = [c]
66     self._std = [c]
67     self._label = [c]
68     self._class =  "ind"
69   def setInitialIdChar(self,c):
70     self._tex = [c]
71     self._class =  "id"
72   def setNextIdChar(self,c):
73     self._tex += [c]
74
75   def setInitialOther(self,c):
76     self._tex = [c]
77     self._underbar = [c]
78     self._std = [c]
79     self._label = [c]
80     self._class =  "other"
81   def setNextOther(self,c):
82     self._tex += [c]
83     self._underbar += [c]
84     self._std += [c]
85     self._label += [c]
86     self._class =  "other"
87   def finishUpId(self):
88     """ This transforms the strings from the input form into
89         the internal forms we want.
90     """
91     self._underbar = []
92     self._std = []
93     self._label = []
94     n = 0
95     # Drop \-
96     while int(n) < len(self._tex):
97       c = self._tex[n]
98       if n < (len (self._tex) - 1) and c == "\\" and self._tex[n+1] == "-":
99         n = n +2
100         continue
101       self._underbar += [c]
102       n = n +1
103     # Drop \ from \_
104     n = 0
105     while int(n) < len(self._underbar):
106       c = self._underbar[n]
107       if n < (len (self._underbar) - 1) and c == "\\" and self._underbar[n+1] == "_":
108         n = n +1
109         continue
110       self._std += [c]
111       n = n +1
112     # Drop  underbar
113     n = 0
114     while int(n) < len(self._std):
115       c = self._std[n]
116       if  c == "_":
117         n = n +1
118         continue
119       self._label += [c]
120       n = n +1
121
122   def dwprintquotedshortform(self,d):
123       print "'",self.shortform(d),"'",
124   def shortform(self,d):
125       return ''.join(d)
126   def dwprint(self):
127     if self._class == "ind":
128       print self._class, 
129       self.dwprintquotedshortform(self._tex)
130       print ""
131     else:
132       # This prints the token with end-line oddly.
133       print self._class, 
134       self.dwprintquotedshortform(self._tex)
135       self.dwprintquotedshortform(self._underbar)
136       self.dwprintquotedshortform(self._std)
137       self.dwprintquotedshortform(self._label)
138       print ""
139   def dwwrite(self,outfile):
140     for x in self._tex:
141       outfile.write(x)
142
143 class  dwline:
144   """using an input line, create a list of tokens for the line.
145      Legal class transitions in tokenize() are:
146      none->other
147      none->id
148      none->ind
149      other->ind
150      other->id
151      id->ind
152      id->other
153   """
154   def __init__(self):
155     # list of dwtoken.
156     self._toks = []
157
158   
159   def tokenize(self,rec):
160     """using an input line, create a list of tokens for the line.
161        Legal class transitions in tokenize() are:
162        none->other
163        none->id
164        none->ind
165        other->ind
166        other->id
167        id->ind
168        id->other
169     """
170     dwclass = "none"
171     combotok = dwtoken()
172     for c in rec:
173       if c == "\n" or c == "\r":
174           # Just drop these for now. Allowing them
175           # would not be harmful.
176           continue
177       elif dwclass == "none" or dwclass == "ind":
178         if isIndivid(c) == "y":
179           a = dwtoken()
180           a.setIndivid(c);
181           self._toks += [a]
182           continue
183         if isIdStart(c) == "y":
184           combotok.setInitialIdChar(c)
185           dwclass = "id"
186           continue
187         # is "other"
188         combotok.setInitialOther(c)
189         dwclass = "other"
190         continue
191       elif dwclass == "id": 
192         if isIdNext(c) == "y":
193           combotok.setNextIdChar(c)
194           continue
195         if isIndivid(c) == "y":
196           combotok.finishUpId()
197           self._toks += [combotok]
198           combotok = dwtoken()
199           a = dwtoken()
200           a.setIndivid(c);
201           dwclass = "ind"
202           self._toks += [a]
203           continue
204         # Other class input, other starts here.
205         combotok.finishUpId()
206         self._toks += [combotok]
207         combotok = dwtoken()
208         combotok.setInitialOther(c);
209         dwclass = "other"
210         continue
211       elif dwclass == "other":
212         if isIndivid(c) == "y":
213           self._toks += [combotok]
214           combotok = dwtoken()
215           a = dwtoken()
216           a.setIndivid(c);
217           dwclass = "ind"
218           self._toks += [a]
219           continue
220         if isIdStart(c) == "y":
221           self._toks += [combotok]
222           combotok = dwtoken()
223           combotok.setInitialIdChar(c);
224           dwclass = "id"
225           continue
226         combotok.setNextOther(c);
227         continue
228       # Else case impossible.
229      
230     #Finish up final non-empty other or id token
231     if dwclass == "id":
232       combotok.finishUpId()
233       self._toks += [combotok]
234       dwclass = "none"
235     if dwclass == "other":
236       self._toks += [combotok]
237       dwclass = "none"
238   def dwprint(self,linenum):
239     print "Number of tokens in line ",linenum," : ",len(self._toks)
240     if len(self._toks) == 0:
241       #Just print an empty line.
242       print ""
243     else:
244       for t in self._toks:
245         t.dwprint()
246   def dwwrite(self, outfile, linenum):
247     for t in self._toks:
248       t.dwwrite(outfile)
249     outfile.write("\n")
250     
251
252 class dwfile:
253   def __init__(self,name):
254     # list of dwline.
255     self._name = name
256     # Name of the file.
257     self._lines = []
258     try:
259       file = open(name,"r");
260     except IOError, message:
261       print >> sys.stderr , "File could not be opened: ", name
262       sys.exit(1)
263     while 1:
264       try:
265         rec = file.readline()
266       except EOFError:
267         break
268       if len(rec) < 1:
269         # eof
270         break
271
272       aline = dwline()
273       aline.tokenize(rec)
274       self._lines += [aline]
275
276   def dwprint(self):
277     print "Number of lines in ", self._name, ":  ",len(self._lines)
278     lnum = 1
279     for l in self._lines:
280        l.dwprint(lnum)
281        lnum = lnum + 1
282   def dwwrite(self):
283     # The lnum is just for debugging messages.
284
285     outname = self._name + ".out"
286     print outname
287     try:
288       outfile = open(outname,"w");
289     except IOError, message:
290       print >> sys.stderr , "Output File could not be opened: ", name
291       sys.exit(1)
292     lnum = 1
293     for l in self._lines:
294       l.dwwrite(outfile,lnum)
295       lnum = lnum + 1
296     
297
298
299 class dwfiles:
300   def __init__(self):
301     # list of dwfile.
302     self._files = []
303
304   def addFile(self,name):
305     f = dwfile(name)
306     self._files += [f]
307     
308   def dwprint(self):
309     print "Number of files: ",len(self._files);
310     for f in self._files:
311       f.dwprint()
312   def dwwrite(self):
313     for f in self._files:
314       f.dwwrite()
315
316
317
318 def readFilelist(filelist):
319   dwf = dwfiles()
320   for f in filelist:
321     dwf.addFile(f)
322   return dwf
323