Added signal demarshallers. Currently they are generated for

each module (= compilation unit) separately, which is bound to
cause some code duplication..
This commit is contained in:
Lauri Alanko 1998-11-21 20:24:18 +00:00
parent 6eb753a2b1
commit f633c7da4e
9 changed files with 161 additions and 77 deletions

View File

@ -1,5 +1,9 @@
1998-11-21 Lauri Alanko <la@iki.fi>
* Added signal demarshallers. Currently they are generated for
each module (= compilation unit) separately, which is bound to
cause some code duplication..
* Added import headers and some more example stuff.
* It actually runs now, with a zillion caveats, but anyway..

View File

@ -5,4 +5,3 @@ Not in any order:
- Pretty formatted comments from doc strings
- HTML doc output
- IDL output
- Demarshallers

View File

@ -6,7 +6,7 @@ import g;
class Ostream {
public virtual void putchar (char c);
public virtual void putstring (char* str);
public virtual void flush ();
public virtual void close ();
public pre-emit void putstring (char* str);
public pre-emit void flush ();
public pre-emit void close ();
}

View File

@ -1,7 +1,19 @@
#include <ex/file_ostream_i.h>
void putstring_handler(Ostream* o, gchar* msg, gpointer data){
gchar* s = data;
g_print("Putstring: %s (%p), \"%s\"..\n", s, o, msg);
}
void close_handler(Ostream* o, gpointer data){
gchar* s = data;
g_print("Closed: %s (%p)!\n", s, o);
}
int main(void){
Ostream* x = OSTREAM(file_ostream_open("foo"));
ostream_connect_putstring(putstring_handler, "foo", x);
ostream_connect_close(close_handler, "foo", x);
ostream_putstring(x, "Whammo!\n");
ostream_close(x);
return 0;

View File

@ -5,6 +5,7 @@
#include "parse.h"
#include <unistd.h>
#include "output.h"
#include "marshall.h"
#ifndef CPP
#define CPP "cpp"
@ -123,11 +124,13 @@ int main(int argc, char* argv[]){
if(!f)
g_error("Unable to open file %s: %s",
source_name, strerror(errno));
p_write(p_fmt("~~~"
p_write(p_fmt("~~~~~"
"#include \"~\"\n",
p_col("source_prot_depends", p_prot_include),
p_col("source_head", NULL),
p_col("source_sigtypes", p_sigdemarsh_decl),
p_col("source", NULL),
p_col("source_sigtypes", p_demarshaller),
p_str(impl_name)),
f, out);
fclose(f);
@ -147,7 +150,8 @@ int main(int argc, char* argv[]){
out);
open_out(p_prot_header, "prot",
p_fmt("~~~",
p_fmt("~~~~",
p_func_include(current_module),
p_col("prot_parent_depends", p_prot_include),
p_col("prot_depends", p_type_include),
p_col("protected", NULL)),

View File

@ -3,6 +3,8 @@
#include "marshall.h"
static GHashTable* sigtype_hash;
typedef enum {
MARSHALL_INT,
MARSHALL_DOUBLE,
@ -14,6 +16,7 @@ typedef enum {
struct _SignalType {
Id package;
Id module;
MarshallType rettype;
GSList* argtypes;
};
@ -42,12 +45,18 @@ MarshallType marshalling_type(Type* t){
}
}
/* Yes, this is hyperbly kludgetical */
SignalType* sig_type(Method* m){
SignalType *t=g_new(SignalType, 1);
SignalType *t=g_new(SignalType, 1), *s;
GSList* p=m->params, *a=NULL;
PNode* g;
gchar* f;
t->package = DEF(MEMBER(m)->my_class)->type->module->package->name;
t->module = DEF(MEMBER(m)->my_class)->type->module->name;
t->rettype = marshalling_type(&m->ret_type);
if(!sigtype_hash)
sigtype_hash = g_hash_table_new(g_str_hash, g_str_equal);
while(p){
Param* param=p->data;
MarshallType* t=g_new(MarshallType, 1);
@ -57,7 +66,19 @@ SignalType* sig_type(Method* m){
}
a=g_slist_reverse(a);
t->argtypes=a;
return t;
g = p_signal_demarshaller_name(t);
f = p_to_str(g, NULL);
p_unref(g);
s = g_hash_table_lookup(sigtype_hash, f);
if(!s){
g_hash_table_insert(sigtype_hash, f, t);
return t;
}
else{
sig_type_free(t);
g_free(f);
return s;
}
}
void sig_type_free(SignalType* t){
@ -70,32 +91,52 @@ void sig_type_free(SignalType* t){
g_free(t);
}
PNode* p_gtype_name(MarshallType t, gboolean abbr){
typedef enum{
GTKNAME,
ENCODING,
CTYPE
} MMap;
PNode* p_gtype_name(MarshallType t, MMap map){
static const struct GTypeName{
MarshallType type;
Id name;
Id aname;
Id gtkname;
Id encoding;
Id ctype;
}names[]={
{MARSHALL_POINTER, "POINTER", "P"},
{MARSHALL_INT, "INT", "I"},
{MARSHALL_DOUBLE, "DOUBLE", "D"},
{MARSHALL_LONG, "LONG", "L"},
{MARSHALL_VOID, "NONE", "0"},
{MARSHALL_POINTER, "POINTER", "P", "gpointer"},
{MARSHALL_INT, "INT", "I", "gint"},
{MARSHALL_DOUBLE, "DOUBLE", "D", "gdouble"},
{MARSHALL_LONG, "LONG", "L", "glong"},
{MARSHALL_VOID, "NONE", "0", "void"},
};
gint i;
for(i=0;i<(gint)(sizeof(names)/sizeof(names[0]));i++)
if(names[i].type==t)
return p_str(abbr
?names[i].aname
:names[i].name);
if(names[i].type==t){
Id id;
switch(map){
case GTKNAME:
id = names[i].gtkname;
break;
case ENCODING:
id = names[i].encoding;
break;
case CTYPE:
id = names[i].ctype;
break;
}
return p_str(id);
}
g_assert_not_reached();
return NULL;
}
PNode* p_gtabbr(gpointer p){
MarshallType* t=p;
return p_gtype_name(*t, TRUE);
return p_gtype_name(*t, ENCODING);
}
@ -136,11 +177,20 @@ PNode* p_gtktype(Type* t){
PNode* p_signal_func_name(SignalType* t, PNode* basename){
return p_fmt("_~_~_~_~",
#if 1
return p_fmt("_~_~_~_~~",
p_c_ident(t->package),
p_c_ident(t->module),
basename,
p_gtype_name(t->rettype, ENCODING),
p_for(t->argtypes, p_gtabbr, p_nil));
#else
return p_fmt("_~_~_~~",
p_c_ident(t->package),
basename,
p_gtype_name(t->rettype, TRUE),
p_gtype_name(t->rettype, ENCODING),
p_for(t->argtypes, p_gtabbr, p_nil));
#endif
}
PNode* p_signal_marshaller_name(SignalType* t){
@ -152,10 +202,18 @@ PNode* p_signal_demarshaller_name(SignalType* t){
}
PNode* p_handler_type(SignalType* t){
return p_fmt("_~Handler_~_~",
#if 1
return p_fmt("_~~Handler_~~",
p_str(t->package),
p_gtype_name(t->rettype, TRUE),
p_str(t->module),
p_gtype_name(t->rettype, ENCODING),
p_for(t->argtypes, p_gtabbr, p_nil));
#else
return p_fmt("_~Handler_~~",
p_str(t->package),
p_gtype_name(t->rettype, ENCODING),
p_for(t->argtypes, p_gtabbr, p_nil));
#endif
}
PNode* p_signal_id(Method* s){
@ -179,7 +237,7 @@ PNode* p_arg_marsh(gpointer p, gpointer d){
"\tGTK_VALUE_~(args[~]) = ~;\n",
/* p_prf("%d", *idx),
p_gtktype(&par->type), */
p_gtype_name(marshalling_type(&par->type), FALSE),
p_gtype_name(marshalling_type(&par->type), GTKNAME),
p_prf("%d", *idx),
p_c_ident(par->name));
}
@ -217,18 +275,44 @@ PNode* p_sig_marshalling(Method* m){
PNode* p_arg_demarsh(gpointer p, gpointer d){
MarshallType* t=p;
ArgMarshData* data=d;
return p_fmt("\t\tGTK_VALUE_~(~[~]),\n",
gint* data=d;
(*data)++;
return p_fmt("\t\tGTK_VALUE_~(args[~]),\n",
p_gtype_name(*t, FALSE),
data->args,
p_fmt("%d", data->idx++));
p_prf("%d", *data));
}
PNode* p_sig_arg_ctype(MarshallType* t){
return p_fmt(", ~", p_gtype_name(*t, CTYPE));
}
PNode* p_sigdemarsh_decl(SignalType* t){
#if 1
return p_fmt("static void ~ (GtkObject*, GtkSignalFunc, "
"gpointer, GtkArg*);\n"
"typedef ~ (*~)(GtkObject*~, gpointer);\n",
p_signal_demarshaller_name(t),
p_gtype_name(t->rettype, CTYPE),
p_handler_type(t),
p_for(t->argtypes, p_sig_arg_ctype, p_nil));
#else
return p_fmt("extern void ~ (GtkObject*, GtkSignalFunc, "
"gpointer, GtkArg*);\n",
p_signal_demarshaller_name(t));
#endif
}
PNode* p_demarshaller(SignalType* t){
gint idx=0;
return p_fmt("~~",
gint idx=-1;
return p_fmt("static void ~ (\n"
"\tGtkObject* object,\n"
"\tGtkSignalFunc func,\n"
"\tgpointer user_data,\n"
"\tGtkArg* args){\n"
"\t(void)args;\n"
"~~"
"}\n",
p_signal_demarshaller_name(t),
(t->rettype==TYPE_NONE)
? p_fmt("\t*(GTK_RETLOC_~(args[~])) =\n",
p_gtype_name(t->rettype, FALSE),
@ -240,5 +324,3 @@ PNode* p_demarshaller(SignalType* t){
p_cast(p_handler_type(t), p_str("func")),
p_for(t->argtypes, p_arg_demarsh, &idx)));
}

View File

@ -14,6 +14,10 @@ PNode* p_arg_marsh(gpointer p, gpointer d);
PNode* p_gtktype(Type* t);
PNode* p_signal_id(Method* s);
PNode* p_sig_marshalling(Method* m);
PNode* p_sigdemarsh_decl(SignalType* t);
PNode* p_demarshaller(SignalType* t);
#endif

View File

@ -128,7 +128,7 @@ void output_connector(PRoot* out, Method* m){
m->ret_type.prim?p_str("return "):p_nil,
p_self_name(MEMBER(m)),
p_str(MEMBER(m)->name)));
output_var_import(out, m->ret_type.prim,
output_var_import(out, DEF(MEMBER(m)->my_class)->type,
p_fmt("connect_~",
p_c_ident(MEMBER(m)->name)));
}
@ -168,10 +168,7 @@ void output_method(PRoot* out, Method* m){
p_signal_id(m));
o.names=FALSE;
o.types=TRUE;
pr_put(out, "class_init_head",
p_fmt("\textern void ~ (GtkObject*, GtkSignalFunc, "
"gpointer, GtkArg*);\n",
p_signal_demarshaller_name(sig)));
pr_put(out, "source_sigtypes", sig);
pr_put(out, "member_class_init",
p_fmt("\t~ =\n"
"\tgtk_signal_new(\"~\",\n"
@ -184,8 +181,7 @@ void output_method(PRoot* out, Method* m){
"~);\n"
"\tgtk_object_class_add_signals(obklass,\n"
"\t\t&~,\n"
"\t\t1);\n"
"\t}\n",
"\t\t1);\n",
p_signal_id(m),
p_str(MEMBER(m)->name),
p_str(m->kind==METH_EMIT_PRE
@ -415,7 +411,7 @@ void output_object_init(PRoot* out, ObjectDef* o){
void output_class_init(PRoot* out, ObjectDef* o){
pr_put(out, "source_head",
p_fmt("static inline void ~ (~* klass);\n",
p_fmt("static void ~ (~* klass);\n",
p_varname(DEF(o)->type, p_str("class_init_real")),
p_class_name(DEF(o)->type)));
output_func(out, NULL,
@ -426,8 +422,8 @@ void output_class_init(PRoot* out, ObjectDef* o){
NULL,
p_fmt("\tGtkObjectClass* obklass = "
"(GtkObjectClass*) klass;\n"
"\t(void) obklass;\n"
"~"
"\t(void) obklass;\n"
"~"
"\t~ (klass);\n",
p_col("class_init_head", NULL),
@ -439,7 +435,6 @@ void output_object(PRoot* out, Def* d){
ObjectDef* o = (ObjectDef*)d;
pr_put(out, "func_depends", d->type->module);
pr_put(out, "func_parent_depends", o->parent->module);
pr_put(out, "prot_depends", d->type->module);
pr_put(out, "prot_parent_depends", o->parent->module);
pr_put(out, "source_prot_depends", d->type->module);
pr_put(out, "import_depends", o->parent->module);

View File

@ -114,23 +114,6 @@ void p_unref(PNode* node){
g_mem_chunk_free(p_node_chunk, node);
}
typedef struct{
FILE* f;
PRoot* p;
PNode* n;
} PCollect;
void cb_pwrite(gpointer key, gpointer value, gpointer data){
PCollect* c = data;
PNodeCreateFunc func = c->n->u.c.func;
(void)key;
if(func)
p_write(func(value), c->f, c->p);
else
p_write(value, c->f, c->p);
}
void p_write(PNode* node, FILE* f, PRoot* r){
g_assert(f);
BE_NODE(node);
@ -150,14 +133,17 @@ void p_write(PNode* node, FILE* f, PRoot* r){
break;
case NODE_COLLECT:
if(r){
GHashTable* h = g_datalist_id_get_data(&r->data,
node->u.c.tag);
PCollect c;
c.f = f;
c.p = r;
c.n = node;
if(h)
g_hash_table_foreach(h, cb_pwrite, &c);
GList* l = g_datalist_id_get_data(&r->data,
node->u.c.tag);
l = g_list_last(l);
if(node->u.c.func)
for(; l; l = l->prev)
p_write(node->u.c.func(l->data),
f, r);
else
for(; l; l = l->prev)
p_write(l->data, f, r);
}
break;
}
@ -297,13 +283,11 @@ PRoot* pr_new(void){
}
*/
void pr_put(PRoot* pr, const gchar* tag, gpointer datum){
GHashTable* h = g_datalist_get_data(&pr->data, tag);
if(!h){
h = g_hash_table_new(NULL, NULL);
g_datalist_set_data(&pr->data, tag, h);
}
GList* l = g_datalist_get_data(&pr->data, tag);
g_hash_table_insert(h, datum, datum);
if(!g_list_find(l, datum))
g_datalist_set_data(&pr->data, tag,
g_list_prepend(l, datum));
}