libglvnd: Changes to 'debian-unstable'
configure.ac | 2
debian/changelog | 10
debian/libgles2.symbols | 112
debian/watch | 3
src/EGL/libeglmapping.c | 2
src/EGL/libeglvendor.c | 1
src/GLdispatch/vnd-glapi/entry_aarch64_tsd.c | 31
src/GLdispatch/vnd-glapi/entry_armv7_tsd.c | 29
src/GLdispatch/vnd-glapi/entry_ppc64le_tls.c | 20
src/GLdispatch/vnd-glapi/entry_ppc64le_tsd.c | 91
src/GLdispatch/vnd-glapi/entry_x86_64_tls.c | 35
src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c | 19
src/GLdispatch/vnd-glapi/entry_x86_tls.c | 27
src/GLdispatch/vnd-glapi/entry_x86_tsd.c | 19
src/generate/genCommon.py | 2
src/util/Makefile.am | 1
src/util/cJSON.c | 3209 +++++++++++++++++++++------
src/util/cJSON.h | 260 +-
src/util/cJSON/LICENSE | 2
src/util/cJSON/README | 247 --
src/util/cJSON/test.c | 162 -
src/util/cJSON/tests/test1 | 22
src/util/cJSON/tests/test2 | 11
src/util/cJSON/tests/test3 | 26
src/util/cJSON/tests/test4 | 88
src/util/cJSON/tests/test5 | 27
src/util/glvnd_genentry.c | 14
27 files changed, 3049 insertions(+), 1423 deletions(-)
New commits:
commit 2068eb813498deaaa85f8934e8f9b80d2a5780c3
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Thu Nov 9 12:14:34 2017 +0200
release to unstable
diff --git a/debian/changelog b/debian/changelog
index e370b66..207a54a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-libglvnd (1.0.0-1) UNRELEASED; urgency=high
+libglvnd (1.0.0-1) unstable; urgency=high
[ Andreas Boll ]
* Add versioned libglvnd0 dependencies (Workaround for #878851).
@@ -10,7 +10,7 @@ libglvnd (1.0.0-1) UNRELEASED; urgency=high
* Add a watch file for uscan.
* libgles2.symbols: Updated.
- -- Andreas Boll <andreas.boll.dev@gmail.com> Fri, 20 Oct 2017 11:03:03 +0200
+ -- Timo Aaltonen <tjaalton@debian.org> Thu, 09 Nov 2017 12:14:14 +0200
libglvnd (0.2.999+git20170802-5) unstable; urgency=medium
commit 16242887df1433ea1e659f864e440f08f7006c47
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Thu Nov 9 12:14:08 2017 +0200
libgles2.symbols: Updated.
diff --git a/debian/changelog b/debian/changelog
index 18e2520..e370b66 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,7 @@ libglvnd (1.0.0-1) UNRELEASED; urgency=high
[ Timo Aaltonen ]
* New upstream release.
* Add a watch file for uscan.
+ * libgles2.symbols: Updated.
-- Andreas Boll <andreas.boll.dev@gmail.com> Fri, 20 Oct 2017 11:03:03 +0200
diff --git a/debian/libgles2.symbols b/debian/libgles2.symbols
index 25df8c7..bcaab60 100644
--- a/debian/libgles2.symbols
+++ b/debian/libgles2.symbols
@@ -1,4 +1,5 @@
libGLESv2.so.2 libgles2 #MINVER#
+ glActiveShaderProgram@Base 1.0.0
glActiveTexture@Base 0
glAttachShader@Base 0
glBeginQuery@Base 0
@@ -8,16 +9,24 @@ libGLESv2.so.2 libgles2 #MINVER#
glBindBufferBase@Base 0
glBindBufferRange@Base 0
glBindFramebuffer@Base 0
+ glBindImageTexture@Base 1.0.0
+ glBindProgramPipeline@Base 1.0.0
glBindRenderbuffer@Base 0
glBindSampler@Base 0
glBindTexture@Base 0
glBindTransformFeedback@Base 0
glBindVertexArray@Base 0
+ glBindVertexBuffer@Base 1.0.0
+ glBlendBarrier@Base 1.0.0
glBlendColor@Base 0
glBlendEquation@Base 0
glBlendEquationSeparate@Base 0
+ glBlendEquationSeparatei@Base 1.0.0
+ glBlendEquationi@Base 1.0.0
glBlendFunc@Base 0
glBlendFuncSeparate@Base 0
+ glBlendFuncSeparatei@Base 1.0.0
+ glBlendFunci@Base 1.0.0
glBlitFramebuffer@Base 0
glBufferData@Base 0
glBufferSubData@Base 0
@@ -32,21 +41,28 @@ libGLESv2.so.2 libgles2 #MINVER#
glClearStencil@Base 0
glClientWaitSync@Base 0
glColorMask@Base 0
+ glColorMaski@Base 1.0.0
glCompileShader@Base 0
glCompressedTexImage2D@Base 0
glCompressedTexImage3D@Base 0
glCompressedTexSubImage2D@Base 0
glCompressedTexSubImage3D@Base 0
glCopyBufferSubData@Base 0
+ glCopyImageSubData@Base 1.0.0
glCopyTexImage2D@Base 0
glCopyTexSubImage2D@Base 0
glCopyTexSubImage3D@Base 0
glCreateProgram@Base 0
glCreateShader@Base 0
+ glCreateShaderProgramv@Base 1.0.0
glCullFace@Base 0
+ glDebugMessageCallback@Base 1.0.0
+ glDebugMessageControl@Base 1.0.0
+ glDebugMessageInsert@Base 1.0.0
glDeleteBuffers@Base 0
glDeleteFramebuffers@Base 0
glDeleteProgram@Base 0
+ glDeleteProgramPipelines@Base 1.0.0
glDeleteQueries@Base 0
glDeleteRenderbuffers@Base 0
glDeleteSamplers@Base 0
@@ -61,13 +77,22 @@ libGLESv2.so.2 libgles2 #MINVER#
glDetachShader@Base 0
glDisable@Base 0
glDisableVertexAttribArray@Base 0
+ glDisablei@Base 1.0.0
+ glDispatchCompute@Base 1.0.0
+ glDispatchComputeIndirect@Base 1.0.0
glDrawArrays@Base 0
+ glDrawArraysIndirect@Base 1.0.0
glDrawArraysInstanced@Base 0
glDrawBuffers@Base 0
glDrawElements@Base 0
+ glDrawElementsBaseVertex@Base 1.0.0
+ glDrawElementsIndirect@Base 1.0.0
glDrawElementsInstanced@Base 0
+ glDrawElementsInstancedBaseVertex@Base 1.0.0
glDrawRangeElements@Base 0
+ glDrawRangeElementsBaseVertex@Base 1.0.0
glEnable@Base 0
+ glEnablei@Base 1.0.0
glEnableVertexAttribArray@Base 0
glEndQuery@Base 0
glEndTransformFeedback@Base 0
@@ -75,12 +100,15 @@ libGLESv2.so.2 libgles2 #MINVER#
glFinish@Base 0
glFlush@Base 0
glFlushMappedBufferRange@Base 0
+ glFramebufferParameteri@Base 1.0.0
glFramebufferRenderbuffer@Base 0
glFramebufferTexture2D@Base 0
+ glFramebufferTexture@Base 1.0.0
glFramebufferTextureLayer@Base 0
glFrontFace@Base 0
glGenBuffers@Base 0
glGenFramebuffers@Base 0
+ glGenProgramPipelines@Base 1.0.0
glGenQueries@Base 0
glGenRenderbuffers@Base 0
glGenSamplers@Base 0
@@ -95,25 +123,42 @@ libGLESv2.so.2 libgles2 #MINVER#
glGetActiveUniformsiv@Base 0
glGetAttachedShaders@Base 0
glGetAttribLocation@Base 0
+ glGetBooleani_v@Base 1.0.0
glGetBooleanv@Base 0
glGetBufferParameteri64v@Base 0
glGetBufferParameteriv@Base 0
glGetBufferPointerv@Base 0
+ glGetDebugMessageLog@Base 1.0.0
glGetError@Base 0
glGetFloatv@Base 0
glGetFragDataLocation@Base 0
glGetFramebufferAttachmentParameteriv@Base 0
+ glGetFramebufferParameteriv@Base 1.0.0
+ glGetGraphicsResetStatus@Base 1.0.0
glGetInteger64i_v@Base 0
glGetInteger64v@Base 0
glGetIntegeri_v@Base 0
glGetIntegerv@Base 0
glGetInternalformativ@Base 0
+ glGetMultisamplefv@Base 1.0.0
+ glGetObjectLabel@Base 1.0.0
+ glGetObjectPtrLabel@Base 1.0.0
+ glGetPointerv@Base 1.0.0
glGetProgramBinary@Base 0
glGetProgramInfoLog@Base 0
+ glGetProgramInterfaceiv@Base 1.0.0
+ glGetProgramPipelineInfoLog@Base 1.0.0
+ glGetProgramPipelineiv@Base 1.0.0
+ glGetProgramResourceIndex@Base 1.0.0
+ glGetProgramResourceLocation@Base 1.0.0
+ glGetProgramResourceName@Base 1.0.0
+ glGetProgramResourceiv@Base 1.0.0
glGetProgramiv@Base 0
glGetQueryObjectuiv@Base 0
glGetQueryiv@Base 0
glGetRenderbufferParameteriv@Base 0
+ glGetSamplerParameterIiv@Base 1.0.0
+ glGetSamplerParameterIuiv@Base 1.0.0
glGetSamplerParameterfv@Base 0
glGetSamplerParameteriv@Base 0
glGetShaderInfoLog@Base 0
@@ -123,6 +168,10 @@ libGLESv2.so.2 libgles2 #MINVER#
glGetString@Base 0
glGetStringi@Base 0
glGetSynciv@Base 0
+ glGetTexLevelParameterfv@Base 1.0.0
+ glGetTexLevelParameteriv@Base 1.0.0
+ glGetTexParameterIiv@Base 1.0.0
+ glGetTexParameterIuiv@Base 1.0.0
glGetTexParameterfv@Base 0
glGetTexParameteriv@Base 0
glGetTransformFeedbackVarying@Base 0
@@ -137,13 +186,18 @@ libGLESv2.so.2 libgles2 #MINVER#
glGetVertexAttribPointerv@Base 0
glGetVertexAttribfv@Base 0
glGetVertexAttribiv@Base 0
+ glGetnUniformfv@Base 1.0.0
+ glGetnUniformiv@Base 1.0.0
+ glGetnUniformuiv@Base 1.0.0
glHint@Base 0
glInvalidateFramebuffer@Base 0
glInvalidateSubFramebuffer@Base 0
glIsBuffer@Base 0
glIsEnabled@Base 0
+ glIsEnabledi@Base 1.0.0
glIsFramebuffer@Base 0
glIsProgram@Base 0
+ glIsProgramPipeline@Base 1.0.0
glIsQuery@Base 0
glIsRenderbuffer@Base 0
glIsSampler@Base 0
@@ -155,18 +209,64 @@ libGLESv2.so.2 libgles2 #MINVER#
glLineWidth@Base 0
glLinkProgram@Base 0
glMapBufferRange@Base 0
+ glMemoryBarrier@Base 1.0.0
+ glMemoryBarrierByRegion@Base 1.0.0
+ glMinSampleShading@Base 1.0.0
+ glObjectLabel@Base 1.0.0
+ glObjectPtrLabel@Base 1.0.0
+ glPatchParameteri@Base 1.0.0
glPauseTransformFeedback@Base 0
glPixelStorei@Base 0
glPolygonOffset@Base 0
+ glPopDebugGroup@Base 1.0.0
+ glPrimitiveBoundingBox@Base 1.0.0
glProgramBinary@Base 0
glProgramParameteri@Base 0
+ glProgramUniform1f@Base 1.0.0
+ glProgramUniform1fv@Base 1.0.0
+ glProgramUniform1i@Base 1.0.0
+ glProgramUniform1iv@Base 1.0.0
+ glProgramUniform1ui@Base 1.0.0
+ glProgramUniform1uiv@Base 1.0.0
+ glProgramUniform2f@Base 1.0.0
+ glProgramUniform2fv@Base 1.0.0
+ glProgramUniform2i@Base 1.0.0
+ glProgramUniform2iv@Base 1.0.0
+ glProgramUniform2ui@Base 1.0.0
+ glProgramUniform2uiv@Base 1.0.0
+ glProgramUniform3f@Base 1.0.0
+ glProgramUniform3fv@Base 1.0.0
+ glProgramUniform3i@Base 1.0.0
+ glProgramUniform3iv@Base 1.0.0
+ glProgramUniform3ui@Base 1.0.0
+ glProgramUniform3uiv@Base 1.0.0
+ glProgramUniform4f@Base 1.0.0
+ glProgramUniform4fv@Base 1.0.0
+ glProgramUniform4i@Base 1.0.0
+ glProgramUniform4iv@Base 1.0.0
+ glProgramUniform4ui@Base 1.0.0
+ glProgramUniform4uiv@Base 1.0.0
+ glProgramUniformMatrix2fv@Base 1.0.0
+ glProgramUniformMatrix2x3fv@Base 1.0.0
+ glProgramUniformMatrix2x4fv@Base 1.0.0
+ glProgramUniformMatrix3fv@Base 1.0.0
+ glProgramUniformMatrix3x2fv@Base 1.0.0
+ glProgramUniformMatrix3x4fv@Base 1.0.0
+ glProgramUniformMatrix4fv@Base 1.0.0
+ glProgramUniformMatrix4x2fv@Base 1.0.0
+ glProgramUniformMatrix4x3fv@Base 1.0.0
+ glPushDebugGroup@Base 1.0.0
glReadBuffer@Base 0
glReadPixels@Base 0
+ glReadnPixels@Base 1.0.0
glReleaseShaderCompiler@Base 0
glRenderbufferStorage@Base 0
glRenderbufferStorageMultisample@Base 0
glResumeTransformFeedback@Base 0
glSampleCoverage@Base 0
+ glSampleMaski@Base 1.0.0
+ glSamplerParameterIiv@Base 1.0.0
+ glSamplerParameterIuiv@Base 1.0.0
glSamplerParameterf@Base 0
glSamplerParameterfv@Base 0
glSamplerParameteri@Base 0
@@ -180,14 +280,20 @@ libGLESv2.so.2 libgles2 #MINVER#
glStencilMaskSeparate@Base 0
glStencilOp@Base 0
glStencilOpSeparate@Base 0
+ glTexBuffer@Base 1.0.0
+ glTexBufferRange@Base 1.0.0
glTexImage2D@Base 0
glTexImage3D@Base 0
+ glTexParameterIiv@Base 1.0.0
+ glTexParameterIuiv@Base 1.0.0
glTexParameterf@Base 0
glTexParameterfv@Base 0
glTexParameteri@Base 0
glTexParameteriv@Base 0
glTexStorage2D@Base 0
+ glTexStorage2DMultisample@Base 1.0.0
glTexStorage3D@Base 0
+ glTexStorage3DMultisample@Base 1.0.0
glTexSubImage2D@Base 0
glTexSubImage3D@Base 0
glTransformFeedbackVaryings@Base 0
@@ -227,7 +333,9 @@ libGLESv2.so.2 libgles2 #MINVER#
glUniformMatrix4x3fv@Base 0
glUnmapBuffer@Base 0
glUseProgram@Base 0
+ glUseProgramStages@Base 1.0.0
glValidateProgram@Base 0
+ glValidateProgramPipeline@Base 1.0.0
glVertexAttrib1f@Base 0
glVertexAttrib1fv@Base 0
glVertexAttrib2f@Base 0
@@ -236,12 +344,16 @@ libGLESv2.so.2 libgles2 #MINVER#
glVertexAttrib3fv@Base 0
glVertexAttrib4f@Base 0
glVertexAttrib4fv@Base 0
+ glVertexAttribBinding@Base 1.0.0
glVertexAttribDivisor@Base 0
+ glVertexAttribFormat@Base 1.0.0
glVertexAttribI4i@Base 0
glVertexAttribI4iv@Base 0
glVertexAttribI4ui@Base 0
glVertexAttribI4uiv@Base 0
+ glVertexAttribIFormat@Base 1.0.0
glVertexAttribIPointer@Base 0
glVertexAttribPointer@Base 0
+ glVertexBindingDivisor@Base 1.0.0
glViewport@Base 0
glWaitSync@Base 0
commit f7a4e545a6a4d6e49170fc11b4f85380132ec17e
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Thu Nov 9 11:36:41 2017 +0200
Add a watch file for uscan.
diff --git a/debian/changelog b/debian/changelog
index b13ff7e..18e2520 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,6 +7,7 @@ libglvnd (1.0.0-1) UNRELEASED; urgency=high
[ Timo Aaltonen ]
* New upstream release.
+ * Add a watch file for uscan.
-- Andreas Boll <andreas.boll.dev@gmail.com> Fri, 20 Oct 2017 11:03:03 +0200
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..b303a95
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,3 @@
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%libglvnd-$1.tar.gz%" \
+https://github.com/NVIDIA/libglvnd/tags (?:.*?/)?v?(\d[\d.]*)\.tar\.gz
commit 1a4ec767c2083e1efa30d2d27eca3ca2292287e3
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Thu Nov 9 11:36:13 2017 +0200
New upstream release.
diff --git a/debian/changelog b/debian/changelog
index 85c22a1..b13ff7e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,13 @@
-libglvnd (0.2.999+git20170802-6) UNRELEASED; urgency=high
+libglvnd (1.0.0-1) UNRELEASED; urgency=high
+ [ Andreas Boll ]
* Add versioned libglvnd0 dependencies (Workaround for #878851).
* Raise Priority to optional.
* Bump standards version to 4.1.1.
+ [ Timo Aaltonen ]
+ * New upstream release.
+
-- Andreas Boll <andreas.boll.dev@gmail.com> Fri, 20 Oct 2017 11:03:03 +0200
libglvnd (0.2.999+git20170802-5) unstable; urgency=medium
commit 005fd3a0c449f809d0128921da8ef6762fecffc9
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date: Thu Nov 2 10:58:38 2017 -0600
Set package version to 1.0.0.
Now that both the EGL and GLX interfaces are defined and stable, set the
package version to 1.0.0.
diff --git a/configure.ac b/configure.ac
index 5443734..56018aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl configure.ac
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
-AC_INIT([libglvnd], [0.2.999], [kbrenneman@nvidia.com])
+AC_INIT([libglvnd], [1.0.0], [kbrenneman@nvidia.com])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
commit e3ab0a24cf35f074ff74365e3feae162c4690c16
Author: Gabríel Arthúr Pétursson <gabriel@system.is>
Date: Sat Oct 7 01:14:38 2017 +0000
Cleanup winsys dispatch index list on EGL mapping teardown
This fixes a memory leak reported by both Valgrind and LeakSanitizer
when libEGL is dlopen()-ed and dlclose()-ed afterwards.
diff --git a/src/EGL/libeglmapping.c b/src/EGL/libeglmapping.c
index d420e88..c736172 100644
--- a/src/EGL/libeglmapping.c
+++ b/src/EGL/libeglmapping.c
@@ -259,6 +259,8 @@ void __eglMappingTeardown(EGLBoolean doReset)
/* Tear down all hashtables used in this file */
LKDHASH_TEARDOWN(__EGLdisplayInfoHash,
__eglDisplayInfoHash, NULL, NULL, EGL_FALSE);
+
+ __glvndWinsysDispatchCleanup();
}
}
commit c2f81ca7ce08cf8eb09f4bf0cd08b86799234843
Author: Gabríel Arthúr Pétursson <gabriel@system.is>
Date: Fri Oct 6 22:39:20 2017 +0000
Fix memory leak in LoadVendorsFromConfigDir
The individual entries allocated by scandir need to be freed too.
diff --git a/src/EGL/libeglvendor.c b/src/EGL/libeglvendor.c
index 88ee060..7b8d6e7 100644
--- a/src/EGL/libeglvendor.c
+++ b/src/EGL/libeglvendor.c
@@ -121,6 +121,7 @@ void LoadVendorsFromConfigDir(const char *dirName)
} else {
fprintf(stderr, "ERROR: Could not allocate vendor library path name\n");
}
+ free(entries[i]);
}
free(entries);
commit 6198bd6ef68f71f60a228906a5ce4c874acf760d
Author: Aaron Plattner <aplattner@nvidia.com>
Date: Wed Sep 13 12:56:57 2017 -0700
Update cJSON to version 1.5.9
Downloaded from https://github.com/DaveGamble/cJSON/releases/tag/v1.5.9
diff --git a/src/util/cJSON.c b/src/util/cJSON.c
index 2bec99d..306bb5b 100644
--- a/src/util/cJSON.c
+++ b/src/util/cJSON.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2009 Dave Gamble
+ Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,10 @@
/* cJSON */
/* JSON parser in C. */
+#ifdef __GNUC__
+#pragma GCC visibility push(default)
+#endif
+
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -30,734 +34,2666 @@
#include <float.h>
#include <limits.h>
#include <ctype.h>
+#include <locale.h>
+
+#ifdef __GNUC__
+#pragma GCC visibility pop
+#endif
+
#include "cJSON.h"
-static const char *ep;
+/* define our own boolean type */
+#define true ((cJSON_bool)1)
+#define false ((cJSON_bool)0)
+
+typedef struct {
+ const unsigned char *json;
+ size_t position;
+} error;
+static error global_error = { NULL, 0 };
+
+CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
+{
+ return (const char*) (global_error.json + global_error.position);
+}
+
+/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
+#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 5) || (CJSON_VERSION_PATCH != 9)
+ #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
+#endif
-const char *cJSON_GetErrorPtr(void) {return ep;}
+CJSON_PUBLIC(const char*) cJSON_Version(void)
+{
+ static char version[15];
+ sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
+
+ return version;
+}
-static int cJSON_strcasecmp(const char *s1,const char *s2)
+/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
+static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
{
- if (!s1) return (s1==s2)?0:1;
- if (!s2) return 1;
- for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
- return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
+ if ((string1 == NULL) || (string2 == NULL))
+ {
+ return 1;
+ }
+
+ if (string1 == string2)
+ {
+ return 0;
+ }
+
+ for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
+ {
+ if (*string1 == '\0')
+ {
+ return 0;
+ }
+ }
+
+ return tolower(*string1) - tolower(*string2);
}
-static void *(*cJSON_malloc)(size_t sz) = malloc;
-static void (*cJSON_free)(void *ptr) = free;
+typedef struct internal_hooks
+{
+ void *(*allocate)(size_t size);
+ void (*deallocate)(void *pointer);
+ void *(*reallocate)(void *pointer, size_t size);
+} internal_hooks;
+
+static internal_hooks global_hooks = { malloc, free, realloc };
-static char* cJSON_strdup(const char* str)
+static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
{
- size_t len;
- char* copy;
+ size_t length = 0;
+ unsigned char *copy = NULL;
+
+ if (string == NULL)
+ {
+ return NULL;
+ }
+
+ length = strlen((const char*)string) + sizeof("");
+ if (!(copy = (unsigned char*)hooks->allocate(length)))
+ {
+ return NULL;
+ }
+ memcpy(copy, string, length);
- len = strlen(str) + 1;
- if (!(copy = (char*)cJSON_malloc(len))) return 0;
- memcpy(copy,str,len);
- return copy;
+ return copy;
}
-void cJSON_InitHooks(cJSON_Hooks* hooks)
+CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
{
- if (!hooks) { /* Reset hooks */
- cJSON_malloc = malloc;
- cJSON_free = free;
+ if (hooks == NULL)
+ {
+ /* Reset hooks */
+ global_hooks.allocate = malloc;
+ global_hooks.deallocate = free;
+ global_hooks.reallocate = realloc;
return;
}
- cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
- cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
+ global_hooks.allocate = malloc;
+ if (hooks->malloc_fn != NULL)
+ {
+ global_hooks.allocate = hooks->malloc_fn;
+ }
+
+ global_hooks.deallocate = free;
+ if (hooks->free_fn != NULL)
+ {
+ global_hooks.deallocate = hooks->free_fn;
+ }
+
+ /* use realloc only if both free and malloc are used */
+ global_hooks.reallocate = NULL;
+ if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
+ {
+ global_hooks.reallocate = realloc;
+ }
}
/* Internal constructor. */
-static cJSON *cJSON_New_Item(void)
+static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
{
- cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
- if (node) memset(node,0,sizeof(cJSON));
- return node;
+ cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
+ if (node)
+ {
+ memset(node, '\0', sizeof(cJSON));
+ }
+
+ return node;
}
/* Delete a cJSON structure. */
-void cJSON_Delete(cJSON *c)
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
+{
+ cJSON *next = NULL;
+ while (item != NULL)
+ {
+ next = item->next;
+ if (!(item->type & cJSON_IsReference) && (item->child != NULL))
+ {
+ cJSON_Delete(item->child);
+ }
+ if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
+ {
+ global_hooks.deallocate(item->valuestring);
+ }
+ if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
+ {
+ global_hooks.deallocate(item->string);
+ }
+ global_hooks.deallocate(item);
+ item = next;
+ }
+}
+
+/* get the decimal point character of the current locale */
+static unsigned char get_decimal_point(void)
{
- cJSON *next;
- while (c)
- {
- next=c->next;
- if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
- if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
- if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
- cJSON_free(c);
- c=next;
- }
+ struct lconv *lconv = localeconv();
+ return (unsigned char) lconv->decimal_point[0];
}
+typedef struct
+{
+ const unsigned char *content;
+ size_t length;
+ size_t offset;
+ size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
+ internal_hooks hooks;
+} parse_buffer;
+
+/* check if the given size is left to read in a given parse buffer (starting with 1) */
+#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
+#define cannot_read(buffer, size) (!can_read(buffer, size))
+/* check if the buffer can be accessed at the given index (starting with 0) */
+#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
+#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
+/* get a pointer to the buffer at the position */
+#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
+
/* Parse the input text to generate a number, and populate the result into item. */
-static const char *parse_number(cJSON *item,const char *num)
+static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
{
- double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+ double number = 0;
+ unsigned char *after_end = NULL;
+ unsigned char number_c_string[64];
+ unsigned char decimal_point = get_decimal_point();
+ size_t i = 0;
+
+ if ((input_buffer == NULL) || (input_buffer->content == NULL))
+ {
+ return false;
+ }
+
+ /* copy the number into a temporary buffer and replace '.' with the decimal point
+ * of the current locale (for strtod)
+ * This also takes care of '\0' not necessarily being available for marking the end of the input */
+ for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
+ {
+ switch (buffer_at_offset(input_buffer)[i])
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '+':
+ case '-':
+ case 'e':
+ case 'E':
+ number_c_string[i] = buffer_at_offset(input_buffer)[i];
+ break;
+
+ case '.':
+ number_c_string[i] = decimal_point;
+ break;
+
+ default:
+ goto loop_end;
+ }
+ }
+loop_end:
+ number_c_string[i] = '\0';
+
+ number = strtod((const char*)number_c_string, (char**)&after_end);
+ if (number_c_string == after_end)
+ {
+ return false; /* parse_error */
+ }
+
+ item->valuedouble = number;
+
+ /* use saturation in case of overflow */
+ if (number >= INT_MAX)
+ {
+ item->valueint = INT_MAX;
+ }
+ else if (number <= INT_MIN)
+ {
+ item->valueint = INT_MIN;
+ }
+ else
+ {
+ item->valueint = (int)number;
+ }
- if (*num=='-') sign=-1,num++; /* Has sign? */
- if (*num=='0') num++; /* is zero */
- if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
- if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
- if (*num=='e' || *num=='E') /* Exponent? */
- { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
- while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
- }
+ item->type = cJSON_Number;
- n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
-
- item->valuedouble=n;
- item->valueint=(int)n;
- item->type=cJSON_Number;
- return num;
+ input_buffer->offset += (size_t)(after_end - number_c_string);
+ return true;
}
-static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; }
+/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
+{
+ if (number >= INT_MAX)
+ {
+ object->valueint = INT_MAX;
+ }
+ else if (number <= INT_MIN)
+ {
+ object->valueint = INT_MIN;
+ }
+ else
+ {
+ object->valueint = (int)number;
+ }
-typedef struct {char *buffer; int length; int offset; } printbuffer;
+ return object->valuedouble = number;
+}
-static char* ensure(printbuffer *p,int needed)
+typedef struct
+{
+ unsigned char *buffer;
+ size_t length;
+ size_t offset;
+ size_t depth; /* current nesting depth (for formatted printing) */
+ cJSON_bool noalloc;
+ cJSON_bool format; /* is this print a formatted print */
+ internal_hooks hooks;
+} printbuffer;
+
+/* realloc printbuffer if necessary to have at least "needed" bytes more */
+static unsigned char* ensure(printbuffer * const p, size_t needed)
{
- char *newbuffer;int newsize;
- if (!p || !p->buffer) return 0;
- needed+=p->offset;
- if (needed<=p->length) return p->buffer+p->offset;
+ unsigned char *newbuffer = NULL;
+ size_t newsize = 0;
+
+ if ((p == NULL) || (p->buffer == NULL))
+ {
+ return NULL;
+ }
+
+ if ((p->length > 0) && (p->offset >= p->length))
+ {
+ /* make sure that offset is valid */
+ return NULL;
+ }
+
+ if (needed > INT_MAX)
+ {
+ /* sizes bigger than INT_MAX are currently not supported */
+ return NULL;
+ }
+
+ needed += p->offset + 1;
+ if (needed <= p->length)
+ {
+ return p->buffer + p->offset;
+ }
+
+ if (p->noalloc) {
+ return NULL;
+ }
+
+ /* calculate new buffer size */
+ if (needed > (INT_MAX / 2))
+ {
+ /* overflow of int, use INT_MAX if possible */
+ if (needed <= INT_MAX)
+ {
+ newsize = INT_MAX;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ newsize = needed * 2;
+ }
+
+ if (p->hooks.reallocate != NULL)
+ {
+ /* reallocate with realloc if available */
+ newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
+ if (newbuffer == NULL)
+ {
+ p->hooks.deallocate(p->buffer);
+ p->length = 0;
+ p->buffer = NULL;
+
+ return NULL;
+ }
+ }
+ else
+ {
+ /* otherwise reallocate manually */
+ newbuffer = (unsigned char*)p->hooks.allocate(newsize);
+ if (!newbuffer)
+ {
+ p->hooks.deallocate(p->buffer);
+ p->length = 0;
+ p->buffer = NULL;
+
+ return NULL;
+ }
+ if (newbuffer)
+ {
+ memcpy(newbuffer, p->buffer, p->offset + 1);
+ }
+ p->hooks.deallocate(p->buffer);
+ }
+ p->length = newsize;
+ p->buffer = newbuffer;
- newsize=pow2gt(needed);
- newbuffer=(char*)cJSON_malloc(newsize);
- if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
- if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
- cJSON_free(p->buffer);
- p->length=newsize;
- p->buffer=newbuffer;
- return newbuffer+p->offset;
+ return newbuffer + p->offset;
}
-static int update(printbuffer *p)
+/* calculate the new length of the string in a printbuffer and update the offset */
+static void update_offset(printbuffer * const buffer)
{
- char *str;
- if (!p || !p->buffer) return 0;
- str=p->buffer+p->offset;
- return p->offset+strlen(str);
+ const unsigned char *buffer_pointer = NULL;
+ if ((buffer == NULL) || (buffer->buffer == NULL))
+ {
+ return;
+ }
+ buffer_pointer = buffer->buffer + buffer->offset;
+
+ buffer->offset += strlen((const char*)buffer_pointer);
}
/* Render the number nicely from the given item into a string. */
-static char *print_number(cJSON *item,printbuffer *p)
-{
- char *str=0;
- double d=item->valuedouble;
- if (d==0)
- {
- if (p) str=ensure(p,2);
- else str=(char*)cJSON_malloc(2); /* special case for 0. */
- if (str) strcpy(str,"0");
- }
- else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
- {
- if (p) str=ensure(p,21);
- else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
- if (str) sprintf(str,"%d",item->valueint);
- }
- else
- {
Reply to: