X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/7231d76fbf4ae0b501af648e1216b88714aa7353..4d534c82fb65897999ade6867534ab952a9bc019:/src/parse.y diff --git a/src/parse.y b/src/parse.y index 36f9abc..53d32eb 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,6 +1,7 @@ /* GOB C Preprocessor * Copyright (C) 1999-2000 the Free Software Foundation. - * Copyright (C) 2001 George Lebl + * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2001-2004 George (Jiri) Lebl * * Author: George Lebl * @@ -31,15 +32,23 @@ #include "main.h" #include "util.h" +/* FIXME: add gettext support */ #define _(x) (x) GList *nodes = NULL; static GList *class_nodes = NULL; Node *class = NULL; +GList *enums = NULL; +static GList *enum_vals = NULL; +static GList *flag_vals = NULL; +static GList *error_vals = NULL; +static gboolean abstract = FALSE; static char *chunk_size = NULL; -static char *bonobo_x_class = NULL; +static char *bonobo_object_class = NULL; +static int glade_xml = FALSE; +static GList *interfaces = NULL; static GList *typestack = NULL; static GList *funcargs = NULL; static GList *checks = NULL; @@ -54,6 +63,7 @@ static int destructor_line = 0; static gboolean destructor_simple = TRUE; static char *initializer = NULL; static int initializer_line = 0; +static int glade_widget = FALSE; static char *onerror = NULL; static char *defreturn = NULL; @@ -71,6 +81,7 @@ int yylex(void); extern int ccode_line; extern int line_no; +extern gboolean for_cpp; extern char *yytext; @@ -118,6 +129,7 @@ push_variable (char *name, int scope, int line_no, char *postfix) var = node_new (VARIABLE_NODE, "scope", scope, "vtype:steal", type, + "glade_widget", glade_widget, "id:steal", name, "line_no", line_no, "destructor_unref", destructor_unref, @@ -126,8 +138,10 @@ push_variable (char *name, int scope, int line_no, char *postfix) "destructor_simple", destructor_simple, "initializer:steal", initializer, "initializer_line", initializer_line, + "initializer_simple", TRUE, NULL); class_nodes = g_list_append(class_nodes, var); + glade_widget = FALSE; } static void @@ -343,8 +357,8 @@ set_return_value(char *type, char *val) static void export_accessors (const char *var_name, gboolean do_get, - gboolean do_set, int get_lineno, + gboolean do_set, int set_lineno, Type *type, const char *gtktype, @@ -432,6 +446,62 @@ export_accessors (const char *var_name, node_free ((Node *)the_type); } +static char * +get_prop_enum_flag_cast (Property *prop) +{ + char *tmp, *ret; + if (prop->extra_gtktype == NULL || + /* HACK! just in case someone made this + * work with 2.0.0 by using the TYPE + * macro directly */ + ((strstr (prop->extra_gtktype, "_TYPE_") != NULL || + strstr (prop->extra_gtktype, "TYPE_") == prop->extra_gtktype) && + strchr (prop->extra_gtktype, ':') == NULL)) { + if (prop->ptype != NULL) + return get_type (prop->ptype, TRUE); + else + return g_strdup (""); + } + tmp = remove_sep (prop->extra_gtktype); + ret = g_strdup_printf ("(%s) ", tmp); + g_free (tmp); + return ret; +} + +static void +add_construct_glade (char * file, char * root, char * domain) +{ + Node *var; + Type * type; + GList * flags = NULL; + + type = (Type *)node_new (TYPE_NODE, + "name", "GladeXML", + "pointer", "*", + NULL); + initializer = g_strdup_printf("\t{\n" + "\tGtkWidget * root;\n" + "\t%%1$s->_priv->_glade_xml = glade_xml_new(%s, %s, %s);\n" + "\troot = glade_xml_get_widget(%%1$s->_priv->_glade_xml, %s);\n" + "\tgtk_widget_show(root);\n" + "\tgtk_container_add(GTK_CONTAINER(%%1$s), root);\n" + "\tglade_xml_signal_autoconnect_full(%%1$s->_priv->_glade_xml, (GladeXMLConnectFunc)___glade_xml_connect_foreach, (gpointer)%%1$s);\n" + "}\n", file, root, domain ? domain : "NULL", root); + + var = node_new (VARIABLE_NODE, + "scope", PRIVATE_SCOPE, + "vtype:steal", type, + "glade_widget", FALSE, + "id:steal", "_glade_xml", + "destructor_unref", FALSE, + "destructor", "g_object_unref", + "destructor_simple", TRUE, + "initializer", initializer, + "initializer_simple", FALSE, + NULL); + class_nodes = g_list_prepend(class_nodes, var); +} + static void property_link_and_export (Node *node) { @@ -462,38 +532,42 @@ property_link_and_export (Node *node) } if (strcmp (prop->gtktype, "STRING") == 0) { - set = g_strdup_printf("g_free (%s->%s); " - "%s->%s = g_value_dup_string (VAL);", + set = g_strdup_printf("{ char *old = %s->%s; " + "%s->%s = g_value_dup_string (VAL); g_free (old); }", 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; " - "} " + char *cast; + if (prop->extra_gtktype != NULL) { + cast = remove_sep (prop->extra_gtktype); + } else { + cast = g_strdup ("void"); + } + set = g_strdup_printf("{ GObject *___old = (GObject *)%s->%s; " + "%s->%s = (%s *)g_value_dup_object (VAL); " "if (___old != NULL) { " - "gtk_object_unref (GTK_OBJECT (___old)); " + "g_object_unref (G_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); + cast); + get = g_strdup_printf ("g_value_set_object (VAL, " + "(gpointer)%s->%s);", + root, prop->name); + g_free (cast); } else if (strcmp (prop->gtktype, "BOXED") == 0) { + char *type = make_me_type (prop->extra_gtktype, + "G_TYPE_BOXED"); 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); " + "gpointer ___new = (gpointer)g_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); " @@ -501,29 +575,53 @@ property_link_and_export (Node *node) "} " "}", root, prop->name, - prop->extra_gtktype, + type, root, prop->name, - prop->extra_gtktype, + type, root, prop->name); - get = g_strdup_printf("g_value_set_object (VAL, %s->%s);", + get = g_strdup_printf("g_value_set_boxed (VAL, %s->%s);", root, prop->name); + g_free (type); } else { char *set_func; char *get_func; + const char *getcast = ""; + const char *setcast = ""; + char *to_free = NULL; 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);", + if (for_cpp) { + if (strcmp (prop->gtktype, "FLAGS") == 0) { + setcast = "(guint) "; + getcast = to_free = + get_prop_enum_flag_cast (prop); + } else if (strcmp (prop->gtktype, "ENUM") == 0) { + setcast = "(gint) "; + getcast = to_free = + get_prop_enum_flag_cast (prop); + } else if (strcmp (prop->gtktype, "POINTER") == 0) { + setcast = "(gpointer) "; + getcast = g_strdup_printf ("(%s%s) ", + prop->ptype->name, + prop->ptype->pointer ? prop->ptype->pointer : ""); + } + } + + set = g_strdup_printf("%s->%s = %s%s (VAL);", root, prop->name, + getcast, get_func); - get = g_strdup_printf("%s (VAL, %s->%s);", + get = g_strdup_printf("%s (VAL, %s%s->%s);", set_func, + setcast, root, prop->name); g_free (get_func); g_free (set_func); + g_free (to_free); } node_set (node, @@ -537,7 +635,7 @@ property_link_and_export (Node *node) if (prop->export) { export_accessors (prop->name, prop->get != NULL, prop->get_line, - prop->set != NULL, prop->get_line, + prop->set != NULL, prop->set_line, prop->ptype, prop->gtktype, prop->line_no); @@ -583,7 +681,7 @@ ensure_property (void) %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 NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE %token FLAGS_TYPE ENUM_TYPE PARAM_TYPE BOXED_TYPE OBJECT_TYPE %% @@ -651,7 +749,13 @@ ccode: CCODE { ; ccodes: ccodes ccode { ; } + | ccodes enumcode { ; } + | ccodes flagcode { ; } + | ccodes errorcode { ; } | ccode { ; } + | enumcode { ; } + | flagcode { ; } + | errorcode { ; } ; class: classdec '{' classcode '}' { @@ -670,20 +774,44 @@ classdec: CLASS TYPETOKEN FROM TYPETOKEN classflags { class = node_new (CLASS_NODE, "otype:steal", $2, "ptype:steal", $4, - "bonobo_x_class:steal", bonobo_x_class, + "bonobo_object_class:steal", bonobo_object_class, + "glade_xml", glade_xml, + "interfaces:steal", interfaces, "chunk_size:steal", chunk_size, + "abstract", abstract, NULL); + bonobo_object_class = NULL; + glade_xml = FALSE; + chunk_size = NULL; + interfaces = NULL; } ; classflags: + | '(' TOKEN ')' classflags { + if(strcmp($2,"abstract") == 0) { + abstract = TRUE; + } else { + yyerror(_("parse error")); + YYERROR; + } + } | '(' TOKEN TOKEN ')' classflags { if(strcmp($2,"chunks") == 0) { 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 if(strcmp($2,"BonoboObject") == 0) { + g_free (bonobo_object_class); + bonobo_object_class = g_strdup($3); + } else { + yyerror(_("parse error")); + YYERROR; + } + } + | '(' TOKEN TYPETOKEN ')' classflags { + if (strcmp ($2, "interface") == 0) { + interfaces = g_list_append (interfaces, + g_strdup ($3)); } else { yyerror(_("parse error")); YYERROR; @@ -701,6 +829,42 @@ classflags: YYERROR; } } + | '(' TOKEN STRING STRING ')' classflags { + if (strcmp ($2, "GladeXML") == 0) { + glade_xml = TRUE; + add_construct_glade($3, $4, NULL); + } else { + yyerror(_("parse error")); + YYERROR; + } + } + | '(' TOKEN STRING STRING STRING ')' classflags { + if (strcmp ($2, "GladeXML") == 0) { + glade_xml = TRUE; + add_construct_glade($3, $4, $5); + } else { + yyerror(_("parse error")); + YYERROR; + } + } + | '(' TOKEN TOKEN STRING ')' classflags { + if (strcmp ($2, "GladeXML") == 0) { + glade_xml = TRUE; + add_construct_glade($3, $4, NULL); + } else { + yyerror(_("parse error")); + YYERROR; + } + } + | '(' TOKEN TOKEN STRING STRING ')' classflags { + if (strcmp ($2, "GladeXML") == 0) { + glade_xml = TRUE; + add_construct_glade($3, $4, $5); + } else { + yyerror(_("parse error")); + YYERROR; + } + } ; classcode: classcode thing { ; } @@ -709,12 +873,25 @@ classcode: classcode thing { ; } thing: method { ; } | TOKEN method { - if (strcmp ($1, "BonoboX") != 0) { - g_free($1); - yyerror(_("parse error")); + if (strcmp ($1, "BonoboObject") != 0) { + g_free ($1); + yyerror (_("parse error")); YYERROR; } - last_added_method->bonobo_x_func = TRUE; + g_free ($1); + last_added_method->bonobo_object_func = TRUE; + } + | TOKEN TYPETOKEN method { + if (strcmp ($1, "interface") != 0) { + g_free ($1); + g_free ($2); + yyerror (_("parse error")); + YYERROR; + } + g_free ($1); + node_set ((Node *)last_added_method, + "interface:steal", $2, + NULL); } | variable { ; } | argument { ; } @@ -788,6 +965,14 @@ varoptions: destructor initializer { ; } | initializer destructor { ; } | initializer { destructor = NULL; } | destructor { initializer = NULL; } + | TOKEN { + if (strcmp ($1, "GladeXML") == 0) { + glade_widget = TRUE; + } else { + yyerror(_("parse error")); + YYERROR; + } + } | { destructor = NULL; initializer = NULL; @@ -929,7 +1114,7 @@ argument: ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE TOKEN '{' CCODE '; char *get, *set = NULL; Variable *var; Type *type; - char *root; + const char *root; if(strcmp($6, "link")!=0 && strcmp($6, "stringlink")!=0 && @@ -946,15 +1131,16 @@ argument: ARGUMENT flags argtype TOKEN export TOKEN '{' CCODE TOKEN '{' CCODE '; type = pop_type(); var = find_var_or_die($4, $1); - if(var->scope == PRIVATE_SCOPE) + if(var->scope == PRIVATE_SCOPE) { root = "self->_priv"; - else if(var->scope == CLASS_SCOPE) { + } else if(var->scope == CLASS_SCOPE) { root = "SELF_GET_CLASS(self)"; if(no_self_alias) error_print(GOB_ERROR, $1, _("Self aliases needed when autolinking to a classwide member")); - } else + } else { root = "self"; + } if(strcmp($6, "link")==0) { set = g_strdup_printf("%s->%s = ARG;", @@ -1193,30 +1379,60 @@ param_spec_value: NICK '=' string { "ptype:steal", type, NULL); } + | FLAGS_TYPE '=' TYPETOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } | FLAGS_TYPE '=' TOKEN { ensure_property (); node_set ((Node *)property, "extra_gtktype:steal", $3, NULL); } + | ENUM_TYPE '=' TYPETOKEN { + 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 '=' TYPETOKEN { + 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 '=' TYPETOKEN { + 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 '=' TYPETOKEN { + ensure_property (); + node_set ((Node *)property, + "extra_gtktype:steal", $3, + NULL); + } | OBJECT_TYPE '=' TOKEN { ensure_property (); node_set ((Node *)property, @@ -1225,7 +1441,12 @@ param_spec_value: NICK '=' string { } | TOKEN { ensure_property (); - if (strcmp ($1, "link") == 0) { + if (strcmp ($1, "override") == 0) { + g_free($1); + node_set ((Node *)property, + "override", TRUE, + NULL); + } else if (strcmp ($1, "link") == 0) { g_free($1); node_set ((Node *)property, "link", TRUE, @@ -1596,8 +1817,8 @@ returnvals: TOKEN retcode { retcode: numtok { $$ = $1; } | '{' CCODE { - $$ = ($3)->str; - g_string_free($3, FALSE); + $$ = ($2)->str; + g_string_free($2, FALSE); } ; @@ -1764,7 +1985,118 @@ check: TOKEN { checks = g_list_append(checks,node); } ; - + +enumcode: ENUM TOKEN '{' enumvals '}' TYPETOKEN ';' { + Node *node = node_new (ENUMDEF_NODE, + "etype:steal", $6, + "prefix:steal", $2, + "values:steal", enum_vals, + NULL); + enum_vals = NULL; + nodes = g_list_append (nodes, node); + } + | ENUM TOKEN '{' enumvals ',' '}' TYPETOKEN ';' { + Node *node = node_new (ENUMDEF_NODE, + "etype:steal", $7, + "prefix:steal", $2, + "values:steal", enum_vals, + NULL); + enum_vals = NULL; + nodes = g_list_append (nodes, node); + } + ; + +enumvals: enumvals ',' enumval {;} + | enumval {;} + ; + +enumval: TOKEN '=' numtok { + Node *node; + char *num = $3; + + /* A float value, that's a bad enum */ + if (num[0] >= '0' && + num[0] <= '9' && + strchr (num, '.') != NULL) { + g_free ($1); + g_free (num); + yyerror(_("parse error (enumerator value not integer constant)")); + YYERROR; + } + + node = node_new (ENUMVALUE_NODE, + "name:steal", $1, + "value:steal", num, + NULL); + enum_vals = g_list_append (enum_vals, node); + } + | TOKEN { + Node *node; + + node = node_new (ENUMVALUE_NODE, + "name:steal", $1, + NULL); + enum_vals = g_list_append (enum_vals, node); + } + ; + +flagcode: FLAGS TOKEN '{' flagvals '}' TYPETOKEN ';' { + Node *node = node_new (FLAGS_NODE, + "ftype:steal", $6, + "prefix:steal", $2, + "values:steal", flag_vals, + NULL); + flag_vals = NULL; + nodes = g_list_append (nodes, node); + } + | FLAGS TOKEN '{' flagvals ',' '}' TYPETOKEN ';' { + Node *node = node_new (FLAGS_NODE, + "ftype:steal", $7, + "prefix:steal", $2, + "values:steal", flag_vals, + NULL); + flag_vals = NULL; + nodes = g_list_append (nodes, node); + } + ; + +flagvals: flagvals ',' TOKEN { + flag_vals = g_list_append (flag_vals, $3); + } + | TOKEN { + flag_vals = g_list_append (flag_vals, $1); + } + ; + +errorcode: ERROR TOKEN '{' errorvals '}' TYPETOKEN ';' { + Node *node = node_new (ERROR_NODE, + "etype:steal", $6, + "prefix:steal", $2, + "values:steal", error_vals, + NULL); + error_vals = NULL; + nodes = g_list_append (nodes, node); + } + | ERROR TOKEN '{' errorvals ',' '}' TYPETOKEN ';' { + Node *node = node_new (ERROR_NODE, + "etype:steal", $7, + "prefix:steal", $2, + "values:steal", error_vals, + NULL); + error_vals = NULL; + nodes = g_list_append (nodes, node); + } + ; + +errorvals: errorvals ',' TOKEN { + error_vals = g_list_append (error_vals, $3); + } + | TOKEN { + error_vals = g_list_append (error_vals, $1); + } + ; + + numtok: NUMBER { $$ = $1; } | '-' NUMBER { $$ = g_strconcat("-",$2,NULL);