"Fossies" - the Fresh Open Source Software Archive

Member "yajl-2.1.0/test/parsing/yajl_test.c" (19 Mar 2014, 7511 Bytes) of package /linux/www/yajl-2.1.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
    3  *
    4  * Permission to use, copy, modify, and/or distribute this software for any
    5  * purpose with or without fee is hereby granted, provided that the above
    6  * copyright notice and this permission notice appear in all copies.
    7  *
    8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15  */
   16 
   17 #include <yajl/yajl_parse.h>
   18 #include <yajl/yajl_gen.h>
   19 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <string.h>
   23 
   24 #include <assert.h>
   25 
   26 /* memory debugging routines */
   27 typedef struct
   28 {
   29     unsigned int numFrees;
   30     unsigned int numMallocs;
   31     /* XXX: we really need a hash table here with per-allocation
   32      *      information */
   33 } yajlTestMemoryContext;
   34 
   35 /* cast void * into context */
   36 #define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
   37 
   38 static void yajlTestFree(void * ctx, void * ptr)
   39 {
   40     assert(ptr != NULL);
   41     TEST_CTX(ctx)->numFrees++;
   42     free(ptr);
   43 }
   44 
   45 static void * yajlTestMalloc(void * ctx, size_t sz)
   46 {
   47     assert(sz != 0);
   48     TEST_CTX(ctx)->numMallocs++;
   49     return malloc(sz);
   50 }
   51 
   52 static void * yajlTestRealloc(void * ctx, void * ptr, size_t sz)
   53 {
   54     if (ptr == NULL) {
   55         assert(sz != 0);
   56         TEST_CTX(ctx)->numMallocs++;
   57     } else if (sz == 0) {
   58         TEST_CTX(ctx)->numFrees++;
   59     }
   60 
   61     return realloc(ptr, sz);
   62 }
   63 
   64 
   65 /* begin parsing callback routines */
   66 #define BUF_SIZE 2048
   67 
   68 static int test_yajl_null(void *ctx)
   69 {
   70     printf("null\n");
   71     return 1;
   72 }
   73 
   74 static int test_yajl_boolean(void * ctx, int boolVal)
   75 {
   76     printf("bool: %s\n", boolVal ? "true" : "false");
   77     return 1;
   78 }
   79 
   80 static int test_yajl_integer(void *ctx, long long integerVal)
   81 {
   82     printf("integer: %lld\n", integerVal);
   83     return 1;
   84 }
   85 
   86 static int test_yajl_double(void *ctx, double doubleVal)
   87 {
   88     printf("double: %g\n", doubleVal);
   89     return 1;
   90 }
   91 
   92 static int test_yajl_string(void *ctx, const unsigned char * stringVal,
   93                             size_t stringLen)
   94 {
   95     printf("string: '");
   96     fwrite(stringVal, 1, stringLen, stdout);
   97     printf("'\n");
   98     return 1;
   99 }
  100 
  101 static int test_yajl_map_key(void *ctx, const unsigned char * stringVal,
  102                              size_t stringLen)
  103 {
  104     char * str = (char *) malloc(stringLen + 1);
  105     str[stringLen] = 0;
  106     memcpy(str, stringVal, stringLen);
  107     printf("key: '%s'\n", str);
  108     free(str);
  109     return 1;
  110 }
  111 
  112 static int test_yajl_start_map(void *ctx)
  113 {
  114     printf("map open '{'\n");
  115     return 1;
  116 }
  117 
  118 
  119 static int test_yajl_end_map(void *ctx)
  120 {
  121     printf("map close '}'\n");
  122     return 1;
  123 }
  124 
  125 static int test_yajl_start_array(void *ctx)
  126 {
  127     printf("array open '['\n");
  128     return 1;
  129 }
  130 
  131 static int test_yajl_end_array(void *ctx)
  132 {
  133     printf("array close ']'\n");
  134     return 1;
  135 }
  136 
  137 static yajl_callbacks callbacks = {
  138     test_yajl_null,
  139     test_yajl_boolean,
  140     test_yajl_integer,
  141     test_yajl_double,
  142     NULL,
  143     test_yajl_string,
  144     test_yajl_start_map,
  145     test_yajl_map_key,
  146     test_yajl_end_map,
  147     test_yajl_start_array,
  148     test_yajl_end_array
  149 };
  150 
  151 static void usage(const char * progname)
  152 {
  153     fprintf(stderr,
  154             "usage:  %s [options]\n"
  155             "Parse input from stdin as JSON and ouput parsing details "
  156                                                           "to stdout\n"
  157             "   -b  set the read buffer size\n"
  158             "   -c  allow comments\n"
  159             "   -g  allow *g*arbage after valid JSON text\n"
  160             "   -m  allows the parser to consume multiple JSON values\n"
  161             "       from a single string separated by whitespace\n"
  162             "   -p  partial JSON documents should not cause errors\n",
  163             progname);
  164     exit(1);
  165 }
  166 
  167 int
  168 main(int argc, char ** argv)
  169 {
  170     yajl_handle hand;
  171     const char * fileName = NULL;
  172     static unsigned char * fileData = NULL;
  173     FILE *file;
  174     size_t bufSize = BUF_SIZE;
  175     yajl_status stat;
  176     size_t rd;
  177     int i, j;
  178 
  179     /* memory allocation debugging: allocate a structure which collects
  180      * statistics */
  181     yajlTestMemoryContext memCtx = { 0,0 };
  182 
  183     /* memory allocation debugging: allocate a structure which holds
  184      * allocation routines */
  185     yajl_alloc_funcs allocFuncs = {
  186         yajlTestMalloc,
  187         yajlTestRealloc,
  188         yajlTestFree,
  189         (void *) NULL
  190     };
  191 
  192     allocFuncs.ctx = (void *) &memCtx;
  193 
  194     /* allocate the parser */
  195     hand = yajl_alloc(&callbacks, &allocFuncs, NULL);
  196 
  197     /* check arguments.  We expect exactly one! */
  198     for (i=1;i<argc;i++) {
  199         if (!strcmp("-c", argv[i])) {
  200             yajl_config(hand, yajl_allow_comments, 1);
  201         } else if (!strcmp("-b", argv[i])) {
  202             if (++i >= argc) usage(argv[0]);
  203 
  204             /* validate integer */
  205             for (j=0;j<(int)strlen(argv[i]);j++) {
  206                 if (argv[i][j] <= '9' && argv[i][j] >= '0') continue;
  207                 fprintf(stderr, "-b requires an integer argument.  '%s' "
  208                         "is invalid\n", argv[i]);
  209                 usage(argv[0]);
  210             }
  211 
  212             bufSize = atoi(argv[i]);
  213             if (!bufSize) {
  214                 fprintf(stderr, "%zu is an invalid buffer size\n",
  215                         bufSize);
  216             }
  217         } else if (!strcmp("-g", argv[i])) {
  218             yajl_config(hand, yajl_allow_trailing_garbage, 1);
  219         } else if (!strcmp("-m", argv[i])) {
  220             yajl_config(hand, yajl_allow_multiple_values, 1);
  221         } else if (!strcmp("-p", argv[i])) {
  222             yajl_config(hand, yajl_allow_partial_values, 1);
  223         } else {
  224             fileName = argv[i];
  225             break;
  226         }
  227     }
  228 
  229     fileData = (unsigned char *) malloc(bufSize);
  230 
  231     if (fileData == NULL) {
  232         fprintf(stderr,
  233                 "failed to allocate read buffer of %zu bytes, exiting.",
  234                 bufSize);
  235         yajl_free(hand);
  236         exit(2);
  237     }
  238 
  239     if (fileName)
  240     {
  241         file = fopen(fileName, "r");
  242     }
  243     else
  244     {
  245         file = stdin;
  246     }
  247     for (;;) {
  248         rd = fread((void *) fileData, 1, bufSize, file);
  249 
  250         if (rd == 0) {
  251             if (!feof(stdin)) {
  252                 fprintf(stderr, "error reading from '%s'\n", fileName);
  253             }
  254             break;
  255         }
  256         /* read file data, now pass to parser */
  257         stat = yajl_parse(hand, fileData, rd);
  258 
  259         if (stat != yajl_status_ok) break;
  260     }
  261 
  262     stat = yajl_complete_parse(hand);
  263     if (stat != yajl_status_ok)
  264     {
  265         unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
  266         fflush(stdout);
  267         fprintf(stderr, "%s", (char *) str);
  268         yajl_free_error(hand, str);
  269     }
  270 
  271     yajl_free(hand);
  272     free(fileData);
  273 
  274     if (fileName)
  275     {
  276         fclose(file);
  277     }
  278     /* finally, print out some memory statistics */
  279 
  280 /* (lth) only print leaks here, as allocations and frees may vary depending
  281  *       on read buffer size, causing false failures.
  282  *
  283  *  printf("allocations:\t%u\n", memCtx.numMallocs);
  284  *  printf("frees:\t\t%u\n", memCtx.numFrees);
  285 */
  286     fflush(stderr);
  287     fflush(stdout);
  288     printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
  289 
  290     return 0;
  291 }