1 /* This file is part of GDBM, the GNU data base manager.
2 Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
5 GDBM is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 GDBM is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
20 #define DEFFMT(name, type, fmt) \
22 name (FILE *fp, void *ptr, int size) \
24 fprintf (fp, fmt, *(type*) ptr); \
28 DEFFMT (f_char, char, "%c")
29 DEFFMT (f_short, short, "%hd")
30 DEFFMT (f_ushort, unsigned short, "%hu")
31 DEFFMT (f_int, int, "%d")
32 DEFFMT (f_uint, unsigned, "%u")
33 DEFFMT (f_long, long, "%ld")
34 DEFFMT (f_ulong, unsigned long, "%lu")
35 DEFFMT (f_llong, long long, "%lld")
36 DEFFMT (f_ullong, unsigned long long, "%llu")
37 DEFFMT (f_float, float, "%f")
38 DEFFMT (f_double, double, "%e")
41 f_stringz (FILE *fp, void *ptr, int size)
46 for (sz = 1, s = ptr; *s; s++, sz++)
52 else if ((c = escape (*s)))
53 fprintf (fp, "\\%c", c);
55 fprintf (fp, "\\%03o", *s);
61 f_string (FILE *fp, void *ptr, int size)
66 for (sz = 0, s = ptr; sz < size; s++, sz++)
72 else if ((c = escape (*s)))
73 fprintf (fp, "\\%c", c);
75 fprintf (fp, "\\%03o", *s);
81 s_char (struct xdatum *xd, char *str)
83 xd_store (xd, str, 1);
87 #define DEFNSCAN(name, type, temptype, strto) \
89 name (struct xdatum *xd, char *str) \
96 n = strto (str, &p, 0); \
99 if (errno == ERANGE || (t = n) != n) \
101 xd_store (xd, &n, sizeof (n)); \
105 DEFNSCAN(s_short, short, long, strtol);
106 DEFNSCAN(s_ushort, unsigned short, unsigned long, strtoul);
107 DEFNSCAN(s_int, int, long, strtol)
108 DEFNSCAN(s_uint, unsigned, unsigned long, strtol)
109 DEFNSCAN(s_long, long, long, strtoul)
110 DEFNSCAN(s_ulong, unsigned long, unsigned long, strtoul)
111 DEFNSCAN(s_llong, long long, long long, strtoll)
112 DEFNSCAN(s_ullong, unsigned long long, unsigned long long, strtoull)
115 s_double (struct xdatum *xd, char *str)
121 d = strtod (str, &p);
124 xd_store (xd, &d, sizeof (d));
129 s_float (struct xdatum *xd, char *str)
135 d = strtod (str, &p);
138 xd_store (xd, &d, sizeof (d));
143 s_stringz (struct xdatum *xd, char *str)
145 xd_store (xd, str, strlen (str) + 1);
150 s_string (struct xdatum *xd, char *str)
152 xd_store (xd, str, strlen (str));
156 static struct datadef datatab[] = {
157 { "char", sizeof(char), f_char, s_char },
158 { "short", sizeof(short), f_short, s_short },
159 { "ushort", sizeof(unsigned short), f_ushort, s_ushort },
160 { "int", sizeof(int), f_int, s_int },
161 { "unsigned", sizeof(unsigned), f_uint, s_uint },
162 { "uint", sizeof(unsigned), f_uint, s_uint },
163 { "long", sizeof(long), f_long, s_long },
164 { "ulong", sizeof(unsigned long), f_ulong, s_ulong },
165 { "llong", sizeof(long long), f_llong, s_llong },
166 { "ullong", sizeof(unsigned long long), f_ullong, s_ullong },
167 { "float", sizeof(float), f_float, s_float },
168 { "double", sizeof(double), f_double, s_double },
169 { "stringz", 0, f_stringz, s_stringz },
170 { "string", 0, f_string, s_string },
175 datadef_lookup (const char *name)
179 for (p = datatab; p->name; p++)
180 if (strcmp (p->name, name) == 0)
188 struct dsegm *p = emalloc (sizeof (*p));
195 dsegm_new_field (struct datadef *type, char *id, int dim)
197 struct dsegm *p = dsegm_new (FDEF_FLD);
198 p->v.field.type = type;
199 p->v.field.name = id;
200 p->v.field.dim = dim;
205 dsegm_free_list (struct dsegm *dp)
209 struct dsegm *next = dp->next;
216 datum_format (FILE *fp, datum const *dat, struct dsegm *ds)
224 fprintf (fp, "%.*s\n", dat->dsize, dat->dptr);
228 if (variable_get ("delim1", VART_STRING, (void*) &delim[0]))
230 if (variable_get ("delim2", VART_STRING, (void*) &delim[1]))
233 for (; ds && off <= dat->dsize; ds = ds->next)
239 fwrite (delim[1], strlen (delim[1]), 1, fp);
240 if (ds->v.field.name)
241 fprintf (fp, "%s=", ds->v.field.name);
242 if (ds->v.field.dim > 1)
244 if (ds->v.field.type->format)
248 for (i = 0; i < ds->v.field.dim; i++)
251 fwrite (delim[0], strlen (delim[0]), 1, fp);
252 if (off + ds->v.field.type->size > dat->dsize)
254 fprintf (fp, _("(not enough data)"));
260 n = ds->v.field.type->format (fp,
261 (char*) dat->dptr + off,
262 ds->v.field.type->size ?
263 ds->v.field.type->size :
269 if (ds->v.field.dim > 1)
294 xd_expand (struct xdatum *xd, size_t size)
298 xd->dptr = erealloc (xd->dptr, size);
299 memset (xd->dptr + xd->dmax, 0, size - xd->dmax);
305 xd_store (struct xdatum *xd, void *val, size_t size)
307 xd_expand (xd, xd->off + size);
308 memcpy (xd->dptr + xd->off, val, size);
310 if (xd->off > xd->dsize)
315 datum_scan_notag (datum *dat, struct dsegm *ds, struct kvpair *kv)
322 memset (&xd, 0, sizeof (xd));
324 for (; err == 0 && ds && kv; ds = ds->next, kv = kv->next)
329 _("mixing tagged and untagged values is not allowed"));
337 if (!ds->v.field.type->scan)
343 err = ds->v.field.type->scan (&xd, kv->val.s);
345 lerror (&kv->loc, _("cannot convert"));
349 for (i = 0, s = kv->val.l; i < ds->v.field.dim && s;
352 err = ds->v.field.type->scan (&xd, s->str);
356 _("cannot convert value #%d: %s"),
361 /* FIXME: Warn if (s) -> "extra data" */
366 xd_expand (&xd, ds->v.n);
371 xd_expand (&xd, xd.off + ds->v.n);
384 dat->dsize = xd.dsize;
390 datum_scan_tag (datum *dat, struct dsegm *ds, struct kvpair *kv)
392 lerror (&kv->loc, "tagged values are not yet supported");
397 datum_scan (datum *dat, struct dsegm *ds, struct kvpair *kv)
399 return (kv->key ? datum_scan_tag : datum_scan_notag) (dat, ds, kv);
403 dsprint (FILE *fp, int what, struct dsegm *ds)
405 static char *dsstr[] = { "key", "content" };
408 fprintf (fp, "define %s", dsstr[what]);
411 fprintf (fp, " {\n");
416 for (; ds; ds = ds->next)
421 fprintf (fp, "%c%s", delim, ds->v.field.type->name);
422 if (ds->v.field.name)
423 fprintf (fp, " %s", ds->v.field.name);
424 if (ds->v.field.dim > 1)
425 fprintf (fp, "[%d]", ds->v.field.dim);
429 fprintf (fp, "%coffset %d", delim, ds->v.n);
433 fprintf (fp, "%cpad %d", delim, ds->v.n);