summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorPhilip Van Hoof <me@pvanhoof.be>2008-03-10 22:08:49 +0000
committerJohan Dahlin <johan@src.gnome.org>2008-03-10 22:08:49 +0000
commitb328ba7044dbfa26e01a85c7f0d11ba1a87a804e (patch)
tree3b3ff3705298681a29567bc78322e074e4875c3b /tools
parent6015ef1e36a338a2e96b986aae1b2b32a7f3b427 (diff)
downloadgobject-introspection-b328ba7044dbfa26e01a85c7f0d11ba1a87a804e.tar.gz
reviewed and extensively tested by Johan
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 svn path=/trunk/; revision=140
Diffstat (limited to 'tools')
-rw-r--r--tools/gidlnode.c13
-rw-r--r--tools/gidlnode.h1
-rw-r--r--tools/gidlwriter.c28
-rw-r--r--tools/scanner.c41
-rw-r--r--tools/scanner.h7
-rw-r--r--tools/scannerlexer.l111
-rw-r--r--tools/scannerparser.y4
7 files changed, 170 insertions, 35 deletions
diff --git a/tools/gidlnode.c b/tools/gidlnode.c
index 96fd8de8..f6e5f435 100644
--- a/tools/gidlnode.c
+++ b/tools/gidlnode.c
@@ -396,6 +396,19 @@ g_idl_node_add_member (GIdlNode *node,
}
}
+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)
{
diff --git a/tools/gidlnode.h b/tools/gidlnode.h
index d0c52af9..3fd48901 100644
--- a/tools/gidlnode.h
+++ b/tools/gidlnode.h
@@ -314,6 +314,7 @@ gboolean g_idl_node_can_have_member (GIdlNode *node);
void g_idl_node_add_member (GIdlNode *node,
GIdlNodeFunction *member);
+const gchar * g_idl_node_param_direction_string (GIdlNodeParam * node);
G_END_DECLS
diff --git a/tools/gidlwriter.c b/tools/gidlwriter.c
index 5caac5e5..d36ee3e9 100644
--- a/tools/gidlwriter.c
+++ b/tools/gidlwriter.c
@@ -163,11 +163,29 @@ function_generate (GIdlWriter * writer, GIdlNodeFunction * node)
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");
}
diff --git a/tools/scanner.c b/tools/scanner.c
index 57f23632..9e3cb1a4 100644
--- a/tools/scanner.c
+++ b/tools/scanner.c
@@ -61,6 +61,7 @@ g_igenerator_new (const gchar *namespace,
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_igenerator_free (GIGenerator *generator)
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 @@ g_igenerator_process_function_symbol (GIGenerator * igenerator, CSymbol * sym)
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 @@ g_igenerator_process_function_symbol (GIGenerator * igenerator, CSymbol * sym)
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 @@ g_igenerator_process_function_symbol (GIGenerator * igenerator, CSymbol * sym)
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 @@ g_igenerator_process_function_symbol (GIGenerator * igenerator, CSymbol * sym)
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;
diff --git a/tools/scanner.h b/tools/scanner.h
index d9258519..277387ce 100644
--- a/tools/scanner.h
+++ b/tools/scanner.h
@@ -55,6 +55,9 @@ struct _GIGenerator
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 _CType
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,
diff --git a/tools/scannerlexer.l b/tools/scannerlexer.l
index 593c058c..f7dea412 100644
--- a/tools/scannerlexer.l
+++ b/tools/scannerlexer.l
@@ -178,57 +178,95 @@ static int yywrap (void)
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 @@ static void parse_comment (GIGenerator *igenerator)
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)
diff --git a/tools/scannerparser.y b/tools/scannerparser.y
index a0d75319..b4de11ac 100644
--- a/tools/scannerparser.y
+++ b/tools/scannerparser.y
@@ -166,13 +166,15 @@ csymbol_merge_type (CSymbol *symbol, CType *type)
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;
}