Support glib-mkenums comment /*< flags >*/
authorAndreas Rottmann <a.rottmann@gmx.at>
Mon, 6 Dec 2010 23:18:15 +0000 (00:18 +0100)
committerAndreas Rottmann <a.rottmann@gmx.at>
Mon, 6 Dec 2010 23:18:15 +0000 (00:18 +0100)
- 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
giscanner/scannerlexer.l
giscanner/scannerparser.y
giscanner/sourcescanner.h
tests/scanner/Annotation-1.0-expected.gir
tests/scanner/annotation.h

index 1025d3d59456e2cad9e00bb89add145aa2e36b5c..493aaa1b9eb4be2262c4f0f767bcbe4df4c4717a 100644 (file)
  * @argv: (array length=argc) (inout) (allow-none):
  */
 
-/**
- * GIOCondition: (type bitfield)
- **/
-
 /**
  * GSourceFunc:
  * @data: (closure data):
index e06bc85d0d0241cfd28090cbd92af2c7a4b0b8f9..6a4039840bc3878827a6f5c094f3cf57df70d499 100644 (file)
@@ -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);
+}
index bac2098007a422525f5722f326bca79d3ba4cdb0..fc4a2850187373669ca888beb200136e0fd489b8 100644 (file)
@@ -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
        :
          {
index b67f037b6483b8e648cb18ab462d43c6ca98247b..1ed9e9b7237c1529209a99c7a93ba2ae4df26882 100644 (file)
@@ -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 */
index 6dcb23c389386a5b13c832e61e9e16ac42ec79fa..330ad236865f61d3be4b3fd8786f8122a2b5606f 100644 (file)
@@ -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">
index e315af5bcedd751be72d73042f7013af4f753f05..b58aa814588ff40d9ec99b4efdff87f8db4bfd32 100644 (file)
@@ -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