ucl_parser.c (262398) | ucl_parser.c (262975) |
---|---|
1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 1219 unchanged lines hidden (view full) --- 1228 newline = false; 1229 } 1230 ucl_chunk_skipc (chunk, p); 1231 } 1232 1233 return len; 1234} 1235 | 1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 1219 unchanged lines hidden (view full) --- 1228 newline = false; 1229 } 1230 ucl_chunk_skipc (chunk, p); 1231 } 1232 1233 return len; 1234} 1235 |
1236static ucl_object_t* 1237ucl_get_value_object (struct ucl_parser *parser) 1238{ 1239 ucl_object_t *t, *obj = NULL; 1240 1241 if (parser->stack->obj->type == UCL_ARRAY) { 1242 /* Object must be allocated */ 1243 obj = ucl_object_new (); 1244 t = parser->stack->obj->value.av; 1245 DL_APPEND (t, obj); 1246 parser->cur_obj = obj; 1247 parser->stack->obj->value.av = t; 1248 parser->stack->obj->len ++; 1249 } 1250 else { 1251 /* Object has been already allocated */ 1252 obj = parser->cur_obj; 1253 } 1254 1255 return obj; 1256} 1257 |
|
1236/** 1237 * Handle value data 1238 * @param parser 1239 * @param chunk 1240 * @return 1241 */ 1242static bool 1243ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk) 1244{ 1245 const unsigned char *p, *c; | 1258/** 1259 * Handle value data 1260 * @param parser 1261 * @param chunk 1262 * @return 1263 */ 1264static bool 1265ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk) 1266{ 1267 const unsigned char *p, *c; |
1246 ucl_object_t *obj = NULL, *t; | 1268 ucl_object_t *obj = NULL; |
1247 unsigned int stripped_spaces; 1248 int str_len; 1249 bool need_unescape = false, ucl_escape = false, var_expand = false; 1250 1251 p = chunk->pos; 1252 | 1269 unsigned int stripped_spaces; 1270 int str_len; 1271 bool need_unescape = false, ucl_escape = false, var_expand = false; 1272 1273 p = chunk->pos; 1274 |
1253 while (p < chunk->end) { 1254 if (obj == NULL) { 1255 if (parser->stack->obj->type == UCL_ARRAY) { 1256 /* Object must be allocated */ 1257 obj = ucl_object_new (); 1258 t = parser->stack->obj->value.av; 1259 DL_APPEND (t, obj); 1260 parser->cur_obj = obj; 1261 parser->stack->obj->value.av = t; 1262 parser->stack->obj->len ++; 1263 } 1264 else { 1265 /* Object has been already allocated */ 1266 obj = parser->cur_obj; 1267 } | 1275 /* Skip any spaces and comments */ 1276 if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) || 1277 (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) { 1278 while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { 1279 ucl_chunk_skipc (chunk, p); |
1268 } | 1280 } |
1281 if (!ucl_skip_comments (parser)) { 1282 return false; 1283 } 1284 p = chunk->pos; 1285 } 1286 1287 while (p < chunk->end) { |
|
1269 c = p; 1270 switch (*p) { 1271 case '"': | 1288 c = p; 1289 switch (*p) { 1290 case '"': |
1291 obj = ucl_get_value_object (parser); |
|
1272 ucl_chunk_skipc (chunk, p); 1273 if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { 1274 return false; 1275 } 1276 str_len = chunk->pos - c - 2; 1277 obj->type = UCL_STRING; 1278 if ((str_len = ucl_copy_or_store_ptr (parser, c + 1, &obj->trash_stack[UCL_TRASH_VALUE], 1279 &obj->value.sv, str_len, need_unescape, false, var_expand)) == -1) { 1280 return false; 1281 } 1282 obj->len = str_len; 1283 parser->state = UCL_STATE_AFTER_VALUE; 1284 p = chunk->pos; 1285 return true; 1286 break; 1287 case '{': | 1292 ucl_chunk_skipc (chunk, p); 1293 if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { 1294 return false; 1295 } 1296 str_len = chunk->pos - c - 2; 1297 obj->type = UCL_STRING; 1298 if ((str_len = ucl_copy_or_store_ptr (parser, c + 1, &obj->trash_stack[UCL_TRASH_VALUE], 1299 &obj->value.sv, str_len, need_unescape, false, var_expand)) == -1) { 1300 return false; 1301 } 1302 obj->len = str_len; 1303 parser->state = UCL_STATE_AFTER_VALUE; 1304 p = chunk->pos; 1305 return true; 1306 break; 1307 case '{': |
1308 obj = ucl_get_value_object (parser); |
|
1288 /* We have a new object */ 1289 obj = ucl_add_parser_stack (obj, parser, false, parser->stack->level); 1290 1291 ucl_chunk_skipc (chunk, p); 1292 return true; 1293 break; 1294 case '[': | 1309 /* We have a new object */ 1310 obj = ucl_add_parser_stack (obj, parser, false, parser->stack->level); 1311 1312 ucl_chunk_skipc (chunk, p); 1313 return true; 1314 break; 1315 case '[': |
1316 obj = ucl_get_value_object (parser); |
|
1295 /* We have a new array */ 1296 obj = ucl_add_parser_stack (obj, parser, true, parser->stack->level); 1297 1298 ucl_chunk_skipc (chunk, p); 1299 return true; 1300 break; | 1317 /* We have a new array */ 1318 obj = ucl_add_parser_stack (obj, parser, true, parser->stack->level); 1319 1320 ucl_chunk_skipc (chunk, p); 1321 return true; 1322 break; |
1323 case ']': 1324 /* We have the array ending */ 1325 if (parser->stack && parser->stack->obj->type == UCL_ARRAY) { 1326 parser->state = UCL_STATE_AFTER_VALUE; 1327 return true; 1328 } 1329 else { 1330 goto parse_string; 1331 } 1332 break; |
|
1301 case '<': | 1333 case '<': |
1334 obj = ucl_get_value_object (parser); |
|
1302 /* We have something like multiline value, which must be <<[A-Z]+\n */ 1303 if (chunk->end - p > 3) { 1304 if (memcmp (p, "<<", 2) == 0) { 1305 p += 2; 1306 /* We allow only uppercase characters in multiline definitions */ 1307 while (p < chunk->end && *p >= 'A' && *p <= 'Z') { 1308 p ++; 1309 } --- 17 unchanged lines hidden (view full) --- 1327 obj->len = str_len; 1328 parser->state = UCL_STATE_AFTER_VALUE; 1329 return true; 1330 } 1331 } 1332 } 1333 /* Fallback to ordinary strings */ 1334 default: | 1335 /* We have something like multiline value, which must be <<[A-Z]+\n */ 1336 if (chunk->end - p > 3) { 1337 if (memcmp (p, "<<", 2) == 0) { 1338 p += 2; 1339 /* We allow only uppercase characters in multiline definitions */ 1340 while (p < chunk->end && *p >= 'A' && *p <= 'Z') { 1341 p ++; 1342 } --- 17 unchanged lines hidden (view full) --- 1360 obj->len = str_len; 1361 parser->state = UCL_STATE_AFTER_VALUE; 1362 return true; 1363 } 1364 } 1365 } 1366 /* Fallback to ordinary strings */ 1367 default: |
1335 /* Skip any spaces and comments */ 1336 if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) || 1337 (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) { 1338 while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { 1339 ucl_chunk_skipc (chunk, p); 1340 } 1341 if (!ucl_skip_comments (parser)) { 1342 return false; 1343 } 1344 p = chunk->pos; 1345 continue; | 1368parse_string: 1369 if (obj == NULL) { 1370 obj = ucl_get_value_object (parser); |
1346 } 1347 /* Parse atom */ 1348 if (ucl_test_character (*p, UCL_CHARACTER_VALUE_DIGIT_START)) { 1349 if (!ucl_lex_number (parser, chunk, obj)) { 1350 if (parser->state == UCL_STATE_ERROR) { 1351 return false; 1352 } 1353 } --- 519 unchanged lines hidden --- | 1371 } 1372 /* Parse atom */ 1373 if (ucl_test_character (*p, UCL_CHARACTER_VALUE_DIGIT_START)) { 1374 if (!ucl_lex_number (parser, chunk, obj)) { 1375 if (parser->state == UCL_STATE_ERROR) { 1376 return false; 1377 } 1378 } --- 519 unchanged lines hidden --- |