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 {
