Change the translation of the "Help" menu item to "?", so that the menu can be displa...
[reactos.git] / rosapps / smartpdf / fitz / mupdf / pdf_lex.c
1 #include <fitz.h>
2 #include <mupdf.h>
3
4 static inline int iswhite(int ch)
5 {
6 return ch == '\000' ||
7 ch == '\011' ||
8 ch == '\012' ||
9 ch == '\014' ||
10 ch == '\015' ||
11 ch == '\040';
12 }
13
14 static inline int isdelim(int ch)
15 {
16 return ch == '(' || ch == ')' ||
17 ch == '<' || ch == '>' ||
18 ch == '[' || ch == ']' ||
19 ch == '{' || ch == '}' ||
20 ch == '/' ||
21 ch == '%';
22 }
23
24 static inline int isregular(int ch)
25 {
26 return !isdelim(ch) && !iswhite(ch) && ch != EOF;
27 }
28
29 static inline int isnumber(int ch)
30 {
31 return ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9');
32 }
33
34 static inline int ishex(int ch)
35 {
36 return (ch >= '0' && ch <= '9') ||
37 (ch >= 'A' && ch <= 'F') ||
38 (ch >= 'a' && ch <= 'f');
39 }
40
41 static inline int fromhex(int ch)
42 {
43 if (ch >= '0' && ch <= '9')
44 return ch - '0';
45 else if (ch >= 'A' && ch <= 'F')
46 return ch - 'A' + 0xA;
47 else if (ch >= 'a' && ch <= 'f')
48 return ch - 'a' + 0xA;
49 return 0;
50 }
51
52 static inline void
53 lexwhite(fz_stream *f)
54 {
55 int c;
56 while (1)
57 {
58 c = fz_peekbyte(f);
59 if (!iswhite(c))
60 break;
61 fz_readbyte(f);
62 }
63 }
64
65 static inline void
66 lexcomment(fz_stream *f)
67 {
68 int c;
69 while (1)
70 {
71 c = fz_readbyte(f);
72 if (c == '\012') break;
73 if (c == '\015') break;
74 if (c == EOF) break;
75 }
76 }
77
78 static void
79 lexnumber(fz_stream *f, unsigned char *s, int n)
80 {
81 while (n > 1)
82 {
83 if (!isnumber(fz_peekbyte(f)))
84 break;
85 *s++ = fz_readbyte(f);
86 n--;
87 }
88 *s = '\0';
89 }
90
91 static void
92 lexname(fz_stream *f, unsigned char *s, int n)
93 {
94 unsigned char *p = s;
95 unsigned char *q = s;
96
97 while (n > 1)
98 {
99 if (!isregular(fz_peekbyte(f)))
100 break;
101 *s++ = fz_readbyte(f);
102 n--;
103 }
104 *s = '\0';
105
106 while (*p)
107 {
108 if (p[0] == '#' && p[1] != 0 && p[2] != 0)
109 {
110 *q++ = fromhex(p[1]) * 16 + fromhex(p[2]);
111 p += 3;
112 }
113 else
114 *q++ = *p++;
115 }
116 *q = '\0';
117 }
118
119 static int
120 lexstring(fz_stream *f, unsigned char *buf, int n)
121 {
122 unsigned char *s = buf;
123 unsigned char *e = buf + n;
124 int bal = 1;
125 int oct;
126 int c;
127
128 while (s < e)
129 {
130 c = fz_readbyte(f);
131 if (c == '(')
132 {
133 bal++;
134 *s++ = c;
135 }
136 else if (c == ')')
137 {
138 bal --;
139 if (bal == 0)
140 break;
141 *s++ = c;
142 }
143 else if (c == '\\')
144 {
145 c = fz_readbyte(f);
146 if (c == 'n') *s++ = '\n';
147 else if (c == 'r') *s++ = '\r';
148 else if (c == 't') *s++ = '\t';
149 else if (c == 'b') *s++ = '\b';
150 else if (c == 'f') *s++ = '\f';
151 else if (c == '(') *s++ = '(';
152 else if (c == ')') *s++ = ')';
153 else if (c == '\\') *s++ = '\\';
154
155 else if (c >= '0' && c <= '9')
156 {
157 oct = c - '0';
158 c = fz_peekbyte(f);
159 if (c >= '0' && c <= '9')
160 {
161 fz_readbyte(f);
162 oct = oct * 8 + (c - '0');
163 c = fz_peekbyte(f);
164 if (c >= '0' && c <= '9')
165 {
166 fz_readbyte(f);
167 oct = oct * 8 + (c - '0');
168 }
169 }
170 *s++ = oct;
171 }
172
173 else if (c == '\n')
174 ;
175 else if (c == '\r')
176 {
177 c = fz_peekbyte(f);
178 if (c == '\n')
179 fz_readbyte(f);
180 }
181 else *s++ = c;
182 }
183 else
184 {
185 *s++ = c;
186 }
187 }
188
189 return s - buf;
190 }
191
192 static int
193 lexhexstring(fz_stream *f, unsigned char *buf, int n)
194 {
195 unsigned char *s = buf;
196 unsigned char *e = buf + n;
197 int a = 0, x = 0;
198 int c;
199
200 while (s < e)
201 {
202 c = fz_readbyte(f);
203 if (c == '>')
204 break;
205 else if (iswhite(c))
206 continue;
207 else if (ishex(c))
208 {
209 if (x)
210 {
211 *s++ = a * 16 + fromhex(c);
212 x = !x;
213 }
214 else
215 {
216 a = fromhex(c);
217 x = !x;
218 }
219 }
220 else
221 break;
222 }
223
224 return s - buf;
225 }
226
227 static int
228 tokenfromkeyword(char *key)
229 {
230 if (!strcmp(key, "R")) return PDF_TR;
231 if (!strcmp(key, "true")) return PDF_TTRUE;
232 if (!strcmp(key, "false")) return PDF_TFALSE;
233 if (!strcmp(key, "null")) return PDF_TNULL;
234
235 if (!strcmp(key, "obj")) return PDF_TOBJ;
236 if (!strcmp(key, "endobj")) return PDF_TENDOBJ;
237 if (!strcmp(key, "stream")) return PDF_TSTREAM;
238 if (!strcmp(key, "endstream")) return PDF_TENDSTREAM;
239
240 if (!strcmp(key, "xref")) return PDF_TXREF;
241 if (!strcmp(key, "trailer")) return PDF_TTRAILER;
242 if (!strcmp(key, "startxref")) return PDF_TSTARTXREF;
243
244 return PDF_TKEYWORD;
245 }
246
247 int
248 pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
249 {
250 int c;
251
252 while (1)
253 {
254 c = fz_peekbyte(f);
255
256 if (c == EOF)
257 return PDF_TEOF;
258
259 else if (iswhite(c))
260 lexwhite(f);
261
262 else if (c == '%')
263 lexcomment(f);
264
265
266 else if (c == '/')
267 {
268 fz_readbyte(f);
269 lexname(f, buf, n);
270 *sl = strlen(buf);
271 return PDF_TNAME;
272 }
273
274 else if (c == '(')
275 {
276 fz_readbyte(f);
277 *sl = lexstring(f, buf, n);
278 return PDF_TSTRING;
279 }
280
281 else if (c == '<')
282 {
283 fz_readbyte(f);
284 c = fz_peekbyte(f);
285 if (c == '<')
286 {
287 fz_readbyte(f);
288 return PDF_TODICT;
289 }
290 else
291 {
292 *sl = lexhexstring(f, buf, n);
293 return PDF_TSTRING;
294 }
295 }
296
297 else if (c == '>')
298 {
299 fz_readbyte(f);
300 c = fz_readbyte(f);
301 if (c == '>')
302 return PDF_TCDICT;
303 return PDF_TERROR;
304 }
305
306 else if (c == '[')
307 {
308 fz_readbyte(f);
309 return PDF_TOARRAY;
310 }
311
312 else if (c == ']')
313 {
314 fz_readbyte(f);
315 return PDF_TCARRAY;
316 }
317
318 else if (c == '{')
319 {
320 fz_readbyte(f);
321 return PDF_TOBRACE;
322 }
323
324 else if (c == '}')
325 {
326 fz_readbyte(f);
327 return PDF_TCBRACE;
328 }
329
330 else if (isnumber(c))
331 {
332 lexnumber(f, buf, n);
333 *sl = strlen(buf);
334 if (strchr(buf, '.'))
335 return PDF_TREAL;
336 return PDF_TINT;
337 }
338
339 else if (isregular(c))
340 {
341 lexname(f, buf, n);
342 *sl = strlen(buf);
343 return tokenfromkeyword(buf);
344 }
345
346 else
347 return PDF_TERROR;
348 }
349 }
350