1167802Sjkim/* Copyright (c) 2013, Vsevolod Stakhov
2167802Sjkim * All rights reserved.
3167802Sjkim *
4167802Sjkim * Redistribution and use in source and binary forms, with or without
5167802Sjkim * modification, are permitted provided that the following conditions are met:
6167802Sjkim *       * Redistributions of source code must retain the above copyright
7217365Sjkim *         notice, this list of conditions and the following disclaimer.
8306536Sjkim *       * Redistributions in binary form must reproduce the above copyright
9167802Sjkim *         notice, this list of conditions and the following disclaimer in the
10167802Sjkim *         documentation and/or other materials provided with the distribution.
11217365Sjkim *
12217365Sjkim * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13217365Sjkim * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14217365Sjkim * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15217365Sjkim * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16217365Sjkim * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17217365Sjkim * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18217365Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19217365Sjkim * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20217365Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21217365Sjkim * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22217365Sjkim */
23217365Sjkim
24217365Sjkim#include <sys/types.h>
25167802Sjkim#include <sys/mman.h>
26217365Sjkim#include <sys/stat.h>
27217365Sjkim#include <sys/time.h>
28217365Sjkim#include <stdio.h>
29167802Sjkim#include <errno.h>
30217365Sjkim#include <unistd.h>
31217365Sjkim#include <fcntl.h>
32217365Sjkim#include <time.h>
33217365Sjkim
34217365Sjkim#ifdef __APPLE__
35217365Sjkim#ifdef HAVE_MACH_MACH_TIME_H
36217365Sjkim#include <mach/mach_time.h>
37217365Sjkim#endif
38217365Sjkim#endif
39217365Sjkim
40217365Sjkim#include "ucl.h"
41217365Sjkim
42217365Sjkimstatic double
43167802Sjkimget_ticks (void)
44193341Sjkim{
45193341Sjkim	double res;
46193341Sjkim
47167802Sjkim#ifdef __APPLE__
48167802Sjkim	res = mach_absolute_time () / 1000000000.;
49167802Sjkim#else
50167802Sjkim	struct timespec ts;
51167802Sjkim	clock_gettime (CLOCK_MONOTONIC, &ts);
52167802Sjkim
53235945Sjkim	res = (double)ts.tv_sec + ts.tv_nsec / 1000000000.;
54167802Sjkim#endif
55167802Sjkim
56193267Sjkim	return res;
57193267Sjkim}
58235945Sjkim
59306536Sjkimint
60281075Sdimmain (int argc, char **argv)
61167802Sjkim{
62167802Sjkim	void *map;
63167802Sjkim	struct ucl_parser *parser;
64167802Sjkim	ucl_object_t *obj;
65167802Sjkim	int fin;
66167802Sjkim	unsigned char *emitted;
67193267Sjkim	struct stat st;
68193267Sjkim	const char *fname_in = NULL;
69167802Sjkim	int ret = 0;
70281075Sdim	double start, end, seconds;
71281075Sdim
72281075Sdim	switch (argc) {
73281075Sdim	case 2:
74281075Sdim		fname_in = argv[1];
75193267Sjkim		break;
76281075Sdim	}
77167802Sjkim
78167802Sjkim	fin = open (fname_in, O_RDONLY);
79167802Sjkim	if (fin == -1) {
80167802Sjkim		perror ("open failed");
81306536Sjkim		exit (EXIT_FAILURE);
82229989Sjkim	}
83229989Sjkim	parser = ucl_parser_new (UCL_PARSER_ZEROCOPY);
84229989Sjkim
85193267Sjkim	(void)fstat (fin, &st);
86281075Sdim	map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fin, 0);
87167802Sjkim	if (map == MAP_FAILED) {
88167802Sjkim		perror ("mmap failed");
89167802Sjkim		exit (EXIT_FAILURE);
90229989Sjkim	}
91167802Sjkim
92167802Sjkim	close (fin);
93281075Sdim
94167802Sjkim	start = get_ticks ();
95167802Sjkim	ucl_parser_add_chunk (parser, map, st.st_size);
96167802Sjkim
97193267Sjkim	obj = ucl_parser_get_object (parser);
98193267Sjkim	end = get_ticks ();
99193267Sjkim
100193267Sjkim	seconds = end - start;
101193267Sjkim	printf ("ucl: parsed input in %.4f seconds\n", seconds);
102193267Sjkim	if (ucl_parser_get_error(parser)) {
103167802Sjkim		printf ("Error occurred: %s\n", ucl_parser_get_error(parser));
104193267Sjkim		ret = 1;
105193267Sjkim		goto err;
106193267Sjkim	}
107193267Sjkim
108193267Sjkim	start = get_ticks ();
109229989Sjkim	emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG);
110167802Sjkim	end = get_ticks ();
111193267Sjkim
112193267Sjkim	seconds = end - start;
113193267Sjkim	printf ("ucl: emitted config in %.4f seconds\n", seconds);
114193267Sjkim
115193267Sjkim	free (emitted);
116193267Sjkim
117167802Sjkim	start = get_ticks ();
118193267Sjkim	emitted = ucl_object_emit (obj, UCL_EMIT_JSON);
119193267Sjkim	end = get_ticks ();
120193267Sjkim
121193267Sjkim	seconds = end - start;
122193267Sjkim	printf ("ucl: emitted json in %.4f seconds\n", seconds);
123229989Sjkim
124167802Sjkim	free (emitted);
125193267Sjkim
126193267Sjkim	start = get_ticks ();
127193267Sjkim	emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT);
128193267Sjkim	end = get_ticks ();
129193267Sjkim
130193267Sjkim	seconds = end - start;
131167802Sjkim	printf ("ucl: emitted compact json in %.4f seconds\n", seconds);
132193267Sjkim
133193267Sjkim	free (emitted);
134193267Sjkim
135193267Sjkim	start = get_ticks ();
136193267Sjkim	emitted = ucl_object_emit (obj, UCL_EMIT_YAML);
137253690Sjkim	end = get_ticks ();
138167802Sjkim
139193267Sjkim	seconds = end - start;
140193267Sjkim	printf ("ucl: emitted yaml in %.4f seconds\n", seconds);
141193267Sjkim
142193267Sjkim	free (emitted);
143193267Sjkim
144281075Sdim	ucl_parser_free (parser);
145167802Sjkim	ucl_object_unref (obj);
146193267Sjkim
147193267Sjkimerr:
148193267Sjkim	munmap (map, st.st_size);
149193267Sjkim
150193267Sjkim	return ret;
151281075Sdim}
152167802Sjkim