X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/714b58ab4606ed4d40cec3702cb378938f8c883f..7231d76fbf4ae0b501af648e1216b88714aa7353:/src/parse.y diff --git a/src/parse.y b/src/parse.y index ba4615b..36f9abc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,5 +1,6 @@ /* GOB C Preprocessor - * Copyright (C) 1999 the Free Software Foundation. + * Copyright (C) 1999-2000 the Free Software Foundation. + * Copyright (C) 2001 George Lebl * * Author: George Lebl * @@ -36,15 +37,18 @@ 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 gboolean destructor_unref = FALSE; static char *destructor = NULL; static int destructor_line = 0; static gboolean destructor_simple = TRUE; @@ -56,6 +60,8 @@ static char *defreturn = NULL; static GList *gtktypes = NULL; +static Property *property = NULL; + /* this can be a global as we will only do one function at a time anyway */ static int the_scope = NO_SCOPE; @@ -102,24 +108,32 @@ pop_type(void) } static void -push_variable(char *name, int scope, int line_no, char *postfix) +push_variable (char *name, int scope, int line_no, char *postfix) { Node *var; - Type *type = pop_type(); + Type *type = pop_type (); type->postfix = postfix; - var = new_variable(scope, type, name, line_no, - destructor, destructor_line, - destructor_simple, - initializer, initializer_line); + var = node_new (VARIABLE_NODE, + "scope", scope, + "vtype:steal", type, + "id:steal", name, + "line_no", line_no, + "destructor_unref", destructor_unref, + "destructor:steal", destructor, + "destructor_line", destructor_line, + "destructor_simple", destructor_simple, + "initializer:steal", initializer, + "initializer_line", initializer_line, + NULL); class_nodes = g_list_append(class_nodes, var); } static void -push_function(int scope, int method, char *oid, char *id, - GString *cbuf, int line_no, int ccode_line, - gboolean vararg, GList *flags) +push_function (int scope, int method, char *oid, char *id, + GString *cbuf, int line_no, int ccode_line, + gboolean vararg, GList *flags) { Node *node; Type *type; @@ -128,7 +142,9 @@ push_function(int scope, int method, char *oid, char *id, g_assert(scope != CLASS_SCOPE); if(method == INIT_METHOD || method == CLASS_INIT_METHOD) { - type = (Type *)new_type(g_strdup("void"), NULL, NULL); + type = (Type *)node_new (TYPE_NODE, + "name", "void", + NULL); } else { type = pop_type(); } @@ -166,9 +182,25 @@ push_function(int scope, int method, char *oid, char *id, } else c_cbuf = NULL; - node = new_method(scope, method, type, oid, gtktypes, flags, - id, funcargs, onerror, defreturn, c_cbuf, line_no, - ccode_line, vararg, method_unique_id++); + node = node_new (METHOD_NODE, + "scope", scope, + "method", method, + "mtype:steal", type, + "otype:steal", oid, + "gtktypes:steal", gtktypes, + "flags:steal", flags, + "id:steal", id, + "args:steal", funcargs, + "onerror:steal", onerror, + "defreturn:steal", defreturn, + "cbuf:steal", c_cbuf, + "line_no", line_no, + "ccode_line", ccode_line, + "vararg", vararg, + "unique_id", method_unique_id++, + NULL); + + last_added_method = (Method *)node; if(cbuf) g_string_free(cbuf, @@ -199,7 +231,7 @@ free_all_global_state(void) g_list_free(gtktypes); gtktypes = NULL; - free_node_list(funcargs); + node_list_free (funcargs); funcargs = NULL; } @@ -211,7 +243,11 @@ push_funcarg(char *name, char *postfix) type->postfix = postfix; - node = new_funcarg(type, name, checks); + node = node_new (FUNCARG_NODE, + "atype:steal", type, + "name:steal", name, + "checks:steal", checks, + NULL); checks = NULL; funcargs = g_list_append(funcargs, node); @@ -229,8 +265,14 @@ push_init_arg(char *name, int is_class) else tn = g_strdup(((Class *)class)->otype); - type = new_type(tn, g_strdup("*"), NULL); - node = new_funcarg((Type *)type,name,NULL); + type = node_new (TYPE_NODE, + "name:steal", tn, + "pointer", "*", + NULL); + node = node_new (FUNCARG_NODE, + "atype:steal", (Type *)type, + "name:steal", name, + NULL); funcargs = g_list_prepend(funcargs, node); } @@ -240,11 +282,21 @@ push_self(char *id, gboolean constant) Node *node; Node *type; GList *ch = NULL; - type = new_type(g_strdup(((Class *)class)->otype), - g_strdup(constant ? "const *" : "*"), NULL); - ch = g_list_append(ch,new_check(NULL_CHECK,NULL)); - ch = g_list_append(ch,new_check(TYPE_CHECK,NULL)); - node = new_funcarg((Type *)type,id,ch); + type = node_new (TYPE_NODE, + "name", ((Class *)class)->otype, + "pointer", constant ? "const *" : "*", + NULL); + ch = g_list_append (ch, node_new (CHECK_NODE, + "chtype", NULL_CHECK, + NULL)); + ch = g_list_append (ch, node_new (CHECK_NODE, + "chtype", TYPE_CHECK, + NULL)); + node = node_new (FUNCARG_NODE, + "atype:steal", (Type *)type, + "name:steal", id, + "checks:steal", ch, + NULL); funcargs = g_list_prepend(funcargs, node); } @@ -288,6 +340,231 @@ set_return_value(char *type, char *val) return FALSE; } +static void +export_accessors (const char *var_name, + gboolean do_get, + gboolean do_set, + int get_lineno, + int set_lineno, + Type *type, + const char *gtktype, + int lineno) +{ + Type *the_type; + + if (type != NULL) + the_type = (Type *)node_copy ((Node *)type); + else + the_type = get_tree_type (gtktype, TRUE); + + if (the_type == NULL) { + error_print (GOB_ERROR, line_no, + _("Cannot determine type of property or argument")); + return; + } + + if (do_get) { + char *get_id = g_strdup_printf ("get_%s", var_name); + GString *get_cbuf = g_string_new (NULL); + Node *node1 = node_new (TYPE_NODE, + "name", the_type->name, + "pointer", the_type->pointer, + "postfix", the_type->postfix, + NULL); + Node *node3 = node_new (TYPE_NODE, + "name", class->class.otype, + "pointer", "*", + NULL); + + g_string_sprintf (get_cbuf, + "\t%s%s val; " + "g_object_get (G_OBJECT (self), \"%s\", " + "&val, NULL); " + "return val;\n", + the_type->name, + the_type->pointer ? the_type->pointer : "", + var_name); + + 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, get_lineno, + lineno, FALSE, NULL); + } + + if (do_set) { + char *set_id = g_strdup_printf ("set_%s", var_name); + GString *set_cbuf = g_string_new (NULL); + Node *node1 = node_new (TYPE_NODE, + "name", the_type->name, + "pointer", the_type->pointer, + "postfix", the_type->postfix, + NULL); + Node *node2 = node_new (TYPE_NODE, + "name", "void", + NULL); + Node *node3 = node_new (TYPE_NODE, + "name", class->class.otype, + "pointer", "*", + NULL); + + g_string_sprintf (set_cbuf, + "\tg_object_set (G_OBJECT (self), " + "\"%s\", val, NULL);\n", + var_name); + + typestack = g_list_prepend (typestack, node2); + typestack = g_list_prepend (typestack, node1); + typestack = g_list_prepend (typestack, node3); + + push_funcarg ("self", FALSE); + push_funcarg ("val", FALSE); + + typestack = g_list_prepend (typestack, node2); + push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL, + set_id, set_cbuf, set_lineno, + lineno, FALSE, NULL); + } + + node_free ((Node *)the_type); +} + +static void +property_link_and_export (Node *node) +{ + Property *prop = (Property *)node; + + if (prop->link) { + const char *root; + char *get = NULL, *set = NULL; + Variable *var; + + if (prop->set != NULL || + prop->get != NULL) { + error_print (GOB_ERROR, prop->line_no, + _("Property linking requested, but " + "getters and setters exist")); + } + + var = find_var_or_die (prop->name, prop->line_no); + if(var->scope == PRIVATE_SCOPE) { + root = "self->_priv"; + } else if (var->scope == CLASS_SCOPE) { + root = "SELF_GET_CLASS(self)"; + if (no_self_alias) + error_print (GOB_ERROR, prop->line_no, + _("Self aliases needed when autolinking to a classwide member")); + } else { + root = "self"; + } + + if (strcmp (prop->gtktype, "STRING") == 0) { + set = g_strdup_printf("g_free (%s->%s); " + "%s->%s = g_value_dup_string (VAL);", + root, prop->name, + root, prop->name); + get = g_strdup_printf("g_value_set_string (VAL, %s->%s);", + root, prop->name); + } else if (strcmp (prop->gtktype, "OBJECT") == 0) { + set = g_strdup_printf("{ GtkObject *___old = (GtkObject *)%s->%s; " + "GtkObject *___new = (GtkObject *)gtk_value_get_object (VAL); " + "if (___new != NULL) { " + "gtk_object_ref (GTK_OBJECT (___new)); " + "%s->%s = GTK_OBJECT (___new); " + "} else { " + "%s->%s = NULL; " + "} " + "if (___old != NULL) { " + "gtk_object_unref (GTK_OBJECT (___old)); " + "} " + "}", + root, prop->name, + root, prop->name, + root, prop->name); + get = g_strdup_printf("g_value_set_object (VAL, %s->%s);", + root, prop->name); + } else if (strcmp (prop->gtktype, "BOXED") == 0) { + if (prop->extra_gtktype == NULL) { + error_print (GOB_ERROR, prop->line_no, + _("Property linking requested for BOXED, but " + "boxed_type not set")); + } + set = g_strdup_printf("{ gpointer ___old = (gpointer)%s->%s; " + "gpointer ___new = (gpointer)gtk_value_get_boxed (VAL); " + "if (___new != ___old) { " + "if (___old != NULL) g_boxed_free (%s, ___old); " + "if (___new != NULL) %s->%s = g_boxed_copy (%s, ___new); " + "else %s->%s = NULL;" + "} " + "}", + root, prop->name, + prop->extra_gtktype, + root, prop->name, + prop->extra_gtktype, + root, prop->name); + get = g_strdup_printf("g_value_set_object (VAL, %s->%s);", + root, prop->name); + } else { + char *set_func; + char *get_func; + set_func = g_strdup_printf ("g_value_set_%s", prop->gtktype); + g_strdown (set_func); + get_func = g_strdup_printf ("g_value_get_%s", prop->gtktype); + g_strdown (get_func); + + set = g_strdup_printf("%s->%s = %s (VAL);", + root, prop->name, + get_func); + get = g_strdup_printf("%s (VAL, %s->%s);", + set_func, + root, prop->name); + + g_free (get_func); + g_free (set_func); + } + + node_set (node, + "get:steal", get, + "get_line", prop->line_no, + "set:steal", set, + "set_line", prop->line_no, + NULL); + } + + if (prop->export) { + export_accessors (prop->name, + prop->get != NULL, prop->get_line, + prop->set != NULL, prop->get_line, + prop->ptype, + prop->gtktype, + prop->line_no); + } +} + + +static char * +debool (char *s) +{ + if (strcmp (s, "BOOL") == 0) { + error_print (GOB_WARN, line_no, + _("BOOL type is deprecated, please use BOOLEAN")); + g_free (s); + return g_strdup ("BOOLEAN"); + } else { + return s; + } +} + +static void +ensure_property (void) +{ + if (property == NULL) + property = (Property *)node_new (PROPERTY_NODE, NULL); +} + %} %union { @@ -302,9 +579,12 @@ set_return_value(char *type, char *val) %token CONST VOID STRUCT UNION ENUM THREEDOTS %token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR -%token TOKEN NUMBER TYPETOKEN ARRAY_DIM -%token CCODE HTCODE PHCODE HCODE ACODE ATCODE -%token PUBLIC PRIVATE PROTECTED CLASSWIDE ARGUMENT VIRTUAL SIGNAL OVERRIDE +%token TOKEN NUMBER TYPETOKEN ARRAY_DIM SINGLE_CHAR +%token CCODE HTCODE PHCODE HCODE ACODE ATCODE STRING +%token PUBLIC PRIVATE PROTECTED CLASSWIDE PROPERTY ARGUMENT +%token VIRTUAL SIGNAL OVERRIDE +%token NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE FLAGS TYPE +%token FLAGS_TYPE ENUM_TYPE PARAM_TYPE BOXED_TYPE OBJECT_TYPE %% @@ -315,38 +595,56 @@ prog: ccodes class ccodes { ; } ; ccode: CCODE { - Node *node = new_ccode(C_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", C_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } | HCODE { - Node *node = new_ccode(H_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", H_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } | HTCODE { - Node *node = new_ccode(HT_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", HT_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } | PHCODE { - Node *node = new_ccode(PH_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", PH_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } | ACODE { - Node *node = new_ccode(A_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", A_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } | ATCODE { - Node *node = new_ccode(AT_CCODE,($1)->str, - ccode_line); + Node *node = node_new (CCODE_NODE, + "cctype", AT_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } @@ -368,24 +666,36 @@ class: classdec '{' classcode '}' { } ; -classdec: CLASS TYPETOKEN FROM TYPETOKEN chunk { - class = new_class($2,$4,chunk_size,NULL); +classdec: CLASS TYPETOKEN FROM TYPETOKEN classflags { + class = node_new (CLASS_NODE, + "otype:steal", $2, + "ptype:steal", $4, + "bonobo_x_class:steal", bonobo_x_class, + "chunk_size:steal", 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; @@ -398,8 +708,17 @@ 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 { ; } + | property { ; } | ';' { ; } ; @@ -410,29 +729,44 @@ scope: PUBLIC { the_scope = PUBLIC_SCOPE; } ; destructor: TOKEN TOKEN { - if(strcmp($1, "destroywith")==0) { - g_free($1); + if (strcmp ($1, "destroywith") == 0) { + g_free ($1); + destructor_unref = FALSE; + destructor = $2; + destructor_line = line_no; + destructor_simple = TRUE; + } else if (strcmp ($1, "unrefwith") == 0) { + g_free ($1); + destructor_unref = TRUE; destructor = $2; destructor_line = line_no; destructor_simple = TRUE; } else { - g_free($1); - g_free($2); - yyerror(_("parse error")); + g_free ($1); + g_free ($2); + yyerror (_("parse error")); YYERROR; } } | TOKEN '{' CCODE { - if(strcmp($1, "destroy")==0) { + if (strcmp ($1, "destroy") == 0) { g_free($1); + destructor_unref = FALSE; destructor = ($3)->str; g_string_free($3, FALSE); destructor_line = ccode_line; destructor_simple = FALSE; + } else if (strcmp ($1, "unref") == 0) { + g_free ($1); + destructor_unref = TRUE; + destructor = ($3)->str; + g_string_free ($3, FALSE); + destructor_line = ccode_line; + destructor_simple = FALSE; } else { - g_free($1); - g_string_free($3, TRUE); - yyerror(_("parse error")); + g_free ($1); + g_string_free ($3, TRUE); + yyerror (_("parse error")); YYERROR; } } @@ -467,82 +801,141 @@ 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) { - Node *node; + +argument: ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE TOKEN '{' CCODE ';' { + Node *node = NULL; + if(strcmp($6,"get")==0 && + strcmp($9,"set")==0) { 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 = node_new (ARGUMENT_NODE, + "gtktype:steal", $3, + "atype:steal", type, + "flags:steal", $2, + "name:steal", $4, + "get:steal", ($8)->str, + "get_line", $7, + "set:steal", ($11)->str, + "set_line", $10, + "line_no", $1, + NULL); + class_nodes = g_list_append(class_nodes,node); - } else if(strcmp($5,"set")==0 && - strcmp($8,"get")==0) { - Node *node; + + g_string_free ($8, FALSE); + g_string_free ($11, FALSE); + + } else if(strcmp($6,"set")==0 && + strcmp($9,"get")==0) { 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 = node_new (ARGUMENT_NODE, + "gtktype:steal", $3, + "atype:steal", type, + "flags:steal", $2, + "name:steal", $4, + "get:steal", ($11)->str, + "get_line", $10, + "set:steal", ($8)->str, + "set_line", $7, + "line_no", $1, + NULL); + 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; } + + if ($5 != NULL) { + Argument *arg = (Argument *)node; + export_accessors (arg->name, + arg->get != NULL, arg->get_line, + arg->set != NULL, arg->set_line, + arg->atype, + arg->gtktype, + arg->line_no); + g_free ($5); + } + } - | ARGUMENT flags argtype TOKEN TOKEN '{' CCODE ';' { - if(strcmp($5, "get") == 0) { - Node *node; + | ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE ';' { + Node *node = NULL; + if(strcmp($6, "get") == 0) { 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 = node_new (ARGUMENT_NODE, + "gtktype:steal", $3, + "atype:steal", type, + "flags:steal", $2, + "name:steal", $4, + "get:steal", ($8)->str, + "get_line", $7, + "line_no", $1, + NULL); + + g_string_free ($8, FALSE); class_nodes = g_list_append(class_nodes, node); - } else if(strcmp($5, "set") == 0) { - Node *node; + } else if(strcmp($6, "set") == 0) { 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 = node_new (ARGUMENT_NODE, + "gtktype:steal", $3, + "atype:steal", type, + "flags:steal", $2, + "name:steal", $4, + "set:steal", ($8)->str, + "set_line", $7, + "line_no", $1, + NULL); + + 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; } + + if ($5 != NULL) { + Argument *arg = (Argument *)node; + export_accessors (arg->name, + arg->get != NULL, arg->get_line, + arg->set != NULL, arg->set_line, + arg->atype, + arg->gtktype, + arg->line_no); + g_free ($5); + } } - | 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); @@ -563,23 +956,21 @@ argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' { } 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) { - set = g_strdup_printf("g_free(%s->%s); " - "%s->%s = g_strdup(ARG);", + } 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) " + "g_object_ref (G_OBJECT (ARG)); " + "if (%s->%s != NULL) " + "g_object_unref (G_OBJECT (%s->%s)); " + "%s->%s = ARG;", root, $4, root, $4, root, $4); @@ -587,23 +978,269 @@ argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' { g_assert_not_reached(); } - if(strcmp($5, "stringlink")==0) { - get = g_strdup_printf("ARG = g_strdup(%s->%s);", root, $4); - } else - /* For everything else, get is just straight assignment */ - get = g_strdup_printf("ARG = %s->%s;", root, $4); + get = g_strdup_printf("ARG = %s->%s;", root, $4); + + g_free ($6); + + if (type == NULL) + type = (Type *)node_copy ((Node *)var->vtype); + + node = node_new (ARGUMENT_NODE, + "gtktype:steal", $3, + "atype:steal", type, + "flags:steal", $2, + "name:steal", $4, + "get:steal", get, + "get_line", $1, + "set:steal", set, + "set_line", $1, + "line_no", $1, + NULL); + + if ($5 != NULL) { + Argument *arg = (Argument *)node; + export_accessors (arg->name, + arg->get != NULL, arg->get_line, + arg->set != NULL, arg->set_line, + arg->atype, + arg->gtktype, + arg->line_no); + g_free ($5); + } + + class_nodes = g_list_append (class_nodes, node); + } + ; - g_free($5); +export: '(' TOKEN ')' { + if (strcmp ($2, "export")!=0) { + g_free ($2); + yyerror (_("parse error")); + YYERROR; + } + $$ = $2; + } + | { + $$ = NULL; + } + ; + +property: PROPERTY TOKEN TOKEN param_spec TOKEN '{' CCODE TOKEN '{' CCODE ';' { + ensure_property (); + node_set ((Node *)property, + "line_no", $1, + "gtktype:steal", debool ($2), + "name:steal", $3, + NULL); + if (strcmp ($5, "get") == 0 && + strcmp ($8, "set") == 0) { + node_set ((Node *)property, + "get:steal", ($7)->str, + "get_line", $6, + "set:steal", ($10)->str, + "set_line", $9, + NULL); + g_string_free ($7, FALSE); + g_string_free ($10, FALSE); + g_free ($5); + g_free ($8); + } else if (strcmp ($5, "set") == 0 && + strcmp ($8, "get") == 0) { + node_set ((Node *)property, + "get:steal", ($10)->str, + "get_line", $9, + "set:steal", ($7)->str, + "set_line", $6, + NULL); + g_string_free ($7, FALSE); + g_string_free ($10, FALSE); + g_free ($5); + g_free ($8); + } else { + g_string_free ($7, TRUE); + g_string_free ($10, TRUE); + g_free ($5); + g_free ($8); + node_free ((Node *)property); + property = NULL; + yyerror (_("parse error")); + YYERROR; + } + property_link_and_export ((Node *)property); + if (property != NULL) { + class_nodes = g_list_append (class_nodes, + property); + property = NULL; + } + } + | PROPERTY TOKEN TOKEN param_spec TOKEN '{' CCODE ';' { + ensure_property (); + node_set ((Node *)property, + "line_no", $1, + "gtktype:steal", debool ($2), + "name:steal", $3, + NULL); + if (strcmp ($5, "get") == 0) { + node_set ((Node *)property, + "get:steal", ($7)->str, + "get_line", $6, + NULL); + g_string_free ($7, FALSE); + g_free ($5); + } else if (strcmp ($5, "set") == 0) { + node_set ((Node *)property, + "set:steal", ($7)->str, + "set_line", $6, + NULL); + g_string_free ($7, FALSE); + g_free ($5); + } else { + g_string_free ($7, TRUE); + g_free ($5); + node_free ((Node *)property); + property = NULL; + yyerror (_("parse error")); + YYERROR; + } + property_link_and_export ((Node *)property); + if (property != NULL) { + class_nodes = g_list_append (class_nodes, + property); + property = NULL; + } + } + | PROPERTY TOKEN TOKEN param_spec ';' { + ensure_property (); + node_set ((Node *)property, + "line_no", $1, + "gtktype:steal", debool ($2), + "name:steal", $3, + NULL); + property_link_and_export ((Node *)property); + if (property != NULL) { + class_nodes = g_list_append (class_nodes, + property); + property = NULL; + } + } + ; +param_spec: '(' param_spec_list ')' { ; } + | { ; } + ; - if(!type) - type = copy_type(var->vtype); +param_spec_list: param_spec_list ',' param_spec_value { ; } + | param_spec_value { ; } + ; - node = new_argument($3, type, $2, - $4, get, $1, - set, $1, $1); - class_nodes = g_list_append(class_nodes,node); - } +string: STRING { $$ = $1; } + | TOKEN '(' STRING ')' { + if (strcmp ($1, "_") != 0) { + g_free ($1); + yyerror(_("parse error")); + YYERROR; + } + g_free ($1); + $$ = g_strconcat ("_(", $3, ")", NULL); + g_free ($3); + } + ; + +anyval: numtok { $$ = $1; } + | string { $$ = $1; } + ; + +param_spec_value: NICK '=' string { + ensure_property (); + node_set ((Node *)property, + "nick:steal", $3, + NULL); + } + | BLURB '=' string { + ensure_property (); + node_set ((Node *)property, + "blurb:steal", $3, + NULL); + } + | MAXIMUM '=' numtok { + ensure_property (); + node_set ((Node *)property, + "maximum:steal", $3, + NULL); + } + | MINIMUM '=' numtok { + ensure_property (); + node_set ((Node *)property, + "minimum:steal", $3, + NULL); + } + | DEFAULT_VALUE '=' anyval { + ensure_property (); + node_set ((Node *)property, + "default_value:steal", $3, + NULL); + } + | FLAGS '=' flaglist { + ensure_property (); + node_set ((Node *)property, + "flags:steal", $3, + NULL); + } + | TYPE '=' type { + Type *type = pop_type (); + ensure_property (); + node_set ((Node *)property, + "ptype:steal", type, + NULL); + } + | FLAGS_TYPE '=' TOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } + | ENUM_TYPE '=' TOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } + | PARAM_TYPE '=' TOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } + | BOXED_TYPE '=' TOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } + | OBJECT_TYPE '=' TOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } + | TOKEN { + ensure_property (); + if (strcmp ($1, "link") == 0) { + g_free($1); + node_set ((Node *)property, + "link", TRUE, + NULL); + } else if (strcmp ($1, "export") == 0) { + g_free($1); + node_set ((Node *)property, + "export", TRUE, + NULL); + } else { + g_free($1); + yyerror(_("parse error")); + YYERROR; + } + } ; argtype: TOKEN '(' TOKEN type ')' { @@ -613,10 +1250,10 @@ argtype: TOKEN '(' TOKEN type ')' { yyerror(_("parse error")); YYERROR; } - $$ = $1; + $$ = debool ($1); } | TOKEN { - $$ = $1; + $$ = debool ($1); typestack = g_list_prepend(typestack,NULL); } ; @@ -635,11 +1272,16 @@ flaglist: TOKEN '|' flaglist { type: specifier_list pointer { - Node *node = new_type($1, $2, NULL); + Node *node = node_new (TYPE_NODE, + "name:steal", $1, + "pointer:steal", $2, + NULL); typestack = g_list_prepend(typestack,node); } | specifier_list { - Node *node = new_type($1, NULL, NULL); + Node *node = node_new (TYPE_NODE, + "name:steal", $1, + NULL); typestack = g_list_prepend(typestack,node); } ; @@ -785,15 +1427,15 @@ fullsigtype: scope TOKEN sigtype { ; sigtype: TOKEN '(' tokenlist ')' { - gtktypes = g_list_prepend(gtktypes, $1); + gtktypes = g_list_prepend(gtktypes, debool ($1)); } ; tokenlist: tokenlist ',' TOKEN { - gtktypes = g_list_append(gtktypes, $3); + gtktypes = g_list_append(gtktypes, debool ($3)); } | TOKEN { - gtktypes = g_list_append(gtktypes, $1); + gtktypes = g_list_append(gtktypes, debool ($1)); } ; @@ -1064,10 +1706,14 @@ checklist: checklist check { ; } check: TOKEN { if(strcmp($1,"type")==0) { - Node *node = new_check(TYPE_CHECK,NULL); + Node *node = node_new (CHECK_NODE, + "chtype", TYPE_CHECK, + NULL); checks = g_list_append(checks,node); } else if(strcmp($1,"null")==0) { - Node *node = new_check(NULL_CHECK,NULL); + Node *node = node_new (CHECK_NODE, + "chtype", NULL_CHECK, + NULL); checks = g_list_append(checks,node); } else { yyerror(_("parse error")); @@ -1076,27 +1722,45 @@ check: TOKEN { g_free($1); } | '>' numtok { - Node *node = new_check(GT_CHECK,$2); + Node *node = node_new (CHECK_NODE, + "chtype", GT_CHECK, + "number:steal", $2, + NULL); checks = g_list_append(checks,node); } | '<' numtok { - Node *node = new_check(LT_CHECK,$2); + Node *node = node_new (CHECK_NODE, + "chtype", LT_CHECK, + "number:steal", $2, + NULL); checks = g_list_append(checks,node); } | '>' '=' numtok { - Node *node = new_check(GE_CHECK,$3); + Node *node = node_new (CHECK_NODE, + "chtype", GE_CHECK, + "number:steal", $3, + NULL); checks = g_list_append(checks,node); } | '<' '=' numtok { - Node *node = new_check(LE_CHECK,$3); + Node *node = node_new (CHECK_NODE, + "chtype", LE_CHECK, + "number:steal", $3, + NULL); checks = g_list_append(checks,node); } | '=' '=' numtok { - Node *node = new_check(EQ_CHECK,$3); + Node *node = node_new (CHECK_NODE, + "chtype", EQ_CHECK, + "number:steal", $3, + NULL); checks = g_list_append(checks,node); } | '!' '=' numtok { - Node *node = new_check(NE_CHECK,$3); + Node *node = node_new (CHECK_NODE, + "chtype", NE_CHECK, + "number:steal", $3, + NULL); checks = g_list_append(checks,node); } ; @@ -1106,6 +1770,7 @@ numtok: NUMBER { $$ = $1; } $$ = g_strconcat("-",$2,NULL); g_free($2); } + | SINGLE_CHAR { $$ = $1; } | TOKEN { $$ = $1; } ;