gobject-introspection r643 - in trunk: girepository giscanner tests/scanner



Author: walters
Date: Thu Oct  2 14:07:38 2008
New Revision: 643
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=643&view=rev

Log:
Merge branch 'bug552393-varargs'


Modified:
   trunk/girepository/girnode.h
   trunk/girepository/girparser.c
   trunk/giscanner/ast.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/scannerparser.y
   trunk/giscanner/sourcescanner.h
   trunk/giscanner/sourcescanner.py
   trunk/giscanner/transformer.py
   trunk/tests/scanner/foo-expected.gir
   trunk/tests/scanner/foo.c
   trunk/tests/scanner/foo.h

Modified: trunk/girepository/girnode.h
==============================================================================
--- trunk/girepository/girnode.h	(original)
+++ trunk/girepository/girnode.h	Thu Oct  2 14:07:38 2008
@@ -85,6 +85,7 @@
   GIrNode node;
 
   gboolean deprecated;
+  gboolean is_varargs; /* Not in typelib yet */ 
 
   gboolean is_method;
   gboolean is_setter;
@@ -183,6 +184,7 @@
 {
   GIrNode node;
 
+  gboolean is_varargs; /* Not in typelib yet */ 
   gboolean must_chain_up;
   gboolean must_be_implemented;
   gboolean must_not_be_implemented;

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Thu Oct  2 14:07:38 2008
@@ -79,6 +79,7 @@
   GIrModule *current_module;
   GIrNode *current_node;
   GIrNode *current_typed;
+  gboolean is_varargs;
   GList *type_stack;
   GList *type_parameters;
   int type_depth;
@@ -1420,11 +1421,13 @@
   const gchar *name;
   const gchar *ctype;
   gboolean is_array;
+  gboolean is_varargs;
   GIrNodeType *typenode;
 
   is_array = strcmp (element_name, "array") == 0;
+  is_varargs = strcmp (element_name, "varargs") == 0;
 
-  if (!(is_array || (strcmp (element_name, "type") == 0)))
+  if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
     return FALSE;
 
   if (ctx->state == STATE_TYPE) 
@@ -1449,6 +1452,25 @@
     {
       state_switch (ctx, STATE_TYPE);
       ctx->type_depth = 1;
+      if (is_varargs)
+	{
+	  switch (ctx->current_node->type)
+	    {
+	    case G_IR_NODE_FUNCTION:
+	    case G_IR_NODE_CALLBACK:
+	      {
+		GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
+		func->is_varargs = TRUE;
+	      }
+	      break;
+	    case G_IR_NODE_VFUNC:
+	      {
+		GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
+		vfunc->is_varargs = TRUE;
+	      }
+	      break;
+	    }
+	}
       ctx->type_stack = NULL;
       ctx->type_parameters = NULL;
     }
@@ -1462,6 +1484,9 @@
       return FALSE;
     }
 
+  if (is_varargs)
+    return TRUE;
+
   if (is_array) 
     {
       const char *zero;
@@ -1509,7 +1534,12 @@
 static void
 end_type_top (ParseContext *ctx)
 {
-  GIrNodeType *typenode = (GIrNodeType*)ctx->type_parameters->data;
+  GIrNodeType *typenode;
+
+  if (!ctx->type_parameters)
+    goto out;
+
+  typenode = (GIrNodeType*)ctx->type_parameters->data;
 
   /* Default to pointer for unspecified containers */
   if (typenode->tag == GI_TYPE_TAG_ARRAY ||
@@ -1559,7 +1589,8 @@
       g_assert_not_reached ();
     }
   g_list_free (ctx->type_parameters);
-  
+
+ out:  
   ctx->type_depth = 0;
   ctx->type_parameters = NULL;
   ctx->current_typed = NULL;
@@ -2322,7 +2353,11 @@
       if (start_vfunc (context, element_name,
 		       attribute_names, attribute_values,
 		       ctx, error))
-	goto out;      
+	goto out;
+      if (start_type (context, element_name,
+		      attribute_names, attribute_values,
+		      ctx, error))
+	goto out;
       break;
     }
 
@@ -2464,36 +2499,43 @@
       break;
 
     case STATE_FUNCTION:
-       if (ctx->current_node == g_list_last (ctx->current_module->entries)->data)
-	{
-	  ctx->current_node = NULL;
-	  state_switch (ctx, STATE_NAMESPACE);
-	}
-      else 
-	{ 
-	  ctx->current_node = g_list_last (ctx->current_module->entries)->data;
-	  if (ctx->current_node->type == G_IR_NODE_INTERFACE)
-	    state_switch (ctx, STATE_INTERFACE);
-	  else if (ctx->current_node->type == G_IR_NODE_OBJECT)
-	    state_switch (ctx, STATE_CLASS);
-	  else if (ctx->current_node->type == G_IR_NODE_BOXED)
-	    state_switch (ctx, STATE_BOXED);
-	  else if (ctx->current_node->type == G_IR_NODE_STRUCT)
-	    state_switch (ctx, STATE_STRUCT);
-	  else if (ctx->current_node->type == G_IR_NODE_UNION)
-	    state_switch (ctx, STATE_UNION);
-	  else
-	    {
-	      int line_number, char_number;
-	      g_markup_parse_context_get_position (context, &line_number, &char_number);
-	      g_set_error (error,
-			   G_MARKUP_ERROR,
-			   G_MARKUP_ERROR_INVALID_CONTENT,
-			   "Unexpected end tag '%s' on line %d char %d",
-			   element_name,
-			   line_number, char_number);
-	    }
-	}
+      {
+ 	gboolean current_is_toplevel;
+	GList *last = g_list_last (ctx->current_module->entries);
+	
+	current_is_toplevel = ctx->current_node == last->data;	
+
+	if (current_is_toplevel)
+	  {
+	    ctx->current_node = NULL;
+	    state_switch (ctx, STATE_NAMESPACE);
+	  }
+	else 
+	  { 
+	    ctx->current_node = g_list_last (ctx->current_module->entries)->data;
+	    if (ctx->current_node->type == G_IR_NODE_INTERFACE)
+	      state_switch (ctx, STATE_INTERFACE);
+	    else if (ctx->current_node->type == G_IR_NODE_OBJECT) 
+	      state_switch (ctx, STATE_CLASS);
+	    else if (ctx->current_node->type == G_IR_NODE_BOXED)
+	      state_switch (ctx, STATE_BOXED);
+	    else if (ctx->current_node->type == G_IR_NODE_STRUCT)
+	      state_switch (ctx, STATE_STRUCT);
+	    else if (ctx->current_node->type == G_IR_NODE_UNION)
+	      state_switch (ctx, STATE_UNION);
+	    else
+	      {
+		int line_number, char_number;
+		g_markup_parse_context_get_position (context, &line_number, &char_number);
+		g_set_error (error,
+			     G_MARKUP_ERROR,
+			     G_MARKUP_ERROR_INVALID_CONTENT,
+			     "Unexpected end tag '%s' on line %d char %d",
+			     element_name,
+			     line_number, char_number);
+	      }
+	  }
+      }
       break;
 
     case STATE_CLASS_FIELD:
@@ -2654,7 +2696,8 @@
 	}
       break;
     case STATE_TYPE:
-      if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0))
+      if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
+	  (strcmp ("varargs", element_name) == 0))
 	{
 	  end_type (ctx);
 	  break;
@@ -2700,6 +2743,69 @@
   cleanup
 };
 
+static GList *
+post_filter_varargs_functions (GList *list)
+{
+  GList *iter;
+
+  iter = list;
+  while (iter)
+    {
+      GList *link = iter;
+      GIrNode *node = iter->data;
+
+      iter = iter->next;
+
+      if (node->type == G_IR_NODE_FUNCTION)
+	{
+	  if (((GIrNodeFunction*)node)->is_varargs)
+	    {
+	      g_printerr ("deleting varargs function\n");
+	      list = g_list_delete_link (list, link);
+	    }
+	}
+    }
+  return list;
+}
+
+static void
+post_filter (GIrModule *module)
+{
+  GList *iter;
+
+  module->entries = post_filter_varargs_functions (module->entries);
+  iter = module->entries;
+  while (iter)
+    {
+      GList *link = iter;
+      GIrNode *node = iter->data;
+
+      iter = iter->next;
+      
+      if (node->type == G_IR_NODE_OBJECT || 
+	  node->type == G_IR_NODE_INTERFACE) 
+	{
+	  GIrNodeInterface *iface = (GIrNodeInterface*)node;
+	  iface->members = post_filter_varargs_functions (iface->members);
+	}
+      else if (node->type == G_IR_NODE_BOXED)
+	{
+	  GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
+	  boxed->members = post_filter_varargs_functions (boxed->members);
+	}
+      else if (node->type == G_IR_NODE_STRUCT)
+	{
+	  GIrNodeStruct *iface = (GIrNodeStruct*)node;
+	  iface->members = post_filter_varargs_functions (iface->members);
+	}
+      else if (node->type == G_IR_NODE_UNION)
+	{
+	  GIrNodeUnion *iface = (GIrNodeUnion*)node;
+	  iface->members = post_filter_varargs_functions (iface->members);
+	}
+    }
+}
+
 GList * 
 g_ir_parse_string (const gchar  *namespace,
 		   const gchar *const *includes,
@@ -2753,6 +2859,7 @@
   gchar *buffer;
   gsize length;
   GList *modules;
+  GList *iter;
   const char *slash;
   char *namespace;
 
@@ -2779,6 +2886,11 @@
   
   modules = g_ir_parse_string (namespace, includes, buffer, length, error);
 
+  for (iter = modules; iter; iter = iter->next) 
+    {
+      post_filter ((GIrModule*)iter->data);
+    }
+
   g_free (namespace);
 
   g_free (buffer);

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Thu Oct  2 14:07:38 2008
@@ -169,6 +169,12 @@
         self.resolved = False
 
 
+class Varargs(Type):
+
+    def __init__(self):
+        Type.__init__(self, '<varargs>')
+
+
 class Array(Type):
 
     def __init__(self, ctype, element_type):

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Thu Oct  2 14:07:38 2008
@@ -23,7 +23,7 @@
 import os
 
 from .ast import (Callback, Class, Enum, Function, Interface, Member,
-                  Array, Struct, Alias, Union, List, Map)
+                  Array, Struct, Alias, Union, List, Map, Varargs)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
                       GLibFlags, GLibObject, GLibInterface)
 from .xmlwriter import XMLWriter
@@ -152,6 +152,10 @@
         else:
             typename = ntype.name
             type_cname = ntype.ctype
+        if isinstance(ntype, Varargs):
+            with self.tagcontext('varargs', []):
+                pass
+            return
         if isinstance(ntype, Array):
             attrs = []
             if not ntype.zeroterminated:

Modified: trunk/giscanner/scannerparser.y
==============================================================================
--- trunk/giscanner/scannerparser.y	(original)
+++ trunk/giscanner/scannerparser.y	Thu Oct  2 14:07:38 2008
@@ -100,7 +100,6 @@
 %type <list> enumerator_list
 %type <list> identifier_list
 %type <list> init_declarator_list
-%type <list> parameter_type_list
 %type <list> parameter_list
 %type <list> struct_declaration
 %type <list> struct_declaration_list
@@ -904,7 +903,7 @@
 		$$ = $1;
 		gi_source_symbol_merge_type ($$, gi_source_array_new ());
 	  }
-	| direct_declarator '(' parameter_type_list ')'
+	| direct_declarator '(' parameter_list ')'
 	  {
 		GISourceType *func = gi_source_function_new ();
 		// ignore (void) parameter list
@@ -958,11 +957,6 @@
 	  }
 	;
 
-parameter_type_list
-	: parameter_list
-	| parameter_list ',' ELLIPSIS
-	;
-
 parameter_list
 	: parameter_declaration
 	  {
@@ -990,6 +984,10 @@
 		$$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
 		$$->base_type = $1;
 	  }
+	| ELLIPSIS
+	  {
+		$$ = gi_source_symbol_new (CSYMBOL_TYPE_ELLIPSIS);
+	  }
 	;
 
 identifier_list
@@ -1057,7 +1055,7 @@
 		$$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
 		gi_source_symbol_merge_type ($$, func);
 	  }
-	| '(' parameter_type_list ')'
+	| '(' parameter_list ')'
 	  {
 		GISourceType *func = gi_source_function_new ();
 		// ignore (void) parameter list
@@ -1073,7 +1071,7 @@
 		$$ = $1;
 		gi_source_symbol_merge_type ($$, func);
 	  }
-	| direct_abstract_declarator '(' parameter_type_list ')'
+	| direct_abstract_declarator '(' parameter_list ')'
 	  {
 		GISourceType *func = gi_source_function_new ();
 		// ignore (void) parameter list

Modified: trunk/giscanner/sourcescanner.h
==============================================================================
--- trunk/giscanner/sourcescanner.h	(original)
+++ trunk/giscanner/sourcescanner.h	Thu Oct  2 14:07:38 2008
@@ -36,6 +36,7 @@
 typedef enum
 {
   CSYMBOL_TYPE_INVALID,
+  CSYMBOL_TYPE_ELLIPSIS,
   CSYMBOL_TYPE_CONST,
   CSYMBOL_TYPE_OBJECT,
   CSYMBOL_TYPE_FUNCTION,

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Thu Oct  2 14:07:38 2008
@@ -25,6 +25,7 @@
 from . import _giscanner
 
 (CSYMBOL_TYPE_INVALID,
+ CSYMBOL_TYPE_ELLIPSIS,
  CSYMBOL_TYPE_CONST,
  CSYMBOL_TYPE_OBJECT,
  CSYMBOL_TYPE_FUNCTION,
@@ -32,7 +33,7 @@
  CSYMBOL_TYPE_UNION,
  CSYMBOL_TYPE_ENUM,
  CSYMBOL_TYPE_TYPEDEF,
- CSYMBOL_TYPE_MEMBER) = range(9)
+ CSYMBOL_TYPE_MEMBER) = range(10)
 
 (CTYPE_INVALID,
  CTYPE_VOID,
@@ -72,6 +73,7 @@
 def symbol_type_name(symbol_type):
     return {
         CSYMBOL_TYPE_INVALID: 'invalid',
+        CSYMBOL_TYPE_ELLIPSIS: 'ellipsis',
         CSYMBOL_TYPE_CONST: 'const',
         CSYMBOL_TYPE_OBJECT: 'object',
         CSYMBOL_TYPE_FUNCTION: 'function',

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Thu Oct  2 14:07:38 2008
@@ -23,8 +23,8 @@
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
                            Parameter, Return, Array, Struct, Field,
                            Type, Alias, Interface, Class, Node, Union,
-                           List, Map, type_name_from_ctype, type_names,
-                           default_array_types)
+                           List, Map, Varargs, type_name_from_ctype,
+                           type_names, default_array_types)
 from giscanner.config import DATADIR
 from .glibast import GLibBoxed
 from giscanner.sourcescanner import (
@@ -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_MEMBER, CSYMBOL_TYPE_ELLIPSIS)
 from .odict import odict
 from .utils import strip_common_prefix, to_underscores
 
@@ -318,7 +318,7 @@
     def _create_type(self, source_type, options=[]):
         ctype = self._create_source_type(source_type)
         if ctype == 'va_list':
-            raise SkipError
+            raise SkipError()
         # FIXME: FILE* should not be skipped, it should be handled
         #        properly instead
         elif ctype == 'FILE*':
@@ -353,7 +353,10 @@
         return Type(resolved_type_name, ctype)
 
     def _create_parameter(self, symbol, options):
-        ptype = self._create_type(symbol.base_type, options)
+        if symbol.type == CSYMBOL_TYPE_ELLIPSIS:
+            ptype = Varargs()
+        else:
+            ptype = self._create_type(symbol.base_type, options)
         param = Parameter(symbol.ident, ptype)
         for option in options:
             if option in ['in-out', 'inout']:

Modified: trunk/tests/scanner/foo-expected.gir
==============================================================================
--- trunk/tests/scanner/foo-expected.gir	(original)
+++ trunk/tests/scanner/foo-expected.gir	Thu Oct  2 14:07:38 2008
@@ -77,6 +77,23 @@
           </parameter>
         </parameters>
       </method>
+      <method name="take_all" c:identifier="foo_object_take_all">
+        <return-value>
+          <type name="none" c:type="void"/>
+        </return-value>
+        <parameters>
+          <parameter name="object">
+            <type name="Object" c:type="FooObject*"/>
+          </parameter>
+          <parameter name="x">
+            <type name="int" c:type="int"/>
+          </parameter>
+          <parameter>
+            <varargs>
+            </varargs>
+          </parameter>
+        </parameters>
+      </method>
       <method name="with_tdef" c:identifier="foo_object_with_tdef">
         <return-value>
           <type name="none" c:type="void"/>

Modified: trunk/tests/scanner/foo.c
==============================================================================
--- trunk/tests/scanner/foo.c	(original)
+++ trunk/tests/scanner/foo.c	Thu Oct  2 14:07:38 2008
@@ -137,6 +137,12 @@
 
 }
 
+void                  
+foo_object_take_all (FooObject *object, int x, ...)
+{
+
+}
+
 void
 foo_do_foo (FooInterface *self)
 {

Modified: trunk/tests/scanner/foo.h
==============================================================================
--- trunk/tests/scanner/foo.h	(original)
+++ trunk/tests/scanner/foo.h	Thu Oct  2 14:07:38 2008
@@ -53,6 +53,8 @@
 
 void                  foo_object_various           (FooObject *object, void *data, GType some_type);
 
+void                  foo_object_take_all          (FooObject *object, int x, ...);
+
 /* A random typedef */
 typedef GSList FooList;
 



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