2 * Copyright 2001-2004 Brandon Long
5 * ClearSilver Templating System
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
12 #ifndef incl_HPHP_NEO_HDF_H_
13 #define incl_HPHP_NEO_HDF_H_ 1
18 #include "hphp/util/neo/neo_err.h"
19 #include "hphp/util/neo/neo_hash.h"
21 #define FORCE_HASH_AT 10
23 typedef struct _hdf HDF
;
25 /* HDFFILELOAD is a callback function to intercept file load requests and
26 * provide templates via another mechanism. This way you can load templates
27 * that you compiled-into your binary, from in-memory caches, or from a
28 * zip file, etc. The HDF is provided so you can choose to use the
29 * hdf_search_path function to find the file. contents should return
30 * a full malloc copy of the contents of the file, which the parser will
31 * own and free. Use hdf_register_fileload to set this function for
32 * your top level HDF node.
33 * NOTE: Technically, we shouldn't need a separate copy for each parse, but
34 * using the separate copy makes this equivalent to the CSFILELOAD function. We
35 * can change this if we really want to save that copy at the expense of
36 * slightly more complicated code. */
37 typedef NEOERR
* (*HDFFILELOAD
)(void *ctx
, HDF
*hdf
, const char *filename
,
59 /* the following fields are used to implement a cache */
63 /* the following HASH is used when we reach more than FORCE_HASH_AT
66 /* When using the HASH, we need to know where to append new children */
67 struct _hdf
*last_child
;
69 /* Should only be set on the head node, used to override the default file
78 * Function: hdf_init - Initialize an HDF data set
79 * Description: hdf_init initializes an HDF data set and returns the
80 * pointer to the top node in the data set.
81 * Input: hdf - pointer to an HDF pointer
82 * Output: hdf - allocated hdf node
83 * Returns: NERR_NOMEM - unable to allocate memory for dataset
85 NEOERR
* hdf_init (HDF
**hdf
);
88 * Function: hdf_destroy - deallocate an HDF data set
89 * Description: hdf_destroy is used to deallocate all memory associated
90 * with an hdf data set. Although you can pass an HDF node
91 * as an argument to this function, you are likely to cause
92 * a segfault if you continue to access the data set. In
93 * the future, we may restrict hdf_destroy so it only works
94 * on the top level node.
95 * Input: hdf - pointer to an HDF data set allocated with hdf_init
99 void hdf_destroy (HDF
**hdf
);
102 * Function: hdf_get_int_value - Return the integer value of a point in
104 * Description: hdf_get_int_value walks the HDF data set pointed to by
105 * hdf to name, and returns the value of that node
106 * converted to an integer. If that node does not exist,
107 * or it does not contain a number, the defval is returned.
108 * Input: hdf -> a node in an HDF data set
109 * name -> the name of a node to walk to in the data set
110 * defval -> value to return in case of error or if the node
113 * Returns: The integer value of the node, or the defval
115 int hdf_get_int_value (HDF
*hdf
, const char *name
, int defval
);
118 * Function: hdf_get_value - Return the value of a node in the data set
119 * Description: hdf_get_value walks the data set pointed to by hdf via
120 * name and returns the string value located there, or
121 * defval if the node doesn't exist
122 * Input: hdf -> the dataset node to start from
123 * name -> the name to walk the data set to
124 * defval -> the default value to return if the node doesn't
127 * Returns: A pointer to the string stored in the data set, or defval.
128 * The data set maintains ownership of the string, if you want
129 * a copy you either have to call strdup yourself, or use
132 char *hdf_get_value (HDF
*hdf
, const char *name
, const char *defval
);
135 * Function: hdf_get_valuevf - Return the value of a node in the data set
136 * Description: hdf_get_valuevf walks the data set pointed to by hdf via
137 * namefmt printf expanded with varargs ap, and returns the
138 * string value located there, or NULL if it doesn't exist.
139 * This differs from hdf_get_value in that there is no
140 * default value possible.
141 * Input: hdf -> the dataset node to start from
142 * namefmt -> the format string
143 * ap -> va_list of varargs
145 * Returns: A pointer to the string stored in the data set, or NULL.
146 * The data set maintains ownership of the string, if you want
147 * a copy you either have to call strdup yourself.
149 char* hdf_get_valuevf (HDF
*hdf
, const char *namefmt
, va_list ap
);
152 * Function: hdf_get_valuef - Return the value of a node in the data set
153 * Description: hdf_get_valuef walks the data set pointed to by hdf via
154 * namefmt printf expanded with varargs, and returns the
155 * string value located there, or NULL if it doesn't exist.
156 * This differs from hdf_get_value in that there is no
157 * default value possible.
158 * Input: hdf -> the dataset node to start from
159 * namefmt -> the printf-style format string
160 * ... -> arguments to fill out namefmt
162 * Returns: A pointer to the string stored in the data set, or NULL.
163 * The data set maintains ownership of the string, if you want
164 * a copy you either have to call strdup yourself.
166 char* hdf_get_valuef (HDF
*hdf
, const char *namefmt
, ...)
167 ATTRIBUTE_PRINTF(2,3);
170 * Function: hdf_get_copy - Returns a copy of a string in the HDF data set
171 * Description: hdf_get_copy is similar to hdf_get_value, except that it
172 * returns an malloc'd copy of the string.
173 * Input: hdf -> the dataset node to start from
174 * name -> the name to walk the data set to
175 * defval -> the default value to return if the node doesn't
177 * Output: value -> the allocated string (if defval = NULL, then value
178 * will be NULL if defval is used)
179 * Returns: NERR_NOMEM if unable to allocate the new copy
181 NEOERR
* hdf_get_copy (HDF
*hdf
, const char *name
, char **value
,
185 * Function: hdf_get_obj - return the HDF data set node at a named location
186 * Description: hdf_get_obj walks the dataset given by hdf to the node
187 * named name, and then returns the pointer to that node
188 * Input: hdf -> the dataset node to start from
189 * name -> the name to walk to
191 * Returns: the pointer to the named node, or NULL if it doesn't exist
193 HDF
* hdf_get_obj (HDF
*hdf
, const char *name
);
196 * Function: hdf_get_node - Similar to hdf_get_obj except all the nodes
197 * are created if the don't exist.
198 * Description: hdf_get_node is similar to hdf_get_obj, except instead
199 * of stopping if it can't find a node in the tree, it will
200 * create all of the nodes necessary to hand you back the
201 * node you ask for. Nodes are created with no value.
202 * Input: hdf -> the dataset node to start from
203 * name -> the name to walk to
204 * Output: ret -> the dataset node you asked for
205 * Returns: NERR_NOMEM - unable to allocate new nodes
207 NEOERR
* hdf_get_node (HDF
*hdf
, const char *name
, HDF
**ret
);
210 * Function: hdf_get_child - return the first child of the named node
211 * Description: hdf_get_child will walk the dataset starting at hdf to
212 * name, and return the first child of that node
213 * Input: hdf -> the dataset node to start from
214 * name -> the name to walk to
216 * Returns: The first child of the named dataset node or NULL if the
217 * node is not found (or it has no children)
219 HDF
* hdf_get_child (HDF
*hdf
, const char *name
);
222 * Function: hdf_get_attr -
228 HDF_ATTR
* hdf_get_attr (HDF
*hdf
, const char *name
);
231 * Function: hdf_set_attr -
237 NEOERR
* hdf_set_attr (HDF
*hdf
, const char *name
, const char *key
,
241 * Function: hdf_set_visited - Mark a node visited or not
243 void hdf_set_visited (HDF
*hdf
, int visited
);
246 * Function: hdf_is_visited - Return a node visited or not
248 int hdf_is_visited (HDF
*hdf
);
251 * Function: hdf_obj_child - Return the first child of a dataset node
252 * Description: hdf_obj_child and the other hdf_obj_ functions are
253 * accessors to the HDF dataset. Although we do not
254 * currently "hide" the HDF struct implementation, we
255 * recommend you use the accessor functions instead of
256 * accessing the values directly.
257 * Input: hdf -> the hdf dataset node
259 * Returns: The pointer to the first child, or NULL if there is none
261 HDF
* hdf_obj_child (HDF
*hdf
);
264 * Function: hdf_obj_next - Return the next node of a dataset level
265 * Description: hdf_obj_next is an accessor function for the HDF struct
266 * Input: hdf -> the hdf dataset node
268 * Returns: The pointer to the next node, or NULL if there is none
270 HDF
* hdf_obj_next (HDF
*hdf
);
273 * Function: hdf_obj_top - Return the pointer to the top dataset node
274 * Description: hdf_obj_top is an accessor function which returns a
275 * pointer to the top of the dataset, the node which was
276 * returned by hdf_init. This is most useful for
277 * implementations of language wrappers where individual
278 * nodes are tied garbage colletion wise to the top node of
280 * Input: hdf -> the hdf dataset node
282 * Returns: The pointer to the top node
284 HDF
* hdf_obj_top (HDF
*hdf
);
287 * Function: hdf_obj_attr - Return the HDF Attributes for a node
293 HDF_ATTR
* hdf_obj_attr (HDF
*hdf
);
296 * Function: hdf_obj_name - Return the name of a node
297 * Description: hdf_obj_name is an accessor function for a datset node
298 * which returns the name of the node. This is just the
299 * local name, and not the full path.
300 * Input: hdf -> the hdf dataset node
302 * Returns: The name of the node. If this is the top node, the name is
305 char* hdf_obj_name (HDF
*hdf
);
308 * Function: hdf_obj_value - Return the value of a node
309 * Description: hdf_obj_value is an accessor function for a dataset node
310 * which returns the value of the node, or NULL if the node
311 * has no value. This is not a copy of the value, so the
312 * node retains ownership of the value
313 * Input: hdf -> the hdf dataset node
315 * Returns: The value of the node, or NULL if it has no value
317 char* hdf_obj_value (HDF
*hdf
);
320 * Function: hdf_set_value - Set the value of a named node
321 * Description: hdf_set_value will set the value of a named node. All
322 * of the interstitial nodes which don't exist will be
323 * created with a value of NULL. Existing nodes are not
324 * modified. New nodes are created at the end of the list.
325 * If a list of nodes exceeds FORCE_HASH_AT, then a HASH
326 * will be created at that level and all of the nodes will
327 * be added to the hash for faster lookup times.
328 * The copy of the value will be made which the dataset
330 * Input: hdf -> the pointer to the hdf dataset
331 * name -> the named node to walk to
332 * value -> the value to set the node to
334 * Returns: NERR_NOMEM
336 NEOERR
* hdf_set_value (HDF
*hdf
, const char *name
, const char *value
);
339 * Function: hdf_set_valuef - Set the value of a named node
340 * Description: hdf_set_valuef is a convenience function that wraps
341 * hdf_set_value. Due to limitations of C, the fmt is in
342 * the format "name=value", where we will first format the
343 * entire string, and then break it at the first (from the
344 * left) equal sign (=) and use the left portion as the
345 * name and the right portion as the value. This function
346 * is somewhat inefficient in that it first allocates the
347 * full name=value, and then the call to hdf_set_value
348 * duplicates the value portion, and then we free the
350 * Currently, we don't strip whitespace from the key or
351 * value. In the future, this function might work more
352 * like reading a single line of an HDF string or file,
353 * allowing for attributes and symlinks to be specified...
355 * Input: hdf -> the pointer to the hdf dataset
356 * fmt -> the name=value printf(3) format string
358 * Returns: NERR_NOMEM
360 NEOERR
* hdf_set_valuef (HDF
*hdf
, const char *fmt
, ...)
361 ATTRIBUTE_PRINTF(2,3);
362 NEOERR
* hdf_set_valuevf (HDF
*hdf
, const char *fmt
, va_list ap
);
365 * Function: hdf_set_int_value - Set the value of a named node to a number
366 * Description: hdf_set_int_value is a helper function that maps an
367 * integer to a string, and then calls hdf_set_value with
369 * Input: hdf -> the pointer to the hdf dataset
370 * name -> the named node to walk to
371 * value -> the value to set the node to
373 * Returns: NERR_NOMEM
375 NEOERR
* hdf_set_int_value (HDF
*hdf
, const char *name
, int value
);
378 * Function: hdf_set_copy - Copy a value from one location in the
380 * Description: hdf_set_copy first walks the hdf dataset to the named src
381 * node, and then copies that value to the named dest node.
382 * If the src node is not found, an error is raised.
383 * Input: hdf -> the pointer to the dataset node
384 * dest -> the name of the destination node
385 * src -> the name of the source node
387 * Returns: NERR_NOMEM, NERR_NOT_FOUND
389 NEOERR
* hdf_set_copy (HDF
*hdf
, const char *dest
, const char *src
);
392 * Function: hdf_set_buf - Set the value of a node without duplicating
394 * Description: hdf_set_buf is similar to hdf_set_value, except the
395 * dataset takes ownership of the value instead of making a
396 * copy of it. The dataset assumes that value was
397 * malloc'd, since it will attempt to free it when
398 * hdf_destroy is called
399 * Input: hdf -> the hdf dataset node
400 * name -> the name to walk to
401 * value -> the malloc'd value
403 * Returns: NERR_NOMEM - unable to allocate a node
406 NEOERR
* hdf_set_buf (HDF
*hdf
, const char *name
, char *value
);
409 * Function: hdf_set_symlink - Set part of the tree to link to another
410 * Description: hdf_set_symlink creates a link between two sections of
411 * an HDF dataset. The link is "by name" hence the term
412 * "symlink". This means that the destination node does
413 * not need to exist. Any attempt to access the source
414 * node will cause the function to walk to the dest node,
415 * and then continue walking from there. Using symlinks
416 * can "hide" values in the dataset since you won't be able
417 * to access any children of the linked node directly,
418 * though dumps and other things which access the data
419 * structure directly will bypass the symlink. Use this
420 * feature sparingly as its likely to surprise you.
421 * Input: hdf -> the dataset node
422 * src -> the source node name
423 * dest -> the destination node name (from the top of the
424 * dataset, not relative names)
426 * Returns: NERR_NOMEM
428 NEOERR
*hdf_set_symlink (HDF
*hdf
, const char *src
, const char *dest
);
431 * Function: hdf_sort_obj - sort the children of an HDF node
432 * Description: hdf_sort_obj will sort the children of an HDF node,
433 * based on the given comparison function.
434 * This function works by creating an array of the pointers
435 * for each child object of h, using qsort to sort that
436 * array, and then re-ordering the linked list of children
437 * to the new order. The qsort compare function uses a
438 * pointer to the value in the array, which in our case is
439 * a pointer to an HDF struct, so your comparison function
440 * should work on HDF ** pointers.
441 * Input: h - HDF node
442 * compareFunc - function which returns 1,0,-1 depending on some
443 * criteria. The arguments to this sort function
444 * are pointers to pointers to HDF elements. For
446 * int sortByName(const void *a, const void *b) {
447 * HDF **ha = (HDF **)a;
448 * HDF **hb = (HDF **)b;
450 * return strcasecmp(hdf_obj_name(*ha), hdf_obj_name(*hb));
453 * Output: None (h children will be sorted)
456 NEOERR
*hdf_sort_obj(HDF
*h
, int (*compareFunc
)(const void *, const void *));
459 * Function: hdf_read_file - read an HDF data file
463 * Returns: NERR_IO, NERR_NOMEM, NERR_PARSE
465 NEOERR
* hdf_read_file (HDF
*hdf
, const char *path
);
468 * Function: hdf_write_file - write an HDF data file
474 NEOERR
* hdf_write_file (HDF
*hdf
, const char *path
);
477 * Function: hdf_write_file_atomic - write an HDF data file atomically
478 * Description: hdf_write_file_atomic is similar to hdf_write_file,
479 * except the new file is created with a unique name and
480 * then rename(2) is used to atomically replace the old
481 * file with the new file
486 NEOERR
* hdf_write_file_atomic (HDF
*hdf
, const char *path
);
489 * Function: hdf_read_string - read an HDF string
493 * Returns: NERR_NOMEM, NERR_PARSE
495 NEOERR
* hdf_read_string (HDF
*hdf
, const char *s
);
498 * Function: hdf_read_string_ignore - Read an HDF string and ignore errors
502 * Returns: NERR_NOMEM
504 NEOERR
* hdf_read_string_ignore (HDF
*hdf
, const char *s
, int ignore
);
507 * Function: hdf_write_string - serialize an HDF dataset to a string
511 * Returns: NERR_NOMEM
513 NEOERR
* hdf_write_string (HDF
*hdf
, char **s
);
516 * Function: hdf_dump - dump an HDF dataset to stdout
522 NEOERR
* hdf_dump (HDF
*hdf
, const char *prefix
);
525 * Function: hdf_dump_format - dump an HDF dataset to FILE *fp
531 NEOERR
* hdf_dump_format (HDF
*hdf
, int lvl
, FILE *fp
);
534 * Function: hdf_dump_str - dump an HDF dataset to NEOSTRING
540 NEOERR
* hdf_dump_str(HDF
*hdf
, const char *prefix
, int compact
, NEOSTRING
*str
);
543 * Function: hdf_remove_tree - delete a subtree of an HDF dataset
549 NEOERR
* hdf_remove_tree (HDF
*hdf
, const char *name
);
552 * Function: hdf_copy - copy part of an HDF dataset to another
553 * Description: hdf_copy is a deep copy of an HDF tree pointed to by
554 * src to the named node of dest. dest and src need not be
555 * part of the same data set
556 * Input: dest_hdf -> the destination dataset
557 * name -> the name of the destination node
558 * src -> the hdf dataset to copy to the destination
560 * Returns: NERR_NOMEM, NERR_NOT_FOUND
562 NEOERR
* hdf_copy (HDF
*dest_hdf
, const char *name
, HDF
*src
);
565 * Function: hdf_search_path - Find a file given a search path in HDF
566 * Description: hdf_search_path is a convenience/utility function that
567 * searches for relative filenames in a search path. The
568 * search path is the list given by the children of
570 * Input: hdf -> the hdf dataset to use
571 * path -> the relative path
572 * full -> a pointer to a buffer
573 * full_len -> size of full buffer
574 * Output: full -> the full path of the file
575 * Returns: NERR_NOT_FOUND if the file wasn't found in the search path
577 NEOERR
* hdf_search_path (HDF
*hdf
, const char *path
, char *full
, int full_len
);
580 * Function: hdf_register_fileload - register a fileload function
581 * Description: hdf_register_fileload registers a fileload function that
582 * overrides the built-in function. The built-in function
583 * uses hdf_search_path and ne_file_load (based on stat/open/read)
584 * to find and load the file on every hdf_read_file (including
585 * #include). You can override this function if you wish to provide
586 * other file search functions, or load the hdf file
587 * from an in-memory cache, etc.
588 * Input: hdf - pointer to a head HDF node
589 * ctx - pointer that is passed to the HDFFILELOAD function when called
590 * fileload - a HDFFILELOAD function
596 void hdf_register_fileload(HDF
*hdf
, void *ctx
, HDFFILELOAD fileload
);
600 #endif /* incl_HPHP_NEO_HDF_H_ */