Deleted Added
full compact
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 ---