sassc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +24 -0
  8. data/Rakefile +21 -0
  9. data/ext/libsass/.editorconfig +15 -0
  10. data/ext/libsass/.gitattributes +2 -0
  11. data/ext/libsass/.gitignore +61 -0
  12. data/ext/libsass/.travis.yml +38 -0
  13. data/ext/libsass/COPYING +25 -0
  14. data/ext/libsass/INSTALL +1 -0
  15. data/ext/libsass/LICENSE +25 -0
  16. data/ext/libsass/Makefile +223 -0
  17. data/ext/libsass/Makefile.am +145 -0
  18. data/ext/libsass/Readme.md +93 -0
  19. data/ext/libsass/appveyor.yml +76 -0
  20. data/ext/libsass/ast.cpp +581 -0
  21. data/ext/libsass/ast.hpp +1949 -0
  22. data/ext/libsass/ast_def_macros.hpp +16 -0
  23. data/ext/libsass/ast_factory.hpp +87 -0
  24. data/ext/libsass/ast_fwd_decl.hpp +72 -0
  25. data/ext/libsass/b64/cencode.h +32 -0
  26. data/ext/libsass/b64/encode.h +77 -0
  27. data/ext/libsass/backtrace.hpp +81 -0
  28. data/ext/libsass/base64vlq.cpp +43 -0
  29. data/ext/libsass/base64vlq.hpp +28 -0
  30. data/ext/libsass/bind.cpp +187 -0
  31. data/ext/libsass/bind.hpp +18 -0
  32. data/ext/libsass/cencode.c +102 -0
  33. data/ext/libsass/color_names.hpp +324 -0
  34. data/ext/libsass/configure.ac +130 -0
  35. data/ext/libsass/constants.cpp +144 -0
  36. data/ext/libsass/constants.hpp +145 -0
  37. data/ext/libsass/context.cpp +507 -0
  38. data/ext/libsass/context.hpp +150 -0
  39. data/ext/libsass/contextualize.cpp +157 -0
  40. data/ext/libsass/contextualize.hpp +65 -0
  41. data/ext/libsass/copy_c_str.cpp +13 -0
  42. data/ext/libsass/copy_c_str.hpp +5 -0
  43. data/ext/libsass/debug.hpp +39 -0
  44. data/ext/libsass/environment.hpp +75 -0
  45. data/ext/libsass/error_handling.cpp +28 -0
  46. data/ext/libsass/error_handling.hpp +28 -0
  47. data/ext/libsass/eval.cpp +1149 -0
  48. data/ext/libsass/eval.hpp +80 -0
  49. data/ext/libsass/expand.cpp +430 -0
  50. data/ext/libsass/expand.hpp +77 -0
  51. data/ext/libsass/extconf.rb +6 -0
  52. data/ext/libsass/extend.cpp +1962 -0
  53. data/ext/libsass/extend.hpp +50 -0
  54. data/ext/libsass/file.cpp +291 -0
  55. data/ext/libsass/file.hpp +18 -0
  56. data/ext/libsass/functions.cpp +1565 -0
  57. data/ext/libsass/functions.hpp +187 -0
  58. data/ext/libsass/inspect.cpp +727 -0
  59. data/ext/libsass/inspect.hpp +108 -0
  60. data/ext/libsass/json.cpp +1411 -0
  61. data/ext/libsass/json.hpp +117 -0
  62. data/ext/libsass/kwd_arg_macros.hpp +23 -0
  63. data/ext/libsass/m4/.gitkeep +0 -0
  64. data/ext/libsass/mapping.hpp +17 -0
  65. data/ext/libsass/memory_manager.hpp +54 -0
  66. data/ext/libsass/node.cpp +251 -0
  67. data/ext/libsass/node.hpp +122 -0
  68. data/ext/libsass/operation.hpp +153 -0
  69. data/ext/libsass/output_compressed.cpp +401 -0
  70. data/ext/libsass/output_compressed.hpp +95 -0
  71. data/ext/libsass/output_nested.cpp +364 -0
  72. data/ext/libsass/output_nested.hpp +108 -0
  73. data/ext/libsass/parser.cpp +2016 -0
  74. data/ext/libsass/parser.hpp +264 -0
  75. data/ext/libsass/paths.hpp +69 -0
  76. data/ext/libsass/position.hpp +22 -0
  77. data/ext/libsass/posix/getopt.c +562 -0
  78. data/ext/libsass/posix/getopt.h +95 -0
  79. data/ext/libsass/prelexer.cpp +688 -0
  80. data/ext/libsass/prelexer.hpp +513 -0
  81. data/ext/libsass/remove_placeholders.cpp +59 -0
  82. data/ext/libsass/remove_placeholders.hpp +43 -0
  83. data/ext/libsass/res/resource.rc +35 -0
  84. data/ext/libsass/sass.cpp +33 -0
  85. data/ext/libsass/sass.h +60 -0
  86. data/ext/libsass/sass2scss.cpp +834 -0
  87. data/ext/libsass/sass2scss.h +110 -0
  88. data/ext/libsass/sass_context.cpp +709 -0
  89. data/ext/libsass/sass_context.h +120 -0
  90. data/ext/libsass/sass_functions.cpp +137 -0
  91. data/ext/libsass/sass_functions.h +90 -0
  92. data/ext/libsass/sass_interface.cpp +277 -0
  93. data/ext/libsass/sass_interface.h +97 -0
  94. data/ext/libsass/sass_util.cpp +136 -0
  95. data/ext/libsass/sass_util.hpp +259 -0
  96. data/ext/libsass/sass_values.cpp +337 -0
  97. data/ext/libsass/sass_values.h +124 -0
  98. data/ext/libsass/script/bootstrap +10 -0
  99. data/ext/libsass/script/branding +10 -0
  100. data/ext/libsass/script/ci-build-libsass +72 -0
  101. data/ext/libsass/script/ci-install-compiler +4 -0
  102. data/ext/libsass/script/ci-install-deps +19 -0
  103. data/ext/libsass/script/ci-report-coverage +25 -0
  104. data/ext/libsass/script/coveralls-debug +32 -0
  105. data/ext/libsass/script/spec +5 -0
  106. data/ext/libsass/script/tap-driver +652 -0
  107. data/ext/libsass/script/tap-runner +1 -0
  108. data/ext/libsass/source_map.cpp +133 -0
  109. data/ext/libsass/source_map.hpp +46 -0
  110. data/ext/libsass/subset_map.hpp +145 -0
  111. data/ext/libsass/support/libsass.pc.in +11 -0
  112. data/ext/libsass/test-driver +127 -0
  113. data/ext/libsass/test/test_node.cpp +98 -0
  114. data/ext/libsass/test/test_paths.cpp +29 -0
  115. data/ext/libsass/test/test_selector_difference.cpp +28 -0
  116. data/ext/libsass/test/test_specificity.cpp +28 -0
  117. data/ext/libsass/test/test_subset_map.cpp +472 -0
  118. data/ext/libsass/test/test_superselector.cpp +71 -0
  119. data/ext/libsass/test/test_unification.cpp +33 -0
  120. data/ext/libsass/to_c.cpp +61 -0
  121. data/ext/libsass/to_c.hpp +44 -0
  122. data/ext/libsass/to_string.cpp +29 -0
  123. data/ext/libsass/to_string.hpp +32 -0
  124. data/ext/libsass/token.hpp +32 -0
  125. data/ext/libsass/units.cpp +54 -0
  126. data/ext/libsass/units.hpp +10 -0
  127. data/ext/libsass/utf8.h +34 -0
  128. data/ext/libsass/utf8/checked.h +327 -0
  129. data/ext/libsass/utf8/core.h +329 -0
  130. data/ext/libsass/utf8/unchecked.h +228 -0
  131. data/ext/libsass/utf8_string.cpp +102 -0
  132. data/ext/libsass/utf8_string.hpp +36 -0
  133. data/ext/libsass/util.cpp +189 -0
  134. data/ext/libsass/util.hpp +26 -0
  135. data/ext/libsass/win/libsass.filters +291 -0
  136. data/ext/libsass/win/libsass.sln +28 -0
  137. data/ext/libsass/win/libsass.vcxproj +255 -0
  138. data/lib/sassc.rb +6 -0
  139. data/lib/sassc/engine.rb +13 -0
  140. data/lib/sassc/native.rb +44 -0
  141. data/lib/sassc/native/native_context_api.rb +140 -0
  142. data/lib/sassc/native/native_functions_api.rb +41 -0
  143. data/lib/sassc/native/sass_input_style.rb +11 -0
  144. data/lib/sassc/native/sass_output_style.rb +10 -0
  145. data/lib/sassc/native/sass_value.rb +95 -0
  146. data/lib/sassc/native/string_list.rb +8 -0
  147. data/lib/sassc/version.rb +3 -0
  148. data/sassc.gemspec +43 -0
  149. data/test/smoke_test.rb +171 -0
  150. data/test/test_helper.rb +4 -0
  151. metadata +281 -0
@@ -0,0 +1,108 @@
1
+ #ifndef SASS_INSPECT
2
+ #define SASS_INSPECT
3
+
4
+ #include <string>
5
+
6
+ #ifndef SASS_OPERATION
7
+ #include "operation.hpp"
8
+ #endif
9
+
10
+ // #ifndef SASS_TO_STRING
11
+ // #include "to_string.hpp"
12
+ // #endif
13
+
14
+ namespace Sass {
15
+ using namespace std;
16
+ struct Context;
17
+
18
+ class Inspect : public Operation_CRTP<void, Inspect> {
19
+ // import all the class-specific methods and override as desired
20
+ using Operation_CRTP<void, Inspect>::operator();
21
+
22
+ // To_String* to_string;
23
+ string buffer;
24
+ size_t indentation;
25
+ Context* ctx;
26
+ void indent();
27
+
28
+ void fallback_impl(AST_Node* n);
29
+
30
+ void append_to_buffer(const string& text);
31
+
32
+ public:
33
+
34
+ Inspect(Context* ctx = 0);
35
+ virtual ~Inspect();
36
+
37
+ string get_buffer() { return buffer; }
38
+
39
+ // statements
40
+ virtual void operator()(Block*);
41
+ virtual void operator()(Ruleset*);
42
+ virtual void operator()(Propset*);
43
+ virtual void operator()(Feature_Block*);
44
+ virtual void operator()(Media_Block*);
45
+ virtual void operator()(At_Rule*);
46
+ virtual void operator()(Declaration*);
47
+ virtual void operator()(Assignment*);
48
+ virtual void operator()(Import*);
49
+ virtual void operator()(Import_Stub*);
50
+ virtual void operator()(Warning*);
51
+ virtual void operator()(Error*);
52
+ virtual void operator()(Debug*);
53
+ virtual void operator()(Comment*);
54
+ virtual void operator()(If*);
55
+ virtual void operator()(For*);
56
+ virtual void operator()(Each*);
57
+ virtual void operator()(While*);
58
+ virtual void operator()(Return*);
59
+ virtual void operator()(Extension*);
60
+ virtual void operator()(Definition*);
61
+ virtual void operator()(Mixin_Call*);
62
+ virtual void operator()(Content*);
63
+ // expressions
64
+ virtual void operator()(Map*);
65
+ virtual void operator()(List*);
66
+ virtual void operator()(Binary_Expression*);
67
+ virtual void operator()(Unary_Expression*);
68
+ virtual void operator()(Function_Call*);
69
+ virtual void operator()(Function_Call_Schema*);
70
+ virtual void operator()(Variable*);
71
+ virtual void operator()(Textual*);
72
+ virtual void operator()(Number*);
73
+ virtual void operator()(Color*);
74
+ virtual void operator()(Boolean*);
75
+ virtual void operator()(String_Schema*);
76
+ virtual void operator()(String_Constant*);
77
+ virtual void operator()(Feature_Query*);
78
+ virtual void operator()(Feature_Query_Condition*);
79
+ virtual void operator()(Media_Query*);
80
+ virtual void operator()(Media_Query_Expression*);
81
+ virtual void operator()(Null*);
82
+ // parameters and arguments
83
+ virtual void operator()(Parameter*);
84
+ virtual void operator()(Parameters*);
85
+ virtual void operator()(Argument*);
86
+ virtual void operator()(Arguments*);
87
+ // selectors
88
+ virtual void operator()(Selector_Schema*);
89
+ virtual void operator()(Selector_Reference*);
90
+ virtual void operator()(Selector_Placeholder*);
91
+ virtual void operator()(Type_Selector*);
92
+ virtual void operator()(Selector_Qualifier*);
93
+ virtual void operator()(Attribute_Selector*);
94
+ virtual void operator()(Pseudo_Selector*);
95
+ virtual void operator()(Wrapped_Selector*);
96
+ virtual void operator()(Compound_Selector*);
97
+ virtual void operator()(Complex_Selector*);
98
+ virtual void operator()(Selector_List*);
99
+
100
+ template <typename U>
101
+ void fallback(U x) { fallback_impl(reinterpret_cast<AST_Node*>(x)); }
102
+ };
103
+
104
+ string unquote(const string&);
105
+ string quote(const string&, char);
106
+
107
+ }
108
+ #endif
@@ -0,0 +1,1411 @@
1
+ /*
2
+ Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)
3
+ All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+ */
23
+
24
+ #include "json.hpp"
25
+
26
+ #include <assert.h>
27
+ #include <stdint.h>
28
+ #include <stdio.h>
29
+ #include <stdlib.h>
30
+ #include <string.h>
31
+
32
+ #ifdef _MSC_VER
33
+
34
+ #include <stdarg.h>
35
+ #define snprintf c99_snprintf
36
+
37
+ inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
38
+ {
39
+ int count = -1;
40
+
41
+ if (size != 0)
42
+ count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
43
+ if (count == -1)
44
+ count = _vscprintf(format, ap);
45
+
46
+ return count;
47
+ }
48
+
49
+ inline int c99_snprintf(char* str, size_t size, const char* format, ...)
50
+ {
51
+ int count;
52
+ va_list ap;
53
+
54
+ va_start(ap, format);
55
+ count = c99_vsnprintf(str, size, format, ap);
56
+ va_end(ap);
57
+
58
+ return count;
59
+ }
60
+ #endif // _MSC_VER
61
+
62
+ #define out_of_memory() do { \
63
+ fprintf(stderr, "Out of memory.\n"); \
64
+ exit(EXIT_FAILURE); \
65
+ } while (0)
66
+
67
+ /* Sadly, strdup is not portable. */
68
+ static char *json_strdup(const char *str)
69
+ {
70
+ char *ret = (char*) malloc(strlen(str) + 1);
71
+ if (ret == NULL)
72
+ out_of_memory();
73
+ strcpy(ret, str);
74
+ return ret;
75
+ }
76
+
77
+ /* String buffer */
78
+
79
+ typedef struct
80
+ {
81
+ char *cur;
82
+ char *end;
83
+ char *start;
84
+ } SB;
85
+
86
+ static void sb_init(SB *sb)
87
+ {
88
+ sb->start = (char*) malloc(17);
89
+ if (sb->start == NULL)
90
+ out_of_memory();
91
+ sb->cur = sb->start;
92
+ sb->end = sb->start + 16;
93
+ }
94
+
95
+ /* sb and need may be evaluated multiple times. */
96
+ #define sb_need(sb, need) do { \
97
+ if ((sb)->end - (sb)->cur < (need)) \
98
+ sb_grow(sb, need); \
99
+ } while (0)
100
+
101
+ static void sb_grow(SB *sb, int need)
102
+ {
103
+ size_t length = sb->cur - sb->start;
104
+ size_t alloc = sb->end - sb->start;
105
+
106
+ do {
107
+ alloc *= 2;
108
+ } while (alloc < length + need);
109
+
110
+ sb->start = (char*) realloc(sb->start, alloc + 1);
111
+ if (sb->start == NULL)
112
+ out_of_memory();
113
+ sb->cur = sb->start + length;
114
+ sb->end = sb->start + alloc;
115
+ }
116
+
117
+ static void sb_put(SB *sb, const char *bytes, int count)
118
+ {
119
+ sb_need(sb, count);
120
+ memcpy(sb->cur, bytes, count);
121
+ sb->cur += count;
122
+ }
123
+
124
+ #define sb_putc(sb, c) do { \
125
+ if ((sb)->cur >= (sb)->end) \
126
+ sb_grow(sb, 1); \
127
+ *(sb)->cur++ = (c); \
128
+ } while (0)
129
+
130
+ static void sb_puts(SB *sb, const char *str)
131
+ {
132
+ sb_put(sb, str, strlen(str));
133
+ }
134
+
135
+ static char *sb_finish(SB *sb)
136
+ {
137
+ *sb->cur = 0;
138
+ assert(sb->start <= sb->cur && strlen(sb->start) == (size_t)(sb->cur - sb->start));
139
+ return sb->start;
140
+ }
141
+
142
+ static void sb_free(SB *sb)
143
+ {
144
+ free(sb->start);
145
+ }
146
+
147
+ /*
148
+ * Unicode helper functions
149
+ *
150
+ * These are taken from the ccan/charset module and customized a bit.
151
+ * Putting them here means the compiler can (choose to) inline them,
152
+ * and it keeps ccan/json from having a dependency.
153
+ */
154
+
155
+ /*
156
+ * Type for Unicode codepoints.
157
+ * We need our own because wchar_t might be 16 bits.
158
+ */
159
+ typedef uint32_t uchar_t;
160
+
161
+ /*
162
+ * Validate a single UTF-8 character starting at @s.
163
+ * The string must be null-terminated.
164
+ *
165
+ * If it's valid, return its length (1 thru 4).
166
+ * If it's invalid or clipped, return 0.
167
+ *
168
+ * This function implements the syntax given in RFC3629, which is
169
+ * the same as that given in The Unicode Standard, Version 6.0.
170
+ *
171
+ * It has the following properties:
172
+ *
173
+ * * All codepoints U+0000..U+10FFFF may be encoded,
174
+ * except for U+D800..U+DFFF, which are reserved
175
+ * for UTF-16 surrogate pair encoding.
176
+ * * UTF-8 byte sequences longer than 4 bytes are not permitted,
177
+ * as they exceed the range of Unicode.
178
+ * * The sixty-six Unicode "non-characters" are permitted
179
+ * (namely, U+FDD0..U+FDEF, U+xxFFFE, and U+xxFFFF).
180
+ */
181
+ static int utf8_validate_cz(const char *s)
182
+ {
183
+ unsigned char c = *s++;
184
+
185
+ if (c <= 0x7F) { /* 00..7F */
186
+ return 1;
187
+ } else if (c <= 0xC1) { /* 80..C1 */
188
+ /* Disallow overlong 2-byte sequence. */
189
+ return 0;
190
+ } else if (c <= 0xDF) { /* C2..DF */
191
+ /* Make sure subsequent byte is in the range 0x80..0xBF. */
192
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
193
+ return 0;
194
+
195
+ return 2;
196
+ } else if (c <= 0xEF) { /* E0..EF */
197
+ /* Disallow overlong 3-byte sequence. */
198
+ if (c == 0xE0 && (unsigned char)*s < 0xA0)
199
+ return 0;
200
+
201
+ /* Disallow U+D800..U+DFFF. */
202
+ if (c == 0xED && (unsigned char)*s > 0x9F)
203
+ return 0;
204
+
205
+ /* Make sure subsequent bytes are in the range 0x80..0xBF. */
206
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
207
+ return 0;
208
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
209
+ return 0;
210
+
211
+ return 3;
212
+ } else if (c <= 0xF4) { /* F0..F4 */
213
+ /* Disallow overlong 4-byte sequence. */
214
+ if (c == 0xF0 && (unsigned char)*s < 0x90)
215
+ return 0;
216
+
217
+ /* Disallow codepoints beyond U+10FFFF. */
218
+ if (c == 0xF4 && (unsigned char)*s > 0x8F)
219
+ return 0;
220
+
221
+ /* Make sure subsequent bytes are in the range 0x80..0xBF. */
222
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
223
+ return 0;
224
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
225
+ return 0;
226
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
227
+ return 0;
228
+
229
+ return 4;
230
+ } else { /* F5..FF */
231
+ return 0;
232
+ }
233
+ }
234
+
235
+ /* Validate a null-terminated UTF-8 string. */
236
+ static bool utf8_validate(const char *s)
237
+ {
238
+ int len;
239
+
240
+ for (; *s != 0; s += len) {
241
+ len = utf8_validate_cz(s);
242
+ if (len == 0)
243
+ return false;
244
+ }
245
+
246
+ return true;
247
+ }
248
+
249
+ /*
250
+ * Read a single UTF-8 character starting at @s,
251
+ * returning the length, in bytes, of the character read.
252
+ *
253
+ * This function assumes input is valid UTF-8,
254
+ * and that there are enough characters in front of @s.
255
+ */
256
+ static int utf8_read_char(const char *s, uchar_t *out)
257
+ {
258
+ const unsigned char *c = (const unsigned char*) s;
259
+
260
+ assert(utf8_validate_cz(s));
261
+
262
+ if (c[0] <= 0x7F) {
263
+ /* 00..7F */
264
+ *out = c[0];
265
+ return 1;
266
+ } else if (c[0] <= 0xDF) {
267
+ /* C2..DF (unless input is invalid) */
268
+ *out = ((uchar_t)c[0] & 0x1F) << 6 |
269
+ ((uchar_t)c[1] & 0x3F);
270
+ return 2;
271
+ } else if (c[0] <= 0xEF) {
272
+ /* E0..EF */
273
+ *out = ((uchar_t)c[0] & 0xF) << 12 |
274
+ ((uchar_t)c[1] & 0x3F) << 6 |
275
+ ((uchar_t)c[2] & 0x3F);
276
+ return 3;
277
+ } else {
278
+ /* F0..F4 (unless input is invalid) */
279
+ *out = ((uchar_t)c[0] & 0x7) << 18 |
280
+ ((uchar_t)c[1] & 0x3F) << 12 |
281
+ ((uchar_t)c[2] & 0x3F) << 6 |
282
+ ((uchar_t)c[3] & 0x3F);
283
+ return 4;
284
+ }
285
+ }
286
+
287
+ /*
288
+ * Write a single UTF-8 character to @s,
289
+ * returning the length, in bytes, of the character written.
290
+ *
291
+ * @unicode must be U+0000..U+10FFFF, but not U+D800..U+DFFF.
292
+ *
293
+ * This function will write up to 4 bytes to @out.
294
+ */
295
+ static int utf8_write_char(uchar_t unicode, char *out)
296
+ {
297
+ unsigned char *o = (unsigned char*) out;
298
+
299
+ assert(unicode <= 0x10FFFF && !(unicode >= 0xD800 && unicode <= 0xDFFF));
300
+
301
+ if (unicode <= 0x7F) {
302
+ /* U+0000..U+007F */
303
+ *o++ = unicode;
304
+ return 1;
305
+ } else if (unicode <= 0x7FF) {
306
+ /* U+0080..U+07FF */
307
+ *o++ = 0xC0 | unicode >> 6;
308
+ *o++ = 0x80 | (unicode & 0x3F);
309
+ return 2;
310
+ } else if (unicode <= 0xFFFF) {
311
+ /* U+0800..U+FFFF */
312
+ *o++ = 0xE0 | unicode >> 12;
313
+ *o++ = 0x80 | (unicode >> 6 & 0x3F);
314
+ *o++ = 0x80 | (unicode & 0x3F);
315
+ return 3;
316
+ } else {
317
+ /* U+10000..U+10FFFF */
318
+ *o++ = 0xF0 | unicode >> 18;
319
+ *o++ = 0x80 | (unicode >> 12 & 0x3F);
320
+ *o++ = 0x80 | (unicode >> 6 & 0x3F);
321
+ *o++ = 0x80 | (unicode & 0x3F);
322
+ return 4;
323
+ }
324
+ }
325
+
326
+ /*
327
+ * Compute the Unicode codepoint of a UTF-16 surrogate pair.
328
+ *
329
+ * @uc should be 0xD800..0xDBFF, and @lc should be 0xDC00..0xDFFF.
330
+ * If they aren't, this function returns false.
331
+ */
332
+ static bool from_surrogate_pair(uint16_t uc, uint16_t lc, uchar_t *unicode)
333
+ {
334
+ if (uc >= 0xD800 && uc <= 0xDBFF && lc >= 0xDC00 && lc <= 0xDFFF) {
335
+ *unicode = 0x10000 + ((((uchar_t)uc & 0x3FF) << 10) | (lc & 0x3FF));
336
+ return true;
337
+ } else {
338
+ return false;
339
+ }
340
+ }
341
+
342
+ /*
343
+ * Construct a UTF-16 surrogate pair given a Unicode codepoint.
344
+ *
345
+ * @unicode must be U+10000..U+10FFFF.
346
+ */
347
+ static void to_surrogate_pair(uchar_t unicode, uint16_t *uc, uint16_t *lc)
348
+ {
349
+ uchar_t n;
350
+
351
+ assert(unicode >= 0x10000 && unicode <= 0x10FFFF);
352
+
353
+ n = unicode - 0x10000;
354
+ *uc = ((n >> 10) & 0x3FF) | 0xD800;
355
+ *lc = (n & 0x3FF) | 0xDC00;
356
+ }
357
+
358
+ #define is_space(c) ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
359
+ #define is_digit(c) ((c) >= '0' && (c) <= '9')
360
+
361
+ static bool parse_value (const char **sp, JsonNode **out);
362
+ static bool parse_string (const char **sp, char **out);
363
+ static bool parse_number (const char **sp, double *out);
364
+ static bool parse_array (const char **sp, JsonNode **out);
365
+ static bool parse_object (const char **sp, JsonNode **out);
366
+ static bool parse_hex16 (const char **sp, uint16_t *out);
367
+
368
+ static bool expect_literal (const char **sp, const char *str);
369
+ static void skip_space (const char **sp);
370
+
371
+ static void emit_value (SB *out, const JsonNode *node);
372
+ static void emit_value_indented (SB *out, const JsonNode *node, const char *space, int indent_level);
373
+ static void emit_string (SB *out, const char *str);
374
+ static void emit_number (SB *out, double num);
375
+ static void emit_array (SB *out, const JsonNode *array);
376
+ static void emit_array_indented (SB *out, const JsonNode *array, const char *space, int indent_level);
377
+ static void emit_object (SB *out, const JsonNode *object);
378
+ static void emit_object_indented (SB *out, const JsonNode *object, const char *space, int indent_level);
379
+
380
+ static int write_hex16(char *out, uint16_t val);
381
+
382
+ static JsonNode *mknode(JsonTag tag);
383
+ static void append_node(JsonNode *parent, JsonNode *child);
384
+ static void prepend_node(JsonNode *parent, JsonNode *child);
385
+ static void append_member(JsonNode *object, char *key, JsonNode *value);
386
+
387
+ /* Assertion-friendly validity checks */
388
+ static bool tag_is_valid(unsigned int tag);
389
+ static bool number_is_valid(const char *num);
390
+
391
+ JsonNode *json_decode(const char *json)
392
+ {
393
+ const char *s = json;
394
+ JsonNode *ret;
395
+
396
+ skip_space(&s);
397
+ if (!parse_value(&s, &ret))
398
+ return NULL;
399
+
400
+ skip_space(&s);
401
+ if (*s != 0) {
402
+ json_delete(ret);
403
+ return NULL;
404
+ }
405
+
406
+ return ret;
407
+ }
408
+
409
+ char *json_encode(const JsonNode *node)
410
+ {
411
+ return json_stringify(node, NULL);
412
+ }
413
+
414
+ char *json_encode_string(const char *str)
415
+ {
416
+ SB sb;
417
+ sb_init(&sb);
418
+
419
+ emit_string(&sb, str);
420
+
421
+ return sb_finish(&sb);
422
+ }
423
+
424
+ char *json_stringify(const JsonNode *node, const char *space)
425
+ {
426
+ SB sb;
427
+ sb_init(&sb);
428
+
429
+ if (space != NULL)
430
+ emit_value_indented(&sb, node, space, 0);
431
+ else
432
+ emit_value(&sb, node);
433
+
434
+ return sb_finish(&sb);
435
+ }
436
+
437
+ void json_delete(JsonNode *node)
438
+ {
439
+ if (node != NULL) {
440
+ json_remove_from_parent(node);
441
+
442
+ switch (node->tag) {
443
+ case JSON_STRING:
444
+ free(node->string_);
445
+ break;
446
+ case JSON_ARRAY:
447
+ case JSON_OBJECT:
448
+ {
449
+ JsonNode *child, *next;
450
+ for (child = node->children.head; child != NULL; child = next) {
451
+ next = child->next;
452
+ json_delete(child);
453
+ }
454
+ break;
455
+ }
456
+ default:;
457
+ }
458
+
459
+ free(node);
460
+ }
461
+ }
462
+
463
+ bool json_validate(const char *json)
464
+ {
465
+ const char *s = json;
466
+
467
+ skip_space(&s);
468
+ if (!parse_value(&s, NULL))
469
+ return false;
470
+
471
+ skip_space(&s);
472
+ if (*s != 0)
473
+ return false;
474
+
475
+ return true;
476
+ }
477
+
478
+ JsonNode *json_find_element(JsonNode *array, int index)
479
+ {
480
+ JsonNode *element;
481
+ int i = 0;
482
+
483
+ if (array == NULL || array->tag != JSON_ARRAY)
484
+ return NULL;
485
+
486
+ json_foreach(element, array) {
487
+ if (i == index)
488
+ return element;
489
+ i++;
490
+ }
491
+
492
+ return NULL;
493
+ }
494
+
495
+ JsonNode *json_find_member(JsonNode *object, const char *name)
496
+ {
497
+ JsonNode *member;
498
+
499
+ if (object == NULL || object->tag != JSON_OBJECT)
500
+ return NULL;
501
+
502
+ json_foreach(member, object)
503
+ if (strcmp(member->key, name) == 0)
504
+ return member;
505
+
506
+ return NULL;
507
+ }
508
+
509
+ JsonNode *json_first_child(const JsonNode *node)
510
+ {
511
+ if (node != NULL && (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT))
512
+ return node->children.head;
513
+ return NULL;
514
+ }
515
+
516
+ static JsonNode *mknode(JsonTag tag)
517
+ {
518
+ JsonNode *ret = (JsonNode*) calloc(1, sizeof(JsonNode));
519
+ if (ret == NULL)
520
+ out_of_memory();
521
+ ret->tag = tag;
522
+ return ret;
523
+ }
524
+
525
+ JsonNode *json_mknull(void)
526
+ {
527
+ return mknode(JSON_NULL);
528
+ }
529
+
530
+ JsonNode *json_mkbool(bool b)
531
+ {
532
+ JsonNode *ret = mknode(JSON_BOOL);
533
+ ret->bool_ = b;
534
+ return ret;
535
+ }
536
+
537
+ static JsonNode *mkstring(char *s)
538
+ {
539
+ JsonNode *ret = mknode(JSON_STRING);
540
+ ret->string_ = s;
541
+ return ret;
542
+ }
543
+
544
+ JsonNode *json_mkstring(const char *s)
545
+ {
546
+ return mkstring(json_strdup(s));
547
+ }
548
+
549
+ JsonNode *json_mknumber(double n)
550
+ {
551
+ JsonNode *node = mknode(JSON_NUMBER);
552
+ node->number_ = n;
553
+ return node;
554
+ }
555
+
556
+ JsonNode *json_mkarray(void)
557
+ {
558
+ return mknode(JSON_ARRAY);
559
+ }
560
+
561
+ JsonNode *json_mkobject(void)
562
+ {
563
+ return mknode(JSON_OBJECT);
564
+ }
565
+
566
+ static void append_node(JsonNode *parent, JsonNode *child)
567
+ {
568
+ child->parent = parent;
569
+ child->prev = parent->children.tail;
570
+ child->next = NULL;
571
+
572
+ if (parent->children.tail != NULL)
573
+ parent->children.tail->next = child;
574
+ else
575
+ parent->children.head = child;
576
+ parent->children.tail = child;
577
+ }
578
+
579
+ static void prepend_node(JsonNode *parent, JsonNode *child)
580
+ {
581
+ child->parent = parent;
582
+ child->prev = NULL;
583
+ child->next = parent->children.head;
584
+
585
+ if (parent->children.head != NULL)
586
+ parent->children.head->prev = child;
587
+ else
588
+ parent->children.tail = child;
589
+ parent->children.head = child;
590
+ }
591
+
592
+ static void append_member(JsonNode *object, char *key, JsonNode *value)
593
+ {
594
+ value->key = key;
595
+ append_node(object, value);
596
+ }
597
+
598
+ void json_append_element(JsonNode *array, JsonNode *element)
599
+ {
600
+ assert(array->tag == JSON_ARRAY);
601
+ assert(element->parent == NULL);
602
+
603
+ append_node(array, element);
604
+ }
605
+
606
+ void json_prepend_element(JsonNode *array, JsonNode *element)
607
+ {
608
+ assert(array->tag == JSON_ARRAY);
609
+ assert(element->parent == NULL);
610
+
611
+ prepend_node(array, element);
612
+ }
613
+
614
+ void json_append_member(JsonNode *object, const char *key, JsonNode *value)
615
+ {
616
+ assert(object->tag == JSON_OBJECT);
617
+ assert(value->parent == NULL);
618
+
619
+ append_member(object, json_strdup(key), value);
620
+ }
621
+
622
+ void json_prepend_member(JsonNode *object, const char *key, JsonNode *value)
623
+ {
624
+ assert(object->tag == JSON_OBJECT);
625
+ assert(value->parent == NULL);
626
+
627
+ value->key = json_strdup(key);
628
+ prepend_node(object, value);
629
+ }
630
+
631
+ void json_remove_from_parent(JsonNode *node)
632
+ {
633
+ JsonNode *parent = node->parent;
634
+
635
+ if (parent != NULL) {
636
+ if (node->prev != NULL)
637
+ node->prev->next = node->next;
638
+ else
639
+ parent->children.head = node->next;
640
+ if (node->next != NULL)
641
+ node->next->prev = node->prev;
642
+ else
643
+ parent->children.tail = node->prev;
644
+
645
+ free(node->key);
646
+
647
+ node->parent = NULL;
648
+ node->prev = node->next = NULL;
649
+ node->key = NULL;
650
+ }
651
+ }
652
+
653
+ static bool parse_value(const char **sp, JsonNode **out)
654
+ {
655
+ const char *s = *sp;
656
+
657
+ switch (*s) {
658
+ case 'n':
659
+ if (expect_literal(&s, "null")) {
660
+ if (out)
661
+ *out = json_mknull();
662
+ *sp = s;
663
+ return true;
664
+ }
665
+ return false;
666
+
667
+ case 'f':
668
+ if (expect_literal(&s, "false")) {
669
+ if (out)
670
+ *out = json_mkbool(false);
671
+ *sp = s;
672
+ return true;
673
+ }
674
+ return false;
675
+
676
+ case 't':
677
+ if (expect_literal(&s, "true")) {
678
+ if (out)
679
+ *out = json_mkbool(true);
680
+ *sp = s;
681
+ return true;
682
+ }
683
+ return false;
684
+
685
+ case '"': {
686
+ char *str;
687
+ if (parse_string(&s, out ? &str : NULL)) {
688
+ if (out)
689
+ *out = mkstring(str);
690
+ *sp = s;
691
+ return true;
692
+ }
693
+ return false;
694
+ }
695
+
696
+ case '[':
697
+ if (parse_array(&s, out)) {
698
+ *sp = s;
699
+ return true;
700
+ }
701
+ return false;
702
+
703
+ case '{':
704
+ if (parse_object(&s, out)) {
705
+ *sp = s;
706
+ return true;
707
+ }
708
+ return false;
709
+
710
+ default: {
711
+ double num;
712
+ if (parse_number(&s, out ? &num : NULL)) {
713
+ if (out)
714
+ *out = json_mknumber(num);
715
+ *sp = s;
716
+ return true;
717
+ }
718
+ return false;
719
+ }
720
+ }
721
+ }
722
+
723
+ static bool parse_array(const char **sp, JsonNode **out)
724
+ {
725
+ const char *s = *sp;
726
+ JsonNode *ret = out ? json_mkarray() : NULL;
727
+ JsonNode *element;
728
+
729
+ if (*s++ != '[')
730
+ goto failure;
731
+ skip_space(&s);
732
+
733
+ if (*s == ']') {
734
+ s++;
735
+ goto success;
736
+ }
737
+
738
+ for (;;) {
739
+ if (!parse_value(&s, out ? &element : NULL))
740
+ goto failure;
741
+ skip_space(&s);
742
+
743
+ if (out)
744
+ json_append_element(ret, element);
745
+
746
+ if (*s == ']') {
747
+ s++;
748
+ goto success;
749
+ }
750
+
751
+ if (*s++ != ',')
752
+ goto failure;
753
+ skip_space(&s);
754
+ }
755
+
756
+ success:
757
+ *sp = s;
758
+ if (out)
759
+ *out = ret;
760
+ return true;
761
+
762
+ failure:
763
+ json_delete(ret);
764
+ return false;
765
+ }
766
+
767
+ static bool parse_object(const char **sp, JsonNode **out)
768
+ {
769
+ const char *s = *sp;
770
+ JsonNode *ret = out ? json_mkobject() : NULL;
771
+ char *key;
772
+ JsonNode *value;
773
+
774
+ if (*s++ != '{')
775
+ goto failure;
776
+ skip_space(&s);
777
+
778
+ if (*s == '}') {
779
+ s++;
780
+ goto success;
781
+ }
782
+
783
+ for (;;) {
784
+ if (!parse_string(&s, out ? &key : NULL))
785
+ goto failure;
786
+ skip_space(&s);
787
+
788
+ if (*s++ != ':')
789
+ goto failure_free_key;
790
+ skip_space(&s);
791
+
792
+ if (!parse_value(&s, out ? &value : NULL))
793
+ goto failure_free_key;
794
+ skip_space(&s);
795
+
796
+ if (out)
797
+ append_member(ret, key, value);
798
+
799
+ if (*s == '}') {
800
+ s++;
801
+ goto success;
802
+ }
803
+
804
+ if (*s++ != ',')
805
+ goto failure;
806
+ skip_space(&s);
807
+ }
808
+
809
+ success:
810
+ *sp = s;
811
+ if (out)
812
+ *out = ret;
813
+ return true;
814
+
815
+ failure_free_key:
816
+ if (out)
817
+ free(key);
818
+ failure:
819
+ json_delete(ret);
820
+ return false;
821
+ }
822
+
823
+ bool parse_string(const char **sp, char **out)
824
+ {
825
+ const char *s = *sp;
826
+ SB sb;
827
+ char throwaway_buffer[4];
828
+ /* enough space for a UTF-8 character */
829
+ char *b;
830
+
831
+ if (*s++ != '"')
832
+ return false;
833
+
834
+ if (out) {
835
+ sb_init(&sb);
836
+ sb_need(&sb, 4);
837
+ b = sb.cur;
838
+ } else {
839
+ b = throwaway_buffer;
840
+ }
841
+
842
+ while (*s != '"') {
843
+ unsigned char c = *s++;
844
+
845
+ /* Parse next character, and write it to b. */
846
+ if (c == '\\') {
847
+ c = *s++;
848
+ switch (c) {
849
+ case '"':
850
+ case '\\':
851
+ case '/':
852
+ *b++ = c;
853
+ break;
854
+ case 'b':
855
+ *b++ = '\b';
856
+ break;
857
+ case 'f':
858
+ *b++ = '\f';
859
+ break;
860
+ case 'n':
861
+ *b++ = '\n';
862
+ break;
863
+ case 'r':
864
+ *b++ = '\r';
865
+ break;
866
+ case 't':
867
+ *b++ = '\t';
868
+ break;
869
+ case 'u':
870
+ {
871
+ uint16_t uc, lc;
872
+ uchar_t unicode;
873
+
874
+ if (!parse_hex16(&s, &uc))
875
+ goto failed;
876
+
877
+ if (uc >= 0xD800 && uc <= 0xDFFF) {
878
+ /* Handle UTF-16 surrogate pair. */
879
+ if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc))
880
+ goto failed; /* Incomplete surrogate pair. */
881
+ if (!from_surrogate_pair(uc, lc, &unicode))
882
+ goto failed; /* Invalid surrogate pair. */
883
+ } else if (uc == 0) {
884
+ /* Disallow "\u0000". */
885
+ goto failed;
886
+ } else {
887
+ unicode = uc;
888
+ }
889
+
890
+ b += utf8_write_char(unicode, b);
891
+ break;
892
+ }
893
+ default:
894
+ /* Invalid escape */
895
+ goto failed;
896
+ }
897
+ } else if (c <= 0x1F) {
898
+ /* Control characters are not allowed in string literals. */
899
+ goto failed;
900
+ } else {
901
+ /* Validate and echo a UTF-8 character. */
902
+ int len;
903
+
904
+ s--;
905
+ len = utf8_validate_cz(s);
906
+ if (len == 0)
907
+ goto failed; /* Invalid UTF-8 character. */
908
+
909
+ while (len--)
910
+ *b++ = *s++;
911
+ }
912
+
913
+ /*
914
+ * Update sb to know about the new bytes,
915
+ * and set up b to write another character.
916
+ */
917
+ if (out) {
918
+ sb.cur = b;
919
+ sb_need(&sb, 4);
920
+ b = sb.cur;
921
+ } else {
922
+ b = throwaway_buffer;
923
+ }
924
+ }
925
+ s++;
926
+
927
+ if (out)
928
+ *out = sb_finish(&sb);
929
+ *sp = s;
930
+ return true;
931
+
932
+ failed:
933
+ if (out)
934
+ sb_free(&sb);
935
+ return false;
936
+ }
937
+
938
+ /*
939
+ * The JSON spec says that a number shall follow this precise pattern
940
+ * (spaces and quotes added for readability):
941
+ * '-'? (0 | [1-9][0-9]*) ('.' [0-9]+)? ([Ee] [+-]? [0-9]+)?
942
+ *
943
+ * However, some JSON parsers are more liberal. For instance, PHP accepts
944
+ * '.5' and '1.'. JSON.parse accepts '+3'.
945
+ *
946
+ * This function takes the strict approach.
947
+ */
948
+ bool parse_number(const char **sp, double *out)
949
+ {
950
+ const char *s = *sp;
951
+
952
+ /* '-'? */
953
+ if (*s == '-')
954
+ s++;
955
+
956
+ /* (0 | [1-9][0-9]*) */
957
+ if (*s == '0') {
958
+ s++;
959
+ } else {
960
+ if (!is_digit(*s))
961
+ return false;
962
+ do {
963
+ s++;
964
+ } while (is_digit(*s));
965
+ }
966
+
967
+ /* ('.' [0-9]+)? */
968
+ if (*s == '.') {
969
+ s++;
970
+ if (!is_digit(*s))
971
+ return false;
972
+ do {
973
+ s++;
974
+ } while (is_digit(*s));
975
+ }
976
+
977
+ /* ([Ee] [+-]? [0-9]+)? */
978
+ if (*s == 'E' || *s == 'e') {
979
+ s++;
980
+ if (*s == '+' || *s == '-')
981
+ s++;
982
+ if (!is_digit(*s))
983
+ return false;
984
+ do {
985
+ s++;
986
+ } while (is_digit(*s));
987
+ }
988
+
989
+ if (out)
990
+ *out = strtod(*sp, NULL);
991
+
992
+ *sp = s;
993
+ return true;
994
+ }
995
+
996
+ static void skip_space(const char **sp)
997
+ {
998
+ const char *s = *sp;
999
+ while (is_space(*s))
1000
+ s++;
1001
+ *sp = s;
1002
+ }
1003
+
1004
+ static void emit_value(SB *out, const JsonNode *node)
1005
+ {
1006
+ assert(tag_is_valid(node->tag));
1007
+ switch (node->tag) {
1008
+ case JSON_NULL:
1009
+ sb_puts(out, "null");
1010
+ break;
1011
+ case JSON_BOOL:
1012
+ sb_puts(out, node->bool_ ? "true" : "false");
1013
+ break;
1014
+ case JSON_STRING:
1015
+ emit_string(out, node->string_);
1016
+ break;
1017
+ case JSON_NUMBER:
1018
+ emit_number(out, node->number_);
1019
+ break;
1020
+ case JSON_ARRAY:
1021
+ emit_array(out, node);
1022
+ break;
1023
+ case JSON_OBJECT:
1024
+ emit_object(out, node);
1025
+ break;
1026
+ default:
1027
+ assert(false);
1028
+ }
1029
+ }
1030
+
1031
+ void emit_value_indented(SB *out, const JsonNode *node, const char *space, int indent_level)
1032
+ {
1033
+ assert(tag_is_valid(node->tag));
1034
+ switch (node->tag) {
1035
+ case JSON_NULL:
1036
+ sb_puts(out, "null");
1037
+ break;
1038
+ case JSON_BOOL:
1039
+ sb_puts(out, node->bool_ ? "true" : "false");
1040
+ break;
1041
+ case JSON_STRING:
1042
+ emit_string(out, node->string_);
1043
+ break;
1044
+ case JSON_NUMBER:
1045
+ emit_number(out, node->number_);
1046
+ break;
1047
+ case JSON_ARRAY:
1048
+ emit_array_indented(out, node, space, indent_level);
1049
+ break;
1050
+ case JSON_OBJECT:
1051
+ emit_object_indented(out, node, space, indent_level);
1052
+ break;
1053
+ default:
1054
+ assert(false);
1055
+ }
1056
+ }
1057
+
1058
+ static void emit_array(SB *out, const JsonNode *array)
1059
+ {
1060
+ const JsonNode *element;
1061
+
1062
+ sb_putc(out, '[');
1063
+ json_foreach(element, array) {
1064
+ emit_value(out, element);
1065
+ if (element->next != NULL)
1066
+ sb_putc(out, ',');
1067
+ }
1068
+ sb_putc(out, ']');
1069
+ }
1070
+
1071
+ static void emit_array_indented(SB *out, const JsonNode *array, const char *space, int indent_level)
1072
+ {
1073
+ const JsonNode *element = array->children.head;
1074
+ int i;
1075
+
1076
+ if (element == NULL) {
1077
+ sb_puts(out, "[]");
1078
+ return;
1079
+ }
1080
+
1081
+ sb_puts(out, "[\n");
1082
+ while (element != NULL) {
1083
+ for (i = 0; i < indent_level + 1; i++)
1084
+ sb_puts(out, space);
1085
+ emit_value_indented(out, element, space, indent_level + 1);
1086
+
1087
+ element = element->next;
1088
+ sb_puts(out, element != NULL ? ",\n" : "\n");
1089
+ }
1090
+ for (i = 0; i < indent_level; i++)
1091
+ sb_puts(out, space);
1092
+ sb_putc(out, ']');
1093
+ }
1094
+
1095
+ static void emit_object(SB *out, const JsonNode *object)
1096
+ {
1097
+ const JsonNode *member;
1098
+
1099
+ sb_putc(out, '{');
1100
+ json_foreach(member, object) {
1101
+ emit_string(out, member->key);
1102
+ sb_putc(out, ':');
1103
+ emit_value(out, member);
1104
+ if (member->next != NULL)
1105
+ sb_putc(out, ',');
1106
+ }
1107
+ sb_putc(out, '}');
1108
+ }
1109
+
1110
+ static void emit_object_indented(SB *out, const JsonNode *object, const char *space, int indent_level)
1111
+ {
1112
+ const JsonNode *member = object->children.head;
1113
+ int i;
1114
+
1115
+ if (member == NULL) {
1116
+ sb_puts(out, "{}");
1117
+ return;
1118
+ }
1119
+
1120
+ sb_puts(out, "{\n");
1121
+ while (member != NULL) {
1122
+ for (i = 0; i < indent_level + 1; i++)
1123
+ sb_puts(out, space);
1124
+ emit_string(out, member->key);
1125
+ sb_puts(out, ": ");
1126
+ emit_value_indented(out, member, space, indent_level + 1);
1127
+
1128
+ member = member->next;
1129
+ sb_puts(out, member != NULL ? ",\n" : "\n");
1130
+ }
1131
+ for (i = 0; i < indent_level; i++)
1132
+ sb_puts(out, space);
1133
+ sb_putc(out, '}');
1134
+ }
1135
+
1136
+ void emit_string(SB *out, const char *str)
1137
+ {
1138
+ bool escape_unicode = false;
1139
+ const char *s = str;
1140
+ char *b;
1141
+
1142
+ assert(utf8_validate(str));
1143
+
1144
+ /*
1145
+ * 14 bytes is enough space to write up to two
1146
+ * \uXXXX escapes and two quotation marks.
1147
+ */
1148
+ sb_need(out, 14);
1149
+ b = out->cur;
1150
+
1151
+ *b++ = '"';
1152
+ while (*s != 0) {
1153
+ unsigned char c = *s++;
1154
+
1155
+ /* Encode the next character, and write it to b. */
1156
+ switch (c) {
1157
+ case '"':
1158
+ *b++ = '\\';
1159
+ *b++ = '"';
1160
+ break;
1161
+ case '\\':
1162
+ *b++ = '\\';
1163
+ *b++ = '\\';
1164
+ break;
1165
+ case '\b':
1166
+ *b++ = '\\';
1167
+ *b++ = 'b';
1168
+ break;
1169
+ case '\f':
1170
+ *b++ = '\\';
1171
+ *b++ = 'f';
1172
+ break;
1173
+ case '\n':
1174
+ *b++ = '\\';
1175
+ *b++ = 'n';
1176
+ break;
1177
+ case '\r':
1178
+ *b++ = '\\';
1179
+ *b++ = 'r';
1180
+ break;
1181
+ case '\t':
1182
+ *b++ = '\\';
1183
+ *b++ = 't';
1184
+ break;
1185
+ default: {
1186
+ int len;
1187
+
1188
+ s--;
1189
+ len = utf8_validate_cz(s);
1190
+
1191
+ if (len == 0) {
1192
+ /*
1193
+ * Handle invalid UTF-8 character gracefully in production
1194
+ * by writing a replacement character (U+FFFD)
1195
+ * and skipping a single byte.
1196
+ *
1197
+ * This should never happen when assertions are enabled
1198
+ * due to the assertion at the beginning of this function.
1199
+ */
1200
+ assert(false);
1201
+ if (escape_unicode) {
1202
+ strcpy(b, "\\uFFFD");
1203
+ b += 6;
1204
+ } else {
1205
+ *b++ = 0xEFu;
1206
+ *b++ = 0xBFu;
1207
+ *b++ = 0xBDu;
1208
+ }
1209
+ s++;
1210
+ } else if (c < 0x1F || (c >= 0x80 && escape_unicode)) {
1211
+ /* Encode using \u.... */
1212
+ uint32_t unicode;
1213
+
1214
+ s += utf8_read_char(s, &unicode);
1215
+
1216
+ if (unicode <= 0xFFFF) {
1217
+ *b++ = '\\';
1218
+ *b++ = 'u';
1219
+ b += write_hex16(b, unicode);
1220
+ } else {
1221
+ /* Produce a surrogate pair. */
1222
+ uint16_t uc, lc;
1223
+ assert(unicode <= 0x10FFFF);
1224
+ to_surrogate_pair(unicode, &uc, &lc);
1225
+ *b++ = '\\';
1226
+ *b++ = 'u';
1227
+ b += write_hex16(b, uc);
1228
+ *b++ = '\\';
1229
+ *b++ = 'u';
1230
+ b += write_hex16(b, lc);
1231
+ }
1232
+ } else {
1233
+ /* Write the character directly. */
1234
+ while (len--)
1235
+ *b++ = *s++;
1236
+ }
1237
+
1238
+ break;
1239
+ }
1240
+ }
1241
+
1242
+ /*
1243
+ * Update *out to know about the new bytes,
1244
+ * and set up b to write another encoded character.
1245
+ */
1246
+ out->cur = b;
1247
+ sb_need(out, 14);
1248
+ b = out->cur;
1249
+ }
1250
+ *b++ = '"';
1251
+
1252
+ out->cur = b;
1253
+ }
1254
+
1255
+ static void emit_number(SB *out, double num)
1256
+ {
1257
+ /*
1258
+ * This isn't exactly how JavaScript renders numbers,
1259
+ * but it should produce valid JSON for reasonable numbers
1260
+ * preserve precision well enough, and avoid some oddities
1261
+ * like 0.3 -> 0.299999999999999988898 .
1262
+ */
1263
+ char buf[64];
1264
+ sprintf(buf, "%.16g", num);
1265
+
1266
+ if (number_is_valid(buf))
1267
+ sb_puts(out, buf);
1268
+ else
1269
+ sb_puts(out, "null");
1270
+ }
1271
+
1272
+ static bool tag_is_valid(unsigned int tag)
1273
+ {
1274
+ return (/* tag >= JSON_NULL && */ tag <= JSON_OBJECT);
1275
+ }
1276
+
1277
+ static bool number_is_valid(const char *num)
1278
+ {
1279
+ return (parse_number(&num, NULL) && *num == '\0');
1280
+ }
1281
+
1282
+ static bool expect_literal(const char **sp, const char *str)
1283
+ {
1284
+ const char *s = *sp;
1285
+
1286
+ while (*str != '\0')
1287
+ if (*s++ != *str++)
1288
+ return false;
1289
+
1290
+ *sp = s;
1291
+ return true;
1292
+ }
1293
+
1294
+ /*
1295
+ * Parses exactly 4 hex characters (capital or lowercase).
1296
+ * Fails if any input chars are not [0-9A-Fa-f].
1297
+ */
1298
+ static bool parse_hex16(const char **sp, uint16_t *out)
1299
+ {
1300
+ const char *s = *sp;
1301
+ uint16_t ret = 0;
1302
+ uint16_t i;
1303
+ uint16_t tmp;
1304
+ char c;
1305
+
1306
+ for (i = 0; i < 4; i++) {
1307
+ c = *s++;
1308
+ if (c >= '0' && c <= '9')
1309
+ tmp = c - '0';
1310
+ else if (c >= 'A' && c <= 'F')
1311
+ tmp = c - 'A' + 10;
1312
+ else if (c >= 'a' && c <= 'f')
1313
+ tmp = c - 'a' + 10;
1314
+ else
1315
+ return false;
1316
+
1317
+ ret <<= 4;
1318
+ ret += tmp;
1319
+ }
1320
+
1321
+ if (out)
1322
+ *out = ret;
1323
+ *sp = s;
1324
+ return true;
1325
+ }
1326
+
1327
+ /*
1328
+ * Encodes a 16-bit number into hexadecimal,
1329
+ * writing exactly 4 hex chars.
1330
+ */
1331
+ static int write_hex16(char *out, uint16_t val)
1332
+ {
1333
+ const char *hex = "0123456789ABCDEF";
1334
+
1335
+ *out++ = hex[(val >> 12) & 0xF];
1336
+ *out++ = hex[(val >> 8) & 0xF];
1337
+ *out++ = hex[(val >> 4) & 0xF];
1338
+ *out++ = hex[ val & 0xF];
1339
+
1340
+ return 4;
1341
+ }
1342
+
1343
+ bool json_check(const JsonNode *node, char errmsg[256])
1344
+ {
1345
+ #define problem(...) do { \
1346
+ if (errmsg != NULL) \
1347
+ snprintf(errmsg, 256, __VA_ARGS__); \
1348
+ return false; \
1349
+ } while (0)
1350
+
1351
+ if (node->key != NULL && !utf8_validate(node->key))
1352
+ problem("key contains invalid UTF-8");
1353
+
1354
+ if (!tag_is_valid(node->tag))
1355
+ problem("tag is invalid (%u)", node->tag);
1356
+
1357
+ if (node->tag == JSON_BOOL) {
1358
+ if (node->bool_ != false && node->bool_ != true)
1359
+ problem("bool_ is neither false (%d) nor true (%d)", (int)false, (int)true);
1360
+ } else if (node->tag == JSON_STRING) {
1361
+ if (node->string_ == NULL)
1362
+ problem("string_ is NULL");
1363
+ if (!utf8_validate(node->string_))
1364
+ problem("string_ contains invalid UTF-8");
1365
+ } else if (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT) {
1366
+ JsonNode *head = node->children.head;
1367
+ JsonNode *tail = node->children.tail;
1368
+
1369
+ if (head == NULL || tail == NULL) {
1370
+ if (head != NULL)
1371
+ problem("tail is NULL, but head is not");
1372
+ if (tail != NULL)
1373
+ problem("head is NULL, but tail is not");
1374
+ } else {
1375
+ JsonNode *child;
1376
+ JsonNode *last = NULL;
1377
+
1378
+ if (head->prev != NULL)
1379
+ problem("First child's prev pointer is not NULL");
1380
+
1381
+ for (child = head; child != NULL; last = child, child = child->next) {
1382
+ if (child == node)
1383
+ problem("node is its own child");
1384
+ if (child->next == child)
1385
+ problem("child->next == child (cycle)");
1386
+ if (child->next == head)
1387
+ problem("child->next == head (cycle)");
1388
+
1389
+ if (child->parent != node)
1390
+ problem("child does not point back to parent");
1391
+ if (child->next != NULL && child->next->prev != child)
1392
+ problem("child->next does not point back to child");
1393
+
1394
+ if (node->tag == JSON_ARRAY && child->key != NULL)
1395
+ problem("Array element's key is not NULL");
1396
+ if (node->tag == JSON_OBJECT && child->key == NULL)
1397
+ problem("Object member's key is NULL");
1398
+
1399
+ if (!json_check(child, errmsg))
1400
+ return false;
1401
+ }
1402
+
1403
+ if (last != tail)
1404
+ problem("tail does not match pointer found by starting at head and following next links");
1405
+ }
1406
+ }
1407
+
1408
+ return true;
1409
+
1410
+ #undef problem
1411
+ }