[gobject-introspection] Support glib-mkenums comment /*< flags >*/



commit d85dbebee2c565a911c79dd199f0e70020f2918a
Author: Andreas Rottmann <a rottmann gmx at>
Date:   Tue Dec 7 00:18:15 2010 +0100

    Support glib-mkenums comment /*< flags >*/
    
    - Modify the lexer to consider all "trigraph" comments specially, and
      parse them for "flags" as well as "private" and "public" (which were
      previously hardcoded).  This change allows for future support of
      multiple annotations inside a single trigraph comment.
    
    - Change the parser to consider the additional field "flags" set by
      the lexer when constructing enums.
    
    - Add a test case for the "flags" trigraph comment to the scanner
      annotation tests.
    
    See <https://bugzilla.gnome.org/show_bug.cgi?id=631530>.

 gir/glib-2.0.c                            |    4 ---
 giscanner/scannerlexer.l                  |   31 +++++++++++++++++++++++++++-
 giscanner/scannerparser.y                 |   31 +++++++++++++++-------------
 giscanner/sourcescanner.h                 |    1 +
 tests/scanner/Annotation-1.0-expected.gir |    4 +++
 tests/scanner/annotation.h                |    6 +++++
 6 files changed, 57 insertions(+), 20 deletions(-)
---
diff --git a/gir/glib-2.0.c b/gir/glib-2.0.c
index 1025d3d..493aaa1 100644
--- a/gir/glib-2.0.c
+++ b/gir/glib-2.0.c
@@ -84,10 +84,6 @@
  */
 
 /**
- * GIOCondition: (type bitfield)
- **/
-
-/**
  * GSourceFunc:
  * @data: (closure data):
  */
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l
index e06bc85..6a40398 100644
--- a/giscanner/scannerlexer.l
+++ b/giscanner/scannerlexer.l
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 1997 Sandro Sigala  <ssigala globalnet it>
  * Copyright (c) 2007-2008 Jürg Billeter  <j bitron ch>
+ * Copyright (c) 2010 Andreas Rottmann <a rottmann gmx at>
  *
  * All rights reserved.
  *
@@ -46,6 +47,7 @@ extern int yylex (GISourceScanner *scanner);
 #define YY_DECL int yylex (GISourceScanner *scanner)
 static int yywrap (void);
 static void parse_comment (GISourceScanner *scanner);
+static void parse_trigraph (GISourceScanner *scanner);
 static void process_linemarks (GISourceScanner *scanner);
 static int check_identifier (GISourceScanner *scanner, const char *);
 static int parse_ignored_macro (void);
@@ -72,8 +74,7 @@ stringtext				([^\\\"])|(\\.)
 [\t\f\v\r ]+				{ /* Ignore whitespace. */ }
 
 "/*"					{ parse_comment(scanner); }
-"/*"[\t ]*<[\t ]*"private"[\t ]*>" */"  { scanner->private = TRUE; }
-"/*"[\t ]*<[\t ]*"public"[\t ]*>" */"   { scanner->private = FALSE; }
+"/*"[\t ]?<[\t ,=A-Za-z0-9_]+>[\t ]?"*/" { parse_trigraph(scanner); }
 "//".*					{ }
 
 "#define "[a-zA-Z_][a-zA-Z_0-9]*"("	{ yyless (yyleng - 1); return FUNCTION_MACRO; }
@@ -330,3 +331,29 @@ parse_ignored_macro (void)
 
 	return TRUE;
 }
+
+static void
+parse_trigraph (GISourceScanner *scanner)
+{
+	char **items;
+	char *start, *end;
+	int i;
+
+	start = g_strstr_len (yytext, yyleng, "<");
+	g_assert (start != NULL);
+	end = g_strstr_len (yytext, yyleng, ">");
+	g_assert (end != NULL);
+	*end = '\0';
+	items = g_strsplit (start + 1, ",", 0);
+	for (i = 0; items[i] != NULL; i++) {
+		char *item = items[i];
+		g_strstrip (item);
+		if (strcmp (item, "public") == 0)
+			scanner->private = FALSE;
+		else if (strcmp (item, "private") == 0)
+			scanner->private = TRUE;
+		else if (strcmp (item, "flags") == 0)
+			scanner->flags = TRUE;
+	}
+	g_strfreev (items);
+}
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y
index bac2098..fc4a285 100644
--- a/giscanner/scannerparser.y
+++ b/giscanner/scannerparser.y
@@ -910,45 +910,48 @@ struct_declarator
 	;
 
 enum_specifier
-	: ENUM identifier_or_typedef_name '{' enumerator_list '}'
+	: enum_keyword identifier_or_typedef_name '{' enumerator_list '}'
 	  {
-                scanner->private = FALSE;
 		$$ = gi_source_enum_new ($2);
 		$$->child_list = $4;
-		$$->is_bitfield = is_bitfield;
+		$$->is_bitfield = is_bitfield || scanner->flags;
 		last_enum_value = -1;
 	  }
-	| ENUM '{' enumerator_list '}'
+	| enum_keyword '{' enumerator_list '}'
 	  {
-                scanner->private = FALSE;
 		$$ = gi_source_enum_new (NULL);
 		$$->child_list = $3;
-		$$->is_bitfield = is_bitfield;
+		$$->is_bitfield = is_bitfield || scanner->flags;
 		last_enum_value = -1;
 	  }
-	| ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
+	| enum_keyword identifier_or_typedef_name '{' enumerator_list ',' '}'
 	  {
-                scanner->private = FALSE;
 		$$ = gi_source_enum_new ($2);
 		$$->child_list = $4;
-		$$->is_bitfield = is_bitfield;
+		$$->is_bitfield = is_bitfield || scanner->flags;
 		last_enum_value = -1;
 	  }
-	| ENUM '{' enumerator_list ',' '}'
+	| enum_keyword '{' enumerator_list ',' '}'
 	  {
-                scanner->private = FALSE;
 		$$ = gi_source_enum_new (NULL);
 		$$->child_list = $3;
-		$$->is_bitfield = is_bitfield;
+		$$->is_bitfield = is_bitfield || scanner->flags;
 		last_enum_value = -1;
 	  }
-	| ENUM identifier_or_typedef_name
+	| enum_keyword identifier_or_typedef_name
 	  {
-                scanner->private = FALSE;
 		$$ = gi_source_enum_new ($2);
 	  }
 	;
 
+enum_keyword
+        : ENUM
+          {
+                scanner->flags = FALSE;
+                scanner->private = FALSE;
+          }
+        ;
+
 enumerator_list
 	:
 	  {
diff --git a/giscanner/sourcescanner.h b/giscanner/sourcescanner.h
index b67f037..1ed9e9b 100644
--- a/giscanner/sourcescanner.h
+++ b/giscanner/sourcescanner.h
@@ -108,6 +108,7 @@ struct _GISourceScanner
   char *current_filename;
   gboolean macro_scan;
   gboolean private; /* set by gtk-doc comment <private>/<public> */
+  gboolean flags; /* set by gtk-doc comment <flags> */
   GSList *symbols;
   GList *filenames;
   GSList *comments; /* _GIComment */
diff --git a/tests/scanner/Annotation-1.0-expected.gir b/tests/scanner/Annotation-1.0-expected.gir
index 6dcb23c..330ad23 100644
--- a/tests/scanner/Annotation-1.0-expected.gir
+++ b/tests/scanner/Annotation-1.0-expected.gir
@@ -15,6 +15,10 @@ and/or use gtk-doc annotations.  -->
              shared-library="libannotation.so"
              c:identifier-prefixes="Annotation"
              c:symbol-prefixes="annotation">
+    <bitfield name="Bitfield" c:type="AnnotationBitfield">
+      <member name="foo" value="1" c:identifier="ANN_FLAG_FOO"/>
+      <member name="bar" value="2" c:identifier="ANN_FLAG_BAR"/>
+    </bitfield>
     <callback name="Callback" c:type="AnnotationCallback">
       <doc xml:whitespace="preserve">This is a callback.</doc>
       <return-value transfer-ownership="none">
diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h
index e315af5..b58aa81 100644
--- a/tests/scanner/annotation.h
+++ b/tests/scanner/annotation.h
@@ -3,6 +3,12 @@
 
 #include <glib-object.h>
 
+typedef enum /*< flags,prefix=ANN >*/
+{
+  ANN_FLAG_FOO = 1,
+  ANN_FLAG_BAR = 2
+} AnnotationBitfield;
+
 /**
  * AnnotationCallback:
  * @in: (in) (transfer none): array of ints



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