chiark / gitweb /
first cut of mask-map: skeleton
authorian <ian>
Sun, 21 Nov 2004 20:33:09 +0000 (20:33 +0000)
committerian <ian>
Sun, 21 Nov 2004 20:33:09 +0000 (20:33 +0000)
base/chiark-tcl.h
base/hook.c
base/parse.c
base/tables-examples.tct
base/troglodyte-Makefile
hbytes/hbytes.h
hbytes/hook.c
hbytes/parse.c
maskmap/maskmap.c [new file with mode: 0644]

index 1014182..207e32a 100644 (file)
  *               uint VARNAME/VALUE         (VARNAME if ul2bitfields;
  *               ulong VARNAME/VALUE         VALUE if bitfields2ul)
  *
+ *  hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT]   => DATA
+ *     error on missing default or if address too short
+ *  hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA
+ *     a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]]
+ *     sorted first by descending PREFIX-LENGTH and then by PREFIX
+ *     each PREFIX is truncated to the shortest number of pairs of
+ *     hex digits which can represent it
+ *
  * Error codes
  *
  * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT  block cipher mode failed somehow (!)
 #include <sys/un.h>
 #include <arpa/inet.h>
 
-#include <tcl.h>
+#include <tcl8.3/tcl.h>
 
 typedef unsigned char Byte;
 
@@ -234,12 +242,30 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str);
 /* from parse.c */
 
 typedef struct {
-  HBytes_Value *hb;
   Tcl_Obj *obj, *var;
   int copied;
+} Something_Var;
+
+void init_somethingv(Something_Var *sth);
+void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth);
+int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var,
+                  Something_Var *sth, Tcl_ObjType *type);
+
+typedef struct {
+  HBytes_Value *hb;
+  Something_Var sth;
 } HBytes_Var;
 
-void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg);
+/* from maskmap.c */
+
+typedef struct MaskMap_Value MaskMap_Value;
+
+typedef struct {
+  MaskMap_Value *mm;
+  Something_Var sth;
+} MaskMap_Var;
+
+extern Tcl_ObjType maskmap_type;
 
 /* from chop.c */
   /* only do_... functions declared in tables.h */
index 32c604f..e067c94 100644 (file)
@@ -380,6 +380,12 @@ int do_toplevel_ulong(ClientData cd, Tcl_Interp *ip,
   return subcmd->func(0,ip,objc,objv);
 }
 
+int do_toplevel_mask_map(ClientData cd, Tcl_Interp *ip,
+                     const MaskMap_SubCommand *subcmd,
+                     int objc, Tcl_Obj *const *objv) {
+  return subcmd->func(0,ip,objc,objv);
+}
+
 #define URANDOM "/dev/urandom"
 
 int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) {
index 911cadd..1d91238 100644 (file)
@@ -22,40 +22,51 @@ int pat_string(Tcl_Interp *ip, Tcl_Obj *obj, const char **val) {
   *val= Tcl_GetString(obj);
   return TCL_OK;
 }
-  
-int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) {
+
+void init_somethingv(Something_Var *sth) {
+  sth->obj=0; sth->var=0; sth->copied=0;
+}
+
+int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var,
+                  Something_Var *sth, Tcl_ObjType *type) {
   int rc;
   Tcl_Obj *val;
 
-  agg->var= var;
+  sth->var= var;
 
   val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG);
   if (!val) return TCL_ERROR;
 
-  rc= Tcl_ConvertToType(ip,val,&hbytes_type);
+  rc= Tcl_ConvertToType(ip,val,type);
   if (rc) return rc;
 
   if (Tcl_IsShared(val)) {
     val= Tcl_DuplicateObj(val);
-    agg->copied= 1;
+    sth->copied= 1;
   }
   Tcl_InvalidateStringRep(val);
-  agg->obj= val;
+  sth->obj= val;
 
-  agg->hb= OBJ_HBYTES(val);
   return TCL_OK;
 }
 
-void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) {
+int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) {
+  int rc;
+  rc= pat_somethingv(ip,var,&agg->sth,&hbytes_type);  if (rc) return rc;
+  agg->hb= OBJ_HBYTES(agg->sth.obj);
+  return TCL_OK;
+}
+
+void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth) {
   Tcl_Obj *ro;
   
   if (!rc) {
-    assert(agg->obj);
-    ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG);
+    assert(sth->obj);
+    ro= Tcl_ObjSetVar2(ip,sth->var,0,sth->obj,TCL_LEAVE_ERR_MSG);
     if (!ro) rc= TCL_ERROR;
   }
-  if (rc && agg->copied)
-    Tcl_DecrRefCount(agg->obj);
+  if (rc && sth->copied)
+    Tcl_DecrRefCount(sth->obj);
 }
 
 int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) {
index 1042378..235f770 100644 (file)
@@ -2,8 +2,12 @@ Type hb:                       HBytes_Value @
 Init hb                                hbytes_sentinel(&@);
 
 Type hbv:                      HBytes_Var @
-Init hbv                       @.hb=0; @.obj=0; @.var=0; @.copied=0;
-Fini hbv                       fini_hbv(ip, rc, &@);
+Init hbv                       @.hb=0; init_somethingv(&@.sth);
+Fini hbv                       fini_somethingv(ip, rc, &@.sth);
+
+Type maskmapv:                 MaskMap_Var @
+Init maskmapv                  @.mm=0; init_somethingv(&@.sth);
+Fini maskmapv                  fini_somethingv(ip, rc, &@.sth);
 
 Type sockaddr:                 SockAddr_Value @
 Init sockaddr                  sockaddr_clear(&@);
@@ -30,6 +34,21 @@ Table toplevel TopLevel_Command
        ulong
                subcmd  enum(ULong_SubCommand,"ulong subcommand")
                ...     obj
+       mask-map
+               subcmd  enum(MaskMap_SubCommand, "hbytes mask-map subcommand")
+               ...     obj
+
+Table maskmap MaskMap_SubCommand
+       lookup
+               map     maskmapv
+               addr    hb
+               ?def    obj
+               =>      obj
+       amend
+               map     maskmapv
+               prefix  hb
+               preflen int
+               data    obj
 
 Table ulong ULong_SubCommand
        ul2int
index 1819d87..b6009f8 100644 (file)
@@ -14,7 +14,8 @@ OBJS=         tables.o \
                misc.o \
                algtables.o \
                crypto.o \
-               parse.o
+               parse.o \
+               maskmap.o
 
 HDRS=          hbytes.h \
                $(AUTO_HDRS)
index 1014182..207e32a 100644 (file)
  *               uint VARNAME/VALUE         (VARNAME if ul2bitfields;
  *               ulong VARNAME/VALUE         VALUE if bitfields2ul)
  *
+ *  hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT]   => DATA
+ *     error on missing default or if address too short
+ *  hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA
+ *     a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]]
+ *     sorted first by descending PREFIX-LENGTH and then by PREFIX
+ *     each PREFIX is truncated to the shortest number of pairs of
+ *     hex digits which can represent it
+ *
  * Error codes
  *
  * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT  block cipher mode failed somehow (!)
 #include <sys/un.h>
 #include <arpa/inet.h>
 
-#include <tcl.h>
+#include <tcl8.3/tcl.h>
 
 typedef unsigned char Byte;
 
@@ -234,12 +242,30 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str);
 /* from parse.c */
 
 typedef struct {
-  HBytes_Value *hb;
   Tcl_Obj *obj, *var;
   int copied;
+} Something_Var;
+
+void init_somethingv(Something_Var *sth);
+void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth);
+int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var,
+                  Something_Var *sth, Tcl_ObjType *type);
+
+typedef struct {
+  HBytes_Value *hb;
+  Something_Var sth;
 } HBytes_Var;
 
-void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg);
+/* from maskmap.c */
+
+typedef struct MaskMap_Value MaskMap_Value;
+
+typedef struct {
+  MaskMap_Value *mm;
+  Something_Var sth;
+} MaskMap_Var;
+
+extern Tcl_ObjType maskmap_type;
 
 /* from chop.c */
   /* only do_... functions declared in tables.h */
index 32c604f..e067c94 100644 (file)
@@ -380,6 +380,12 @@ int do_toplevel_ulong(ClientData cd, Tcl_Interp *ip,
   return subcmd->func(0,ip,objc,objv);
 }
 
+int do_toplevel_mask_map(ClientData cd, Tcl_Interp *ip,
+                     const MaskMap_SubCommand *subcmd,
+                     int objc, Tcl_Obj *const *objv) {
+  return subcmd->func(0,ip,objc,objv);
+}
+
 #define URANDOM "/dev/urandom"
 
 int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) {
index 911cadd..1d91238 100644 (file)
@@ -22,40 +22,51 @@ int pat_string(Tcl_Interp *ip, Tcl_Obj *obj, const char **val) {
   *val= Tcl_GetString(obj);
   return TCL_OK;
 }
-  
-int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) {
+
+void init_somethingv(Something_Var *sth) {
+  sth->obj=0; sth->var=0; sth->copied=0;
+}
+
+int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var,
+                  Something_Var *sth, Tcl_ObjType *type) {
   int rc;
   Tcl_Obj *val;
 
-  agg->var= var;
+  sth->var= var;
 
   val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG);
   if (!val) return TCL_ERROR;
 
-  rc= Tcl_ConvertToType(ip,val,&hbytes_type);
+  rc= Tcl_ConvertToType(ip,val,type);
   if (rc) return rc;
 
   if (Tcl_IsShared(val)) {
     val= Tcl_DuplicateObj(val);
-    agg->copied= 1;
+    sth->copied= 1;
   }
   Tcl_InvalidateStringRep(val);
-  agg->obj= val;
+  sth->obj= val;
 
-  agg->hb= OBJ_HBYTES(val);
   return TCL_OK;
 }
 
-void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) {
+int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) {
+  int rc;
+  rc= pat_somethingv(ip,var,&agg->sth,&hbytes_type);  if (rc) return rc;
+  agg->hb= OBJ_HBYTES(agg->sth.obj);
+  return TCL_OK;
+}
+
+void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth) {
   Tcl_Obj *ro;
   
   if (!rc) {
-    assert(agg->obj);
-    ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG);
+    assert(sth->obj);
+    ro= Tcl_ObjSetVar2(ip,sth->var,0,sth->obj,TCL_LEAVE_ERR_MSG);
     if (!ro) rc= TCL_ERROR;
   }
-  if (rc && agg->copied)
-    Tcl_DecrRefCount(agg->obj);
+  if (rc && sth->copied)
+    Tcl_DecrRefCount(sth->obj);
 }
 
 int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) {
diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c
new file mode 100644 (file)
index 0000000..9968801
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ */
+
+#include "tables.h"
+#include "hbytes.h"
+
+typedef struct {
+  int prefixlen; /* there may be some empty slots with prefixlen==-1 at end */
+  Byte *prefix; /* ceil(prefixlen/8) bytes */
+  Tcl_Obj *data;
+} MaskMap_Entry;
+
+struct MaskMap_Value {
+  int allocd;
+  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;
+}
+
+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; }
+
+Tcl_ObjType maskmap_type = {
+  "mask-map",
+  maskmap_t_free, maskmap_t_dup, maskmap_t_ustr, maskmap_t_sfa
+};