chiark / gitweb /
hbytes range
[chiark-tcl.git] / hbytes / ulongs.c
1 /*
2  */
3
4 #include "hbytes.h"
5 #include "tables.h"
6
7 #define SIZES                                   \
8   DO_SIZE(ulong, 4, 0xffffffffUL,               \
9           DO_BYTE(0,24)                         \
10           DO_BYTE(1,16)                         \
11           DO_BYTE(2,8)                          \
12           DO_BYTE(3,0))                         \
13   DO_SIZE(ushort, 2, 0x0000ffffUL,              \
14           DO_BYTE(0,8)                          \
15           DO_BYTE(1,0))
16
17 #define DO_BYTE(index,shift) (data[index] << shift) |
18 #define DO_SIZE(ulongint, len, max, bytes)                              \
19   int do_hbytes_h2##ulongint(ClientData cd, Tcl_Interp *ip,             \
20                              HBytes_Value hex, unsigned long *result) { \
21     const Byte *data;                                                   \
22     if (hbytes_len(&hex) != len)                                        \
23       return staticerr(ip, #ulongint " must be " #len " bytes");        \
24     data= hbytes_data(&hex);                                            \
25     *result= (bytes  0);                                                \
26     return TCL_OK;                                                      \
27   }
28 SIZES
29 #undef DO_BYTE
30 #undef DO_SIZE
31
32 #define DO_BYTE(index,shift) data[index]= (value >> shift);
33 #define DO_SIZE(ulongint, len, max, bytes)                                  \
34   int do_hbytes_##ulongint##2h(ClientData cd, Tcl_Interp *ip,               \
35                                unsigned long value, HBytes_Value *result) { \
36     Byte *data;                                                             \
37     if (value > max) return staticerr(ip, #ulongint " too big");            \
38     data= hbytes_arrayspace(result,len);                                    \
39     bytes                                                                   \
40     return TCL_OK;                                                          \
41   }
42 SIZES
43 #undef DO_BYTE
44 #undef DO_SIZE
45
46 int pat_ulong(Tcl_Interp *ip, Tcl_Obj *obj, unsigned long *val) {
47   char *str, *ep;
48
49   str= Tcl_GetString(obj);
50   errno= 0;
51   *val= strtoul(str,&ep,0);
52   if (*ep || errno) return staticerr(ip, "bad unsigned value");
53   return TCL_OK;
54 }
55
56 Tcl_Obj *ret_ulong(Tcl_Interp *ip, unsigned long val) {
57   char buf[11];
58   assert(val <= 0xffffffffUL);
59   snprintf(buf,sizeof(buf), "0x%08lx", val);
60   return Tcl_NewStringObj(buf,sizeof(buf)-1);
61 }