]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libucl/tests/test_basic.c
sysctl(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / contrib / libucl / tests / test_basic.c
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 #include <sys/types.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29
30
31 int
32 main (int argc, char **argv)
33 {
34         char *inbuf = NULL;
35         struct ucl_parser *parser = NULL, *parser2 = NULL;
36         ucl_object_t *obj, *comments = NULL;
37         ssize_t bufsize, r;
38         FILE *in, *out;
39         unsigned char *emitted = NULL;
40         const char *fname_in = NULL, *fname_out = NULL;
41         int ret = 0, opt, json = 0, compact = 0, yaml = 0,
42                         save_comments = 0, skip_macro = 0,
43                         flags, fd_out, fd_in, use_fd = 0;
44         struct ucl_emitter_functions *func;
45
46         while ((opt = getopt(argc, argv, "fjcyCM")) != -1) {
47                 switch (opt) {
48                 case 'j':
49                         json = 1;
50                         break;
51                 case 'c':
52                         compact = 1;
53                         break;
54                 case 'C':
55                         save_comments = 1;
56                         break;
57                 case 'y':
58                         yaml = 1;
59                         break;
60                 case 'M':
61                         skip_macro = true;
62                         break;
63                 case 'f':
64                         use_fd = true;
65                         break;
66                 default: /* '?' */
67                         fprintf (stderr, "Usage: %s [-jcy] [-CM] [-f] [in] [out]\n",
68                                         argv[0]);
69                         exit (EXIT_FAILURE);
70                 }
71         }
72
73         argc -= optind;
74         argv += optind;
75
76         switch (argc) {
77         case 1:
78                 fname_in = argv[0];
79                 break;
80         case 2:
81                 fname_in = argv[0];
82                 fname_out = argv[1];
83                 break;
84         }
85
86         if (!use_fd) {
87                 if (fname_in != NULL) {
88                         in = fopen (fname_in, "r");
89                         if (in == NULL) {
90                                 exit (-errno);
91                         }
92                 }
93                 else {
94                         in = stdin;
95                 }
96         }
97         else {
98                 if (fname_in != NULL) {
99                         fd_in = open (fname_in, O_RDONLY);
100                         if (fd_in == -1) {
101                                 exit (-errno);
102                         }
103                 }
104                 else {
105                         fd_in = STDIN_FILENO;
106                 }
107         }
108
109         flags = UCL_PARSER_KEY_LOWERCASE;
110
111         if (save_comments) {
112                 flags |= UCL_PARSER_SAVE_COMMENTS;
113         }
114
115         if (skip_macro) {
116                 flags |= UCL_PARSER_DISABLE_MACRO;
117         }
118
119         parser = ucl_parser_new (flags);
120         ucl_parser_register_variable (parser, "ABI", "unknown");
121
122         if (fname_in != NULL) {
123                 ucl_parser_set_filevars (parser, fname_in, true);
124         }
125
126         if (!use_fd) {
127                 inbuf = malloc (BUFSIZ);
128                 bufsize = BUFSIZ;
129                 r = 0;
130
131                 while (!feof (in) && !ferror (in)) {
132                         if (r == bufsize) {
133                                 inbuf = realloc (inbuf, bufsize * 2);
134                                 bufsize *= 2;
135                                 if (inbuf == NULL) {
136                                         perror ("realloc");
137                                         exit (EXIT_FAILURE);
138                                 }
139                         }
140                         r += fread (inbuf + r, 1, bufsize - r, in);
141                 }
142
143                 if (ferror (in)) {
144                         fprintf (stderr, "Failed to read the input file.\n");
145                         exit (EXIT_FAILURE);
146                 }
147
148                 ucl_parser_add_chunk (parser, (const unsigned char *)inbuf, r);
149                 fclose (in);
150         }
151         else {
152                 ucl_parser_add_fd (parser, fd_in);
153                 close (fd_in);
154         }
155
156         if (!use_fd) {
157                 if (fname_out != NULL) {
158                         out = fopen (fname_out, "w");
159                         if (out == NULL) {
160                                 exit (-errno);
161                         }
162                 }
163                 else {
164                         out = stdout;
165                 }
166         }
167         else {
168                 if (fname_out != NULL) {
169                         fd_out = open (fname_out, O_WRONLY | O_CREAT, 00644);
170                         if (fd_out == -1) {
171                                 exit (-errno);
172                         }
173                 }
174                 else {
175                         fd_out = STDOUT_FILENO;
176                 }
177         }
178
179
180         if (ucl_parser_get_error (parser) != NULL) {
181                 fprintf (out, "Error occurred (phase 1): %s\n",
182                                                 ucl_parser_get_error(parser));
183                 ret = 1;
184                 goto end;
185         }
186
187         obj = ucl_parser_get_object (parser);
188
189         if (save_comments) {
190                 comments = ucl_object_ref (ucl_parser_get_comments (parser));
191         }
192
193         if (json) {
194                 if (compact) {
195                         emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT);
196                 }
197                 else {
198                         emitted = ucl_object_emit (obj, UCL_EMIT_JSON);
199                 }
200         }
201         else if (yaml) {
202                 emitted = ucl_object_emit (obj, UCL_EMIT_YAML);
203         }
204         else {
205                 emitted = NULL;
206                 func = ucl_object_emit_memory_funcs ((void **)&emitted);
207
208                 if (func != NULL) {
209                         ucl_object_emit_full (obj, UCL_EMIT_CONFIG, func, comments);
210                         ucl_object_emit_funcs_free (func);
211                 }
212         }
213
214 #if 0
215         fprintf (out, "%s\n****\n", emitted);
216 #endif
217
218         ucl_parser_free (parser);
219         ucl_object_unref (obj);
220         parser2 = ucl_parser_new (flags);
221         ucl_parser_add_string (parser2, (const char *)emitted, 0);
222
223         if (ucl_parser_get_error(parser2) != NULL) {
224                 fprintf (out, "Error occurred (phase 2): %s\n",
225                                 ucl_parser_get_error(parser2));
226                 fprintf (out, "%s\n", emitted);
227                 ret = 1;
228                 goto end;
229         }
230
231         if (emitted != NULL) {
232                 free (emitted);
233         }
234         if (comments) {
235                 ucl_object_unref (comments);
236                 comments = NULL;
237         }
238
239         if (save_comments) {
240                 comments = ucl_object_ref (ucl_parser_get_comments (parser2));
241         }
242
243         obj = ucl_parser_get_object (parser2);
244
245         if (!use_fd) {
246                 func = ucl_object_emit_file_funcs (out);
247         }
248         else {
249                 func = ucl_object_emit_fd_funcs (fd_out);
250         }
251
252         if (func != NULL) {
253                 if (json) {
254                         if (compact) {
255                                 ucl_object_emit_full (obj, UCL_EMIT_JSON_COMPACT,
256                                                 func, comments);
257                         }
258                         else {
259                                 ucl_object_emit_full (obj, UCL_EMIT_JSON,
260                                                 func, comments);
261                         }
262                 }
263                 else if (yaml) {
264                         ucl_object_emit_full (obj, UCL_EMIT_YAML,
265                                         func, comments);
266                 }
267                 else {
268                         ucl_object_emit_full (obj, UCL_EMIT_CONFIG,
269                                         func, comments);
270                 }
271
272                 ucl_object_emit_funcs_free (func);
273         }
274
275         if (!use_fd) {
276                 fprintf (out, "\n");
277                 fclose (out);
278         }
279         else {
280                 write (fd_out, "\n", 1);
281                 close (fd_out);
282         }
283
284         ucl_object_unref (obj);
285
286 end:
287         if (parser2 != NULL) {
288                 ucl_parser_free (parser2);
289         }
290         if (comments) {
291                 ucl_object_unref (comments);
292         }
293         if (inbuf != NULL) {
294                 free (inbuf);
295         }
296
297         return ret;
298 }