gobject-introspection r140 - in trunk: . tests/parser tools



Author: johan
Date: Mon Mar 10 22:08:49 2008
New Revision: 140
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=140&view=rev

Log:
2008-03-10  Philip Van Hoof  <me pvanhoof be>

        reviewed and extensively tested by Johan

        * tests/parser/Foo-expected.gidl:
        * tests/parser/foo-object.h:
        * tests/parser/foo.c:
        * tools/gidlnode.c:
        * tools/gidlnode.h:
        * tools/gidlwriter.c:
        * tools/scanner.c:
        * tools/scanner.h:
        * tools/scannerlexer.l:
        * tools/scannerparser.y:

        Add support for scanning for gtk-doc comments inside
        C source files. Add tests



Modified:
   trunk/ChangeLog
   trunk/tests/parser/Foo-expected.gidl
   trunk/tests/parser/foo-object.h
   trunk/tests/parser/foo.c
   trunk/tools/gidlnode.c
   trunk/tools/gidlnode.h
   trunk/tools/gidlwriter.c
   trunk/tools/scanner.c
   trunk/tools/scanner.h
   trunk/tools/scannerlexer.l
   trunk/tools/scannerparser.y

Modified: trunk/tests/parser/Foo-expected.gidl
==============================================================================
--- trunk/tests/parser/Foo-expected.gidl	(original)
+++ trunk/tests/parser/Foo-expected.gidl	Mon Mar 10 22:08:49 2008
@@ -46,6 +46,13 @@
 			<constructor name="new" symbol="foo_object_new">
 				<return-type type="FooObject*"/>
 			</constructor>
+			<method name="out" symbol="foo_object_out">
+				<return-type type="gint"/>
+				<parameters>
+					<parameter name="object" type="FooObject*"/>
+					<parameter name="outarg" type="int*" null-ok="1"/>
+				</parameters>
+			</method>
 		</object>
 		<object name="FooSubobject" parent="FooObject" type-name="FooSubobject" get-type="foo_subobject_get_type">
 			<constructor name="new" symbol="foo_subobject_new">

Modified: trunk/tests/parser/foo-object.h
==============================================================================
--- trunk/tests/parser/foo-object.h	(original)
+++ trunk/tests/parser/foo-object.h	Mon Mar 10 22:08:49 2008
@@ -47,6 +47,8 @@
 GType                 foo_object_get_type          (void) G_GNUC_CONST;
 FooObject*            foo_object_new               ();
 gint                  foo_object_method            (FooObject *object);
+gint                  foo_object_out               (FooObject *object,
+						    int       *outarg);
 
 struct _FooSubobject
 {

Modified: trunk/tests/parser/foo.c
==============================================================================
--- trunk/tests/parser/foo.c	(original)
+++ trunk/tests/parser/foo.c	Mon Mar 10 22:08:49 2008
@@ -44,6 +44,23 @@
 
 }
 
+gint
+foo_object_method (FooObject *object)
+{
+
+}
+
+/**
+ * foo_object_out:
+ * This is a test for out arguments
+ * @outarg: (null-ok): This is an argument test
+ */
+gint
+foo_object_out (FooObject *object, int *outarg)
+{
+
+}
+
 G_DEFINE_TYPE (FooSubobject, foo_subobject, FOO_TYPE_OBJECT);
 
 static void

Modified: trunk/tools/gidlnode.c
==============================================================================
--- trunk/tools/gidlnode.c	(original)
+++ trunk/tools/gidlnode.c	Mon Mar 10 22:08:49 2008
@@ -396,6 +396,19 @@
     }
 }
 
+const gchar *
+g_idl_node_param_direction_string (GIdlNodeParam * node)
+{
+  if (node->out)
+    {
+      if (node->in)
+	return "in-out";
+      else
+	return "out";
+    }
+  return "in";
+}
+
 static gint64
 parse_int_value (const gchar *str)
 {

Modified: trunk/tools/gidlnode.h
==============================================================================
--- trunk/tools/gidlnode.h	(original)
+++ trunk/tools/gidlnode.h	Mon Mar 10 22:08:49 2008
@@ -314,6 +314,7 @@
 void      g_idl_node_add_member      (GIdlNode         *node,
 				      GIdlNodeFunction *member);
 
+const gchar * g_idl_node_param_direction_string (GIdlNodeParam * node);
 
 G_END_DECLS
 

Modified: trunk/tools/gidlwriter.c
==============================================================================
--- trunk/tools/gidlwriter.c	(original)
+++ trunk/tools/gidlwriter.c	Mon Mar 10 22:08:49 2008
@@ -163,11 +163,29 @@
       for (l = node->parameters; l != NULL; l = l->next)
 	{
 	  GIdlNodeParam *param = l->data;
-	  markup =
-	    g_markup_printf_escaped ("<parameter name=\"%s\" type=\"%s\"/>\n",
-				     param->node.name, param->type->unparsed);
-	  g_writer_write (writer, markup);
-	  g_free (markup);
+	  const gchar *direction = g_idl_node_param_direction_string (param);
+	  
+	  markup_s = g_string_new ("<parameter");
+
+	  g_string_append_printf (markup_s, " name=\"%s\"", param->node.name);
+
+	  g_string_append (markup_s,
+			   g_markup_printf_escaped (" type=\"%s\"",
+						    param->type->unparsed));
+
+	  if (param->null_ok)
+	    g_string_append (markup_s,
+			     g_markup_printf_escaped (" null-ok=\"1\""));
+	  
+	  if (strcmp (direction, "in") != 0)
+	    g_string_append (markup_s,
+			     g_markup_printf_escaped (" direction=\"%s\"",
+						      direction));
+
+	  g_string_append (markup_s, "/>\n");
+
+	  g_writer_write (writer, markup_s->str);
+	  g_string_free (markup_s, TRUE);
 	}
       g_writer_write_unindent (writer, "</parameters>\n");
     }

Modified: trunk/tools/scanner.c
==============================================================================
--- trunk/tools/scanner.c	(original)
+++ trunk/tools/scanner.c	Mon Mar 10 22:08:49 2008
@@ -61,6 +61,7 @@
   igenerator->type_by_lower_case_prefix =
     g_hash_table_new (g_str_hash, g_str_equal);
   igenerator->symbols = g_hash_table_new (g_str_hash, g_str_equal);
+  igenerator->directives_map = g_hash_table_new (g_str_hash, g_str_equal);
 
   return igenerator;
 }
@@ -80,6 +81,8 @@
   g_hash_table_destroy (generator->type_by_lower_case_prefix);
   g_hash_table_destroy (generator->symbols);
   g_list_foreach (generator->filenames, (GFunc)g_free, NULL);
+  g_hash_table_destroy (generator->directives_map);
+
   g_list_free (generator->filenames);
 #if 0
   g_list_foreach (generator->symbol_list, (GFunc)csymbol_free, NULL);
@@ -596,8 +599,9 @@
   char *last_underscore;
   GList *param_l;
   int i;
-  GSList *l;
-
+  GList *l;
+  GSList *j, *directives;
+  
   func = (GIdlNodeFunction *) g_idl_node_new (G_IDL_NODE_FUNCTION);
   
   /* check whether this is a type method */
@@ -668,6 +672,8 @@
   func->result = (GIdlNodeParam *) g_idl_node_new (G_IDL_NODE_PARAM);
   func->result->type = create_node_from_ctype (sym->base_type->base_type);
 
+  directives = g_hash_table_lookup (igenerator->directives_map, func->symbol);
+
   for (param_l = sym->base_type->child_list, i = 1; param_l != NULL;
        param_l = param_l->next, i++)
     {
@@ -677,6 +683,29 @@
       param = (GIdlNodeParam *) g_idl_node_new (G_IDL_NODE_PARAM);
       param->type = create_node_from_ctype (param_sym->base_type);
 
+      for (j = directives; j; j = j->next) 
+       {
+          CDirective *directive = j->data;
+
+          if (g_ascii_strcasecmp (param_sym->ident, directive->name) == 0) 
+	    {
+	      
+	      GSList *options;
+
+              for (options = directive->options; options; options = options->next)
+               {
+                  gchar *stringy_data = options->data;
+
+                  if (g_ascii_strcasecmp (stringy_data, "null-ok") == 0)
+                      param->null_ok = TRUE;
+                  if (g_ascii_strcasecmp (stringy_data, "in") == 0)
+                      param->in = TRUE;
+                  if (g_ascii_strcasecmp (stringy_data, "out") == 0)
+                      param->out = TRUE;
+               }
+          }
+       }
+
       if (param_sym->ident == NULL)
 	param->node.name = g_strdup_printf ("p%d", i);
       else
@@ -685,9 +714,13 @@
       func->parameters = g_list_append (func->parameters, param);
     }
 
-  for (l = sym->directives; l; l = l->next)
+ /* By removing it here, we mark it as handled, memory will be freed by
+  * the cleanup for sym */
+  g_hash_table_remove (igenerator->directives_map, func->symbol);
+
+  for (j = sym->directives; j; j = j->next)
     {
-      CDirective *directive = (CDirective*)l->data;
+      CDirective *directive = (CDirective*)j->data;
 
       if (!strcmp (directive->name, "deprecated"))
 	func->deprecated = TRUE;

Modified: trunk/tools/scanner.h
==============================================================================
--- trunk/tools/scanner.h	(original)
+++ trunk/tools/scanner.h	Mon Mar 10 22:08:49 2008
@@ -55,6 +55,9 @@
 
   GHashTable *symbols; /* typename -> module.name */
 
+  /* symbol -> GList of CDirective */
+  GHashTable *directives_map;
+  
   /* scanner variables */
   gboolean macro_scan;
   GSList *directives; /* list of CDirective for the current symbol */
@@ -146,13 +149,15 @@
 struct _CDirective {
   char *name;
   char *value;
+  GSList *options;
 };
 
 CSymbol *    csymbol_new               (CSymbolType  type);
 gboolean     csymbol_get_const_boolean (CSymbol     *symbol);
 void         csymbol_free              (CSymbol     *symbol);
 CDirective * cdirective_new            (const gchar *name,
-					const gchar *value);
+					const gchar *value,
+					GSList *options);
 void         cdirective_free           (CDirective  *directive);
 
 gboolean g_igenerator_lex_filename  (GIGenerator *igenerator,

Modified: trunk/tools/scannerlexer.l
==============================================================================
--- trunk/tools/scannerlexer.l	(original)
+++ trunk/tools/scannerlexer.l	Mon Mar 10 22:08:49 2008
@@ -178,57 +178,95 @@
   return 1;
 }
 
-static void parse_gtkdoc (GIGenerator *igenerator, int *c1, int *c2)
+static void parse_gtkdoc (GIGenerator *igenerator, gchar *symbol, int *c1, int *c2)
 {
   gboolean isline = FALSE;
   gchar line[256];
   int i;
   gchar **parts;
   CDirective *directive;
-  char *name, *value;
+  char *name,*value;
+  GSList *directives;
+  GSList *options = NULL;
 
   i = 0;
-  do {
+  do 
+    {
       *c1 = *c2;
       if (*c1 == '\n')
-	{
-	  isline = TRUE;
-	  break;
-	}
+        {
+          isline = TRUE;
+          break;
+        }
       if (i >= 256)
-	break;
+        break;
       line[i++] = *c1;
       *c2 = input();
-
-  } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/'));
+    } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/'));
   
   if (!isline)
     return;
 
   line[i] = '\0';
 
-  parts = g_strsplit (line, ": ", 2);
+  parts = g_strsplit (line, ": ", 3);
 
-  if (g_strv_length (parts) == 2)
+  if (g_strv_length (parts) >= 2)
     {
       name = parts[0];
-      value = parts[1];
+
+      if (g_strv_length (parts) == 3) 
+        {
+          char *ptr = parts[1];
+          GString *current = NULL;
+          gboolean open = FALSE;
+
+          current = g_string_new ("");
+          value = parts[2];
+
+          while (*ptr++) 
+            {
+              if (*ptr != ')')
+                g_string_append_c (current, *ptr);
+              else if (*ptr == ')')
+                options = g_slist_prepend (options, g_strdup (current->str));
+            }
+          g_string_free (current, TRUE);
+        } 
+      else
+        value = parts[1];
     }
   else /* parts == 1 */
     {
       name = parts[0];
       value = NULL;
     }
-  
-  directive = cdirective_new (name, value);
-  igenerator->directives = g_slist_prepend (igenerator->directives,
-					    directive);
+ 
+  directive = cdirective_new (name, value, options);
+ 
+  if (symbol == NULL)
+    {
+      igenerator->directives = g_slist_prepend (igenerator->directives,
+						directive);
+    }
+  else
+    {
+      directives = g_hash_table_lookup (igenerator->directives_map, symbol);
+      directives = g_slist_prepend (directives, directive);
 
+      g_hash_table_replace (igenerator->directives_map, 
+			    g_strdup (symbol), directives);
+    }
+  
   g_strfreev (parts);
+  
 }
+    
 
 static void parse_comment (GIGenerator *igenerator)
 {
+  GString *symbol = NULL;
+  gboolean startofline = FALSE, have_symbol = FALSE, start1 = FALSE, start_symbol = FALSE;
   int c1, c2;
   
   c1 = input();
@@ -236,18 +274,43 @@
 
   while (c2 != EOF && !(c1 == '*' && c2 == '/'))
     {
-      if (c1 == '\n')
-	++lineno;
+      if (c1 == ':')
+        have_symbol = TRUE;
+      else if (c1 == '\n')
+         start1 = TRUE;
+      else if (c1 == '*' && start1)
+         start_symbol = TRUE;
+      else if (!have_symbol && start_symbol) 
+        {
+          if (!symbol)
+            symbol = g_string_new ("");
+          if (c1 != ' ')
+            g_string_append_c (symbol, c1);
+        }
+
+      if (c1 == '\n') 
+        {
+          ++lineno;
+          startofline = TRUE;
+        }
+
       c1 = c2;
       c2 = input();
 
-      if (c1 == ' ' && c2 == '@')
-	{
-	  c1 = c2;
-	  c2 = input();
-	  parse_gtkdoc (igenerator, &c1, &c2);
+      if ((c1 != '*' && c1 != ' '))
+          startofline = FALSE;
+
+      if (startofline && c1 == ' ' && c2 == '@')
+        {
+           c1 = c2;
+           c2 = input();
+	   parse_gtkdoc (igenerator, symbol ? symbol->str : NULL, &c1, &c2);
+	   
 	}
     }
+  if (symbol)
+    g_string_free (symbol, TRUE);
+  
 }
 
 static int check_identifier (GIGenerator *igenerator, const char *s)

Modified: trunk/tools/scannerparser.y
==============================================================================
--- trunk/tools/scannerparser.y	(original)
+++ trunk/tools/scannerparser.y	Mon Mar 10 22:08:49 2008
@@ -166,13 +166,15 @@
 
 CDirective *
 cdirective_new (const gchar *name,
-		const gchar *value)
+		const gchar *value,
+		GSList *options)
 {
   CDirective *directive;
     
   directive = g_slice_new (CDirective);
   directive->name = g_strdup (name);
   directive->value = g_strdup (value);
+  directive->options = options;
   return directive;
 }
 



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