summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLloyd Hilaiel <lloyd@hilaiel.com>2011-04-25 11:06:02 -0600
committerLloyd Hilaiel <lloyd@hilaiel.com>2011-04-25 11:06:16 -0600
commitc152ba0ab3b4de220ae86f0c2ab702e197e81b3c (patch)
tree2c8475132b98b13f4507ff1506e8415788529f3a
parent575226189f1bc0874589a529fba1f6ede4f3924b (diff)
downloadyajl-c152ba0ab3b4de220ae86f0c2ab702e197e81b3c.tar.gz
documentation updates
-rw-r--r--example/parse_config.c13
-rw-r--r--src/YAJL.dxy2
-rw-r--r--src/api/yajl_parse.h24
-rw-r--r--src/api/yajl_tree.h37
-rw-r--r--src/yajl194
5 files changed, 60 insertions, 210 deletions
diff --git a/example/parse_config.c b/example/parse_config.c
index acce032..0e70192 100644
--- a/example/parse_config.c
+++ b/example/parse_config.c
@@ -34,20 +34,19 @@ main(void)
/* read the entire config file */
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
+ /* file read error handling */
if (rd == 0 && !feof(stdin)) {
fprintf(stderr, "error encountered on file read\n");
return 1;
- }
-
- if (rd >= sizeof(fileData) - 1) {
+ } else if (rd >= sizeof(fileData) - 1) {
fprintf(stderr, "config file too big\n");
return 1;
}
- /* we have the whole config file in memory. let's parse it */
+ /* we have the whole config file in memory. let's parse it ... */
node = yajl_tree_parse((const char *) fileData, errbuf, sizeof(errbuf));
- /* error handling */
+ /* parse error handling */
if (node == NULL) {
fprintf(stderr, "parse_error: ");
if (strlen(errbuf)) fprintf(stderr, " %s", errbuf);
@@ -56,11 +55,11 @@ main(void)
return 1;
}
- /* now extract a nested value from the config file */
+ /* ... and extract a nested value from the config file */
{
const char * path[] = { "Logging", "timeFormat", (const char *) 0 };
yajl_val v = yajl_tree_get(node, path, yajl_t_string);
- if (v) printf("Logging/timeFomat: %s\n", YAJL_GET_STRING(v));
+ if (v) printf("%s/%s: %s\n", path[0], path[1], YAJL_GET_STRING(v));
else printf("no such node: %s/%s\n", path[0], path[1]);
}
diff --git a/src/YAJL.dxy b/src/YAJL.dxy
index 3bdae86..57c720c 100644
--- a/src/YAJL.dxy
+++ b/src/YAJL.dxy
@@ -518,7 +518,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
-EXAMPLE_PATH =
+EXAMPLE_PATH = ..
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
diff --git a/src/api/yajl_parse.h b/src/api/yajl_parse.h
index 23be584..55c8311 100644
--- a/src/api/yajl_parse.h
+++ b/src/api/yajl_parse.h
@@ -16,7 +16,7 @@
/**
* \file yajl_parse.h
- * Interface to YAJL's JSON parsing facilities.
+ * Interface to YAJL's JSON stream parsing facilities.
*/
#include <yajl/yajl_common.h>
@@ -57,15 +57,19 @@ extern "C" {
* continue. If zero, the parse will be canceled and
* yajl_status_client_canceled will be returned from the parse.
*
- * Note about handling of numbers:
- * yajl will only convert numbers that can be represented in a double
- * or a 64 bit (long long) int. All other numbers will be passed to the client
- * in string form using the yajl_number callback. Furthermore, if
- * yajl_number is not NULL, it will always be used to return numbers,
- * that is yajl_integer and yajl_double will be ignored. If
- * yajl_number is NULL but one of yajl_integer or yajl_double are
- * defined, parsing of a number larger than is representable
- * in a double or 64 bit integer will result in a parse error.
+ * \attention {
+ * A note about the handling of numbers:
+ *
+ * yajl will only convert numbers that can be represented in a
+ * double or a 64 bit (long long) int. All other numbers will
+ * be passed to the client in string form using the yajl_number
+ * callback. Furthermore, if yajl_number is not NULL, it will
+ * always be used to return numbers, that is yajl_integer and
+ * yajl_double will be ignored. If yajl_number is NULL but one
+ * of yajl_integer or yajl_double are defined, parsing of a
+ * number larger than is representable in a double or 64 bit
+ * integer will result in a parse error.
+ * }
*/
typedef struct {
int (* yajl_null)(void * ctx);
diff --git a/src/api/yajl_tree.h b/src/api/yajl_tree.h
index f23f191..a02c531 100644
--- a/src/api/yajl_tree.h
+++ b/src/api/yajl_tree.h
@@ -21,6 +21,11 @@
*
* \author Florian Forster
* \date August 2010
+ *
+ * This interface makes quick parsing and extraction of
+ * smallish JSON docs trivial:
+ *
+ * \include example/parse_config.c
*/
#ifndef YAJL_TREE_H
@@ -50,17 +55,18 @@ typedef enum {
typedef struct yajl_val_s * yajl_val;
/**
- * A JSON value:is one of the seven types above. For "string", "number",
- * "object", and "array" additional data is available in the "data" union.
- * The "YAJL_IS_*" and "YAJL_GET_*" macros below allow type checking
- * and convenient value extraction.
+ * A JSON value representation capable of holding one of the seven
+ * types above. For "string", "number", "object", and "array"
+ * additional data is available in the union. The "YAJL_IS_*"
+ * and "YAJL_GET_*" macros below allow type checking and convenient
+ * value extraction.
*/
struct yajl_val_s
{
/** Type of the value contained. Use the "YAJL_IS_*" macors to check for a
* specific type. */
yajl_type type;
- /** Type-specific data. Use the "YAJL_TO_*" macros to access these
+ /** Type-specific data. You may use the "YAJL_GET_*" macros to access these
* members. */
union
{
@@ -76,7 +82,7 @@ struct yajl_val_s
} number;
struct {
const char **keys; /*< Array of keys */
- yajl_val *values; /** Array of values. */
+ yajl_val *values; /*< Array of values. */
size_t len; /*< Number of key-value-pairs. */
} object;
struct {
@@ -92,7 +98,7 @@ struct yajl_val_s
* Parses an null-terminated string containing JSON data and returns a pointer
* to the top-level value (root of the parse tree).
*
- * \param input Pointer to a null-terminated string containing
+ * \param input Pointer to a null-terminated utf8 string containing
* JSON data.
* \param error_buffer Pointer to a buffer in which an error message will
* be stored if \em yajl_tree_parse fails, or
@@ -112,9 +118,7 @@ YAJL_API yajl_val yajl_tree_parse (const char *input,
char *error_buffer, size_t error_buffer_size);
/**
- * Free a parse tree.
- *
- * Recursively frees a pointer returned by "yajl_tree_parse".
+ * Free a parse tree returned by "yajl_tree_parse".
*
* \param v Pointer to a JSON value returned by "yajl_tree_parse". Passing NULL
* is valid and results in a no-op.
@@ -122,7 +126,18 @@ YAJL_API yajl_val yajl_tree_parse (const char *input,
YAJL_API void yajl_tree_free (yajl_val v);
/**
- * Access a nested value.
+ * Access a nested value inside a tree.
+ *
+ * \param parent the node under which you'd like to extract values.
+ * \param path A null terminated array of strings, each the name of an object key
+ * \param type the yajl_type of the object you seek, or yajl_t_any if any will do.
+ *
+ * \returns a pointer to the found value, or NULL if we came up empty.
+ *
+ * Future Ideas: it'd be nice to move path to a string and implement support for
+ * a teeny tiny micro language here, so you can extract array elements, do things
+ * like .first and .last, even .length. Inspiration from JSONPath and css selectors?
+ * No it wouldn't be fast, but that's not what this API is about.
*/
YAJL_API yajl_val yajl_tree_get(yajl_val parent, const char ** path, yajl_type type);
diff --git a/src/yajl b/src/yajl
index c59dd96..a7b5205 100644
--- a/src/yajl
+++ b/src/yajl
@@ -1,3 +1,8 @@
+/**
+\example reformatter/json_reformat.c
+\example example/parse_config.c
+*/
+
/*!
\mainpage Yet Another JSON Library (YAJL)
\author Lloyd Hilaiel
@@ -5,9 +10,7 @@
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style)
JSON parser written in ANSI C, and a small validating JSON
-generator. It also includes a small simplified tree interface for
-simplified parsing and extraction of data from smallish JSON documents.
-YAJL is released under the permissive ISC license.
+generator. YAJL is released under the permissive ISC license.
\section features Features
@@ -17,186 +20,15 @@ YAJL is released under the permissive ISC license.
-# tiny
-# event driven
-# support for generating "beautified" JSON
+ -# includes
+It also includes a small simplified tree interface for
+simplified parsing and extraction of data from smallish JSON documents.
\section usage Usage
-The following code sample is a complete JSON "reformating" program. It
-demonstrates how to perform stream parsing and generation.
-
-\code
-#include <yajl/yajl_parse.h>
-#include <yajl/yajl_gen.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static int reformat_null(void * ctx)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_null(g);
-}
-
-static int reformat_boolean(void * ctx, int boolean)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_bool(g, boolean);
-}
-
-static int reformat_number(void * ctx, const char * s, size_t l)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_number(g, s, l);
-}
-
-static int reformat_string(void * ctx, const unsigned char * stringVal,
- size_t stringLen)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
-}
-
-static int reformat_map_key(void * ctx, const unsigned char * stringVal,
- size_t stringLen)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
-}
-
-static int reformat_start_map(void * ctx)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_map_open(g);
-}
-
-
-static int reformat_end_map(void * ctx)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_map_close(g);
-}
-
-static int reformat_start_array(void * ctx)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_array_open(g);
-}
-
-static int reformat_end_array(void * ctx)
-{
- yajl_gen g = (yajl_gen) ctx;
- return yajl_gen_status_ok == yajl_gen_array_close(g);
-}
-
-static yajl_callbacks callbacks = {
- reformat_null,
- reformat_boolean,
- NULL,
- NULL,
- reformat_number,
- reformat_string,
- reformat_start_map,
- reformat_map_key,
- reformat_end_map,
- reformat_start_array,
- reformat_end_array
-};
-
-static void
-usage(const char * progname)
-{
- fprintf(stderr, "%s: reformat json from stdin\n"
- "usage: json_reformat [options]\n"
- " -m minimize json rather than beautify (default)\n"
- " -u allow invalid UTF8 inside strings during parsing\n",
- progname);
- exit(1);
-
-}
-
-int
-main(int argc, char ** argv)
-{
- yajl_handle hand;
- static unsigned char fileData[65536];
- /* generator config */
- yajl_gen g;
- yajl_status stat;
- size_t rd;
- int retval = 0;
-
- g = yajl_gen_alloc(NULL);
- yajl_gen_config(g, yajl_gen_beautify, 1);
- yajl_gen_config(g, yajl_gen_validate_utf8, 1);
-
- /* ok. open file. let's read and parse */
- hand = yajl_alloc(&callbacks, NULL, (void *) g);
- /* and let's allow comments by default */
- yajl_config(hand, yajl_allow_comments, 1);
-
- /* check arguments.*/
- int a = 1;
- while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
- unsigned int i;
- for ( i=1; i < strlen(argv[a]); i++) {
- switch (argv[a][i]) {
- case 'm':
- yajl_gen_config(g, yajl_gen_beautify, 0);
- break;
- case 'u':
- yajl_config(hand, yajl_dont_validate_strings, 1);
- break;
- default:
- fprintf(stderr, "unrecognized option: '%c'\n\n",
- argv[a][i]);
- usage(argv[0]);
- }
- }
- ++a;
- }
- if (a < argc) {
- usage(argv[0]);
- }
-
-
- for (;;) {
- rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
-
- if (rd == 0) {
- if (!feof(stdin)) {
- fprintf(stderr, "error on file read.\n");
- retval = 1;
- }
- break;
- }
- fileData[rd] = 0;
-
- stat = yajl_parse(hand, fileData, rd);
-
- if (stat != yajl_status_ok) break;
-
- {
- const unsigned char * buf;
- size_t len;
- yajl_gen_get_buf(g, &buf, &len);
- fwrite(buf, 1, len, stdout);
- yajl_gen_clear(g);
- }
- }
-
- stat = yajl_complete_parse(hand);
-
- if (stat != yajl_status_ok) {
- unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
- fprintf(stderr, "%s", (const char *) str);
- yajl_free_error(hand, str);
- retval = 1;
- }
-
- yajl_gen_free(g);
- yajl_free(hand);
+The following code sample is a complete JSON "reformating" program.
+See <a href="reformatter_2json_reformat_8c-example.html">json_reformat.c</a> for a complete example of stream based parsing
+and generation of JSON. See <a href="example_2parse_config_8c-example.html">parse_config.c</a> for an example of the
+simplified tree interface.
- return retval;
-}
-\endcode
*/