Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.  * @file
  3.  * Simple parser for "key = value" text files, by zamaz.
  4.  *
  5.  * Can also manage the following weird cases:
  6.  *
  7.  * @code
  8.  *   # comment
  9.  *   # empty lines are ignored
  10.  *   foo = bar # comment
  11.  *   b\
  12.  *   lah = blah ; rah=meh
  13.  *   'with spaces' = "with\ncr"
  14.  *
  15.  *   \x2a = 'do not eat \x2a in simple quotes,'" here we can \x2a"
  16.  *
  17.  *   # EOF
  18.  * @endcode
  19.  */
  20.  
  21. #ifndef CKVP_H_
  22. #define CKVP_H_
  23.  
  24. #include <stddef.h>
  25.  
  26. #ifdef __cplusplus
  27. #define CKVP_DECL_BEGIN__       extern "C" {
  28. #define CKVP_DECL_END__         }
  29. #else
  30. #define CKVP_DECL_BEGIN__
  31. #define CKVP_DECL_END__
  32. #endif
  33.  
  34. CKVP_DECL_BEGIN__
  35.  
  36. #define CKVP_OUT_SIZE           511
  37. #define CKVP_OUT_SIZE_STR       "511"
  38. #define CKVP_INIT               { CKVP_NONE, 1, 1, 0x0002, 0, "" }
  39.  
  40. /**
  41.  * ckvp_t stores the state, it must be initialized with CKVP_INIT before
  42.  * being fed to ckvp_parse().
  43.  *
  44.  * When "state" reaches CKVP_OUT_FULL, "out_size" is equal to CKVP_OUT_SIZE
  45.  * ("out" is full), and ckvp_parse() won't process any more characters until
  46.  * "out_size" is reset.
  47.  */
  48. typedef struct {
  49.         unsigned int state;    /**< Parsing status */
  50.         unsigned int line;     /**< Current line */
  51.         unsigned int column;   /**< Current column */
  52.         unsigned int internal; /**< Internal state */
  53.         size_t out_size;       /**< Number of characters in "out" */
  54.         /**
  55.          * Output buffer. Be careful, this buffer not NUL-terminated.
  56.          */
  57.         char out[(CKVP_OUT_SIZE + 1)]; /* hack: this +1 saves room for \0 */
  58. } ckvp_t;
  59.  
  60. /**
  61.  *  Possible states (previously defined in an enum, but C++ didn't like it)
  62.  */
  63. #define CKVP_NONE      0 /**< Nothing to report */
  64. #define CKVP_OUT_FULL  1 /**< Buffer "out" is full, must be flushed */
  65. #define CKVP_OUT_KEY   2 /**< Everything stored until now is a key */
  66. #define CKVP_OUT_VALUE 3 /**< Everything stored until now is a value */
  67. #define CKVP_ERROR     4 /**< Error status, check line/column */
  68.  
  69. /**
  70.  * ckvp_parse() takes the current state (ckvp), a buffer in[size] and returns
  71.  * the number of characters processed.
  72.  *
  73.  * Each time ckvp_parse() returns, ckvp->state must be checked. If no error
  74.  * occured, ckvp_parse() must be called again with the remaining characters
  75.  * if any, otherwise the next input buffer.
  76.  *
  77.  * At the end of input, ckvp_parse() must be called with a zero size.
  78.  *
  79.  * This function doesn't allocate anything.
  80.  *
  81.  * @param[in,out] ckvp Current state.
  82.  * @param size Number of characters in buffer "in".
  83.  * @param in Input buffer to parse.
  84.  * @return Number of characters processed.
  85.  */
  86. extern size_t ckvp_parse(ckvp_t *ckvp, size_t size, const char in[]);
  87.  
  88. CKVP_DECL_END__
  89.  
  90. #endif /* CKVP_H_ */
  91.