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 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * 12 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 13 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 16 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 */ 23 24 #include "ucl.h" 25 #include "ucl_internal.h" 26 27 int 28 main (int argc, char **argv) 29 { 30 char *inbuf; 31 struct ucl_parser *parser = NULL, *parser2 = NULL; 32 ucl_object_t *obj; 33 ssize_t bufsize, r; 34 FILE *in, *out; 35 unsigned char *emitted = NULL; 36 const char *fname_in = NULL, *fname_out = NULL; 37 int ret = 0, opt, json = 0, compact = 0, yaml = 0; 38 39 while ((opt = getopt(argc, argv, "jcy")) != -1) { 40 switch (opt) { 41 case 'j': 42 json = 1; 43 break; 44 case 'c': 45 compact = 1; 46 break; 47 case 'y': 48 yaml = 1; 49 break; 50 default: /* '?' */ 51 fprintf (stderr, "Usage: %s [-jcy] [in] [out]\n", 52 argv[0]); 53 exit (EXIT_FAILURE); 54 } 55 } 56 57 argc -= optind; 58 argv += optind; 59 60 switch (argc) { 61 case 1: 62 fname_in = argv[0]; 63 break; 64 case 2: 65 fname_in = argv[0]; 66 fname_out = argv[1]; 67 break; 68 } 69 70 if (fname_in != NULL) { 71 in = fopen (fname_in, "r"); 72 if (in == NULL) { 73 exit (-errno); 74 } 75 } 76 else { 77 in = stdin; 78 } 79 parser = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE); 80 ucl_parser_register_variable (parser, "ABI", "unknown"); 81 82 if (fname_in != NULL) { 83 ucl_parser_set_filevars (parser, fname_in, true); 84 } 85 86 inbuf = malloc (BUFSIZ); 87 bufsize = BUFSIZ; 88 r = 0; 89 90 while (!feof (in) && !ferror (in)) { 91 if (r == bufsize) { 92 inbuf = realloc (inbuf, bufsize * 2); 93 bufsize *= 2; 94 if (inbuf == NULL) { 95 perror ("realloc"); 96 exit (EXIT_FAILURE); 97 } 98 } 99 r += fread (inbuf + r, 1, bufsize - r, in); 100 } 101 102 if (ferror (in)) { 103 fprintf (stderr, "Failed to read the input file.\n"); 104 exit (EXIT_FAILURE); 105 } 106 107 ucl_parser_add_chunk (parser, (const unsigned char *)inbuf, r); 108 fclose (in); 109 110 if (fname_out != NULL) { 111 out = fopen (fname_out, "w"); 112 if (out == NULL) { 113 exit (-errno); 114 } 115 } 116 else { 117 out = stdout; 118 } 119 120 if (ucl_parser_get_error (parser) != NULL) { 121 fprintf (out, "Error occurred: %s\n", ucl_parser_get_error(parser)); 122 ret = 1; 123 goto end; 124 } 125 126 obj = ucl_parser_get_object (parser); 127 128 if (json) { 129 if (compact) { 130 emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT); 131 } 132 else { 133 emitted = ucl_object_emit (obj, UCL_EMIT_JSON); 134 } 135 } 136 else if (yaml) { 137 emitted = ucl_object_emit (obj, UCL_EMIT_YAML); 138 } 139 else { 140 emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG); 141 } 142 143 ucl_parser_free (parser); 144 ucl_object_unref (obj); 145 parser2 = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE); 146 ucl_parser_add_string (parser2, (const char *)emitted, 0); 147 148 if (ucl_parser_get_error(parser2) != NULL) { 149 fprintf (out, "Error occurred: %s\n", ucl_parser_get_error(parser2)); 150 fprintf (out, "%s\n", emitted); 151 ret = 1; 152 goto end; 153 } 154 155 if (emitted != NULL) { 156 free (emitted); 157 } 158 159 obj = ucl_parser_get_object (parser2); 160 if (json) { 161 if (compact) { 162 emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT); 163 } 164 else { 165 emitted = ucl_object_emit (obj, UCL_EMIT_JSON); 166 } 167 } 168 else if (yaml) { 169 emitted = ucl_object_emit (obj, UCL_EMIT_YAML); 170 } 171 else { 172 emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG); 173 } 174 175 fprintf (out, "%s\n", emitted); 176 ucl_object_unref (obj); 177 178 end: 179 if (emitted != NULL) { 180 free (emitted); 181 } 182 if (parser2 != NULL) { 183 ucl_parser_free (parser2); 184 } 185 if (inbuf != NULL) { 186 free (inbuf); 187 } 188 189 fclose (out); 190 191 return ret; 192 } 193