chiark / gitweb /
1a66aa34629961b696d084d2bef9784de694be78
[chiark-tcl.git] / base / enum.c
1 /*
2  *
3  */
4
5 #include "hbytes.h"
6
7 static void enum_nt_dup(Tcl_Obj *src, Tcl_Obj *dup) {
8   dup->internalRep= src->internalRep;
9 }
10
11 static void enum_nt_ustr(Tcl_Obj *o) {
12   abort();
13 }
14
15 static int enum_nt_sfa(Tcl_Interp *ip, Tcl_Obj *o) {
16   abort();
17 }
18
19 Tcl_ObjType enum_nearlytype = {
20   "enum-nearly",
21   0, enum_nt_dup, enum_nt_ustr, enum_nt_sfa
22 };
23
24 const void *enum_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o,
25                                     size_t entrysize, const void *firstentry,
26                                     const char *what) {
27   const char *supplied, *found;
28   const char *ep;
29   
30   if (o->typePtr == &enum_nearlytype &&
31       o->internalRep.twoPtrValue.ptr1 == firstentry)
32     return o->internalRep.twoPtrValue.ptr2;
33
34   supplied= Tcl_GetStringFromObj(o,0);  assert(supplied);
35   for (ep= firstentry;
36        (found= *(const char*const*)ep) && strcmp(supplied,found);
37        ep += entrysize);
38
39   if (found) {
40     objfreeir(o);
41     o->typePtr= &enum_nearlytype;
42     o->internalRep.twoPtrValue.ptr1= (void*)firstentry;
43     o->internalRep.twoPtrValue.ptr2= (void*)ep;
44     return ep;
45   }
46
47   Tcl_ResetResult(ip);
48   Tcl_AppendResult(ip, "invalid ",what," - must be one of:",(char*)0);
49   for (ep= firstentry;
50        (found= *(const char*const*)ep);
51        ep += entrysize)
52     Tcl_AppendResult(ip, " ",found,(char*)0);
53   return 0;
54 }