
|
introduction, gob2 interface patch, misc
Hi everybody, I have recently started learning about GObject, GType, and DBus. It is a nice system and seems very well designed. But it is a bit rough and so I was led to find Gob2. It seems like just about exactly what I needed
for my purposes and so I wanted to use it but I found one small problem: no interface support. I have spent some time trying to add interface support to gob2. Since I have very little experience with GType it is a bit
challenging for me, however I think I have made some good progress. At this point I have a patch and wanted to find out if anybody else is interested. I think it is reasonably close to useful but would like more experienced
GObject opinions on the matter (maybe help finish whatever is still broken) before I move on to the next part of my project. I would also like to eventually get this functionality into the main Gob2 source base if we can figure
out how to properly clean it up. I had a look at the mailing list archives and it seems they might be broken; or is it just otherwise low activity? I attach the patch in this email. Best regards, Rudi
-- Democracy is two wolves and a sheep deciding what to eat for lunch. Liberty is a well-armed sheep contesting the vote.
[interface-gob2-2.0.14.patch] diff -r gob2-2.0.14/src/lexer.l gobnew/src/lexer.l
407a408,420
> interface {
> static int found_classes = 0;
> look_for_includes = 2;
> BEGIN(CLASS_CODE);
>
> if(++found_classes > 1) {
> error_print(GOB_ERROR, line_no,
> "Only one interface per file allowed");
> }
>
> return INTERFACE;
> }
>
diff -r gob2-2.0.14/src/main.c gobnew/src/main.c
1068c1068,1089
< out_printf(out,
---
> if (((Class *)class)->isinterface)
> out_printf(out,
> "GType\n"
> "%s_get_type (void)\n"
> "{\n"
> "\tstatic GType type = 0;\n\n"
> "\tif ___GOB_UNLIKELY(type == 0) {\n"
> "\t\tstatic const GTypeInfo info = {\n"
> "\t\t\tsizeof (%sClass),\n"
> "\t\t\t(GBaseInitFunc) %s_class_init,\n"
> "\t\t\t(GBaseFinalizeFunc) NULL,\n"
> "\t\t\t(GClassInitFunc) NULL,\n"
> "\t\t\t(GClassFinalizeFunc) NULL,\n"
> "\t\t\tNULL /* class_data */,\n"
> "\t\t\t0,\n"
> "\t\t\t0,\n"
> "\t\t\tNULL,\n"
> "\t\t\tNULL\n"
> "\t\t};\n\n",
> funcbase, typebase, funcbase);
> else
> out_printf(out,
2400,2401c2421,2427
<
< if(m->cbuf) {
---
> if (c->isinterface) {
> out_printf(out, " {\n");
> out_printf(out, " %s_GET_CLASS (self)->%s (self);",
> macrobase, m->id);
> out_printf(out, " }\n");
> }
> if(!c->isinterface && m->cbuf) {
diff -r gob2-2.0.14/src/parse.y gobnew/src/parse.y
47a48
> static gboolean isinterface = FALSE;
676c677
< %token CLASS FROM
---
> %token CLASS INTERFACE FROM
689,692c690,697
< prog: ccodes class ccodes { ; }
< | class ccodes { ; }
< | ccodes class { ; }
< | class { ; }
---
> prog: ccodes iclass ccodes { ; }
> | iclass ccodes { ; }
> | ccodes iclass { ; }
> | iclass { ; }
> ;
>
> iclass: class { ; }
> | interface { ; }
760a766,779
> interface: interfacedec '{' interfacecode '}' {
> ((Class *)class)->nodes = class_nodes;
> isinterface = TRUE;
> ((Class *)class)->isinterface = TRUE;
> class_nodes = NULL;
> nodes = g_list_append(nodes,class);
> }
> | interfacedec '{' '}' {
> ((Class *)class)->nodes = NULL;
> class_nodes = NULL;
> nodes = g_list_append(nodes,class);
> }
> ;
>
772a792,890
> interfacedec: INTERFACE TYPETOKEN FROM TYPETOKEN interfaceflags {
> class = node_new (CLASS_NODE,
> "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,
> "isinterface", isinterface,
> NULL);
> bonobo_object_class = NULL;
> glade_xml = FALSE;
> chunk_size = NULL;
> interfaces = NULL;
> isinterface = FALSE;
> }
> ;
>
> interfaceflags:
> | '(' TOKEN ')' interfaceflags {
> if(strcmp($<id>2,"abstract") == 0) {
> abstract = TRUE;
> } else {
> yyerror(_("parse error"));
> YYERROR;
> }
> }
> | '(' TOKEN TOKEN ')' interfaceflags {
> if(strcmp($<id>2,"chunks") == 0) {
> g_free (chunk_size);
> chunk_size = 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 ')' interfaceflags {
> if (strcmp ($<id>2, "interface") == 0) {
> interfaces = g_list_append (interfaces,
> g_strdup ($<id>3));
> } else {
> yyerror(_("parse error"));
> YYERROR;
> }
> }
> | '(' TOKEN NUMBER ')' interfaceflags {
> if(strcmp($<id>2,"chunks") == 0) {
> g_free (chunk_size);
> if(atoi($<id>3) != 0)
> chunk_size = g_strdup($<id>3);
> else
> chunk_size = NULL;
> } else {
> yyerror(_("parse error"));
> YYERROR;
> }
> }
> | '(' TOKEN STRING STRING ')' interfaceflags {
> 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 ')' interfaceflags {
> 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 ')' interfaceflags {
> 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 ')' interfaceflags {
> if (strcmp ($<id>2, "GladeXML") == 0) {
> glade_xml = TRUE;
> add_construct_glade($<id>3, $<id>4, $<id>5);
> } else {
> yyerror(_("parse error"));
> YYERROR;
> }
> }
> ;
>
873a992,1020
> interfacecode: interfacecode interfacething { ; }
> | interfacething { ; }
> ;
>
> interfacething: method { ; }
> | TOKEN method {
> 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;
> }
> g_free ($<id>1);
> node_set ((Node *)last_added_method,
> "interface:steal", $<id>2,
> NULL);
> }
> | ';' { ; }
> ;
>
diff -r gob2-2.0.14/src/treefuncs.c gobnew/src/treefuncs.c
108a109
> QUARK_isinterface,
216a218
> g_hash_table_insert (quark_ht, "isinterface", GINT_TO_POINTER (QUARK_isinterface));
365a368
> new->isinterface = self->isinterface;
957a961,965
> case QUARK_isinterface: {
> gboolean isinterface = va_arg (__ap, gboolean);
> self->isinterface = isinterface;
> break;
> }
diff -r gob2-2.0.14/src/treefuncs.def gobnew/src/treefuncs.def
59c59,60
< BOOL abstract # if G_TYPE_FLAG_ABSTRACT should be used
---
> BOOL abstract # if G_TYPE_FLAG_ABSTRACT should be used
> BOOL isinterface # if it is an interface instead of a class
diff -r gob2-2.0.14/src/treefuncs.h gobnew/src/treefuncs.h
121a122
> gboolean isinterface;
--
to unsubscribe:
send mail to minimalist@... with "unsubscribe gob-list" in the subject
|

|
Re: introduction, gob2 interface patch, misc
Sure; it is attached. I hope we can get this patch into something useful. Cheers, Rudi On 4/22/07, Behdad Esfahbod <behdad@...> wrote:On Sun, 2007-04-22 at 05:52 -0400, Rudi Cilibrasi, Ph.D
. wrote: > Hi everybody, > > I have recently started learning about GObject, GType, and DBus. It > is a nice system and seems very well > designed. But it is a bit rough and so I was led to find Gob2. It
> seems like just about exactly what I needed > for my purposes and so I wanted to use it but I found one small > problem: no interface support. I have spent > some time trying to add interface support to gob2. Since I have very
> little experience with GType it is a bit > challenging for me, however I think I have made some good progress. > At this point I have a patch and wanted > to find out if anybody else is interested. I think it is reasonably
> close to useful but would like more experienced > GObject opinions on the matter (maybe help finish whatever is still > broken) before I move on to the next part of > my project. I would also like to eventually get this functionality
> into the main Gob2 source base if we can figure > out how to properly clean it up. I had a look at the mailing list > archives and it seems they might be broken; or > is it just otherwise low activity? I attach the patch in this email.
> Best regards,
Nice work. Can you send the patch again, producing it with diff -u instead?
behdad
> Rudi > > -- > Democracy is two wolves and a sheep deciding what to eat for lunch.
> Liberty is a well-armed sheep contesting the vote. -- behdad http://behdad.org/
"Those who would give up Essential Liberty to purchase a little Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
-- Democracy is two wolves and a sheep deciding what to eat for lunch. Liberty is a well-armed sheep contesting the vote.
[interface-gob2u-2.0.14.patch] Only in gob2-2.0.14/src: lexer.c
diff -u gob2-2.0.14/src/lexer.l gobnew/src/lexer.l
--- gob2-2.0.14/src/lexer.l 2005-07-22 20:50:37.000000000 +0200
+++ gobnew/src/lexer.l 2007-04-22 11:45:14.000000000 +0200
@@ -405,6 +405,19 @@
<C_CODE>. { add_to_cbuf(yytext); }
<C_CODE>\n { add_to_cbuf(yytext); }
+interface {
+ static int found_classes = 0;
+ look_for_includes = 2;
+ BEGIN(CLASS_CODE);
+
+ if(++found_classes > 1) {
+ error_print(GOB_ERROR, line_no,
+ "Only one interface per file allowed");
+ }
+
+ return INTERFACE;
+ }
+
class {
static int found_classes = 0;
look_for_includes = 2;
diff -u gob2-2.0.14/src/main.c gobnew/src/main.c
--- gob2-2.0.14/src/main.c 2006-01-05 19:05:45.000000000 +0100
+++ gobnew/src/main.c 2007-04-22 11:45:14.000000000 +0200
@@ -1065,7 +1065,28 @@
{
/*char *chunk_size = ((Class*)class)->chunk_size;*/
- out_printf(out,
+ if (((Class *)class)->isinterface)
+ out_printf(out,
+ "GType\n"
+ "%s_get_type (void)\n"
+ "{\n"
+ "\tstatic GType type = 0;\n\n"
+ "\tif ___GOB_UNLIKELY(type == 0) {\n"
+ "\t\tstatic const GTypeInfo info = {\n"
+ "\t\t\tsizeof (%sClass),\n"
+ "\t\t\t(GBaseInitFunc) %s_class_init,\n"
+ "\t\t\t(GBaseFinalizeFunc) NULL,\n"
+ "\t\t\t(GClassInitFunc) NULL,\n"
+ "\t\t\t(GClassFinalizeFunc) NULL,\n"
+ "\t\t\tNULL /* class_data */,\n"
+ "\t\t\t0,\n"
+ "\t\t\t0,\n"
+ "\t\t\tNULL,\n"
+ "\t\t\tNULL\n"
+ "\t\t};\n\n",
+ funcbase, typebase, funcbase);
+ else
+ out_printf(out,
"GType\n"
"%s_get_type (void)\n"
"{\n"
@@ -2397,8 +2418,13 @@
}
} else
continue;
-
- if(m->cbuf) {
+ if (c->isinterface) {
+ out_printf(out, " {\n");
+ out_printf(out, " %s_GET_CLASS (self)->%s (self);",
+ macrobase, m->id);
+ out_printf(out, " }\n");
+ }
+ if(!c->isinterface && m->cbuf) {
out_printf(out, " {\n");
out_addline_infile(out, m->ccode_line);
out_printf(out, "%s\n", m->cbuf);
Only in gobnew/src: .main.c.swp
Only in gobnew/src: Makefile
Only in gobnew/src: o
Only in gob2-2.0.14/src: parse.c
Only in gob2-2.0.14/src: parse.h
diff -u gob2-2.0.14/src/parse.y gobnew/src/parse.y
--- gob2-2.0.14/src/parse.y 2005-12-16 20:11:20.000000000 +0100
+++ gobnew/src/parse.y 2007-04-22 11:45:14.000000000 +0200
@@ -45,6 +45,7 @@
static GList *error_vals = NULL;
static gboolean abstract = FALSE;
+static gboolean isinterface = FALSE;
static char *chunk_size = NULL;
static char *bonobo_object_class = NULL;
static int glade_xml = FALSE;
@@ -673,7 +674,7 @@
int sigtype;
}
-%token CLASS FROM
+%token CLASS INTERFACE FROM
%token CONST VOID STRUCT UNION ENUM THREEDOTS
%token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR
@@ -686,10 +687,14 @@
%%
-prog: ccodes class ccodes { ; }
- | class ccodes { ; }
- | ccodes class { ; }
- | class { ; }
+prog: ccodes iclass ccodes { ; }
+ | iclass ccodes { ; }
+ | ccodes iclass { ; }
+ | iclass { ; }
+ ;
+
+iclass: class { ; }
+ | interface { ; }
;
ccode: CCODE {
@@ -758,6 +763,20 @@
| errorcode { ; }
;
+interface: interfacedec '{' interfacecode '}' {
+ ((Class *)class)->nodes = class_nodes;
+ isinterface = TRUE;
+ ((Class *)class)->isinterface = TRUE;
+ class_nodes = NULL;
+ nodes = g_list_append(nodes,class);
+ }
+ | interfacedec '{' '}' {
+ ((Class *)class)->nodes = NULL;
+ class_nodes = NULL;
+ nodes = g_list_append(nodes,class);
+ }
+ ;
+
class: classdec '{' classcode '}' {
((Class *)class)->nodes = class_nodes;
class_nodes = NULL;
@@ -770,6 +789,105 @@
}
;
+interfacedec: INTERFACE TYPETOKEN FROM TYPETOKEN interfaceflags {
+ class = node_new (CLASS_NODE,
+ "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,
+ "isinterface", isinterface,
+ NULL);
+ bonobo_object_class = NULL;
+ glade_xml = FALSE;
+ chunk_size = NULL;
+ interfaces = NULL;
+ isinterface = FALSE;
+ }
+ ;
+
+interfaceflags:
+ | '(' TOKEN ')' interfaceflags {
+ if(strcmp($<id>2,"abstract") == 0) {
+ abstract = TRUE;
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN TOKEN ')' interfaceflags {
+ if(strcmp($<id>2,"chunks") == 0) {
+ g_free (chunk_size);
+ chunk_size = 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 ')' interfaceflags {
+ if (strcmp ($<id>2, "interface") == 0) {
+ interfaces = g_list_append (interfaces,
+ g_strdup ($<id>3));
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN NUMBER ')' interfaceflags {
+ if(strcmp($<id>2,"chunks") == 0) {
+ g_free (chunk_size);
+ if(atoi($<id>3) != 0)
+ chunk_size = g_strdup($<id>3);
+ else
+ chunk_size = NULL;
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | '(' TOKEN STRING STRING ')' interfaceflags {
+ 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 ')' interfaceflags {
+ 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 ')' interfaceflags {
+ 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 ')' interfaceflags {
+ if (strcmp ($<id>2, "GladeXML") == 0) {
+ glade_xml = TRUE;
+ add_construct_glade($<id>3, $<id>4, $<id>5);
+ } else {
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ ;
+
classdec: CLASS TYPETOKEN FROM TYPETOKEN classflags {
class = node_new (CLASS_NODE,
"otype:steal", $<id>2,
@@ -871,6 +989,35 @@
| thing { ; }
;
+interfacecode: interfacecode interfacething { ; }
+ | interfacething { ; }
+ ;
+
+interfacething: method { ; }
+ | TOKEN method {
+ 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;
+ }
+ g_free ($<id>1);
+ node_set ((Node *)last_added_method,
+ "interface:steal", $<id>2,
+ NULL);
+ }
+ | ';' { ; }
+ ;
+
thing: method { ; }
| TOKEN method {
if (strcmp ($<id>1, "BonoboObject") != 0) {
Only in gobnew/src: t2.gob
diff -u gob2-2.0.14/src/treefuncs.c gobnew/src/treefuncs.c
--- gob2-2.0.14/src/treefuncs.c 2005-12-16 20:11:38.000000000 +0100
+++ gobnew/src/treefuncs.c 2007-04-22 11:45:14.000000000 +0200
@@ -106,6 +106,7 @@
QUARK_nodes,
QUARK_nodes_STEAL,
QUARK_abstract,
+ QUARK_isinterface,
QUARK_name,
QUARK_name_STEAL,
QUARK_pointer,
@@ -214,6 +215,7 @@
g_hash_table_insert (quark_ht, "nodes", GINT_TO_POINTER (QUARK_nodes));
g_hash_table_insert (quark_ht, "nodes:steal", GINT_TO_POINTER (QUARK_nodes_STEAL));
g_hash_table_insert (quark_ht, "abstract", GINT_TO_POINTER (QUARK_abstract));
+ g_hash_table_insert (quark_ht, "isinterface", GINT_TO_POINTER (QUARK_isinterface));
g_hash_table_insert (quark_ht, "name", GINT_TO_POINTER (QUARK_name));
g_hash_table_insert (quark_ht, "name:steal", GINT_TO_POINTER (QUARK_name_STEAL));
g_hash_table_insert (quark_ht, "pointer", GINT_TO_POINTER (QUARK_pointer));
@@ -363,6 +365,7 @@
new->interfaces = g_list_copy (self->interfaces); COPY_LIST_VALS(new->interfaces, g_strdup);
new->nodes = node_list_copy (self->nodes);
new->abstract = self->abstract;
+ new->isinterface = self->isinterface;
return new;
}
@@ -955,6 +958,11 @@
self->abstract = abstract;
break;
}
+ case QUARK_isinterface: {
+ gboolean isinterface = va_arg (__ap, gboolean);
+ self->isinterface = isinterface;
+ break;
+ }
default:
g_warning ("Argument named 'Class::%s' does not exist", arg);
break;
diff -u gob2-2.0.14/src/treefuncs.def gobnew/src/treefuncs.def
--- gob2-2.0.14/src/treefuncs.def 2005-12-16 20:11:20.000000000 +0100
+++ gobnew/src/treefuncs.def 2007-04-22 11:45:14.000000000 +0200
@@ -56,7 +56,8 @@
STRING chunk_size # if the object should be allocated with mem_chunks
STRINGLIST interfaces # GObject interfaces this class exports
NODELIST nodes
- BOOL abstract # if G_TYPE_FLAG_ABSTRACT should be used
+ BOOL abstract # if G_TYPE_FLAG_ABSTRACT should be used
+ BOOL isinterface # if it is an interface instead of a class
ENDCLASS
CLASS Type
diff -u gob2-2.0.14/src/treefuncs.h gobnew/src/treefuncs.h
--- gob2-2.0.14/src/treefuncs.h 2005-12-16 20:11:38.000000000 +0100
+++ gobnew/src/treefuncs.h 2007-04-22 11:45:14.000000000 +0200
@@ -119,6 +119,7 @@
GList * interfaces;
GList * nodes;
gboolean abstract;
+ gboolean isinterface;
};
struct _EnumDef {
--
to unsubscribe:
send mail to minimalist@... with "unsubscribe gob-list" in the subject
|