make #includes consistent
[hiphop-php.git] / hphp / util / neo / neo_hdf.h
blobd866b0a449a0676eae827986336a30363b233890
1 /*
2 * Copyright 2001-2004 Brandon Long
3 * All Rights Reserved.
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
15 __BEGIN_DECLS
17 #include <stdio.h>
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,
38 char **contents);
40 typedef struct _attr
42 char *key;
43 char *value;
44 struct _attr *next;
45 } HDF_ATTR;
47 struct _hdf
49 int link;
50 int alloc_value;
51 char *name;
52 int name_len;
53 char *value;
54 struct _attr *attr;
55 struct _hdf *top;
56 struct _hdf *next;
57 struct _hdf *child;
59 /* the following fields are used to implement a cache */
60 struct _hdf *last_hp;
61 struct _hdf *last_hs;
63 /* the following HASH is used when we reach more than FORCE_HASH_AT
64 * elements */
65 NE_HASH *hash;
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
70 * load method */
71 void *fileload_ctx;
72 HDFFILELOAD fileload;
74 int visited;
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
96 * Output: None
97 * Returns: None
99 void hdf_destroy (HDF **hdf);
102 * Function: hdf_get_int_value - Return the integer value of a point in
103 * the data set
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
111 * doesn't exist
112 * Output: None
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
125 * exist
126 * Output: None
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
130 * hdf_get_copy
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
144 * Output: None
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
161 * Output: None
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
176 * exist
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,
182 const char *defval);
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
190 * Output: None
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
215 * Output: None
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 -
223 * Description:
224 * Input:
225 * Output:
226 * Returns:
228 HDF_ATTR* hdf_get_attr (HDF *hdf, const char *name);
231 * Function: hdf_set_attr -
232 * Description:
233 * Input:
234 * Output:
235 * Returns:
237 NEOERR* hdf_set_attr (HDF *hdf, const char *name, const char *key,
238 const char *value);
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
258 * Output: None
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
267 * Output: None
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
279 * the data set
280 * Input: hdf -> the hdf dataset node
281 * Output: None
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
288 * Description:
289 * Input:
290 * Output:
291 * Returns:
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
301 * Output: None
302 * Returns: The name of the node. If this is the top node, the name is
303 * NULL.
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
314 * Output: None
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
329 * will own.
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
333 * Output: None
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
349 * name=value.
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...
354 * maybe.
355 * Input: hdf -> the pointer to the hdf dataset
356 * fmt -> the name=value printf(3) format string
357 * Output: None
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
368 * that string
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
372 * Output: None
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
379 * dataset to another
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
386 * Output: None
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
393 * the value
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
402 * Output: None
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)
425 * Output: None
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
445 * example:
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)
454 * Return: NERR_NOMEM
456 NEOERR *hdf_sort_obj(HDF *h, int (*compareFunc)(const void *, const void *));
459 * Function: hdf_read_file - read an HDF data file
460 * Description:
461 * Input:
462 * Output:
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
469 * Description:
470 * Input:
471 * Output:
472 * Returns: NERR_IO
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
482 * Input:
483 * Output:
484 * Returns: NERR_IO
486 NEOERR* hdf_write_file_atomic (HDF *hdf, const char *path);
489 * Function: hdf_read_string - read an HDF string
490 * Description:
491 * Input:
492 * Output:
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
499 * Description:
500 * Input:
501 * Output:
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
508 * Description:
509 * Input:
510 * Output:
511 * Returns: NERR_NOMEM
513 NEOERR* hdf_write_string (HDF *hdf, char **s);
516 * Function: hdf_dump - dump an HDF dataset to stdout
517 * Description:
518 * Input:
519 * Output:
520 * Returns:
522 NEOERR* hdf_dump (HDF *hdf, const char *prefix);
525 * Function: hdf_dump_format - dump an HDF dataset to FILE *fp
526 * Description:
527 * Input:
528 * Output:
529 * Returns:
531 NEOERR* hdf_dump_format (HDF *hdf, int lvl, FILE *fp);
534 * Function: hdf_dump_str - dump an HDF dataset to NEOSTRING
535 * Description:
536 * Input:
537 * Output:
538 * Returns:
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
544 * Description:
545 * Input:
546 * Output:
547 * Returns:
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
559 * Output: None
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
569 * hdf.loadpaths.
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
591 * Output: None
592 * Return: None
596 void hdf_register_fileload(HDF *hdf, void *ctx, HDFFILELOAD fileload);
598 __END_DECLS
600 #endif /* incl_HPHP_NEO_HDF_H_ */