"Fossies" - the Fresh Open Source Software Archive

Member "yajl-2.1.0/reformatter/json_reformat.c" (19 Mar 2014, 6048 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. For more information about "json_reformat.c" see the Fossies "Dox" file reference documentation.

    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 /* non-zero when we're reformatting a stream */
   25 static int s_streamReformat = 0;
   26 
   27 #define GEN_AND_RETURN(func)                                          \
   28   {                                                                   \
   29     yajl_gen_status __stat = func;                                    \
   30     if (__stat == yajl_gen_generation_complete && s_streamReformat) { \
   31       yajl_gen_reset(g, "\n");                                        \
   32       __stat = func;                                                  \
   33     }                                                                 \
   34     return __stat == yajl_gen_status_ok; }
   35 
   36 static int reformat_null(void * ctx)
   37 {
   38     yajl_gen g = (yajl_gen) ctx;
   39     GEN_AND_RETURN(yajl_gen_null(g));
   40 }
   41 
   42 static int reformat_boolean(void * ctx, int boolean)
   43 {
   44     yajl_gen g = (yajl_gen) ctx;
   45     GEN_AND_RETURN(yajl_gen_bool(g, boolean));
   46 }
   47 
   48 static int reformat_number(void * ctx, const char * s, size_t l)
   49 {
   50     yajl_gen g = (yajl_gen) ctx;
   51     GEN_AND_RETURN(yajl_gen_number(g, s, l));
   52 }
   53 
   54 static int reformat_string(void * ctx, const unsigned char * stringVal,
   55                            size_t stringLen)
   56 {
   57     yajl_gen g = (yajl_gen) ctx;
   58     GEN_AND_RETURN(yajl_gen_string(g, stringVal, stringLen));
   59 }
   60 
   61 static int reformat_map_key(void * ctx, const unsigned char * stringVal,
   62                             size_t stringLen)
   63 {
   64     yajl_gen g = (yajl_gen) ctx;
   65     GEN_AND_RETURN(yajl_gen_string(g, stringVal, stringLen));
   66 }
   67 
   68 static int reformat_start_map(void * ctx)
   69 {
   70     yajl_gen g = (yajl_gen) ctx;
   71     GEN_AND_RETURN(yajl_gen_map_open(g));
   72 }
   73 
   74 
   75 static int reformat_end_map(void * ctx)
   76 {
   77     yajl_gen g = (yajl_gen) ctx;
   78     GEN_AND_RETURN(yajl_gen_map_close(g));
   79 }
   80 
   81 static int reformat_start_array(void * ctx)
   82 {
   83     yajl_gen g = (yajl_gen) ctx;
   84     GEN_AND_RETURN(yajl_gen_array_open(g));
   85 }
   86 
   87 static int reformat_end_array(void * ctx)
   88 {
   89     yajl_gen g = (yajl_gen) ctx;
   90     GEN_AND_RETURN(yajl_gen_array_close(g));
   91 }
   92 
   93 static yajl_callbacks callbacks = {
   94     reformat_null,
   95     reformat_boolean,
   96     NULL,
   97     NULL,
   98     reformat_number,
   99     reformat_string,
  100     reformat_start_map,
  101     reformat_map_key,
  102     reformat_end_map,
  103     reformat_start_array,
  104     reformat_end_array
  105 };
  106 
  107 static void
  108 usage(const char * progname)
  109 {
  110     fprintf(stderr, "%s: reformat json from stdin\n"
  111             "usage:  json_reformat [options]\n"
  112             "    -e escape any forward slashes (for embedding in HTML)\n"
  113             "    -m minimize json rather than beautify (default)\n"
  114             "    -s reformat a stream of multiple json entites\n"
  115             "    -u allow invalid UTF8 inside strings during parsing\n",
  116             progname);
  117     exit(1);
  118 }
  119 
  120 int
  121 main(int argc, char ** argv)
  122 {
  123     yajl_handle hand;
  124     static unsigned char fileData[65536];
  125     /* generator config */
  126     yajl_gen g;
  127     yajl_status stat;
  128     size_t rd;
  129     int retval = 0;
  130     int a = 1;
  131 
  132     g = yajl_gen_alloc(NULL);
  133     yajl_gen_config(g, yajl_gen_beautify, 1);
  134     yajl_gen_config(g, yajl_gen_validate_utf8, 1);
  135 
  136     /* ok.  open file.  let's read and parse */
  137     hand = yajl_alloc(&callbacks, NULL, (void *) g);
  138     /* and let's allow comments by default */
  139     yajl_config(hand, yajl_allow_comments, 1);
  140 
  141     /* check arguments.*/
  142     while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
  143         unsigned int i;
  144         for ( i=1; i < strlen(argv[a]); i++) {
  145             switch (argv[a][i]) {
  146                 case 'm':
  147                     yajl_gen_config(g, yajl_gen_beautify, 0);
  148                     break;
  149                 case 's':
  150                     yajl_config(hand, yajl_allow_multiple_values, 1);
  151                     s_streamReformat = 1;
  152                     break;
  153                 case 'u':
  154                     yajl_config(hand, yajl_dont_validate_strings, 1);
  155                     break;
  156                 case 'e':
  157                     yajl_gen_config(g, yajl_gen_escape_solidus, 1);
  158                     break;
  159                 default:
  160                     fprintf(stderr, "unrecognized option: '%c'\n\n",
  161                             argv[a][i]);
  162                     usage(argv[0]);
  163             }
  164         }
  165         ++a;
  166     }
  167     if (a < argc) {
  168         usage(argv[0]);
  169     }
  170 
  171 
  172     for (;;) {
  173         rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
  174 
  175         if (rd == 0) {
  176             if (!feof(stdin)) {
  177                 fprintf(stderr, "error on file read.\n");
  178                 retval = 1;
  179             }
  180             break;
  181         }
  182         fileData[rd] = 0;
  183 
  184         stat = yajl_parse(hand, fileData, rd);
  185 
  186         if (stat != yajl_status_ok) break;
  187 
  188         {
  189             const unsigned char * buf;
  190             size_t len;
  191             yajl_gen_get_buf(g, &buf, &len);
  192             fwrite(buf, 1, len, stdout);
  193             yajl_gen_clear(g);
  194         }
  195     }
  196 
  197     stat = yajl_complete_parse(hand);
  198 
  199     if (stat != yajl_status_ok) {
  200         unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
  201         fprintf(stderr, "%s", (const char *) str);
  202         yajl_free_error(hand, str);
  203         retval = 1;
  204     }
  205 
  206     yajl_gen_free(g);
  207     yajl_free(hand);
  208 
  209     return retval;
  210 }