Sat Aug 7 04:53:56 2010 UTC ()
fix up 64-bit lint


(agc)
diff -r1.2 -r1.3 src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c

cvs diff -r1.2 -r1.3 src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c (switch to unified diff)

--- src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c 2010/08/07 04:50:35 1.2
+++ src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c 2010/08/07 04:53:56 1.3
@@ -1,521 +1,521 @@ @@ -1,521 +1,521 @@
1/*- 1/*-
2 * Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org> 2 * Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25#include <sys/types.h> 25#include <sys/types.h>
26 26
27#include <inttypes.h> 27#include <inttypes.h>
28#include <regex.h> 28#include <regex.h>
29#include <stdarg.h> 29#include <stdarg.h>
30#include <stdio.h> 30#include <stdio.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33#include <unistd.h> 33#include <unistd.h>
34 34
35#include "mj.h" 35#include "mj.h"
36#include "defs.h" 36#include "defs.h"
37 37
38/* save 'n' chars of 's' in malloc'd memory */ 38/* save 'n' chars of 's' in malloc'd memory */
39static char * 39static char *
40strnsave(const char *s, int n, unsigned esc) 40strnsave(const char *s, int n, unsigned esc)
41{ 41{
42 char *newc; 42 char *newc;
43 char *cp; 43 char *cp;
44 int i; 44 int i;
45 45
46 if (n < 0) { 46 if (n < 0) {
47 n = strlen(s); 47 n = (int)strlen(s);
48 } 48 }
49 NEWARRAY(char, cp, (n * 2) + 1, "strnsave", return NULL); 49 NEWARRAY(char, cp, (n * 2) + 1, "strnsave", return NULL);
50 if (esc) { 50 if (esc) {
51 newc = cp; 51 newc = cp;
52 for (i = 0 ; i < n ; i++) { 52 for (i = 0 ; i < n ; i++) {
53 if (*s == '\\') { 53 if (*s == '\\') {
54 *newc++ = *s++; 54 *newc++ = *s++;
55 } else if (*s == '"') { 55 } else if (*s == '"') {
56 *newc++ = '\\'; 56 *newc++ = '\\';
57 } 57 }
58 *newc++ = *s++; 58 *newc++ = *s++;
59 } 59 }
60 *newc = 0x0; 60 *newc = 0x0;
61 } else { 61 } else {
62 (void) memcpy(cp, s, (unsigned)n); 62 (void) memcpy(cp, s, (unsigned)n);
63 cp[n] = 0x0; 63 cp[n] = 0x0;
64 } 64 }
65 return cp; 65 return cp;
66} 66}
67 67
68/* look in an object for the item */ 68/* look in an object for the item */
69static int 69static int
70findentry(mj_t *atom, const char *name, const unsigned from, const unsigned incr) 70findentry(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
71{ 71{
72 unsigned i; 72 unsigned i;
73 73
74 for (i = from ; i < atom->c ; i += incr) { 74 for (i = from ; i < atom->c ; i += incr) {
75 if (strcmp(name, atom->value.v[i].value.s) == 0) { 75 if (strcmp(name, atom->value.v[i].value.s) == 0) {
76 return i; 76 return i;
77 } 77 }
78 } 78 }
79 return -1; 79 return -1;
80} 80}
81 81
82/* create a real number */ 82/* create a real number */
83static void 83static void
84create_number(mj_t *atom, double d) 84create_number(mj_t *atom, double d)
85{ 85{
86 char number[128]; 86 char number[128];
87 87
88 atom->type = MJ_NUMBER; 88 atom->type = MJ_NUMBER;
89 atom->c = snprintf(number, sizeof(number), "%g", d); 89 atom->c = snprintf(number, sizeof(number), "%g", d);
90 atom->value.s = strnsave(number, (int)atom->c, 0); 90 atom->value.s = strnsave(number, (int)atom->c, 0);
91} 91}
92 92
93/* create an integer */ 93/* create an integer */
94static void 94static void
95create_integer(mj_t *atom, int64_t i) 95create_integer(mj_t *atom, int64_t i)
96{ 96{
97 char number[128]; 97 char number[128];
98 98
99 atom->type = MJ_NUMBER; 99 atom->type = MJ_NUMBER;
100 atom->c = snprintf(number, sizeof(number), "%" PRIi64, i); 100 atom->c = snprintf(number, sizeof(number), "%" PRIi64, i);
101 atom->value.s = strnsave(number, (int)atom->c, 0); 101 atom->value.s = strnsave(number, (int)atom->c, 0);
102} 102}
103 103
104/* create a string */ 104/* create a string */
105static void 105static void
106create_string(mj_t *atom, const char *s) 106create_string(mj_t *atom, const char *s)
107{ 107{
108 atom->type = MJ_STRING; 108 atom->type = MJ_STRING;
109 atom->value.s = strnsave(s, -1, 1); 109 atom->value.s = strnsave(s, -1, 1);
110 atom->c = strlen(atom->value.s); 110 atom->c = (unsigned)strlen(atom->value.s);
111} 111}
112 112
113#define MJ_OPEN_BRACKET (MJ_OBJECT + 1) /* 8 */ 113#define MJ_OPEN_BRACKET (MJ_OBJECT + 1) /* 8 */
114#define MJ_CLOSE_BRACKET (MJ_OPEN_BRACKET + 1) /* 9 */ 114#define MJ_CLOSE_BRACKET (MJ_OPEN_BRACKET + 1) /* 9 */
115#define MJ_OPEN_BRACE (MJ_CLOSE_BRACKET + 1) /* 10 */ 115#define MJ_OPEN_BRACE (MJ_CLOSE_BRACKET + 1) /* 10 */
116#define MJ_CLOSE_BRACE (MJ_OPEN_BRACE + 1) /* 11 */ 116#define MJ_CLOSE_BRACE (MJ_OPEN_BRACE + 1) /* 11 */
117#define MJ_COLON (MJ_CLOSE_BRACE + 1) /* 12 */ 117#define MJ_COLON (MJ_CLOSE_BRACE + 1) /* 12 */
118#define MJ_COMMA (MJ_COLON + 1) /* 13 */ 118#define MJ_COMMA (MJ_COLON + 1) /* 13 */
119 119
120/* return the token type, and start and finish locations in string */ 120/* return the token type, and start and finish locations in string */
121static int 121static int
122gettok(const char *s, int *from, int *to, int *tok) 122gettok(const char *s, int *from, int *to, int *tok)
123{ 123{
124 static regex_t tokregex; 124 static regex_t tokregex;
125 regmatch_t matches[15]; 125 regmatch_t matches[15];
126 static int compiled; 126 static int compiled;
127 127
128 if (!compiled) { 128 if (!compiled) {
129 compiled = 1; 129 compiled = 1;
130 (void) regcomp(&tokregex, 130 (void) regcomp(&tokregex,
131 "[ \t\r\n]*(([+-]?[0-9]{1,21}(\\.[0-9]*)?([eE][-+][0-9]+)?)|" 131 "[ \t\r\n]*(([+-]?[0-9]{1,21}(\\.[0-9]*)?([eE][-+][0-9]+)?)|"
132 "(\"([^\"]|\\\\.)*\")|(null)|(false)|(true)|([][{}:,]))", 132 "(\"([^\"]|\\\\.)*\")|(null)|(false)|(true)|([][{}:,]))",
133 REG_EXTENDED); 133 REG_EXTENDED);
134 } 134 }
135 if (regexec(&tokregex, &s[*from = *to], 15, matches, 0) != 0) { 135 if (regexec(&tokregex, &s[*from = *to], 15, matches, 0) != 0) {
136 return *tok = -1; 136 return *tok = -1;
137 } 137 }
138 *to = *from + (int)(matches[1].rm_eo); 138 *to = *from + (int)(matches[1].rm_eo);
139 *tok = (matches[2].rm_so >= 0) ? MJ_NUMBER : 139 *tok = (matches[2].rm_so >= 0) ? MJ_NUMBER :
140 (matches[5].rm_so >= 0) ? MJ_STRING : 140 (matches[5].rm_so >= 0) ? MJ_STRING :
141 (matches[7].rm_so >= 0) ? MJ_NULL : 141 (matches[7].rm_so >= 0) ? MJ_NULL :
142 (matches[8].rm_so >= 0) ? MJ_FALSE : 142 (matches[8].rm_so >= 0) ? MJ_FALSE :
143 (matches[9].rm_so >= 0) ? MJ_TRUE : 143 (matches[9].rm_so >= 0) ? MJ_TRUE :
144 (matches[10].rm_so < 0) ? -1 : 144 (matches[10].rm_so < 0) ? -1 :
145 (s[*from + (int)(matches[10].rm_so)] == '[') ? MJ_OPEN_BRACKET : 145 (s[*from + (int)(matches[10].rm_so)] == '[') ? MJ_OPEN_BRACKET :
146 (s[*from + (int)(matches[10].rm_so)] == ']') ? MJ_CLOSE_BRACKET : 146 (s[*from + (int)(matches[10].rm_so)] == ']') ? MJ_CLOSE_BRACKET :
147 (s[*from + (int)(matches[10].rm_so)] == '{') ? MJ_OPEN_BRACE : 147 (s[*from + (int)(matches[10].rm_so)] == '{') ? MJ_OPEN_BRACE :
148 (s[*from + (int)(matches[10].rm_so)] == '}') ? MJ_CLOSE_BRACE : 148 (s[*from + (int)(matches[10].rm_so)] == '}') ? MJ_CLOSE_BRACE :
149 (s[*from + (int)(matches[10].rm_so)] == ':') ? MJ_COLON : 149 (s[*from + (int)(matches[10].rm_so)] == ':') ? MJ_COLON :
150 MJ_COMMA; 150 MJ_COMMA;
151 *from += (int)(matches[1].rm_so); 151 *from += (int)(matches[1].rm_so);
152 return *tok; 152 return *tok;
153} 153}
154 154
155/***************************************************************************/ 155/***************************************************************************/
156 156
157/* return the number of entries in the array */ 157/* return the number of entries in the array */
158int 158int
159mj_arraycount(mj_t *atom) 159mj_arraycount(mj_t *atom)
160{ 160{
161 return atom->c; 161 return atom->c;
162} 162}
163 163
164/* create a new JSON node */ 164/* create a new JSON node */
165int 165int
166mj_create(mj_t *atom, const char *type, ...) 166mj_create(mj_t *atom, const char *type, ...)
167{ 167{
168 va_list args; 168 va_list args;
169 169
170 if (strcmp(type, "false") == 0) { 170 if (strcmp(type, "false") == 0) {
171 atom->type = MJ_FALSE; 171 atom->type = MJ_FALSE;
172 atom->c = 0; 172 atom->c = 0;
173 } else if (strcmp(type, "true") == 0) { 173 } else if (strcmp(type, "true") == 0) {
174 atom->type = MJ_TRUE; 174 atom->type = MJ_TRUE;
175 atom->c = 1; 175 atom->c = 1;
176 } else if (strcmp(type, "null") == 0) { 176 } else if (strcmp(type, "null") == 0) {
177 atom->type = MJ_NULL; 177 atom->type = MJ_NULL;
178 } else if (strcmp(type, "number") == 0) { 178 } else if (strcmp(type, "number") == 0) {
179 va_start(args, type); 179 va_start(args, type);
180 create_number(atom, (double)va_arg(args, double)); 180 create_number(atom, (double)va_arg(args, double));
181 va_end(args); 181 va_end(args);
182 } else if (strcmp(type, "integer") == 0) { 182 } else if (strcmp(type, "integer") == 0) {
183 va_start(args, type); 183 va_start(args, type);
184 create_integer(atom, (int64_t)va_arg(args, int64_t)); 184 create_integer(atom, (int64_t)va_arg(args, int64_t));
185 va_end(args); 185 va_end(args);
186 } else if (strcmp(type, "string") == 0) { 186 } else if (strcmp(type, "string") == 0) {
187 va_start(args, type); 187 va_start(args, type);
188 create_string(atom, (char *)va_arg(args, char *)); 188 create_string(atom, (char *)va_arg(args, char *));
189 va_end(args); 189 va_end(args);
190 } else if (strcmp(type, "array") == 0) { 190 } else if (strcmp(type, "array") == 0) {
191 atom->type = MJ_ARRAY; 191 atom->type = MJ_ARRAY;
192 } else if (strcmp(type, "object") == 0) { 192 } else if (strcmp(type, "object") == 0) {
193 atom->type = MJ_OBJECT; 193 atom->type = MJ_OBJECT;
194 } else { 194 } else {
195 (void) fprintf(stderr, "weird type '%s'\n", type); 195 (void) fprintf(stderr, "weird type '%s'\n", type);
196 return 0; 196 return 0;
197 } 197 }
198 return 1; 198 return 1;
199} 199}
200 200
201/* put a JSON tree into a text string */ 201/* put a JSON tree into a text string */
202int 202int
203mj_snprint(char *buf, size_t size, mj_t *atom) 203mj_snprint(char *buf, size_t size, mj_t *atom)
204{ 204{
205 unsigned i; 205 unsigned i;
206 int cc; 206 int cc;
207 207
208 switch(atom->type) { 208 switch(atom->type) {
209 case MJ_NULL: 209 case MJ_NULL:
210 return snprintf(buf, size, "null"); 210 return snprintf(buf, size, "null");
211 case MJ_FALSE: 211 case MJ_FALSE:
212 return snprintf(buf, size, "false"); 212 return snprintf(buf, size, "false");
213 case MJ_TRUE: 213 case MJ_TRUE:
214 return snprintf(buf, size, "true"); 214 return snprintf(buf, size, "true");
215 case MJ_NUMBER: 215 case MJ_NUMBER:
216 return snprintf(buf, size, "%s", atom->value.s); 216 return snprintf(buf, size, "%s", atom->value.s);
217 case MJ_STRING: 217 case MJ_STRING:
218 return snprintf(buf, size, "\"%s\"", atom->value.s); 218 return snprintf(buf, size, "\"%s\"", atom->value.s);
219 case MJ_ARRAY: 219 case MJ_ARRAY:
220 cc = snprintf(buf, size, "[ "); 220 cc = snprintf(buf, size, "[ ");
221 for (i = 0 ; i < atom->c ; i++) { 221 for (i = 0 ; i < atom->c ; i++) {
222 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]); 222 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]);
223 if (i < atom->c - 1) { 223 if (i < atom->c - 1) {
224 cc += snprintf(&buf[cc], size - cc, ", "); 224 cc += snprintf(&buf[cc], size - cc, ", ");
225 } 225 }
226 } 226 }
227 return cc + snprintf(&buf[cc], size - cc, "]\n"); 227 return cc + snprintf(&buf[cc], size - cc, "]\n");
228 case MJ_OBJECT: 228 case MJ_OBJECT:
229 cc = snprintf(buf, size, "{ "); 229 cc = snprintf(buf, size, "{ ");
230 for (i = 0 ; i < atom->c ; i += 2) { 230 for (i = 0 ; i < atom->c ; i += 2) {
231 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]); 231 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]);
232 cc += snprintf(&buf[cc], size - cc, ":"); 232 cc += snprintf(&buf[cc], size - cc, ":");
233 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1]); 233 cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1]);
234 if (i + 1 < atom->c - 1) { 234 if (i + 1 < atom->c - 1) {
235 cc += snprintf(&buf[cc], size - cc, ", "); 235 cc += snprintf(&buf[cc], size - cc, ", ");
236 } 236 }
237 } 237 }
238 return cc + snprintf(&buf[cc], size - cc, "}\n"); 238 return cc + snprintf(&buf[cc], size - cc, "}\n");
239 default: 239 default:
240 (void) fprintf(stderr, "mj_snprint: weird type %d\n", atom->type); 240 (void) fprintf(stderr, "mj_snprint: weird type %d\n", atom->type);
241 return 0; 241 return 0;
242 } 242 }
243} 243}
244 244
245/* allocate and print the atom */ 245/* allocate and print the atom */
246int 246int
247mj_asprint(char **buf, mj_t *atom) 247mj_asprint(char **buf, mj_t *atom)
248{ 248{
249 int size; 249 int size;
250 250
251 size = mj_string_size(atom); 251 size = mj_string_size(atom);
252 if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) { 252 if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) {
253 return -1; 253 return -1;
254 } 254 }
255 (void) mj_snprint(*buf, (unsigned)(size + 1), atom); 255 (void) mj_snprint(*buf, (unsigned)(size + 1), atom);
256 return size + 1; 256 return size + 1;
257} 257}
258 258
259/* read into a JSON tree from a string */ 259/* read into a JSON tree from a string */
260int 260int
261mj_parse(mj_t *atom, const char *s, int *from, int *to, int *tok) 261mj_parse(mj_t *atom, const char *s, int *from, int *to, int *tok)
262{ 262{
263 int i; 263 int i;
264 264
265 switch(atom->type = *tok = gettok(s, from, to, tok)) { 265 switch(atom->type = *tok = gettok(s, from, to, tok)) {
266 case MJ_NUMBER: 266 case MJ_NUMBER:
267 atom->value.s = strnsave(&s[*from], *to - *from, 1); 267 atom->value.s = strnsave(&s[*from], *to - *from, 1);
268 atom->c = atom->size = strlen(atom->value.s); 268 atom->c = atom->size = (unsigned)strlen(atom->value.s);
269 return gettok(s, from, to, tok); 269 return gettok(s, from, to, tok);
270 case MJ_STRING: 270 case MJ_STRING:
271 atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, 1); 271 atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, 1);
272 atom->c = atom->size = strlen(atom->value.s); 272 atom->c = atom->size = (unsigned)strlen(atom->value.s);
273 return gettok(s, from, to, tok); 273 return gettok(s, from, to, tok);
274 case MJ_NULL: 274 case MJ_NULL:
275 case MJ_FALSE: 275 case MJ_FALSE:
276 case MJ_TRUE: 276 case MJ_TRUE:
277 atom->c = (unsigned)*to; 277 atom->c = (unsigned)*to;
278 return gettok(s, from, to, tok); 278 return gettok(s, from, to, tok);
279 case MJ_OPEN_BRACKET: 279 case MJ_OPEN_BRACKET:
280 mj_create(atom, "array"); 280 mj_create(atom, "array");
281 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); 281 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
282 while (mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACKET) { 282 while (mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACKET) {
283 if (*tok != MJ_COMMA) { 283 if (*tok != MJ_COMMA) {
284 (void) fprintf(stderr, "1. expected comma (got %d) at '%s'\n", *tok, &s[*from]); 284 (void) fprintf(stderr, "1. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
285 break; 285 break;
286 } 286 }
287 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); 287 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
288 } 288 }
289 return gettok(s, from, to, tok); 289 return gettok(s, from, to, tok);
290 case MJ_OPEN_BRACE: 290 case MJ_OPEN_BRACE:
291 mj_create(atom, "object"); 291 mj_create(atom, "object");
292 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); 292 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
293 for (i = 0 ; mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACE ; i++) { 293 for (i = 0 ; mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACE ; i++) {
294 if (((i % 2) == 0 && *tok != MJ_COLON) || ((i % 2) == 1 && *tok != MJ_COMMA)) { 294 if (((i % 2) == 0 && *tok != MJ_COLON) || ((i % 2) == 1 && *tok != MJ_COMMA)) {
295 (void) fprintf(stderr, "2. expected comma (got %d) at '%s'\n", *tok, &s[*from]); 295 (void) fprintf(stderr, "2. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
296 break; 296 break;
297 } 297 }
298 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); 298 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
299 } 299 }
300 return gettok(s, from, to, tok); 300 return gettok(s, from, to, tok);
301 default: 301 default:
302 return *tok; 302 return *tok;
303 } 303 }
304} 304}
305 305
306/* return the index of the item which corresponds to the name in the array */ 306/* return the index of the item which corresponds to the name in the array */
307int 307int
308mj_object_find(mj_t *atom, const char *name, const unsigned from, const unsigned incr) 308mj_object_find(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
309{ 309{
310 return findentry(atom, name, from, incr); 310 return findentry(atom, name, from, incr);
311} 311}
312 312
313/* find an atom in a composite mj JSON node */ 313/* find an atom in a composite mj JSON node */
314mj_t * 314mj_t *
315mj_get_atom(mj_t *atom, ...) 315mj_get_atom(mj_t *atom, ...)
316{ 316{
317 unsigned i; 317 unsigned i;
318 va_list args; 318 va_list args;
319 char *name; 319 char *name;
320 int n; 320 int n;
321 321
322 switch(atom->type) { 322 switch(atom->type) {
323 case MJ_ARRAY: 323 case MJ_ARRAY:
324 va_start(args, atom); 324 va_start(args, atom);
325 i = va_arg(args, int); 325 i = va_arg(args, int);
326 va_end(args); 326 va_end(args);
327 return (i < atom->c) ? &atom->value.v[i] : NULL; 327 return (i < atom->c) ? &atom->value.v[i] : NULL;
328 case MJ_OBJECT: 328 case MJ_OBJECT:
329 va_start(args, atom); 329 va_start(args, atom);
330 name = va_arg(args, char *); 330 name = va_arg(args, char *);
331 va_end(args); 331 va_end(args);
332 return ((n = findentry(atom, name, 0, 2)) >= 0) ? &atom->value.v[n + 1] : NULL; 332 return ((n = findentry(atom, name, 0, 2)) >= 0) ? &atom->value.v[n + 1] : NULL;
333 default: 333 default:
334 return NULL; 334 return NULL;
335 } 335 }
336} 336}
337 337
338/* perform a deep copy on an mj JSON atom */ 338/* perform a deep copy on an mj JSON atom */
339int 339int
340mj_deepcopy(mj_t *dst, mj_t *src) 340mj_deepcopy(mj_t *dst, mj_t *src)
341{ 341{
342 unsigned i; 342 unsigned i;
343 343
344 switch(src->type) { 344 switch(src->type) {
345 case MJ_FALSE: 345 case MJ_FALSE:
346 case MJ_TRUE: 346 case MJ_TRUE:
347 case MJ_NULL: 347 case MJ_NULL:
348 (void) memcpy(dst, src, sizeof(*dst)); 348 (void) memcpy(dst, src, sizeof(*dst));
349 return 1; 349 return 1;
350 case MJ_STRING: 350 case MJ_STRING:
351 case MJ_NUMBER: 351 case MJ_NUMBER:
352 (void) memcpy(dst, src, sizeof(*dst)); 352 (void) memcpy(dst, src, sizeof(*dst));
353 dst->value.s = strnsave(src->value.s, -1, 0); 353 dst->value.s = strnsave(src->value.s, -1, 0);
354 dst->c = dst->size = strlen(dst->value.s); 354 dst->c = dst->size = (unsigned)strlen(dst->value.s);
355 return 1; 355 return 1;
356 case MJ_ARRAY: 356 case MJ_ARRAY:
357 case MJ_OBJECT: 357 case MJ_OBJECT:
358 (void) memcpy(dst, src, sizeof(*dst)); 358 (void) memcpy(dst, src, sizeof(*dst));
359 NEWARRAY(mj_t, dst->value.v, dst->size, "mj_deepcopy()", return 0); 359 NEWARRAY(mj_t, dst->value.v, dst->size, "mj_deepcopy()", return 0);
360 for (i = 0 ; i < src->c ; i++) { 360 for (i = 0 ; i < src->c ; i++) {
361 if (!mj_deepcopy(&dst->value.v[i], &src->value.v[i])) { 361 if (!mj_deepcopy(&dst->value.v[i], &src->value.v[i])) {
362 return 0; 362 return 0;
363 } 363 }
364 } 364 }
365 return 1; 365 return 1;
366 default: 366 default:
367 (void) fprintf(stderr, "weird type '%d'\n", src->type); 367 (void) fprintf(stderr, "weird type '%d'\n", src->type);
368 return 0; 368 return 0;
369 } 369 }
370} 370}
371 371
372/* do a deep delete on the object */ 372/* do a deep delete on the object */
373void 373void
374mj_delete(mj_t *atom) 374mj_delete(mj_t *atom)
375{ 375{
376 unsigned i; 376 unsigned i;
377 377
378 switch(atom->type) { 378 switch(atom->type) {
379 case MJ_STRING: 379 case MJ_STRING:
380 case MJ_NUMBER: 380 case MJ_NUMBER:
381 free(atom->value.s); 381 free(atom->value.s);
382 break; 382 break;
383 case MJ_ARRAY: 383 case MJ_ARRAY:
384 case MJ_OBJECT: 384 case MJ_OBJECT:
385 for (i = 0 ; i < atom->c ; i++) { 385 for (i = 0 ; i < atom->c ; i++) {
386 mj_delete(&atom->value.v[i]); 386 mj_delete(&atom->value.v[i]);
387 } 387 }
388 break; 388 break;
389 default: 389 default:
390 break; 390 break;
391 } 391 }
392} 392}
393 393
394/* return the string size needed for the textual output of the JSON node */ 394/* return the string size needed for the textual output of the JSON node */
395int 395int
396mj_string_size(mj_t *atom) 396mj_string_size(mj_t *atom)
397{ 397{
398 unsigned i; 398 unsigned i;
399 int cc; 399 int cc;
400 400
401 switch(atom->type) { 401 switch(atom->type) {
402 case MJ_NULL: 402 case MJ_NULL:
403 case MJ_TRUE: 403 case MJ_TRUE:
404 return 4; 404 return 4;
405 case MJ_FALSE: 405 case MJ_FALSE:
406 return 5; 406 return 5;
407 case MJ_NUMBER: 407 case MJ_NUMBER:
408 return atom->c; 408 return atom->c;
409 case MJ_STRING: 409 case MJ_STRING:
410 return atom->c + 2; 410 return atom->c + 2;
411 case MJ_ARRAY: 411 case MJ_ARRAY:
412 for (cc = 2, i = 0 ; i < atom->c ; i++) { 412 for (cc = 2, i = 0 ; i < atom->c ; i++) {
413 cc += mj_string_size(&atom->value.v[i]); 413 cc += mj_string_size(&atom->value.v[i]);
414 if (i < atom->c - 1) { 414 if (i < atom->c - 1) {
415 cc += 2; 415 cc += 2;
416 } 416 }
417 } 417 }
418 return cc + 1 + 1; 418 return cc + 1 + 1;
419 case MJ_OBJECT: 419 case MJ_OBJECT:
420 for (cc = 2, i = 0 ; i < atom->c ; i += 2) { 420 for (cc = 2, i = 0 ; i < atom->c ; i += 2) {
421 cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]); 421 cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]);
422 if (i + 1 < atom->c - 1) { 422 if (i + 1 < atom->c - 1) {
423 cc += 2; 423 cc += 2;
424 } 424 }
425 } 425 }
426 return cc + 1 + 1; 426 return cc + 1 + 1;
427 default: 427 default:
428 (void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type); 428 (void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type);
429 return 0; 429 return 0;
430 } 430 }
431} 431}
432 432
433/* create a new atom, and append it to the array or object */ 433/* create a new atom, and append it to the array or object */
434int 434int
435mj_append(mj_t *atom, const char *type, ...) 435mj_append(mj_t *atom, const char *type, ...)
436{ 436{
437 va_list args; 437 va_list args;
438 438
439 if (atom->type != MJ_ARRAY && atom->type != MJ_OBJECT) { 439 if (atom->type != MJ_ARRAY && atom->type != MJ_OBJECT) {
440 return 0; 440 return 0;
441 } 441 }
442 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append()", return 0); 442 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append()", return 0);
443 va_start(args, type); 443 va_start(args, type);
444 if (strcmp(type, "string") == 0) { 444 if (strcmp(type, "string") == 0) {
445 create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *)); 445 create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *));
446 } else if (strcmp(type, "integer") == 0) { 446 } else if (strcmp(type, "integer") == 0) {
447 create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t)); 447 create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
448 } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) { 448 } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
449 mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *)); 449 mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
450 } else { 450 } else {
451 (void) fprintf(stderr, "mj_append: weird type '%s'\n", type); 451 (void) fprintf(stderr, "mj_append: weird type '%s'\n", type);
452 } 452 }
453 va_end(args); 453 va_end(args);
454 return 1; 454 return 1;
455} 455}
456 456
457/* append a field to an object */ 457/* append a field to an object */
458int 458int
459mj_append_field(mj_t *atom, const char *name, const char *type, ...) 459mj_append_field(mj_t *atom, const char *name, const char *type, ...)
460{ 460{
461 va_list args; 461 va_list args;
462 462
463 if (atom->type != MJ_OBJECT) { 463 if (atom->type != MJ_OBJECT) {
464 return 0; 464 return 0;
465 } 465 }
466 mj_append(atom, "string", name); 466 mj_append(atom, "string", name);
467 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append_field()", return 0); 467 ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append_field()", return 0);
468 va_start(args, type); 468 va_start(args, type);
469 if (strcmp(type, "string") == 0) { 469 if (strcmp(type, "string") == 0) {
470 create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *)); 470 create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *));
471 } else if (strcmp(type, "integer") == 0) { 471 } else if (strcmp(type, "integer") == 0) {
472 create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t)); 472 create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
473 } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) { 473 } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
474 mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *)); 474 mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
475 } else { 475 } else {
476 (void) fprintf(stderr, "mj_append_field: weird type '%s'\n", type); 476 (void) fprintf(stderr, "mj_append_field: weird type '%s'\n", type);
477 } 477 }
478 va_end(args); 478 va_end(args);
479 return 1; 479 return 1;
480} 480}
481 481
482int 482int
483mj_lint(mj_t *obj) 483mj_lint(mj_t *obj)
484{ 484{
485 unsigned i; 485 unsigned i;
486 int ret; 486 int ret;
487 487
488 switch(obj->type) { 488 switch(obj->type) {
489 case MJ_NULL: 489 case MJ_NULL:
490 case MJ_FALSE: 490 case MJ_FALSE:
491 case MJ_TRUE: 491 case MJ_TRUE:
492 if (obj->value.s != NULL) { 492 if (obj->value.s != NULL) {
493 (void) fprintf(stderr, "null/false/true: non zero string\n"); 493 (void) fprintf(stderr, "null/false/true: non zero string\n");
494 return 0; 494 return 0;
495 } 495 }
496 return 1; 496 return 1;
497 case MJ_NUMBER: 497 case MJ_NUMBER:
498 case MJ_STRING: 498 case MJ_STRING:
499 if (obj->c > obj->size) { 499 if (obj->c > obj->size) {
500 (void) fprintf(stderr, "string/number lint c (%u) > size (%u)\n", obj->c, obj->size); 500 (void) fprintf(stderr, "string/number lint c (%u) > size (%u)\n", obj->c, obj->size);
501 return 0; 501 return 0;
502 } 502 }
503 return 1; 503 return 1;
504 case MJ_ARRAY: 504 case MJ_ARRAY:
505 case MJ_OBJECT: 505 case MJ_OBJECT:
506 if (obj->c > obj->size) { 506 if (obj->c > obj->size) {
507 (void) fprintf(stderr, "array/object lint c (%u) > size (%u)\n", obj->c, obj->size); 507 (void) fprintf(stderr, "array/object lint c (%u) > size (%u)\n", obj->c, obj->size);
508 return 0; 508 return 0;
509 } 509 }
510 for (ret = 1, i = 0 ; i < obj->c ; i++) { 510 for (ret = 1, i = 0 ; i < obj->c ; i++) {
511 if (!mj_lint(&obj->value.v[i])) { 511 if (!mj_lint(&obj->value.v[i])) {
512 (void) fprintf(stderr, "array/object lint found at %d of %p\n", i, obj); 512 (void) fprintf(stderr, "array/object lint found at %d of %p\n", i, obj);
513 ret = 0; 513 ret = 0;
514 } 514 }
515 } 515 }
516 return ret; 516 return ret;
517 default: 517 default:
518 (void) fprintf(stderr, "problem type %d in %p\n", obj->type, obj); 518 (void) fprintf(stderr, "problem type %d in %p\n", obj->type, obj);
519 return 0; 519 return 0;
520 } 520 }
521} 521}