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,
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;
i<dm->allocd;
i++, sme++, dme++) {
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<len; i++) {
rc= Tcl_ListObjIndex(ip,o,i,&eo); if (rc) goto x_rc;