/* 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
*
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;
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;
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);
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,
"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
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);
} 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,
"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,
above */
c_cbuf?FALSE:TRUE);
gtktypes = NULL;
+ signal_name = NULL;
funcargs = NULL;
-
+ funcattrs = NULL;
onerror = NULL;
defreturn = NULL;
static void
free_all_global_state(void)
{
+ g_free(funcattrs);
+ funcattrs = NULL;
g_free(onerror);
onerror = NULL;
g_free(defreturn);
}
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;
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)
{
%token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR
%token <id> TOKEN NUMBER TYPETOKEN ARRAY_DIM SINGLE_CHAR
-%token <cbuf> CCODE HTCODE PHCODE HCODE ACODE ATCODE STRING
+%token <cbuf> CCODE CTCODE ADCODE HTCODE PHCODE HCODE ACODE ATCODE STRING
%token <line> PUBLIC PRIVATE PROTECTED CLASSWIDE PROPERTY ARGUMENT
%token <line> VIRTUAL SIGNAL OVERRIDE
-%token <line> NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE
+%token <line> NAME NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE
%token <line> FLAGS_TYPE ENUM_TYPE PARAM_TYPE BOXED_TYPE OBJECT_TYPE
%%
nodes = g_list_append(nodes,node);
g_string_free($<cbuf>1,FALSE);
}
+ | ADCODE {
+ Node *node = node_new (CCODE_NODE,
+ "cctype", AD_CCODE,
+ "cbuf:steal", ($<cbuf>1)->str,
+ "line_no", ccode_line,
+ NULL);
+ nodes = g_list_append(nodes,node);
+ g_string_free($<cbuf>1,FALSE);
+ }
| HCODE {
Node *node = node_new (CCODE_NODE,
"cctype", H_CCODE,
nodes = g_list_append(nodes,node);
g_string_free($<cbuf>1,FALSE);
}
+ | CTCODE {
+ Node *node = node_new (CCODE_NODE,
+ "cctype", CT_CCODE,
+ "cbuf:steal", ($<cbuf>1)->str,
+ "line_no", ccode_line,
+ NULL);
+ nodes = g_list_append(nodes,node);
+ g_string_free($<cbuf>1,FALSE);
+ }
;
ccodes: ccodes ccode { ; }
"otype:steal", $<id>2,
"ptype:steal", $<id>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($<id>2,"abstract") == 0) {
+ abstract = TRUE;
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
| '(' TOKEN TOKEN ')' classflags {
if(strcmp($<id>2,"chunks") == 0) {
g_free (chunk_size);
YYERROR;
}
}
+ | '(' TOKEN STRING STRING ')' classflags {
+ if (strcmp ($<id>2, "GladeXML") == 0) {
+ glade_xml = TRUE;
+ add_construct_glade($<id>3, $<id>4, NULL);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN STRING STRING STRING ')' classflags {
+ if (strcmp ($<id>2, "GladeXML") == 0) {
+ glade_xml = TRUE;
+ add_construct_glade($<id>3, $<id>4, $<id>5);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN TOKEN STRING ')' classflags {
+ if (strcmp ($<id>2, "GladeXML") == 0) {
+ glade_xml = TRUE;
+ add_construct_glade($<id>3, $<id>4, NULL);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN TOKEN STRING STRING ')' classflags {
+ if (strcmp ($<id>2, "GladeXML") == 0) {
+ glade_xml = TRUE;
+ add_construct_glade($<id>3, $<id>4, $<id>5);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
;
classcode: classcode thing { ; }
| initializer destructor { ; }
| initializer { destructor = NULL; }
| destructor { initializer = NULL; }
+ | TOKEN {
+ if (strcmp ($<id>1, "GladeXML") == 0) {
+ glade_widget = TRUE;
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
| {
destructor = NULL;
initializer = NULL;
| string { $<id>$ = $<id>1; }
;
-param_spec_value: NICK '=' string {
+param_spec_value: NAME '=' string {
+ ensure_property ();
+ node_set ((Node *)property,
+ "canonical_name:steal", gob_str_delete_quotes($<id>3),
+ NULL);
+ }
+ | NICK '=' string {
ensure_property ();
node_set ((Node *)property,
"nick:steal", $<id>3,
sigtype: TOKEN '(' tokenlist ')' {
gtktypes = g_list_prepend(gtktypes, debool ($<id>1));
}
+ | TOKEN STRING '(' tokenlist ')' {
+ gtktypes = g_list_prepend(gtktypes, debool ($<id>1));
+ signal_name=$<id>2;
+ }
;
tokenlist: tokenlist ',' TOKEN {
;
/*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"));
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, $<sigtype>3,NULL,
$<id>5, $<cbuf>10,$<line>1,
ccode_line, vararg, $<list>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"));
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, $<sigtype>4, NULL,
$<id>6, $<cbuf>11, $<line>2,
ccode_line, vararg, $<list>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"));
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, $<id>4,
$<cbuf>9, $<line>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"));
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, $<id>4,
$<cbuf>9, $<line>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,
$<id>3, $<cbuf>8, $<line>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, $<id>3,
$<id>6, $<cbuf>11,
$<line>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();
push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL,
$<id>1, $<cbuf>5, $<line>2,
ccode_line, FALSE, NULL);
+ } else if(strcmp($<id>1, "constructor")==0) {
+ push_init_arg($<id>3, FALSE);
+ push_function(NO_SCOPE, CONSTRUCTOR_METHOD, NULL,
+ $<id>1, $<cbuf>5, $<line>2,
+ ccode_line, FALSE, NULL);
+ } else if(strcmp($<id>1, "dispose")==0) {
+ push_init_arg($<id>3, FALSE);
+ push_function(NO_SCOPE, DISPOSE_METHOD, NULL,
+ $<id>1, $<cbuf>5, $<line>2,
+ ccode_line, FALSE, NULL);
+ } else if(strcmp($<id>1, "finalize")==0) {
+ push_init_arg($<id>3, FALSE);
+ push_function(NO_SCOPE, FINALIZE_METHOD, NULL,
+ $<id>1, $<cbuf>5, $<line>2,
+ ccode_line, FALSE, NULL);
+
} else {
g_free($<id>1);
g_free($<id>3);
g_string_free($<cbuf>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($<id>1, $<id>2)) {
+ if(!set_attr_value($<id>1, $<id>2)) {
g_free($<id>1);
g_free($<id>2);
yyerror(_("parse error"));
g_free($<id>1);
}
| TOKEN retcode TOKEN retcode {
+ g_free(funcattrs); funcattrs = NULL;
g_free(onerror); onerror = NULL;
g_free(defreturn); defreturn = NULL;
- if(!set_return_value($<id>1, $<id>2)) {
+ if(!set_attr_value($<id>1, $<id>2)) {
g_free($<id>1); g_free($<id>2);
g_free($<id>3); g_free($<id>4);
yyerror(_("parse error"));
YYERROR;
}
- if(!set_return_value($<id>3, $<id>4)) {
- onerror = defreturn = NULL;
+ if(!set_attr_value($<id>3, $<id>4)) {
+ funcattrs = onerror = defreturn = NULL;
g_free($<id>1); g_free($<id>2);
g_free($<id>3); g_free($<id>4);
yyerror(_("parse error"));
g_free($<id>1);
g_free($<id>3);
}
+ | TOKEN retcode TOKEN retcode TOKEN retcode {
+ g_free(funcattrs); funcattrs = NULL;
+ g_free(onerror); onerror = NULL;
+ g_free(defreturn); defreturn = NULL;
+ if(!set_attr_value($<id>1, $<id>2)) {
+ g_free($<id>1); g_free($<id>2);
+ g_free($<id>3); g_free($<id>4);
+ g_free($<id>5); g_free($<id>6);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ if(!set_attr_value($<id>3, $<id>4)) {
+ funcattrs = onerror = defreturn = NULL;
+ g_free($<id>1); g_free($<id>2);
+ g_free($<id>3); g_free($<id>4);
+ g_free($<id>5); g_free($<id>6);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ if(!set_attr_value($<id>5, $<id>6)) {
+ funcattrs = onerror = defreturn = NULL;
+ g_free($<id>1); g_free($<id>2);
+ g_free($<id>3); g_free($<id>4);
+ g_free($<id>5); g_free($<id>6);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ g_free($<id>1);
+ g_free($<id>3);
+ g_free($<id>5);
+ }
| {
+ g_free(funcattrs); funcattrs = NULL;
g_free(onerror); onerror = NULL;
g_free(defreturn); defreturn = NULL;
}