From ed0fcd1b27831486f2894edb2d0838e38657b4fb Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 25 Nov 2004 00:21:54 +0000 Subject: [PATCH] compiles and appears to work (as far as it goes) --- maskmap/maskmap.c | 171 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 53 deletions(-) diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c index bb1e258..e0c7f90 100644 --- a/maskmap/maskmap.c +++ b/maskmap/maskmap.c @@ -1,6 +1,8 @@ /* */ +#include + #include "tables.h" #include "hbytes.h" @@ -15,87 +17,152 @@ struct MaskMap_Value { MaskMap_Entry *entries; }; /* overlays internalRep */ -int pat_maskmapv(Tcl_Interp *ip, Tcl_Obj *var, MaskMap_Var *agg) { - int rc; - rc= pat_somethingv(ip,var,&agg->sth,&maskmap_type); if (rc) return rc; - agg->mm= (void*)&agg->sth.obj->internalRep; - return TCL_OK; -} - -int do_maskmap_amend(ClientData cd, Tcl_Interp *ip, - MaskMap_Var map, HBytes_Value prefix, - int preflen, Tcl_Obj *data) { - return TCL_OK; -} - -int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, - MaskMap_Var map, HBytes_Value addr, Tcl_Obj *def, - Tcl_Obj **result) { - return TCL_OK; -} +/*---------- useful stuff ----------*/ static int prefix_bytes (int prefixlen) { return (prefixlen + 7)/8; } +/*---------- operations on MaskMap_Entry ----------*/ + static void mme_init(MaskMap_Entry *mme) { mme->prefix= 0; mme->data= 0; } +static void mme_free(MaskMap_Entry *mme) { + TFREE(mme->prefix); mme->prefix=0; + if (mme->data) { Tcl_DecrRefCount(mme->data); mme->data=0; } +} + +static int mme_parsekey(Tcl_Interp *ip, MaskMap_Entry *mme, + Tcl_Obj *prefixo, Tcl_Obj *prefixleno, + int inmap) { + /* *mme should be blank entry; after exit (even error exit) it will be valid + * - on errors, it will be blank. inmap is 1 if we're parsing an existing + * map or 0 if it's an entry to be added or modified. */ + HBytes_Value prefix; + int suppliedprefixbytes, prefixlen, wantprefixbytes; + int rc; + + hbytes_empty(&prefix); + + rc= pat_hb(ip,prefixo,&prefix); if (rc) goto x_rc; + rc= pat_int(ip,prefixleno,&prefixlen); if (rc) goto x_rc; + + wantprefixbytes= prefix_bytes(prefixlen); + suppliedprefixbytes= hbytes_len(&prefix); + + if (suppliedprefixbytes < wantprefixbytes) { + rc= staticerr(ip, "mask-map entry PREFIX too short for PREFIX-LEN", + "HBYTES MASKMAP SYNTAX UNDERRUN"); + goto x_rc; + } + if (inmap && suppliedprefixbytes > wantprefixbytes) { + rc= staticerr(ip, "mask-map existing entry PREFIX too long for PREFIX-LEN", + "HBYTES MASKMAP SYNTAX OVERRUN"); + goto x_rc; + } + mme->prefixlen= prefixlen; + mme->prefix= TALLOC(wantprefixbytes); assert(mme->prefix); + memcpy(mme->prefix, hbytes_data(&prefix), wantprefixbytes); + return TCL_OK; + + x_rc: + mme_free(mme); + return rc; +} + +static int mme_ordercompare(MaskMap_Entry *a, MaskMap_Entry *b) { + if (a->prefixlen != b->prefixlen) + return a->prefixlen - b->prefixlen; + else + return memcmp(b->prefix, a->prefix, prefix_bytes(a->prefixlen)); +} + +/*---------- useful operations on MaskMap_Value etc. ----------*/ + static int mm_count(const MaskMap_Value *mm) { int i; - for (i=0; iallocd && sm->entries[i].prefixlen != -1; i++); + for (i=0; iallocd && mm->entries[i].prefixlen != -1; i++); return i; } static void mm_allocentries(MaskMap_Value *mm, int len) { int i; mm->allocd= len; - mm->entries= Tcl_Alloc(sizeof(*mm->entries) * len); + mm->entries= TALLOC(sizeof(*mm->entries) * len); assert(mm->entries); for (i=0; i < len; i++) mme_init(&mm->entries[i]); } +/*---------- substantial operations on mask maps ----------*/ + +int do_maskmap_amend(ClientData cd, Tcl_Interp *ip, + MaskMap_Var map, HBytes_Value prefix, + int preflen, Tcl_Obj *data) { + return TCL_OK; /*fixme*/ +} + +int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, + MaskMap_Var map, HBytes_Value addr, Tcl_Obj *def, + Tcl_Obj **result) { + *result= Tcl_NewIntObj(42); + return TCL_OK; /*fixme*/ +} + +/*---------- Tcl type and arg parsing functions ----------*/ + +int pat_maskmapv(Tcl_Interp *ip, Tcl_Obj *var, MaskMap_Var *agg) { + int rc; + rc= pat_somethingv(ip,var,&agg->sth,&maskmap_type); if (rc) return rc; + agg->mm= (void*)&agg->sth.obj->internalRep; + return TCL_OK; +} + static void maskmap_t_free(Tcl_Obj *o) { MaskMap_Value *mm= (void*)&o->internalRep; - for (i=0; ientries; iallocd; i++, mme++) { + if (mme->prefixlen==-1) break; + mme_free(mme); } } -static void maskmap_t_dup(Tcl_Obj *so, Tcl_Obj *do) { - MaskMap_Value *sm= (void*)&so->internalRep; - MaskMap_Value *dm= (void*)&do->internalRep; +static void maskmap_t_dup(Tcl_Obj *sob, Tcl_Obj *dob) { + MaskMap_Value *sm= (void*)&sob->internalRep; + MaskMap_Value *dm= (void*)&dob->internalRep; + MaskMap_Entry *sme, *dme; int l, i, nbytes; - assert(so->typePtr == &maskmap_type); - objfreeir(do); - l= mm_count(&sm); + assert(sob->typePtr == &maskmap_type); + objfreeir(dob); + l= mm_count(sm); - mm_allocentries(&dm,l); + mm_allocentries(dm,l); for (i=0, sme=sm->entries, dme=dm->entries; iallocd; i++, sme++, dme++) { *dme= *sme; nbytes= prefix_bytes(sme->prefixlen); - dme->prefix= Tcl_Alloc(nbytes); assert(dme->prefix); + dme->prefix= TALLOC(nbytes); assert(dme->prefix); memcpy(dme->prefix, sme->prefix, nbytes); Tcl_IncrRefCount(dme->data); } + dob->typePtr= &maskmap_type; } static void maskmap_t_ustr(Tcl_Obj *so) { MaskMap_Value *sm= (void*)&so->internalRep; Tcl_Obj **mainlobjsl, *mainobj; - char *string; - int stringl; + int i, l; assert(so->typePtr == &maskmap_type); l= mm_count(sm); - mainlobjsl= Tcl_Alloc(sizeof(*mainobjsl) * l); assert(mainlobjsl); + mainlobjsl= TALLOC(sizeof(*mainlobjsl) * l); assert(mainlobjsl); for (i=0; ientries[i]; @@ -103,7 +170,7 @@ static void maskmap_t_ustr(Tcl_Obj *so) { Tcl_Obj *subl[3], *sublo; hbytes_array(&hb, sme->prefix, prefix_bytes(sme->prefixlen)); - subl[0]= ret_hb(ip, &hb); assert(subl[0]); + subl[0]= ret_hb(0, hb); assert(subl[0]); subl[1]= Tcl_NewIntObj(sme->prefixlen); assert(subl[1]); subl[2]= sme->data; @@ -117,59 +184,57 @@ static void maskmap_t_ustr(Tcl_Obj *so) { } static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { - int len, eol; + int rc, len, eol, i; MaskMap_Value mm; + Tcl_Obj *eo, *prefixo, *prefixleno; mm.allocd= 0; mm.entries= 0; rc= Tcl_ListObjLength(ip,o,&len); if (rc) goto x_rc; - mm_allocentries(len); + mm_allocentries(&mm, len); for (i=0; i0) { - if (mme_compare(&mm.entries[i-1], &mm.entries[i]) <= 0) { - rc= staticerr(ip, "mask-map entries out of order"); + if (mme_ordercompare(&mm.entries[i-1], &mm.entries[i]) <= 0) { + rc= staticerr(ip, "mask-map entries out of order", + "HBYTES MASKMAP SYNTAX ORDER"); goto x_rc; } } } /* we commit now */ - assert(sizeof(mm) <= sizeof(o.internalRep)); + assert(sizeof(mm) <= sizeof(o->internalRep)); objfreeir(o); - memcpy(&o.internalRep, &mm, sizeof(mm)); - o.typePtr= &maskmap_type; + memcpy(&o->internalRep, &mm, sizeof(mm)); + o->typePtr= &maskmap_type; return TCL_OK; x_rc: if (mm.entries) { for (i=0; i