| | @@ -5112,1087 +5112,10 @@ |
| 5112 | 5112 | #undef CSON_VCAST |
| 5113 | 5113 | #undef CSON_MALLOC_IMPL |
| 5114 | 5114 | #undef CSON_FREE_IMPL |
| 5115 | 5115 | #undef CSON_REALLOC_IMPL |
| 5116 | 5116 | /* end file ./cson.c */ |
| 5117 | | -/* begin file ./cson_pack.c */ |
| 5118 | | -/* LICENSE |
| 5119 | | - |
| 5120 | | -Copyright (c) 2018 Guido Berhoerster <[email protected]> |
| 5121 | | - |
| 5122 | | -Permission is hereby granted, free of charge, to any person |
| 5123 | | -obtaining a copy of this software and associated documentation |
| 5124 | | -files (the "Software"), to deal in the Software without |
| 5125 | | -restriction, including without limitation the rights to use, |
| 5126 | | -copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 5127 | | -copies of the Software, and to permit persons to whom the |
| 5128 | | -Software is furnished to do so, subject to the following |
| 5129 | | -conditions: |
| 5130 | | - |
| 5131 | | -The above copyright notice and this permission notice shall be |
| 5132 | | -included in all copies or substantial portions of the Software. |
| 5133 | | - |
| 5134 | | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 5135 | | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| 5136 | | -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 5137 | | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| 5138 | | -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 5139 | | -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 5140 | | -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 5141 | | -OTHER DEALINGS IN THE SOFTWARE. |
| 5142 | | - |
| 5143 | | -*/ |
| 5144 | | - |
| 5145 | | -#include <assert.h> |
| 5146 | | -#include <stdlib.h> |
| 5147 | | -#include <string.h> |
| 5148 | | - |
| 5149 | | - |
| 5150 | | -#if __STDC_VERSION__ >= 199901L |
| 5151 | | -#define INLINE inline |
| 5152 | | -#else |
| 5153 | | -#define INLINE |
| 5154 | | -#endif /* __STDC_VERSION__ >= 199901L */ |
| 5155 | | - |
| 5156 | | -#define PACK_IGNORED_CHARS " \t\r\n:," |
| 5157 | | - |
| 5158 | | -enum parser_state { |
| 5159 | | - STATE_INVALID, |
| 5160 | | - STATE_INITIAL, |
| 5161 | | - STATE_END, |
| 5162 | | - STATE_ARRAY_VALUE, |
| 5163 | | - STATE_PROPERTY_NAME, |
| 5164 | | - STATE_PROPERTY_VALUE |
| 5165 | | -}; |
| 5166 | | - |
| 5167 | | -struct token |
| 5168 | | -{ |
| 5169 | | - int type; /* type specifier */ |
| 5170 | | - int optional; /* optional property modifier */ |
| 5171 | | - int suppress; /* suppress assignment modifier */ |
| 5172 | | - int alloc; /* assignment allocation modifier */ |
| 5173 | | - int len_l; /* long length modifier */ |
| 5174 | | -}; |
| 5175 | | - |
| 5176 | | -struct state |
| 5177 | | -{ |
| 5178 | | - cson_value * parent_value; |
| 5179 | | - const char * property_name; |
| 5180 | | - enum parser_state parser_state; |
| 5181 | | - int property_optional; |
| 5182 | | - unsigned int index; |
| 5183 | | -}; |
| 5184 | | - |
| 5185 | | -struct state_stack |
| 5186 | | -{ |
| 5187 | | - size_t capacity; |
| 5188 | | - size_t top; |
| 5189 | | - struct state *state; |
| 5190 | | -}; |
| 5191 | | - |
| 5192 | | -union pack_value |
| 5193 | | -{ |
| 5194 | | - cson_array * array; |
| 5195 | | - cson_object * object; |
| 5196 | | - const char * string; |
| 5197 | | - cson_int_t i; |
| 5198 | | - double d; |
| 5199 | | - char b; |
| 5200 | | -}; |
| 5201 | | - |
| 5202 | | -union unpack_value |
| 5203 | | -{ |
| 5204 | | - cson_array ** arrayp; |
| 5205 | | - cson_object ** objectp; |
| 5206 | | - const char ** stringp; |
| 5207 | | - char ** astringp; |
| 5208 | | - cson_int_t * ip; |
| 5209 | | - double * dp; |
| 5210 | | - char * bp; |
| 5211 | | -}; |
| 5212 | | - |
| 5213 | | -static const char * next_token( const char * s, struct token * tok ) |
| 5214 | | -{ |
| 5215 | | - tok->type = -1; |
| 5216 | | - tok->optional = 0; |
| 5217 | | - tok->suppress = 0; |
| 5218 | | - tok->alloc = 0; |
| 5219 | | - tok->len_l = 0; |
| 5220 | | - |
| 5221 | | - /* skip ignored characters */ |
| 5222 | | - while( ( *s != '\0' ) && ( strchr( PACK_IGNORED_CHARS, *s ) != NULL ) ) |
| 5223 | | - { |
| 5224 | | - s++; |
| 5225 | | - } |
| 5226 | | - |
| 5227 | | - switch( *s ) |
| 5228 | | - { |
| 5229 | | - case '%': |
| 5230 | | - for( s++; *s != '\0'; s++ ) |
| 5231 | | - { |
| 5232 | | - switch( *s ) |
| 5233 | | - { |
| 5234 | | - case '?': |
| 5235 | | - tok->optional++; |
| 5236 | | - break; |
| 5237 | | - case '*': |
| 5238 | | - tok->suppress++; |
| 5239 | | - break; |
| 5240 | | - case 'm': |
| 5241 | | - tok->alloc++; |
| 5242 | | - break; |
| 5243 | | - case 'l': |
| 5244 | | - tok->len_l++; |
| 5245 | | - break; |
| 5246 | | - case 'D': |
| 5247 | | - /* short form of "lld" */ |
| 5248 | | - tok->len_l += 2; |
| 5249 | | - tok->type = 'd'; |
| 5250 | | - s++; |
| 5251 | | - goto out; |
| 5252 | | - case 'i': |
| 5253 | | - /* same as 'd' */ |
| 5254 | | - tok->type = 'd'; |
| 5255 | | - s++; |
| 5256 | | - goto out; |
| 5257 | | - case 's': /* FALLTHROUGH */ |
| 5258 | | - case 'd': /* FALLTHROUGH */ |
| 5259 | | - case 'f': /* FALLTHROUGH */ |
| 5260 | | - case 'b': /* FALLTHROUGH */ |
| 5261 | | - case 'N': /* FALLTHROUGH */ |
| 5262 | | - case '[': /* FALLTHROUGH */ |
| 5263 | | - case '{': |
| 5264 | | - tok->type = *s++; |
| 5265 | | - goto out; |
| 5266 | | - default: |
| 5267 | | - return ( NULL ); |
| 5268 | | - } |
| 5269 | | - } |
| 5270 | | - return ( NULL ); |
| 5271 | | - case '[': /* FALLTHROUGH */ |
| 5272 | | - case '{': |
| 5273 | | - /* short form of "*[" or "*{" */ |
| 5274 | | - tok->type = *s++; |
| 5275 | | - tok->suppress = 1; |
| 5276 | | - break; |
| 5277 | | - case ']': /* FALLTHROUGH */ |
| 5278 | | - case '}': |
| 5279 | | - tok->type = *s++; |
| 5280 | | - break; |
| 5281 | | - case '\0': |
| 5282 | | - tok->type = *s; |
| 5283 | | - break; |
| 5284 | | - default: |
| 5285 | | - return ( NULL ); |
| 5286 | | - } |
| 5287 | | - |
| 5288 | | -out: |
| 5289 | | - if( ( tok->optional > 1 ) || ( tok->suppress > 1 ) || ( tok->alloc > 1 ) || |
| 5290 | | - ( tok->len_l > 2 ) || ( ( tok->type != 'd' ) && ( tok->len_l > 0 ) ) ) |
| 5291 | | - { |
| 5292 | | - return ( NULL ); |
| 5293 | | - } |
| 5294 | | - |
| 5295 | | - return ( s ); |
| 5296 | | -} |
| 5297 | | - |
| 5298 | | -static struct state_stack * state_stack_create( size_t capacity ) |
| 5299 | | -{ |
| 5300 | | - struct state_stack * stack; |
| 5301 | | - |
| 5302 | | - assert( capacity >= 2 ); |
| 5303 | | - |
| 5304 | | - stack = malloc( sizeof( struct state_stack ) ); |
| 5305 | | - if( stack == NULL ) |
| 5306 | | - { |
| 5307 | | - return ( NULL ); |
| 5308 | | - } |
| 5309 | | - stack->state = malloc( capacity * sizeof( struct state ) ); |
| 5310 | | - if( stack->state == NULL ) |
| 5311 | | - { |
| 5312 | | - return ( NULL ); |
| 5313 | | - } |
| 5314 | | - stack->top = 0; |
| 5315 | | - stack->capacity = capacity; |
| 5316 | | - /* initialize bottom of the stack */ |
| 5317 | | - stack->state[0].parser_state = STATE_INVALID; |
| 5318 | | - stack->state[0].parent_value = NULL; |
| 5319 | | - stack->state[0].property_name = NULL; |
| 5320 | | - stack->state[0].property_optional = 0; |
| 5321 | | - stack->state[0].index = 0; |
| 5322 | | - |
| 5323 | | - return ( stack ); |
| 5324 | | -} |
| 5325 | | - |
| 5326 | | -static INLINE struct state * state_stack_top( struct state_stack * stack ) |
| 5327 | | -{ |
| 5328 | | - assert( stack->top >= 1 ); |
| 5329 | | - |
| 5330 | | - return ( &stack->state[stack->top] ); |
| 5331 | | -} |
| 5332 | | - |
| 5333 | | -static INLINE void state_stack_push( struct state_stack * stack, |
| 5334 | | - enum parser_state parser_state, |
| 5335 | | - cson_value * parent_value, |
| 5336 | | - const char * property_name, |
| 5337 | | - int property_optional, |
| 5338 | | - unsigned int index ) |
| 5339 | | -{ |
| 5340 | | - struct state * state = &stack->state[++stack->top]; |
| 5341 | | - |
| 5342 | | - state->parser_state = parser_state; |
| 5343 | | - state->parent_value = parent_value; |
| 5344 | | - state->property_name = property_name; |
| 5345 | | - state->property_optional = property_optional; |
| 5346 | | - state->index = index; |
| 5347 | | -} |
| 5348 | | - |
| 5349 | | -static INLINE void state_stack_pop( struct state_stack * stack ) |
| 5350 | | -{ |
| 5351 | | - assert( stack->top >= 1 ); |
| 5352 | | - |
| 5353 | | - stack->top--; |
| 5354 | | -} |
| 5355 | | - |
| 5356 | | -static int |
| 5357 | | -on_pack_initial( struct state_stack * stack, |
| 5358 | | - struct token * tok, |
| 5359 | | - union pack_value * pack_value, |
| 5360 | | - cson_value ** root_valuep ) |
| 5361 | | -{ |
| 5362 | | - cson_value * value; |
| 5363 | | - cson_value * root_value; |
| 5364 | | - |
| 5365 | | - if( tok->optional || tok->alloc ) |
| 5366 | | - { |
| 5367 | | - /* invalid modifier */ |
| 5368 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5369 | | - } |
| 5370 | | - |
| 5371 | | - if( tok->type == '[' ) |
| 5372 | | - { |
| 5373 | | - if( tok->suppress ) |
| 5374 | | - { |
| 5375 | | - root_value = cson_value_new_array( ); |
| 5376 | | - if( root_value == NULL ) |
| 5377 | | - { |
| 5378 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5379 | | - } |
| 5380 | | - } |
| 5381 | | - else |
| 5382 | | - { |
| 5383 | | - value = cson_array_value( pack_value->array ); |
| 5384 | | - root_value = cson_value_clone( value ); |
| 5385 | | - } |
| 5386 | | - |
| 5387 | | - state_stack_pop( stack ); |
| 5388 | | - state_stack_push( stack, STATE_END, NULL, NULL, 0, 0 ); |
| 5389 | | - state_stack_push( stack, STATE_ARRAY_VALUE, root_value, NULL, 0, 0 ); |
| 5390 | | - } |
| 5391 | | - else if( tok->type == '{' ) |
| 5392 | | - { |
| 5393 | | - if( tok->suppress ) |
| 5394 | | - { |
| 5395 | | - root_value = cson_value_new_object( ); |
| 5396 | | - if( root_value == NULL ) |
| 5397 | | - { |
| 5398 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5399 | | - } |
| 5400 | | - } |
| 5401 | | - else |
| 5402 | | - { |
| 5403 | | - value = cson_object_value( pack_value->object ); |
| 5404 | | - root_value = cson_value_clone( value ); |
| 5405 | | - } |
| 5406 | | - |
| 5407 | | - state_stack_pop( stack ); |
| 5408 | | - state_stack_push( stack, STATE_END, NULL, NULL, 0, 0 ); |
| 5409 | | - state_stack_push( stack, STATE_PROPERTY_NAME, root_value, NULL, 0, 0 ); |
| 5410 | | - } |
| 5411 | | - else |
| 5412 | | - { |
| 5413 | | - /* root value is neither an object nor an array */ |
| 5414 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5415 | | - } |
| 5416 | | - |
| 5417 | | - *root_valuep = root_value; |
| 5418 | | - |
| 5419 | | - return ( 0 ); |
| 5420 | | -} |
| 5421 | | - |
| 5422 | | -static int on_pack_property_name( struct state_stack * stack, struct token * tok, const char * property_name ) |
| 5423 | | -{ |
| 5424 | | - cson_value * parent_value; |
| 5425 | | - |
| 5426 | | - if( tok->optional || tok->suppress || tok->alloc ) |
| 5427 | | - { |
| 5428 | | - /* invalid modifier */ |
| 5429 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5430 | | - } |
| 5431 | | - |
| 5432 | | - if( tok->type == 's' ) |
| 5433 | | - { |
| 5434 | | - parent_value = state_stack_top( stack )->parent_value; |
| 5435 | | - state_stack_pop( stack ); |
| 5436 | | - state_stack_push( stack, STATE_PROPERTY_VALUE, parent_value, property_name, 0, 0 ); |
| 5437 | | - } |
| 5438 | | - else if( tok->type == '}' ) |
| 5439 | | - { |
| 5440 | | - state_stack_pop( stack ); |
| 5441 | | - } |
| 5442 | | - else |
| 5443 | | - { |
| 5444 | | - /* neither property specifier nor end of object */ |
| 5445 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5446 | | - } |
| 5447 | | - |
| 5448 | | - return ( 0 ); |
| 5449 | | -} |
| 5450 | | - |
| 5451 | | -static int |
| 5452 | | -handle_pack_value( struct state_stack * stack, |
| 5453 | | - struct token * tok, |
| 5454 | | - union pack_value * pack_value, |
| 5455 | | - enum parser_state new_parser_state ) |
| 5456 | | -{ |
| 5457 | | - cson_value * value; |
| 5458 | | - cson_object * object; |
| 5459 | | - cson_array * array; |
| 5460 | | - int cson_retval; |
| 5461 | | - struct state * state; |
| 5462 | | - cson_value * parent_value; |
| 5463 | | - |
| 5464 | | - /* create value */ |
| 5465 | | - switch( tok->type ) |
| 5466 | | - { |
| 5467 | | - case '[': |
| 5468 | | - value = tok->suppress ? cson_value_new_array( ) : |
| 5469 | | - cson_value_clone( cson_array_value( pack_value->array ) ); |
| 5470 | | - if( value == NULL ) |
| 5471 | | - { |
| 5472 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5473 | | - } |
| 5474 | | - break; |
| 5475 | | - case '{': |
| 5476 | | - value = tok->suppress ? cson_value_new_object( ) : |
| 5477 | | - cson_value_clone( cson_object_value( pack_value->object ) ); |
| 5478 | | - if( value == NULL ) |
| 5479 | | - { |
| 5480 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5481 | | - } |
| 5482 | | - break; |
| 5483 | | - case 's': |
| 5484 | | - value = cson_value_new_string( pack_value->string, strlen( pack_value->string ) ); |
| 5485 | | - if( value == NULL ) |
| 5486 | | - { |
| 5487 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5488 | | - } |
| 5489 | | - break; |
| 5490 | | - case 'd': |
| 5491 | | - value = cson_value_new_integer( pack_value->i ); |
| 5492 | | - if( value == NULL ) |
| 5493 | | - { |
| 5494 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5495 | | - } |
| 5496 | | - break; |
| 5497 | | - case 'f': |
| 5498 | | - value = cson_value_new_double( pack_value->d ); |
| 5499 | | - if( value == NULL ) |
| 5500 | | - { |
| 5501 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5502 | | - } |
| 5503 | | - break; |
| 5504 | | - case 'b': |
| 5505 | | - value = cson_value_new_bool( pack_value->b ); |
| 5506 | | - if( value == NULL ) |
| 5507 | | - { |
| 5508 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5509 | | - } |
| 5510 | | - break; |
| 5511 | | - case 'N': |
| 5512 | | - value = cson_value_null( ); |
| 5513 | | - break; |
| 5514 | | - default: |
| 5515 | | - /* invalid token type */ |
| 5516 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5517 | | - } |
| 5518 | | - |
| 5519 | | - state = state_stack_top( stack ); |
| 5520 | | - parent_value = state->parent_value; |
| 5521 | | - if( cson_value_is_object( parent_value ) ) |
| 5522 | | - { |
| 5523 | | - /* set object property to value */ |
| 5524 | | - object = cson_value_get_object( parent_value ); |
| 5525 | | - cson_retval = cson_object_set( object, state->property_name, value ); |
| 5526 | | - if( cson_retval != 0 ) |
| 5527 | | - { |
| 5528 | | - cson_value_free( value ); |
| 5529 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5530 | | - } |
| 5531 | | - } |
| 5532 | | - else if( cson_value_is_array( parent_value ) ) |
| 5533 | | - { |
| 5534 | | - /* append array value */ |
| 5535 | | - array = cson_value_get_array( parent_value ); |
| 5536 | | - cson_retval = cson_array_append( array, value ); |
| 5537 | | - if( cson_retval != 0 ) |
| 5538 | | - { |
| 5539 | | - cson_value_free( value ); |
| 5540 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5541 | | - } |
| 5542 | | - } |
| 5543 | | - |
| 5544 | | - if( tok->type == '[' ) |
| 5545 | | - { |
| 5546 | | - state_stack_pop( stack ); |
| 5547 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, 0 ); |
| 5548 | | - state_stack_push( stack, STATE_ARRAY_VALUE, value, NULL, 0, 0 ); |
| 5549 | | - } |
| 5550 | | - else if( tok->type == '{' ) |
| 5551 | | - { |
| 5552 | | - state_stack_pop( stack ); |
| 5553 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, 0 ); |
| 5554 | | - state_stack_push( stack, STATE_PROPERTY_NAME, value, NULL, 0, 0 ); |
| 5555 | | - } |
| 5556 | | - else |
| 5557 | | - { |
| 5558 | | - state_stack_pop( stack ); |
| 5559 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, 0 ); |
| 5560 | | - } |
| 5561 | | - |
| 5562 | | - return ( 0 ); |
| 5563 | | -} |
| 5564 | | - |
| 5565 | | -static int on_pack_array_value( struct state_stack * stack, struct token * tok, union pack_value * pack_value ) |
| 5566 | | -{ |
| 5567 | | - if( tok->optional || tok->alloc || ( tok->suppress && ( tok->type != '{' ) && ( tok->type != '[' ) ) ) |
| 5568 | | - { |
| 5569 | | - /* invalid modifier */ |
| 5570 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5571 | | - } |
| 5572 | | - |
| 5573 | | - if( tok->type == ']' ) |
| 5574 | | - { |
| 5575 | | - /* end of array specifier */ |
| 5576 | | - state_stack_pop( stack ); |
| 5577 | | - |
| 5578 | | - return ( 0 ); |
| 5579 | | - } |
| 5580 | | - |
| 5581 | | - return ( handle_pack_value( stack, tok, pack_value, STATE_ARRAY_VALUE ) ); |
| 5582 | | -} |
| 5583 | | - |
| 5584 | | -static int on_pack_property_value( struct state_stack * stack, struct token * tok, union pack_value * pack_value ) |
| 5585 | | -{ |
| 5586 | | - if( tok->optional || tok->alloc || ( tok->suppress && ( tok->type != '{' ) && ( tok->type != '[' ) ) ) |
| 5587 | | - { |
| 5588 | | - /* invalid modifier */ |
| 5589 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5590 | | - } |
| 5591 | | - |
| 5592 | | - return ( handle_pack_value( stack, tok, pack_value, STATE_PROPERTY_NAME ) ); |
| 5593 | | -} |
| 5594 | | - |
| 5595 | | -int cson_vpack( cson_value ** root_valuep, const char * fmt, va_list args ) |
| 5596 | | -{ |
| 5597 | | - int retval = CSON_PACK_INTERNAL_ERROR; |
| 5598 | | - cson_value * root_value = NULL; |
| 5599 | | - struct state_stack * stack = NULL; |
| 5600 | | - const char * p = fmt; |
| 5601 | | - struct token tok = { 0 }; |
| 5602 | | - struct state * state; |
| 5603 | | - union pack_value pack_value = { 0 }; |
| 5604 | | - const char * property_name; |
| 5605 | | - |
| 5606 | | - stack = state_stack_create( strlen( fmt ) + 2 ); |
| 5607 | | - if( stack == NULL ) |
| 5608 | | - { |
| 5609 | | - retval = CSON_PACK_ALLOC_ERROR; |
| 5610 | | - goto out; |
| 5611 | | - } |
| 5612 | | - state_stack_push( stack, STATE_INITIAL, NULL, NULL, 0, 0 ); |
| 5613 | | - |
| 5614 | | - for( p = next_token( p, &tok ); p != NULL; p = next_token( p, &tok ) ) |
| 5615 | | - { |
| 5616 | | - state = state_stack_top( stack ); |
| 5617 | | - if( state->parser_state == STATE_PROPERTY_NAME ) |
| 5618 | | - { |
| 5619 | | - property_name = ( tok.type == 's' ) ? va_arg( args, const char * ) : NULL; |
| 5620 | | - } |
| 5621 | | - else if( !tok.suppress ) |
| 5622 | | - { |
| 5623 | | - switch( tok.type ) |
| 5624 | | - { |
| 5625 | | - case '[': |
| 5626 | | - pack_value.array = va_arg( args, cson_array * ); |
| 5627 | | - break; |
| 5628 | | - case '{': |
| 5629 | | - pack_value.object = va_arg( args, cson_object * ); |
| 5630 | | - break; |
| 5631 | | - case 's': |
| 5632 | | - pack_value.string = va_arg( args, const char * ); |
| 5633 | | - break; |
| 5634 | | - case 'd': |
| 5635 | | - if( tok.len_l == 0 ) |
| 5636 | | - { |
| 5637 | | - pack_value.i = va_arg( args, int ); |
| 5638 | | - } |
| 5639 | | - else if( tok.len_l == 1 ) |
| 5640 | | - { |
| 5641 | | - pack_value.i = va_arg( args, long ); |
| 5642 | | - } |
| 5643 | | - else |
| 5644 | | - { |
| 5645 | | - pack_value.i = va_arg( args, cson_int_t ); |
| 5646 | | - } |
| 5647 | | - break; |
| 5648 | | - case 'f': |
| 5649 | | - pack_value.d = va_arg( args, double ); |
| 5650 | | - break; |
| 5651 | | - case 'b': |
| 5652 | | - pack_value.b = va_arg( args, int ); |
| 5653 | | - break; |
| 5654 | | - } |
| 5655 | | - } |
| 5656 | | - |
| 5657 | | - switch( state->parser_state ) |
| 5658 | | - { |
| 5659 | | - case STATE_INITIAL: |
| 5660 | | - retval = on_pack_initial( stack, &tok, &pack_value, &root_value ); |
| 5661 | | - if( retval != 0 ) |
| 5662 | | - { |
| 5663 | | - goto out; |
| 5664 | | - } |
| 5665 | | - break; |
| 5666 | | - case STATE_END: |
| 5667 | | - /* check for trailing characters */ |
| 5668 | | - retval = ( tok.type == '\0' ) ? 0 : CSON_PACK_ARG_ERROR; |
| 5669 | | - goto out; |
| 5670 | | - case STATE_PROPERTY_NAME: |
| 5671 | | - retval = on_pack_property_name( stack, &tok, property_name ); |
| 5672 | | - if( retval != 0 ) |
| 5673 | | - { |
| 5674 | | - goto out; |
| 5675 | | - } |
| 5676 | | - break; |
| 5677 | | - case STATE_PROPERTY_VALUE: |
| 5678 | | - retval = on_pack_property_value( stack, &tok, &pack_value ); |
| 5679 | | - if( retval != 0 ) |
| 5680 | | - { |
| 5681 | | - goto out; |
| 5682 | | - } |
| 5683 | | - break; |
| 5684 | | - case STATE_ARRAY_VALUE: |
| 5685 | | - retval = on_pack_array_value( stack, &tok, &pack_value ); |
| 5686 | | - if( retval != 0 ) |
| 5687 | | - { |
| 5688 | | - goto out; |
| 5689 | | - } |
| 5690 | | - break; |
| 5691 | | - default: |
| 5692 | | - retval = CSON_PACK_INTERNAL_ERROR; |
| 5693 | | - goto out; |
| 5694 | | - } |
| 5695 | | - } |
| 5696 | | - if( p == NULL ) |
| 5697 | | - { |
| 5698 | | - /* parse error */ |
| 5699 | | - retval = CSON_PACK_ARG_ERROR; |
| 5700 | | - } |
| 5701 | | - |
| 5702 | | -out: |
| 5703 | | - if( retval == 0 ) |
| 5704 | | - { |
| 5705 | | - *root_valuep = root_value; |
| 5706 | | - } |
| 5707 | | - else |
| 5708 | | - { |
| 5709 | | - cson_value_free( root_value ); |
| 5710 | | - } |
| 5711 | | - if( stack != NULL ) { |
| 5712 | | - free( stack->state ); |
| 5713 | | - free( stack ); |
| 5714 | | - } |
| 5715 | | - |
| 5716 | | - return ( retval ); |
| 5717 | | -} |
| 5718 | | - |
| 5719 | | -int cson_pack( cson_value ** root_valuep, const char * fmt, ... ) |
| 5720 | | -{ |
| 5721 | | - int retval; |
| 5722 | | - va_list args; |
| 5723 | | - |
| 5724 | | - va_start( args, fmt ); |
| 5725 | | - retval = cson_vpack( root_valuep, fmt, args ); |
| 5726 | | - va_end( args ); |
| 5727 | | - |
| 5728 | | - return ( retval ); |
| 5729 | | -} |
| 5730 | | - |
| 5731 | | -static int on_unpack_initial( struct state_stack * stack, struct token * tok, union unpack_value * unpack_value ) |
| 5732 | | -{ |
| 5733 | | - int subst = 0; |
| 5734 | | - cson_value * root_value; |
| 5735 | | - |
| 5736 | | - if( tok->optional || tok->alloc ) |
| 5737 | | - { |
| 5738 | | - /* invalid modifier */ |
| 5739 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5740 | | - } |
| 5741 | | - |
| 5742 | | - root_value = state_stack_top( stack )->parent_value; |
| 5743 | | - if( tok->type == '[' ) |
| 5744 | | - { |
| 5745 | | - if( !cson_value_is_array( root_value ) ) |
| 5746 | | - { |
| 5747 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5748 | | - } |
| 5749 | | - |
| 5750 | | - if( !tok->suppress ) |
| 5751 | | - { |
| 5752 | | - *unpack_value->arrayp = cson_value_get_array( root_value ); |
| 5753 | | - subst = 1; |
| 5754 | | - } |
| 5755 | | - |
| 5756 | | - state_stack_pop( stack ); |
| 5757 | | - state_stack_push( stack, STATE_END, NULL, NULL, 0, 0 ); |
| 5758 | | - state_stack_push( stack, STATE_ARRAY_VALUE, root_value, NULL, 0, 0 ); |
| 5759 | | - } |
| 5760 | | - else if( tok->type == '{' ) |
| 5761 | | - { |
| 5762 | | - if( !cson_value_is_object( root_value ) ) |
| 5763 | | - { |
| 5764 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5765 | | - } |
| 5766 | | - |
| 5767 | | - if( !tok->suppress ) |
| 5768 | | - { |
| 5769 | | - *unpack_value->objectp = cson_value_get_object( root_value ); |
| 5770 | | - subst = 1; |
| 5771 | | - } |
| 5772 | | - |
| 5773 | | - state_stack_pop( stack ); |
| 5774 | | - state_stack_push( stack, STATE_END, NULL, NULL, 0, 0 ); |
| 5775 | | - state_stack_push( stack, STATE_PROPERTY_NAME, root_value, NULL, 0, 0 ); |
| 5776 | | - } |
| 5777 | | - else |
| 5778 | | - { |
| 5779 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5780 | | - } |
| 5781 | | - |
| 5782 | | - return ( subst ); |
| 5783 | | -} |
| 5784 | | - |
| 5785 | | -static int on_unpack_property_name( struct state_stack * stack, struct token * tok, const char * property_name ) |
| 5786 | | -{ |
| 5787 | | - cson_value * parent_value; |
| 5788 | | - |
| 5789 | | - if( tok->type == '}' ) |
| 5790 | | - { |
| 5791 | | - state_stack_pop( stack ); |
| 5792 | | - } |
| 5793 | | - else if( tok->type == 's' ) |
| 5794 | | - { |
| 5795 | | - if( tok->suppress || tok->alloc ) |
| 5796 | | - { |
| 5797 | | - /* invalid modifier */ |
| 5798 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5799 | | - } |
| 5800 | | - |
| 5801 | | - parent_value = state_stack_top( stack )->parent_value; |
| 5802 | | - state_stack_pop( stack ); |
| 5803 | | - state_stack_push( stack, STATE_PROPERTY_VALUE, parent_value, property_name, tok->optional, 0 ); |
| 5804 | | - } |
| 5805 | | - else |
| 5806 | | - { |
| 5807 | | - /* neither property specifier nor end of object */ |
| 5808 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5809 | | - } |
| 5810 | | - |
| 5811 | | - return ( 0 ); |
| 5812 | | -} |
| 5813 | | - |
| 5814 | | -static int handle_unpack_value( struct state_stack * stack, |
| 5815 | | - struct token * tok, |
| 5816 | | - cson_value * value, |
| 5817 | | - union unpack_value * unpack_value, |
| 5818 | | - enum parser_state new_parser_state ) |
| 5819 | | -{ |
| 5820 | | - int subst = 0; |
| 5821 | | - struct state * state; |
| 5822 | | - cson_value * parent_value; |
| 5823 | | - unsigned int index; |
| 5824 | | - int skip; |
| 5825 | | - const char * string; |
| 5826 | | - char * astring; |
| 5827 | | - size_t len; |
| 5828 | | - |
| 5829 | | - state = state_stack_top( stack ); |
| 5830 | | - parent_value = state->parent_value; |
| 5831 | | - index = state->index; |
| 5832 | | - skip = ( parent_value == NULL ) || ( value == NULL ); |
| 5833 | | - |
| 5834 | | - switch( tok->type ) |
| 5835 | | - { |
| 5836 | | - case 's': |
| 5837 | | - if( !skip ) |
| 5838 | | - { |
| 5839 | | - if( !cson_value_is_string( value ) ) |
| 5840 | | - { |
| 5841 | | - /* property value is not a string */ |
| 5842 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5843 | | - } |
| 5844 | | - |
| 5845 | | - if( !tok->suppress ) |
| 5846 | | - { |
| 5847 | | - string = cson_value_get_cstr( value ); |
| 5848 | | - if( tok->alloc ) |
| 5849 | | - { |
| 5850 | | - len = strlen ( string ); |
| 5851 | | - astring = malloc( len + 1 ); |
| 5852 | | - if( astring == NULL ) |
| 5853 | | - { |
| 5854 | | - return ( CSON_PACK_ALLOC_ERROR ); |
| 5855 | | - } |
| 5856 | | - memcpy( astring, string, len + 1 ); |
| 5857 | | - *unpack_value->astringp = astring; |
| 5858 | | - } |
| 5859 | | - else |
| 5860 | | - { |
| 5861 | | - *unpack_value->stringp = string; |
| 5862 | | - } |
| 5863 | | - subst = 1; |
| 5864 | | - } |
| 5865 | | - } |
| 5866 | | - |
| 5867 | | - state_stack_pop( stack ); |
| 5868 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5869 | | - break; |
| 5870 | | - case 'd': |
| 5871 | | - if( !skip ) |
| 5872 | | - { |
| 5873 | | - if( !cson_value_is_integer( value ) ) |
| 5874 | | - { |
| 5875 | | - /* property value is not an integer */ |
| 5876 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5877 | | - } |
| 5878 | | - |
| 5879 | | - if( !tok->suppress ) |
| 5880 | | - { |
| 5881 | | - *unpack_value->ip = cson_value_get_integer( value ); |
| 5882 | | - subst = 1; |
| 5883 | | - } |
| 5884 | | - } |
| 5885 | | - |
| 5886 | | - state_stack_pop( stack ); |
| 5887 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5888 | | - break; |
| 5889 | | - case 'f': |
| 5890 | | - if( !skip ) |
| 5891 | | - { |
| 5892 | | - if( !cson_value_is_double( value ) ) |
| 5893 | | - { |
| 5894 | | - /* property value is not a float */ |
| 5895 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5896 | | - } |
| 5897 | | - |
| 5898 | | - if( !tok->suppress ) |
| 5899 | | - { |
| 5900 | | - *unpack_value->dp = cson_value_get_double( value ); |
| 5901 | | - subst = 1; |
| 5902 | | - } |
| 5903 | | - } |
| 5904 | | - |
| 5905 | | - state_stack_pop( stack ); |
| 5906 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5907 | | - break; |
| 5908 | | - case 'b': |
| 5909 | | - if( !skip ) |
| 5910 | | - { |
| 5911 | | - if( !cson_value_is_bool( value ) ) |
| 5912 | | - { |
| 5913 | | - /* property value is not a boolean */ |
| 5914 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5915 | | - } |
| 5916 | | - |
| 5917 | | - if( !tok->suppress ) |
| 5918 | | - { |
| 5919 | | - *unpack_value->bp = cson_value_get_bool( value ); |
| 5920 | | - subst = 1; |
| 5921 | | - } |
| 5922 | | - } |
| 5923 | | - |
| 5924 | | - state_stack_pop( stack ); |
| 5925 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5926 | | - break; |
| 5927 | | - case 'N': |
| 5928 | | - if( !skip ) |
| 5929 | | - { |
| 5930 | | - if( !cson_value_is_null( value ) ) |
| 5931 | | - { |
| 5932 | | - /* property value is not an array */ |
| 5933 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5934 | | - } |
| 5935 | | - } |
| 5936 | | - |
| 5937 | | - state_stack_pop( stack ); |
| 5938 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5939 | | - break; |
| 5940 | | - case '[': |
| 5941 | | - if( !skip ) |
| 5942 | | - { |
| 5943 | | - if( !cson_value_is_array( value ) ) |
| 5944 | | - { |
| 5945 | | - /* property value is not an array */ |
| 5946 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5947 | | - } |
| 5948 | | - |
| 5949 | | - if( !tok->suppress ) |
| 5950 | | - { |
| 5951 | | - *unpack_value->arrayp = cson_value_get_array( value ); |
| 5952 | | - subst = 1; |
| 5953 | | - } |
| 5954 | | - } |
| 5955 | | - |
| 5956 | | - state_stack_pop( stack ); |
| 5957 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5958 | | - state_stack_push( stack, STATE_ARRAY_VALUE, value, NULL, 0, 0 ); |
| 5959 | | - break; |
| 5960 | | - case '{': |
| 5961 | | - if( !skip ) |
| 5962 | | - { |
| 5963 | | - if( !cson_value_is_object( value ) ) |
| 5964 | | - { |
| 5965 | | - /* property value is not an object */ |
| 5966 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 5967 | | - } |
| 5968 | | - |
| 5969 | | - if( !tok->suppress ) |
| 5970 | | - { |
| 5971 | | - *unpack_value->objectp = cson_value_get_object( value ); |
| 5972 | | - subst = 1; |
| 5973 | | - } |
| 5974 | | - } |
| 5975 | | - |
| 5976 | | - state_stack_pop( stack ); |
| 5977 | | - state_stack_push( stack, new_parser_state, parent_value, NULL, 0, index ); |
| 5978 | | - state_stack_push( stack, STATE_PROPERTY_NAME, value, NULL, 0, 0 ); |
| 5979 | | - break; |
| 5980 | | - default: |
| 5981 | | - return ( CSON_PACK_INTERNAL_ERROR ); |
| 5982 | | - } |
| 5983 | | - |
| 5984 | | - return ( subst ); |
| 5985 | | -} |
| 5986 | | - |
| 5987 | | -static int on_unpack_array_value( struct state_stack * stack, struct token * tok, union unpack_value * unpack_value ) |
| 5988 | | -{ |
| 5989 | | - struct state * state; |
| 5990 | | - cson_array * array; |
| 5991 | | - cson_value * value = NULL; |
| 5992 | | - |
| 5993 | | - if( tok->optional ) |
| 5994 | | - { |
| 5995 | | - /* invalid modifier */ |
| 5996 | | - return ( CSON_PACK_ARG_ERROR ); |
| 5997 | | - } |
| 5998 | | - |
| 5999 | | - if( tok->type == ']' ) |
| 6000 | | - { |
| 6001 | | - state_stack_pop( stack ); |
| 6002 | | - |
| 6003 | | - return ( 0 ); |
| 6004 | | - } |
| 6005 | | - else if( ( tok->type != 's' ) && tok->alloc ) |
| 6006 | | - { |
| 6007 | | - /* invalid modifier */ |
| 6008 | | - return ( CSON_PACK_ARG_ERROR ); |
| 6009 | | - } |
| 6010 | | - |
| 6011 | | - state = state_stack_top( stack ); |
| 6012 | | - if( state->parent_value != NULL ) |
| 6013 | | - { |
| 6014 | | - /* get next array value */ |
| 6015 | | - array = cson_value_get_array( state->parent_value ); |
| 6016 | | - value = cson_array_get( array, state->index ); |
| 6017 | | - if( value == NULL ) |
| 6018 | | - { |
| 6019 | | - /* index out of bounds */ |
| 6020 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 6021 | | - } |
| 6022 | | - } |
| 6023 | | - state->index++; |
| 6024 | | - |
| 6025 | | - return ( handle_unpack_value( stack, tok, value, unpack_value, STATE_ARRAY_VALUE ) ); |
| 6026 | | -} |
| 6027 | | - |
| 6028 | | -static int on_unpack_property_value( struct state_stack * stack, struct token * tok, union unpack_value * unpack_value ) |
| 6029 | | -{ |
| 6030 | | - struct state * state; |
| 6031 | | - cson_object * object; |
| 6032 | | - cson_value * value; |
| 6033 | | - |
| 6034 | | - if( ( tok->optional ) || ( ( tok->type != 's' ) && tok->alloc ) ) |
| 6035 | | - { |
| 6036 | | - /* invalid modifier */ |
| 6037 | | - return ( CSON_PACK_ARG_ERROR ); |
| 6038 | | - } |
| 6039 | | - |
| 6040 | | - state = state_stack_top( stack ); |
| 6041 | | - object = cson_value_get_object( state->parent_value ); |
| 6042 | | - value = cson_object_get( object, state->property_name ); |
| 6043 | | - if( !state->property_optional && ( value == NULL ) ) |
| 6044 | | - { |
| 6045 | | - /* missing mandatory property */ |
| 6046 | | - return ( CSON_PACK_VALIDATION_ERROR ); |
| 6047 | | - } |
| 6048 | | - |
| 6049 | | - return ( handle_unpack_value( stack, tok, value, unpack_value, STATE_PROPERTY_NAME ) ); |
| 6050 | | -} |
| 6051 | | - |
| 6052 | | -int cson_vunpack( cson_value * root_value, const char * fmt, va_list args ) |
| 6053 | | -{ |
| 6054 | | - int retval = CSON_PACK_INTERNAL_ERROR; |
| 6055 | | - int subst = 0; |
| 6056 | | - struct state_stack * stack = NULL; |
| 6057 | | - struct state * state; |
| 6058 | | - const char * p = fmt; |
| 6059 | | - struct token tok = { 0 }; |
| 6060 | | - union unpack_value unpack_value = { 0 }; |
| 6061 | | - const char * property_name; |
| 6062 | | - |
| 6063 | | - if( root_value == NULL ) |
| 6064 | | - { |
| 6065 | | - retval = CSON_PACK_ARG_ERROR; |
| 6066 | | - goto out; |
| 6067 | | - } |
| 6068 | | - |
| 6069 | | - stack = state_stack_create( strlen( fmt ) + 2 ); /* worst case */ |
| 6070 | | - if( stack == NULL ) |
| 6071 | | - { |
| 6072 | | - retval = CSON_PACK_ALLOC_ERROR; |
| 6073 | | - goto out; |
| 6074 | | - } |
| 6075 | | - state_stack_push( stack, STATE_INITIAL, root_value, NULL, 0, 0 ); |
| 6076 | | - |
| 6077 | | - for( p = next_token( p, &tok ); p != NULL; p = next_token( p, &tok ) ) |
| 6078 | | - { |
| 6079 | | - state = state_stack_top( stack ); |
| 6080 | | - if( state->parser_state == STATE_PROPERTY_NAME ) |
| 6081 | | - { |
| 6082 | | - property_name = ( tok.type == 's' ) ? va_arg( args, const char * ) : NULL; |
| 6083 | | - } |
| 6084 | | - else if( !tok.suppress ) |
| 6085 | | - { |
| 6086 | | - switch( tok.type ) |
| 6087 | | - { |
| 6088 | | - case '[': |
| 6089 | | - unpack_value.arrayp = va_arg( args, cson_array ** ); |
| 6090 | | - break; |
| 6091 | | - case '{': |
| 6092 | | - unpack_value.objectp = va_arg( args, cson_object ** ); |
| 6093 | | - break; |
| 6094 | | - case 's': |
| 6095 | | - if( tok.alloc ) |
| 6096 | | - { |
| 6097 | | - unpack_value.astringp = va_arg( args, char ** ); |
| 6098 | | - } |
| 6099 | | - else |
| 6100 | | - { |
| 6101 | | - unpack_value.stringp = va_arg( args, const char ** ); |
| 6102 | | - } |
| 6103 | | - break; |
| 6104 | | - case 'd': |
| 6105 | | - if( tok.len_l != 2 ) |
| 6106 | | - { |
| 6107 | | - /* |
| 6108 | | - * parsed values are always of type |
| 6109 | | - * cson_int_t |
| 6110 | | - */ |
| 6111 | | - retval = CSON_PACK_ARG_ERROR; |
| 6112 | | - goto out; |
| 6113 | | - } |
| 6114 | | - unpack_value.ip = va_arg( args, cson_int_t * ); |
| 6115 | | - break; |
| 6116 | | - case 'f': |
| 6117 | | - unpack_value.dp = va_arg( args, double * ); |
| 6118 | | - break; |
| 6119 | | - case 'b': |
| 6120 | | - unpack_value.bp = va_arg( args, char * ); |
| 6121 | | - break; |
| 6122 | | - } |
| 6123 | | - } |
| 6124 | | - |
| 6125 | | - switch( state->parser_state ) |
| 6126 | | - { |
| 6127 | | - case STATE_INITIAL: |
| 6128 | | - retval = on_unpack_initial( stack, &tok, &unpack_value ); |
| 6129 | | - if( retval < 0 ) |
| 6130 | | - { |
| 6131 | | - goto out; |
| 6132 | | - } |
| 6133 | | - subst += retval; |
| 6134 | | - break; |
| 6135 | | - case STATE_END: |
| 6136 | | - /* check for trailing characters */ |
| 6137 | | - retval = ( tok.type == '\0' ) ? subst : CSON_PACK_ARG_ERROR; |
| 6138 | | - goto out; |
| 6139 | | - case STATE_PROPERTY_NAME: |
| 6140 | | - retval = on_unpack_property_name( stack, &tok, property_name ); |
| 6141 | | - if( retval != 0 ) |
| 6142 | | - { |
| 6143 | | - goto out; |
| 6144 | | - } |
| 6145 | | - break; |
| 6146 | | - case STATE_PROPERTY_VALUE: |
| 6147 | | - retval = on_unpack_property_value( stack, &tok, &unpack_value ); |
| 6148 | | - if( retval < 0 ) |
| 6149 | | - { |
| 6150 | | - goto out; |
| 6151 | | - } |
| 6152 | | - subst += retval; |
| 6153 | | - break; |
| 6154 | | - case STATE_ARRAY_VALUE: |
| 6155 | | - retval = on_unpack_array_value( stack, &tok, &unpack_value ); |
| 6156 | | - if( retval < 0 ) |
| 6157 | | - { |
| 6158 | | - goto out; |
| 6159 | | - } |
| 6160 | | - subst += retval; |
| 6161 | | - break; |
| 6162 | | - default: |
| 6163 | | - retval = CSON_PACK_INTERNAL_ERROR; |
| 6164 | | - goto out; |
| 6165 | | - } |
| 6166 | | - } |
| 6167 | | - if( p == NULL ) |
| 6168 | | - { |
| 6169 | | - /* parse error */ |
| 6170 | | - retval = CSON_PACK_ARG_ERROR; |
| 6171 | | - } |
| 6172 | | - |
| 6173 | | -out: |
| 6174 | | - if( stack != NULL ) { |
| 6175 | | - free( stack->state ); |
| 6176 | | - free( stack ); |
| 6177 | | - } |
| 6178 | | - |
| 6179 | | - return ( retval ); |
| 6180 | | -} |
| 6181 | | - |
| 6182 | | -int cson_unpack( cson_value * root_value, const char * fmt, ... ) |
| 6183 | | -{ |
| 6184 | | - int retval; |
| 6185 | | - va_list args; |
| 6186 | | - |
| 6187 | | - va_start( args, fmt ); |
| 6188 | | - retval = cson_vunpack( root_value, fmt, args ); |
| 6189 | | - va_end( args ); |
| 6190 | | - |
| 6191 | | - return ( retval ); |
| 6192 | | -} |
| 6193 | | -/* end file ./cson_pack.c */ |
| 6194 | 5117 | /* begin file ./cson_lists.h */ |
| 6195 | 5118 | /* Auto-generated from cson_list.h. Edit at your own risk! */ |
| 6196 | 5119 | unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n ) |
| 6197 | 5120 | { |
| 6198 | 5121 | if( !self ) return 0; |
| 6199 | 5122 | |