]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/flist.c
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 static void flist_expand_arrays(flist_t
*fl
);
30 static void flist_expand_structs(flist_t
*fl
, void *obj
);
31 static flist_t
*flist_replicate(flist_t
*fl
);
32 static ftok_t
*flist_split(char *s
);
33 static void ftok_free(ftok_t
*ft
);
52 fa
= &ftattrtab
[f
->ftyp
];
54 ASSERT(fa
->ftyp
== f
->ftyp
);
55 ASSERT(f
->flags
& FLD_ARRAY
);
60 for (idx
= low
+ 1, prev
= fl
; idx
<= high
; idx
++) {
61 new = flist_make(f
->name
);
63 new->low
= new->high
= idx
;
64 new->flags
|= FL_OKLOW
| FL_OKHIGH
;
65 new->child
= flist_replicate(fl
->child
);
84 fa
= &ftattrtab
[f
->ftyp
];
85 ASSERT(fa
->ftyp
== f
->ftyp
);
86 ASSERT(fa
->subfld
!= NULL
);
87 ASSERT(fl
->child
== NULL
);
88 for (cf
= fa
->subfld
, prev
= NULL
; cf
->name
!= NULL
; cf
++) {
89 if (fcount(cf
, obj
, fl
->offset
) == 0)
91 if (cf
->flags
& FLD_SKIPALL
)
93 new = flist_make(cf
->name
);
108 flist_free(fl
->child
);
110 flist_free(fl
->sibling
);
122 fl
= xmalloc(sizeof(*fl
));
123 fl
->name
= xstrdup(name
);
136 const field_t
*fields
,
147 f
= findfield(fl
->name
, fields
, obj
, startoff
);
149 dbprintf(_("field %s not found\n"), fl
->name
);
153 fa
= &ftattrtab
[f
->ftyp
];
154 ASSERT(fa
->ftyp
== f
->ftyp
);
155 if (f
->flags
& FLD_ARRAY
) {
156 low
= (f
->flags
& FLD_ABASE1
) != 0;
157 high
= fcount(f
, obj
, startoff
) + low
- 1;
159 dbprintf(_("no elements in %s\n"), fl
->name
);
162 if (fl
->flags
& FL_OKHIGH
) {
163 if (fl
->low
< low
|| fl
->low
> high
||
164 fl
->high
< low
|| fl
->high
> high
) {
165 dbprintf(_("indices %d-%d for field %s "
166 "out of range %d-%d\n"),
167 fl
->low
, fl
->high
, fl
->name
,
171 } else if (fl
->flags
& FL_OKLOW
) {
172 if (fl
->low
< low
|| fl
->low
> high
) {
173 dbprintf(_("index %d for field %s out of "
175 fl
->low
, fl
->name
, low
, high
);
179 fl
->flags
|= FL_OKHIGH
;
183 fl
->flags
|= FL_OKLOW
| FL_OKHIGH
;
186 if (fl
->flags
& FL_OKLOW
) {
187 dbprintf(_("field %s is not an array\n"),
192 fl
->offset
= startoff
+ bitoffset(f
, obj
, startoff
, fl
->low
);
193 if ((fl
->child
!= NULL
|| fa
->prfunc
== NULL
) &&
194 (f
->flags
& FLD_ARRAY
) && fl
->low
!= fl
->high
)
195 flist_expand_arrays(fl
);
196 if (fa
->prfunc
== NULL
&& fl
->child
== NULL
)
197 flist_expand_structs(fl
, obj
);
199 if (fa
->subfld
== NULL
) {
200 dbprintf(_("field %s has no subfields\n"),
204 if (!flist_parse(fa
->subfld
, fl
->child
, obj
,
217 if (!(debug_state
& DEBUG_FLIST
))
220 dbprintf(_("fl@%p:\n"), fl
);
221 dbprintf(_("\tname=%s, fld=%p, child=%p, sibling=%p\n"),
222 fl
->name
, fl
->fld
, fl
->child
, fl
->sibling
);
223 dbprintf(_("\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n"),
224 fl
->low
, fl
->high
, fl
->flags
,
225 fl
->flags
& FL_OKLOW
? _("oklow ") : "",
226 fl
->flags
& FL_OKHIGH
? _("okhigh") : "", fl
->offset
);
227 dbprintf(_("\tfld->name=%s, fld->ftyp=%d (%s)\n"),
228 fl
->fld
->name
, fl
->fld
->ftyp
,
229 ftattrtab
[fl
->fld
->ftyp
].name
);
230 dbprintf(_("\tfld->flags=%d (%s%s%s%s%s)\n"), fl
->fld
->flags
,
231 fl
->fld
->flags
& FLD_ABASE1
? "abase1 " : "",
232 fl
->fld
->flags
& FLD_SKIPALL
? "skipall " : "",
233 fl
->fld
->flags
& FLD_ARRAY
? "array " : "",
234 fl
->fld
->flags
& FLD_OFFSET
? "offset " : "",
235 fl
->fld
->flags
& FLD_COUNT
? "count " : "");
237 flist_print(fl
->child
);
250 new = flist_make(f
->name
);
252 new->child
= flist_replicate(f
->child
);
253 new->sibling
= flist_replicate(f
->sibling
);
256 new->flags
= f
->flags
;
257 new->offset
= f
->offset
;
273 v
= flist_split(name
);
278 while (p
->tokty
!= TT_END
) {
279 if (p
->tokty
!= TT_NAME
)
281 nfl
= flist_make(p
->tok
);
288 if (p
->tokty
== TT_LB
) {
290 if (p
->tokty
!= TT_NUM
)
292 num
= (int)strtoul(p
->tok
, &x
, 0);
295 nfl
->flags
|= FL_OKLOW
;
298 if (p
->tokty
== TT_DASH
) {
300 if (p
->tokty
!= TT_NUM
)
302 num
= (int)strtoul(p
->tok
, &x
, 0);
305 nfl
->flags
|= FL_OKHIGH
;
309 if (p
->tokty
!= TT_RB
)
313 if (p
->tokty
== TT_DOT
) {
315 if (p
->tokty
== TT_END
)
322 dbprintf(_("bad syntax in field name %s\n"), name
);
335 static char *idchars
;
336 static char *initidchar
;
339 static char *numchars
;
340 static char *xnumchars
; /* extended for hex conversion */
342 static char punctchars
[] = "[-].";
343 static tokty_t puncttypes
[] = { TT_LB
, TT_DASH
, TT_RB
, TT_DOT
};
347 if (idchars
== NULL
) {
348 idchars
= xmalloc(26 + 10 + 1 + 1);
349 initidchar
= xmalloc(26 + 1);
350 numchars
= xmalloc(10 + 1);
351 xnumchars
= xmalloc(12 + 1);
352 for (i
= 'a'; i
<= 'z'; i
++) {
353 idchars
[i
- 'a'] = i
;
354 initidchar
[i
- 'a'] = i
;
357 for (i
= '0'; i
<= '9'; i
++) {
358 idchars
[26 + (i
- '0')] = i
;
359 numchars
[i
- '0'] = i
;
360 xnumchars
[i
- '0'] = i
;
362 idchars
[26 + 10] = '_';
363 idchars
[26 + 10 + 1] = '\0';
364 initidchar
[26] = '\0';
368 xnumchars
[12] = '\0';
371 v
= xmalloc(sizeof(*v
));
374 /* need to add string handling */
376 s
++; /* skip first quote */
377 if ((a
= strrchr(s
, '\"')) == NULL
) {
378 dbprintf(_("missing closing quote %s\n"), s
);
382 tailskip
= 1; /* skip remaing quote */
385 } else if (strchr(initidchar
, *s
)) {
386 l
= (int)strspn(s
, idchars
);
388 } else if (strchr(numchars
, *s
)) {
389 l
= (int)strspn(s
, xnumchars
);
391 } else if ((a
= strchr(punctchars
, *s
))) {
393 t
= puncttypes
[a
- punctchars
];
395 dbprintf(_("bad character in field %s\n"), s
);
402 v
= xrealloc(v
, (nv
+ 2) * sizeof(*v
));
410 v
[nv
].tokty
= TT_END
;
415 * Given a set of fields, scan for a field of the given type.
416 * Return an flist leading to the first found field
418 * Return NULL if no field of the given type is found.
422 const field_t
*fields
,
429 for (f
= fields
; f
->name
; f
++) {
430 fl
= flist_make(f
->name
);
434 fa
= &ftattrtab
[f
->ftyp
];
438 nfl
= flist_find_ftyp(fa
->subfld
, type
);
455 for (p
= ft
; p
->tok
; p
++)