13dcf5eb7SBaptiste Daroussin /* Copyright (c) 2014, Vsevolod Stakhov 23dcf5eb7SBaptiste Daroussin * All rights reserved. 33dcf5eb7SBaptiste Daroussin * 43dcf5eb7SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 53dcf5eb7SBaptiste Daroussin * modification, are permitted provided that the following conditions are met: 63dcf5eb7SBaptiste Daroussin * * Redistributions of source code must retain the above copyright 73dcf5eb7SBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 83dcf5eb7SBaptiste Daroussin * * Redistributions in binary form must reproduce the above copyright 93dcf5eb7SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 103dcf5eb7SBaptiste Daroussin * documentation and/or other materials provided with the distribution. 113dcf5eb7SBaptiste Daroussin * 123dcf5eb7SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 133dcf5eb7SBaptiste Daroussin * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 143dcf5eb7SBaptiste Daroussin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 153dcf5eb7SBaptiste Daroussin * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 163dcf5eb7SBaptiste Daroussin * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 173dcf5eb7SBaptiste Daroussin * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 183dcf5eb7SBaptiste Daroussin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 193dcf5eb7SBaptiste Daroussin * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 203dcf5eb7SBaptiste Daroussin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 213dcf5eb7SBaptiste Daroussin * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 223dcf5eb7SBaptiste Daroussin */ 233dcf5eb7SBaptiste Daroussin 243dcf5eb7SBaptiste Daroussin #ifdef HAVE_CONFIG_H 253dcf5eb7SBaptiste Daroussin #include "config.h" 263dcf5eb7SBaptiste Daroussin #endif 273dcf5eb7SBaptiste Daroussin 283dcf5eb7SBaptiste Daroussin #include "ucl.h" 293dcf5eb7SBaptiste Daroussin #include "ucl_internal.h" 303dcf5eb7SBaptiste Daroussin #include "ucl_chartable.h" 313dcf5eb7SBaptiste Daroussin 323dcf5eb7SBaptiste Daroussin #ifdef HAVE_FLOAT_H 333dcf5eb7SBaptiste Daroussin #include <float.h> 343dcf5eb7SBaptiste Daroussin #endif 353dcf5eb7SBaptiste Daroussin #ifdef HAVE_MATH_H 363dcf5eb7SBaptiste Daroussin #include <math.h> 373dcf5eb7SBaptiste Daroussin #endif 383dcf5eb7SBaptiste Daroussin 393dcf5eb7SBaptiste Daroussin extern const struct ucl_emitter_operations ucl_standartd_emitter_ops[]; 403dcf5eb7SBaptiste Daroussin 413dcf5eb7SBaptiste Daroussin static const struct ucl_emitter_context ucl_standard_emitters[] = { 423dcf5eb7SBaptiste Daroussin [UCL_EMIT_JSON] = { 433dcf5eb7SBaptiste Daroussin .name = "json", 443dcf5eb7SBaptiste Daroussin .id = UCL_EMIT_JSON, 453dcf5eb7SBaptiste Daroussin .func = NULL, 463dcf5eb7SBaptiste Daroussin .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON] 473dcf5eb7SBaptiste Daroussin }, 483dcf5eb7SBaptiste Daroussin [UCL_EMIT_JSON_COMPACT] = { 493dcf5eb7SBaptiste Daroussin .name = "json_compact", 503dcf5eb7SBaptiste Daroussin .id = UCL_EMIT_JSON_COMPACT, 513dcf5eb7SBaptiste Daroussin .func = NULL, 523dcf5eb7SBaptiste Daroussin .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON_COMPACT] 533dcf5eb7SBaptiste Daroussin }, 543dcf5eb7SBaptiste Daroussin [UCL_EMIT_CONFIG] = { 553dcf5eb7SBaptiste Daroussin .name = "config", 563dcf5eb7SBaptiste Daroussin .id = UCL_EMIT_CONFIG, 573dcf5eb7SBaptiste Daroussin .func = NULL, 583dcf5eb7SBaptiste Daroussin .ops = &ucl_standartd_emitter_ops[UCL_EMIT_CONFIG] 593dcf5eb7SBaptiste Daroussin }, 603dcf5eb7SBaptiste Daroussin [UCL_EMIT_YAML] = { 613dcf5eb7SBaptiste Daroussin .name = "yaml", 623dcf5eb7SBaptiste Daroussin .id = UCL_EMIT_YAML, 633dcf5eb7SBaptiste Daroussin .func = NULL, 643dcf5eb7SBaptiste Daroussin .ops = &ucl_standartd_emitter_ops[UCL_EMIT_YAML] 653dcf5eb7SBaptiste Daroussin } 663dcf5eb7SBaptiste Daroussin }; 673dcf5eb7SBaptiste Daroussin 683dcf5eb7SBaptiste Daroussin /** 693dcf5eb7SBaptiste Daroussin * Get standard emitter context for a specified emit_type 703dcf5eb7SBaptiste Daroussin * @param emit_type type of emitter 713dcf5eb7SBaptiste Daroussin * @return context or NULL if input is invalid 723dcf5eb7SBaptiste Daroussin */ 733dcf5eb7SBaptiste Daroussin const struct ucl_emitter_context * 743dcf5eb7SBaptiste Daroussin ucl_emit_get_standard_context (enum ucl_emitter emit_type) 753dcf5eb7SBaptiste Daroussin { 763dcf5eb7SBaptiste Daroussin if (emit_type >= UCL_EMIT_JSON && emit_type <= UCL_EMIT_YAML) { 773dcf5eb7SBaptiste Daroussin return &ucl_standard_emitters[emit_type]; 783dcf5eb7SBaptiste Daroussin } 793dcf5eb7SBaptiste Daroussin 803dcf5eb7SBaptiste Daroussin return NULL; 813dcf5eb7SBaptiste Daroussin } 823dcf5eb7SBaptiste Daroussin 833dcf5eb7SBaptiste Daroussin /** 843dcf5eb7SBaptiste Daroussin * Serialise string 853dcf5eb7SBaptiste Daroussin * @param str string to emit 863dcf5eb7SBaptiste Daroussin * @param buf target buffer 873dcf5eb7SBaptiste Daroussin */ 883dcf5eb7SBaptiste Daroussin void 893dcf5eb7SBaptiste Daroussin ucl_elt_string_write_json (const char *str, size_t size, 903dcf5eb7SBaptiste Daroussin struct ucl_emitter_context *ctx) 913dcf5eb7SBaptiste Daroussin { 923dcf5eb7SBaptiste Daroussin const char *p = str, *c = str; 933dcf5eb7SBaptiste Daroussin size_t len = 0; 943dcf5eb7SBaptiste Daroussin const struct ucl_emitter_functions *func = ctx->func; 953dcf5eb7SBaptiste Daroussin 963dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_character ('"', 1, func->ud); 973dcf5eb7SBaptiste Daroussin 983dcf5eb7SBaptiste Daroussin while (size) { 993dcf5eb7SBaptiste Daroussin if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) { 1003dcf5eb7SBaptiste Daroussin if (len > 0) { 1013dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len (c, len, func->ud); 1023dcf5eb7SBaptiste Daroussin } 1033dcf5eb7SBaptiste Daroussin switch (*p) { 1043dcf5eb7SBaptiste Daroussin case '\n': 1053dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\n", 2, func->ud); 1063dcf5eb7SBaptiste Daroussin break; 1073dcf5eb7SBaptiste Daroussin case '\r': 1083dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\r", 2, func->ud); 1093dcf5eb7SBaptiste Daroussin break; 1103dcf5eb7SBaptiste Daroussin case '\b': 1113dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\b", 2, func->ud); 1123dcf5eb7SBaptiste Daroussin break; 1133dcf5eb7SBaptiste Daroussin case '\t': 1143dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\t", 2, func->ud); 1153dcf5eb7SBaptiste Daroussin break; 1163dcf5eb7SBaptiste Daroussin case '\f': 1173dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\f", 2, func->ud); 1183dcf5eb7SBaptiste Daroussin break; 1193dcf5eb7SBaptiste Daroussin case '\\': 1203dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\\\", 2, func->ud); 1213dcf5eb7SBaptiste Daroussin break; 1223dcf5eb7SBaptiste Daroussin case '"': 1233dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len ("\\\"", 2, func->ud); 1243dcf5eb7SBaptiste Daroussin break; 1253dcf5eb7SBaptiste Daroussin } 1263dcf5eb7SBaptiste Daroussin len = 0; 1273dcf5eb7SBaptiste Daroussin c = ++p; 1283dcf5eb7SBaptiste Daroussin } 1293dcf5eb7SBaptiste Daroussin else { 1303dcf5eb7SBaptiste Daroussin p ++; 1313dcf5eb7SBaptiste Daroussin len ++; 1323dcf5eb7SBaptiste Daroussin } 1333dcf5eb7SBaptiste Daroussin size --; 1343dcf5eb7SBaptiste Daroussin } 1353dcf5eb7SBaptiste Daroussin if (len > 0) { 1363dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_len (c, len, func->ud); 1373dcf5eb7SBaptiste Daroussin } 1383dcf5eb7SBaptiste Daroussin func->ucl_emitter_append_character ('"', 1, func->ud); 1393dcf5eb7SBaptiste Daroussin } 140*4bf54857SBaptiste Daroussin 141*4bf54857SBaptiste Daroussin void 142*4bf54857SBaptiste Daroussin ucl_elt_string_write_multiline (const char *str, size_t size, 143*4bf54857SBaptiste Daroussin struct ucl_emitter_context *ctx) 144*4bf54857SBaptiste Daroussin { 145*4bf54857SBaptiste Daroussin const struct ucl_emitter_functions *func = ctx->func; 146*4bf54857SBaptiste Daroussin 147*4bf54857SBaptiste Daroussin func->ucl_emitter_append_len ("<<EOD\n", sizeof ("<<EOD\n") - 1, func->ud); 148*4bf54857SBaptiste Daroussin func->ucl_emitter_append_len (str, size, func->ud); 149*4bf54857SBaptiste Daroussin func->ucl_emitter_append_len ("\nEOD", sizeof ("\nEOD") - 1, func->ud); 1503dcf5eb7SBaptiste Daroussin } 1513dcf5eb7SBaptiste Daroussin 1523dcf5eb7SBaptiste Daroussin /* 1533dcf5eb7SBaptiste Daroussin * Generic utstring output 1543dcf5eb7SBaptiste Daroussin */ 1553dcf5eb7SBaptiste Daroussin static int 1563dcf5eb7SBaptiste Daroussin ucl_utstring_append_character (unsigned char c, size_t len, void *ud) 1573dcf5eb7SBaptiste Daroussin { 1583dcf5eb7SBaptiste Daroussin UT_string *buf = ud; 1593dcf5eb7SBaptiste Daroussin 1603dcf5eb7SBaptiste Daroussin if (len == 1) { 1613dcf5eb7SBaptiste Daroussin utstring_append_c (buf, c); 1623dcf5eb7SBaptiste Daroussin } 1633dcf5eb7SBaptiste Daroussin else { 164*4bf54857SBaptiste Daroussin utstring_reserve (buf, len + 1); 1653dcf5eb7SBaptiste Daroussin memset (&buf->d[buf->i], c, len); 1663dcf5eb7SBaptiste Daroussin buf->i += len; 1673dcf5eb7SBaptiste Daroussin buf->d[buf->i] = '\0'; 1683dcf5eb7SBaptiste Daroussin } 1693dcf5eb7SBaptiste Daroussin 1703dcf5eb7SBaptiste Daroussin return 0; 1713dcf5eb7SBaptiste Daroussin } 1723dcf5eb7SBaptiste Daroussin 1733dcf5eb7SBaptiste Daroussin static int 1743dcf5eb7SBaptiste Daroussin ucl_utstring_append_len (const unsigned char *str, size_t len, void *ud) 1753dcf5eb7SBaptiste Daroussin { 1763dcf5eb7SBaptiste Daroussin UT_string *buf = ud; 1773dcf5eb7SBaptiste Daroussin 1783dcf5eb7SBaptiste Daroussin utstring_append_len (buf, str, len); 1793dcf5eb7SBaptiste Daroussin 1803dcf5eb7SBaptiste Daroussin return 0; 1813dcf5eb7SBaptiste Daroussin } 1823dcf5eb7SBaptiste Daroussin 1833dcf5eb7SBaptiste Daroussin static int 1843dcf5eb7SBaptiste Daroussin ucl_utstring_append_int (int64_t val, void *ud) 1853dcf5eb7SBaptiste Daroussin { 1863dcf5eb7SBaptiste Daroussin UT_string *buf = ud; 1873dcf5eb7SBaptiste Daroussin 1883dcf5eb7SBaptiste Daroussin utstring_printf (buf, "%jd", (intmax_t)val); 1893dcf5eb7SBaptiste Daroussin return 0; 1903dcf5eb7SBaptiste Daroussin } 1913dcf5eb7SBaptiste Daroussin 1923dcf5eb7SBaptiste Daroussin static int 1933dcf5eb7SBaptiste Daroussin ucl_utstring_append_double (double val, void *ud) 1943dcf5eb7SBaptiste Daroussin { 1953dcf5eb7SBaptiste Daroussin UT_string *buf = ud; 1963dcf5eb7SBaptiste Daroussin const double delta = 0.0000001; 1973dcf5eb7SBaptiste Daroussin 1983dcf5eb7SBaptiste Daroussin if (val == (double)(int)val) { 1993dcf5eb7SBaptiste Daroussin utstring_printf (buf, "%.1lf", val); 2003dcf5eb7SBaptiste Daroussin } 2013dcf5eb7SBaptiste Daroussin else if (fabs (val - (double)(int)val) < delta) { 2023dcf5eb7SBaptiste Daroussin /* Write at maximum precision */ 2033dcf5eb7SBaptiste Daroussin utstring_printf (buf, "%.*lg", DBL_DIG, val); 2043dcf5eb7SBaptiste Daroussin } 2053dcf5eb7SBaptiste Daroussin else { 2063dcf5eb7SBaptiste Daroussin utstring_printf (buf, "%lf", val); 2073dcf5eb7SBaptiste Daroussin } 2083dcf5eb7SBaptiste Daroussin 2093dcf5eb7SBaptiste Daroussin return 0; 2103dcf5eb7SBaptiste Daroussin } 2113dcf5eb7SBaptiste Daroussin 2123dcf5eb7SBaptiste Daroussin /* 2133dcf5eb7SBaptiste Daroussin * Generic file output 2143dcf5eb7SBaptiste Daroussin */ 2153dcf5eb7SBaptiste Daroussin static int 2163dcf5eb7SBaptiste Daroussin ucl_file_append_character (unsigned char c, size_t len, void *ud) 2173dcf5eb7SBaptiste Daroussin { 2183dcf5eb7SBaptiste Daroussin FILE *fp = ud; 2193dcf5eb7SBaptiste Daroussin 2203dcf5eb7SBaptiste Daroussin while (len --) { 2213dcf5eb7SBaptiste Daroussin fputc (c, fp); 2223dcf5eb7SBaptiste Daroussin } 2233dcf5eb7SBaptiste Daroussin 2243dcf5eb7SBaptiste Daroussin return 0; 2253dcf5eb7SBaptiste Daroussin } 2263dcf5eb7SBaptiste Daroussin 2273dcf5eb7SBaptiste Daroussin static int 2283dcf5eb7SBaptiste Daroussin ucl_file_append_len (const unsigned char *str, size_t len, void *ud) 2293dcf5eb7SBaptiste Daroussin { 2303dcf5eb7SBaptiste Daroussin FILE *fp = ud; 2313dcf5eb7SBaptiste Daroussin 2323dcf5eb7SBaptiste Daroussin fwrite (str, len, 1, fp); 2333dcf5eb7SBaptiste Daroussin 2343dcf5eb7SBaptiste Daroussin return 0; 2353dcf5eb7SBaptiste Daroussin } 2363dcf5eb7SBaptiste Daroussin 2373dcf5eb7SBaptiste Daroussin static int 2383dcf5eb7SBaptiste Daroussin ucl_file_append_int (int64_t val, void *ud) 2393dcf5eb7SBaptiste Daroussin { 2403dcf5eb7SBaptiste Daroussin FILE *fp = ud; 2413dcf5eb7SBaptiste Daroussin 2423dcf5eb7SBaptiste Daroussin fprintf (fp, "%jd", (intmax_t)val); 2433dcf5eb7SBaptiste Daroussin 2443dcf5eb7SBaptiste Daroussin return 0; 2453dcf5eb7SBaptiste Daroussin } 2463dcf5eb7SBaptiste Daroussin 2473dcf5eb7SBaptiste Daroussin static int 2483dcf5eb7SBaptiste Daroussin ucl_file_append_double (double val, void *ud) 2493dcf5eb7SBaptiste Daroussin { 2503dcf5eb7SBaptiste Daroussin FILE *fp = ud; 2513dcf5eb7SBaptiste Daroussin const double delta = 0.0000001; 2523dcf5eb7SBaptiste Daroussin 2533dcf5eb7SBaptiste Daroussin if (val == (double)(int)val) { 2543dcf5eb7SBaptiste Daroussin fprintf (fp, "%.1lf", val); 2553dcf5eb7SBaptiste Daroussin } 2563dcf5eb7SBaptiste Daroussin else if (fabs (val - (double)(int)val) < delta) { 2573dcf5eb7SBaptiste Daroussin /* Write at maximum precision */ 2583dcf5eb7SBaptiste Daroussin fprintf (fp, "%.*lg", DBL_DIG, val); 2593dcf5eb7SBaptiste Daroussin } 2603dcf5eb7SBaptiste Daroussin else { 2613dcf5eb7SBaptiste Daroussin fprintf (fp, "%lf", val); 2623dcf5eb7SBaptiste Daroussin } 2633dcf5eb7SBaptiste Daroussin 2643dcf5eb7SBaptiste Daroussin return 0; 2653dcf5eb7SBaptiste Daroussin } 2663dcf5eb7SBaptiste Daroussin 2673dcf5eb7SBaptiste Daroussin /* 2683dcf5eb7SBaptiste Daroussin * Generic file descriptor writing functions 2693dcf5eb7SBaptiste Daroussin */ 2703dcf5eb7SBaptiste Daroussin static int 2713dcf5eb7SBaptiste Daroussin ucl_fd_append_character (unsigned char c, size_t len, void *ud) 2723dcf5eb7SBaptiste Daroussin { 2733dcf5eb7SBaptiste Daroussin int fd = *(int *)ud; 2743dcf5eb7SBaptiste Daroussin unsigned char *buf; 2753dcf5eb7SBaptiste Daroussin 2763dcf5eb7SBaptiste Daroussin if (len == 1) { 277*4bf54857SBaptiste Daroussin return write (fd, &c, 1); 2783dcf5eb7SBaptiste Daroussin } 2793dcf5eb7SBaptiste Daroussin else { 2803dcf5eb7SBaptiste Daroussin buf = malloc (len); 2813dcf5eb7SBaptiste Daroussin if (buf == NULL) { 2823dcf5eb7SBaptiste Daroussin /* Fallback */ 2833dcf5eb7SBaptiste Daroussin while (len --) { 284*4bf54857SBaptiste Daroussin if (write (fd, &c, 1) == -1) { 285*4bf54857SBaptiste Daroussin return -1; 286*4bf54857SBaptiste Daroussin } 2873dcf5eb7SBaptiste Daroussin } 2883dcf5eb7SBaptiste Daroussin } 2893dcf5eb7SBaptiste Daroussin else { 2903dcf5eb7SBaptiste Daroussin memset (buf, c, len); 291*4bf54857SBaptiste Daroussin if (write (fd, buf, len) == -1) { 292*4bf54857SBaptiste Daroussin return -1; 293*4bf54857SBaptiste Daroussin } 2943dcf5eb7SBaptiste Daroussin free (buf); 2953dcf5eb7SBaptiste Daroussin } 2963dcf5eb7SBaptiste Daroussin } 2973dcf5eb7SBaptiste Daroussin 2983dcf5eb7SBaptiste Daroussin return 0; 2993dcf5eb7SBaptiste Daroussin } 3003dcf5eb7SBaptiste Daroussin 3013dcf5eb7SBaptiste Daroussin static int 3023dcf5eb7SBaptiste Daroussin ucl_fd_append_len (const unsigned char *str, size_t len, void *ud) 3033dcf5eb7SBaptiste Daroussin { 3043dcf5eb7SBaptiste Daroussin int fd = *(int *)ud; 3053dcf5eb7SBaptiste Daroussin 306*4bf54857SBaptiste Daroussin return write (fd, str, len); 3073dcf5eb7SBaptiste Daroussin } 3083dcf5eb7SBaptiste Daroussin 3093dcf5eb7SBaptiste Daroussin static int 3103dcf5eb7SBaptiste Daroussin ucl_fd_append_int (int64_t val, void *ud) 3113dcf5eb7SBaptiste Daroussin { 3123dcf5eb7SBaptiste Daroussin int fd = *(int *)ud; 3133dcf5eb7SBaptiste Daroussin char intbuf[64]; 3143dcf5eb7SBaptiste Daroussin 3153dcf5eb7SBaptiste Daroussin snprintf (intbuf, sizeof (intbuf), "%jd", (intmax_t)val); 316*4bf54857SBaptiste Daroussin return write (fd, intbuf, strlen (intbuf)); 3173dcf5eb7SBaptiste Daroussin } 3183dcf5eb7SBaptiste Daroussin 3193dcf5eb7SBaptiste Daroussin static int 3203dcf5eb7SBaptiste Daroussin ucl_fd_append_double (double val, void *ud) 3213dcf5eb7SBaptiste Daroussin { 3223dcf5eb7SBaptiste Daroussin int fd = *(int *)ud; 3233dcf5eb7SBaptiste Daroussin const double delta = 0.0000001; 3243dcf5eb7SBaptiste Daroussin char nbuf[64]; 3253dcf5eb7SBaptiste Daroussin 3263dcf5eb7SBaptiste Daroussin if (val == (double)(int)val) { 3273dcf5eb7SBaptiste Daroussin snprintf (nbuf, sizeof (nbuf), "%.1lf", val); 3283dcf5eb7SBaptiste Daroussin } 3293dcf5eb7SBaptiste Daroussin else if (fabs (val - (double)(int)val) < delta) { 3303dcf5eb7SBaptiste Daroussin /* Write at maximum precision */ 3313dcf5eb7SBaptiste Daroussin snprintf (nbuf, sizeof (nbuf), "%.*lg", DBL_DIG, val); 3323dcf5eb7SBaptiste Daroussin } 3333dcf5eb7SBaptiste Daroussin else { 3343dcf5eb7SBaptiste Daroussin snprintf (nbuf, sizeof (nbuf), "%lf", val); 3353dcf5eb7SBaptiste Daroussin } 3363dcf5eb7SBaptiste Daroussin 337*4bf54857SBaptiste Daroussin return write (fd, nbuf, strlen (nbuf)); 3383dcf5eb7SBaptiste Daroussin } 3393dcf5eb7SBaptiste Daroussin 3403dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions* 3413dcf5eb7SBaptiste Daroussin ucl_object_emit_memory_funcs (void **pmem) 3423dcf5eb7SBaptiste Daroussin { 3433dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions *f; 3443dcf5eb7SBaptiste Daroussin UT_string *s; 3453dcf5eb7SBaptiste Daroussin 3463dcf5eb7SBaptiste Daroussin f = calloc (1, sizeof (*f)); 3473dcf5eb7SBaptiste Daroussin 3483dcf5eb7SBaptiste Daroussin if (f != NULL) { 3493dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_character = ucl_utstring_append_character; 3503dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_double = ucl_utstring_append_double; 3513dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_int = ucl_utstring_append_int; 3523dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_len = ucl_utstring_append_len; 3533dcf5eb7SBaptiste Daroussin f->ucl_emitter_free_func = free; 3543dcf5eb7SBaptiste Daroussin utstring_new (s); 3553dcf5eb7SBaptiste Daroussin f->ud = s; 3563dcf5eb7SBaptiste Daroussin *pmem = s->d; 3573dcf5eb7SBaptiste Daroussin s->pd = pmem; 3583dcf5eb7SBaptiste Daroussin } 3593dcf5eb7SBaptiste Daroussin 3603dcf5eb7SBaptiste Daroussin return f; 3613dcf5eb7SBaptiste Daroussin } 3623dcf5eb7SBaptiste Daroussin 3633dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions* 3643dcf5eb7SBaptiste Daroussin ucl_object_emit_file_funcs (FILE *fp) 3653dcf5eb7SBaptiste Daroussin { 3663dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions *f; 3673dcf5eb7SBaptiste Daroussin 3683dcf5eb7SBaptiste Daroussin f = calloc (1, sizeof (*f)); 3693dcf5eb7SBaptiste Daroussin 3703dcf5eb7SBaptiste Daroussin if (f != NULL) { 3713dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_character = ucl_file_append_character; 3723dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_double = ucl_file_append_double; 3733dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_int = ucl_file_append_int; 3743dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_len = ucl_file_append_len; 3753dcf5eb7SBaptiste Daroussin f->ucl_emitter_free_func = NULL; 3763dcf5eb7SBaptiste Daroussin f->ud = fp; 3773dcf5eb7SBaptiste Daroussin } 3783dcf5eb7SBaptiste Daroussin 3793dcf5eb7SBaptiste Daroussin return f; 3803dcf5eb7SBaptiste Daroussin } 3813dcf5eb7SBaptiste Daroussin 3823dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions* 3833dcf5eb7SBaptiste Daroussin ucl_object_emit_fd_funcs (int fd) 3843dcf5eb7SBaptiste Daroussin { 3853dcf5eb7SBaptiste Daroussin struct ucl_emitter_functions *f; 3863dcf5eb7SBaptiste Daroussin int *ip; 3873dcf5eb7SBaptiste Daroussin 3883dcf5eb7SBaptiste Daroussin f = calloc (1, sizeof (*f)); 3893dcf5eb7SBaptiste Daroussin 3903dcf5eb7SBaptiste Daroussin if (f != NULL) { 3913dcf5eb7SBaptiste Daroussin ip = malloc (sizeof (fd)); 3923dcf5eb7SBaptiste Daroussin if (ip == NULL) { 3933dcf5eb7SBaptiste Daroussin free (f); 3943dcf5eb7SBaptiste Daroussin return NULL; 3953dcf5eb7SBaptiste Daroussin } 3963dcf5eb7SBaptiste Daroussin 3973dcf5eb7SBaptiste Daroussin memcpy (ip, &fd, sizeof (fd)); 3983dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_character = ucl_fd_append_character; 3993dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_double = ucl_fd_append_double; 4003dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_int = ucl_fd_append_int; 4013dcf5eb7SBaptiste Daroussin f->ucl_emitter_append_len = ucl_fd_append_len; 4023dcf5eb7SBaptiste Daroussin f->ucl_emitter_free_func = free; 4033dcf5eb7SBaptiste Daroussin f->ud = ip; 4043dcf5eb7SBaptiste Daroussin } 4053dcf5eb7SBaptiste Daroussin 4063dcf5eb7SBaptiste Daroussin return f; 4073dcf5eb7SBaptiste Daroussin } 4083dcf5eb7SBaptiste Daroussin 4093dcf5eb7SBaptiste Daroussin void 4103dcf5eb7SBaptiste Daroussin ucl_object_emit_funcs_free (struct ucl_emitter_functions *f) 4113dcf5eb7SBaptiste Daroussin { 4123dcf5eb7SBaptiste Daroussin if (f != NULL) { 4133dcf5eb7SBaptiste Daroussin if (f->ucl_emitter_free_func != NULL) { 4143dcf5eb7SBaptiste Daroussin f->ucl_emitter_free_func (f->ud); 4153dcf5eb7SBaptiste Daroussin } 4163dcf5eb7SBaptiste Daroussin free (f); 4173dcf5eb7SBaptiste Daroussin } 4183dcf5eb7SBaptiste Daroussin } 4193dcf5eb7SBaptiste Daroussin 4203dcf5eb7SBaptiste Daroussin 4213dcf5eb7SBaptiste Daroussin unsigned char * 4223dcf5eb7SBaptiste Daroussin ucl_object_emit_single_json (const ucl_object_t *obj) 4233dcf5eb7SBaptiste Daroussin { 4243dcf5eb7SBaptiste Daroussin UT_string *buf = NULL; 4253dcf5eb7SBaptiste Daroussin unsigned char *res = NULL; 4263dcf5eb7SBaptiste Daroussin 4273dcf5eb7SBaptiste Daroussin if (obj == NULL) { 4283dcf5eb7SBaptiste Daroussin return NULL; 4293dcf5eb7SBaptiste Daroussin } 4303dcf5eb7SBaptiste Daroussin 4313dcf5eb7SBaptiste Daroussin utstring_new (buf); 4323dcf5eb7SBaptiste Daroussin 4333dcf5eb7SBaptiste Daroussin if (buf != NULL) { 4343dcf5eb7SBaptiste Daroussin switch (obj->type) { 4353dcf5eb7SBaptiste Daroussin case UCL_OBJECT: 4363dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("object", 6, buf); 4373dcf5eb7SBaptiste Daroussin break; 4383dcf5eb7SBaptiste Daroussin case UCL_ARRAY: 4393dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("array", 5, buf); 4403dcf5eb7SBaptiste Daroussin break; 4413dcf5eb7SBaptiste Daroussin case UCL_INT: 4423dcf5eb7SBaptiste Daroussin ucl_utstring_append_int (obj->value.iv, buf); 4433dcf5eb7SBaptiste Daroussin break; 4443dcf5eb7SBaptiste Daroussin case UCL_FLOAT: 4453dcf5eb7SBaptiste Daroussin case UCL_TIME: 4463dcf5eb7SBaptiste Daroussin ucl_utstring_append_double (obj->value.dv, buf); 4473dcf5eb7SBaptiste Daroussin break; 4483dcf5eb7SBaptiste Daroussin case UCL_NULL: 4493dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("null", 4, buf); 4503dcf5eb7SBaptiste Daroussin break; 4513dcf5eb7SBaptiste Daroussin case UCL_BOOLEAN: 4523dcf5eb7SBaptiste Daroussin if (obj->value.iv) { 4533dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("true", 4, buf); 4543dcf5eb7SBaptiste Daroussin } 4553dcf5eb7SBaptiste Daroussin else { 4563dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("false", 5, buf); 4573dcf5eb7SBaptiste Daroussin } 4583dcf5eb7SBaptiste Daroussin break; 4593dcf5eb7SBaptiste Daroussin case UCL_STRING: 4603dcf5eb7SBaptiste Daroussin ucl_utstring_append_len (obj->value.sv, obj->len, buf); 4613dcf5eb7SBaptiste Daroussin break; 4623dcf5eb7SBaptiste Daroussin case UCL_USERDATA: 4633dcf5eb7SBaptiste Daroussin ucl_utstring_append_len ("userdata", 8, buf); 4643dcf5eb7SBaptiste Daroussin break; 4653dcf5eb7SBaptiste Daroussin } 4663dcf5eb7SBaptiste Daroussin res = utstring_body (buf); 4673dcf5eb7SBaptiste Daroussin free (buf); 4683dcf5eb7SBaptiste Daroussin } 4693dcf5eb7SBaptiste Daroussin 4703dcf5eb7SBaptiste Daroussin return res; 4713dcf5eb7SBaptiste Daroussin } 472*4bf54857SBaptiste Daroussin 473*4bf54857SBaptiste Daroussin #define LONG_STRING_LIMIT 80 474*4bf54857SBaptiste Daroussin 475*4bf54857SBaptiste Daroussin bool 476*4bf54857SBaptiste Daroussin ucl_maybe_long_string (const ucl_object_t *obj) 477*4bf54857SBaptiste Daroussin { 478*4bf54857SBaptiste Daroussin if (obj->len > LONG_STRING_LIMIT || (obj->flags & UCL_OBJECT_MULTILINE)) { 479*4bf54857SBaptiste Daroussin /* String is long enough, so search for newline characters in it */ 480*4bf54857SBaptiste Daroussin if (memchr (obj->value.sv, '\n', obj->len) != NULL) { 481*4bf54857SBaptiste Daroussin return true; 482*4bf54857SBaptiste Daroussin } 483*4bf54857SBaptiste Daroussin } 484*4bf54857SBaptiste Daroussin 485*4bf54857SBaptiste Daroussin return false; 486*4bf54857SBaptiste Daroussin } 487