X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/c9914e54f16c3315d47040f4cca2d3788228c504..refs/tags/v1.0.11:/src/parse.y diff --git a/src/parse.y b/src/parse.y index f29f9de..0bc9836 100644 --- a/src/parse.y +++ b/src/parse.y @@ -36,13 +36,15 @@ GList *nodes = NULL; static GList *class_nodes = NULL; Node *class = NULL; -char *chunk_size = NULL; +static char *chunk_size = NULL; +static char *bonobo_x_class = NULL; static GList *typestack = NULL; static GList *funcargs = NULL; static GList *checks = NULL; static int has_self = FALSE; static int vararg = FALSE; +static Method *last_added_method = NULL; /* destructor and initializer for variables */ static char *destructor = NULL; @@ -141,18 +143,18 @@ push_function(int scope, int method, char *oid, char *id, !(g_list_length(funcargs) == 1 && g_list_length(gtktypes) == 2 && strcmp(gtktypes->next->data, "NONE")==0)) { - print_error(TRUE, _("The number of GTK arguments and " - "function arguments for a signal " - "don't seem to match"), line_no); + error_print(GOB_WARN, line_no, + _("The number of GTK arguments and " + "function arguments for a signal " + "don't seem to match")); } if(g_list_length(gtktypes) > 2) { GList *li; for(li = gtktypes->next; li; li = li->next) { if(strcmp(li->data, "NONE")==0) { - print_error(FALSE, + error_print(GOB_ERROR, line_no, _("NONE can only appear in an " - "argument list by itself"), - line_no); + "argument list by itself")); } } } @@ -168,7 +170,10 @@ push_function(int scope, int method, char *oid, char *id, node = new_method(scope, method, type, oid, gtktypes, flags, id, funcargs, onerror, defreturn, c_cbuf, line_no, - ccode_line, vararg, method_unique_id++); + ccode_line, vararg, method_unique_id++, + FALSE); + + last_added_method = (Method *)node; if(cbuf) g_string_free(cbuf, @@ -252,7 +257,6 @@ static Variable * find_var_or_die(const char *id, int line) { GList *li; - char *s; for(li = class_nodes; li != NULL; li = li->next) { Variable *var; @@ -264,8 +268,7 @@ find_var_or_die(const char *id, int line) return var; } - s = g_strdup_printf(_("Variable %s not defined here"), id); - print_error(FALSE, s, line); + error_printf(GOB_ERROR, line, _("Variable %s not defined here"), id); g_assert_not_reached(); return NULL; @@ -290,6 +293,87 @@ set_return_value(char *type, char *val) return FALSE; } +static void +export_accessors (const char *var_name, + const char *get_cbuf, + int get_lineno, + const char *set_cbuf, + int set_lineno, + Type *type, + const char *gtktype, + int lineno) +{ + if (type == NULL) { + char *cast = g_strdup (get_cast (gtktype, FALSE)); + char *p = strchr (cast, ' '); + if (p != NULL) { + *p = '\0'; + p++; + } + /* leak, but we don't really care any more */ + type = (Type *)new_type (cast, + g_strdup (p), + NULL); + } + + if (get_cbuf != NULL) { + char *get_id = g_strdup_printf ("get_%s", var_name); + GString *get_cbuf_copy = g_string_new (get_cbuf); + char *tmp; + Node *node1 = new_type (g_strdup (type->name), + g_strdup (type->pointer), + g_strdup (type->postfix)); + Node *node3 = new_type (g_strdup (class->class.otype), + g_strdup ("*"), + NULL); + + tmp = g_strdup_printf ("\t%s%s ARG;\n", + type->name, + type->pointer ? type->pointer : ""); + get_cbuf_copy = g_string_prepend (get_cbuf_copy, tmp); + g_free (tmp); + + tmp = g_strdup_printf ("\n\t\treturn ARG;\n"); + get_cbuf_copy = g_string_append (get_cbuf_copy, tmp); + g_free (tmp); + + typestack = g_list_prepend (typestack, node1); + typestack = g_list_prepend (typestack, node3); + + push_funcarg ("self", FALSE); + + push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL, + get_id, get_cbuf_copy, get_lineno, + lineno, FALSE, NULL); + } + + if (set_cbuf != NULL) { + char *set_id = g_strdup_printf ("set_%s", var_name); + GString *set_cbuf_copy = g_string_new (set_cbuf); + Node *node1 = new_type (g_strdup (type->name), + g_strdup (type->pointer), + g_strdup (type->postfix)); + Node *node2 = new_type (g_strdup ("void"), + NULL, + NULL); + Node *node3 = new_type (g_strdup (class->class.otype), + g_strdup ("*"), + NULL); + + typestack = g_list_prepend (typestack, node2); + typestack = g_list_prepend (typestack, node1); + typestack = g_list_prepend (typestack, node3); + + push_funcarg ("self", FALSE); + push_funcarg ("ARG", FALSE); + + typestack = g_list_prepend (typestack, node2); + push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL, + set_id, set_cbuf_copy, set_lineno, + lineno, FALSE, NULL); + } +} + %} %union { @@ -370,24 +454,32 @@ class: classdec '{' classcode '}' { } ; -classdec: CLASS TYPETOKEN FROM TYPETOKEN chunk { - class = new_class($2,$4,chunk_size,NULL); +classdec: CLASS TYPETOKEN FROM TYPETOKEN classflags { + class = new_class ($2, $4, + bonobo_x_class, chunk_size, NULL); } ; -chunk: - | '(' TOKEN TOKEN ')' { +classflags: + | '(' TOKEN TOKEN ')' classflags { if(strcmp($2,"chunks") == 0) { - chunk_size = g_strdup($4); + g_free (chunk_size); + chunk_size = g_strdup($3); + } else if(strcmp($2,"BonoboX") == 0) { + g_free (bonobo_x_class); + bonobo_x_class = g_strdup($3); } else { yyerror(_("parse error")); YYERROR; } } - | '(' TOKEN NUMBER ')' { + | '(' TOKEN NUMBER ')' classflags { if(strcmp($2,"chunks") == 0) { - if(atoi($4) != 0) - chunk_size = g_strdup($4); + g_free (chunk_size); + if(atoi($3) != 0) + chunk_size = g_strdup($3); + else + chunk_size = NULL; } else { yyerror(_("parse error")); YYERROR; @@ -400,6 +492,14 @@ classcode: classcode thing { ; } ; thing: method { ; } + | TOKEN method { + if (strcmp ($1, "BonoboX") != 0) { + g_free($1); + yyerror(_("parse error")); + YYERROR; + } + last_added_method->bonobo_x_func = TRUE; + } | variable { ; } | argument { ; } | ';' { ; } @@ -469,82 +569,135 @@ variable: scope type TOKEN varoptions ';' { push_variable($3, the_scope, $1, $4); } ; -argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' { - if(strcmp($5,"get")==0 && - strcmp($8,"set")==0) { + +argument: ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE TOKEN '{' CCODE ';' { + if(strcmp($6,"get")==0 && + strcmp($9,"set")==0) { Node *node; Type *type = pop_type(); - g_free($5); g_free($8); - node = new_argument($3,type,$2,$4, - ($7)->str,$6, - ($10)->str,$9, - $1); - g_string_free($7,FALSE); - g_string_free($10,FALSE); + g_free ($6); + g_free ($9); + node = new_argument ($3, type, $2, $4, + ($8)->str, $7, + ($11)->str,$10, + $1); + class_nodes = g_list_append(class_nodes,node); - } else if(strcmp($5,"set")==0 && - strcmp($8,"get")==0) { + + if ($5) { + export_accessors ($4, + ($8)->str, $7, + ($11)->str, $10, + type, + $3, + $1); + g_free ($5); + } + + g_string_free ($8, FALSE); + g_string_free ($11, FALSE); + + } else if(strcmp($6,"set")==0 && + strcmp($9,"get")==0) { Node *node; Type *type = pop_type(); - g_free($5); g_free($8); - node = new_argument($3,type,$2,$4, - ($10)->str,$9, - ($7)->str,$6, - $1); - g_string_free($10,FALSE); - g_string_free($7,FALSE); + g_free ($6); + g_free ($9); + node = new_argument ($3, type, $2, $4, + ($11)->str,$10, + ($8)->str,$7, + $1); + + if ($5) { + export_accessors ($4, + ($11)->str, $10, + ($8)->str, $7, + type, + $3, + $1); + g_free ($5); + } + + g_string_free ($11, FALSE); + g_string_free ($8, FALSE); class_nodes = g_list_append(class_nodes,node); } else { - g_free($3); g_free($4); - g_free($5); g_free($8); - g_list_foreach($2,(GFunc)g_free,NULL); - g_list_free($2); - g_string_free($10,TRUE); - g_string_free($7,TRUE); - yyerror(_("parse error")); + g_free ($3); + g_free ($4); + g_free ($6); + g_free ($9); + g_list_foreach ($2, (GFunc)g_free, NULL); + g_list_free ($2); + g_string_free ($11, TRUE); + g_string_free ($8, TRUE); + yyerror (_("parse error")); YYERROR; } } - | ARGUMENT flags argtype TOKEN TOKEN '{' CCODE ';' { - if(strcmp($5, "get") == 0) { + | ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE ';' { + if(strcmp($6, "get") == 0) { Node *node; Type *type = pop_type(); - g_free($5); - node = new_argument($3, type, $2, $4, - ($7)->str, $6, - NULL, 0, $1); - g_string_free($7, FALSE); + g_free ($6); + node = new_argument ($3, type, $2, $4, + ($8)->str, $7, + NULL, 0, + $1); + if ($5) { + export_accessors ($4, + ($8)->str, $7, + NULL, 0, + type, + $3, + $1); + g_free ($5); + } + + g_string_free ($8, FALSE); class_nodes = g_list_append(class_nodes, node); - } else if(strcmp($5, "set") == 0) { + } else if(strcmp($6, "set") == 0) { Node *node; Type *type = pop_type(); - g_free($5); - node = new_argument($3, type, $2, $4, - NULL, 0, ($7)->str, - $6, $1); - g_string_free($7, FALSE); - class_nodes = g_list_append(class_nodes, node); + g_free ($6); + node = new_argument ($3, type, $2, $4, + NULL, 0, + ($8)->str, $7, + $1); + if ($5) { + export_accessors ($4, + NULL, 0, + ($8)->str, $7, + type, + $3, + $1); + g_free ($5); + } + + g_string_free ($8, FALSE); + class_nodes = g_list_append (class_nodes, node); } else { - g_free($5); g_free($3); - g_free($4); - g_list_foreach($2, (GFunc)g_free, NULL); - g_list_free($2); - g_string_free($7, TRUE); + g_free ($6); + g_free ($3); + g_free ($4); + g_list_foreach ($2, (GFunc)g_free, NULL); + g_list_free ($2); + g_string_free ($8, TRUE); yyerror(_("parse error")); YYERROR; } } - | ARGUMENT flags argtype TOKEN TOKEN { + | ARGUMENT flags argtype TOKEN export TOKEN { Node *node; char *get, *set = NULL; Variable *var; Type *type; char *root; - if(strcmp($5, "link")!=0 && - strcmp($5, "stringlink")!=0 && - strcmp($5, "objectlink")!=0) { - g_free($5); g_free($3); + if(strcmp($6, "link")!=0 && + strcmp($6, "stringlink")!=0 && + strcmp($6, "objectlink")!=0) { + g_free($6); + g_free($3); g_free($4); g_list_foreach($2,(GFunc)g_free,NULL); g_list_free($2); @@ -560,29 +713,26 @@ argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' { else if(var->scope == CLASS_SCOPE) { root = "SELF_GET_CLASS(self)"; if(no_self_alias) - print_error(FALSE, - _("Self aliases needed when autolinking to a classwide member"), - $1); + error_print(GOB_ERROR, $1, + _("Self aliases needed when autolinking to a classwide member")); } else root = "self"; - if(strcmp($5, "link")==0) { + if(strcmp($6, "link")==0) { set = g_strdup_printf("%s->%s = ARG;", root, $4); - } else if(strcmp($5, "stringlink")==0) { + } else if(strcmp ($6, "stringlink")==0) { set = g_strdup_printf("g_free(%s->%s); " "%s->%s = g_strdup(ARG);", root, $4, root, $4); - } else if(strcmp($5, "objectlink")==0) { + } else if(strcmp ($6, "objectlink")==0) { set = g_strdup_printf( - "if(%s->%s) " - "gtk_object_unref(GTK_OBJECT(%s->%s)); " - "%s->%s = ARG; " - "if(%s->%s) " - "gtk_object_ref(GTK_OBJECT(%s->%s));", - root, $4, - root, $4, + "if (ARG != NULL) " + "gtk_object_ref (GTK_OBJECT (ARG)); " + "if (%s->%s != NULL) " + "gtk_object_unref (GTK_OBJECT (%s->%s)); " + "%s->%s = ARG;", root, $4, root, $4, root, $4); @@ -590,25 +740,48 @@ argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' { g_assert_not_reached(); } - if(strcmp($5, "stringlink")==0) { + if (strcmp ($6, "stringlink")==0) { get = g_strdup_printf("ARG = g_strdup(%s->%s);", root, $4); - } else + } else { /* For everything else, get is just straight assignment */ get = g_strdup_printf("ARG = %s->%s;", root, $4); + } - g_free($5); + g_free ($6); if(!type) type = copy_type(var->vtype); - node = new_argument($3, type, $2, - $4, get, $1, - set, $1, $1); + node = new_argument ($3, type, $2, + $4, + get, $1, + set, $1, + $1); + if ($5) { + export_accessors ($4, + get, $1, + set, $1, + type, + $3, + $1); + g_free ($5); + } + class_nodes = g_list_append(class_nodes,node); } ; +export: '(' TOKEN ')' { + if (strcmp ($2, "export")!=0) { + g_free ($2); + yyerror (_("parse error")); + YYERROR; + } + $$ = $2; + } + | { $$ = NULL; } + argtype: TOKEN '(' TOKEN type ')' { if(strcmp($3,"type")!=0) { g_free($1);