Fossil SCM
upstream cson fix: output chars >0xffff as UTF16 surrogate pairs.
Commit
5280dbc91997819b4b566c6ce7b3eb14e6c3c710
Parent
66c3bc159d4caa9…
2 files changed
+22
-8
+35
-11
+22
-8
| --- src/cson_amalgamation.c | ||
| +++ src/cson_amalgamation.c | ||
| @@ -30,11 +30,11 @@ | ||
| 30 | 30 | /* Determine the integer type use to parse non-floating point numbers */ |
| 31 | 31 | #ifdef _WIN32 |
| 32 | 32 | typedef __int64 JSON_int_t; |
| 33 | 33 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%I64d" |
| 34 | 34 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%I64d" |
| 35 | -#elif __STDC_VERSION__ >= 199901L || HAVE_LONG_LONG == 1 | |
| 35 | +#elif (__STDC_VERSION__ >= 199901L) || (HAVE_LONG_LONG == 1) | |
| 36 | 36 | typedef long long JSON_int_t; |
| 37 | 37 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%lld" |
| 38 | 38 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%lld" |
| 39 | 39 | #else |
| 40 | 40 | typedef long JSON_int_t; |
| @@ -3787,11 +3787,11 @@ | ||
| 3787 | 3787 | unsigned char const * end = (unsigned char const *)(str ? (str + len) : NULL); |
| 3788 | 3788 | unsigned char const * next = NULL; |
| 3789 | 3789 | int ch; |
| 3790 | 3790 | unsigned char clen = 0; |
| 3791 | 3791 | char escChar[3] = {'\\',0,0}; |
| 3792 | - enum { UBLen = 8 }; | |
| 3792 | + enum { UBLen = 13 }; | |
| 3793 | 3793 | char ubuf[UBLen]; |
| 3794 | 3794 | int rc = 0; |
| 3795 | 3795 | rc = f(state, "\"", 1 ); |
| 3796 | 3796 | for( ; (pos < end) && (0 == rc); pos += clen ) |
| 3797 | 3797 | { |
| @@ -3879,17 +3879,31 @@ | ||
| 3879 | 3879 | { /* UTF: transform it to \uXXXX */ |
| 3880 | 3880 | #if defined(CSON_FOSSIL_MODE) |
| 3881 | 3881 | assume_latin1: |
| 3882 | 3882 | #endif |
| 3883 | 3883 | memset(ubuf,0,UBLen); |
| 3884 | - rc = sprintf(ubuf, "\\u%04x",ch); | |
| 3885 | - if( rc != 6 ) | |
| 3886 | - { | |
| 3887 | - rc = cson_rc.RangeError; | |
| 3888 | - break; | |
| 3884 | + if(ch <= 0xFFFF){ | |
| 3885 | + rc = sprintf(ubuf, "\\u%04x",ch); | |
| 3886 | + if( rc != 6 ) | |
| 3887 | + { | |
| 3888 | + rc = cson_rc.RangeError; | |
| 3889 | + break; | |
| 3890 | + } | |
| 3891 | + rc = f( state, ubuf, 6 ); | |
| 3892 | + }else{ /* encode as a UTF16 surrugate pair */ | |
| 3893 | + /* http://unicodebook.readthedocs.org/en/latest/unicode_encodings.html#surrogates */ | |
| 3894 | + ch -= 0x10000; | |
| 3895 | + rc = sprintf(ubuf, "\\u%04x\\u%04x", | |
| 3896 | + (0xd800 | (ch>>10)), | |
| 3897 | + (0xdc00 | (ch & 0x3ff))); | |
| 3898 | + if( rc != 12 ) | |
| 3899 | + { | |
| 3900 | + rc = cson_rc.RangeError; | |
| 3901 | + break; | |
| 3902 | + } | |
| 3903 | + rc = f( state, ubuf, 12 ); | |
| 3889 | 3904 | } |
| 3890 | - rc = f( state, ubuf, 6 ); | |
| 3891 | 3905 | continue; |
| 3892 | 3906 | } |
| 3893 | 3907 | } |
| 3894 | 3908 | if( 0 == rc ) |
| 3895 | 3909 | { |
| 3896 | 3910 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -30,11 +30,11 @@ | |
| 30 | /* Determine the integer type use to parse non-floating point numbers */ |
| 31 | #ifdef _WIN32 |
| 32 | typedef __int64 JSON_int_t; |
| 33 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%I64d" |
| 34 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%I64d" |
| 35 | #elif __STDC_VERSION__ >= 199901L || HAVE_LONG_LONG == 1 |
| 36 | typedef long long JSON_int_t; |
| 37 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%lld" |
| 38 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%lld" |
| 39 | #else |
| 40 | typedef long JSON_int_t; |
| @@ -3787,11 +3787,11 @@ | |
| 3787 | unsigned char const * end = (unsigned char const *)(str ? (str + len) : NULL); |
| 3788 | unsigned char const * next = NULL; |
| 3789 | int ch; |
| 3790 | unsigned char clen = 0; |
| 3791 | char escChar[3] = {'\\',0,0}; |
| 3792 | enum { UBLen = 8 }; |
| 3793 | char ubuf[UBLen]; |
| 3794 | int rc = 0; |
| 3795 | rc = f(state, "\"", 1 ); |
| 3796 | for( ; (pos < end) && (0 == rc); pos += clen ) |
| 3797 | { |
| @@ -3879,17 +3879,31 @@ | |
| 3879 | { /* UTF: transform it to \uXXXX */ |
| 3880 | #if defined(CSON_FOSSIL_MODE) |
| 3881 | assume_latin1: |
| 3882 | #endif |
| 3883 | memset(ubuf,0,UBLen); |
| 3884 | rc = sprintf(ubuf, "\\u%04x",ch); |
| 3885 | if( rc != 6 ) |
| 3886 | { |
| 3887 | rc = cson_rc.RangeError; |
| 3888 | break; |
| 3889 | } |
| 3890 | rc = f( state, ubuf, 6 ); |
| 3891 | continue; |
| 3892 | } |
| 3893 | } |
| 3894 | if( 0 == rc ) |
| 3895 | { |
| 3896 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -30,11 +30,11 @@ | |
| 30 | /* Determine the integer type use to parse non-floating point numbers */ |
| 31 | #ifdef _WIN32 |
| 32 | typedef __int64 JSON_int_t; |
| 33 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%I64d" |
| 34 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%I64d" |
| 35 | #elif (__STDC_VERSION__ >= 199901L) || (HAVE_LONG_LONG == 1) |
| 36 | typedef long long JSON_int_t; |
| 37 | #define JSON_PARSER_INTEGER_SSCANF_TOKEN "%lld" |
| 38 | #define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%lld" |
| 39 | #else |
| 40 | typedef long JSON_int_t; |
| @@ -3787,11 +3787,11 @@ | |
| 3787 | unsigned char const * end = (unsigned char const *)(str ? (str + len) : NULL); |
| 3788 | unsigned char const * next = NULL; |
| 3789 | int ch; |
| 3790 | unsigned char clen = 0; |
| 3791 | char escChar[3] = {'\\',0,0}; |
| 3792 | enum { UBLen = 13 }; |
| 3793 | char ubuf[UBLen]; |
| 3794 | int rc = 0; |
| 3795 | rc = f(state, "\"", 1 ); |
| 3796 | for( ; (pos < end) && (0 == rc); pos += clen ) |
| 3797 | { |
| @@ -3879,17 +3879,31 @@ | |
| 3879 | { /* UTF: transform it to \uXXXX */ |
| 3880 | #if defined(CSON_FOSSIL_MODE) |
| 3881 | assume_latin1: |
| 3882 | #endif |
| 3883 | memset(ubuf,0,UBLen); |
| 3884 | if(ch <= 0xFFFF){ |
| 3885 | rc = sprintf(ubuf, "\\u%04x",ch); |
| 3886 | if( rc != 6 ) |
| 3887 | { |
| 3888 | rc = cson_rc.RangeError; |
| 3889 | break; |
| 3890 | } |
| 3891 | rc = f( state, ubuf, 6 ); |
| 3892 | }else{ /* encode as a UTF16 surrugate pair */ |
| 3893 | /* http://unicodebook.readthedocs.org/en/latest/unicode_encodings.html#surrogates */ |
| 3894 | ch -= 0x10000; |
| 3895 | rc = sprintf(ubuf, "\\u%04x\\u%04x", |
| 3896 | (0xd800 | (ch>>10)), |
| 3897 | (0xdc00 | (ch & 0x3ff))); |
| 3898 | if( rc != 12 ) |
| 3899 | { |
| 3900 | rc = cson_rc.RangeError; |
| 3901 | break; |
| 3902 | } |
| 3903 | rc = f( state, ubuf, 12 ); |
| 3904 | } |
| 3905 | continue; |
| 3906 | } |
| 3907 | } |
| 3908 | if( 0 == rc ) |
| 3909 | { |
| 3910 |
+35
-11
| --- src/cson_amalgamation.h | ||
| +++ src/cson_amalgamation.h | ||
| @@ -67,23 +67,47 @@ | ||
| 67 | 67 | #define CSON_INT_T_PFMT "ld" |
| 68 | 68 | #endif |
| 69 | 69 | |
| 70 | 70 | /** @typedef double_or_long_double cson_double_t |
| 71 | 71 | |
| 72 | -This is the type of double value used by the library. | |
| 73 | -It is only lightly tested with long double, and when using | |
| 74 | -long double the memory requirements for such values goes | |
| 75 | -up. | |
| 72 | + This is the type of double value used by the library. | |
| 73 | + It is only lightly tested with long double, and when using | |
| 74 | + long double the memory requirements for such values goes | |
| 75 | + up. | |
| 76 | + | |
| 77 | + Note that by default cson uses C-API defaults for numeric | |
| 78 | + precision. To use a custom precision throughout the library, one | |
| 79 | + needs to define the macros CSON_DOUBLE_T_SFMT and/or | |
| 80 | + CSON_DOUBLE_T_PFMT macros to include their desired precision, and | |
| 81 | + must build BOTH cson AND the client using these same values. For | |
| 82 | + example: | |
| 83 | + | |
| 84 | + @code | |
| 85 | + #define CSON_DOUBLE_T_PFMT ".8Lf" // for Modified Julian Day values | |
| 86 | + #define HAVE_LONG_DOUBLE | |
| 87 | + @endcode | |
| 88 | + | |
| 89 | + (Only CSON_DOUBLE_T_PFTM should be needed for most | |
| 90 | + purposes.) | |
| 76 | 91 | */ |
| 77 | -#if 0 | |
| 78 | -typedef long double cson_double_t; | |
| 79 | -#define CSON_DOUBLE_T_SFMT "Lf" | |
| 80 | -#define CSON_DOUBLE_T_PFMT "Lf" | |
| 92 | + | |
| 93 | +#if defined(HAVE_LONG_DOUBLE) | |
| 94 | + typedef long double cson_double_t; | |
| 95 | +# ifndef CSON_DOUBLE_T_SFMT | |
| 96 | +# define CSON_DOUBLE_T_SFMT "Lf" | |
| 97 | +# endif | |
| 98 | +# ifndef CSON_DOUBLE_T_PFMT | |
| 99 | +# define CSON_DOUBLE_T_PFMT "Lf" | |
| 100 | +# endif | |
| 81 | 101 | #else |
| 82 | -typedef double cson_double_t; | |
| 83 | -#define CSON_DOUBLE_T_SFMT "f" | |
| 84 | -#define CSON_DOUBLE_T_PFMT "f" | |
| 102 | + typedef double cson_double_t; | |
| 103 | +# ifndef CSON_DOUBLE_T_SFMT | |
| 104 | +# define CSON_DOUBLE_T_SFMT "f" | |
| 105 | +# endif | |
| 106 | +# ifndef CSON_DOUBLE_T_PFMT | |
| 107 | +# define CSON_DOUBLE_T_PFMT "f" | |
| 108 | +# endif | |
| 85 | 109 | #endif |
| 86 | 110 | |
| 87 | 111 | /** @def CSON_VOID_PTR_IS_BIG |
| 88 | 112 | |
| 89 | 113 | ONLY define this to a true value if you know that |
| 90 | 114 |
| --- src/cson_amalgamation.h | |
| +++ src/cson_amalgamation.h | |
| @@ -67,23 +67,47 @@ | |
| 67 | #define CSON_INT_T_PFMT "ld" |
| 68 | #endif |
| 69 | |
| 70 | /** @typedef double_or_long_double cson_double_t |
| 71 | |
| 72 | This is the type of double value used by the library. |
| 73 | It is only lightly tested with long double, and when using |
| 74 | long double the memory requirements for such values goes |
| 75 | up. |
| 76 | */ |
| 77 | #if 0 |
| 78 | typedef long double cson_double_t; |
| 79 | #define CSON_DOUBLE_T_SFMT "Lf" |
| 80 | #define CSON_DOUBLE_T_PFMT "Lf" |
| 81 | #else |
| 82 | typedef double cson_double_t; |
| 83 | #define CSON_DOUBLE_T_SFMT "f" |
| 84 | #define CSON_DOUBLE_T_PFMT "f" |
| 85 | #endif |
| 86 | |
| 87 | /** @def CSON_VOID_PTR_IS_BIG |
| 88 | |
| 89 | ONLY define this to a true value if you know that |
| 90 |
| --- src/cson_amalgamation.h | |
| +++ src/cson_amalgamation.h | |
| @@ -67,23 +67,47 @@ | |
| 67 | #define CSON_INT_T_PFMT "ld" |
| 68 | #endif |
| 69 | |
| 70 | /** @typedef double_or_long_double cson_double_t |
| 71 | |
| 72 | This is the type of double value used by the library. |
| 73 | It is only lightly tested with long double, and when using |
| 74 | long double the memory requirements for such values goes |
| 75 | up. |
| 76 | |
| 77 | Note that by default cson uses C-API defaults for numeric |
| 78 | precision. To use a custom precision throughout the library, one |
| 79 | needs to define the macros CSON_DOUBLE_T_SFMT and/or |
| 80 | CSON_DOUBLE_T_PFMT macros to include their desired precision, and |
| 81 | must build BOTH cson AND the client using these same values. For |
| 82 | example: |
| 83 | |
| 84 | @code |
| 85 | #define CSON_DOUBLE_T_PFMT ".8Lf" // for Modified Julian Day values |
| 86 | #define HAVE_LONG_DOUBLE |
| 87 | @endcode |
| 88 | |
| 89 | (Only CSON_DOUBLE_T_PFTM should be needed for most |
| 90 | purposes.) |
| 91 | */ |
| 92 | |
| 93 | #if defined(HAVE_LONG_DOUBLE) |
| 94 | typedef long double cson_double_t; |
| 95 | # ifndef CSON_DOUBLE_T_SFMT |
| 96 | # define CSON_DOUBLE_T_SFMT "Lf" |
| 97 | # endif |
| 98 | # ifndef CSON_DOUBLE_T_PFMT |
| 99 | # define CSON_DOUBLE_T_PFMT "Lf" |
| 100 | # endif |
| 101 | #else |
| 102 | typedef double cson_double_t; |
| 103 | # ifndef CSON_DOUBLE_T_SFMT |
| 104 | # define CSON_DOUBLE_T_SFMT "f" |
| 105 | # endif |
| 106 | # ifndef CSON_DOUBLE_T_PFMT |
| 107 | # define CSON_DOUBLE_T_PFMT "f" |
| 108 | # endif |
| 109 | #endif |
| 110 | |
| 111 | /** @def CSON_VOID_PTR_IS_BIG |
| 112 | |
| 113 | ONLY define this to a true value if you know that |
| 114 |