Commit a8abef06 authored by Lauri Alanko's avatar Lauri Alanko
Browse files

Changed lotsa internal stuff. Started work on signal wrappers

and marshallers.
parent 4d0d391c
1998-11-14 Lauri Alanko <la@iki.fi>
* Changed lotsa internal stuff. Started work on signal wrappers
and marshallers.
1998-10-24 Lauri Alanko <la@iki.fi>
* Redid the backend. It takes more time and memory now, but should
......
......@@ -31,6 +31,8 @@ gcg_SOURCES = \
output_enum.c \
output_flags.c \
output_object.c \
fp.c \
marshall.c \
parser.h
gcg_DEPENDS = parser.h
......
#include "gcg.h"
void put_decl(PrimType* t){
g_hash_table_insert(decl_hash, &t->name, t);
static GHashTable* module_hash;
void init_db(void){
module_hash=g_hash_table_new(NULL, NULL);
}
PrimType* get_type(Id modname, Id name){
Module* m = get_mod(modname);
PrimType* p = g_hash_table_lookup(m->decl_hash, name);
if(!p){
p=g_new(PrimType, 1);
p->module=m;
p->name=name;
p->kind=GTK_TYPE_INVALID;
p->decl_header=NULL;
p->def_header=NULL;
p->definition=NULL;
g_hash_table_insert(m->decl_hash, name, p);
}
return p;
}
void put_def(Def* d){
g_hash_table_insert(def_hash, &d->type->name, d);
PrimType* t=d->type;
g_assert(t);
t->definition=d;
}
Def* get_def(Id modname, Id type){
PrimType* t=get_type(modname, type);
g_assert(t);
return t->definition;
}
Def* get_def(Id module, Id type){
TypeName n;
n.module=module;
n.type=type;
return g_hash_table_lookup(def_hash, &n);
Module* get_mod(Id modname){
Module* m=g_hash_table_lookup(module_hash, modname);
if(!m){
m=g_new(Module, 1);
m->name=modname;
m->decl_hash=g_hash_table_new(NULL, NULL);
m->common_header=NULL;
g_hash_table_insert(module_hash, modname, m);
}
return m;
}
PrimType* get_decl(Id module, Id type){
TypeName n;
n.module=module;
n.type=type;
return g_hash_table_lookup(decl_hash, &n);
typedef struct{
DefFunc f;
gpointer user_data;
}DFEdata;
void dfe_bar(gpointer key, gpointer p, gpointer foo){
PrimType* t=p;
DFEdata* d=foo;
if(t->definition)
(d->f)(t->definition, d->user_data);
}
void dfe_foo(gpointer key, gpointer p, gpointer dfed){
Module* m=p;
g_hash_table_foreach(m->decl_hash, dfe_bar, dfed);
}
void foreach_def(DefFunc f, gpointer user_data){
DFEdata d={f,user_data};
g_hash_table_foreach(module_hash, dfe_foo, &d);
};
#include "output.h"
FunParams* fparams(const gchar* fmt, ...){
FunParams* first;
FunParams** last=&first;
gint i;
va_list args;
va_start(args, fmt);
for(i=0;fmt[i];i++) switch(fmt[i]){
FunParams* f;
GSList* l;
case 'p':
l=va_arg(args, GSList*);
while(l){
Param* p=l->data;
f=g_new(FunParams, 1);
f->type=p->type;
f->name=p_c_ident(p->name);
f->doc=p_nil;
*last=f;
last=&f->next;
l=l->next;
}
break;
case 't':
f=g_new(FunParams, 1);
f->type=*va_arg(args, Type*);
f->name=va_arg(args, PNode*);
p_ref(f->name);
f->doc=va_arg(args, PNode*);
p_ref(f->doc);
*last=f;
last=&f->next;
break;
case 's':
f=g_new(FunParams, 1);
f->type.prim=va_arg(args, PrimType*);
f->type.indirection=va_arg(args, gint);
f->type.notnull=va_arg(args, gboolean);
f->name=va_arg(args, PNode*);
p_ref(f->name);
f->doc=va_arg(args, PNode*);
p_ref(f->doc);
*last=f;
last=&f->next;
break;
}
*last=NULL;
return first;
}
void fparams_free(FunParams* f){
while(f){
FunParams* n=f->next;
p_unref(f->name);
p_unref(f->doc);
g_free(f);
f=n;
}
}
......@@ -5,13 +5,6 @@
#include <unistd.h>
#include "output.h"
GHashTable* decl_hash;
GHashTable* def_hash;
Id current_module;
Method* current_method;
ObjectDef* current_class;
Id current_header;
GSList* imports;
Type* type_gtk_type;
Id func_hdr_name;
......@@ -54,30 +47,21 @@ void get_options(int argc, char* argv[]){
}while(x!=EOF);
}
guint type_name_hash(gconstpointer c){
const TypeName* t=c;
return g_str_hash(t->module) ^ g_str_hash(t->type);
}
gboolean type_name_cmp(gconstpointer a, gconstpointer b){
const TypeName *t1=a, *t2=b;
return (t1->type == t2->type) && (t1->module == t2->module);
}
void output_cb(gpointer typename, gpointer def, gpointer ctx){
(void)typename; /* Shut off warnings */
output_def(ctx, def);
void output_cb(Def* def, gpointer out){
output_def(out, def);
}
int main(int argc, char* argv[]){
/* target=stdout;*/
OutCtx ctx;
PRoot* out=pr_new();
const gchar* tag_type="type";
const gchar* tag_source="source";
const gchar* tag_source_head="source_head";
const gchar* tag_functions="functions";
const gchar* tag_protected="protected";
FILE* f;
decl_hash=g_hash_table_new(type_name_hash, type_name_cmp);
def_hash=g_hash_table_new(type_name_hash, type_name_cmp);
init_db();
yydebug=0;
get_options(argc, argv);
yyin=fopen(argv[optind], "r");
......@@ -87,24 +71,19 @@ int main(int argc, char* argv[]){
type_gtk_type->is_const=FALSE;
type_gtk_type->indirection=0;
type_gtk_type->notnull=FALSE;
type_gtk_type->prim=get_decl(GET_ID("Gtk"), GET_ID("Type"));
type_gtk_type->prim=get_type(GET_ID("Gtk"), GET_ID("Type"));
g_assert(type_gtk_type->prim);
ctx.type_hdr=pr_new();
ctx.func_hdr=pr_new();
ctx.prot_hdr=pr_new();
ctx.pvt_hdr=pr_new();
ctx.src=pr_new();
g_hash_table_foreach(def_hash, output_cb, &ctx);
foreach_def(output_cb, out);
f=fopen(type_hdr_name, "w+");
pr_write(ctx.type_hdr, f);
pr_write(out, f, &tag_type, 1);
f=fopen(source_name, "w+");
pr_write(ctx.pvt_hdr, f);
pr_write(ctx.src, f);
pr_write(out, f, &tag_source_head, 1);
pr_write(out, f, &tag_source, 1);
f=fopen(func_hdr_name, "w+");
pr_write(ctx.func_hdr, f);
pr_write(out, f, &tag_functions, 1);
f=fopen(prot_hdr_name, "w+");
pr_write(ctx.prot_hdr, f);
pr_write(out, f, &tag_protected, 1);
return 0;
}
......
......@@ -12,7 +12,6 @@ typedef const gchar* Id;
typedef const gchar* Header;
typedef struct _Member Member;
typedef struct _TypeName TypeName;
typedef struct _PrimType PrimType;
typedef struct _Type Type;
typedef struct _ObjectDef ObjectDef;
......@@ -24,17 +23,22 @@ typedef struct _Method Method;
typedef struct _MemberClass MemberClass;
typedef struct _DefClass DefClass;
typedef struct _Param Param;
typedef struct _Module Module;
struct _TypeName {
Id module;
Id type;
struct _Module {
Id name;
Id common_header;
GHashTable* decl_hash;
};
struct _PrimType {
TypeName name;
Module* module;
Id name;
GtkFundamentalType kind;
Id decl_header;
Id def_header;
Def* definition;
};
struct _Type {
......@@ -59,6 +63,7 @@ extern DefClass enum_class;
struct _EnumDef {
Def def;
PrimType* parent;
GSList* alternatives; /* list of Id */
};
......@@ -66,6 +71,7 @@ extern DefClass flags_class;
struct _FlagsDef {
Def def;
PrimType* parent; /* flags to extend */
GSList* flags; /* list of Id */
};
......@@ -79,16 +85,10 @@ struct _ObjectDef {
};
typedef enum {
KIND_DIRECT,
KIND_ABSTRACT,
KIND_STATIC
} MemberKind;
typedef enum {
VIS_PUBLIC,
VIS_PROTECTED,
METH_PUBLIC,
METH_PROTECTED,
VIS_PRIVATE
} Visibility;
} MethProtection;
typedef enum {
DATA_READWRITE,
......@@ -105,13 +105,25 @@ typedef enum _EmitDef{
typedef enum _MemberType{
MEMBER_DATA,
MEMBER_METHOD,
MEMBER_SIGNAL
} MemberType;
typedef enum _DataMemberKind{
DATA_STATIC,
DATA_DIRECT,
DATA_STATIC_VIRTUAL
} DataMemberKind;
typedef enum _MethodKind{
METH_STATIC,
METH_DIRECT,
METH_VIRTUAL,
METH_EMIT_PRE,
METH_EMIT_POST,
METH_EMIT_BOTH
} MethodKind;
struct _Member{
MemberType membertype;
MemberKind kind;
ObjectDef* my_class;
Id name;
GString* doc;
......@@ -121,19 +133,20 @@ struct _Member{
struct _DataMember {
Member member;
DataMemberKind kind;
DataProtection prot;
Type type;
};
struct _Method {
Member member;
Visibility prot;
MethodKind kind;
MethProtection prot;
GSList* params; /* list of Param* */
gboolean self_const;
Type ret_type;
};
struct _Param {
Id name;
Method* method;
......@@ -141,22 +154,21 @@ struct _Param {
Type type;
};
typedef void (*DefFunc)(Def* def, gpointer user_data);
void init_db(void);
void put_decl(PrimType* t);
void put_def(Def* d);
PrimType* get_decl(Id module, Id type);
PrimType* get_type(Id module, Id type);
Def* get_def(Id module, Id type);
Module* get_mod(Id module);
void foreach_def(DefFunc f, gpointer user_data);
extern Type* type_gtk_type;
extern Id current_header;
extern Id current_module;
extern ObjectDef* current_class;
extern GSList* imports;
extern Method* current_method;
extern GHashTable* def_hash;
extern GHashTable* decl_hash;
......
// this is just a simple test input file
module g {
header <glib.h> {
@int int;
};
@int int;
};
module Gtk {
header <gtk/gtktypeutils.h> {
@int Type;
};
@int Type;
};
module Gimp{
header <gimpobject.h> {
class Object;
};
header <gimplayer.h> {
class Layer;
};
header <gimpdrawable.h> {
class Drawable;
};
header <gimpimage.h> {
class Image;
enum ImageType;
enum ChannelType;
enum BaseType;
};
enum ImageType{
rgb, rgba, gray, graya, indexed, indexeda
};
enum ChannelType{
red, green, blue, gray, indexed, auxillary
};
enum BaseType{
};
module Gimp;
enum ImageType{
rgb, rgba, gray, graya, indexed, indexeda
};
enum ChannelType{
red, green, blue, gray, indexed, auxillary
};
enum BaseType{
rgb, gray, indexed
};
};
class Image : Object{
read-only g.int width;
read-only g.int height;
g.int num-cols;
read-only BaseType base-type;
Layer* active-layer;
Layer* floating-sel;
public static Image* new(g.int width,
g.int height,
BaseType base-type);
};
class Image : Object{
read-only g.int width;
read-only g.int height;
g.int num-cols;
read-only BaseType base-type;
read-write g.int foobar;
Layer* active-layer;
Layer* floating-sel;
public static Image* new(g.int width,
g.int height,
BaseType base-type);
public void add-layer(Layer* l);
public static g.int foo-1(Layer* x);
public direct g.int foo-2(Layer* x);
public abstract void foo-3(g.int x);
public pre-emit void foo-4(g.int x) const;
public post-emit void foo-5(g.int x, Drawable**& n, Image* z);
};
......@@ -10,6 +10,7 @@ header <[[:alnum:]/.]+>
ws [ \n\t\r]
comment \/\/[^\n]*\n
string \"(([^\"]*)|\\\"|\\\\)*\"
preproc ^#.*\n
%%
......@@ -34,7 +35,7 @@ opaque return T_OPAQUE;
void return T_VOID;
enum return T_ENUM;
lags return T_FLAGS;
flags return T_FLAGS;
@int return T_INT;
real return T_DOUBLE;
boxed return T_BOXED;
......@@ -51,6 +52,9 @@ boxed return T_BOXED;
{ws} {
}
{preproc} {
}
{header} {
yylval.id=g_quark_to_string(g_quark_from_string(yytext));
return T_HEADERNAME;
......
#include "gcg.h"
#include "output.h"
typedef struct {
Id package;
GtkType rettype;
GSList* argtypes;
} SignalType;
PNode* p_gtype_name(GtkType t, gboolean abbr){
static const struct GTypeName{
GtkType type;
Id name;
Id aname;
}names[]={
{GTK_TYPE_POINTER, "POINTER", "P"},
{GTK_TYPE_INT, "INT", "I"},
{GTK_TYPE_DOUBLE, "DOUBLE", "D"},
{GTK_TYPE_LONG, "LONG", "L"},
{GTK_TYPE_CHAR, "CHAR", "C"},
{GTK_TYPE_NONE, "NONE", "0"},
};
gint i;
for(i=0;i<sizeof(names)/sizeof(names[0]);i++)
if(names[i].type==t)
if(abbr)
return p_str(names[i].aname);
else
return p_str(names[i].name);
g_assert_not_reached();
return NULL;
}
PNode* p_gtabbr(gpointer p){
GtkType* t=p;
return p_gtype_name(*t, TRUE);
}
GtkType marshalling_type(Type* t){
g_assert(t);
if(!t->prim)
return GTK_TYPE_NONE;
g_assert(t->prim->kind!=GTK_TYPE_INVALID);
if(t->indirection)
return GTK_TYPE_POINTER;
switch(t->prim->kind){
case GTK_TYPE_UINT:
case GTK_TYPE_BOOL:
case GTK_TYPE_FLAGS:
case GTK_TYPE_ENUM:
return GTK_TYPE_INT;
case GTK_TYPE_STRING:
return GTK_TYPE_POINTER;
case GTK_TYPE_UCHAR:
return GTK_TYPE_CHAR;
case GTK_TYPE_ULONG:
return GTK_TYPE_LONG;
default:
return t->prim->kind;
}
}
PNode* p_signal_func_name(Method* s, PNode* basename){
SignalType t;
GSList* p=s->params, *a=NULL;
PNode* ret;
t.package = DEF(MEMBER(s)->my_class)->type->module->name;
t.rettype = marshalling_type(&s->ret_type);
while(p){
Param* param=p->data;
GtkType* t=g_new(GtkType, 1);
*t=marshalling_type(&param->type);
a=g_slist_prepend(a, t);
p=p->next;
}
a=g_slist_reverse(a);
t.argtypes=a;
ret=p_fmt("_~_~_~_~",
p_c_ident(t.package),
basename,
p_gtype_name(t.rettype, TRUE),
p_for(t.argtypes, p_gtabbr, p_nil));
while(a){
g_free(a->data);
a=a->next;
}
g_slist_free(a);
return ret;
}
PNode* p_signal_marshaller_name(Method* m){
return p_signal_func_name(m, p_str("marshall"));
}
PNode* p_signal_demarshaller_name(Method* m){
return p_signal_func_name(m, p_str("demarshall"));
}
PNode* p_handler_type(SignalType* t){
return p_fmt("_~Handler_~_~",
p_str(t->package),
p_gtype_name(t->rettype, TRUE),
p_for(t->argtypes, p_gtabbr, p_nil));
}
typedef struct{
PNode* args;