2 * Copyright 2007-2009, Lloyd Hilaiel.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. Neither the name of Lloyd Hilaiel nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include <yajl/yajl_parse.h>
34 #include <yajl/yajl_gen.h>
42 /* memory debugging routines */
45 unsigned int numFrees
;
46 unsigned int numMallocs
;
47 /* XXX: we really need a hash table here with per-allocation
49 } yajlTestMemoryContext
;
51 /* cast void * into context */
52 #define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
54 static void yajlTestFree(void * ctx
, void * ptr
)
57 TEST_CTX(ctx
)->numFrees
++;
61 static void * yajlTestMalloc(void * ctx
, unsigned int sz
)
64 TEST_CTX(ctx
)->numMallocs
++;
68 static void * yajlTestRealloc(void * ctx
, void * ptr
, unsigned int sz
)
72 TEST_CTX(ctx
)->numMallocs
++;
74 TEST_CTX(ctx
)->numFrees
++;
77 return realloc(ptr
, sz
);
81 /* begin parsing callback routines */
84 static int test_yajl_null(void *ctx
)
90 static int test_yajl_boolean(void * ctx
, int boolVal
)
92 printf("bool: %s\n", boolVal
? "true" : "false");
96 static int test_yajl_integer(void *ctx
, long integerVal
)
98 printf("integer: %ld\n", integerVal
);
102 static int test_yajl_double(void *ctx
, double doubleVal
)
104 printf("double: %g\n", doubleVal
);
108 static int test_yajl_string(void *ctx
, const unsigned char * stringVal
,
109 unsigned int stringLen
)
112 fwrite(stringVal
, 1, stringLen
, stdout
);
117 static int test_yajl_map_key(void *ctx
, const unsigned char * stringVal
,
118 unsigned int stringLen
)
120 char * str
= (char *) malloc(stringLen
+ 1);
122 memcpy(str
, stringVal
, stringLen
);
123 printf("key: '%s'\n", str
);
128 static int test_yajl_start_map(void *ctx
)
130 printf("map open '{'\n");
135 static int test_yajl_end_map(void *ctx
)
137 printf("map close '}'\n");
141 static int test_yajl_start_array(void *ctx
)
143 printf("array open '['\n");
147 static int test_yajl_end_array(void *ctx
)
149 printf("array close ']'\n");
153 static yajl_callbacks callbacks
= {
163 test_yajl_start_array
,
167 static void usage(const char * progname
)
170 "usage: %s [options] <filename>\n"
171 " -c allow comments\n"
172 " -b set the read buffer size\n",
178 main(int argc
, char ** argv
)
181 const char * fileName
;
182 static unsigned char * fileData
= NULL
;
183 unsigned int bufSize
= BUF_SIZE
;
186 yajl_parser_config cfg
= { 0, 1 };
189 /* memory allocation debugging: allocate a structure which collects
191 yajlTestMemoryContext memCtx
= { 0,0 };
193 /* memory allocation debugging: allocate a structure which holds
194 * allocation routines */
195 yajl_alloc_funcs allocFuncs
= {
202 allocFuncs
.ctx
= (void *) &memCtx
;
204 /* check arguments. We expect exactly one! */
205 for (i
=1;i
<argc
;i
++) {
206 if (!strcmp("-c", argv
[i
])) {
207 cfg
.allowComments
= 1;
208 } else if (!strcmp("-b", argv
[i
])) {
209 if (++i
>= argc
) usage(argv
[0]);
211 /* validate integer */
212 for (j
=0;j
<(int)strlen(argv
[i
]);j
++) {
213 if (argv
[i
][j
] <= '9' && argv
[i
][j
] >= '0') continue;
214 fprintf(stderr
, "-b requires an integer argument. '%s' "
215 "is invalid\n", argv
[i
]);
219 bufSize
= atoi(argv
[i
]);
221 fprintf(stderr
, "%d is an invalid buffer size\n",
225 fprintf(stderr
, "invalid command line option: '%s'\n",
231 fileData
= (unsigned char *) malloc(bufSize
);
233 if (fileData
== NULL
) {
235 "failed to allocate read buffer of %u bytes, exiting.",
240 fileName
= argv
[argc
-1];
242 /* ok. open file. let's read and parse */
243 hand
= yajl_alloc(&callbacks
, &cfg
, &allocFuncs
, NULL
);
247 rd
= fread((void *) fileData
, 1, bufSize
, stdin
);
251 fprintf(stderr
, "error reading from '%s'\n", fileName
);
258 /* parse any remaining buffered data */
259 stat
= yajl_parse_complete(hand
);
261 /* read file data, pass to parser */
262 stat
= yajl_parse(hand
, fileData
, rd
);
264 if (stat
!= yajl_status_insufficient_data
&&
265 stat
!= yajl_status_ok
)
267 unsigned char * str
= yajl_get_error(hand
, 0, fileData
, rd
);
269 fprintf(stderr
, (char *) str
);
270 yajl_free_error(hand
, str
);
278 /* finally, print out some memory statistics */
280 /* (lth) only print leaks here, as allocations and frees may vary depending
281 * on read buffer size, causing false failures.
283 * printf("allocations:\t%u\n", memCtx.numMallocs);
284 * printf("frees:\t\t%u\n", memCtx.numFrees);
288 printf("memory leaks:\t%u\n", memCtx
.numMallocs
- memCtx
.numFrees
);