diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gidlnode.c | 13 | ||||
-rw-r--r-- | tools/gidlnode.h | 1 | ||||
-rw-r--r-- | tools/gidlwriter.c | 28 | ||||
-rw-r--r-- | tools/scanner.c | 41 | ||||
-rw-r--r-- | tools/scanner.h | 7 | ||||
-rw-r--r-- | tools/scannerlexer.l | 111 | ||||
-rw-r--r-- | tools/scannerparser.y | 4 |
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; } |