Tizen 2.1 base
[sdk/emulator/qemu.git] / gl / mesa / src / mesa / drivers / dri / common / xmlpool / gen_xmlpool.py
1 #!/usr/bin/python
2
3 import sys
4 import gettext
5 import re
6
7 # List of supported languages
8 languages = sys.argv[1:]
9
10 # Escape special characters in C strings
11 def escapeCString (s):
12     escapeSeqs = {'\a' : '\\a', '\b' : '\\b', '\f' : '\\f', '\n' : '\\n',
13                   '\r' : '\\r', '\t' : '\\t', '\v' : '\\v', '\\' : '\\\\'}
14     # " -> '' is a hack. Quotes (") aren't possible in XML attributes.
15     # Better use Unicode characters for typographic quotes in option
16     # descriptions and translations.
17     i = 0
18     r = ''
19     while i < len(s):
20         # Special case: escape double quote with \u201c or \u201d, depending
21         # on whether it's an open or close quote. This is needed because plain
22         # double quotes are not possible in XML attributes.
23         if s[i] == '"':
24             if i == len(s)-1 or s[i+1].isspace():
25                 # close quote
26                 q = u'\u201c'
27             else:
28                 # open quote
29                 q = u'\u201d'
30             r = r + q
31         elif escapeSeqs.has_key(s[i]):
32             r = r + escapeSeqs[s[i]]
33         else:
34             r = r + s[i]
35         i = i + 1
36     return r
37
38 # Expand escape sequences in C strings (needed for gettext lookup)
39 def expandCString (s):
40     escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n',
41                   'r' : '\r', 't' : '\t', 'v' : '\v',
42                   '"' : '"', '\\' : '\\'}
43     i = 0
44     escape = False
45     hexa = False
46     octa = False
47     num = 0
48     digits = 0
49     r = ''
50     while i < len(s):
51         if not escape:
52             if s[i] == '\\':
53                 escape = True
54             else:
55                 r = r + s[i]
56         elif hexa:
57             if (s[i] >= '0' and s[i] <= '9') or \
58                (s[i] >= 'a' and s[i] <= 'f') or \
59                (s[i] >= 'A' and s[i] <= 'F'):
60                 num = num * 16 + int(s[i],16)
61                 digits = digits + 1
62             else:
63                 digits = 2
64             if digits >= 2:
65                 hexa = False
66                 escape = False
67                 r = r + chr(num)
68         elif octa:
69             if s[i] >= '0' and s[i] <= '7':
70                 num = num * 8 + int(s[i],8)
71                 digits = digits + 1
72             else:
73                 digits = 3
74             if digits >= 3:
75                 octa = False
76                 escape = False
77                 r = r + chr(num)
78         else:
79             if escapeSeqs.has_key(s[i]):
80                 r = r + escapeSeqs[s[i]]
81                 escape = False
82             elif s[i] >= '0' and s[i] <= '7':
83                 octa = True
84                 num = int(s[i],8)
85                 if num <= 3:
86                     digits = 1
87                 else:
88                     digits = 2
89             elif s[i] == 'x' or s[i] == 'X':
90                 hexa = True
91                 num = 0
92                 digits = 0
93             else:
94                 r = r + s[i]
95                 escape = False
96         i = i + 1
97     return r
98
99 # Expand matches. The first match is always a DESC or DESC_BEGIN match.
100 # Subsequent matches are ENUM matches.
101 #
102 # DESC, DESC_BEGIN format: \1 \2=<lang> \3 \4=gettext(" \5=<text> \6=") \7
103 # ENUM format:             \1 \2=gettext(" \3=<text> \4=") \5
104 def expandMatches (matches, translations, end=None):
105     assert len(matches) > 0
106     nTranslations = len(translations)
107     i = 0
108     # Expand the description+enums for all translations
109     for lang,trans in translations:
110         i = i + 1
111         # Make sure that all but the last line of a simple description
112         # are extended with a backslash.
113         suffix = ''
114         if len(matches) == 1 and i < len(translations) and \
115                not matches[0].expand (r'\7').endswith('\\'):
116             suffix = ' \\'
117         # Expand the description line. Need to use ugettext in order to allow
118         # non-ascii unicode chars in the original English descriptions.
119         text = escapeCString (trans.ugettext (unicode (expandCString (
120             matches[0].expand (r'\5')), "utf-8"))).encode("utf-8")
121         print matches[0].expand (r'\1' + lang + r'\3"' + text + r'"\7') + suffix
122         # Expand any subsequent enum lines
123         for match in matches[1:]:
124             text = escapeCString (trans.ugettext (unicode (expandCString (
125                 match.expand (r'\3')), "utf-8"))).encode("utf-8")
126             print match.expand (r'\1"' + text + r'"\5')
127
128         # Expand description end
129         if end:
130             print end,
131
132 # Compile a list of translation classes to all supported languages.
133 # The first translation is always a NullTranslations.
134 translations = [("en", gettext.NullTranslations())]
135 for lang in languages:
136     try:
137         trans = gettext.translation ("options", ".", [lang])
138     except IOError:
139         sys.stderr.write ("Warning: language '%s' not found.\n" % lang)
140         continue
141     translations.append ((lang, trans))
142
143 # Regular expressions:
144 reLibintl_h  = re.compile (r'#\s*include\s*<libintl.h>')
145 reDESC       = re.compile (r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
146 reDESC_BEGIN = re.compile (r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
147 reENUM       = re.compile (r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
148 reDESC_END   = re.compile (r'\s*DRI_CONF_DESC_END')
149
150 # Print a header
151 print \
152 "/***********************************************************************\n" \
153 " ***        THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT!        ***\n" \
154 " ***********************************************************************/"
155
156 # Process the options template and generate options.h with all
157 # translations.
158 template = file ("t_options.h", "r")
159 descMatches = []
160 for line in template:
161     if len(descMatches) > 0:
162         matchENUM     = reENUM    .match (line)
163         matchDESC_END = reDESC_END.match (line)
164         if matchENUM:
165             descMatches.append (matchENUM)
166         elif matchDESC_END:
167             expandMatches (descMatches, translations, line)
168             descMatches = []
169         else:
170             sys.stderr.write (
171                 "Warning: unexpected line inside description dropped:\n%s\n" \
172                 % line)
173         continue
174     if reLibintl_h.search (line):
175         # Ignore (comment out) #include <libintl.h>
176         print "/* %s * commented out by gen_xmlpool.py */" % line
177         continue
178     matchDESC       = reDESC      .match (line)
179     matchDESC_BEGIN = reDESC_BEGIN.match (line)
180     if matchDESC:
181         assert len(descMatches) == 0
182         expandMatches ([matchDESC], translations)
183     elif matchDESC_BEGIN:
184         assert len(descMatches) == 0
185         descMatches = [matchDESC_BEGIN]
186     else:
187         print line,
188
189 if len(descMatches) > 0:
190     sys.stderr.write ("Warning: unterminated description at end of file.\n")
191     expandMatches (descMatches, translations)