1262395Sbapt/* Copyright (c) 2013, Vsevolod Stakhov
2262395Sbapt * All rights reserved.
3262395Sbapt *
4262395Sbapt * Redistribution and use in source and binary forms, with or without
5262395Sbapt * modification, are permitted provided that the following conditions are met:
6262395Sbapt *       * Redistributions of source code must retain the above copyright
7262395Sbapt *         notice, this list of conditions and the following disclaimer.
8262395Sbapt *       * Redistributions in binary form must reproduce the above copyright
9262395Sbapt *         notice, this list of conditions and the following disclaimer in the
10262395Sbapt *         documentation and/or other materials provided with the distribution.
11262395Sbapt *
12262395Sbapt * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13262395Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14262395Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15262395Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16262395Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17262395Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18262395Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19262395Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20262395Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21262395Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22262395Sbapt */
23262395Sbapt
24262395Sbapt#include "ucl.h"
25268896Sbapt#include "ucl_internal.h"
26262395Sbapt
27262395Sbaptint
28262395Sbaptmain (int argc, char **argv)
29262395Sbapt{
30262395Sbapt	char inbuf[8192], *test_in = NULL;
31262395Sbapt	struct ucl_parser *parser = NULL, *parser2 = NULL;
32262395Sbapt	ucl_object_t *obj;
33262395Sbapt	FILE *in, *out;
34262395Sbapt	unsigned char *emitted = NULL;
35262395Sbapt	const char *fname_in = NULL, *fname_out = NULL;
36262395Sbapt	int ret = 0, inlen, opt, json = 0;
37262395Sbapt
38262395Sbapt	while ((opt = getopt(argc, argv, "j")) != -1) {
39262395Sbapt		switch (opt) {
40262395Sbapt		case 'j':
41262395Sbapt			json = 1;
42262395Sbapt			break;
43262395Sbapt		default: /* '?' */
44262395Sbapt			fprintf (stderr, "Usage: %s [-j] [in] [out]\n",
45262395Sbapt					argv[0]);
46262395Sbapt			exit (EXIT_FAILURE);
47262395Sbapt		}
48262395Sbapt	}
49262395Sbapt
50262395Sbapt	argc -= optind;
51262395Sbapt	argv += optind;
52262395Sbapt
53262395Sbapt	switch (argc) {
54262395Sbapt	case 1:
55262395Sbapt		fname_in = argv[0];
56262395Sbapt		break;
57262395Sbapt	case 2:
58262395Sbapt		fname_in = argv[0];
59262395Sbapt		fname_out = argv[1];
60262395Sbapt		break;
61262395Sbapt	}
62262395Sbapt
63262395Sbapt	if (fname_in != NULL) {
64262395Sbapt		in = fopen (fname_in, "r");
65262395Sbapt		if (in == NULL) {
66262395Sbapt			exit (-errno);
67262395Sbapt		}
68262395Sbapt	}
69262395Sbapt	else {
70262395Sbapt		in = stdin;
71262395Sbapt	}
72262395Sbapt	parser = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE);
73262395Sbapt	ucl_parser_register_variable (parser, "ABI", "unknown");
74262395Sbapt
75262395Sbapt	if (fname_in != NULL) {
76262395Sbapt		ucl_parser_set_filevars (parser, fname_in, true);
77262395Sbapt	}
78262395Sbapt
79262395Sbapt	while (!feof (in)) {
80262395Sbapt		memset (inbuf, 0, sizeof (inbuf));
81268896Sbapt		if (fread (inbuf, 1, sizeof (inbuf) - 1, in) == 0) {
82268896Sbapt			break;
83268896Sbapt		}
84262395Sbapt		inlen = strlen (inbuf);
85262395Sbapt		test_in = malloc (inlen);
86262395Sbapt		memcpy (test_in, inbuf, inlen);
87262395Sbapt		ucl_parser_add_chunk (parser, test_in, inlen);
88262395Sbapt	}
89262395Sbapt	fclose (in);
90262395Sbapt
91262395Sbapt	if (fname_out != NULL) {
92262395Sbapt		out = fopen (fname_out, "w");
93262395Sbapt		if (out == NULL) {
94262395Sbapt			exit (-errno);
95262395Sbapt		}
96262395Sbapt	}
97262395Sbapt	else {
98262395Sbapt		out = stdout;
99262395Sbapt	}
100268896Sbapt	if (ucl_parser_get_error (parser) != NULL) {
101262395Sbapt		fprintf (out, "Error occurred: %s\n", ucl_parser_get_error(parser));
102262395Sbapt		ret = 1;
103262395Sbapt		goto end;
104262395Sbapt	}
105262395Sbapt	obj = ucl_parser_get_object (parser);
106262395Sbapt	if (json) {
107262395Sbapt		emitted = ucl_object_emit (obj, UCL_EMIT_JSON);
108262395Sbapt	}
109262395Sbapt	else {
110262395Sbapt		emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG);
111262395Sbapt	}
112262395Sbapt	ucl_parser_free (parser);
113262395Sbapt	ucl_object_unref (obj);
114262395Sbapt	parser2 = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE);
115268896Sbapt	ucl_parser_add_string (parser2, emitted, 0);
116262395Sbapt
117262395Sbapt	if (ucl_parser_get_error(parser2) != NULL) {
118262395Sbapt		fprintf (out, "Error occurred: %s\n", ucl_parser_get_error(parser2));
119262395Sbapt		fprintf (out, "%s\n", emitted);
120262395Sbapt		ret = 1;
121262395Sbapt		goto end;
122262395Sbapt	}
123262395Sbapt	if (emitted != NULL) {
124262395Sbapt		free (emitted);
125262395Sbapt	}
126262395Sbapt	obj = ucl_parser_get_object (parser2);
127262395Sbapt	if (json) {
128262395Sbapt		emitted = ucl_object_emit (obj, UCL_EMIT_JSON);
129262395Sbapt	}
130262395Sbapt	else {
131262395Sbapt		emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG);
132262395Sbapt	}
133262395Sbapt
134262395Sbapt	fprintf (out, "%s\n", emitted);
135262395Sbapt	ucl_object_unref (obj);
136262395Sbapt
137262395Sbaptend:
138262395Sbapt	if (emitted != NULL) {
139262395Sbapt		free (emitted);
140262395Sbapt	}
141262395Sbapt	if (parser2 != NULL) {
142262395Sbapt		ucl_parser_free (parser2);
143262395Sbapt	}
144262395Sbapt	if (test_in != NULL) {
145262395Sbapt		free (test_in);
146262395Sbapt	}
147262395Sbapt
148262395Sbapt	fclose (out);
149262395Sbapt
150262395Sbapt	return ret;
151262395Sbapt}
152