X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/573256d3bc21896c54c511d5c0e6927f09b4209e..8445442abc02fc325a9ce228759403113583818c:/src/parse.y diff --git a/src/parse.y b/src/parse.y index ded33fd..1831ad0 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,7 +1,7 @@ /* GOB C Preprocessor * Copyright (C) 1999-2000 the Free Software Foundation. * Copyright (C) 2000 Eazel, Inc. - * Copyright (C) 2001-2004 George (Jiri) Lebl + * Copyright (C) 2001-2009 George (Jiri) Lebl * * Author: George Lebl * @@ -44,8 +44,10 @@ 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_object_class = NULL; +static int glade_xml = FALSE; static GList *interfaces = NULL; static GList *typestack = NULL; static GList *funcargs = NULL; @@ -61,11 +63,14 @@ 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 *funcattrs = NULL; static char *onerror = NULL; static char *defreturn = NULL; static GList *gtktypes = NULL; +static char *signal_name=NULL; static Property *property = NULL; @@ -88,9 +93,10 @@ yyerror(char *str) char *out=NULL; char *p; - if(strcmp(yytext,"\n")==0) { - out=g_strconcat("Error: ",str," before newline",NULL); - } else if(yytext[0]=='\0') { + if (strcmp (yytext, "\n") == 0 || + strcmp (yytext, "\r") == 0) { + out = g_strconcat ("Error: ", str, " before end of line", NULL); + } else if (yytext[0] == '\0') { out=g_strconcat("Error: ", str, " at end of input", NULL); } else { char *tmp = g_strdup(yytext); @@ -126,6 +132,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, @@ -134,8 +141,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 @@ -149,7 +158,11 @@ push_function (int scope, int method, char *oid, char *id, g_assert(scope != CLASS_SCOPE); - if(method == INIT_METHOD || method == CLASS_INIT_METHOD) { + if(method == INIT_METHOD || + method == CLASS_INIT_METHOD || + method == CONSTRUCTOR_METHOD || + method == DISPOSE_METHOD || + method == FINALIZE_METHOD) { type = (Type *)node_new (TYPE_NODE, "name", "void", NULL); @@ -190,6 +203,13 @@ push_function (int scope, int method, char *oid, char *id, } else c_cbuf = NULL; + if (signal_name == NULL ) + { + GString * buffer=g_string_new(""); + g_string_printf(buffer, "\"%s\"", id); + signal_name = buffer->str; + g_string_free(buffer, FALSE); + } node = node_new (METHOD_NODE, "scope", scope, "method", method, @@ -198,7 +218,9 @@ push_function (int scope, int method, char *oid, char *id, "gtktypes:steal", gtktypes, "flags:steal", flags, "id:steal", id, + "signal_name:steal", signal_name, "args:steal", funcargs, + "funcattrs:steal", funcattrs, "onerror:steal", onerror, "defreturn:steal", defreturn, "cbuf:steal", c_cbuf, @@ -216,8 +238,9 @@ push_function (int scope, int method, char *oid, char *id, above */ c_cbuf?FALSE:TRUE); gtktypes = NULL; + signal_name = NULL; funcargs = NULL; - + funcattrs = NULL; onerror = NULL; defreturn = NULL; @@ -227,6 +250,8 @@ push_function (int scope, int method, char *oid, char *id, static void free_all_global_state(void) { + g_free(funcattrs); + funcattrs = NULL; g_free(onerror); onerror = NULL; g_free(defreturn); @@ -330,9 +355,15 @@ find_var_or_die(const char *id, int line) } static gboolean -set_return_value(char *type, char *val) +set_attr_value(char *type, char *val) { - if(strcmp(type, "onerror")==0) { + if(strcmp(type, "attr")==0) { + if(!funcattrs) { + funcattrs = val; + return TRUE; + } else + return FALSE; + } else if(strcmp(type, "onerror")==0) { if(!onerror) { onerror = val; return TRUE; @@ -462,6 +493,39 @@ get_prop_enum_flag_cast (Property *prop) return ret; } +static void +add_construct_glade (char * file, char * root, char * domain) +{ + Node *var; + Type * type; + + 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) { @@ -562,6 +626,11 @@ property_link_and_export (Node *node) 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 : ""); } } @@ -633,10 +702,10 @@ ensure_property (void) %token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR %token TOKEN NUMBER TYPETOKEN ARRAY_DIM SINGLE_CHAR -%token CCODE HTCODE PHCODE HCODE ACODE ATCODE STRING +%token CCODE CTCODE ADCODE HTCODE PHCODE HCODE ACODE ATCODE STRING %token PUBLIC PRIVATE PROTECTED CLASSWIDE PROPERTY ARGUMENT %token VIRTUAL SIGNAL OVERRIDE -%token NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE +%token NAME NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE %token FLAGS_TYPE ENUM_TYPE PARAM_TYPE BOXED_TYPE OBJECT_TYPE %% @@ -656,6 +725,15 @@ ccode: CCODE { nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } + | ADCODE { + Node *node = node_new (CCODE_NODE, + "cctype", AD_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); + nodes = g_list_append(nodes,node); + g_string_free($1,FALSE); + } | HCODE { Node *node = node_new (CCODE_NODE, "cctype", H_CCODE, @@ -701,6 +779,15 @@ ccode: CCODE { nodes = g_list_append(nodes,node); g_string_free($1,FALSE); } + | CTCODE { + Node *node = node_new (CCODE_NODE, + "cctype", CT_CCODE, + "cbuf:steal", ($1)->str, + "line_no", ccode_line, + NULL); + nodes = g_list_append(nodes,node); + g_string_free($1,FALSE); + } ; ccodes: ccodes ccode { ; } @@ -730,16 +817,27 @@ classdec: CLASS TYPETOKEN FROM TYPETOKEN classflags { "otype:steal", $2, "ptype:steal", $4, "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); @@ -773,6 +871,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 { ; } @@ -873,6 +1007,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; @@ -1236,7 +1378,13 @@ anyval: numtok { $$ = $1; } | string { $$ = $1; } ; -param_spec_value: NICK '=' string { +param_spec_value: NAME '=' string { + ensure_property (); + node_set ((Node *)property, + "canonical_name:steal", gob_str_delete_quotes($3), + NULL); + } + | NICK '=' string { ensure_property (); node_set ((Node *)property, "nick:steal", $3, @@ -1341,7 +1489,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, @@ -1545,6 +1698,10 @@ fullsigtype: scope TOKEN sigtype { sigtype: TOKEN '(' tokenlist ')' { gtktypes = g_list_prepend(gtktypes, debool ($1)); } + | TOKEN STRING '(' tokenlist ')' { + gtktypes = g_list_prepend(gtktypes, debool ($1)); + signal_name=$2; + } ; tokenlist: tokenlist ',' TOKEN { @@ -1560,7 +1717,7 @@ codenocode: '{' CCODE { $$ = $2; } ; /*here CCODE will include the ending '}' */ -method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenocode { +method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' methodmods codenocode { if(!has_self) { yyerror(_("signal without 'self' as " "first parameter")); @@ -1572,11 +1729,18 @@ method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc free_all_global_state(); YYERROR; } + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with signal methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(the_scope, $3,NULL, $5, $10,$1, ccode_line, vararg, $2); } - | scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' returnvals codenocode { + | scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' methodmods codenocode { if(!has_self) { yyerror(_("signal without 'self' as " "first parameter")); @@ -1588,11 +1752,18 @@ method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc free_all_global_state(); YYERROR; } + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with signal methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(the_scope, $4, NULL, $6, $11, $2, ccode_line, vararg, $3); } - | VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode { + | VIRTUAL scope type TOKEN '(' funcargs ')' methodmods codenocode { if(!has_self) { yyerror(_("virtual method without 'self' as " "first parameter")); @@ -1604,11 +1775,18 @@ method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc free_all_global_state(); YYERROR; } + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with virtual methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(the_scope, VIRTUAL_METHOD, NULL, $4, $9, $1, ccode_line, vararg, NULL); } - | scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { + | scope VIRTUAL type TOKEN '(' funcargs ')' methodmods codenocode { if(!has_self) { yyerror(_("virtual method without 'self' as " "first parameter")); @@ -1620,28 +1798,49 @@ method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc free_all_global_state(); YYERROR; } + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with virtual methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(the_scope, VIRTUAL_METHOD, NULL, $4, $9, $2, ccode_line, vararg, NULL); } - | VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { + | VIRTUAL type TOKEN '(' funcargs ')' methodmods codenocode { if(!has_self) { - yyerror(_("virtual method without 'self' as " + yyerror(_("virtual method without 'szelf' as " "first parameter")); free_all_global_state(); YYERROR; } + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with virtual methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL, $3, $8, $1, ccode_line, vararg, NULL); } - | OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' returnvals codenocode { + | OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' methodmods codenocode { + if (funcattrs != NULL) { + char *error = g_strdup_printf + (_("function attribute macros ('%s' in this case) may not be used with override methods"), + funcattrs); + yyerror (error); + YYERROR; + } push_function(NO_SCOPE, OVERRIDE_METHOD, $3, $6, $11, $1, ccode_line, vararg, NULL); } - | scope type TOKEN '(' funcargs ')' returnvals codenocode { + | scope type TOKEN '(' funcargs ')' methodmods codenocode { if(the_scope == CLASS_SCOPE) { yyerror(_("a method cannot be of class scope")); free_all_global_state(); @@ -1662,22 +1861,40 @@ method: SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL, $1, $5, $2, ccode_line, FALSE, NULL); + } else if(strcmp($1, "constructor")==0) { + push_init_arg($3, FALSE); + push_function(NO_SCOPE, CONSTRUCTOR_METHOD, NULL, + $1, $5, $2, + ccode_line, FALSE, NULL); + } else if(strcmp($1, "dispose")==0) { + push_init_arg($3, FALSE); + push_function(NO_SCOPE, DISPOSE_METHOD, NULL, + $1, $5, $2, + ccode_line, FALSE, NULL); + } else if(strcmp($1, "finalize")==0) { + push_init_arg($3, FALSE); + push_function(NO_SCOPE, FINALIZE_METHOD, NULL, + $1, $5, $2, + ccode_line, FALSE, NULL); + } else { g_free($1); g_free($3); g_string_free($5,TRUE); yyerror(_("parse error " - "(untyped blocks must be init or " - "class_init)")); + "(untyped blocks must be init, " + "class_init, constructor, dispose " + "or finalize)")); YYERROR; } } ; -returnvals: TOKEN retcode { +methodmods: TOKEN retcode { + g_free(funcattrs); funcattrs = NULL; g_free(onerror); onerror = NULL; g_free(defreturn); defreturn = NULL; - if(!set_return_value($1, $2)) { + if(!set_attr_value($1, $2)) { g_free($1); g_free($2); yyerror(_("parse error")); @@ -1686,25 +1903,58 @@ returnvals: TOKEN retcode { g_free($1); } | TOKEN retcode TOKEN retcode { + g_free(funcattrs); funcattrs = NULL; + g_free(onerror); onerror = NULL; + g_free(defreturn); defreturn = NULL; + if(!set_attr_value($1, $2)) { + g_free($1); g_free($2); + g_free($3); g_free($4); + yyerror(_("parse error")); + YYERROR; + } + if(!set_attr_value($3, $4)) { + funcattrs = onerror = defreturn = NULL; + g_free($1); g_free($2); + g_free($3); g_free($4); + yyerror(_("parse error")); + YYERROR; + } + g_free($1); + g_free($3); + } + | TOKEN retcode TOKEN retcode TOKEN retcode { + g_free(funcattrs); funcattrs = NULL; g_free(onerror); onerror = NULL; g_free(defreturn); defreturn = NULL; - if(!set_return_value($1, $2)) { + if(!set_attr_value($1, $2)) { g_free($1); g_free($2); g_free($3); g_free($4); + g_free($5); g_free($6); yyerror(_("parse error")); YYERROR; } - if(!set_return_value($3, $4)) { - onerror = defreturn = NULL; + if(!set_attr_value($3, $4)) { + funcattrs = onerror = defreturn = NULL; g_free($1); g_free($2); g_free($3); g_free($4); + g_free($5); g_free($6); + yyerror(_("parse error")); + YYERROR; + } + if(!set_attr_value($5, $6)) { + funcattrs = onerror = defreturn = NULL; + g_free($1); g_free($2); + g_free($3); g_free($4); + g_free($5); g_free($6); yyerror(_("parse error")); YYERROR; } g_free($1); g_free($3); + g_free($5); } | { + g_free(funcattrs); funcattrs = NULL; g_free(onerror); onerror = NULL; g_free(defreturn); defreturn = NULL; }