]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/flist.c
Update copyright dates (again)
[thirdparty/xfsprogs-dev.git] / db / flist.c
CommitLineData
2bd0ea18 1/*
0d3e0b37 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <libxfs.h>
34#include "type.h"
35#include "faddr.h"
36#include "fprint.h"
37#include "field.h"
38#include "flist.h"
39#include "debug.h"
40#include "output.h"
41#include "malloc.h"
42
43static void flist_expand_arrays(flist_t *fl);
44static void flist_expand_structs(flist_t *fl, void *obj);
45static flist_t *flist_replicate(flist_t *fl);
46static ftok_t *flist_split(char *s);
47static void ftok_free(ftok_t *ft);
48
49static void
50flist_expand_arrays(
51 flist_t *fl)
52{
53 const field_t *f;
54#ifdef DEBUG
55 const ftattr_t *fa;
56#endif
57 int high;
58 int idx;
59 int low;
60 flist_t *new;
61 flist_t *prev;
62 flist_t *sib;
63
64 f = fl->fld;
65#ifdef DEBUG
66 fa = &ftattrtab[f->ftyp];
67#endif
68 ASSERT(fa->ftyp == f->ftyp);
69 ASSERT(f->flags & FLD_ARRAY);
70 low = fl->low;
71 high = fl->high;
72 fl->high = fl->low;
73 sib = fl->sibling;
74 for (idx = low + 1, prev = fl; idx <= high; idx++) {
75 new = flist_make(f->name);
76 new->fld = f;
77 new->low = new->high = idx;
78 new->flags |= FL_OKLOW | FL_OKHIGH;
79 new->child = flist_replicate(fl->child);
80 prev->sibling = new;
81 prev = new;
82 }
83 prev->sibling = sib;
84}
85
86static void
87flist_expand_structs(
88 flist_t *fl,
89 void *obj)
90{
91 const field_t *cf;
92 const field_t *f;
93 const ftattr_t *fa;
94 flist_t *new;
95 flist_t *prev;
96
97 f = fl->fld;
98 fa = &ftattrtab[f->ftyp];
99 ASSERT(fa->ftyp == f->ftyp);
100 ASSERT(fa->subfld != NULL);
101 ASSERT(fl->child == NULL);
102 for (cf = fa->subfld, prev = NULL; cf->name != NULL; cf++) {
103 if (fcount(cf, obj, fl->offset) == 0)
104 continue;
105 if (cf->flags & FLD_SKIPALL)
106 continue;
107 new = flist_make(cf->name);
108 new->fld = cf;
109 if (prev)
110 prev->sibling = new;
111 else
112 fl->child = new;
113 prev = new;
114 }
115}
116
117void
118flist_free(
119 flist_t *fl)
120{
121 if (fl->child)
122 flist_free(fl->child);
123 if (fl->sibling)
124 flist_free(fl->sibling);
125 if (fl->name)
126 xfree(fl->name);
127 xfree(fl);
128}
129
130flist_t *
131flist_make(
132 char *name)
133{
134 flist_t *fl;
135
136 fl = xmalloc(sizeof(*fl));
137 fl->name = xstrdup(name);
138 fl->fld = NULL;
139 fl->child = NULL;
140 fl->sibling = NULL;
141 fl->low = 0;
142 fl->high = 0;
143 fl->flags = 0;
144 fl->offset = 0;
145 return fl;
146}
147
148int
149flist_parse(
150 const field_t *fields,
151 flist_t *fl,
152 void *obj,
153 int startoff)
154{
155 const field_t *f;
156 const ftattr_t *fa;
157 int high;
158 int low;
159
160 while (fl) {
161 f = findfield(fl->name, fields, obj, startoff);
162 if (f == NULL) {
163 dbprintf("field %s not found\n", fl->name);
164 return 0;
165 }
166 fl->fld = f;
167 fa = &ftattrtab[f->ftyp];
168 ASSERT(fa->ftyp == f->ftyp);
169 if (f->flags & FLD_ARRAY) {
170 low = (f->flags & FLD_ABASE1) != 0;
171 high = fcount(f, obj, startoff) + low - 1;
172 if (low > high) {
173 dbprintf("no elements in %s\n", fl->name);
174 return 0;
175 }
176 if (fl->flags & FL_OKHIGH) {
177 if (fl->low < low || fl->low > high ||
178 fl->high < low || fl->high > high) {
179 dbprintf("indices %d-%d for field %s "
180 "out of range %d-%d\n",
181 fl->low, fl->high, fl->name,
182 low, high);
183 return 0;
184 }
185 } else if (fl->flags & FL_OKLOW) {
186 if (fl->low < low || fl->low > high) {
187 dbprintf("index %d for field %s out of "
188 "range %d-%d\n",
189 fl->low, fl->name, low, high);
190 return 0;
191 }
192 fl->high = fl->low;
193 fl->flags |= FL_OKHIGH;
194 } else {
195 fl->low = low;
196 fl->high = high;
197 fl->flags |= FL_OKLOW | FL_OKHIGH;
198 }
199 } else {
200 if (fl->flags & FL_OKLOW) {
201 dbprintf("field %s is not an array\n",
202 fl->name);
203 return 0;
204 }
205 }
206 fl->offset = startoff + bitoffset(f, obj, startoff, fl->low);
207 if ((fl->child != NULL || fa->prfunc == NULL) &&
208 (f->flags & FLD_ARRAY) && fl->low != fl->high)
209 flist_expand_arrays(fl);
210 if (fa->prfunc == NULL && fl->child == NULL)
211 flist_expand_structs(fl, obj);
212 if (fl->child) {
213 if (fa->subfld == NULL) {
214 dbprintf("field %s has no subfields\n",
215 fl->name);
216 return 0;
217 }
218 if (!flist_parse(fa->subfld, fl->child, obj,
219 fl->offset))
220 return 0;
221 }
222 fl = fl->sibling;
223 }
224 return 1;
225}
226
227void
228flist_print(
229 flist_t *fl)
230{
231 if (!(debug_state & DEBUG_FLIST))
232 return;
233 while (fl) {
234 dbprintf("fl@%p:\n", fl);
235 dbprintf("\tname=%s, fld=%p, child=%p, sibling=%p\n",
236 fl->name, fl->fld, fl->child, fl->sibling);
237 dbprintf("\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n",
238 fl->low, fl->high, fl->flags,
239 fl->flags & FL_OKLOW ? "oklow " : "",
240 fl->flags & FL_OKHIGH ? "okhigh" : "", fl->offset);
241 dbprintf("\tfld->name=%s, fld->ftyp=%d (%s)\n",
242 fl->fld->name, fl->fld->ftyp,
243 ftattrtab[fl->fld->ftyp].name);
244 dbprintf("\tfld->flags=%d (%s%s%s%s%s)\n", fl->fld->flags,
245 fl->fld->flags & FLD_ABASE1 ? "abase1 " : "",
246 fl->fld->flags & FLD_SKIPALL ? "skipall " : "",
247 fl->fld->flags & FLD_ARRAY ? "array " : "",
248 fl->fld->flags & FLD_OFFSET ? "offset " : "",
249 fl->fld->flags & FLD_COUNT ? "count " : "");
250 if (fl->child)
251 flist_print(fl->child);
252 fl = fl->sibling;
253 }
254}
255
256static flist_t *
257flist_replicate(
258 flist_t *f)
259{
260 flist_t *new;
261
262 if (f == NULL)
263 return NULL;
264 new = flist_make(f->name);
265 new->fld = f->fld;
266 new->child = flist_replicate(f->child);
267 new->sibling = flist_replicate(f->sibling);
268 new->low = f->low;
269 new->high = f->high;
270 new->flags = f->flags;
271 new->offset = f->offset;
272 return new;
273}
274
275flist_t *
276flist_scan(
277 char *name)
278{
279 flist_t *fl;
280 flist_t *lfl;
281 flist_t *nfl;
282 int num;
283 ftok_t *p;
284 ftok_t *v;
285 char *x;
286
287 v = flist_split(name);
288 if (!v)
289 return NULL;
290 p = v;
291 fl = lfl = NULL;
292 while (p->tokty != TT_END) {
293 if (p->tokty != TT_NAME)
294 goto bad;
295 nfl = flist_make(p->tok);
296 if (lfl)
297 lfl->child = nfl;
298 else
299 fl = nfl;
300 lfl = nfl;
301 p++;
302 if (p->tokty == TT_LB) {
303 p++;
304 if (p->tokty != TT_NUM)
305 goto bad;
306 num = (int)strtoul(p->tok, &x, 0);
307 if (*x != '\0')
308 goto bad;
309 nfl->flags |= FL_OKLOW;
310 nfl->low = num;
311 p++;
312 if (p->tokty == TT_DASH) {
313 p++;
314 if (p->tokty != TT_NUM)
315 goto bad;
316 num = (int)strtoul(p->tok, &x, 0);
317 if (*x != '\0')
318 goto bad;
319 nfl->flags |= FL_OKHIGH;
320 nfl->high = num;
321 p++;
322 }
323 if (p->tokty != TT_RB)
324 goto bad;
325 p++;
326 }
327 if (p->tokty == TT_DOT) {
328 p++;
329 if (p->tokty == TT_END)
330 goto bad;
331 }
332 }
333 ftok_free(v);
334 return fl;
335bad:
336 dbprintf("bad syntax in field name %s\n", name);
337 ftok_free(v);
338 if (fl)
339 flist_free(fl);
340 return NULL;
341}
342
343static ftok_t *
344flist_split(
345 char *s)
346{
347 char *a;
348 int i;
349 static char *idchars;
350 static char *initidchar;
351 int l;
352 int tailskip = 0;
353 static char *numchars;
354 static char *xnumchars; /* extended for hex conversion */
355 int nv;
356 static char punctchars[] = "[-].";
357 static tokty_t puncttypes[] = { TT_LB, TT_DASH, TT_RB, TT_DOT };
358 tokty_t t;
359 ftok_t *v;
360
361 if (idchars == NULL) {
362 idchars = xmalloc(26 + 10 + 1 + 1);
363 initidchar = xmalloc(26 + 1);
364 numchars = xmalloc(10 + 1);
365 xnumchars = xmalloc(12 + 1);
366 for (i = 'a'; i <= 'z'; i++) {
367 idchars[i - 'a'] = i;
368 initidchar[i - 'a'] = i;
369 }
370
371 for (i = '0'; i <= '9'; i++) {
372 idchars[26 + (i - '0')] = i;
373 numchars[i - '0'] = i;
374 xnumchars[i - '0'] = i;
375 }
376 idchars[26 + 10] = '_';
377 idchars[26 + 10 + 1] = '\0';
378 initidchar[26] = '\0';
379 numchars[10] = '\0';
380 xnumchars[10] = 'x';
381 xnumchars[11] = 'X';
382 xnumchars[12] = '\0';
383 }
384 nv = 0;
385 v = xmalloc(sizeof(*v));
386 v->tok = NULL;
387 while (*s) {
388 /* need to add string handling */
389 if (*s == '\"') {
390 s++; /* skip first quote */
391 if ((a = strrchr(s, '\"')) == NULL) {
392 dbprintf("missing closing quote %s\n", s);
393 ftok_free(v);
394 return NULL;
395 }
396 tailskip = 1; /* skip remaing quote */
397 l = (int)(a - s);
398 t = TT_STRING;
399 } else if (strchr(initidchar, *s)) {
400 l = (int)strspn(s, idchars);
401 t = TT_NAME;
402 } else if (strchr(numchars, *s)) {
403 l = (int)strspn(s, xnumchars);
404 t = TT_NUM;
27527004 405 } else if ((a = strchr(punctchars, *s))) {
2bd0ea18
NS
406 l = 1;
407 t = puncttypes[a - punctchars];
408 } else {
409 dbprintf("bad character in field %s\n", s);
410 ftok_free(v);
411 return NULL;
412 }
413 a = xmalloc(l + 1);
414 strncpy(a, s, l);
415 a[l] = '\0';
416 v = xrealloc(v, (nv + 2) * sizeof(*v));
417 v[nv].tok = a;
418 v[nv].tokty = t;
419 nv++;
420 s += l + tailskip;
421 tailskip = 0;
422 }
423 v[nv].tok = NULL;
424 v[nv].tokty = TT_END;
425 return v;
426}
427
428static void
429ftok_free(
430 ftok_t *ft)
431{
432 ftok_t *p;
433
434 for (p = ft; p->tok; p++)
435 xfree(p->tok);
436 xfree(ft);
437}