diff options
Diffstat (limited to 'gconf/gconf-lex.l')
-rw-r--r-- | gconf/gconf-lex.l | 476 |
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 @@ -/* gconf - General purpose configuration parser. -*- c -*- */ -%{ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <gconf.h> -#include <gconf-gram.h> -#include <unistd.h> -#include <fcntl.h> -#include <ctype.h> -#include <stdlib.h> -#include <errno.h> - -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include <obstack.h> -#include <xalloc.h> -#include <wordsplit.h> - -#if ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#else -# define _(msgid) msgid -#endif - -static char *multiline_delimiter; -static size_t multiline_delimiter_len; -static int multiline_unescape; /* Unescape here-document contents */ -static int (*char_to_strip) (char); /* Strip matching characters of each - here-document line */ - -gconf_locus_t gconf_current_locus; /* Input file location */ -/* Line correction. Equals to the number of #line directives inserted into - the input by the preprocessor instance. The external preprocessor, if - any, counts these as input lines and therefore the line numbers in *its* - #line directives are offset by the value of XLINES. - - Uff, running two preprocessors is confusing... -*/ -static size_t xlines; -static struct obstack stk; - -static void multiline_begin (char *); -static void multiline_add (char *); -static char *multiline_strip_tabs (char *text); -static void line_add_unescape_last (char *text, size_t len); -static int ident (void); -static int isemptystr (int off); - -static void parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines); -static void parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines); - -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - do \ - { \ - if (gconf_preprocessor) \ - result = fread (buf, 1, max_size, yyin); \ - else \ - result = gconf_preproc_fill_buffer(buf, max_size); \ - } \ - while (0) - -%} - - -%x COMMENT ML STR - -WS [ \t\f][ \t\f]* -ID [a-zA-Z_][a-zA-Z_0-9-]+ -P [1-9][0-9]* - -%% - /* C-style comments */ -"/*" BEGIN (COMMENT); -<COMMENT>[^*\n]* /* eat anything that's not a '*' */ -<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ -<COMMENT>\n ++gconf_current_locus.line; -<COMMENT>"*"+"/" BEGIN (INITIAL); - /* Line directive */ -^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { parse_line_cpp (yytext, - &gconf_current_locus, - &xlines); } -^[ \t]*#[ \t]*line[ \t].*\n { parse_line (yytext, &gconf_current_locus, - &xlines); } - /* End-of-line comments */ -#.*\n { gconf_current_locus.line++; } -#.* /* end-of-file comment */; -"//".*\n { gconf_current_locus.line++; } -"//".* /* end-of-file comment */; - /* Identifiers */ -<INITIAL>{ID} return ident (); - /* Strings */ -[a-zA-Z0-9_\.\*/:@-]+ { gconf_line_begin (); - gconf_line_add (yytext, yyleng); - yylval.string = gconf_line_finish (); - return STRING; } - /* Quoted strings */ -\"[^\\"\n]*\" { gconf_line_begin (); - gconf_line_add (yytext + 1, yyleng - 2); - yylval.string = gconf_line_finish (); - return QSTRING; } -\"[^\\"\n]*\\. | -\"[^\\"\n]*\\\n { BEGIN (STR); - gconf_line_begin (); - line_add_unescape_last (yytext + 1, yyleng - 1); } -<STR>[^\\"\n]*\\. | -<STR>\"[^\\"\n]*\\\n { line_add_unescape_last (yytext, yyleng); } -<STR>[^\\"\n]*\" { BEGIN(INITIAL); - if (yyleng > 1) - gconf_line_add (yytext, yyleng - 1); - yylval.string = gconf_line_finish (); - return QSTRING; } - /* Multiline strings */ -"<<"(-" "?)?\\?{ID}[ \t]*#.*\n | -"<<"(-" "?)?\\?{ID}[ \t]*"//".*\n | -"<<"(-" "?)?\\?{ID}[ \t]*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*#.*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*\n { - BEGIN (ML); - multiline_begin (yytext+2); - gconf_current_locus.line++; } - /* Ignore m4 line statements */ -<ML>^"#line ".*\n { gconf_current_locus.line++; } -<ML>.*\n { char *p = multiline_strip_tabs (yytext); - - if (!strncmp (p, multiline_delimiter, multiline_delimiter_len) - && isemptystr (p + multiline_delimiter_len - yytext)) - { - free (multiline_delimiter); - multiline_delimiter = NULL; - BEGIN (INITIAL); - yylval.string = gconf_line_finish (); - return MSTRING; - } - gconf_current_locus.line++; - multiline_add (p); } -{WS} ; - /* Other tokens */ -\n { gconf_current_locus.line++; } -[,;{}()] return yytext[0]; -. { if (isascii (yytext[0]) && isprint (yytext[0])) - gconf_error (&gconf_current_locus, 0, _("stray character %c"), yytext[0]); - else - gconf_error (&gconf_current_locus, 0, _("stray character \\%03o"), - (unsigned char) yytext[0]); } -%% - -pid_t gconf_preproc_pid; - -int -yywrap () -{ - if (yyin) - gconf_preproc_extrn_shutdown (gconf_preproc_pid); - else - gconf_preproc_done (); - gconf_current_locus.file = NULL; - return 1; -} - -int -gconf_lex_begin (const char *name) -{ - if (yy_flex_debug > 0) - yy_flex_debug = 0; - obstack_init (&stk); - if (gconf_preprocessor) - { - int fd; - - fd = open (name, O_RDONLY); - if (fd == -1) - { - gconf_error (NULL, errno, _("Cannot open `%s'"), name); - return 1; - } - close (fd); - - yyin = gconf_preproc_extrn_start (name, &gconf_preproc_pid); - if (!yyin) - { - gconf_error (NULL, errno, - _("Unable to start external preprocessor `%s'"), - gconf_preprocessor); - return 1; - } - } - else - return gconf_preproc_init (name); - - return 0; -} - -void -gconf_lex_end () -{ -} - -static int -isemptystr (int off) -{ - for (; yytext[off] && isspace (yytext[off]); off++) - ; - if (yytext[off] == ';') - { - int i; - for (i = off + 1; yytext[i]; i++) - if (!isspace (yytext[i])) - return 0; - yyless (off); - return 1; - } - return yytext[off] == 0; -} - -char * -multiline_strip_tabs (char *text) -{ - if (char_to_strip) - for (; *text && char_to_strip (*text); text++) - ; - return text; -} - -static int -unquote_char (int c) -{ - static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t"; - - char *p; - - for (p = quote_transtab; *p; p += 2) - { - if (*p == c) - return p[1]; - } - return -1; -} - -static void -unescape_to_obstack (int c) -{ - if (c != '\n') - { - int t = unquote_char (c); - if (t != -1) - obstack_1grow (&stk, t); - else - { - gconf_warning(&gconf_current_locus, 0, - _("unknown escape sequence '\\%c'"), - c); - obstack_1grow (&stk, c); - } - } -} - -void -gconf_line_add (const char *text, size_t len) -{ - obstack_grow (&stk, text, len); -} - -/* Same, but unescapes the last character from yytext */ -static void -line_add_unescape_last (char *text, size_t len) -{ - obstack_grow (&stk, text, len - 2); - unescape_to_obstack (text[len - 1]); -} - -static void -multiline_add (char *s) -{ - if (multiline_unescape) - { - for (; *s; s++) - { - if (*s == '\\') - { - unescape_to_obstack (s[1]); - ++s; - } - else - obstack_1grow (&stk, *s); - } - } - else - gconf_line_add (s, strlen (s)); -} - -void -gconf_line_begin () -{ - /* FIXME: nothing so far. Maybe prepare stk by calling obstack_finish? */ -} - -static int -is_tab (char c) -{ - return c == '\t'; -} - -static int -is_ws (char c) -{ - return c == '\t' || c == ' '; -} - -void -multiline_begin (char *p) -{ - if (*p == '-') - { - if (*++p == ' ') - { - char_to_strip = is_ws; - p++; - } - else - char_to_strip = is_tab; - } - else - char_to_strip = NULL; - if (*p == '\\') - { - p++; - multiline_unescape = 0; - } - else if (*p == '"') - { - char *q; - - p++; - multiline_unescape = 0; - q = strchr (p, '"'); - multiline_delimiter_len = q - p; - } - else - { - multiline_delimiter_len = strcspn (p, " \t"); - multiline_unescape = 1; - } - - /* Remove trailing newline */ - multiline_delimiter_len--; - multiline_delimiter = xmalloc (multiline_delimiter_len + 1); - memcpy (multiline_delimiter, p, multiline_delimiter_len); - multiline_delimiter[multiline_delimiter_len] = 0; - gconf_line_begin (); -} - -char * -gconf_line_finish () -{ - obstack_1grow (&stk, 0); - return obstack_finish (&stk); -} - -static int -ident () -{ - char *p; - - for (p = yytext; *p && isspace (*p); p++) - ; - obstack_grow (&stk, p, strlen (p)); - obstack_1grow (&stk, 0); - yylval.string = obstack_finish (&stk); - return IDENT; -} - -void -gconf_lex_trace (int n) -{ - yy_flex_debug = -n; -} - -gconf_value_t * -gconf_value_dup(gconf_value_t *input) -{ - gconf_value_t *ptr = obstack_alloc (&stk, sizeof (*ptr)); - *ptr = *input; - return ptr; -} - - -static int -assign_locus (gconf_locus_t *ploc, char *name, char *line, size_t *pxlines) -{ - char *p; - - if (name) - { - if (pxlines && (!ploc->file || strcmp(name, ploc->file))) - *pxlines = 0; - ploc->file = gconf_install_text (name); - } - ploc->line = strtoul (line, &p, 10) - (pxlines ? *pxlines : 0); - return *p != 0; -} - -static void -parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines) -{ - int rc = 1; - struct wordsplit ws; - - if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) - gconf_error (ploc, 0, _("cannot parse #line line")); - else - { - if (ws.ws_wordc == 2) - rc = assign_locus (ploc, NULL, ws.ws_wordv[1], pxlines); - else if (ws.ws_wordc == 3) - rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines); - else if (ws.ws_wordc == 4) - { - rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], 0); - if (rc == 0) - { - char *p; - unsigned long x = strtoul (ws.ws_wordv[3], &p, 10); - rc = *p != 0; - if (rc == 0) - *pxlines = x; - } - } - else - gconf_error (ploc, 0, _("invalid #line statement")); - - if (rc) - gconf_error (ploc, 0, _("malformed #line statement")); - wordsplit_free (&ws); - } -} - -static void -parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines) -{ - struct wordsplit ws; - - if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) - { - gconf_error (ploc, 0, _("cannot parse #line line")); - return; - } - else if (ws.ws_wordc < 3) - gconf_error (ploc, 0, _("invalid #line statement")); - else - { - if (assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines)) - gconf_error (ploc, 0, _("malformed #line statement")); - } - wordsplit_free (&ws); -} - |