gobject-introspection r673 - in trunk: . girepository giscanner tools



Author: lucasr
Date: Sat Oct 11 23:19:59 2008
New Revision: 673
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=673&view=rev

Log:
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


Modified:
   trunk/ChangeLog
   trunk/girepository/gtypelib.c
   trunk/giscanner/girwriter.py
   trunk/giscanner/giscannermodule.c
   trunk/giscanner/glibtransformer.py
   trunk/giscanner/scannerparser.y
   trunk/giscanner/sourcescanner.py
   trunk/giscanner/transformer.py
   trunk/tools/g-ir-scanner

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Sat Oct 11 23:19:59 2008
@@ -878,13 +878,35 @@
 			GError       **error)
 {
   gint value_size[] = {
-    0, 4, 1, 1, 2, 2, 4, 4, 8, 8, 
-    sizeof (gint), sizeof (guint), 
-    sizeof (glong), sizeof (gulong),
-    sizeof (gssize), sizeof (gsize),
-    sizeof (gfloat), sizeof (gdouble), 
-    0, 0
-  }; 
+    0, /* VOID */
+    4, /* BOOLEAN */
+    1, /* INT8 */
+    1, /* UINT8 */
+    2, /* INT16 */
+    2, /* UINT16 */
+    4, /* INT32 */
+    4, /* UINT32 */
+    8, /* INT64 */
+    8, /* UINT64 */
+    sizeof (gint),
+    sizeof (guint),
+    sizeof (glong),
+    sizeof (gulong),
+    sizeof (gssize),
+    sizeof (gsize),
+    sizeof (gfloat),
+    sizeof (gdouble),
+    sizeof (time_t),
+    0, /* GTYPE */
+    0, /* UTF8 */
+    0, /* FILENAME */
+    0, /* ARRAY */
+    0, /* INTERFACE */
+    0, /* GLIST */
+    0, /* GSLIST */
+    0, /* GHASH */
+    0, /* ERROR */
+  };
   ConstantBlob *blob;
   SimpleTypeBlob *type;
 

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Sat Oct 11 23:19:59 2008
@@ -22,7 +22,7 @@
 
 import os
 
-from .ast import (Callback, Class, Enum, Function, Interface, Member,
+from .ast import (Callback, Class, Constant, Enum, Function, Interface, Member,
                   Array, Struct, Alias, Union, List, Map, Varargs)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
                       GLibFlags, GLibObject, GLibInterface)
@@ -82,6 +82,8 @@
             pass
         elif isinstance(node, Alias):
             self._write_alias(node)
+        elif isinstance(node, Constant):
+            self._write_constant(node)
         else:
             print 'WRITER: Unhandled node', node
 
@@ -213,6 +215,12 @@
             attrs.append(('glib:nick', member.nick))
         self.write_tag('member', attrs)
 
+    def _write_constant(self, constant):
+        attrs = [('name', constant.name),
+                 ('value', str(constant.value))]
+        with self.tagcontext('constant', attrs):
+            self._write_type(constant.type)
+
     def _write_class(self, node):
         attrs = [('name', node.name),
                  ('c:type', node.ctype)]

Modified: trunk/giscanner/giscannermodule.c
==============================================================================
--- trunk/giscanner/giscannermodule.c	(original)
+++ trunk/giscanner/giscannermodule.c	Sat Oct 11 23:19:59 2008
@@ -392,6 +392,41 @@
 }
 
 static PyObject *
+pygi_source_scanner_parse_macros (PyGISourceScanner *self,
+                                  PyObject          *args)
+{
+  GList *filenames;
+  int i;
+  PyObject *list;
+
+  list = PyTuple_GET_ITEM (args, 0);
+
+  if (!PyList_Check (list))
+    {
+      PyErr_SetString (PyExc_RuntimeError, "parse macro takes a list of filenames");
+      return NULL;
+    }
+
+  filenames = NULL;
+  for (i = 0; i < PyList_Size (list); ++i)
+    {
+      PyObject *obj;
+      char *filename;
+
+      obj = PyList_GetItem (list, i);
+      filename = PyString_AsString (obj);
+
+      filenames = g_list_append (filenames, filename);
+    }
+
+  gi_source_scanner_parse_macros (self->scanner, filenames);
+  g_list_free (filenames);
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
 pygi_source_scanner_parse_file (PyGISourceScanner *self,
 				PyObject          *args)
 {
@@ -548,6 +583,7 @@
   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
   { "append_filename", (PyCFunction) pygi_source_scanner_append_filename, METH_VARARGS },
   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
+  { "parse_macros", (PyCFunction) pygi_source_scanner_parse_macros, METH_VARARGS },
   { "lex_filename", (PyCFunction) pygi_source_scanner_lex_filename, METH_VARARGS },
   { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS },
   { NULL, NULL, 0 }

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Sat Oct 11 23:19:59 2008
@@ -24,8 +24,8 @@
 from ctypes.util import find_library
 
 from . import cgobject
-from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
-                  Property, Return, Struct, Type, Alias, Array,
+from .ast import (Callback, Constant, Enum, Function, Member, Namespace,
+                  Parameter, Property, Return, Struct, Type, Alias, Array,
                   Union, type_name_from_ctype,
                   default_array_types, TYPE_UINT8)
 from .transformer import Names
@@ -228,6 +228,8 @@
             pass
         elif isinstance(node, Union):
             self._parse_union(node)
+        elif isinstance(node, Constant):
+            self._parse_constant(node)
         else:
             print 'GLIB Transformer: Unhandled node:', node
 
@@ -237,6 +239,9 @@
     def _parse_enum(self, enum):
         self._add_attribute(enum)
 
+    def _parse_constant(self, constant):
+        self._add_attribute(constant)
+
     def _parse_function(self, func):
         if func.symbol in SYMBOL_BLACKLIST:
             return

Modified: trunk/giscanner/scannerparser.y
==============================================================================
--- trunk/giscanner/scannerparser.y	(original)
+++ trunk/giscanner/scannerparser.y	Sat Oct 11 23:19:59 2008
@@ -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 @@
 		$$ = 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 @@
     }
 }
 
+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)
 {

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Sat Oct 11 23:19:59 2008
@@ -140,7 +140,7 @@
 
 
 class SourceSymbol(object):
-    __members__ = ['const_int', 'ident', 'type', 'base_type']
+    __members__ = ['const_int', 'const_string', 'ident', 'type', 'base_type']
 
     def __init__(self, scanner, symbol):
         self._scanner = scanner
@@ -163,6 +163,10 @@
         return self._symbol.const_int
 
     @property
+    def const_string(self):
+        return self._symbol.const_string
+
+    @property
     def ident(self):
         return self._symbol.ident
 
@@ -210,9 +214,9 @@
         self._parse(headers)
         self._filenames.extend(headers)
 
-    def parse_macros(self):
+    def parse_macros(self, filenames):
         self._scanner.set_macro_scan(True)
-        self._parse(self._filenames)
+        self._scanner.parse_macros(filenames)
         self._scanner.set_macro_scan(False)
 
     def get_symbols(self):

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Sat Oct 11 23:19:59 2008
@@ -23,7 +23,7 @@
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
                            Parameter, Return, Array, Struct, Field,
                            Type, Alias, Interface, Class, Node, Union,
-                           List, Map, Varargs, type_name_from_ctype,
+                           List, Map, Varargs, Constant, type_name_from_ctype,
                            type_names, default_array_types)
 from giscanner.config import DATADIR
 from .glibast import GLibBoxed
@@ -33,7 +33,7 @@
     CTYPE_VOID, CTYPE_ENUM, CTYPE_FUNCTION, CTYPE_STRUCT,
     CSYMBOL_TYPE_FUNCTION, CSYMBOL_TYPE_TYPEDEF, CSYMBOL_TYPE_STRUCT,
     CSYMBOL_TYPE_ENUM, CSYMBOL_TYPE_UNION, CSYMBOL_TYPE_OBJECT,
-    CSYMBOL_TYPE_MEMBER, CSYMBOL_TYPE_ELLIPSIS,
+    CSYMBOL_TYPE_MEMBER, CSYMBOL_TYPE_ELLIPSIS, CSYMBOL_TYPE_CONST,
     TYPE_QUALIFIER_CONST)
 from .odict import odict
 from .utils import strip_common_prefix, to_underscores
@@ -201,6 +201,8 @@
             return self._create_member(symbol)
         elif stype == CSYMBOL_TYPE_UNION:
             return self._create_union(symbol)
+        elif stype == CSYMBOL_TYPE_CONST:
+            return self._create_const(symbol)
         else:
             raise NotImplementedError(
                 'Transformer: unhandled symbol: %r' % (symbol, ))
@@ -424,6 +426,18 @@
                     option, )
         return return_
 
+    def _create_const(self, symbol):
+        name = self._remove_prefix(symbol.ident)
+        name = self.strip_namespace_object(name)
+        if symbol.const_string is None:
+            type_name = 'int'
+            value = symbol.const_int
+        else:
+            type_name = 'utf8'
+            value = symbol.const_string
+        const = Constant(name, type_name, value)
+        return const
+
     def _create_typedef_struct(self, symbol):
         name = self.strip_namespace_object(symbol.ident)
         struct = Struct(name, symbol.ident)

Modified: trunk/tools/g-ir-scanner
==============================================================================
--- trunk/tools/g-ir-scanner	(original)
+++ trunk/tools/g-ir-scanner	Sat Oct 11 23:19:59 2008
@@ -241,7 +241,7 @@
                        options.cpp_defines,
                        options.cpp_undefines)
     ss.parse_files(filenames)
-    ss.parse_macros()
+    ss.parse_macros(filenames)
 
     # Transform the C symbols into AST nodes
     transformer = Transformer(ss, options.namespace_name)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]