Fossil SCM
Pulled in latest upstream cson, which includes a workaround for an encoding-related problem reported by Matt Welland. The JSON i-tests run with this change, but it is not pretty.
Commit
aa6c2b1eb7ab60c079daad14e0959705aae74af5
Parent
1b0a259301bb19e…
1 file changed
+37
-9
+37
-9
| --- src/cson_amalgamation.c | ||
| +++ src/cson_amalgamation.c | ||
| @@ -1576,14 +1576,29 @@ | ||
| 1576 | 1576 | }; |
| 1577 | 1577 | #define cson_string_empty_m {0/*length*/} |
| 1578 | 1578 | static const cson_string cson_string_empty = cson_string_empty_m; |
| 1579 | 1579 | |
| 1580 | 1580 | |
| 1581 | - | |
| 1581 | +/** | |
| 1582 | + Assumes V is a (cson_value*) ans V->value is a (T*). Returns | |
| 1583 | + V->value cast to a (T*). | |
| 1584 | +*/ | |
| 1582 | 1585 | #define CSON_CAST(T,V) ((T*)((V)->value)) |
| 1586 | +/** | |
| 1587 | + Assumes V is a pointer to memory which is allocated as part of a | |
| 1588 | + cson_value instance (the bytes immediately after that part). | |
| 1589 | + Returns a pointer a a cson_value by subtracting sizeof(cson_value) | |
| 1590 | + from that address and casting it to a (cson_value*) | |
| 1591 | +*/ | |
| 1583 | 1592 | #define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value))) |
| 1584 | 1593 | |
| 1594 | +/** | |
| 1595 | + CSON_INT(V) assumes that V is a (cson_value*) of type | |
| 1596 | + CSON_TYPE_INTEGER. This macro returns a (cson_int_t*) representing | |
| 1597 | + its value (how that is stored depends on whether we are running in | |
| 1598 | + 32- or 64-bit mode). | |
| 1599 | + */ | |
| 1585 | 1600 | #if CSON_VOID_PTR_IS_BIG |
| 1586 | 1601 | # define CSON_INT(V) ((cson_int_t*)(&((V)->value))) |
| 1587 | 1602 | #else |
| 1588 | 1603 | # define CSON_INT(V) ((cson_int_t*)(V)->value) |
| 1589 | 1604 | #endif |
| @@ -1592,14 +1607,12 @@ | ||
| 1592 | 1607 | #define CSON_STR(V) CSON_CAST(cson_string,(V)) |
| 1593 | 1608 | #define CSON_OBJ(V) CSON_CAST(cson_object,(V)) |
| 1594 | 1609 | #define CSON_ARRAY(V) CSON_CAST(cson_array,(V)) |
| 1595 | 1610 | |
| 1596 | 1611 | /** |
| 1597 | - | |
| 1598 | 1612 | Holds special shared "constant" (though they are non-const) |
| 1599 | - values. | |
| 1600 | - | |
| 1613 | + values. | |
| 1601 | 1614 | */ |
| 1602 | 1615 | static struct CSON_EMPTY_HOLDER_ |
| 1603 | 1616 | { |
| 1604 | 1617 | char trueValue; |
| 1605 | 1618 | cson_string stringValue; |
| @@ -1809,11 +1822,11 @@ | ||
| 1809 | 1822 | Frees any resources owned by val, but does not free val itself |
| 1810 | 1823 | (which may be stack-allocated). If !val or val->api or |
| 1811 | 1824 | val->api->cleanup are NULL then this is a no-op. |
| 1812 | 1825 | |
| 1813 | 1826 | If v is a container type (object or array) its children are also |
| 1814 | - cleaned up (BUT NOT FREED), recursively. | |
| 1827 | + cleaned up, recursively. | |
| 1815 | 1828 | |
| 1816 | 1829 | After calling this, val will have the special "undefined" type. |
| 1817 | 1830 | */ |
| 1818 | 1831 | static void cson_value_clean( cson_value * val ); |
| 1819 | 1832 | |
| @@ -1889,11 +1902,11 @@ | ||
| 1889 | 1902 | |
| 1890 | 1903 | |
| 1891 | 1904 | /** |
| 1892 | 1905 | Fetches v's string value as a non-const string. |
| 1893 | 1906 | |
| 1894 | - cson_strings are supposed to be immutable, but this form provides | |
| 1907 | + cson_strings are intended to be immutable, but this form provides | |
| 1895 | 1908 | access to the immutable bits, which are v->length bytes long. A |
| 1896 | 1909 | length-0 string is returned as NULL from here, as opposed to |
| 1897 | 1910 | "". (This is a side-effect of the string allocation mechanism.) |
| 1898 | 1911 | Returns NULL if !v or if v is the internal empty-string singleton. |
| 1899 | 1912 | */ |
| @@ -3781,10 +3794,22 @@ | ||
| 3781 | 3794 | assert( next > pos ); |
| 3782 | 3795 | clen = next - pos; |
| 3783 | 3796 | assert( clen ); |
| 3784 | 3797 | if( 1 == clen ) |
| 3785 | 3798 | { /* ASCII */ |
| 3799 | +#if defined(CSON_FOSSIL_MODE) | |
| 3800 | + /* Workaround for fossil repo artifact | |
| 3801 | + f460839cff85d4e4f1360b366bb2858cef1411ea, | |
| 3802 | + which has what appears to be latin1-encoded | |
| 3803 | + text. file(1) thinks it's a FORTRAN program. | |
| 3804 | + */ | |
| 3805 | + if((*pos != ch) && (0xfffd==ch)){ | |
| 3806 | + ch = *pos; | |
| 3807 | + /* MARKER("ch=%04x, *pos=%04x\n", ch, *pos); */ | |
| 3808 | + goto two_bytes; | |
| 3809 | + } | |
| 3810 | +#endif | |
| 3786 | 3811 | assert( *pos == ch ); |
| 3787 | 3812 | escChar[1] = 0; |
| 3788 | 3813 | switch(ch) |
| 3789 | 3814 | { |
| 3790 | 3815 | case '\t': escChar[1] = 't'; break; |
| @@ -3836,10 +3861,13 @@ | ||
| 3836 | 3861 | } |
| 3837 | 3862 | continue; |
| 3838 | 3863 | } |
| 3839 | 3864 | else |
| 3840 | 3865 | { /* UTF: transform it to \uXXXX */ |
| 3866 | +#if defined(CSON_FOSSIL_MODE) | |
| 3867 | + two_bytes: | |
| 3868 | +#endif | |
| 3841 | 3869 | memset(ubuf,0,UBLen); |
| 3842 | 3870 | rc = sprintf(ubuf, "\\u%04x",ch); |
| 3843 | 3871 | if( rc != 6 ) |
| 3844 | 3872 | { |
| 3845 | 3873 | rc = cson_rc.RangeError; |
| @@ -4105,11 +4133,11 @@ | ||
| 4105 | 4133 | rc = f(state, ",", 1); |
| 4106 | 4134 | if( 0 == rc ) |
| 4107 | 4135 | { |
| 4108 | 4136 | rc = doIndent |
| 4109 | 4137 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4110 | - : f( state, " ", 1 ); | |
| 4138 | + : 0 /*f( state, " ", 1 )*/; | |
| 4111 | 4139 | } |
| 4112 | 4140 | } |
| 4113 | 4141 | } |
| 4114 | 4142 | } |
| 4115 | 4143 | --level; |
| @@ -4183,11 +4211,11 @@ | ||
| 4183 | 4211 | rc = f(state, ",", 1); |
| 4184 | 4212 | if( 0 == rc ) |
| 4185 | 4213 | { |
| 4186 | 4214 | rc = doIndent |
| 4187 | 4215 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4188 | - : f( state, " ", 1 ); | |
| 4216 | + : 0 /*f( state, " ", 1 )*/; | |
| 4189 | 4217 | } |
| 4190 | 4218 | } |
| 4191 | 4219 | } |
| 4192 | 4220 | } |
| 4193 | 4221 | --level; |
| @@ -4396,11 +4424,11 @@ | ||
| 4396 | 4424 | const cson_size_t oldCap = sb->capacity; |
| 4397 | 4425 | const cson_size_t asz = npos * 2; |
| 4398 | 4426 | if( asz < npos ) return cson_rc.ArgError; /* overflow */ |
| 4399 | 4427 | else if( 0 != cson_buffer_reserve( sb, asz ) ) return cson_rc.AllocError; |
| 4400 | 4428 | assert( (sb->capacity > oldCap) && "Internal error in memory buffer management!" ); |
| 4401 | - /* make sure it gets NULL terminated. */ | |
| 4429 | + /* make sure it gets NUL terminated. */ | |
| 4402 | 4430 | memset( sb->mem + oldCap, 0, (sb->capacity - oldCap) ); |
| 4403 | 4431 | } |
| 4404 | 4432 | for( i = 0; i < n; ++i, ++sb->used ) |
| 4405 | 4433 | { |
| 4406 | 4434 | sb->mem[sb->used] = data[i]; |
| 4407 | 4435 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -1576,14 +1576,29 @@ | |
| 1576 | }; |
| 1577 | #define cson_string_empty_m {0/*length*/} |
| 1578 | static const cson_string cson_string_empty = cson_string_empty_m; |
| 1579 | |
| 1580 | |
| 1581 | |
| 1582 | #define CSON_CAST(T,V) ((T*)((V)->value)) |
| 1583 | #define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value))) |
| 1584 | |
| 1585 | #if CSON_VOID_PTR_IS_BIG |
| 1586 | # define CSON_INT(V) ((cson_int_t*)(&((V)->value))) |
| 1587 | #else |
| 1588 | # define CSON_INT(V) ((cson_int_t*)(V)->value) |
| 1589 | #endif |
| @@ -1592,14 +1607,12 @@ | |
| 1592 | #define CSON_STR(V) CSON_CAST(cson_string,(V)) |
| 1593 | #define CSON_OBJ(V) CSON_CAST(cson_object,(V)) |
| 1594 | #define CSON_ARRAY(V) CSON_CAST(cson_array,(V)) |
| 1595 | |
| 1596 | /** |
| 1597 | |
| 1598 | Holds special shared "constant" (though they are non-const) |
| 1599 | values. |
| 1600 | |
| 1601 | */ |
| 1602 | static struct CSON_EMPTY_HOLDER_ |
| 1603 | { |
| 1604 | char trueValue; |
| 1605 | cson_string stringValue; |
| @@ -1809,11 +1822,11 @@ | |
| 1809 | Frees any resources owned by val, but does not free val itself |
| 1810 | (which may be stack-allocated). If !val or val->api or |
| 1811 | val->api->cleanup are NULL then this is a no-op. |
| 1812 | |
| 1813 | If v is a container type (object or array) its children are also |
| 1814 | cleaned up (BUT NOT FREED), recursively. |
| 1815 | |
| 1816 | After calling this, val will have the special "undefined" type. |
| 1817 | */ |
| 1818 | static void cson_value_clean( cson_value * val ); |
| 1819 | |
| @@ -1889,11 +1902,11 @@ | |
| 1889 | |
| 1890 | |
| 1891 | /** |
| 1892 | Fetches v's string value as a non-const string. |
| 1893 | |
| 1894 | cson_strings are supposed to be immutable, but this form provides |
| 1895 | access to the immutable bits, which are v->length bytes long. A |
| 1896 | length-0 string is returned as NULL from here, as opposed to |
| 1897 | "". (This is a side-effect of the string allocation mechanism.) |
| 1898 | Returns NULL if !v or if v is the internal empty-string singleton. |
| 1899 | */ |
| @@ -3781,10 +3794,22 @@ | |
| 3781 | assert( next > pos ); |
| 3782 | clen = next - pos; |
| 3783 | assert( clen ); |
| 3784 | if( 1 == clen ) |
| 3785 | { /* ASCII */ |
| 3786 | assert( *pos == ch ); |
| 3787 | escChar[1] = 0; |
| 3788 | switch(ch) |
| 3789 | { |
| 3790 | case '\t': escChar[1] = 't'; break; |
| @@ -3836,10 +3861,13 @@ | |
| 3836 | } |
| 3837 | continue; |
| 3838 | } |
| 3839 | else |
| 3840 | { /* UTF: transform it to \uXXXX */ |
| 3841 | memset(ubuf,0,UBLen); |
| 3842 | rc = sprintf(ubuf, "\\u%04x",ch); |
| 3843 | if( rc != 6 ) |
| 3844 | { |
| 3845 | rc = cson_rc.RangeError; |
| @@ -4105,11 +4133,11 @@ | |
| 4105 | rc = f(state, ",", 1); |
| 4106 | if( 0 == rc ) |
| 4107 | { |
| 4108 | rc = doIndent |
| 4109 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4110 | : f( state, " ", 1 ); |
| 4111 | } |
| 4112 | } |
| 4113 | } |
| 4114 | } |
| 4115 | --level; |
| @@ -4183,11 +4211,11 @@ | |
| 4183 | rc = f(state, ",", 1); |
| 4184 | if( 0 == rc ) |
| 4185 | { |
| 4186 | rc = doIndent |
| 4187 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4188 | : f( state, " ", 1 ); |
| 4189 | } |
| 4190 | } |
| 4191 | } |
| 4192 | } |
| 4193 | --level; |
| @@ -4396,11 +4424,11 @@ | |
| 4396 | const cson_size_t oldCap = sb->capacity; |
| 4397 | const cson_size_t asz = npos * 2; |
| 4398 | if( asz < npos ) return cson_rc.ArgError; /* overflow */ |
| 4399 | else if( 0 != cson_buffer_reserve( sb, asz ) ) return cson_rc.AllocError; |
| 4400 | assert( (sb->capacity > oldCap) && "Internal error in memory buffer management!" ); |
| 4401 | /* make sure it gets NULL terminated. */ |
| 4402 | memset( sb->mem + oldCap, 0, (sb->capacity - oldCap) ); |
| 4403 | } |
| 4404 | for( i = 0; i < n; ++i, ++sb->used ) |
| 4405 | { |
| 4406 | sb->mem[sb->used] = data[i]; |
| 4407 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -1576,14 +1576,29 @@ | |
| 1576 | }; |
| 1577 | #define cson_string_empty_m {0/*length*/} |
| 1578 | static const cson_string cson_string_empty = cson_string_empty_m; |
| 1579 | |
| 1580 | |
| 1581 | /** |
| 1582 | Assumes V is a (cson_value*) ans V->value is a (T*). Returns |
| 1583 | V->value cast to a (T*). |
| 1584 | */ |
| 1585 | #define CSON_CAST(T,V) ((T*)((V)->value)) |
| 1586 | /** |
| 1587 | Assumes V is a pointer to memory which is allocated as part of a |
| 1588 | cson_value instance (the bytes immediately after that part). |
| 1589 | Returns a pointer a a cson_value by subtracting sizeof(cson_value) |
| 1590 | from that address and casting it to a (cson_value*) |
| 1591 | */ |
| 1592 | #define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value))) |
| 1593 | |
| 1594 | /** |
| 1595 | CSON_INT(V) assumes that V is a (cson_value*) of type |
| 1596 | CSON_TYPE_INTEGER. This macro returns a (cson_int_t*) representing |
| 1597 | its value (how that is stored depends on whether we are running in |
| 1598 | 32- or 64-bit mode). |
| 1599 | */ |
| 1600 | #if CSON_VOID_PTR_IS_BIG |
| 1601 | # define CSON_INT(V) ((cson_int_t*)(&((V)->value))) |
| 1602 | #else |
| 1603 | # define CSON_INT(V) ((cson_int_t*)(V)->value) |
| 1604 | #endif |
| @@ -1592,14 +1607,12 @@ | |
| 1607 | #define CSON_STR(V) CSON_CAST(cson_string,(V)) |
| 1608 | #define CSON_OBJ(V) CSON_CAST(cson_object,(V)) |
| 1609 | #define CSON_ARRAY(V) CSON_CAST(cson_array,(V)) |
| 1610 | |
| 1611 | /** |
| 1612 | Holds special shared "constant" (though they are non-const) |
| 1613 | values. |
| 1614 | */ |
| 1615 | static struct CSON_EMPTY_HOLDER_ |
| 1616 | { |
| 1617 | char trueValue; |
| 1618 | cson_string stringValue; |
| @@ -1809,11 +1822,11 @@ | |
| 1822 | Frees any resources owned by val, but does not free val itself |
| 1823 | (which may be stack-allocated). If !val or val->api or |
| 1824 | val->api->cleanup are NULL then this is a no-op. |
| 1825 | |
| 1826 | If v is a container type (object or array) its children are also |
| 1827 | cleaned up, recursively. |
| 1828 | |
| 1829 | After calling this, val will have the special "undefined" type. |
| 1830 | */ |
| 1831 | static void cson_value_clean( cson_value * val ); |
| 1832 | |
| @@ -1889,11 +1902,11 @@ | |
| 1902 | |
| 1903 | |
| 1904 | /** |
| 1905 | Fetches v's string value as a non-const string. |
| 1906 | |
| 1907 | cson_strings are intended to be immutable, but this form provides |
| 1908 | access to the immutable bits, which are v->length bytes long. A |
| 1909 | length-0 string is returned as NULL from here, as opposed to |
| 1910 | "". (This is a side-effect of the string allocation mechanism.) |
| 1911 | Returns NULL if !v or if v is the internal empty-string singleton. |
| 1912 | */ |
| @@ -3781,10 +3794,22 @@ | |
| 3794 | assert( next > pos ); |
| 3795 | clen = next - pos; |
| 3796 | assert( clen ); |
| 3797 | if( 1 == clen ) |
| 3798 | { /* ASCII */ |
| 3799 | #if defined(CSON_FOSSIL_MODE) |
| 3800 | /* Workaround for fossil repo artifact |
| 3801 | f460839cff85d4e4f1360b366bb2858cef1411ea, |
| 3802 | which has what appears to be latin1-encoded |
| 3803 | text. file(1) thinks it's a FORTRAN program. |
| 3804 | */ |
| 3805 | if((*pos != ch) && (0xfffd==ch)){ |
| 3806 | ch = *pos; |
| 3807 | /* MARKER("ch=%04x, *pos=%04x\n", ch, *pos); */ |
| 3808 | goto two_bytes; |
| 3809 | } |
| 3810 | #endif |
| 3811 | assert( *pos == ch ); |
| 3812 | escChar[1] = 0; |
| 3813 | switch(ch) |
| 3814 | { |
| 3815 | case '\t': escChar[1] = 't'; break; |
| @@ -3836,10 +3861,13 @@ | |
| 3861 | } |
| 3862 | continue; |
| 3863 | } |
| 3864 | else |
| 3865 | { /* UTF: transform it to \uXXXX */ |
| 3866 | #if defined(CSON_FOSSIL_MODE) |
| 3867 | two_bytes: |
| 3868 | #endif |
| 3869 | memset(ubuf,0,UBLen); |
| 3870 | rc = sprintf(ubuf, "\\u%04x",ch); |
| 3871 | if( rc != 6 ) |
| 3872 | { |
| 3873 | rc = cson_rc.RangeError; |
| @@ -4105,11 +4133,11 @@ | |
| 4133 | rc = f(state, ",", 1); |
| 4134 | if( 0 == rc ) |
| 4135 | { |
| 4136 | rc = doIndent |
| 4137 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4138 | : 0 /*f( state, " ", 1 )*/; |
| 4139 | } |
| 4140 | } |
| 4141 | } |
| 4142 | } |
| 4143 | --level; |
| @@ -4183,11 +4211,11 @@ | |
| 4211 | rc = f(state, ",", 1); |
| 4212 | if( 0 == rc ) |
| 4213 | { |
| 4214 | rc = doIndent |
| 4215 | ? cson_output_indent( f, state, fmt->indentation, level ) |
| 4216 | : 0 /*f( state, " ", 1 )*/; |
| 4217 | } |
| 4218 | } |
| 4219 | } |
| 4220 | } |
| 4221 | --level; |
| @@ -4396,11 +4424,11 @@ | |
| 4424 | const cson_size_t oldCap = sb->capacity; |
| 4425 | const cson_size_t asz = npos * 2; |
| 4426 | if( asz < npos ) return cson_rc.ArgError; /* overflow */ |
| 4427 | else if( 0 != cson_buffer_reserve( sb, asz ) ) return cson_rc.AllocError; |
| 4428 | assert( (sb->capacity > oldCap) && "Internal error in memory buffer management!" ); |
| 4429 | /* make sure it gets NUL terminated. */ |
| 4430 | memset( sb->mem + oldCap, 0, (sb->capacity - oldCap) ); |
| 4431 | } |
| 4432 | for( i = 0; i < n; ++i, ++sb->used ) |
| 4433 | { |
| 4434 | sb->mem[sb->used] = data[i]; |
| 4435 |