chiark / gitweb /
ulongs and ushorts
authorian <ian>
Sun, 8 Sep 2002 13:26:42 +0000 (13:26 +0000)
committerian <ian>
Sun, 8 Sep 2002 13:26:42 +0000 (13:26 +0000)
base/tables-examples.tct
base/troglodyte-Makefile
hbytes/ulongs.c [new file with mode: 0644]

index 71cb4bf3935bb88a76524bad4c1a2a61e94c9dce..37286adb6bcf5597d479aaa4dfbcb9534b59cedd 100644 (file)
@@ -9,6 +9,7 @@ Type sockaddr:                  SockAddr_Value @
 Init sockaddr                  sockaddr_clear(&@);
 
 Type sockid:                   DgramSockID @
 Init sockaddr                  sockaddr_clear(&@);
 
 Type sockid:                   DgramSockID @
+Type ulong:                    unsigned long @
 
 H-Include      "hbytes.h"
 
 
 H-Include      "hbytes.h"
 
@@ -27,6 +28,18 @@ Table hbytes HBytes_SubCommand
        h2raw
                hex     hb
                =>      obj
        h2raw
                hex     hb
                =>      obj
+       ulong2h
+               value   ulong
+               =>      hb
+       h2ulong
+               hex     hb
+               =>      ulong
+       ushort2h
+               value   ulong
+               =>      hb
+       h2ushort
+               hex     hb
+               =>      ulong
        length
                v       hb
                =>      int
        length
                v       hb
                =>      int
index 64160c038e6edd55ac6f717233cadb86d5cf14bc..cdcebde8de8c16a424f10b7c2d60dd2e4f3ebf37 100644 (file)
@@ -1,6 +1,7 @@
 OBJS=          tables.o \
                hbytes.o \
                enum.o \
 OBJS=          tables.o \
                hbytes.o \
                enum.o \
+               ulongs.o \
                sockaddr.o \
                dgram.o \
                chop.o \
                sockaddr.o \
                dgram.o \
                chop.o \
diff --git a/hbytes/ulongs.c b/hbytes/ulongs.c
new file mode 100644 (file)
index 0000000..8260a44
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ */
+
+#include "hbytes.h"
+#include "tables.h"
+
+#define SIZES                                  \
+  DO_SIZE(ulong, 4, 0xffffffffUL,              \
+         DO_BYTE(0,24)                         \
+         DO_BYTE(1,16)                         \
+         DO_BYTE(2,8)                          \
+         DO_BYTE(3,0))                         \
+  DO_SIZE(ushort, 2, 0x0000ffffUL,             \
+         DO_BYTE(0,8)                          \
+         DO_BYTE(1,0))
+
+#define DO_BYTE(index,shift) (data[index] << shift) |
+#define DO_SIZE(ulongint, len, max, bytes)                             \
+  int do_hbytes_h2##ulongint(ClientData cd, Tcl_Interp *ip,            \
+                            HBytes_Value hex, unsigned long *result) { \
+    const Byte *data;                                                  \
+    if (hbytes_len(&hex) != len)                                       \
+      return staticerr(ip, #ulongint " must be " #len " bytes");       \
+    data= hbytes_data(&hex);                                           \
+    *result= (bytes  0);                                               \
+    return TCL_OK;                                                     \
+  }
+SIZES
+#undef DO_BYTE
+#undef DO_SIZE
+
+#define DO_BYTE(index,shift) data[index]= (value >> shift);
+#define DO_SIZE(ulongint, len, max, bytes)                                 \
+  int do_hbytes_##ulongint##2h(ClientData cd, Tcl_Interp *ip,              \
+                              unsigned long value, HBytes_Value *result) { \
+    Byte *data;                                                                    \
+    if (value > max) return staticerr(ip, #ulongint " too big");           \
+    data= hbytes_arrayspace(result,len);                                   \
+    bytes                                                                  \
+    return TCL_OK;                                                         \
+  }
+SIZES
+#undef DO_BYTE
+#undef DO_SIZE
+
+int pat_ulong(Tcl_Interp *ip, Tcl_Obj *obj, unsigned long *val) {
+  char *str, *ep;
+
+  str= Tcl_GetString(obj);
+  errno= 0;
+  *val= strtoul(str,&ep,0);
+  if (*ep || errno) return staticerr(ip, "bad unsigned value");
+  return TCL_OK;
+}
+
+Tcl_Obj *ret_ulong(Tcl_Interp *ip, unsigned long val) {
+  char buf[11];
+  assert(val <= 0xffffffffUL);
+  snprintf(buf,sizeof(buf), "0x%08lx", val);
+  return Tcl_NewStringObj(buf,sizeof(buf)-1);
+}