mirror of https://github.com/GNOME/gimp.git
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:
parent
6eb753a2b1
commit
f633c7da4e
|
@ -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..
|
||||
|
|
|
@ -5,4 +5,3 @@ Not in any order:
|
|||
- Pretty formatted comments from doc strings
|
||||
- HTML doc output
|
||||
- IDL output
|
||||
- Demarshallers
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue