Commit 5343dbb8 authored by Lauri Alanko's avatar Lauri Alanko

Added vfunc wrappers and accessors.

parent adeae228
1998-10-21 Lauri Alanko <la@iki.fi>
* Added vfunc wrappers and accessors
1998-10-21 Lauri Alanko <la@iki.fi>
* Initially committed to CVS
......@@ -80,6 +80,7 @@ extern DefClass object_class;
struct _ObjectDef {
Def def;
PrimType* parent;
Type self_type[2]; /* both non-const and const */
GSList* members;
};
......
// this is just a simple test input file
module g {
header <glib.h> {
......@@ -27,7 +28,10 @@ module Gimp{
foo, bar, baz, quux
};
class Image : Gimp.Object{
g.int x;
read-write g.int x;
read-only g.int y;
public abstract g.int foo(g.int bar);
abstract g.int name;
public abstract g.int baz(Object* o, Image*& i) const;
};
};
......@@ -2,18 +2,26 @@
#include "output.h"
#include <stdarg.h>
void pr_param(File* s, Param* p, PBool first){
pr(s, "%?s%1 %s",
!first, ", ",
pr_type, p->type,
p->name);
void pr_param(File* s, Param* p, ParamOptions* opt){
pr(s, "%?s%?1%?s%?s",
!(*opt & PARAMS_FIRST), ", ",
!!(*opt & PARAMS_TYPES), pr_type, &p->type,
(*opt & PARAMS_TYPES) && (*opt & PARAMS_NAMES), " ",
!!(*opt & PARAMS_NAMES), p->name);
}
void pr_params(File* s, GSList* args){
pr(s, "%?s%?2%3",
!args, "void",
!!args, pr_param, args?args->data:NULL, ptrue,
pr_list_foreach, (args?args->next:NULL), pr_param, pfalse);
void pr_params(File* s, GSList* args, ParamOptions* opt){
ParamOptions o=*opt;
if(args)
if(o & PARAMS_FIRST){
pr_param(s, args->data, &o);
o &= ~PARAMS_FIRST;
pr_list_foreach(s, args->next, pr_param, &o);
}else
pr_list_foreach(s, args, pr_param, &o);
else
if(o & PARAMS_FIRST)
pr(s, "void");
}
void pr_primtype(File* s, PrimType* t){
......@@ -23,8 +31,8 @@ void pr_primtype(File* s, PrimType* t){
}
void pr_type(File* s, Type* t){
gint i=t->indirection;
if(t->prim){
if(t && t->prim){
gint i=t->indirection;
pr(s, "%?s%1",
t->is_const, "const ",
pr_primtype, t->prim);
......@@ -59,28 +67,40 @@ void pr_internal_varname(File* s, PrimType* t, Id name){
void pr_prototype(File* s, PrimType* type, Id funcname,
GSList* params, Type* rettype, gboolean internal){
pr(s, "%1 %2 (%1)",
ParamOptions o=PARAMS_NAMES | PARAMS_TYPES | PARAMS_FIRST;
pr(s, "%1 %2 (%2)",
pr_type, rettype,
(internal?pr_internal_varname:pr_varname), type, funcname,
pr_params, params);
pr_params, params, &o);
}
void pr_gtype(File* s, Type* t){
if((t->indirection==0 && t->prim->kind==TYPE_TRANSPARENT)
|| (t->indirection==1 && t->prim->kind==TYPE_CLASS))
pr_macro_name(s, t->prim, "TYPE", NULL);
else if(t->indirection)
pr(s, "GTK_TYPE_POINTER");
else
g_error("Illegal non-pointer type %s%s\n",
t->prim->name.module,
t->prim->name.type);
}
void pr_type_guard(File* s, Param* p){
Type* t=&p->type;
if(t->indirection==1 && t->prim->kind == TYPE_CLASS)
/* A direct object pointer is checked for its type */
pr(s, "\tg_assert(%?2%3(%s));",
pr(s, "\tg_assert(%?2%3(%s));\n",
!t->notnull, pr, "!%s || ", p->name,
pr_macro_name, t->prim->name, "IS", NULL,
pr_macro_name, t->prim, "IS", NULL,
p->name);
else if(t->indirection && t->notnull)
/* Other pointers are just possibly checked for nullness */
pr(s, "\tg_assert(%s);",
pr(s, "\tg_assert(%s);\n",
p->name);
/* todo (low priority): range checks for enums */
}
void output_func(PrimType* type, Id funcname, GSList* params, Type* rettype,
File* hdr, ObjectDef* self, gboolean self_const,
gboolean internal, const gchar* body, ...){
......
......@@ -36,7 +36,16 @@ void pr_up(File* s, const gchar* str);
extern const gconstpointer no_data;
void pr_list_foreach(File* s, GSList* l, void (*f)(), gpointer arg);
void pr_params(File* s, GSList* args);
typedef enum{
PARAMS_FIRST = 1<<0,
PARAMS_NAMES = 1<<1,
PARAMS_TYPES = 1<<2,
PARAMS_DOCS = 1<<3
} ParamOptions;
void pr_params(File* s, GSList* args, ParamOptions* opt);
void pr_primtype(File* s, PrimType* t);
void pr_type(File* s, Type* t);
void pr_self_type(File* s, ObjectDef* c, PBool const_self);
......
......@@ -36,18 +36,27 @@ void pr_object_decl(File* s, ObjectDef* o){
}
void pr_class_member(File* s, Member* m){
#if 0
ParamOptions o=PARAMS_TYPES;
if(m->kind!=KIND_ABSTRACT)
return;
pr(s, "\t%1 %1%5;\n",
pr_type, m->type,
(m->method?pr_nil:pr), m->name
(m->method?pr:pr_nil), "(*%s) (%2)",
m->name,
pr_params, m->params, ptrue);
#endif
if(m->membertype==MEMBER_DATA){
DataMember* d=(DataMember*)m;
pr(s, "\t%1 %s;\n",
pr_type, &d->type,
m->name);
}else if (m->membertype==MEMBER_METHOD){
Method* d=(Method*)m;
pr(s, "\t%1 (*%s) (%1%2);\n",
pr_type, &d->ret_type,
m->name,
pr_type, &m->my_class->self_type[d->self_const],
pr_params, d->params, &o);
}
}
void pr_class_name(File* s, PrimType* o){
pr(s, "%1Class",
pr_primtype, o);
......@@ -77,25 +86,10 @@ void pr_class_decl(File* s, ObjectDef* o){
pr_class_name, DEF(o)->type);
}
void pr_class_cast(File* s, ObjectDef* t, const gchar* format, ...){
va_list args;
va_start (args, format);
pr(s, "%3 (%2)",
pr_macro_name, DEF(t)->type, NULL, "CLASS_CAST",
prv, format, args);
}
void pr_abstract_member(File* s, Id varname, ObjectDef* klass, Id membername){
pr(s,
"(%3->%s)",
pr_class_cast, klass, "GTK_OBJECT(%s)->klass", varname,
membername);
}
void output_method_funcs(Method* m){
void output_abstract_method(Method* m){
PrimType* t=DEF(MEMBER(m)->my_class)->type;
Id name=MEMBER(m)->name;
ParamOptions o=PARAMS_NAMES;
output_func
(t,
name,
......@@ -105,25 +99,66 @@ void output_method_funcs(Method* m){
MEMBER(m)->my_class,
m->self_const,
FALSE,
"\t%?s%?5%%%%",
"\t%?s%3(GTK_OBJECT(self)->klass)->%s(self%2);\n",
!!m->ret_type.prim, "return ",
MEMBER(m)->kind==KIND_ABSTRACT,
pr, "%2%2", pr_abstract_member, "self", t, name
);
pr_macro_name, t, NULL, "CLASS",
name,
pr_params, m->params, &o);
}
/*
void pr_accessor_def(...){
Param p;
GSList l;
l.data=&p;
mk_self_param(
pr_func(m->klass, m->name, ,
"\treturn self->%s;\n");
*/
void output_data_member(DataMember* m){
Id name=MEMBER(m)->name;
PrimType* t=DEF(MEMBER(m)->my_class)->type;
switch(m->prot){
case DATA_READWRITE: {
Id set_name=g_strconcat("set_", name, NULL);
Param p;
GSList l;
p.type=m->type;
p.name="value";
l.data=&p;
l.next=NULL;
output_func(t,
set_name,
&l,
NULL,
func_hdr,
MEMBER(m)->my_class,
FALSE,
FALSE,
"\tself->%s=value;\n",
name);
g_free(set_name);
}
/* fall through */
case DATA_READONLY:
output_func(t,
name,
NULL,
&m->type,
func_hdr,
MEMBER(m)->my_class,
TRUE,
FALSE,
"\treturn self->%s;\n",
name);
case DATA_PROTECTED:
}
}
void output_member(Member* m, gpointer dummy){
switch(m->membertype){
case MEMBER_METHOD:
if(m->kind==KIND_ABSTRACT)
output_abstract_method((Method*)m);
break;
case MEMBER_DATA:
if(m->kind==KIND_DIRECT)
output_data_member((DataMember*)m);
break;
}
}
void pr_class_macros(File* s, ObjectDef* o ){
PrimType* t=DEF(o)->type;
pr(s, "#define %3(o) GTK_CHECK_CAST(o, %3, %1)\n",
......@@ -153,7 +188,7 @@ void output_object_type_init(ObjectDef* o){
"\treturn %2;\n",
pr_primtype, t,
pr_primtype, t,
pr_class_name, o,
pr_class_name, DEF(o)->type,
pr_varname, t, "class_init",
pr_varname, t, "init",
pr_internal_varname, t, "type",
......@@ -161,17 +196,6 @@ void output_object_type_init(ObjectDef* o){
pr_internal_varname, t, "type");
}
void pr_gtype(File* s, Type* t){
if((t->indirection==0 && t->prim->kind==TYPE_TRANSPARENT)
|| (t->indirection==1 && t->prim->kind==TYPE_CLASS))
pr_macro_name(s, t->prim, "TYPE", NULL);
else if(t->indirection)
pr(s, "GTK_TYPE_POINTER");
else
g_error("Illegal non-pointer type %s%s\n",
t->prim->name.module,
t->prim->name.type);
}
void output_object(ObjectDef* o){
output_def(DEF(o));
......@@ -180,6 +204,7 @@ void output_object(ObjectDef* o){
pr_class_decl(prot_hdr, o);
pr_object_decl(type_hdr, o);
pr_object_body(prot_hdr, o);
g_slist_foreach(o->members, output_member, NULL);
}
......
......@@ -294,6 +294,10 @@ flagsdef: T_FLAGS primtype T_OPEN_B idlist T_CLOSE_B docstring T_END {
classdef: T_CLASS object_type T_INHERITANCE object_type docstring T_OPEN_B {
current_class=g_new(ObjectDef, 1);
} classbody T_CLOSE_B T_END {
Type t={FALSE, 1, TRUE, $2};
current_class->self_type[0]=t;
t.is_const=TRUE;
current_class->self_type[1]=t;
current_class->parent = $4;
current_class->members = $8;
$$=DEF(current_class);
......@@ -321,7 +325,6 @@ data_member_def: dataprot kinddef type T_IDENT emitdef docstring T_END {
method_def: methprot kinddef typeorvoid T_IDENT T_OPEN_P {
current_method = g_new(Method, 1);
} paramlist T_CLOSE_P const_def emitdef docstring T_END {
current_method = NULL;
current_method->prot = $1;
current_method->ret_type = $3;
current_method->self_const = $9;
......@@ -344,6 +347,7 @@ const_def: T_CONST {
classbody: /* empty */ {
$$ = NULL;
} | classbody member_def{
$2->my_class=current_class;
$$ = g_slist_prepend($1, $2);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment