summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLloyd Hilaiel <lloyd@hilaiel.com>2009-04-01 18:05:07 +0300
committerLloyd Hilaiel <lloyd@hilaiel.com>2009-04-01 18:05:07 +0300
commitb78dd790825e3347422ef8ac56d2ad557a473e8f (patch)
treee1caa8c32bad3281b704d334b1a4d94c561af2ce
parentaf305526e77828621de645c4dd4c93f2d76b821b (diff)
downloadyajl-b78dd790825e3347422ef8ac56d2ad557a473e8f.tar.gz
* BREAKING API CHANGE: allow client to specify memory allocation routines
* bump yajl version to 1.0.0 * update TODO list, removing completed tasks * update yajl_test to override allocation routines and count allocations/frees, providing an automated standalone way to validate we're not leaky * update all copyright dates * update all .gold files with new test output * update ChangeLog in preparation for 1.0.0 release
-rw-r--r--CMakeLists.txt8
-rw-r--r--COPYING2
-rw-r--r--ChangeLog11
-rw-r--r--TODO4
-rwxr-xr-xconfigure2
-rw-r--r--reformatter/CMakeLists.txt2
-rw-r--r--reformatter/json_reformat.c8
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/api/yajl_common.h36
-rw-r--r--src/api/yajl_gen.h16
-rw-r--r--src/api/yajl_parse.h5
-rw-r--r--src/yajl2
-rw-r--r--src/yajl.c37
-rw-r--r--src/yajl_alloc.c65
-rw-r--r--src/yajl_alloc.h50
-rw-r--r--src/yajl_buf.c18
-rw-r--r--src/yajl_buf.h7
-rw-r--r--src/yajl_encode.c2
-rw-r--r--src/yajl_encode.h2
-rw-r--r--src/yajl_gen.c31
-rw-r--r--src/yajl_lex.c15
-rw-r--r--src/yajl_lex.h7
-rw-r--r--src/yajl_parser.c13
-rw-r--r--src/yajl_parser.h4
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/cases/array.json.gold1
-rw-r--r--test/cases/array_close.json.gold1
-rw-r--r--test/cases/array_open.json.gold1
-rw-r--r--test/cases/bogus_char.json.gold1
-rw-r--r--test/cases/codepoints_from_unicode_org.json.gold1
-rw-r--r--test/cases/dc_simple_with_comments.json.gold1
-rw-r--r--test/cases/deep_arrays.json.gold1
-rw-r--r--test/cases/difficult_json_c_test_case.json.gold1
-rw-r--r--test/cases/difficult_json_c_test_case_with_comments.json.gold1
-rw-r--r--test/cases/doubles.json.gold1
-rw-r--r--test/cases/empty_array.json.gold1
-rw-r--r--test/cases/empty_string.json.gold1
-rw-r--r--test/cases/escaped_bulgarian.json.gold1
-rw-r--r--test/cases/escaped_foobar.json.gold1
-rw-r--r--test/cases/false.json.gold1
-rw-r--r--test/cases/false_then_garbage.json.gold1
-rw-r--r--test/cases/integers.json.gold1
-rw-r--r--test/cases/invalid_utf8.json.gold1
-rw-r--r--test/cases/isolated_surrogate_marker.json.gold1
-rw-r--r--test/cases/leading_zero_in_number.json.gold1
-rw-r--r--test/cases/lonely_minus_sign.json.gold1
-rw-r--r--test/cases/lonely_number.json.gold1
-rw-r--r--test/cases/map_close.json.gold1
-rw-r--r--test/cases/map_open.json.gold1
-rw-r--r--test/cases/missing_integer_after_decimal_point.json.gold1
-rw-r--r--test/cases/missing_integer_after_exponent.json.gold1
-rw-r--r--test/cases/non_utf8_char_in_string.json.gold1
-rw-r--r--test/cases/null.json.gold1
-rw-r--r--test/cases/null_then_garbage.json.gold1
-rw-r--r--test/cases/nulls_and_bools.json.gold1
-rw-r--r--test/cases/simple.json.gold1
-rw-r--r--test/cases/simple_with_comments.json.gold1
-rw-r--r--test/cases/string_invalid_escape.json.gold1
-rw-r--r--test/cases/string_invalid_hex_char.json.gold1
-rw-r--r--test/cases/string_with_escapes.json.gold1
-rw-r--r--test/cases/string_with_invalid_newline.json.gold1
-rw-r--r--test/cases/true.json.gold1
-rw-r--r--test/cases/true_then_garbage.json.gold1
-rw-r--r--test/cases/unescaped_bulgarian.json.gold1
-rw-r--r--test/yajl_test.c73
-rw-r--r--verify/CMakeLists.txt2
-rw-r--r--verify/json_verify.c6
67 files changed, 404 insertions, 72 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 08a043e..f0570f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -32,9 +32,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(YetAnotherJSONParser)
-SET (YAJL_MAJOR 0)
-SET (YAJL_MINOR 4)
-SET (YAJL_MICRO 1)
+SET (YAJL_MAJOR 1)
+SET (YAJL_MINOR 0)
+SET (YAJL_MICRO 0)
SET (YAJL_DIST_NAME "yajl-${YAJL_MAJOR}.${YAJL_MINOR}.${YAJL_MICRO}")
diff --git a/COPYING b/COPYING
index 1e95b1b..fac48ba 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright 2007, Lloyd Hilaiel.
+Copyright 2007-2009, Lloyd Hilaiel.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/ChangeLog b/ChangeLog
index 92e4964..4b8fe9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,17 @@
1.0.0
* lth add 'make install' rules, thaks to Andrei Soroker for the
contribution.
+ * lth client may override allocation routines at generator or parser
+ allocation time
+ * tjw add yajl_parse_complete routine to allow client to explicitly
+ specify end-of-input, solving the "lonely number" case, where
+ json text consists only of an element with no explicit syntactic
+ end.
+ * tjw many new test cases
+ * tjw cleanup of code for symmetry and ease of reading
+ * lth integration of patches from Robert Varga which cleanup
+ compilation warnings on 64 bit linux
+
0.4.0
* lth buffer overflow bug in yajl_gen_double s/%lf/%g/ - thanks to
Eric Bergstrome
diff --git a/TODO b/TODO
index 0641fbb..56c3dc0 100644
--- a/TODO
+++ b/TODO
@@ -1,13 +1,9 @@
* add a test for 0x1F bug
* numeric overflow in integers and double
* line and char offsets in the lexer and in error messages
-* numbers at eof bug. client must have a way of indicating 'end of input'
- (other than passing in a ' ' whitespace byte),
- problem illustrated with lonely number test case.
* testing:
a. the permuter
b. some performance comparison against json_checker.
* investigate pull instead of push parsing
* Handle memory allocation failures gracefully
-* allow client to override malloc/calloc/free impl.
* cygwin/msys support on win32
diff --git a/configure b/configure
index 1792ec2..bed8c28 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/reformatter/CMakeLists.txt b/reformatter/CMakeLists.txt
index 5ac7035..5e6a281 100644
--- a/reformatter/CMakeLists.txt
+++ b/reformatter/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/reformatter/json_reformat.c b/reformatter/json_reformat.c
index b1c2ee7..d117179 100644
--- a/reformatter/json_reformat.c
+++ b/reformatter/json_reformat.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -156,10 +156,10 @@ main(int argc, char ** argv)
usage(argv[0]);
}
- g = yajl_gen_alloc(&conf);
+ g = yajl_gen_alloc(&conf, NULL);
/* ok. open file. let's read and parse */
- hand = yajl_alloc(&callbacks, &cfg, (void *) g);
+ hand = yajl_alloc(&callbacks, &cfg, (void *) g, NULL);
while (!done) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
@@ -185,7 +185,7 @@ main(int argc, char ** argv)
{
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, (const char *) str);
- yajl_free_error(str);
+ yajl_free_error(hand, str);
} else {
const unsigned char * buf;
unsigned int len;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index db24757..59027cb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -28,8 +28,9 @@
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_encode.c yajl_gen.c)
-SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h)
+SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c
+ yajl_encode.c yajl_gen.c yajl_alloc.c)
+SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h yajl_alloc.h)
SET (PUB_HDRS api/yajl_parse.h api/yajl_gen.h api/yajl_common.h)
# useful when fixing lexer bugs.
diff --git a/src/api/yajl_common.h b/src/api/yajl_common.h
index a97b3c0..004c6c6 100644
--- a/src/api/yajl_common.h
+++ b/src/api/yajl_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,10 @@
#ifndef __YAJL_COMMON_H__
#define __YAJL_COMMON_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define YAJL_MAX_DEPTH 128
/* msft dll export gunk. To build a DLL on windows, you
@@ -48,4 +52,34 @@
# define YAJL_API
#endif
+/** pointer to a malloc function, supporting client overriding memory
+ * allocation routines */
+typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz);
+
+/** pointer to a free function, supporting client overriding memory
+ * allocation routines */
+typedef void (*yajl_free_func)(void *ctx, void * ptr);
+
+/** pointer to a realloc function which can resize an allocation. */
+typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz);
+
+/** A structure which can be passed to yajl_*_alloc routines to allow the
+ * client to specify memory allocation functions to be used. */
+typedef struct
+{
+ /** pointer to a function that can allocate uninitialized memory */
+ yajl_malloc_func malloc;
+ /** pointer to a function that can resize memory allocations */
+ yajl_realloc_func realloc;
+ /** pointer to a function that can free memory allocated using
+ * reallocFunction or mallocFunction */
+ yajl_free_func free;
+ /** a context pointer that will be passed to above allocation routines */
+ void * ctx;
+} yajl_alloc_funcs;
+
+#ifdef __cplusplus
+};
+#endif
+
#endif
diff --git a/src/api/yajl_gen.h b/src/api/yajl_gen.h
index 334373b..c26dc6a 100644
--- a/src/api/yajl_gen.h
+++ b/src/api/yajl_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -73,8 +73,18 @@ extern "C" {
const char * indentString;
} yajl_gen_config;
- /** allocate a generator handle */
- yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config);
+ /** allocate a generator handle
+ * \param config a pointer to a structure containing parameters which
+ * configure the behavior of the json generator
+ * \param allocFuncs an optional pointer to a structure which allows
+ * the client to overide the memory allocation
+ * used by yajl. May be NULL, in which case
+ * malloc/free/realloc will be used.
+ *
+ * \returns an allocated handle on success, NULL on failure (bad params)
+ */
+ yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config,
+ const yajl_alloc_funcs * allocFuncs);
/** free a generator handle */
void YAJL_API yajl_gen_free(yajl_gen handle);
diff --git a/src/api/yajl_parse.h b/src/api/yajl_parse.h
index 6f6dba3..56504f3 100644
--- a/src/api/yajl_parse.h
+++ b/src/api/yajl_parse.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -129,6 +129,7 @@ extern "C" {
*/
yajl_handle YAJL_API yajl_alloc(const yajl_callbacks * callbacks,
const yajl_parser_config * config,
+ const yajl_alloc_funcs * allocFuncs,
void * ctx);
/** free a parser handle */
@@ -169,7 +170,7 @@ extern "C" {
unsigned int jsonTextLength);
/** free an error returned from yajl_get_error */
- void YAJL_API yajl_free_error(unsigned char * str);
+ void YAJL_API yajl_free_error(yajl_handle hand, unsigned char * str);
#ifdef __cplusplus
};
diff --git a/src/yajl b/src/yajl
index 3b359fc..95913e3 100644
--- a/src/yajl
+++ b/src/yajl
@@ -1,7 +1,7 @@
/*!
\mainpage Yet Another JSON Library (YAJL)
\author Lloyd Hilaiel
- \date 2007-2008
+ \date 2007-2009
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style)
JSON parser written in ANSI C, and a small validating JSON
diff --git a/src/yajl.c b/src/yajl.c
index 4993b62..0db3d90 100644
--- a/src/yajl.c
+++ b/src/yajl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,7 @@
#include "api/yajl_parse.h"
#include "yajl_lex.h"
#include "yajl_parser.h"
+#include "yajl_alloc.h"
#include <stdlib.h>
#include <string.h>
@@ -62,11 +63,29 @@ yajl_status_to_string(yajl_status stat)
yajl_handle
yajl_alloc(const yajl_callbacks * callbacks,
const yajl_parser_config * config,
+ const yajl_alloc_funcs * afs,
void * ctx)
{
unsigned int allowComments = 0;
unsigned int validateUTF8 = 0;
- yajl_handle hand = (yajl_handle) malloc(sizeof(struct yajl_handle_t));
+ yajl_handle hand = NULL;
+ yajl_alloc_funcs afsBuffer;
+
+ /* first order of business is to set up memory allocation routines */
+ if (afs != NULL) {
+ if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
+ {
+ return NULL;
+ }
+ } else {
+ yajl_set_default_alloc_funcs(&afsBuffer);
+ afs = &afsBuffer;
+ }
+
+ hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
+
+ /* copy in pointers to allocation routines */
+ memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
if (config != NULL) {
allowComments = config->allowComments;
@@ -75,10 +94,10 @@ yajl_alloc(const yajl_callbacks * callbacks,
hand->callbacks = callbacks;
hand->ctx = ctx;
- hand->lexer = yajl_lex_alloc(allowComments, validateUTF8);
+ hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
hand->errorOffset = 0;
- hand->decodeBuf = yajl_buf_alloc();
- hand->stateBuf = yajl_buf_alloc();
+ hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
+ hand->stateBuf = yajl_buf_alloc(&(hand->alloc));
yajl_state_push(hand, yajl_state_start);
@@ -91,7 +110,7 @@ yajl_free(yajl_handle handle)
yajl_buf_free(handle->stateBuf);
yajl_buf_free(handle->decodeBuf);
yajl_lex_free(handle->lexer);
- free(handle);
+ YA_FREE(&(handle->alloc), handle);
}
yajl_status
@@ -124,10 +143,10 @@ yajl_get_error(yajl_handle hand, int verbose,
}
void
-yajl_free_error(unsigned char * str)
+yajl_free_error(yajl_handle hand, unsigned char * str)
{
- /* XXX: use memory allocation functions if set */
- free(str);
+ /* use memory allocation functions if set */
+ YA_FREE(&(hand->alloc), str);
}
/* XXX: add utility routines to parse from file */
diff --git a/src/yajl_alloc.c b/src/yajl_alloc.c
new file mode 100644
index 0000000..0b4bf37
--- /dev/null
+++ b/src/yajl_alloc.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007-2009, Lloyd Hilaiel.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file yajl_alloc.h
+ * default memory allocation routines for yajl which use malloc/realloc and
+ * free
+ */
+
+#include "yajl_alloc.h"
+#include <stdlib.h>
+
+static void * yajl_internal_malloc(void *ctx, unsigned int sz)
+{
+ return malloc(sz);
+}
+
+static void * yajl_internal_realloc(void *ctx, void * previous,
+ unsigned int sz)
+{
+ return realloc(previous, sz);
+}
+
+static void yajl_internal_free(void *ctx, void * ptr)
+{
+ free(ptr);
+}
+
+void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf)
+{
+ yaf->malloc = yajl_internal_malloc;
+ yaf->free = yajl_internal_free;
+ yaf->realloc = yajl_internal_realloc;
+ yaf->ctx = NULL;
+}
+
diff --git a/src/yajl_alloc.h b/src/yajl_alloc.h
new file mode 100644
index 0000000..bf19308
--- /dev/null
+++ b/src/yajl_alloc.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007-2009, Lloyd Hilaiel.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file yajl_alloc.h
+ * default memory allocation routines for yajl which use malloc/realloc and
+ * free
+ */
+
+#ifndef __YAJL_ALLOC_H__
+#define __YAJL_ALLOC_H__
+
+#include "api/yajl_common.h"
+
+#define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz))
+#define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr))
+#define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz))
+
+void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf);
+
+#endif
diff --git a/src/yajl_buf.c b/src/yajl_buf.c
index 55051c8..97f1ced 100644
--- a/src/yajl_buf.c
+++ b/src/yajl_buf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -42,6 +42,7 @@ struct yajl_buf_t {
unsigned int len;
unsigned int used;
unsigned char * data;
+ yajl_alloc_funcs * alloc;
};
static
@@ -54,7 +55,7 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
/* first call */
if (buf->data == NULL) {
buf->len = YAJL_BUF_INIT_SIZE;
- buf->data = (unsigned char *) malloc(buf->len);
+ buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len);
buf->data[0] = 0;
}
@@ -63,21 +64,24 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
while (want >= (need - buf->used)) need <<= 1;
if (need != buf->len) {
- buf->data = (unsigned char *) realloc(buf->data, need);
+ buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need);
buf->len = need;
}
}
-yajl_buf yajl_buf_alloc(void)
+yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc)
{
- return (yajl_buf) calloc(1, sizeof(struct yajl_buf_t));
+ yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t));
+ memset((void *) b, 0, sizeof(struct yajl_buf_t));
+ b->alloc = alloc;
+ return b;
}
void yajl_buf_free(yajl_buf buf)
{
assert(buf != NULL);
- if (buf->data) free(buf->data);
- free(buf);
+ if (buf->data) YA_FREE(buf->alloc, buf->data);
+ YA_FREE(buf->alloc, buf);
}
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len)
diff --git a/src/yajl_buf.h b/src/yajl_buf.h
index e2c08b5..62b5554 100644
--- a/src/yajl_buf.h
+++ b/src/yajl_buf.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,9 @@
#ifndef __YAJL_BUF_H__
#define __YAJL_BUF_H__
+#include "api/yajl_common.h"
+#include "yajl_alloc.h"
+
/**
* yajl_buf is a buffer with exponential growth. the buffer ensures that
* you are always null padded.
@@ -40,7 +43,7 @@
typedef struct yajl_buf_t * yajl_buf;
/* allocate a new buffer */
-yajl_buf yajl_buf_alloc(void);
+yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc);
/* free the buffer */
void yajl_buf_free(yajl_buf buf);
diff --git a/src/yajl_encode.c b/src/yajl_encode.c
index 0449225..184277b 100644
--- a/src/yajl_encode.c
+++ b/src/yajl_encode.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/yajl_encode.h b/src/yajl_encode.h
index f3ab5bd..8bd01af 100644
--- a/src/yajl_encode.h
+++ b/src/yajl_encode.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/yajl_gen.c b/src/yajl_gen.c
index 67740ec..34cfbec 100644
--- a/src/yajl_gen.c
+++ b/src/yajl_gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -56,18 +56,39 @@ struct yajl_gen_t
const char * indentString;
yajl_gen_state state[YAJL_MAX_DEPTH];
yajl_buf buf;
+ /* memory allocation routines */
+ yajl_alloc_funcs alloc;
};
yajl_gen
-yajl_gen_alloc(const yajl_gen_config * config)
+yajl_gen_alloc(const yajl_gen_config * config,
+ const yajl_alloc_funcs * afs)
{
- yajl_gen g = (yajl_gen) malloc(sizeof(struct yajl_gen_t));
+ yajl_gen g = NULL;
+ yajl_alloc_funcs afsBuffer;
+
+ /* first order of business is to set up memory allocation routines */
+ if (afs != NULL) {
+ if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
+ {
+ return NULL;
+ }
+ } else {
+ yajl_set_default_alloc_funcs(&afsBuffer);
+ afs = &afsBuffer;
+ }
+
+ g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
memset((void *) g, 0, sizeof(struct yajl_gen_t));
+ /* copy in pointers to allocation routines */
+ memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
+
if (config) {
g->pretty = config->beautify;
g->indentString = config->indentString ? config->indentString : " ";
}
- g->buf = yajl_buf_alloc();
+ g->buf = yajl_buf_alloc(&(g->alloc));
+
return g;
}
@@ -75,7 +96,7 @@ void
yajl_gen_free(yajl_gen g)
{
yajl_buf_free(g->buf);
- free(g);
+ YA_FREE(&(g->alloc), g);
}
#define INSERT_SEP \
diff --git a/src/yajl_lex.c b/src/yajl_lex.c
index 5392422..b56f32b 100644
--- a/src/yajl_lex.c
+++ b/src/yajl_lex.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -105,6 +105,8 @@ struct yajl_lexer_t {
/* shall we validate utf8 inside strings? */
unsigned int validateUTF8;
+
+ yajl_alloc_funcs * alloc;
};
static unsigned char
@@ -127,12 +129,15 @@ unreadChar(yajl_lexer lxr, unsigned int *off)
}
yajl_lexer
-yajl_lex_alloc(unsigned int allowComments, unsigned int validateUTF8)
+yajl_lex_alloc(yajl_alloc_funcs * alloc,
+ unsigned int allowComments, unsigned int validateUTF8)
{
- yajl_lexer lxr = (yajl_lexer) calloc(1, sizeof(struct yajl_lexer_t));
- lxr->buf = yajl_buf_alloc();
+ yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t));
+ memset((void *) lxr, 0, sizeof(struct yajl_lexer_t));
+ lxr->buf = yajl_buf_alloc(alloc);
lxr->allowComments = allowComments;
lxr->validateUTF8 = validateUTF8;
+ lxr->alloc = alloc;
return lxr;
}
@@ -140,7 +145,7 @@ void
yajl_lex_free(yajl_lexer lxr)
{
yajl_buf_free(lxr->buf);
- free(lxr);
+ YA_FREE(lxr->alloc, lxr);
return;
}
diff --git a/src/yajl_lex.h b/src/yajl_lex.h
index e84131a..966365c 100644
--- a/src/yajl_lex.h
+++ b/src/yajl_lex.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,8 @@
#ifndef __YAJL_LEX_H__
#define __YAJL_LEX_H__
+#include "api/yajl_common.h"
+
typedef enum {
yajl_tok_bool,
yajl_tok_colon,
@@ -61,7 +63,8 @@ typedef enum {
typedef struct yajl_lexer_t * yajl_lexer;
-yajl_lexer yajl_lex_alloc(unsigned int allowComments,
+yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc,
+ unsigned int allowComments,
unsigned int validateUTF8);
void yajl_lex_free(yajl_lexer lexer);
diff --git a/src/yajl_parser.c b/src/yajl_parser.c
index e6bc437..398873c 100644
--- a/src/yajl_parser.c
+++ b/src/yajl_parser.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -71,7 +71,7 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
memneeded += strlen(": ");
memneeded += strlen(errorText);
}
- str = (unsigned char *) malloc(memneeded + 2);
+ str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2);
str[0] = 0;
strcat((char *) str, errorType);
strcat((char *) str, " error");
@@ -108,14 +108,15 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
text[i++] = '\n';
text[i] = 0;
{
- char * newStr = (char *) malloc(strlen((char *) str) +
- strlen((char *) text) +
- strlen(arrow) + 1);
+ char * newStr = (char *)
+ YA_MALLOC(&(hand->alloc), (strlen((char *) str) +
+ strlen((char *) text) +
+ strlen(arrow) + 1));
newStr[0] = 0;
strcat((char *) newStr, (char *) str);
strcat((char *) newStr, text);
strcat((char *) newStr, arrow);
- free(str);
+ YA_FREE(&(hand->alloc), str);
str = (unsigned char *) newStr;
}
}
diff --git a/src/yajl_parser.h b/src/yajl_parser.h
index ba6c49d..0e1227d 100644
--- a/src/yajl_parser.h
+++ b/src/yajl_parser.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -61,6 +61,8 @@ struct yajl_handle_t {
yajl_buf decodeBuf;
/* a stack of states. access with yajl_state_XXX routines */
yajl_buf stateBuf;
+ /* memory allocation routines */
+ yajl_alloc_funcs alloc;
};
yajl_status
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c6d65e9..85d673d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/test/cases/array.json.gold b/test/cases/array.json.gold
index 95ec334..477559d 100644
--- a/test/cases/array.json.gold
+++ b/test/cases/array.json.gold
@@ -19,3 +19,4 @@ array close ']'
string: '
\'
array close ']'
+memory leaks: 0
diff --git a/test/cases/array_close.json.gold b/test/cases/array_close.json.gold
index 4eedbc9..972fd39 100644
--- a/test/cases/array_close.json.gold
+++ b/test/cases/array_close.json.gold
@@ -1 +1,2 @@
parse error: unallowed token at this point in JSON text
+memory leaks: 0
diff --git a/test/cases/array_open.json.gold b/test/cases/array_open.json.gold
index 86c13ec..478b6b9 100644
--- a/test/cases/array_open.json.gold
+++ b/test/cases/array_open.json.gold
@@ -1 +1,2 @@
array open '['
+memory leaks: 0
diff --git a/test/cases/bogus_char.json.gold b/test/cases/bogus_char.json.gold
index ccbeed5..0c68a49 100644
--- a/test/cases/bogus_char.json.gold
+++ b/test/cases/bogus_char.json.gold
@@ -7,3 +7,4 @@ string: 'be'
string: 'a happy bit of json'
string: 'but someone, misspelled "true"'
lexical error: invalid string in json text.
+memory leaks: 0
diff --git a/test/cases/codepoints_from_unicode_org.json.gold b/test/cases/codepoints_from_unicode_org.json.gold
index 12b358a..f359a1b 100644
--- a/test/cases/codepoints_from_unicode_org.json.gold
+++ b/test/cases/codepoints_from_unicode_org.json.gold
@@ -1 +1,2 @@
string: 'Mа二𐌂'
+memory leaks: 0
diff --git a/test/cases/dc_simple_with_comments.json.gold b/test/cases/dc_simple_with_comments.json.gold
index 92be7a5..d222e9b 100644
--- a/test/cases/dc_simple_with_comments.json.gold
+++ b/test/cases/dc_simple_with_comments.json.gold
@@ -2,3 +2,4 @@ map open '{'
key: 'this'
string: 'is'
lexical error: probable comment found in input text, comments are not enabled.
+memory leaks: 0
diff --git a/test/cases/deep_arrays.json.gold b/test/cases/deep_arrays.json.gold
index e549637..4d5cd99 100644
--- a/test/cases/deep_arrays.json.gold
+++ b/test/cases/deep_arrays.json.gold
@@ -2046,3 +2046,4 @@ array close ']'
array close ']'
array close ']'
array close ']'
+memory leaks: 0
diff --git a/test/cases/difficult_json_c_test_case.json.gold b/test/cases/difficult_json_c_test_case.json.gold
index eaaf41a..c3adc11 100644
--- a/test/cases/difficult_json_c_test_case.json.gold
+++ b/test/cases/difficult_json_c_test_case.json.gold
@@ -33,3 +33,4 @@ array close ']'
map close '}'
map close '}'
map close '}'
+memory leaks: 0
diff --git a/test/cases/difficult_json_c_test_case_with_comments.json.gold b/test/cases/difficult_json_c_test_case_with_comments.json.gold
index eaaf41a..c3adc11 100644
--- a/test/cases/difficult_json_c_test_case_with_comments.json.gold
+++ b/test/cases/difficult_json_c_test_case_with_comments.json.gold
@@ -33,3 +33,4 @@ array close ']'
map close '}'
map close '}'
map close '}'
+memory leaks: 0
diff --git a/test/cases/doubles.json.gold b/test/cases/doubles.json.gold
index 0426b37..c0ea726 100644
--- a/test/cases/doubles.json.gold
+++ b/test/cases/doubles.json.gold
@@ -4,3 +4,4 @@ double: 10
double: 3.14157
double: 1000
array close ']'
+memory leaks: 0
diff --git a/test/cases/empty_array.json.gold b/test/cases/empty_array.json.gold
index 45924af..f069c8f 100644
--- a/test/cases/empty_array.json.gold
+++ b/test/cases/empty_array.json.gold
@@ -1,2 +1,3 @@
array open '['
array close ']'
+memory leaks: 0
diff --git a/test/cases/empty_string.json.gold b/test/cases/empty_string.json.gold
index c3a3cd3..c197bba 100644
--- a/test/cases/empty_string.json.gold
+++ b/test/cases/empty_string.json.gold
@@ -1 +1,2 @@
string: ''
+memory leaks: 0
diff --git a/test/cases/escaped_bulgarian.json.gold b/test/cases/escaped_bulgarian.json.gold
index 9f2aa00..a0c9ae9 100644
--- a/test/cases/escaped_bulgarian.json.gold
+++ b/test/cases/escaped_bulgarian.json.gold
@@ -4,3 +4,4 @@ string: 'Му'
string: 'Еба'
string: 'Майката'
array close ']'
+memory leaks: 0
diff --git a/test/cases/escaped_foobar.json.gold b/test/cases/escaped_foobar.json.gold
index 774e867..5753c64 100644
--- a/test/cases/escaped_foobar.json.gold
+++ b/test/cases/escaped_foobar.json.gold
@@ -1 +1,2 @@
string: 'foobar'
+memory leaks: 0
diff --git a/test/cases/false.json.gold b/test/cases/false.json.gold
index c91690a..e55fa1f 100644
--- a/test/cases/false.json.gold
+++ b/test/cases/false.json.gold
@@ -1 +1,2 @@
bool: false
+memory leaks: 0
diff --git a/test/cases/false_then_garbage.json.gold b/test/cases/false_then_garbage.json.gold
index c91690a..e55fa1f 100644
--- a/test/cases/false_then_garbage.json.gold
+++ b/test/cases/false_then_garbage.json.gold
@@ -1 +1,2 @@
bool: false
+memory leaks: 0
diff --git a/test/cases/integers.json.gold b/test/cases/integers.json.gold
index 7341a2d..bb55c39 100644
--- a/test/cases/integers.json.gold
+++ b/test/cases/integers.json.gold
@@ -11,3 +11,4 @@ integer: -123456789
integer: 2147483647
integer: -2147483647
parse error: integer overflow
+memory leaks: 0
diff --git a/test/cases/invalid_utf8.json.gold b/test/cases/invalid_utf8.json.gold
index 0cabb13..c0dec77 100644
--- a/test/cases/invalid_utf8.json.gold
+++ b/test/cases/invalid_utf8.json.gold
@@ -1,2 +1,3 @@
array open '['
lexical error: invalid bytes in UTF8 string.
+memory leaks: 0
diff --git a/test/cases/isolated_surrogate_marker.json.gold b/test/cases/isolated_surrogate_marker.json.gold
index 1ad9e8b..cca172e 100644
--- a/test/cases/isolated_surrogate_marker.json.gold
+++ b/test/cases/isolated_surrogate_marker.json.gold
@@ -1 +1,2 @@
string: '?'
+memory leaks: 0
diff --git a/test/cases/leading_zero_in_number.json.gold b/test/cases/leading_zero_in_number.json.gold
index 828aec8..1a1580d 100644
--- a/test/cases/leading_zero_in_number.json.gold
+++ b/test/cases/leading_zero_in_number.json.gold
@@ -2,3 +2,4 @@ map open '{'
key: 'bad thing'
integer: 0
parse error: after key and value, inside map, I expect ',' or '}'
+memory leaks: 0
diff --git a/test/cases/lonely_minus_sign.json.gold b/test/cases/lonely_minus_sign.json.gold
index 4b23c61..d15ede9 100644
--- a/test/cases/lonely_minus_sign.json.gold
+++ b/test/cases/lonely_minus_sign.json.gold
@@ -6,3 +6,4 @@ string: 'blue'
string: 'baby where are you?'
string: 'oh boo hoo!'
lexical error: malformed number, a digit is required after the minus sign.
+memory leaks: 0
diff --git a/test/cases/lonely_number.json.gold b/test/cases/lonely_number.json.gold
index cdc08ba..181fdfa 100644
--- a/test/cases/lonely_number.json.gold
+++ b/test/cases/lonely_number.json.gold
@@ -1 +1,2 @@
integer: 123456789
+memory leaks: 0
diff --git a/test/cases/map_close.json.gold b/test/cases/map_close.json.gold
index 4eedbc9..972fd39 100644
--- a/test/cases/map_close.json.gold
+++ b/test/cases/map_close.json.gold
@@ -1 +1,2 @@
parse error: unallowed token at this point in JSON text
+memory leaks: 0
diff --git a/test/cases/map_open.json.gold b/test/cases/map_open.json.gold
index a823ebe..ab1f33d 100644
--- a/test/cases/map_open.json.gold
+++ b/test/cases/map_open.json.gold
@@ -1 +1,2 @@
map open '{'
+memory leaks: 0
diff --git a/test/cases/missing_integer_after_decimal_point.json.gold b/test/cases/missing_integer_after_decimal_point.json.gold
index 1d85c91..c2e7e2e 100644
--- a/test/cases/missing_integer_after_decimal_point.json.gold
+++ b/test/cases/missing_integer_after_decimal_point.json.gold
@@ -1 +1,2 @@
lexical error: malformed number, a digit is required after the decimal point.
+memory leaks: 0
diff --git a/test/cases/missing_integer_after_exponent.json.gold b/test/cases/missing_integer_after_exponent.json.gold
index b9f184f..5089681 100644
--- a/test/cases/missing_integer_after_exponent.json.gold
+++ b/test/cases/missing_integer_after_exponent.json.gold
@@ -1 +1,2 @@
lexical error: malformed number, a digit is required after the exponent.
+memory leaks: 0
diff --git a/test/cases/non_utf8_char_in_string.json.gold b/test/cases/non_utf8_char_in_string.json.gold
index b3780ae..5e3c580 100644
--- a/test/cases/non_utf8_char_in_string.json.gold
+++ b/test/cases/non_utf8_char_in_string.json.gold
@@ -5,3 +5,4 @@ key: 'CoreletType'
string: 'standalone'
key: 'documentation'
lexical error: invalid bytes in UTF8 string.
+memory leaks: 0
diff --git a/test/cases/null.json.gold b/test/cases/null.json.gold
index 19765bd..94ad0fa 100644
--- a/test/cases/null.json.gold
+++ b/test/cases/null.json.gold
@@ -1 +1,2 @@
null
+memory leaks: 0
diff --git a/test/cases/null_then_garbage.json.gold b/test/cases/null_then_garbage.json.gold
index 19765bd..94ad0fa 100644
--- a/test/cases/null_then_garbage.json.gold
+++ b/test/cases/null_then_garbage.json.gold
@@ -1 +1,2 @@
null
+memory leaks: 0
diff --git a/test/cases/nulls_and_bools.json.gold b/test/cases/nulls_and_bools.json.gold
index 8dc173c..51f990b 100644
--- a/test/cases/nulls_and_bools.json.gold
+++ b/test/cases/nulls_and_bools.json.gold
@@ -6,3 +6,4 @@ bool: false
key: 'null'
null
map close '}'
+memory leaks: 0
diff --git a/test/cases/simple.json.gold b/test/cases/simple.json.gold
index 59b7d6a..80fcad2 100644
--- a/test/cases/simple.json.gold
+++ b/test/cases/simple.json.gold
@@ -6,3 +6,4 @@ string: 'simple'
key: 'json'
string: 'right?'
map close '}'
+memory leaks: 0
diff --git a/test/cases/simple_with_comments.json.gold b/test/cases/simple_with_comments.json.gold
index 59b7d6a..80fcad2 100644
--- a/test/cases/simple_with_comments.json.gold
+++ b/test/cases/simple_with_comments.json.gold
@@ -6,3 +6,4 @@ string: 'simple'
key: 'json'
string: 'right?'
map close '}'
+memory leaks: 0
diff --git a/test/cases/string_invalid_escape.json.gold b/test/cases/string_invalid_escape.json.gold
index bdc473e..439df43 100644
--- a/test/cases/string_invalid_escape.json.gold
+++ b/test/cases/string_invalid_escape.json.gold
@@ -1,2 +1,3 @@
array open '['
lexical error: inside a string, '\' occurs before a character which it may not.
+memory leaks: 0
diff --git a/test/cases/string_invalid_hex_char.json.gold b/test/cases/string_invalid_hex_char.json.gold
index d8b535e..8498792 100644
--- a/test/cases/string_invalid_hex_char.json.gold
+++ b/test/cases/string_invalid_hex_char.json.gold
@@ -1 +1,2 @@
lexical error: invalid (non-hex) character occurs after '\u' inside string.
+memory leaks: 0
diff --git a/test/cases/string_with_escapes.json.gold b/test/cases/string_with_escapes.json.gold
index ac878a2..086a9dc 100644
--- a/test/cases/string_with_escapes.json.gold
+++ b/test/cases/string_with_escapes.json.gold
@@ -4,3 +4,4 @@ string: '
string: '"and this string has an escape at the beginning'
string: 'and this string has no escapes'
array close ']'
+memory leaks: 0
diff --git a/test/cases/string_with_invalid_newline.json.gold b/test/cases/string_with_invalid_newline.json.gold
index 80c1b8a..c38bdef 100644
--- a/test/cases/string_with_invalid_newline.json.gold
+++ b/test/cases/string_with_invalid_newline.json.gold
@@ -1 +1,2 @@
lexical error: invalid character inside string.
+memory leaks: 0
diff --git a/test/cases/true.json.gold b/test/cases/true.json.gold
index 3283d03..0858bf7 100644
--- a/test/cases/true.json.gold
+++ b/test/cases/true.json.gold
@@ -1 +1,2 @@
bool: true
+memory leaks: 0
diff --git a/test/cases/true_then_garbage.json.gold b/test/cases/true_then_garbage.json.gold
index 3283d03..0858bf7 100644
--- a/test/cases/true_then_garbage.json.gold
+++ b/test/cases/true_then_garbage.json.gold
@@ -1 +1,2 @@
bool: true
+memory leaks: 0
diff --git a/test/cases/unescaped_bulgarian.json.gold b/test/cases/unescaped_bulgarian.json.gold
index ac34442..8db076e 100644
--- a/test/cases/unescaped_bulgarian.json.gold
+++ b/test/cases/unescaped_bulgarian.json.gold
@@ -1,3 +1,4 @@
array open '['
string: 'Да Му Еба Майката'
array close ']'
+memory leaks: 0
diff --git a/test/yajl_test.c b/test/yajl_test.c
index 3c2fcf1..77281a5 100644
--- a/test/yajl_test.c
+++ b/test/yajl_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,48 @@
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
+
+/* memory debugging routines */
+typedef struct
+{
+ unsigned int numFrees;
+ unsigned int numMallocs;
+ /* XXX: we really need a hash table here with per-allocation
+ * information */
+} yajlTestMemoryContext;
+
+/* cast void * into context */
+#define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
+
+static void yajlTestFree(void * ctx, void * ptr)
+{
+ assert(ptr != NULL);
+ TEST_CTX(ctx)->numFrees++;
+ free(ptr);
+}
+
+static void * yajlTestMalloc(void * ctx, unsigned int sz)
+{
+ assert(sz != 0);
+ TEST_CTX(ctx)->numMallocs++;
+ return malloc(sz);
+}
+
+static void * yajlTestRealloc(void * ctx, void * ptr, unsigned int sz)
+{
+ if (ptr == NULL) {
+ assert(sz != 0);
+ TEST_CTX(ctx)->numMallocs++;
+ } else if (sz == 0) {
+ TEST_CTX(ctx)->numFrees++;
+ }
+
+ return realloc(ctx, sz);
+}
+
+
+/* begin parsing callback routines */
#define BUF_SIZE 2048
static int test_yajl_null(void *ctx)
@@ -144,6 +186,21 @@ main(int argc, char ** argv)
yajl_parser_config cfg = { 0, 1 };
int i, j, done;
+ /* memory allocation debugging: allocate a structure which collects
+ * statistics */
+ yajlTestMemoryContext memCtx = { 0,0 };
+
+ /* memory allocation debugging: allocate a structure which holds
+ * allocation routines */
+ yajl_alloc_funcs allocFuncs = {
+ yajlTestMalloc,
+ yajlTestRealloc,
+ yajlTestFree,
+ (void *) NULL
+ };
+
+ allocFuncs.ctx = (void *) &memCtx;
+
/* check arguments. We expect exactly one! */
for (i=1;i<argc;i++) {
if (!strcmp("-c", argv[i])) {
@@ -183,7 +240,7 @@ main(int argc, char ** argv)
fileName = argv[argc-1];
/* ok. open file. let's read and parse */
- hand = yajl_alloc(&callbacks, &cfg, NULL);
+ hand = yajl_alloc(&callbacks, &cfg, &allocFuncs, NULL);
done = 0;
while (!done) {
@@ -210,7 +267,7 @@ main(int argc, char ** argv)
unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
fflush(stdout);
fprintf(stderr, (char *) str);
- yajl_free_error(str);
+ yajl_free_error(hand, str);
break;
}
}
@@ -218,5 +275,15 @@ main(int argc, char ** argv)
yajl_free(hand);
free(fileData);
+ /* finally, print out some memory statistics */
+
+/* (lth) only print leaks here, as allocations and frees may vary depending
+ * on read buffer size, causing false failures.
+ *
+ * printf("allocations:\t%u\n", memCtx.numMallocs);
+ * printf("frees:\t\t%u\n", memCtx.numFrees);
+*/
+ printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
+
return 0;
}
diff --git a/verify/CMakeLists.txt b/verify/CMakeLists.txt
index 17efd83..68aaff9 100644
--- a/verify/CMakeLists.txt
+++ b/verify/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2007, Lloyd Hilaiel.
+# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/verify/json_verify.c b/verify/json_verify.c
index f76fbe9..11d0285 100644
--- a/verify/json_verify.c
+++ b/verify/json_verify.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, Lloyd Hilaiel.
+ * Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -80,7 +80,7 @@ main(int argc, char ** argv)
}
/* allocate a parser */
- hand = yajl_alloc(NULL, &cfg, NULL);
+ hand = yajl_alloc(NULL, &cfg, NULL, NULL);
while (!done) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
@@ -112,7 +112,7 @@ main(int argc, char ** argv)
if (!quiet) {
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, (const char *) str);
- yajl_free_error(str);
+ yajl_free_error(hand, str);
}
retval = 1;
break;