summaryrefslogtreecommitdiff
path: root/giscanner/scannerparser.y
diff options
context:
space:
mode:
authorJohan Bilien <jobi@litl.com>2008-10-11 23:19:59 +0000
committerLucas Almeida Rocha <lucasr@src.gnome.org>2008-10-11 23:19:59 +0000
commite36cf2f246a5e65c8fa9ed8b3b18d73c1b9ce470 (patch)
tree17ddfc31a142d124e853e8d398c76fba2bb90f4d /giscanner/scannerparser.y
parent8d37e2cb7be78a40ca3649a48f405db29d2cabcc (diff)
downloadgobject-introspection-e36cf2f246a5e65c8fa9ed8b3b18d73c1b9ce470.tar.gz
ignore non-UTF-8 string constants
2008-10-11 Johan Bilien <jobi@litl.com> * giscanner/scannerparser.y: ignore non-UTF-8 string constants 2008-10-11 Johan Bilien <jobi@litl.com> Bug 552347: Parse #defines constants * girepository/gtypelib.c: update the list of value_size with recently defined type tags * giscanner/scannerparser.y: brought back parsing of #defined, as present in older version * giscanner/giscannermodule.c: bind gi_source_scanner_append_filename * giscanner/girwriter.py: write out constant tags in the gir * giscanner/sourcescanner.py: add accessor for const_string * giscanner/transformer.py, giscanner/glibtransformer.py: handle constant svn path=/trunk/; revision=673
Diffstat (limited to 'giscanner/scannerparser.y')
-rw-r--r--giscanner/scannerparser.y185
1 files changed, 185 insertions, 0 deletions
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y
index 43635bd7..69d39a5c 100644
--- a/giscanner/scannerparser.y
+++ b/giscanner/scannerparser.y
@@ -32,6 +32,7 @@
#include <string.h>
#include <errno.h>
#include <glib.h>
+#include <glib/gstdio.h>
#include "sourcescanner.h"
#include "scannerparser.h"
@@ -179,6 +180,13 @@ strings
$$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
yytext[strlen (yytext) - 1] = '\0';
$$->const_string = g_strcompress (yytext + 1);
+ if (!g_utf8_validate ($$->const_string, -1, NULL))
+ {
+ g_warning ("Ignoring non-UTF-8 constant string %s", $$->ident);
+ g_free($$->const_string);
+ $$->const_string = NULL;
+ }
+
}
| strings STRING
{
@@ -1253,6 +1261,183 @@ yyerror (GISourceScanner *scanner, const char *s)
}
}
+static int
+eat_hspace (FILE * f)
+{
+ int c;
+ do
+ {
+ c = fgetc (f);
+ }
+ while (c == ' ' || c == '\t');
+ return c;
+}
+
+static int
+eat_line (FILE * f, int c)
+{
+ while (c != EOF && c != '\n')
+ {
+ c = fgetc (f);
+ }
+ if (c == '\n')
+ {
+ c = fgetc (f);
+ if (c == ' ' || c == '\t')
+ {
+ c = eat_hspace (f);
+ }
+ }
+ return c;
+}
+
+static int
+read_identifier (FILE * f, int c, char **identifier)
+{
+ GString *id = g_string_new ("");
+ while (g_ascii_isalnum (c) || c == '_')
+ {
+ g_string_append_c (id, c);
+ c = fgetc (f);
+ }
+ *identifier = g_string_free (id, FALSE);
+ return c;
+}
+
+void
+gi_source_scanner_parse_macros (GISourceScanner *scanner, GList *filenames)
+{
+ GError *error = NULL;
+ char *tmp_name = NULL;
+ FILE *fmacros =
+ fdopen (g_file_open_tmp ("gen-introspect-XXXXXX.h", &tmp_name, &error),
+ "w+");
+ g_unlink (tmp_name);
+
+ GList *l;
+ for (l = filenames; l != NULL; l = l->next)
+ {
+ FILE *f = fopen (l->data, "r");
+ int line = 1;
+
+ GString *define_line;
+ char *str;
+ gboolean error_line = FALSE;
+ int c = eat_hspace (f);
+ while (c != EOF)
+ {
+ if (c != '#')
+ {
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+
+ /* print current location */
+ str = g_strescape (l->data, "");
+ fprintf (fmacros, "# %d \"%s\"\n", line, str);
+ g_free (str);
+
+ c = eat_hspace (f);
+ c = read_identifier (f, c, &str);
+ if (strcmp (str, "define") != 0 || (c != ' ' && c != '\t'))
+ {
+ g_free (str);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ g_free (str);
+ c = eat_hspace (f);
+ c = read_identifier (f, c, &str);
+ if (strlen (str) == 0 || (c != ' ' && c != '\t' && c != '('))
+ {
+ g_free (str);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ define_line = g_string_new ("#define ");
+ g_string_append (define_line, str);
+ g_free (str);
+ if (c == '(')
+ {
+ while (c != ')')
+ {
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+ if (c == EOF || c == '\n')
+ {
+ error_line = TRUE;
+ break;
+ }
+ }
+ if (error_line)
+ {
+ g_string_free (define_line, TRUE);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+
+ g_assert (c == ')');
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+
+ /* found function-like macro */
+ fprintf (fmacros, "%s\n", define_line->str);
+
+ g_string_free (define_line, TRUE);
+ /* ignore rest of line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ if (c != ' ' && c != '\t')
+ {
+ g_string_free (define_line, TRUE);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ while (c != EOF && c != '\n')
+ {
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+ if (c == '\\')
+ {
+ c = fgetc (f);
+ if (c == '\n')
+ {
+ /* fold lines when seeing backslash new-line sequence */
+ c = fgetc (f);
+ }
+ else
+ {
+ g_string_append_c (define_line, '\\');
+ }
+ }
+ }
+
+ /* found object-like macro */
+ fprintf (fmacros, "%s\n", define_line->str);
+
+ c = eat_line (f, c);
+ line++;
+ }
+
+ fclose (f);
+ }
+
+ rewind (fmacros);
+ gi_source_scanner_parse_file (scanner, fmacros);
+}
+
gboolean
gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file)
{