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 <sys/types.h> 25 #include <sys/mman.h> 26 #include <sys/stat.h> 27 #include <sys/time.h> 28 #include <stdio.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <time.h> 33 34 #ifdef __APPLE__ 35 #ifdef HAVE_MACH_MACH_TIME_H 36 #include <mach/mach_time.h> 37 #endif 38 #endif 39 40 #include "ucl.h" 41 42 static double 43 get_ticks (void) 44 { 45 double res; 46 47 #ifdef __APPLE__ 48 res = mach_absolute_time () / 1000000000.; 49 #else 50 struct timespec ts; 51 clock_gettime (CLOCK_MONOTONIC, &ts); 52 53 res = (double)ts.tv_sec + ts.tv_nsec / 1000000000.; 54 #endif 55 56 return res; 57 } 58 59 int 60 main (int argc, char **argv) 61 { 62 void *map; 63 struct ucl_parser *parser; 64 ucl_object_t *obj; 65 int fin; 66 unsigned char *emitted; 67 struct stat st; 68 const char *fname_in = NULL; 69 int ret = 0; 70 double start, end, seconds; 71 72 switch (argc) { 73 case 2: 74 fname_in = argv[1]; 75 break; 76 } 77 78 fin = open (fname_in, O_RDONLY); 79 if (fin == -1) { 80 perror ("open failed"); 81 exit (EXIT_FAILURE); 82 } 83 parser = ucl_parser_new (UCL_PARSER_ZEROCOPY); 84 85 (void)fstat (fin, &st); 86 map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fin, 0); 87 if (map == MAP_FAILED) { 88 perror ("mmap failed"); 89 exit (EXIT_FAILURE); 90 } 91 92 close (fin); 93 94 start = get_ticks (); 95 ucl_parser_add_chunk (parser, map, st.st_size); 96 97 obj = ucl_parser_get_object (parser); 98 end = get_ticks (); 99 100 seconds = end - start; 101 printf ("ucl: parsed input in %.4f seconds\n", seconds); 102 if (ucl_parser_get_error(parser)) { 103 printf ("Error occurred: %s\n", ucl_parser_get_error(parser)); 104 ret = 1; 105 goto err; 106 } 107 108 start = get_ticks (); 109 emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG); 110 end = get_ticks (); 111 112 seconds = end - start; 113 printf ("ucl: emitted config in %.4f seconds\n", seconds); 114 115 free (emitted); 116 117 start = get_ticks (); 118 emitted = ucl_object_emit (obj, UCL_EMIT_JSON); 119 end = get_ticks (); 120 121 seconds = end - start; 122 printf ("ucl: emitted json in %.4f seconds\n", seconds); 123 124 free (emitted); 125 126 start = get_ticks (); 127 emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT); 128 end = get_ticks (); 129 130 seconds = end - start; 131 printf ("ucl: emitted compact json in %.4f seconds\n", seconds); 132 133 free (emitted); 134 135 start = get_ticks (); 136 emitted = ucl_object_emit (obj, UCL_EMIT_YAML); 137 end = get_ticks (); 138 139 seconds = end - start; 140 printf ("ucl: emitted yaml in %.4f seconds\n", seconds); 141 142 free (emitted); 143 144 ucl_parser_free (parser); 145 ucl_object_unref (obj); 146 147 err: 148 munmap (map, st.st_size); 149 150 return ret; 151 } 152