Mon, 16 Feb 2004 18:04:44 +0100
trunk: changeset 1313
Moved Ion object system and other generic code from Ion to libtu.
Makefile | file | annotate | diff | comparison | revisions | |
README | file | annotate | diff | comparison | revisions | |
minmax.h | file | annotate | diff | comparison | revisions | |
np/np-conv.h | file | annotate | diff | comparison | revisions | |
np/numparser2.h | file | annotate | diff | comparison | revisions | |
obj.c | file | annotate | diff | comparison | revisions | |
obj.h | file | annotate | diff | comparison | revisions | |
objlist.c | file | annotate | diff | comparison | revisions | |
objlist.h | file | annotate | diff | comparison | revisions | |
objp.h | file | annotate | diff | comparison | revisions | |
symlist.c | file | annotate | diff | comparison | revisions | |
symlist.h | file | annotate | diff | comparison | revisions | |
tokenizer.c | file | annotate | diff | comparison | revisions |
--- a/Makefile Mon Feb 16 00:55:23 2004 +0100 +++ b/Makefile Mon Feb 16 18:04:44 2004 +0100 @@ -11,7 +11,8 @@ INCLUDES += -I./include CFLAGS += $(C89_SOURCE) $(POSIX_SOURCE) -SOURCES=misc.c output.c util.c optparser.c parser.c tokenizer.c map.c +SOURCES=misc.c output.c util.c optparser.c parser.c tokenizer.c \ + map.c obj.c objlist.c errorlog.c symlist.c ifdef LIBTU_NO_ERRMSG DEFINES += -DLIBTU_NO_ERRMSG @@ -25,8 +26,6 @@ TARGETS=libtu.a TESTERS=tester tester2 tester3 -HEADERS=dlist.h misc.h output.h tokenizer.h util.h \ - map.h np-conv.h optparser.h parser.h types.h ###################################### @@ -53,6 +52,6 @@ $(INSTALLDIR) $(LIBDIR) $(INSTALLDIR) $(INCDIR)/libtu $(INSTALL) -m $(DATA_MODE) libtu.a $(LIBDIR) - for i in $(HEADERS); do \ + for i in *.h; do \ $(INSTALL) -m $(DATA_MODE) $$i $(INCDIR)/libtu; \ done
--- a/README Mon Feb 16 00:55:23 2004 +0100 +++ b/README Mon Feb 16 18:04:44 2004 +0100 @@ -1,7 +1,7 @@ libtu -Copyright (c) Tuomo Valkonen 1999-2003. +Copyright (c) Tuomo Valkonen 1999-2004. <tuomov at iki.fi>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/minmax.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,27 @@ +/* + * libtu/minmax.h + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef LIBTU_MINMAX_H +#define LIBTU_MINMAX_H + + +static int minof(int x, int y) +{ + return (x<y ? x : y); +} + + +static int maxof(int x, int y) +{ + return (x>y ? x : y); +} + + +#endif /* LIBTU_MINMAX_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/np/np-conv.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,121 @@ +/* + * libtu/np-conv.h + * + * Copyright (c) Tuomo Valkonen 1999-2002. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#include <math.h> + +#ifdef NP_SIMPLE_IMPL + +#define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN) \ + static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \ + { \ + if(num->type!=NPNUM_INT) \ + return E_TOKZ_NOTINT; \ + \ + if(!num->negative){ \ + *ret=num->ival; \ + if(allow_uns_big?num->ival>UMAX:num->ival>MAX) \ + return E_TOKZ_RANGE; \ + }else{ \ + *ret=-num->ival; \ + if(num->ival>-(ulong)MIN) \ + return E_TOKZ_RANGE; \ + } \ + return 0; \ + } + +#define FN_NUM_TO_UNSIGNED(T, UMAX, MIN) \ + static int num_to_##T(T *ret, const NPNum *num, bool allow_neg) \ + { \ + if(num->type!=NPNUM_INT) \ + return E_TOKZ_NOTINT; \ + \ + if(!num->negative){ \ + *ret=num->ival; \ + if(num->ival>UMAX) \ + return E_TOKZ_RANGE; \ + }else{ \ + *ret=-num->ival; \ + if(!allow_neg || num->ival>(ulong)-MIN) \ + return E_TOKZ_RANGE; \ + } \ + return 0; \ + } + +#define FN_NUM_TO_FLOAT(T, POW) \ + static int num_to_##T(T *ret, const NPNum *num) \ + { \ + *ret=(num->negative?-num->fval:num->fval); \ + return 0; \ + } + +#else /* NP_SIMPLE_IMPL */ + +#define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN) \ + static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \ + { \ + if(num->exponent) \ + return E_TOKZ_NOTINT; \ + if(num->nmantissa>0) \ + return E_TOKZ_RANGE; \ + \ + if(!num->negative){ \ + *ret=num->mantissa[0]; \ + if(allow_uns_big?num->mantissa[0]>UMAX:num->mantissa[0]>MAX) \ + return E_TOKZ_RANGE; \ + }else{ \ + *ret=-num->mantissa[0]; \ + if(num->mantissa[0]>-(ulong)MIN) \ + return E_TOKZ_RANGE; \ + } \ + return 0; \ +} + +#define FN_NUM_TO_UNSIGNED(T, UMAX, MIN) \ + static int num_to_##T(T *ret, const NPNum *num, bool allow_neg) \ + { \ + if(num->exponent) \ + return E_TOKZ_NOTINT; \ + if(num->nmantissa>0) \ + return E_TOKZ_RANGE; \ + \ + if(!num->negative){ \ + *ret=num->mantissa[0]; \ + if(num->mantissa[0]>UMAX) \ + return E_TOKZ_RANGE; \ + }else{ \ + *ret=-num->mantissa[0]; \ + if(!allow_neg || num->mantissa[0]>(ulong)-MIN) \ + return E_TOKZ_RANGE; \ + } \ + return 0; \ +} + + +#define FN_NUM_TO_FLOAT(T, POW) \ + static int num_to_##T(T *ret, const NPNum *num) \ + { \ + T d=0; \ + int i; \ + \ + for(i=num->nmantissa;i>=0;i--) \ + d=d*(T)(ULONG_MAX+1.0)+num->mantissa[i]; \ + \ + d*=POW(num->base, num->exponent); \ + *ret=d; \ + \ + return 0; \ + } + +#endif /* NP_SIMPLE_IMPL */ + +FN_NUM_TO_SIGNED(long, ULONG_MAX, LONG_MAX, LONG_MIN) +FN_NUM_TO_SIGNED(char, UCHAR_MAX, CHAR_MAX, CHAR_MIN) +FN_NUM_TO_FLOAT(double, pow) + +#undef NEG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/np/numparser2.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,272 @@ +/* + * libtu/numparser2.h + * + * Copyright (c) Tuomo Valkonen 1999-2002. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#define MAX_MANTISSA 10 /* should be enough for our needs */ +#define ULONG_SIZE (sizeof(ulong)*8) + +enum{ + NPNUM_INT, + NPNUM_FLOAT +}; + +#ifdef NP_SIMPLE_IMPL + +typedef struct _NPNum{ + int type; + int base; + bool negative; + double fval; + ulong ival; +} NPNum; + +#define NUM_INIT {0, 0, 0, 0.0, 0} + +static int npnum_mulbase_add(NPNum *num, long base, long v) +{ + double iold=num->ival; + + num->fval=num->fval*base+(double)v; + + num->ival*=base; + + if(num->ival<iold) + num->type=NPNUM_FLOAT; + + num->ival+=v; + + return 0; +} + +#else /* NP_SIMPLE_IMPL */ + +typedef struct _NPNum{ + unsigned char nmantissa; + int type; + int base; + bool negative; + ulong mantissa[MAX_MANTISSA]; + long exponent; +} NPNum; + +#define NUM_INIT {0, 0, 0, 0, {0,}, 0} + +#define ADD_EXP(NUM, X) (NUM)->exponent+=(X); + +#if defined(__GNUG__) && defined(i386) && !defined(NP_NO_I386_ASM) + #define NP_I386_ASM +#endif + +static int npnum_mulbase_add(NPNum *num, long base, long v) +{ + long i, j; + ulong overflow; +#ifndef NP_I386_ASM + ulong val; +#endif + + for(i=num->nmantissa;i>=0;i--){ +#ifdef NP_I386_ASM + __asm__("mul %4\n" + : "=a" (num->mantissa[i]), "=d" (overflow) + : "0" (num->mantissa[i]), "1" (0), "q" (base) + : "eax", "edx"); +#else + overflow=0; + val=num->mantissa[i]; + + if(val<ULONG_MAX/base){ + val*=base; + }else if(val){ + ulong tmp=val; + ulong old=val; + for(j=0; j<base; j++){ + val+=tmp; + if(val<=old) + overflow++; + old=val; + } + } + num->mantissa[i]=val; +#endif + if(overflow){ + if(i==num->nmantissa){ + if(num->nmantissa==MAX_MANTISSA) + return E_TOKZ_TOOBIG; + num->nmantissa++; + } + num->mantissa[i+1]+=overflow; + } + } + num->mantissa[0]+=v; + + return 0; +} + +#undef NP_I386_ASM + +#endif /* NP_SIMPLE_IMPL */ + + +/* */ + + +static bool is_end(int c) +{ + /* oops... EOF was missing */ + return (c==EOF || (c!='.' && ispunct(c)) || isspace(c) || iscntrl(c)); +} + + +/* */ + + +static int parse_exponent(NPNum *num, Tokenizer *tokz, int c) +{ + long exp=0; + bool neg=FALSE; + int err=0; + + c=GETCH(); + + if(c=='-' || c=='+'){ + if(c=='-') + neg=TRUE; + c=GETCH(); + } + + for(; 1; c=GETCH()){ + if(isdigit(c)){ + exp*=10; + exp+=c-'0'; + }else if(is_end(c)){ + UNGETCH(c); + break; + }else{ + err=E_TOKZ_NUMFMT; + } + } + + if(neg) + exp*=-1; + +#ifndef NP_SIMPLE_IMPL + ADD_EXP(num, exp); +#else + num->fval*=pow(num->base, exp); +#endif + return err; +} + + +static int parse_number(NPNum *num, Tokenizer *tokz, int c) +{ + int base=10; + int dm=1; + int err=0; + int tmp; +#ifdef NP_SIMPLE_IMPL + double divisor=base; +#endif + + if(c=='-' || c=='+'){ + if(c=='-') + num->negative=TRUE; + c=GETCH(); + if(!isdigit(c)) + err=E_TOKZ_NUMFMT; + } + + if(c=='0'){ + dm=0; + c=GETCH(); + if(c=='x' || c=='X'){ + base=16; + c=GETCH(); + }else if(c=='b' || c=='B'){ + base=2; + c=GETCH(); + }else if('0'<=c && c<='7'){ + base=8; + }else{ + dm=2; + } + } + + num->base=base; + + for(; 1; c=GETCH()){ + if((c=='e' || c=='E') && dm!=0){ + if(dm<2){ + err=E_TOKZ_NUMFMT; + continue; + } + tmp=parse_exponent(num, tokz, c); + if(err==0) + err=tmp; + break; + } + + if(isxdigit(c)){ + if('0'<=c && c<='9') + c-='0'; + else if(isupper(c)) + c-='A'-10; + else + c-='a'-10; + + if(c>=base) + err=E_TOKZ_NUMFMT; + +#ifdef NP_SIMPLE_IMPL + if(dm==3){ + num->fval+=(double)c/divisor; + divisor*=base; + }else +#endif + { + tmp=npnum_mulbase_add(num, base, c); + if(err==0) + err=tmp; + } + + if(dm==1) + dm=2; +#ifndef NP_SIMPLE_IMPL + else if(dm==3) + ADD_EXP(num, -1); +#endif + continue; + } + + if(c=='.'){ + if(dm!=2){ + err=E_TOKZ_NUMFMT; + } + dm=3; +#ifdef NP_SIMPLE_IMPL + num->type=NPNUM_FLOAT; + divisor=base; +#endif + continue; + } + + if(is_end(c)){ + UNGETCH(c); + break; + } + + err=E_TOKZ_NUMFMT; + } + +#ifndef NP_SIMPLE_IMPL + num->type=(num->exponent==0 ? NPNUM_INT : NPNUM_FLOAT); +#endif + + return err; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/obj.c Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,297 @@ +/* + * libtu/obj.c + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#include <string.h> + +#include "types.h" +#include "obj.h" +#include "objp.h" +#include "misc.h" +#include "dlist.h" + + +ClassDescr CLASSDESCR(Obj)={"Obj", NULL, 0, NULL, NULL}; + + +static void do_watches(Obj *obj, bool call); + + +/*{{{ Destroy */ + + +void destroy_obj(Obj *obj) +{ + ClassDescr *d; + + if(OBJ_IS_BEING_DESTROYED(obj)) + return; + + obj->flags|=OBJ_DEST; + + do_watches(obj, TRUE); + + d=obj->obj_type; + + while(d!=NULL){ + if(d->destroy_fn!=NULL){ + d->destroy_fn(obj); + break; + } + d=d->ancestor; + } + + do_watches(obj, FALSE); + + free(obj); +} + + +/*}}}*/ + + +/*{{{ is/cast */ + + +bool obj_is(const Obj *obj, const ClassDescr *descr) +{ + ClassDescr *d; + + if(obj==NULL) + return FALSE; + + d=obj->obj_type; + + while(d!=NULL){ + if(d==descr) + return TRUE; + d=d->ancestor; + } + return FALSE; +} + + +bool obj_is_str(const Obj *obj, const char *str) +{ + ClassDescr *d; + + if(obj==NULL || str==NULL) + return FALSE; + + d=obj->obj_type; + + while(d!=NULL){ + if(strcmp(d->name, str)==0) + return TRUE; + d=d->ancestor; + } + return FALSE; +} + + +const void *obj_cast(const Obj *obj, const ClassDescr *descr) +{ + ClassDescr *d; + + if(obj==NULL) + return NULL; + + d=obj->obj_type; + + while(d!=NULL){ + if(d==descr) + return (void*)obj; + d=d->ancestor; + } + return NULL; +} + + +/*}}}*/ + + +/*{{{ Dynamic functions */ + + +/* This function is called when no handler is found. + */ +static void dummy_dyn() +{ +} + + +static int comp_fun(const void *a, const void *b) +{ + void *af=(void*)((DynFunTab*)a)->func; + void *bf=(void*)((DynFunTab*)b)->func; + + return (af<bf ? -1 : (af==bf ? 0 : 1)); +} + + +DynFun *lookup_dynfun(const Obj *obj, DynFun *func, + bool *funnotfound) +{ + ClassDescr *descr; + DynFunTab *df; + /*DynFunTab dummy={NULL, NULL};*/ + /*dummy.func=func;*/ + + if(obj==NULL) + return NULL; + + descr=obj->obj_type; + + for(; descr!=&Obj_classdescr; descr=descr->ancestor){ + if(descr->funtab==NULL) + continue; + + if(descr->funtab_n==-1){ + /* Need to sort the table. */ + descr->funtab_n=0; + df=descr->funtab; + while(df->func!=NULL){ + descr->funtab_n++; + df++; + } + + if(descr->funtab_n>0){ + qsort(descr->funtab, descr->funtab_n, sizeof(DynFunTab), + comp_fun); + } + } + + /* + if(descr->funtab_n==0) + continue; + + df=(DynFunTab*)bsearch(&dummy, descr->funtab, descr->funtab_n, + sizeof(DynFunTab), comp_fun); + if(df!=NULL){ + *funnotfound=FALSE; + return df->handler; + } + */ + + /* Using custom bsearch instead of the one in libc is probably + * faster as the overhead of calling a comparison function would + * be significant given that the comparisons are simple and + * funtab_n not that big. + */ + { + int min=0, max=descr->funtab_n-1; + int ndx; + df=descr->funtab; + while(max>=min){ + ndx=(max+min)/2; + if((void*)df[ndx].func==(void*)func){ + *funnotfound=FALSE; + return df[ndx].handler; + } + if((void*)df[ndx].func<(void*)func) + min=ndx+1; + else + max=ndx-1; + } + } + } + + *funnotfound=TRUE; + return dummy_dyn; +} + + +bool has_dynfun(const Obj *obj, DynFun *func) +{ + bool funnotfound; + lookup_dynfun(obj, func, &funnotfound); + return !funnotfound; +} + + +/*}}}*/ + + +/*{{{ Watches */ + + +bool watch_setup(Watch *watch, Obj *obj, WatchHandler *handler) +{ + if(OBJ_IS_BEING_DESTROYED(obj)) + return FALSE; + + watch_reset(watch); + + watch->handler=handler; + LINK_ITEM(obj->obj_watches, watch, next, prev); + watch->obj=obj; + + return TRUE; +} + +void do_watch_reset(Watch *watch, bool call) +{ + WatchHandler *handler=watch->handler; + Obj *obj=watch->obj; + + watch->handler=NULL; + + if(obj==NULL) + return; + + UNLINK_ITEM(obj->obj_watches, watch, next, prev); + watch->obj=NULL; + + if(call && handler!=NULL) + handler(watch, obj); +} + + +void watch_reset(Watch *watch) +{ + do_watch_reset(watch, FALSE); +} + + +bool watch_ok(Watch *watch) +{ + return watch->obj!=NULL; +} + + +static void do_watches(Obj *obj, bool call) +{ + Watch *watch, *next; + + watch=obj->obj_watches; + + while(watch!=NULL){ + next=watch->next; + do_watch_reset(watch, call); + watch=next; + } +} + + +void watch_call(Obj *obj) +{ + do_watches(obj, FALSE); +} + + +void watch_init(Watch *watch) +{ + watch->obj=NULL; + watch->next=NULL; + watch->prev=NULL; + watch->handler=NULL; +} + + +/*}}}*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/obj.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,68 @@ +/* + * libtu/obj.h + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef LIBTU_OBJ_H +#define LIBTU_OBJ_H + +#include "types.h" + +#define CLASSDESCR(TYPE) TYPE##_classdescr + +#define OBJ_IS(OBJ, TYPE) obj_is((Obj*)OBJ, &CLASSDESCR(TYPE)) +#define OBJ_CAST(OBJ, TYPE) (TYPE*)obj_cast((Obj*)OBJ, &CLASSDESCR(TYPE)) + +#define INTRSTRUCT(STRU) \ + struct STRU##_struct; typedef struct STRU##_struct STRU +#define DECLSTRUCT(STRU) \ + struct STRU##_struct + +#define INTRCLASS(OBJ) INTRSTRUCT(OBJ); extern ClassDescr CLASSDESCR(OBJ) +#define DECLCLASS(OBJ) DECLSTRUCT(OBJ) + +INTRSTRUCT(ClassDescr); +INTRCLASS(Obj); +INTRSTRUCT(Watch); + +extern bool obj_is(const Obj *obj, const ClassDescr *descr); +extern bool obj_is_str(const Obj *obj, const char *str); +extern const void *obj_cast(const Obj *obj, const ClassDescr *descr); + +extern void destroy_obj(Obj *obj); + +DECLCLASS(Obj){ + ClassDescr *obj_type; + Watch *obj_watches; + int flags; +}; + +#define OBJ_DEST 0x0001 +#define OBJ_EXTL_CACHED 0x0002 + +#define OBJ_IS_BEING_DESTROYED(OBJ) (((Obj*)(OBJ))->flags&OBJ_DEST) + +#define DYNFUN + +typedef void WatchHandler(Watch *watch, Obj *obj); + +#define WWATCH_INIT {NULL, NULL, NULL, NULL} + +DECLSTRUCT(Watch){ + Obj *obj; + Watch *next, *prev; + WatchHandler *handler; +}; + +extern bool watch_setup(Watch *watch, Obj *obj, + WatchHandler *handler); +extern void watch_reset(Watch *watch); +extern bool watch_ok(Watch *watch); +extern void watch_init(Watch *watch); +extern void watch_call(Obj *obj); + +#endif /* LIBTU_OBJ_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objlist.c Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,112 @@ +/* + * libtu/objlist.c + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#include "obj.h" +#include "types.h" +#include "objlist.h" +#include "dlist.h" +#include "misc.h" + + +static ObjList *iter_next=NULL; + + +static void free_node(ObjList **objlist, ObjList *node) +{ + UNLINK_ITEM(*objlist, node, next, prev); + free(node); +} + + +void watch_handler(Watch *watch, Obj *obj) +{ + ObjList *node=(ObjList*)watch; + ObjList **list=node->list; + + if(iter_next==node) + iter_next=node->next; + + free_node(list, node); +} + + + +bool objlist_insert(ObjList **objlist, Obj *obj) +{ + ObjList *node; + + if(obj==NULL) + return FALSE; + + node=ALLOC(ObjList); + + if(node==NULL) + return FALSE; + + watch_init(&(node->watch)); + watch_setup(&(node->watch), obj, watch_handler); + node->list=objlist; + + LINK_ITEM_FIRST(*objlist, node, next, prev); + + return TRUE; +} + + +void objlist_remove(ObjList **objlist, Obj *obj) +{ + ObjList *node=*objlist; + + while(node!=NULL){ + if(node->watch.obj==obj){ + watch_reset(&(node->watch)); + free_node(objlist, node); + return; + } + node=node->next; + } +} + + +void objlist_clear(ObjList **objlist) +{ + while(*objlist!=NULL){ + watch_reset(&((*objlist)->watch)); + free_node(objlist, *objlist); + } +} + + +/* Warning: not thread-safe */ + + +Obj *objlist_init_iter(ObjList *objlist) +{ + if(objlist==NULL){ + iter_next=NULL; + return NULL; + } + + iter_next=objlist->next; + return objlist->watch.obj; +} + + +Obj *objlist_iter() +{ + ObjList *ret; + + if(iter_next==NULL) + return NULL; + + ret=iter_next; + iter_next=iter_next->next; + + return ret->watch.obj; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objlist.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,39 @@ +/* + * libtu/objlist.h + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef LIBTU_OBJLIST_H +#define LIBTU_OBJLIST_H + +#include "types.h" +#include "obj.h" + + +INTRSTRUCT(ObjList); + + +DECLSTRUCT(ObjList){ + Watch watch; /* Must be kept at head of structure */ + ObjList *next, *prev; + ObjList **list; +}; + + +#define FOR_ALL_ON_OBJLIST(TYPE, VAR, LIST) \ + for((VAR)=(TYPE)objlist_init_iter(LIST); \ + (VAR)!=NULL; \ + (VAR)=(TYPE)objlist_iter()) + + +bool objlist_insert(ObjList **objlist, Obj *obj); +void objlist_remove(ObjList **objlist, Obj *obj); +void objlist_clear(ObjList **objlist); +Obj *objlist_init_iter(ObjList *objlist); +Obj *objlist_iter(); + +#endif /* LIBTU_OBJLIST_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objp.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,72 @@ +/* + * libtu/objp.h + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef LIBTU_OBJP_H +#define LIBTU_OBJP_H + +#include "types.h" +#include "obj.h" + +typedef void DynFun(); + +INTRSTRUCT(DynFunTab); + +DECLSTRUCT(DynFunTab){ + DynFun *func, *handler; +}; + +DECLSTRUCT(ClassDescr){ + const char *name; + ClassDescr *ancestor; + int funtab_n; + DynFunTab *funtab; + void (*destroy_fn)(); +}; + +#define OBJ_TYPESTR(OBJ) (((Obj*)OBJ)->obj_type->name) + +#define IMPLCLASS(CLS, ANCESTOR, DFN, DYN) \ + ClassDescr CLASSDESCR(CLS)={ \ + #CLS, &CLASSDESCR(ANCESTOR), -1, DYN, (void (*)())DFN} + +#define OBJ_INIT(O, TYPE) {((Obj*)(O))->obj_type=&CLASSDESCR(TYPE); \ + ((Obj*)(O))->obj_watches=NULL; ((Obj*)(O))->flags=0;} + +#define CREATEOBJ_IMPL(OBJ, LOWOBJ, INIT_ARGS) \ + OBJ *p; p=ALLOC(OBJ); if(p==NULL){ warn_err(); return NULL; } \ + OBJ_INIT(p, OBJ); \ + if(!LOWOBJ ## _init INIT_ARGS) { free((void*)p); return NULL; } return p + +#define SIMPLECREATEOBJ_IMPL(OBJ, LOWOBJ) \ + OBJ *p; p=ALLOC(OBJ); if(p==NULL){ warn_err(); return NULL; } \ + OBJ_INIT(p, OBJ); \ + return p; + +#define END_DYNFUNTAB {NULL, NULL} + +extern DynFun *lookup_dynfun(const Obj *obj, DynFun *func, + bool *funnotfound); +extern bool has_dynfun(const Obj *obj, DynFun *func); + +#define CALL_DYN(FUNC, OBJ, ARGS) \ + bool funnotfound; \ + lookup_dynfun((Obj*)OBJ, (DynFun*)FUNC, &funnotfound) ARGS; + +#define CALL_DYN_RET(RETV, RET, FUNC, OBJ, ARGS) \ + typedef RET ThisDynFun(); \ + bool funnotfound; \ + ThisDynFun *funtmp; \ + funtmp=(ThisDynFun*)lookup_dynfun((Obj*)OBJ, (DynFun*)FUNC, \ + &funnotfound); \ + if(!funnotfound) \ + RETV=funtmp ARGS; + +#define HAS_DYN(OBJ, FUNC) has_dynfun((Obj*)OBJ, (DynFun*)FUNC) + +#endif /* LIBTU_OBJP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symlist.c Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,95 @@ +/* + * libtu/symlist.c + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#include "obj.h" +#include "symlist.h" +#include "types.h" +#include "dlist.h" +#include "misc.h" + + +static void free_node(Symlist **symlist, Symlist *node) +{ + UNLINK_ITEM(*symlist, node, next, prev); + free(node); +} + + +bool symlist_insert(Symlist **symlist, void *symbol) +{ + Symlist *node; + + if(symbol==NULL) + return FALSE; + + node=ALLOC(Symlist); + + if(node==NULL) + return FALSE; + + node->symbol=symbol; + + LINK_ITEM_FIRST(*symlist, node, next, prev); + + return TRUE; +} + + +void symlist_remove(Symlist **symlist, void *symbol) +{ + Symlist *node=*symlist; + + while(node!=NULL){ + if(node->symbol==symbol){ + free_node(symlist, node); + return; + } + node=node->next; + } +} + + +void symlist_clear(Symlist **symlist) +{ + while(*symlist!=NULL) + free_node(symlist, *symlist); +} + + +/* Warning: not thread-safe */ + + +static Symlist *iter_next=NULL; + + +void *symlist_init_iter(Symlist *symlist) +{ + if(symlist==NULL){ + iter_next=NULL; + return NULL; + } + + iter_next=symlist->next; + return symlist->symbol; +} + + +void *symlist_iter() +{ + Symlist *ret; + + if(iter_next==NULL) + return NULL; + + ret=iter_next; + iter_next=iter_next->next; + + return ret->symbol; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symlist.h Mon Feb 16 18:04:44 2004 +0100 @@ -0,0 +1,38 @@ +/* + * libtu/symlist.h + * + * Copyright (c) Tuomo Valkonen 1999-2004. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef LIBTU_SYMLIST_H +#define LIBTU_SYMLIST_H + +#include "types.h" +#include "obj.h" + + +INTRSTRUCT(Symlist); + + +DECLSTRUCT(Symlist){ + void *symbol; + Symlist *next, *prev; +}; + + +#define ITERATE_SYMLIST(TYPE, VAR, LIST) \ + for((VAR)=(TYPE)symlist_init_iter(LIST); \ + (VAR)!=NULL; \ + (VAR)=(TYPE)symlist_iter()) + + +bool symlist_insert(Symlist **symlist, void *symbol); +void symlist_remove(Symlist **symlist, void *symbol); +void symlist_clear(Symlist **symlist); +void *symlist_init_iter(Symlist *symlist); +void *symlist_iter(); + +#endif /* LIBTU_SYMLIST_H */
--- a/tokenizer.c Mon Feb 16 00:55:23 2004 +0100 +++ b/tokenizer.c Mon Feb 16 18:04:44 2004 +0100 @@ -419,8 +419,8 @@ } #define NP_SIMPLE_IMPL -#include "numparser2.h" -#include "np-conv.h" +#include "np/numparser2.h" +#include "np/np-conv.h" static int scan_number(Token *tok, Tokenizer *tokz, int c)