BRL-CAD
parse.h
Go to the documentation of this file.
1 /* P A R S E . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /** @file parse.h
22  *
23  */
24 #ifndef BU_PARSE_H
25 #define BU_PARSE_H
26 
27 #include "common.h"
28 #include <stdio.h> /* For FILE */
29 #include <stddef.h> /* for size_t */
30 
31 #include "bu/defines.h"
32 #include "bu/magic.h"
33 #include "bu/vls.h"
34 
36 
37 /*----------------------------------------------------------------------*/
38 /* parse.c */
39 /** @addtogroup parse */
40 /** @{ */
41 /*
42  * Structure parse/print
43  *
44  * Definitions and data structures needed for routines that assign
45  * values to elements of arbitrary data structures, the layout of
46  * which is described by tables of "bu_structparse" structures.
47  */
48 
49 /**
50  * The general problem of word-addressed hardware where (int *) and
51  * (char *) have different representations is handled in the parsing
52  * routines that use sp_offset, because of the limitations placed on
53  * compile-time initializers.
54  *
55  * Files using bu_offsetof or bu_offsetofarray will need to include
56  * stddef.h in order to get offsetof()
57  */
58 /* FIXME - this is a temporary cast. The bu_structparse sp_offset member
59  * should be a size_t.
60  */
61 #ifndef offsetof
62 # define offsetof(_t, _m) (size_t)(&(((_t *)0)->_m))
63 #endif
64 #define bu_offsetof(_t, _m) (size_t)offsetof(_t, _m)
65 #define bu_offsetofarray(_t, _a, _d, _i) bu_offsetof(_t, _a) + sizeof(_d) * _i
66 
67 
68 /**
69  * Convert address of global data object into byte "offset" from
70  * address 0.
71  *
72  * Strictly speaking, the C language only permits initializers of the
73  * form: address +- constant, where here the intent is to measure the
74  * byte address of the indicated variable. Matching compensation code
75  * for the CRAY is located in librt/parse.c
76  */
77 #if defined(__ia64__) || defined(__x86_64__) || defined(__sparc64__) || defined(_HPUX_SOURCE) || defined(__clang__)
78 # define bu_byteoffset(_i) ((size_t)((char *)&(_i)))
79 #else
80 /* "Conservative" way of finding # bytes as diff of 2 char ptrs */
81 # define bu_byteoffset(_i) ((size_t)(((char *)&(_i))-((char *)0)))
82 #endif
83 
84 
85 /**
86  * The "bu_structparse" struct describes one element of a structure.
87  * Collections of these are combined to describe entire structures (or at
88  * least those portions for which parse/print/import/export support is
89  * desired.
90  *
91  * Provides a convenient way of describing a C data structure, and
92  * reading and writing it in both human-readable ASCII and efficient
93  * binary forms.
94  *
95  * For example:
96  *
97  @code
98 
99  struct data_structure {
100  char a_char;
101  char str[32];
102  short a_short;
103  int a_int;
104  fastf_t a_fastf_t;
105  double a_double;
106  }
107 
108  struct data_structure default = { 'c', "the default string", 32767, 1, 1.0, 1.0 };
109 
110  struct data_structure my_values;
111 
112  struct bu_structparse data_sp[] ={
113  {"%c", 1, "a_char", bu_offsetof(data_structure, a_char), BU_STRUCTPARSE_FUNC_NULL, "a single character", (void*)&default.a_char},
114  {"%s", 32, "str", bu_offsetofarray(data_structure, str), BU_STRUCTPARSE_FUNC_NULL, "This is a full character string", (void*)default.str},
115  {"%i", 1, "a_short", bu_offsetof(data_structure, a_short), BU_STRUCTPARSE_FUNC_NULL, "A 16bit integer", (void*)&default.a_short},
116  {"%d", 1, "a_int", bu_offsetof(data_structure, a_int), BU_STRUCTPARSE_FUNC_NULL, "A full integer", (void*)&default.a_int},
117  {"%f", 1, "a_fastf_t", bu_offsetof(data_structure, a_fastf_t), BU_STRUCTPARSE_FUNC_NULL, "A variable-precision fasf_t floating point value", (void*)&default.a_fastf_t},
118  {"%g", 1, "a_double", bu_offsetof(data_structure, a_double), BU_STRUCTPARSE_FUNC_NULL, "A double-precision fasf_t floating point value", (void*)&default.a_double},
119  { "", 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL, (char *)NULL, (void *)NULL}
120  };
121 
122  @endcode
123  *
124  * To parse a string, call:
125  *
126  * bu_struct_parse(vls_string, data_sp, (char *)my_values)
127  *
128  * this will parse the vls string and assign values to the members of
129  * the structure my_values
130  *
131  * A gross hack: To set global variables (or others for that matter)
132  * you can store the actual address of the variable in the sp_offset
133  * field and pass a null pointer as the last argument to
134  * bu_struct_parse. If you don't understand why this would work, you
135  * probably shouldn't use this technique.
136  */
138  const char sp_fmt[4]; /**< "%i" or "%f", etc. */
139  size_t sp_count; /**< number of elements */
140  const char *sp_name; /**< Element's symbolic name */
141  size_t sp_offset; /**< Byte offset in struct */
142  void (*sp_hook)(const struct bu_structparse *,
143  const char *,
144  void *,
145  const char *,
146  void *); /**< Optional hooked function, or indir ptr */
147  const char *sp_desc; /**< description of element */
148  void *sp_default; /**< ptr to default value */
149 };
151 #define BU_STRUCTPARSE_NULL ((struct bu_structparse *)0)
152 
153 #define BU_STRUCTPARSE_FUNC_NULL ((void(*)(const struct bu_structparse *, const char *, void *, const char *, void *))0)
154 
155 /* There are situations (such as the usage pattern in libdm)
156  * where applications may want to associate structparse
157  * functions with variables but not set up a full structparse
158  * table. */
160  const char *sp_name;
161  void (*sp_hook)(const struct bu_structparse *,
162  const char *,
163  void *,
164  const char *,
165  void *); /**< Optional hooked function, or indir ptr */
166 };
167 
168 /**
169  * assert the integrity of a bu_structparse struct.
170  */
171 #define BU_CK_STRUCTPARSE(_sp) /* nothing to do */
172 
173 /**
174  * initialize a bu_structparse struct without allocating any memory.
175  */
176 #define BU_STRUCTPARSE_INIT(_sp) { \
177  (_sp)->sp_fmt[0] = (_sp)->sp_fmt[1] = (_sp)->sp_fmt[2] = (_sp)->sp_fmt[3] = '\0'; \
178  (_sp)->sp_count = 0; \
179  (_sp)->sp_name = NULL; \
180  (_sp)->sp_offset = 0; \
181  (_sp)->sp_hook = BU_STRUCTPARSE_FUNC_NULL; \
182  (_sp)->sp_desc = NULL; \
183  (_sp)->sp_default = NULL; \
184  }
185 
186 /**
187  * macro suitable for declaration statement initialization of a bu_structparse
188  * struct. does not allocate memory.
189  */
190 #define BU_STRUCTPARSE_INIT_ZERO { {'\0', '\0', '\0', '\0'}, 0, NULL, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
191 
192 /**
193  * returns truthfully whether a bu_structparse struct has been
194  * initialized. validates whether pointer is non-NULL.
195  */
196 #define BU_STRUCTPARSE_IS_INITIALIZED(_sp) ((struct bu_structparse *)(_sp) != BU_STRUCTPARSE_NULL)
197 
198 
199 /*----------------------------------------------------------------------*/
200 /**
201  * An "opaque" handle for holding onto objects, typically in some kind
202  * of external form that is not directly usable without passing
203  * through an "importation" function.
204  *
205  * A "bu_external" struct holds the "external binary" representation
206  * of a structure or other block of arbitrary data.
207  */
208 struct bu_external {
209  uint32_t ext_magic;
210  size_t ext_nbytes;
211 #if defined(USE_BINARY_ATTRIBUTES)
212  unsigned char widcode; /* needed for decoding binary attributes,
213  * same type as 'struct
214  * db5_raw_internal.a_width' */
215 #endif
216  uint8_t *ext_buf;
217 };
218 typedef struct bu_external bu_external_t;
219 #define BU_EXTERNAL_NULL ((struct bu_external *)0)
220 
221 /**
222  * assert the integrity of a bu_external struct.
223  */
224 #define BU_CK_EXTERNAL(_p) BU_CKMAG(_p, BU_EXTERNAL_MAGIC, "bu_external")
225 
226 /**
227  * initializes a bu_external struct without allocating any memory.
228  */
229 #define BU_EXTERNAL_INIT(_p) { \
230  (_p)->ext_magic = BU_EXTERNAL_MAGIC; \
231  (_p)->ext_nbytes = 0; \
232  (_p)->ext_buf = NULL; \
233  }
234 
235 /**
236  * macro suitable for declaration statement initialization of a
237  * bu_external struct. does not allocate memory.
238  */
239 #define BU_EXTERNAL_INIT_ZERO { BU_EXTERNAL_MAGIC, 0, NULL }
240 
241 /**
242  * returns truthfully whether a bu_external struct has been
243  * initialized. is not reliable unless the struct has been
244  * initialized with BU_EXTERNAL_INIT().
245  */
246 #define BU_EXTERNAL_IS_INITIALIZED(_p) (((struct bu_external *)(_p) != BU_EXTERNAL_NULL) && (_p)->ext_magic == BU_EXTERNAL_MAGIC)
247 
248 /** @file libbu/parse.c
249  *
250  * routines for parsing arbitrary structures
251  *
252  * Routines to assign values to elements of arbitrary structures. The
253  * layout of a structure to be processed is described by a structure
254  * of type "bu_structparse", giving element names, element formats, an
255  * offset from the beginning of the structure, and a pointer to an
256  * optional "hooked" function that is called whenever that structure
257  * element is changed.
258  */
259 
260 /**
261  * ASCII to struct elements.
262  *
263  * Parse the structure element description in the vls string "vls"
264  * according to the structure description in "parsetab"
265  *
266  * @return <0 failure
267  * @return 0 OK
268  */
269 BU_EXPORT extern int bu_struct_parse(const struct bu_vls *in_vls,
270  const struct bu_structparse *desc,
271  const char *base,
272  void *data);
273 
274 /**
275  * struct elements to ASCII.
276  */
277 BU_EXPORT extern void bu_struct_print(const char *title,
278  const struct bu_structparse *parsetab,
279  const char *base);
280 
281 /**
282  * struct elements to machine-independent binary.
283  *
284  * copies ext data to base
285  */
286 BU_EXPORT extern int bu_struct_export(struct bu_external *ext,
287  const void *base,
288  const struct bu_structparse *imp);
289 
290 /**
291  * machine-independent binary to struct elements.
292  *
293  * copies ext data to base
294  */
295 BU_EXPORT extern int bu_struct_import(void *base,
296  const struct bu_structparse *imp,
297  const struct bu_external *ext,
298  void *data);
299 
300 /**
301  * Put a structure in external form to a stdio file. All formatting
302  * must have been accomplished previously.
303  *
304  * Returns number of bytes written. On error, a short byte count (or
305  * zero) is returned. Use feof(3) or ferror(3) to determine which
306  * errors occur.
307  */
308 BU_EXPORT extern size_t bu_struct_put(FILE *fp,
309  const struct bu_external *ext);
310 
311 /**
312  * Obtain the next structure in external form from a stdio file.
313  *
314  * Returns number of bytes read into the bu_external. On error, zero
315  * is returned.
316  */
317 BU_EXPORT extern size_t bu_struct_get(struct bu_external *ext,
318  FILE *fp);
319 
320 /**
321  * Given a buffer with an external representation of a structure
322  * (e.g. the ext_buf portion of the output from bu_struct_export),
323  * check it for damage in shipment, and if it's OK, wrap it up in an
324  * bu_external structure, suitable for passing to bu_struct_import().
325  */
326 BU_EXPORT extern void bu_struct_wrap_buf(struct bu_external *ext,
327  void *buf);
328 
329 /**
330  * This differs from bu_struct_print in that this output is less
331  * readable by humans, but easier to parse with the computer.
332  */
333 BU_EXPORT extern void bu_vls_struct_print(struct bu_vls *vls,
334  const struct bu_structparse *sdp,
335  const char *base);
336 
337 /**
338  * This differs from bu_struct_print in that it prints to a vls.
339  */
340 BU_EXPORT extern void bu_vls_struct_print2(struct bu_vls *vls,
341  const char *title,
342  const struct bu_structparse *sdp,
343  const char *base);
344 
345 /**
346  * Convert a structure element (indicated by sdp) to its ASCII
347  * representation in a VLS.
348  */
349 BU_EXPORT extern void bu_vls_struct_item(struct bu_vls *vp,
350  const struct bu_structparse *sdp,
351  const char *base,
352  int sep_char);
353 
354 /**
355  * Convert a structure element called "name" to an ASCII
356  * representation in a VLS.
357  */
358 BU_EXPORT extern int bu_vls_struct_item_named(struct bu_vls *vp,
359  const struct bu_structparse *sdp,
360  const char *name,
361  const char *base,
362  int sep_char);
363 
364 /**
365  * This allows us to specify the "size" parameter as values like ".5m"
366  * or "27in" rather than using mm all the time.
367  */
368 BU_EXPORT extern void bu_parse_mm(const struct bu_structparse *sdp,
369  const char *name,
370  char *base,
371  const char *value);
372 
373 BU_EXPORT extern int bu_key_eq_to_key_val(const char *in,
374  const char **next,
375  struct bu_vls *vls);
376 
377 /**
378  * Take an old v4 shader specification of the form
379  *
380  * shadername arg1=value1 arg2=value2 color=1/2/3
381  *
382  * and convert it into the v5 {} list form
383  *
384  * shadername {arg1 value1 arg2 value2 color 1/2/3}
385  *
386  * Note -- the input string is smashed with nulls.
387  *
388  * Note -- the v5 version is used everywhere internally, and in v5
389  * databases.
390  *
391  * @return 1 error
392  * @return 0 OK
393  */
394 BU_EXPORT extern int bu_shader_to_list(const char *in, struct bu_vls *vls);
395 
396 BU_EXPORT extern int bu_shader_to_key_eq(const char *in, struct bu_vls *vls);
397 
398 /**
399  * Take a block of memory, and write it into a file.
400  *
401  * Caller is responsible for freeing memory of external representation,
402  * using bu_free_external().
403  *
404  * @return <0 error
405  * @return 0 OK
406  */
407 BU_EXPORT extern int bu_fwrite_external(FILE *fp,
408  const struct bu_external *ep);
409 
410 BU_EXPORT extern void bu_hexdump_external(FILE *fp, const struct bu_external *ep,
411  const char *str);
412 
413 BU_EXPORT extern void bu_free_external(struct bu_external *ep);
414 
415 BU_EXPORT extern void bu_copy_external(struct bu_external *op,
416  const struct bu_external *ip);
417 
418 /**
419  * Advance pointer through string over current token,
420  * across white space, to beginning of next token.
421  */
422 BU_EXPORT extern char *bu_next_token(char *str);
423 
424 BU_EXPORT extern void bu_structparse_get_terse_form(struct bu_vls *logstr,
425  const struct bu_structparse *sp);
426 
427 /**
428  * Support routine for db adjust and db put. Much like the
429  * bu_struct_parse routine which takes its input as a bu_vls. This
430  * routine, however, takes the arguments as lists, a more Tcl-friendly
431  * method. There is a log vls for storing messages.
432  *
433  * Operates on argv[0] and argv[1], then on argv[2] and argv[3], ...
434  *
435  * @param str - vls for dumping info that might have gone to bu_log
436  * @param argc - number of elements in argv
437  * @param argv - contains the keyword-value pairs
438  * @param desc - structure description
439  * @param base - base addr of users struct
440  * @param data - user data to be passed to the sp_hook function
441  *
442  * @retval BRLCAD_OK if successful,
443  * @retval BRLCAD_ERROR on failure
444  */
445 BU_EXPORT extern int bu_structparse_argv(struct bu_vls *str,
446  int argc,
447  const char **argv,
448  const struct bu_structparse *desc,
449  char *base,
450  void *data);
451 
452 /**
453  * Skip the separator(s) (i.e. whitespace and open-braces)
454  *
455  * @param _cp - character pointer
456  */
457 #define BU_SP_SKIP_SEP(_cp) { \
458  while (*(_cp) && (*(_cp) == ' ' || *(_cp) == '\n' || \
459  *(_cp) == '\t' || *(_cp) == '{')) ++(_cp); \
460  }
461 
462 
463 /** @file libbu/booleanize.c
464  *
465  * routines for parsing boolean values from strings
466  */
467 
468 /**
469  * Returns truthfully if a given input string represents an
470  * "affirmative string".
471  *
472  * Input values that are null, empty, begin with the letter 'n', or
473  * are 0-valued return as false. Any other input value returns as
474  * true. Strings that strongly indicate true return as 1, other
475  * values still return as true but may be a value greater than 1.
476  */
477 BU_EXPORT extern int bu_str_true(const char *str);
478 
479 /**
480  * Returns truthfully if a given input string represents a
481  * "negative string".
482  *
483  * Input values that are null, empty, begin with the letter 'n', or
484  * are 0-valued return as true. Any other input value returns as
485  * false.
486  */
487 BU_EXPORT extern int bu_str_false(const char *str);
488 
489 
490 /** @} */
491 
493 
494 #endif /* BU_PARSE_H */
495 
496 /*
497  * Local Variables:
498  * mode: C
499  * tab-width: 8
500  * indent-tabs-mode: t
501  * c-file-style: "stroustrup"
502  * End:
503  * ex: shiftwidth=4 tabstop=8
504  */
int bu_struct_import(void *base, const struct bu_structparse *imp, const struct bu_external *ext, void *data)
Definition: parse.c:295
void bu_vls_struct_print2(struct bu_vls *vls, const char *title, const struct bu_structparse *sdp, const char *base)
Definition: parse.c:1606
const char * sp_desc
Definition: parse.h:147
const char * sp_name
Definition: parse.h:140
int bu_shader_to_list(const char *in, struct bu_vls *vls)
Definition: parse.c:1933
Definition: clone.c:90
void bu_parse_mm(const struct bu_structparse *sdp, const char *name, char *base, const char *value)
Definition: parse.c:1794
int bu_fwrite_external(FILE *fp, const struct bu_external *ep)
Definition: parse.c:2368
void bu_free_external(struct bu_external *ep)
Header file for the BRL-CAD common definitions.
void bu_hexdump_external(FILE *fp, const struct bu_external *ep, const char *str)
Definition: parse.c:2390
void bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
Definition: parse.c:1221
void(* sp_hook)(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: parse.h:142
int bu_key_eq_to_key_val(const char *in, const char **next, struct bu_vls *vls)
Definition: parse.c:1821
const char sp_fmt[4]
Definition: parse.h:138
COMPLEX data[64]
Definition: fftest.c:34
int bu_vls_struct_item_named(struct bu_vls *vp, const struct bu_structparse *sdp, const char *name, const char *base, int sep_char)
Definition: parse.c:1203
#define __BEGIN_DECLS
Definition: common.h:73
int bu_struct_export(struct bu_external *ext, const void *base, const struct bu_structparse *imp)
Definition: parse.c:120
uint8_t * ext_buf
Definition: parse.h:216
const char * sp_name
Definition: parse.h:160
char * bu_next_token(char *str)
Definition: parse.c:2469
size_t sp_offset
Definition: parse.h:141
void bu_vls_struct_print(struct bu_vls *vls, const struct bu_structparse *sdp, const char *base)
int bu_structparse_argv(struct bu_vls *str, int argc, const char **argv, const struct bu_structparse *desc, char *base, void *data)
Definition: parse.c:2522
uint32_t ext_magic
Definition: parse.h:209
void(* sp_hook)(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: parse.h:161
void bu_vls_struct_item(struct bu_vls *vp, const struct bu_structparse *sdp, const char *base, int sep_char)
Definition: parse.c:1097
size_t sp_count
Definition: parse.h:139
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
void bu_structparse_get_terse_form(struct bu_vls *logstr, const struct bu_structparse *sp)
Definition: parse.c:2483
void bu_struct_wrap_buf(struct bu_external *ext, void *buf)
Definition: parse.c:542
int bu_shader_to_key_eq(const char *in, struct bu_vls *vls)
Definition: parse.c:2279
#define __END_DECLS
Definition: common.h:74
int bu_str_false(const char *str)
Definition: booleanize.c:113
size_t bu_struct_put(FILE *fp, const struct bu_external *ext)
Definition: parse.c:457
int bu_str_true(const char *str)
Definition: booleanize.c:32
void * sp_default
Definition: parse.h:148
size_t ext_nbytes
Definition: parse.h:210
Definition: vls.h:56
void bu_copy_external(struct bu_external *op, const struct bu_external *ip)
Definition: parse.c:2454
size_t bu_struct_get(struct bu_external *ext, FILE *fp)
Definition: parse.c:469