From: ian Date: Sun, 21 Nov 2004 22:05:32 +0000 (+0000) Subject: some maskmap stuff; X-Git-Tag: debian/1.1.1~127 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=commitdiff_plain;h=d55fe169a327a1a3352ed88587c8f52907e2301d some maskmap stuff; --- diff --git a/base/hook.c b/base/hook.c index e067c94..8ef140f 100644 --- a/base/hook.c +++ b/base/hook.c @@ -421,6 +421,7 @@ int Hbytes_Init(Tcl_Interp *ip) { Tcl_RegisterObjType(&sockaddr_type); Tcl_RegisterObjType(&tabledataid_nearlytype); Tcl_RegisterObjType(&ulong_type); + Tcl_RegisterObjType(&maskmap_type); for (cmd=toplevel_commands; cmd->name; diff --git a/hbytes/hook.c b/hbytes/hook.c index e067c94..8ef140f 100644 --- a/hbytes/hook.c +++ b/hbytes/hook.c @@ -421,6 +421,7 @@ int Hbytes_Init(Tcl_Interp *ip) { Tcl_RegisterObjType(&sockaddr_type); Tcl_RegisterObjType(&tabledataid_nearlytype); Tcl_RegisterObjType(&ulong_type); + Tcl_RegisterObjType(&maskmap_type); for (cmd=toplevel_commands; cmd->name; diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c index 9968801..bb1e258 100644 --- a/maskmap/maskmap.c +++ b/maskmap/maskmap.c @@ -34,10 +34,141 @@ int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -static void maskmap_t_free(Tcl_Obj *o) { } -static void maskmap_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { } -static void maskmap_t_ustr(Tcl_Obj *o) { } -static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { return TCL_ERROR; } +static int prefix_bytes (int prefixlen) { + return (prefixlen + 7)/8; +} + +static void mme_init(MaskMap_Entry *mme) { + mme->prefix= 0; + mme->data= 0; +} + +static int mm_count(const MaskMap_Value *mm) { + int i; + for (i=0; iallocd && sm->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); + assert(mm->entries); + for (i=0; i < len; i++) + mme_init(&mm->entries[i]); +} + +static void maskmap_t_free(Tcl_Obj *o) { + MaskMap_Value *mm= (void*)&o->internalRep; + for (i=0; iinternalRep; + MaskMap_Value *dm= (void*)&do->internalRep; + int l, i, nbytes; + + assert(so->typePtr == &maskmap_type); + objfreeir(do); + l= mm_count(&sm); + + 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); + memcpy(dme->prefix, sme->prefix, nbytes); + Tcl_IncrRefCount(dme->data); + } +} + +static void maskmap_t_ustr(Tcl_Obj *so) { + MaskMap_Value *sm= (void*)&so->internalRep; + Tcl_Obj **mainlobjsl, *mainobj; + char *string; + int stringl; + + assert(so->typePtr == &maskmap_type); + l= mm_count(sm); + mainlobjsl= Tcl_Alloc(sizeof(*mainobjsl) * l); assert(mainlobjsl); + + for (i=0; ientries[i]; + HBytes_Value hb; + Tcl_Obj *subl[3], *sublo; + + hbytes_array(&hb, sme->prefix, prefix_bytes(sme->prefixlen)); + subl[0]= ret_hb(ip, &hb); assert(subl[0]); + subl[1]= Tcl_NewIntObj(sme->prefixlen); assert(subl[1]); + subl[2]= sme->data; + + sublo= Tcl_NewListObj(3,subl); assert(sublo); + mainlobjsl[i]= sublo; + } + + mainobj= Tcl_NewListObj(l,mainlobjsl); assert(mainobj); + so->bytes= Tcl_GetStringFromObj(mainobj, &so->length); assert(so->bytes); + mainobj->bytes= 0; mainobj->length= 0; /* we stole it */ +} + +static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { + int len, eol; + MaskMap_Value mm; + + mm.allocd= 0; + mm.entries= 0; + + rc= Tcl_ListObjLength(ip,o,&len); if (rc) goto x_rc; + mm_allocentries(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"); + goto x_rc; + } + } + } + + /* we commit now */ + assert(sizeof(mm) <= sizeof(o.internalRep)); + objfreeir(o); + memcpy(&o.internalRep, &mm, sizeof(mm)); + o.typePtr= &maskmap_type; + return TCL_OK; + +x_rc: + if (mm.entries) { + for (i=0; i