From 4149293c485d766e446f1a841892420059755347 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 25 Nov 2004 01:18:14 +0000 Subject: [PATCH] mask-map amend implemented, but untested --- base/chiark-tcl.h | 1 + base/tables-examples.tct | 4 +-- hbytes/hbytes.h | 1 + maskmap/maskmap.c | 72 ++++++++++++++++++++++++++++++++++------ 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index 48ee798..17a0594 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -390,5 +390,6 @@ int setnonblock(int fd, int isnonblock); #define TALLOC(s) ((void*)Tcl_Alloc((s))) #define TFREE(f) (Tcl_Free((void*)(f))) +#define TREALLOC(p,l) ((void*)Tcl_Realloc((void*)(p),(l))) #endif /*HBYTES_H*/ diff --git a/base/tables-examples.tct b/base/tables-examples.tct index 267b88c..9165827 100644 --- a/base/tables-examples.tct +++ b/base/tables-examples.tct @@ -45,8 +45,8 @@ Table maskmap MaskMap_SubCommand => obj amend map maskmapv - prefix hb - preflen int + prefix obj + preflen obj data obj Table ulong ULong_SubCommand diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index 48ee798..17a0594 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -390,5 +390,6 @@ int setnonblock(int fd, int isnonblock); #define TALLOC(s) ((void*)Tcl_Alloc((s))) #define TFREE(f) (Tcl_Free((void*)(f))) +#define TREALLOC(p,l) ((void*)Tcl_Realloc((void*)(p),(l))) #endif /*HBYTES_H*/ diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c index 1f122e9..77c677f 100644 --- a/maskmap/maskmap.c +++ b/maskmap/maskmap.c @@ -97,22 +97,72 @@ static int mm_count(const MaskMap_Value *mm) { return i; } -static void mm_allocentries(MaskMap_Value *mm, int len) { +static void mm_init(MaskMap_Value *mm) { + mm->allocd= 0; + mm->entries= 0; +} + +static void mm_reallocentries(MaskMap_Value *mm, int len) { int i; + MaskMap_Entry *newentries, *clear; + + newentries= TREALLOC(mm->entries, sizeof(*newentries)*len); + assert(!len || newentries); + + for (i=mm->allocd, clear=&mm->entries[mm->allocd]; + i < len; + i++, clear++) + mme_init(clear); + mm->allocd= len; - mm->entries= TALLOC(sizeof(*mm->entries) * len); - assert(mm->entries); - for (i=0; i < len; i++) - mme_init(&mm->entries[i]); + mm->entries= newentries; } /*---------- 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) { + MaskMap_Var map, Tcl_Obj *prefix, + Tcl_Obj *preflen, Tcl_Obj *data) { + MaskMap_Value *mm= map.mm; + MaskMap_Entry mme, *search; + int rc, insertat, findend, cmp; + + mme_init(&mme); + rc= mme_parsekey(ip,&mme,prefix,preflen,0); if (rc) goto x_rc; + + for (insertat=0, search=mm->entries; + insertat < mm->allocd && + search->prefixlen != -1; + insertat++, search++) { + cmp= mme_ordercompare(&mme,search); + if (!cmp) { + mme_free(&mme); + Tcl_DecrRefCount(search->data); + goto put_here; + } + if (cmp>0) + /* the new one sorts later, insert it here */ + break; + } + + /* we're adding an entry, make room for it */ + findend= mm_count(mm); + if (findend == mm->allocd) mm_reallocentries(mm, mm->allocd*2 + 1); + if (findend > insertat) + memmove(&mm->entries[insertat+1], + &mm->entries[insertat], + sizeof(mm->entries[0]) * (findend - insertat)); + *search= mme; + + put_here: + Tcl_IncrRefCount(data); + search->data= data; return TCL_OK; + + x_rc: + mme_free(&mme); + return rc; } int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, @@ -153,7 +203,8 @@ static void maskmap_t_dup(Tcl_Obj *sob, Tcl_Obj *dob) { objfreeir(dob); l= mm_count(sm); - mm_allocentries(dm,l); + mm_init(dm); + mm_reallocentries(dm,l); for (i=0, sme=sm->entries, dme=dm->entries; iallocd; i++, sme++, dme++) { @@ -199,11 +250,10 @@ static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { MaskMap_Value mm; Tcl_Obj *eo, *prefixo, *prefixleno; - mm.allocd= 0; - mm.entries= 0; + mm_init(&mm); rc= Tcl_ListObjLength(ip,o,&len); if (rc) goto x_rc; - mm_allocentries(&mm, len); + mm_reallocentries(&mm, len); for (i=0; i