ucl_emitter.c (1709ccf9d38a5753192420ce5fccd93b04ce4d07) ucl_emitter.c (b04a7a0baf6523245034b8ccd06cd0176b8a18cf)
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

--- 27 unchanged lines hidden (view full) ---

36#endif
37
38/**
39 * @file rcl_emitter.c
40 * Serialise UCL object to various of output formats
41 */
42
43
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

--- 27 unchanged lines hidden (view full) ---

36#endif
37
38/**
39 * @file rcl_emitter.c
40 * Serialise UCL object to various of output formats
41 */
42
43
44static void ucl_obj_write_json (ucl_object_t *obj,
44static void ucl_obj_write_json (const ucl_object_t *obj,
45 struct ucl_emitter_functions *func,
46 unsigned int tabs,
47 bool start_tabs,
48 bool compact);
45 struct ucl_emitter_functions *func,
46 unsigned int tabs,
47 bool start_tabs,
48 bool compact);
49static void ucl_elt_write_json (ucl_object_t *obj,
49static void ucl_elt_write_json (const ucl_object_t *obj,
50 struct ucl_emitter_functions *func,
51 unsigned int tabs,
52 bool start_tabs,
53 bool compact);
50 struct ucl_emitter_functions *func,
51 unsigned int tabs,
52 bool start_tabs,
53 bool compact);
54static void ucl_elt_write_config (ucl_object_t *obj,
54static void ucl_elt_write_config (const ucl_object_t *obj,
55 struct ucl_emitter_functions *func,
56 unsigned int tabs,
57 bool start_tabs,
58 bool is_top,
59 bool expand_array);
55 struct ucl_emitter_functions *func,
56 unsigned int tabs,
57 bool start_tabs,
58 bool is_top,
59 bool expand_array);
60static void ucl_elt_write_yaml (ucl_object_t *obj,
60static void ucl_elt_write_yaml (const ucl_object_t *obj,
61 struct ucl_emitter_functions *func,
62 unsigned int tabs,
63 bool start_tabs,
64 bool compact,
65 bool expand_array);
61 struct ucl_emitter_functions *func,
62 unsigned int tabs,
63 bool start_tabs,
64 bool compact,
65 bool expand_array);
66static void ucl_elt_array_write_yaml (ucl_object_t *obj,
66static void ucl_elt_array_write_yaml (const ucl_object_t *obj,
67 struct ucl_emitter_functions *func,
68 unsigned int tabs,
69 bool start_tabs,
70 bool is_top);
71
72/**
73 * Add tabulation to the output buffer
74 * @param buf target buffer

--- 64 unchanged lines hidden (view full) ---

139}
140
141/**
142 * Write a single object to the buffer
143 * @param obj object to write
144 * @param buf target buffer
145 */
146static void
67 struct ucl_emitter_functions *func,
68 unsigned int tabs,
69 bool start_tabs,
70 bool is_top);
71
72/**
73 * Add tabulation to the output buffer
74 * @param buf target buffer

--- 64 unchanged lines hidden (view full) ---

139}
140
141/**
142 * Write a single object to the buffer
143 * @param obj object to write
144 * @param buf target buffer
145 */
146static void
147ucl_elt_obj_write_json (ucl_object_t *obj, struct ucl_emitter_functions *func,
147ucl_elt_obj_write_json (const ucl_object_t *obj, struct ucl_emitter_functions *func,
148 unsigned int tabs, bool start_tabs, bool compact)
149{
148 unsigned int tabs, bool start_tabs, bool compact)
149{
150 ucl_object_t *cur;
150 const ucl_object_t *cur;
151 ucl_hash_iter_t it = NULL;
152
153 if (start_tabs) {
154 ucl_add_tabs (func, tabs, compact);
155 }
156 if (compact) {
157 func->ucl_emitter_append_character ('{', 1, func->ud);
158 }

--- 32 unchanged lines hidden (view full) ---

191}
192
193/**
194 * Write a single array to the buffer
195 * @param obj array to write
196 * @param buf target buffer
197 */
198static void
151 ucl_hash_iter_t it = NULL;
152
153 if (start_tabs) {
154 ucl_add_tabs (func, tabs, compact);
155 }
156 if (compact) {
157 func->ucl_emitter_append_character ('{', 1, func->ud);
158 }

--- 32 unchanged lines hidden (view full) ---

191}
192
193/**
194 * Write a single array to the buffer
195 * @param obj array to write
196 * @param buf target buffer
197 */
198static void
199ucl_elt_array_write_json (ucl_object_t *obj, struct ucl_emitter_functions *func,
199ucl_elt_array_write_json (const ucl_object_t *obj, struct ucl_emitter_functions *func,
200 unsigned int tabs, bool start_tabs, bool compact)
201{
200 unsigned int tabs, bool start_tabs, bool compact)
201{
202 ucl_object_t *cur = obj;
202 const ucl_object_t *cur = obj;
203
204 if (start_tabs) {
205 ucl_add_tabs (func, tabs, compact);
206 }
207 if (compact) {
208 func->ucl_emitter_append_character ('[', 1, func->ud);
209 }
210 else {

--- 19 unchanged lines hidden (view full) ---

230}
231
232/**
233 * Emit a single element
234 * @param obj object
235 * @param buf buffer
236 */
237static void
203
204 if (start_tabs) {
205 ucl_add_tabs (func, tabs, compact);
206 }
207 if (compact) {
208 func->ucl_emitter_append_character ('[', 1, func->ud);
209 }
210 else {

--- 19 unchanged lines hidden (view full) ---

230}
231
232/**
233 * Emit a single element
234 * @param obj object
235 * @param buf buffer
236 */
237static void
238ucl_elt_write_json (ucl_object_t *obj, struct ucl_emitter_functions *func,
238ucl_elt_write_json (const ucl_object_t *obj, struct ucl_emitter_functions *func,
239 unsigned int tabs, bool start_tabs, bool compact)
240{
241 bool flag;
242
243 switch (obj->type) {
244 case UCL_INT:
245 if (start_tabs) {
246 ucl_add_tabs (func, tabs, compact);

--- 43 unchanged lines hidden (view full) ---

290}
291
292/**
293 * Write a single object to the buffer
294 * @param obj object
295 * @param buf target buffer
296 */
297static void
239 unsigned int tabs, bool start_tabs, bool compact)
240{
241 bool flag;
242
243 switch (obj->type) {
244 case UCL_INT:
245 if (start_tabs) {
246 ucl_add_tabs (func, tabs, compact);

--- 43 unchanged lines hidden (view full) ---

290}
291
292/**
293 * Write a single object to the buffer
294 * @param obj object
295 * @param buf target buffer
296 */
297static void
298ucl_obj_write_json (ucl_object_t *obj, struct ucl_emitter_functions *func,
298ucl_obj_write_json (const ucl_object_t *obj, struct ucl_emitter_functions *func,
299 unsigned int tabs, bool start_tabs, bool compact)
300{
299 unsigned int tabs, bool start_tabs, bool compact)
300{
301 ucl_object_t *cur;
301 const ucl_object_t *cur;
302 bool is_array = (obj->next != NULL);
303
304 if (is_array) {
305 /* This is an array actually */
306 if (start_tabs) {
307 ucl_add_tabs (func, tabs, compact);
308 }
309

--- 24 unchanged lines hidden (view full) ---

334}
335
336/**
337 * Emit an object to json
338 * @param obj object
339 * @return json output (should be freed after using)
340 */
341static void
302 bool is_array = (obj->next != NULL);
303
304 if (is_array) {
305 /* This is an array actually */
306 if (start_tabs) {
307 ucl_add_tabs (func, tabs, compact);
308 }
309

--- 24 unchanged lines hidden (view full) ---

334}
335
336/**
337 * Emit an object to json
338 * @param obj object
339 * @return json output (should be freed after using)
340 */
341static void
342ucl_object_emit_json (ucl_object_t *obj, bool compact, struct ucl_emitter_functions *func)
342ucl_object_emit_json (const ucl_object_t *obj, bool compact,
343 struct ucl_emitter_functions *func)
343{
344 ucl_obj_write_json (obj, func, 0, false, compact);
345}
346
347/**
348 * Write a single object to the buffer
349 * @param obj object to write
350 * @param buf target buffer
351 */
352static void
344{
345 ucl_obj_write_json (obj, func, 0, false, compact);
346}
347
348/**
349 * Write a single object to the buffer
350 * @param obj object to write
351 * @param buf target buffer
352 */
353static void
353ucl_elt_obj_write_config (ucl_object_t *obj, struct ucl_emitter_functions *func,
354ucl_elt_obj_write_config (const ucl_object_t *obj, struct ucl_emitter_functions *func,
354 unsigned int tabs, bool start_tabs, bool is_top)
355{
355 unsigned int tabs, bool start_tabs, bool is_top)
356{
356 ucl_object_t *cur, *cur_obj;
357 const ucl_object_t *cur, *cur_obj;
357 ucl_hash_iter_t it = NULL;
358
359 if (start_tabs) {
360 ucl_add_tabs (func, tabs, is_top);
361 }
362 if (!is_top) {
363 func->ucl_emitter_append_len ("{\n", 2, func->ud);
364 }

--- 32 unchanged lines hidden (view full) ---

397}
398
399/**
400 * Write a single array to the buffer
401 * @param obj array to write
402 * @param buf target buffer
403 */
404static void
358 ucl_hash_iter_t it = NULL;
359
360 if (start_tabs) {
361 ucl_add_tabs (func, tabs, is_top);
362 }
363 if (!is_top) {
364 func->ucl_emitter_append_len ("{\n", 2, func->ud);
365 }

--- 32 unchanged lines hidden (view full) ---

398}
399
400/**
401 * Write a single array to the buffer
402 * @param obj array to write
403 * @param buf target buffer
404 */
405static void
405ucl_elt_array_write_config (ucl_object_t *obj, struct ucl_emitter_functions *func,
406ucl_elt_array_write_config (const ucl_object_t *obj, struct ucl_emitter_functions *func,
406 unsigned int tabs, bool start_tabs, bool is_top)
407{
407 unsigned int tabs, bool start_tabs, bool is_top)
408{
408 ucl_object_t *cur = obj;
409 const ucl_object_t *cur = obj;
409
410 if (start_tabs) {
411 ucl_add_tabs (func, tabs, false);
412 }
413
414 func->ucl_emitter_append_len ("[\n", 2, func->ud);
415 while (cur) {
416 ucl_elt_write_config (cur, func, tabs + 1, true, false, false);

--- 5 unchanged lines hidden (view full) ---

422}
423
424/**
425 * Emit a single element
426 * @param obj object
427 * @param buf buffer
428 */
429static void
410
411 if (start_tabs) {
412 ucl_add_tabs (func, tabs, false);
413 }
414
415 func->ucl_emitter_append_len ("[\n", 2, func->ud);
416 while (cur) {
417 ucl_elt_write_config (cur, func, tabs + 1, true, false, false);

--- 5 unchanged lines hidden (view full) ---

423}
424
425/**
426 * Emit a single element
427 * @param obj object
428 * @param buf buffer
429 */
430static void
430ucl_elt_write_config (ucl_object_t *obj, struct ucl_emitter_functions *func,
431ucl_elt_write_config (const ucl_object_t *obj, struct ucl_emitter_functions *func,
431 unsigned int tabs, bool start_tabs, bool is_top, bool expand_array)
432{
433 bool flag;
434
435 if (expand_array && obj->next != NULL) {
436 ucl_elt_array_write_config (obj, func, tabs, start_tabs, is_top);
437 }
438 else {

--- 48 unchanged lines hidden (view full) ---

487}
488
489/**
490 * Emit an object to rcl
491 * @param obj object
492 * @return rcl output (should be freed after using)
493 */
494static void
432 unsigned int tabs, bool start_tabs, bool is_top, bool expand_array)
433{
434 bool flag;
435
436 if (expand_array && obj->next != NULL) {
437 ucl_elt_array_write_config (obj, func, tabs, start_tabs, is_top);
438 }
439 else {

--- 48 unchanged lines hidden (view full) ---

488}
489
490/**
491 * Emit an object to rcl
492 * @param obj object
493 * @return rcl output (should be freed after using)
494 */
495static void
495ucl_object_emit_config (ucl_object_t *obj, struct ucl_emitter_functions *func)
496ucl_object_emit_config (const ucl_object_t *obj, struct ucl_emitter_functions *func)
496{
497 ucl_elt_write_config (obj, func, 0, false, true, true);
498}
499
500
501static void
497{
498 ucl_elt_write_config (obj, func, 0, false, true, true);
499}
500
501
502static void
502ucl_obj_write_yaml (ucl_object_t *obj, struct ucl_emitter_functions *func,
503ucl_obj_write_yaml (const ucl_object_t *obj, struct ucl_emitter_functions *func,
503 unsigned int tabs, bool start_tabs)
504{
505 bool is_array = (obj->next != NULL);
506
507 if (is_array) {
508 ucl_elt_array_write_yaml (obj, func, tabs, start_tabs, false);
509 }
510 else {
511 ucl_elt_write_yaml (obj, func, tabs, start_tabs, false, true);
512 }
513}
514
515/**
516 * Write a single object to the buffer
517 * @param obj object to write
518 * @param buf target buffer
519 */
520static void
504 unsigned int tabs, bool start_tabs)
505{
506 bool is_array = (obj->next != NULL);
507
508 if (is_array) {
509 ucl_elt_array_write_yaml (obj, func, tabs, start_tabs, false);
510 }
511 else {
512 ucl_elt_write_yaml (obj, func, tabs, start_tabs, false, true);
513 }
514}
515
516/**
517 * Write a single object to the buffer
518 * @param obj object to write
519 * @param buf target buffer
520 */
521static void
521ucl_elt_obj_write_yaml (ucl_object_t *obj, struct ucl_emitter_functions *func,
522ucl_elt_obj_write_yaml (const ucl_object_t *obj, struct ucl_emitter_functions *func,
522 unsigned int tabs, bool start_tabs, bool is_top)
523{
523 unsigned int tabs, bool start_tabs, bool is_top)
524{
524 ucl_object_t *cur;
525 const ucl_object_t *cur;
525 ucl_hash_iter_t it = NULL;
526
527 if (start_tabs) {
528 ucl_add_tabs (func, tabs, is_top);
529 }
530 if (!is_top) {
531 func->ucl_emitter_append_len ("{\n", 2, func->ud);
532 }

--- 28 unchanged lines hidden (view full) ---

561}
562
563/**
564 * Write a single array to the buffer
565 * @param obj array to write
566 * @param buf target buffer
567 */
568static void
526 ucl_hash_iter_t it = NULL;
527
528 if (start_tabs) {
529 ucl_add_tabs (func, tabs, is_top);
530 }
531 if (!is_top) {
532 func->ucl_emitter_append_len ("{\n", 2, func->ud);
533 }

--- 28 unchanged lines hidden (view full) ---

562}
563
564/**
565 * Write a single array to the buffer
566 * @param obj array to write
567 * @param buf target buffer
568 */
569static void
569ucl_elt_array_write_yaml (ucl_object_t *obj, struct ucl_emitter_functions *func,
570ucl_elt_array_write_yaml (const ucl_object_t *obj, struct ucl_emitter_functions *func,
570 unsigned int tabs, bool start_tabs, bool is_top)
571{
571 unsigned int tabs, bool start_tabs, bool is_top)
572{
572 ucl_object_t *cur = obj;
573 const ucl_object_t *cur = obj;
573
574 if (start_tabs) {
575 ucl_add_tabs (func, tabs, false);
576 }
577
578 func->ucl_emitter_append_len ("[\n", 2, func->ud);
579 while (cur) {
580 ucl_elt_write_yaml (cur, func, tabs + 1, true, false, false);

--- 5 unchanged lines hidden (view full) ---

586}
587
588/**
589 * Emit a single element
590 * @param obj object
591 * @param buf buffer
592 */
593static void
574
575 if (start_tabs) {
576 ucl_add_tabs (func, tabs, false);
577 }
578
579 func->ucl_emitter_append_len ("[\n", 2, func->ud);
580 while (cur) {
581 ucl_elt_write_yaml (cur, func, tabs + 1, true, false, false);

--- 5 unchanged lines hidden (view full) ---

587}
588
589/**
590 * Emit a single element
591 * @param obj object
592 * @param buf buffer
593 */
594static void
594ucl_elt_write_yaml (ucl_object_t *obj, struct ucl_emitter_functions *func,
595ucl_elt_write_yaml (const ucl_object_t *obj, struct ucl_emitter_functions *func,
595 unsigned int tabs, bool start_tabs, bool is_top, bool expand_array)
596{
597 bool flag;
598
599 if (expand_array && obj->next != NULL ) {
600 ucl_elt_array_write_yaml (obj, func, tabs, start_tabs, is_top);
601 }
602 else {

--- 48 unchanged lines hidden (view full) ---

651}
652
653/**
654 * Emit an object to rcl
655 * @param obj object
656 * @return rcl output (should be freed after using)
657 */
658static void
596 unsigned int tabs, bool start_tabs, bool is_top, bool expand_array)
597{
598 bool flag;
599
600 if (expand_array && obj->next != NULL ) {
601 ucl_elt_array_write_yaml (obj, func, tabs, start_tabs, is_top);
602 }
603 else {

--- 48 unchanged lines hidden (view full) ---

652}
653
654/**
655 * Emit an object to rcl
656 * @param obj object
657 * @return rcl output (should be freed after using)
658 */
659static void
659ucl_object_emit_yaml (ucl_object_t *obj, struct ucl_emitter_functions *func)
660ucl_object_emit_yaml (const ucl_object_t *obj, struct ucl_emitter_functions *func)
660{
661 ucl_elt_write_yaml (obj, func, 0, false, true, true);
662}
663
664/*
665 * Generic utstring output
666 */
667static int

--- 50 unchanged lines hidden (view full) ---

718 utstring_printf (buf, "%lf", val);
719 }
720
721 return 0;
722}
723
724
725unsigned char *
661{
662 ucl_elt_write_yaml (obj, func, 0, false, true, true);
663}
664
665/*
666 * Generic utstring output
667 */
668static int

--- 50 unchanged lines hidden (view full) ---

719 utstring_printf (buf, "%lf", val);
720 }
721
722 return 0;
723}
724
725
726unsigned char *
726ucl_object_emit (ucl_object_t *obj, enum ucl_emitter emit_type)
727ucl_object_emit (const ucl_object_t *obj, enum ucl_emitter emit_type)
727{
728 UT_string *buf = NULL;
729 unsigned char *res = NULL;
730 struct ucl_emitter_functions func = {
731 .ucl_emitter_append_character = ucl_utstring_append_character,
732 .ucl_emitter_append_len = ucl_utstring_append_len,
733 .ucl_emitter_append_int = ucl_utstring_append_int,
734 .ucl_emitter_append_double = ucl_utstring_append_double

--- 23 unchanged lines hidden (view full) ---

758 res = utstring_body (buf);
759 free (buf);
760 }
761
762 return res;
763}
764
765bool
728{
729 UT_string *buf = NULL;
730 unsigned char *res = NULL;
731 struct ucl_emitter_functions func = {
732 .ucl_emitter_append_character = ucl_utstring_append_character,
733 .ucl_emitter_append_len = ucl_utstring_append_len,
734 .ucl_emitter_append_int = ucl_utstring_append_int,
735 .ucl_emitter_append_double = ucl_utstring_append_double

--- 23 unchanged lines hidden (view full) ---

759 res = utstring_body (buf);
760 free (buf);
761 }
762
763 return res;
764}
765
766bool
766ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type,
767ucl_object_emit_full (const ucl_object_t *obj, enum ucl_emitter emit_type,
767 struct ucl_emitter_functions *emitter)
768{
769 if (emit_type == UCL_EMIT_JSON) {
770 ucl_object_emit_json (obj, false, emitter);
771 }
772 else if (emit_type == UCL_EMIT_JSON_COMPACT) {
773 ucl_object_emit_json (obj, true, emitter);
774 }

--- 5 unchanged lines hidden (view full) ---

780 }
781
782 /* XXX: need some error checks here */
783 return true;
784}
785
786
787unsigned char *
768 struct ucl_emitter_functions *emitter)
769{
770 if (emit_type == UCL_EMIT_JSON) {
771 ucl_object_emit_json (obj, false, emitter);
772 }
773 else if (emit_type == UCL_EMIT_JSON_COMPACT) {
774 ucl_object_emit_json (obj, true, emitter);
775 }

--- 5 unchanged lines hidden (view full) ---

781 }
782
783 /* XXX: need some error checks here */
784 return true;
785}
786
787
788unsigned char *
788ucl_object_emit_single_json (ucl_object_t *obj)
789ucl_object_emit_single_json (const ucl_object_t *obj)
789{
790 UT_string *buf = NULL;
791 unsigned char *res = NULL;
792
793 if (obj == NULL) {
794 return NULL;
795 }
796

--- 41 unchanged lines hidden ---
790{
791 UT_string *buf = NULL;
792 unsigned char *res = NULL;
793
794 if (obj == NULL) {
795 return NULL;
796 }
797

--- 41 unchanged lines hidden ---