📄 tbl.c
字号:
/* $Id: tbl.c,v 1.2 2006/06/27 12:43:47 ellson Exp $ $Revision: 1.2 $ *//* vim:set shiftwidth=4 ts=8: *//*********************************************************** This software is part of the graphviz package ** http://www.graphviz.org/ ** ** Copyright (c) 1994-2004 AT&T Corp. ** and is licensed under the ** Common Public License, Version 1.0 ** by AT&T Corp. ** ** Information and Software Systems Research ** AT&T Research, Florham Park NJ ***********************************************************//* Lefteris Koutsofios - AT&T Bell Laboratories */#include "common.h"#include "mem.h"#include "code.h"#include "tbl.h"long Ttime = 0;int Tstringoffset, Tcodeoffset, Tkvoffset;Tobj Ttrue, Tfalse;#define ISEQIK(ik, ko) \ (T_ISNUMBER (ko) && Tgetnumber (ko) == (ik))#define ISEQRK(rk, ko) \ (T_ISNUMBER (ko) && Tgetnumber (ko) == (rk))#define ISEQSK(sk, ko) \ (T_ISSTRING (ko) && Strcmp (((Tstring_t *) (ko))->s, (sk)) == 0)#define GETIKINDEX(tp, ik) (unsigned long) ik % tp->ln#define GETRKINDEX(tp, rk) (unsigned long) rk % tp->ln#define GETSKINDEX(tp, sk) (unsigned long) *sk % tp->lntypedef struct mapentry_t { struct mapentry_t *next; Tobj fmo, too;} mapentry_t;#define MAPENTRYSIZE sizeof (mapentry_t)#define MAPLISTN 100typedef struct map_tt { struct mapentry_t *list[MAPLISTN];} map_tt;static map_tt map;static long mapentrybyte2size;static long truem, falsem;static Tinteger_t keyi;static Treal_t keyr;static Tstring_t keys;static void insert(Ttable_t *, Tobj, char *, Tobj);static Tobj find(Ttable_t *, Tobj, char *);static void delete(Ttable_t *, Tobj, char *);static void copytable(Ttable_t *, long);static void reccopytable(Ttable_t *, Ttable_t *);static void mapinit(void);static void mapterm(void);static void mapinsert(Tobj, Tobj);static Tobj mapfind(Tobj);void Tinit(void){ Tstring_t s; Tcode_t c; Tkvlist_t kvl; Mhaspointers[T_INTEGER] = FALSE; Mhaspointers[T_REAL] = FALSE; Mhaspointers[T_STRING] = FALSE; Mhaspointers[T_CODE] = FALSE; Mhaspointers[T_TABLE] = TRUE; Ttrue = Tinteger(1); truem = Mpushmark(Ttrue); Tfalse = Tinteger(0); falsem = Mpushmark(Tfalse); Tstringoffset = (char *) &s.s[0] - (char *) &s + 1; /* the + 1 above accounts for the null character */ Tcodeoffset = (char *) &c.c[0] - (char *) &c; Tkvoffset = (char *) &kvl.kv[0] - (char *) &kvl; keyi.head.type = T_INTEGER; keyr.head.type = T_REAL; keys.head.type = T_STRING; mapentrybyte2size = M_BYTE2SIZE(MAPENTRYSIZE);}void Tterm(void){ Mpopmark(falsem); Tfalse = NULL; Mpopmark(truem); Ttrue = NULL; Mdogc(M_GCFULL); Mdogc(M_GCFULL);}void Tgchelper(void *p){ Ttable_t *tp; Tkvlist_t *kvlp; long i, j; /* must be a table */ tp = (Ttable_t *) p; for (i = 0; i < tp->ln; i++) if ((kvlp = tp->lp[i])) for (j = 0; j < kvlp->i; j++) Mmkcurr(kvlp->kv[j].ko), Mmkcurr(kvlp->kv[j].vo);}void Tfreehelper(void *p){ Ttable_t *tp; Tkvlist_t *kvlp; long i; /* must be a table */ tp = (Ttable_t *) p; for (i = 0; i < tp->ln; i++) if ((kvlp = tp->lp[i])) Mfree(kvlp, M_BYTE2SIZE(T_KVLISTSIZE(kvlp->n))); Mfree(tp->lp, M_BYTE2SIZE(tp->ln * T_KVLISTPTRSIZE));}Tobj Tinteger(long i){ Tinteger_t *ip; ip = Mnew(T_INTEGERSIZE, T_INTEGER); ip->i = i; return ip;}Tobj Treal(double d){ Treal_t *rp; if (d == (double) (long) d) return Tinteger((long) d); rp = Mnew(T_REALSIZE, T_REAL); rp->d = d; return rp;}Tobj Tstring(char *s){ Tstring_t *sp; sp = Mnew((long) T_STRINGSIZE(strlen(s)), T_STRING); strcpy(&sp->s[0], s); return sp;}Tobj Tcode(Code_t * cp, int ci, int cl){ Tcode_t *codep; Code_t *cp2; char *s; int i, j, cn; codep = Mnew((long) T_CODESIZE(cl), T_CODE); cp2 = codep->c; for (i = 0; i < cl; i++) { switch (cp[i].ctype) { case C_INTEGER: cp2[i] = cp[i]; if (cp2[i].next != C_NULL) cp2[i].next -= ci; break; case C_REAL: cp2[i] = cp[i]; if (cp2[i].next != C_NULL) cp2[i].next -= ci; break; case C_STRING: cp2[i] = cp[i]; if (cp2[i].next != C_NULL) cp2[i].next -= ci; s = (char *) &cp[i].u.s; while (*s) s++; cn = (long) (s - (char *) &cp[i]) / sizeof(Code_t); for (j = 0; j < cn; j++) i++, cp2[i] = cp[i]; break; default: cp2[i] = cp[i]; if (cp2[i].next != C_NULL) cp2[i].next -= ci; if (cp2[i].u.fp != C_NULL) cp2[i].u.fp -= ci; break; } } return codep;}Tobj Ttable(long sizehint){ Ttable_t *tp; Tkvlist_t **lp; long i; sizehint = (sizehint < 2) ? 2 : sizehint; tp = Mnew(T_TABLESIZE, T_TABLE); lp = Mallocate((long) (sizehint * T_KVLISTPTRSIZE)); tp->lp = lp; tp->ln = sizehint; tp->n = 0; tp->time = Ttime; for (i = 0; i < sizehint; i++) lp[i] = NULL; return tp;}void Tinsi(Tobj to, long ik, Tobj vo){ long tm; if (!to || !T_ISTABLE(to)) panic1(POS, "Tinsi", "insert attempted on non-table"); tm = Mpushmark(to); if (vo) Mpushmark(vo); keyi.i = ik; insert(to, &keyi, NULL, vo); Mpopmark(tm);}void Tinsr(Tobj to, double rk, Tobj vo){ long tm; if (!to || !T_ISTABLE(to)) panic1(POS, "Tinsr", "insert attempted on non-table"); tm = Mpushmark(to); if (vo) Mpushmark(vo); keyr.d = rk; insert(to, &keyr, NULL, vo); Mpopmark(tm);}void Tinss(Tobj to, char *sk, Tobj vo){ long tm; if (!to || !T_ISTABLE(to)) panic1(POS, "Tinss", "insert attempted on non-table"); tm = Mpushmark(to); if (vo) Mpushmark(vo); insert(to, &keys, sk, vo); Mpopmark(tm);}void Tinso(Tobj to, Tobj ko, Tobj vo){ long tm; if (!to || !T_ISTABLE(to)) panic1(POS, "Tinso", "insert attempted on non-table"); if (!ko || !(T_ISINTEGER(ko) || T_ISREAL(ko) || T_ISSTRING(ko))) panic1(POS, "Tinso", "bad key"); tm = Mpushmark(to); Mpushmark(ko); if (vo) Mpushmark(vo); insert(to, ko, NULL, vo); Mpopmark(tm);}Tobj Tfindi(Tobj to, long ik){ if (!to) return NULL; if (!T_ISTABLE(to)) panic1(POS, "Tfindi", "find attempted on non-table"); keyi.i = ik; return find(to, &keyi, NULL);}Tobj Tfindr(Tobj to, double rk){ if (!to) return NULL; if (!T_ISTABLE(to)) panic1(POS, "Tfindr", "find attempted on non-table"); keyr.d = rk; return find(to, &keyr, NULL);}Tobj Tfinds(Tobj to, char *sk){ if (!to) return NULL; if (!T_ISTABLE(to)) panic1(POS, "Tfinds", "find attempted on non-table"); return find(to, &keys, sk);}Tobj Tfindo(Tobj to, Tobj ko){ if (!to || !ko) return NULL; if (!T_ISTABLE(to)) panic1(POS, "Tfindo", "find attempted on non-table"); if (!(T_ISINTEGER(ko) || T_ISREAL(ko) || T_ISSTRING(ko))) panic1(POS, "Tfindo", "bad key"); return find(to, ko, NULL);}void Tdeli(Tobj to, long ik){ if (!to) return; if (!T_ISTABLE(to)) panic1(POS, "Tdeli", "delete attempted on non-table"); keyi.i = ik; delete(to, &keyi, NULL);}void Tdelr(Tobj to, double rk){ if (!to) return; if (!T_ISTABLE(to)) panic1(POS, "Tdelr", "delete attempted on non-table"); keyr.d = rk; delete(to, &keyr, NULL);}void Tdels(Tobj to, char *sk){ if (!to) return; if (!T_ISTABLE(to)) panic1(POS, "Tdels", "delete attempted on non-table"); delete(to, &keys, sk);}void Tdelo(Tobj to, Tobj ko){ if (!to || !ko) return; if (!T_ISTABLE(to)) panic1(POS, "Tdelo", "delete attempted on non-table"); if (!(T_ISINTEGER(ko) || T_ISREAL(ko) || T_ISSTRING(ko))) panic1(POS, "Tdelo", "bad key"); delete(to, ko, NULL);}Tobj Tcopy(Tobj fmvo){ Tobj tovo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -