aboutsummaryrefslogtreecommitdiff
path: root/gconf/gconf-lex.l
diff options
context:
space:
mode:
Diffstat (limited to 'gconf/gconf-lex.l')
-rw-r--r--gconf/gconf-lex.l476
1 files changed, 0 insertions, 476 deletions
diff --git a/gconf/gconf-lex.l b/gconf/gconf-lex.l
deleted file mode 100644
index 1379640..0000000
--- a/gconf/gconf-lex.l
+++ /dev/null
@@ -1,476 +0,0 @@
1/* gconf - General purpose configuration parser. -*- c -*- */
2%{
3/* gconf - General purpose configuration parser.
4 Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3 of the License, or (at your
9 option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22#include <gconf.h>
23#include <gconf-gram.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <ctype.h>
27#include <stdlib.h>
28#include <errno.h>
29
30#define obstack_chunk_alloc malloc
31#define obstack_chunk_free free
32#include <obstack.h>
33#include <xalloc.h>
34#include <wordsplit.h>
35
36#if ENABLE_NLS
37# include "gettext.h"
38# define _(msgid) gettext (msgid)
39#else
40# define _(msgid) msgid
41#endif
42
43static char *multiline_delimiter;
44static size_t multiline_delimiter_len;
45static int multiline_unescape; /* Unescape here-document contents */
46static int (*char_to_strip) (char); /* Strip matching characters of each
47 here-document line */
48
49gconf_locus_t gconf_current_locus; /* Input file location */
50/* Line correction. Equals to the number of #line directives inserted into
51 the input by the preprocessor instance. The external preprocessor, if
52 any, counts these as input lines and therefore the line numbers in *its*
53 #line directives are offset by the value of XLINES.
54
55 Uff, running two preprocessors is confusing...
56*/
57static size_t xlines;
58static struct obstack stk;
59
60static void multiline_begin (char *);
61static void multiline_add (char *);
62static char *multiline_strip_tabs (char *text);
63static void line_add_unescape_last (char *text, size_t len);
64static int ident (void);
65static int isemptystr (int off);
66
67static void parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines);
68static void parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines);
69
70#undef YY_INPUT
71#define YY_INPUT(buf,result,max_size) \
72 do \
73 { \
74 if (gconf_preprocessor) \
75 result = fread (buf, 1, max_size, yyin); \
76 else \
77 result = gconf_preproc_fill_buffer(buf, max_size); \
78 } \
79 while (0)
80
81%}
82
83
84%x COMMENT ML STR
85
86WS [ \t\f][ \t\f]*
87ID [a-zA-Z_][a-zA-Z_0-9-]+
88P [1-9][0-9]*
89
90%%
91 /* C-style comments */
92"/*" BEGIN (COMMENT);
93<COMMENT>[^*\n]* /* eat anything that's not a '*' */
94<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
95<COMMENT>\n ++gconf_current_locus.line;
96<COMMENT>"*"+"/" BEGIN (INITIAL);
97 /* Line directive */
98^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { parse_line_cpp (yytext,
99 &gconf_current_locus,
100 &xlines); }
101^[ \t]*#[ \t]*line[ \t].*\n { parse_line (yytext, &gconf_current_locus,
102 &xlines); }
103 /* End-of-line comments */
104#.*\n { gconf_current_locus.line++; }
105#.* /* end-of-file comment */;
106"//".*\n { gconf_current_locus.line++; }
107"//".* /* end-of-file comment */;
108 /* Identifiers */
109<INITIAL>{ID} return ident ();
110 /* Strings */
111[a-zA-Z0-9_\.\*/:@-]+ { gconf_line_begin ();
112 gconf_line_add (yytext, yyleng);
113 yylval.string = gconf_line_finish ();
114 return STRING; }
115 /* Quoted strings */
116\"[^\\"\n]*\" { gconf_line_begin ();
117 gconf_line_add (yytext + 1, yyleng - 2);
118 yylval.string = gconf_line_finish ();
119 return QSTRING; }
120\"[^\\"\n]*\\. |
121\"[^\\"\n]*\\\n { BEGIN (STR);
122 gconf_line_begin ();
123 line_add_unescape_last (yytext + 1, yyleng - 1); }
124<STR>[^\\"\n]*\\. |
125<STR>\"[^\\"\n]*\\\n { line_add_unescape_last (yytext, yyleng); }
126<STR>[^\\"\n]*\" { BEGIN(INITIAL);
127 if (yyleng > 1)
128 gconf_line_add (yytext, yyleng - 1);
129 yylval.string = gconf_line_finish ();
130 return QSTRING; }
131 /* Multiline strings */
132"<<"(-" "?)?\\?{ID}[ \t]*#.*\n |
133"<<"(-" "?)?\\?{ID}[ \t]*"//".*\n |
134"<<"(-" "?)?\\?{ID}[ \t]*\n |
135"<<"(-" "?)?\"{ID}\"[ \t]*#.*\n |
136"<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n |
137"<<"(-" "?)?\"{ID}\"[ \t]*\n {
138 BEGIN (ML);
139 multiline_begin (yytext+2);
140 gconf_current_locus.line++; }
141 /* Ignore m4 line statements */
142<ML>^"#line ".*\n { gconf_current_locus.line++; }
143<ML>.*\n { char *p = multiline_strip_tabs (yytext);
144
145 if (!strncmp (p, multiline_delimiter, multiline_delimiter_len)
146 && isemptystr (p + multiline_delimiter_len - yytext))
147 {
148 free (multiline_delimiter);
149 multiline_delimiter = NULL;
150 BEGIN (INITIAL);
151 yylval.string = gconf_line_finish ();
152 return MSTRING;
153 }
154 gconf_current_locus.line++;
155 multiline_add (p); }
156{WS} ;
157 /* Other tokens */
158\n { gconf_current_locus.line++; }
159[,;{}()] return yytext[0];
160. { if (isascii (yytext[0]) && isprint (yytext[0]))
161 gconf_error (&gconf_current_locus, 0, _("stray character %c"), yytext[0]);
162 else
163 gconf_error (&gconf_current_locus, 0, _("stray character \\%03o"),
164 (unsigned char) yytext[0]); }
165%%
166
167pid_t gconf_preproc_pid;
168
169int
170yywrap ()
171{
172 if (yyin)
173 gconf_preproc_extrn_shutdown (gconf_preproc_pid);
174 else
175 gconf_preproc_done ();
176 gconf_current_locus.file = NULL;
177 return 1;
178}
179
180int
181gconf_lex_begin (const char *name)
182{
183 if (yy_flex_debug > 0)
184 yy_flex_debug = 0;
185 obstack_init (&stk);
186 if (gconf_preprocessor)
187 {
188 int fd;
189
190 fd = open (name, O_RDONLY);
191 if (fd == -1)
192 {
193 gconf_error (NULL, errno, _("Cannot open `%s'"), name);
194 return 1;
195 }
196 close (fd);
197
198 yyin = gconf_preproc_extrn_start (name, &gconf_preproc_pid);
199 if (!yyin)
200 {
201 gconf_error (NULL, errno,
202 _("Unable to start external preprocessor `%s'"),
203 gconf_preprocessor);
204 return 1;
205 }
206 }
207 else
208 return gconf_preproc_init (name);
209
210 return 0;
211}
212
213void
214gconf_lex_end ()
215{
216}
217
218static int
219isemptystr (int off)
220{
221 for (; yytext[off] && isspace (yytext[off]); off++)
222 ;
223 if (yytext[off] == ';')
224 {
225 int i;
226 for (i = off + 1; yytext[i]; i++)
227 if (!isspace (yytext[i]))
228 return 0;
229 yyless (off);
230 return 1;
231 }
232 return yytext[off] == 0;
233}
234
235char *
236multiline_strip_tabs (char *text)
237{
238 if (char_to_strip)
239 for (; *text && char_to_strip (*text); text++)
240 ;
241 return text;
242}
243
244static int
245unquote_char (int c)
246{
247 static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t";
248
249 char *p;
250
251 for (p = quote_transtab; *p; p += 2)
252 {
253 if (*p == c)
254 return p[1];
255 }
256 return -1;
257}
258
259static void
260unescape_to_obstack (int c)
261{
262 if (c != '\n')
263 {
264 int t = unquote_char (c);
265 if (t != -1)
266 obstack_1grow (&stk, t);
267 else
268 {
269 gconf_warning(&gconf_current_locus, 0,
270 _("unknown escape sequence '\\%c'"),
271 c);
272 obstack_1grow (&stk, c);
273 }
274 }
275}
276
277void
278gconf_line_add (const char *text, size_t len)
279{
280 obstack_grow (&stk, text, len);
281}
282
283/* Same, but unescapes the last character from yytext */
284static void
285line_add_unescape_last (char *text, size_t len)
286{
287 obstack_grow (&stk, text, len - 2);
288 unescape_to_obstack (text[len - 1]);
289}
290
291static void
292multiline_add (char *s)
293{
294 if (multiline_unescape)
295 {
296 for (; *s; s++)
297 {
298 if (*s == '\\')
299 {
300 unescape_to_obstack (s[1]);
301 ++s;
302 }
303 else
304 obstack_1grow (&stk, *s);
305 }
306 }
307 else
308 gconf_line_add (s, strlen (s));
309}
310
311void
312gconf_line_begin ()
313{
314 /* FIXME: nothing so far. Maybe prepare stk by calling obstack_finish? */
315}
316
317static int
318is_tab (char c)
319{
320 return c == '\t';
321}
322
323static int
324is_ws (char c)
325{
326 return c == '\t' || c == ' ';
327}
328
329void
330multiline_begin (char *p)
331{
332 if (*p == '-')
333 {
334 if (*++p == ' ')
335 {
336 char_to_strip = is_ws;
337 p++;
338 }
339 else
340 char_to_strip = is_tab;
341 }
342 else
343 char_to_strip = NULL;
344 if (*p == '\\')
345 {
346 p++;
347 multiline_unescape = 0;
348 }
349 else if (*p == '"')
350 {
351 char *q;
352
353 p++;
354 multiline_unescape = 0;
355 q = strchr (p, '"');
356 multiline_delimiter_len = q - p;
357 }
358 else
359 {
360 multiline_delimiter_len = strcspn (p, " \t");
361 multiline_unescape = 1;
362 }
363
364 /* Remove trailing newline */
365 multiline_delimiter_len--;
366 multiline_delimiter = xmalloc (multiline_delimiter_len + 1);
367 memcpy (multiline_delimiter, p, multiline_delimiter_len);
368 multiline_delimiter[multiline_delimiter_len] = 0;
369 gconf_line_begin ();
370}
371
372char *
373gconf_line_finish ()
374{
375 obstack_1grow (&stk, 0);
376 return obstack_finish (&stk);
377}
378
379static int
380ident ()
381{
382 char *p;
383
384 for (p = yytext; *p && isspace (*p); p++)
385 ;
386 obstack_grow (&stk, p, strlen (p));
387 obstack_1grow (&stk, 0);
388 yylval.string = obstack_finish (&stk);
389 return IDENT;
390}
391
392void
393gconf_lex_trace (int n)
394{
395 yy_flex_debug = -n;
396}
397
398gconf_value_t *
399gconf_value_dup(gconf_value_t *input)
400{
401 gconf_value_t *ptr = obstack_alloc (&stk, sizeof (*ptr));
402 *ptr = *input;
403 return ptr;
404}
405
406
407static int
408assign_locus (gconf_locus_t *ploc, char *name, char *line, size_t *pxlines)
409{
410 char *p;
411
412 if (name)
413 {
414 if (pxlines && (!ploc->file || strcmp(name, ploc->file)))
415 *pxlines = 0;
416 ploc->file = gconf_install_text (name);
417 }
418 ploc->line = strtoul (line, &p, 10) - (pxlines ? *pxlines : 0);
419 return *p != 0;
420}
421
422static void
423parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines)
424{
425 int rc = 1;
426 struct wordsplit ws;
427
428 if (wordsplit (text, &ws, WRDSF_DEFFLAGS))
429 gconf_error (ploc, 0, _("cannot parse #line line"));
430 else
431 {
432 if (ws.ws_wordc == 2)
433 rc = assign_locus (ploc, NULL, ws.ws_wordv[1], pxlines);
434 else if (ws.ws_wordc == 3)
435 rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines);
436 else if (ws.ws_wordc == 4)
437 {
438 rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], 0);
439 if (rc == 0)
440 {
441 char *p;
442 unsigned long x = strtoul (ws.ws_wordv[3], &p, 10);
443 rc = *p != 0;
444 if (rc == 0)
445 *pxlines = x;
446 }
447 }
448 else
449 gconf_error (ploc, 0, _("invalid #line statement"));
450
451 if (rc)
452 gconf_error (ploc, 0, _("malformed #line statement"));
453 wordsplit_free (&ws);
454 }
455}
456
457static void
458parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines)
459{
460 struct wordsplit ws;
461
462 if (wordsplit (text, &ws, WRDSF_DEFFLAGS))
463 {
464 gconf_error (ploc, 0, _("cannot parse #line line"));
465 return;
466 }
467 else if (ws.ws_wordc < 3)
468 gconf_error (ploc, 0, _("invalid #line statement"));
469 else
470 {
471 if (assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines))
472 gconf_error (ploc, 0, _("malformed #line statement"));
473 }
474 wordsplit_free (&ws);
475}
476

Return to:

Send suggestions and report system problems to the System administrator.