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