/* 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
*
#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 char *chunk_size = NULL;
-static char *bonobo_x_class = NULL;
+static char *bonobo_object_class = NULL;
+static GList *interfaces = NULL;
static GList *typestack = NULL;
static GList *funcargs = NULL;
static GList *checks = NULL;
extern int ccode_line;
extern int line_no;
+extern gboolean for_cpp;
extern char *yytext;
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,
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
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); "
"} "
"}",
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);
+ }
+ }
+
+ 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,
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);
%token <cbuf> CCODE 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 FLAGS TYPE
+%token <line> NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE
%token <line> FLAGS_TYPE ENUM_TYPE PARAM_TYPE BOXED_TYPE OBJECT_TYPE
%%
;
ccodes: ccodes ccode { ; }
+ | ccodes enumcode { ; }
+ | ccodes flagcode { ; }
+ | ccodes errorcode { ; }
| ccode { ; }
+ | enumcode { ; }
+ | flagcode { ; }
+ | errorcode { ; }
;
class: classdec '{' classcode '}' {
class = node_new (CLASS_NODE,
"otype:steal", $<id>2,
"ptype:steal", $<id>4,
- "bonobo_x_class:steal", bonobo_x_class,
+ "bonobo_object_class:steal", bonobo_object_class,
+ "interfaces:steal", interfaces,
"chunk_size:steal", chunk_size,
NULL);
+ bonobo_object_class = NULL;
+ chunk_size = NULL;
+ interfaces = NULL;
}
;
if(strcmp($<id>2,"chunks") == 0) {
g_free (chunk_size);
chunk_size = g_strdup($<id>3);
- } else if(strcmp($<id>2,"BonoboX") == 0) {
- g_free (bonobo_x_class);
- bonobo_x_class = g_strdup($<id>3);
+ } else if(strcmp($<id>2,"BonoboObject") == 0) {
+ g_free (bonobo_object_class);
+ bonobo_object_class = g_strdup($<id>3);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN TYPETOKEN ')' classflags {
+ if (strcmp ($<id>2, "interface") == 0) {
+ interfaces = g_list_append (interfaces,
+ g_strdup ($<id>3));
} else {
yyerror(_("parse error"));
YYERROR;
thing: method { ; }
| TOKEN method {
- if (strcmp ($<id>1, "BonoboX") != 0) {
- g_free($<id>1);
- yyerror(_("parse error"));
+ if (strcmp ($<id>1, "BonoboObject") != 0) {
+ g_free ($<id>1);
+ yyerror (_("parse error"));
+ YYERROR;
+ }
+ g_free ($<id>1);
+ last_added_method->bonobo_object_func = TRUE;
+ }
+ | TOKEN TYPETOKEN method {
+ if (strcmp ($<id>1, "interface") != 0) {
+ g_free ($<id>1);
+ g_free ($<id>2);
+ yyerror (_("parse error"));
YYERROR;
}
- last_added_method->bonobo_x_func = TRUE;
+ g_free ($<id>1);
+ node_set ((Node *)last_added_method,
+ "interface:steal", $<id>2,
+ NULL);
}
| variable { ; }
| argument { ; }
char *get, *set = NULL;
Variable *var;
Type *type;
- char *root;
+ const char *root;
if(strcmp($<id>6, "link")!=0 &&
strcmp($<id>6, "stringlink")!=0 &&
type = pop_type();
var = find_var_or_die($<id>4, $<line>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, $<line>1,
_("Self aliases needed when autolinking to a classwide member"));
- } else
+ } else {
root = "self";
+ }
if(strcmp($<id>6, "link")==0) {
set = g_strdup_printf("%s->%s = ARG;",
"ptype:steal", type,
NULL);
}
+ | FLAGS_TYPE '=' TYPETOKEN {
+ ensure_property ();
+ node_set ((Node *)property,
+ "extra_gtktype:steal", $<id>3,
+ NULL);
+ }
| FLAGS_TYPE '=' TOKEN {
ensure_property ();
node_set ((Node *)property,
"extra_gtktype:steal", $<id>3,
NULL);
}
+ | ENUM_TYPE '=' TYPETOKEN {
+ ensure_property ();
+ node_set ((Node *)property,
+ "extra_gtktype:steal", $<id>3,
+ NULL);
+ }
| ENUM_TYPE '=' TOKEN {
ensure_property ();
node_set ((Node *)property,
"extra_gtktype:steal", $<id>3,
NULL);
}
+ | PARAM_TYPE '=' TYPETOKEN {
+ ensure_property ();
+ node_set ((Node *)property,
+ "extra_gtktype:steal", $<id>3,
+ NULL);
+ }
| PARAM_TYPE '=' TOKEN {
ensure_property ();
node_set ((Node *)property,
"extra_gtktype:steal", $<id>3,
NULL);
}
+ | BOXED_TYPE '=' TYPETOKEN {
+ ensure_property ();
+ node_set ((Node *)property,
+ "extra_gtktype:steal", $<id>3,
+ NULL);
+ }
| BOXED_TYPE '=' TOKEN {
ensure_property ();
node_set ((Node *)property,
"extra_gtktype:steal", $<id>3,
NULL);
}
+ | OBJECT_TYPE '=' TYPETOKEN {
+ ensure_property ();
+ node_set ((Node *)property,
+ "extra_gtktype:steal", $<id>3,
+ NULL);
+ }
| OBJECT_TYPE '=' TOKEN {
ensure_property ();
node_set ((Node *)property,
retcode: numtok { $<id>$ = $<id>1; }
| '{' CCODE {
- $<id>$ = ($<cbuf>3)->str;
- g_string_free($<cbuf>3, FALSE);
+ $<id>$ = ($<cbuf>2)->str;
+ g_string_free($<cbuf>2, FALSE);
}
;
checks = g_list_append(checks,node);
}
;
-
+
+enumcode: ENUM TOKEN '{' enumvals '}' TYPETOKEN ';' {
+ Node *node = node_new (ENUMDEF_NODE,
+ "etype:steal", $<id>6,
+ "prefix:steal", $<id>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", $<id>7,
+ "prefix:steal", $<id>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 = $<id>3;
+
+ /* A float value, that's a bad enum */
+ if (num[0] >= '0' &&
+ num[0] <= '9' &&
+ strchr (num, '.') != NULL) {
+ g_free ($<id>1);
+ g_free (num);
+ yyerror(_("parse error (enumerator value not integer constant)"));
+ YYERROR;
+ }
+
+ node = node_new (ENUMVALUE_NODE,
+ "name:steal", $<id>1,
+ "value:steal", num,
+ NULL);
+ enum_vals = g_list_append (enum_vals, node);
+ }
+ | TOKEN {
+ Node *node;
+
+ node = node_new (ENUMVALUE_NODE,
+ "name:steal", $<id>1,
+ NULL);
+ enum_vals = g_list_append (enum_vals, node);
+ }
+ ;
+
+flagcode: FLAGS TOKEN '{' flagvals '}' TYPETOKEN ';' {
+ Node *node = node_new (FLAGS_NODE,
+ "ftype:steal", $<id>6,
+ "prefix:steal", $<id>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", $<id>7,
+ "prefix:steal", $<id>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, $<id>3);
+ }
+ | TOKEN {
+ flag_vals = g_list_append (flag_vals, $<id>1);
+ }
+ ;
+
+errorcode: ERROR TOKEN '{' errorvals '}' TYPETOKEN ';' {
+ Node *node = node_new (ERROR_NODE,
+ "etype:steal", $<id>6,
+ "prefix:steal", $<id>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", $<id>7,
+ "prefix:steal", $<id>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, $<id>3);
+ }
+ | TOKEN {
+ error_vals = g_list_append (error_vals, $<id>1);
+ }
+ ;
+
+
numtok: NUMBER { $<id>$ = $<id>1; }
| '-' NUMBER {
$<id>$ = g_strconcat("-",$<id>2,NULL);