Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright 2001-2004 Brandon Long
      3  * All Rights Reserved.
      4  *
      5  * ClearSilver Templating System
      6  *
      7  * This code is made available under the terms of the ClearSilver License.
      8  * http://www.clearsilver.net/license.hdf
      9  *
     10  */
     11 
     12 #ifndef __NEO_HDF_H_
     13 #define __NEO_HDF_H_ 1
     14 
     15 __BEGIN_DECLS
     16 
     17 #include <stdio.h>
     18 #include "util/neo_err.h"
     19 #include "util/neo_hash.h"
     20 
     21 #define FORCE_HASH_AT 10
     22 
     23 typedef struct _hdf HDF;
     24 
     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);
     39 
     40 typedef struct _attr
     41 {
     42   char *key;
     43   char *value;
     44   struct _attr *next;
     45 } HDF_ATTR;
     46 
     47 struct _hdf
     48 {
     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;
     58 
     59   /* the following fields are used to implement a cache */
     60   struct _hdf *last_hp;
     61   struct _hdf *last_hs;
     62 
     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;
     68 
     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;
     73 };
     74 
     75 /*
     76  * Function: hdf_init - Initialize an HDF data set
     77  * Description: hdf_init initializes an HDF data set and returns the
     78  *              pointer to the top node in the data set.
     79  * Input: hdf - pointer to an HDF pointer
     80  * Output: hdf - allocated hdf node
     81  * Returns: NERR_NOMEM - unable to allocate memory for dataset
     82  */
     83 NEOERR* hdf_init (HDF **hdf);
     84 
     85 /*
     86  * Function: hdf_destroy - deallocate an HDF data set
     87  * Description: hdf_destroy is used to deallocate all memory associated
     88  *              with an hdf data set.  Although you can pass an HDF node
     89  *              as an argument to this function, you are likely to cause
     90  *              a segfault if you continue to access the data set.  In
     91  *              the future, we may restrict hdf_destroy so it only works
     92  *              on the top level node.
     93  * Input: hdf - pointer to an HDF data set allocated with hdf_init
     94  * Output: None
     95  * Returns: None
     96  */
     97 void hdf_destroy (HDF **hdf);
     98 
     99 /*
    100  * Function: hdf_get_int_value - Return the integer value of a point in
    101  *           the data set
    102  * Description: hdf_get_int_value walks the HDF data set pointed to by
    103  *              hdf to name, and returns the value of that node
    104  *              converted to an integer.  If that node does not exist,
    105  *              or it does not contain a number, the defval is returned.
    106  * Input: hdf -> a node in an HDF data set
    107  *        name -> the name of a node to walk to in the data set
    108  *        defval -> value to return in case of error or if the node
    109  *                  doesn't exist
    110  * Output: None
    111  * Returns: The integer value of the node, or the defval
    112  */
    113 int hdf_get_int_value (HDF *hdf, const char *name, int defval);
    114 
    115 /*
    116  * Function: hdf_get_value - Return the value of a node in the data set
    117  * Description: hdf_get_value walks the data set pointed to by hdf via
    118  *              name and returns the string value located there, or
    119  *              defval if the node doesn't exist
    120  * Input: hdf -> the dataset node to start from
    121  *        name -> the name to walk the data set to
    122  *        defval -> the default value to return if the node doesn't
    123  *                  exist
    124  * Output: None
    125  * Returns: A pointer to the string stored in the data set, or defval.
    126  *          The data set maintains ownership of the string, if you want
    127  *          a copy you either have to call strdup yourself, or use
    128  *          hdf_get_copy
    129  */
    130 char *hdf_get_value (HDF *hdf, const char *name, const char *defval);
    131 
    132 /*
    133  * Function: hdf_get_valuevf - Return the value of a node in the data set
    134  * Description: hdf_get_valuevf walks the data set pointed to by hdf via
    135  *              namefmt printf expanded with varargs ap, and returns the
    136  *              string value located there, or NULL if it doesn't exist.
    137  *              This differs from hdf_get_value in that there is no
    138  *              default value possible.
    139  * Input: hdf -> the dataset node to start from
    140  *        namefmt -> the format string
    141  *        ap -> va_list of varargs
    142  * Output: None
    143  * Returns: A pointer to the string stored in the data set, or NULL.
    144  *          The data set maintains ownership of the string, if you want
    145  *          a copy you either have to call strdup yourself.
    146  */
    147 char* hdf_get_valuevf (HDF *hdf, const char *namefmt, va_list ap);
    148 
    149 /*
    150  * Function: hdf_get_valuef - Return the value of a node in the data set
    151  * Description: hdf_get_valuef walks the data set pointed to by hdf via
    152  *              namefmt printf expanded with varargs, and returns the
    153  *              string value located there, or NULL if it doesn't exist.
    154  *              This differs from hdf_get_value in that there is no
    155  *              default value possible.
    156  * Input: hdf -> the dataset node to start from
    157  *        namefmt -> the printf-style format string
    158  *        ... -> arguments to fill out namefmt
    159  * Output: None
    160  * Returns: A pointer to the string stored in the data set, or NULL.
    161  *          The data set maintains ownership of the string, if you want
    162  *          a copy you either have to call strdup yourself.
    163  */
    164 char* hdf_get_valuef (HDF *hdf, const char *namefmt, ...)
    165                       ATTRIBUTE_PRINTF(2,3);
    166 
    167 /*
    168  * Function: hdf_get_copy - Returns a copy of a string in the HDF data set
    169  * Description: hdf_get_copy is similar to hdf_get_value, except that it
    170  *              returns an malloc'd copy of the string.
    171  * Input: hdf -> the dataset node to start from
    172  *        name -> the name to walk the data set to
    173  *        defval -> the default value to return if the node doesn't
    174  *                  exist
    175  * Output: value -> the allocated string (if defval = NULL, then value
    176  *                  will be NULL if defval is used)
    177  * Returns: NERR_NOMEM if unable to allocate the new copy
    178  */
    179 NEOERR* hdf_get_copy (HDF *hdf, const char *name, char **value,
    180                       const char *defval);
    181 
    182 /*
    183  * Function: hdf_get_obj - return the HDF data set node at a named location
    184  * Description: hdf_get_obj walks the dataset given by hdf to the node
    185  *              named name, and then returns the pointer to that node
    186  * Input: hdf -> the dataset node to start from
    187  *        name -> the name to walk to
    188  * Output: None
    189  * Returns: the pointer to the named node, or NULL if it doesn't exist
    190  */
    191 HDF* hdf_get_obj (HDF *hdf, const char *name);
    192 
    193 /*
    194  * Function: hdf_get_node - Similar to hdf_get_obj except all the nodes
    195  *           are created if the don't exist.
    196  * Description: hdf_get_node is similar to hdf_get_obj, except instead
    197  *              of stopping if it can't find a node in the tree, it will
    198  *              create all of the nodes necessary to hand you back the
    199  *              node you ask for.  Nodes are created with no value.
    200  * Input: hdf -> the dataset node to start from
    201  *        name -> the name to walk to
    202  * Output: ret -> the dataset node you asked for
    203  * Returns: NERR_NOMEM - unable to allocate new nodes
    204  */
    205 NEOERR * hdf_get_node (HDF *hdf, const char *name, HDF **ret);
    206 
    207 /*
    208  * Function: hdf_get_child - return the first child of the named node
    209  * Description: hdf_get_child will walk the dataset starting at hdf to
    210  *              name, and return the first child of that node
    211  * Input: hdf -> the dataset node to start from
    212  *        name -> the name to walk to
    213  * Output: None
    214  * Returns: The first child of the named dataset node or NULL if the
    215  *          node is not found (or it has no children)
    216  */
    217 HDF* hdf_get_child (HDF *hdf, const char *name);
    218 
    219 /*
    220  * Function: hdf_get_attr -
    221  * Description:
    222  * Input:
    223  * Output:
    224  * Returns:
    225  */
    226 HDF_ATTR* hdf_get_attr (HDF *hdf, const char *name);
    227 
    228 /*
    229  * Function: hdf_set_attr -
    230  * Description:
    231  * Input:
    232  * Output:
    233  * Returns:
    234  */
    235 NEOERR* hdf_set_attr (HDF *hdf, const char *name, const char *key,
    236                       const char *value);
    237 
    238 /*
    239  * Function: hdf_obj_child - Return the first child of a dataset node
    240  * Description: hdf_obj_child and the other hdf_obj_ functions are
    241  *              accessors to the HDF dataset.  Although we do not
    242  *              currently "hide" the HDF struct implementation, we
    243  *              recommend you use the accessor functions instead of
    244  *              accessing the values directly.
    245  * Input: hdf -> the hdf dataset node
    246  * Output: None
    247  * Returns: The pointer to the first child, or NULL if there is none
    248  */
    249 HDF* hdf_obj_child (HDF *hdf);
    250 
    251 /*
    252  * Function: hdf_obj_next - Return the next node of a dataset level
    253  * Description: hdf_obj_next is an accessor function for the HDF struct
    254  * Input: hdf -> the hdf dataset node
    255  * Output: None
    256  * Returns: The pointer to the next node, or NULL if there is none
    257  */
    258 HDF* hdf_obj_next (HDF *hdf);
    259 
    260 /*
    261  * Function: hdf_obj_top - Return the pointer to the top dataset node
    262  * Description: hdf_obj_top is an accessor function which returns a
    263  *              pointer to the top of the dataset, the node which was
    264  *              returned by hdf_init.  This is most useful for
    265  *              implementations of language wrappers where individual
    266  *              nodes are tied garbage colletion wise to the top node of
    267  *              the data set
    268  * Input: hdf -> the hdf dataset node
    269  * Output: None
    270  * Returns: The pointer to the top node
    271  */
    272 HDF* hdf_obj_top (HDF *hdf);
    273 
    274 /*
    275  * Function: hdf_obj_attr - Return the HDF Attributes for a node
    276  * Description:
    277  * Input:
    278  * Output:
    279  * Returns:
    280  */
    281 HDF_ATTR* hdf_obj_attr (HDF *hdf);
    282 
    283 /*
    284  * Function: hdf_obj_name - Return the name of a node
    285  * Description: hdf_obj_name is an accessor function for a datset node
    286  *              which returns the name of the node.  This is just the
    287  *              local name, and not the full path.
    288  * Input: hdf -> the hdf dataset node
    289  * Output: None
    290  * Returns: The name of the node.  If this is the top node, the name is
    291  * NULL.
    292  */
    293 char* hdf_obj_name (HDF *hdf);
    294 
    295 /*
    296  * Function: hdf_obj_value - Return the value of a node
    297  * Description: hdf_obj_value is an accessor function for a dataset node
    298  *              which returns the value of the node, or NULL if the node
    299  *              has no value.  This is not a copy of the value, so the
    300  *              node retains ownership of the value
    301  * Input: hdf -> the hdf dataset node
    302  * Output: None
    303  * Returns: The value of the node, or NULL if it has no value
    304  */
    305 char* hdf_obj_value (HDF *hdf);
    306 
    307 /*
    308  * Function: hdf_set_value - Set the value of a named node
    309  * Description: hdf_set_value will set the value of a named node.  All
    310  *              of the interstitial nodes which don't exist will be
    311  *              created with a value of NULL.  Existing nodes are not
    312  *              modified.  New nodes are created at the end of the list.
    313  *              If a list of nodes exceeds FORCE_HASH_AT, then a HASH
    314  *              will be created at that level and all of the nodes will
    315  *              be added to the hash for faster lookup times.
    316  *              The copy of the value will be made which the dataset
    317  *              will own.
    318  * Input: hdf -> the pointer to the hdf dataset
    319  *        name -> the named node to walk to
    320  *        value -> the value to set the node to
    321  * Output: None
    322  * Returns: NERR_NOMEM
    323  */
    324 NEOERR* hdf_set_value (HDF *hdf, const char *name, const char *value);
    325 
    326 /*
    327  * Function: hdf_set_valuef - Set the value of a named node
    328  * Description: hdf_set_valuef is a convenience function that wraps
    329  *              hdf_set_value.  Due to limitations of C, the fmt is in
    330  *              the format "name=value", where we will first format the
    331  *              entire string, and then break it at the first (from the
    332  *              left) equal sign (=) and use the left portion as the
    333  *              name and the right portion as the value.  This function
    334  *              is somewhat inefficient in that it first allocates the
    335  *              full name=value, and then the call to hdf_set_value
    336  *              duplicates the value portion, and then we free the
    337  *              name=value.
    338  *              Currently, we don't strip whitespace from the key or
    339  *              value.  In the future, this function might work more
    340  *              like reading a single line of an HDF string or file,
    341  *              allowing for attributes and symlinks to be specified...
    342  *              maybe.
    343  * Input: hdf -> the pointer to the hdf dataset
    344  *        fmt -> the name=value printf(3) format string
    345  * Output: None
    346  * Returns: NERR_NOMEM
    347  */
    348 NEOERR* hdf_set_valuef (HDF *hdf, const char *fmt, ...)
    349                         ATTRIBUTE_PRINTF(2,3);
    350 NEOERR* hdf_set_valuevf (HDF *hdf, const char *fmt, va_list ap);
    351 
    352 /*
    353  * Function: hdf_set_int_value - Set the value of a named node to a number
    354  * Description: hdf_set_int_value is a helper function that maps an
    355  *              integer to a string, and then calls hdf_set_value with
    356  *              that string
    357  * Input: hdf -> the pointer to the hdf dataset
    358  *        name -> the named node to walk to
    359  *        value -> the value to set the node to
    360  * Output: None
    361  * Returns: NERR_NOMEM
    362  */
    363 NEOERR* hdf_set_int_value (HDF *hdf, const char *name, int value);
    364 
    365 /*
    366  * Function: hdf_set_copy -> Copy a value from one location in the
    367  *           dataset to another
    368  * Description: hdf_set_copy first walks the hdf dataset to the named src
    369  *              node, and then copies that value to the named dest node.
    370  *              If the src node is not found, an error is raised.
    371  * Input: hdf -> the pointer to the dataset node
    372  *        dest -> the name of the destination node
    373  *        src -> the name of the source node
    374  * Output: None
    375  * Returns: NERR_NOMEM, NERR_NOT_FOUND
    376  */
    377 NEOERR* hdf_set_copy (HDF *hdf, const char *dest, const char *src);
    378 
    379 /*
    380  * Function: hdf_set_buf - Set the value of a node without duplicating
    381  *           the value
    382  * Description: hdf_set_buf is similar to hdf_set_value, except the
    383  *              dataset takes ownership of the value instead of making a
    384  *              copy of it.  The dataset assumes that value was
    385  *              malloc'd, since it will attempt to free it when
    386  *              hdf_destroy is called
    387  * Input: hdf -> the hdf dataset node
    388  *        name -> the name to walk to
    389  *        value -> the malloc'd value
    390  * Output: None
    391  * Returns: NERR_NOMEM - unable to allocate a node
    392  */
    393 
    394 NEOERR* hdf_set_buf (HDF *hdf, const char *name, char *value);
    395 
    396 /*
    397  * Function: hdf_set_symlink - Set part of the tree to link to another
    398  * Description: hdf_set_symlink creates a link between two sections of
    399  *              an HDF dataset.  The link is "by name" hence the term
    400  *              "symlink".  This means that the destination node does
    401  *              not need to exist.  Any attempt to access the source
    402  *              node will cause the function to walk to the dest node,
    403  *              and then continue walking from there.  Using symlinks
    404  *              can "hide" values in the dataset since you won't be able
    405  *              to access any children of the linked node directly,
    406  *              though dumps and other things which access the data
    407  *              structure directly will bypass the symlink.  Use this
    408  *              feature sparingly as its likely to surprise you.
    409  * Input: hdf -> the dataset node
    410  *        src -> the source node name
    411  *        dest -> the destination node name (from the top of the
    412  *        dataset, not relative names)
    413  * Output: None
    414  * Returns: NERR_NOMEM
    415  */
    416 NEOERR *hdf_set_symlink (HDF *hdf, const char *src, const char *dest);
    417 
    418 /*
    419  * Function: hdf_sort_obj - sort the children of an HDF node
    420  * Description: hdf_sort_obj will sort the children of an HDF node,
    421  *              based on the given comparison function.
    422  *              This function works by creating an array of the pointers
    423  *              for each child object of h, using qsort to sort that
    424  *              array, and then re-ordering the linked list of children
    425  *              to the new order.  The qsort compare function uses a
    426  *              pointer to the value in the array, which in our case is
    427  *              a pointer to an HDF struct, so your comparison function
    428  *              should work on HDF ** pointers.
    429  * Input: h - HDF node
    430  *        compareFunc - function which returns 1,0,-1 depending on some
    431  *                      criteria.  The arguments to this sort function
    432  *                      are pointers to pointers to HDF elements.  For
    433  *                      example:
    434  *                      int sortByName(const void *a, const void *b) {
    435  *                        HDF **ha = (HDF **)a;
    436  *                        HDF **hb = (HDF **)b;
    437  *
    438  *                      return strcasecmp(hdf_obj_name(*ha), hdf_obj_name(*hb));
    439  *                      }
    440  *
    441  * Output: None (h children will be sorted)
    442  * Return: NERR_NOMEM
    443  */
    444 NEOERR *hdf_sort_obj(HDF *h, int (*compareFunc)(const void *, const void *));
    445 
    446 /*
    447  * Function: hdf_read_file - read an HDF data file
    448  * Description:
    449  * Input:
    450  * Output:
    451  * Returns: NERR_IO, NERR_NOMEM, NERR_PARSE
    452  */
    453 NEOERR* hdf_read_file (HDF *hdf, const char *path);
    454 
    455 /*
    456  * Function: hdf_write_file - write an HDF data file
    457  * Description:
    458  * Input:
    459  * Output:
    460  * Returns: NERR_IO
    461  */
    462 NEOERR* hdf_write_file (HDF *hdf, const char *path);
    463 
    464 /*
    465  * Function: hdf_write_file_atomic - write an HDF data file atomically
    466  * Description: hdf_write_file_atomic is similar to hdf_write_file,
    467  *              except the new file is created with a unique name and
    468  *              then rename(2) is used to atomically replace the old
    469  *              file with the new file
    470  * Input:
    471  * Output:
    472  * Returns: NERR_IO
    473  */
    474 NEOERR* hdf_write_file_atomic (HDF *hdf, const char *path);
    475 
    476 /*
    477  * Function: hdf_read_string - read an HDF string
    478  * Description:
    479  * Input:
    480  * Output:
    481  * Returns: NERR_NOMEM, NERR_PARSE
    482  */
    483 NEOERR* hdf_read_string (HDF *hdf, const char *s);
    484 
    485 /*
    486  * Function: hdf_read_string_ignore - Read an HDF string and ignore errors
    487  * Description:
    488  * Input:
    489  * Output:
    490  * Returns: NERR_NOMEM
    491  */
    492 NEOERR* hdf_read_string_ignore (HDF *hdf, const char *s, int ignore);
    493 
    494 /*
    495  * Function: hdf_write_string - serialize an HDF dataset to a string
    496  * Description:
    497  * Input:
    498  * Output:
    499  * Returns: NERR_NOMEM
    500  */
    501 NEOERR* hdf_write_string (HDF *hdf, char **s);
    502 
    503 /*
    504  * Function: hdf_dump - dump an HDF dataset to stdout
    505  * Description:
    506  * Input:
    507  * Output:
    508  * Returns:
    509  */
    510 NEOERR* hdf_dump (HDF *hdf, const char *prefix);
    511 
    512 /*
    513  * Function: hdf_dump_format - dump an HDF dataset to FILE *fp
    514  * Description:
    515  * Input:
    516  * Output:
    517  * Returns:
    518  */
    519 NEOERR* hdf_dump_format (HDF *hdf, int lvl, FILE *fp);
    520 
    521 /*
    522  * Function: hdf_dump_str - dump an HDF dataset to STRING
    523  * Description:
    524  * Input:
    525  * Output:
    526  * Returns:
    527  */
    528 NEOERR* hdf_dump_str(HDF *hdf, const char *prefix, int compact, STRING *str);
    529 
    530 /*
    531  * Function: hdf_remove_tree - delete a subtree of an HDF dataset
    532  * Description:
    533  * Input:
    534  * Output:
    535  * Returns:
    536  */
    537 NEOERR* hdf_remove_tree (HDF *hdf, const char *name);
    538 
    539 /*
    540  * Function: hdf_copy - copy part of an HDF dataset to another
    541  * Description: hdf_copy is a deep copy of an HDF tree pointed to by
    542  *              src to the named node of dest.  dest and src need not be
    543  *              part of the same data set
    544  * Input: dest_hdf -> the destination dataset
    545  *        name -> the name of the destination node
    546  *        src -> the hdf dataset to copy to the destination
    547  * Output: None
    548  * Returns: NERR_NOMEM, NERR_NOT_FOUND
    549  */
    550 NEOERR* hdf_copy (HDF *dest_hdf, const char *name, HDF *src);
    551 
    552 /*
    553  * Function: hdf_search_path - Find a file given a search path in HDF
    554  * Description: hdf_search_path is a convenience/utility function that
    555  *              searches for relative filenames in a search path.  The
    556  *              search path is the list given by the children of
    557  *              hdf.loadpaths.
    558  * Input: hdf -> the hdf dataset to use
    559  *        path -> the relative path
    560  *        full -> a pointer to a _POSIX_PATH_MAX buffer
    561  * Output: full -> the full path of the file
    562  * Returns: NERR_NOT_FOUND if the file wasn't found in the search path
    563  */
    564 NEOERR* hdf_search_path (HDF *hdf, const char *path, char *full);
    565 
    566 /*
    567  * Function: hdf_register_fileload - register a fileload function
    568  * Description: hdf_register_fileload registers a fileload function that
    569  *              overrides the built-in function.  The built-in function
    570  *              uses hdf_search_path and ne_file_load (based on stat/open/read)
    571  *              to find and load the file on every hdf_read_file (including
    572  *              #include).  You can override this function if you wish to provide
    573  *              other file search functions, or load the hdf file
    574  *              from an in-memory cache, etc.
    575  * Input: hdf - pointer to a head HDF node
    576  *        ctx - pointer that is passed to the HDFFILELOAD function when called
    577  *        fileload - a HDFFILELOAD function
    578  * Output: None
    579  * Return: None
    580  *
    581  */
    582 
    583 void hdf_register_fileload(HDF *hdf, void *ctx, HDFFILELOAD fileload);
    584 
    585 __END_DECLS
    586 
    587 #endif /* __NEO_HDF_H_ */
    588