exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

mustach-tool.c (5048B)


      1 /*
      2  Author: José Bollo <jobol@nonadev.net>
      3 
      4  https://gitlab.com/jobol/mustach
      5 
      6  SPDX-License-Identifier: ISC
      7 */
      8 
      9 #ifndef _GNU_SOURCE
     10 #define _GNU_SOURCE
     11 #endif
     12 
     13 #include <stdlib.h>
     14 #include <stdio.h>
     15 #include <sys/stat.h>
     16 #include <unistd.h>
     17 #include <fcntl.h>
     18 #include <string.h>
     19 #include <libgen.h>
     20 
     21 #include "mustach-wrap.h"
     22 
     23 static const size_t BLOCKSIZE = 8192;
     24 
     25 static const char *errors[] = {
     26 	"??? unreferenced ???",
     27 	"system",
     28 	"unexpected end",
     29 	"empty tag",
     30 	"tag too long",
     31 	"bad separators",
     32 	"too depth",
     33 	"closing",
     34 	"bad unescape tag",
     35 	"invalid interface",
     36 	"item not found",
     37 	"partial not found",
     38 	"undefined tag",
     39 	"too much template nesting"
     40 };
     41 
     42 static const char *errmsg = 0;
     43 static int flags = 0;
     44 static FILE *output = 0;
     45 
     46 static void help(char *prog)
     47 {
     48 	char *name = basename(prog);
     49 #define STR_INDIR(x) #x
     50 #define STR(x) STR_INDIR(x)
     51 	printf("%s version %s\n", name, STR(VERSION));
     52 #undef STR
     53 #undef STR_INDIR
     54 	printf(
     55 		"\n"
     56 		"USAGE:\n"
     57 		"    %s [FLAGS] <json-file> <mustach-templates...>\n"
     58 		"\n"
     59 		"FLAGS:\n"
     60 		"    -h, --help     Prints help information\n"
     61 		"    -s, --strict   Error when a tag is undefined\n"
     62 		"\n"
     63 		"ARGS: (if a file is -, read standard input)\n"
     64 		"    <json-file>              JSON file with input data\n"
     65 		"    <mustach-templates...>   Template files to instantiate\n",
     66 		name);
     67 	exit(0);
     68 }
     69 
     70 static char *readfile(const char *filename, size_t *length)
     71 {
     72 	int f;
     73 	struct stat s;
     74 	char *result;
     75 	size_t size, pos;
     76 	ssize_t rc;
     77 
     78 	result = NULL;
     79 	if (filename[0] == '-' &&  filename[1] == 0)
     80 		f = dup(0);
     81 	else
     82 		f = open(filename, O_RDONLY);
     83 	if (f < 0) {
     84 		fprintf(stderr, "Can't open file: %s\n", filename);
     85 		exit(1);
     86 	}
     87 
     88 	fstat(f, &s);
     89 	switch (s.st_mode & S_IFMT) {
     90 	case S_IFREG:
     91 		size = s.st_size;
     92 		break;
     93 	case S_IFSOCK:
     94 	case S_IFIFO:
     95 		size = BLOCKSIZE;
     96 		break;
     97 	default:
     98 		fprintf(stderr, "Bad file: %s\n", filename);
     99 		exit(1);
    100 	}
    101 
    102 	pos = 0;
    103 	result = malloc(size + 1);
    104 	do {
    105 		if (result == NULL) {
    106 			fprintf(stderr, "Out of memory\n");
    107 			exit(1);
    108 		}
    109 		rc = read(f, &result[pos], (size - pos) + 1);
    110 		if (rc < 0) {
    111 			fprintf(stderr, "Error while reading %s\n", filename);
    112 			exit(1);
    113 		}
    114 		if (rc > 0) {
    115 			pos += (size_t)rc;
    116 			if (pos > size) {
    117 				size = pos + BLOCKSIZE;
    118 				result = realloc(result, size + 1);
    119 			}
    120 		}
    121 	} while(rc > 0);
    122 
    123 	close(f);
    124 	if (length != NULL)
    125 		*length = pos;
    126 	result[pos] = 0;
    127 	return result;
    128 }
    129 
    130 static int load_json(const char *filename);
    131 static int process(const char *content, size_t length);
    132 static void close_json(void);
    133 
    134 int main(int ac, char **av)
    135 {
    136     char *t;
    137     const char *f;
    138 	char *prog = *av;
    139 	int s;
    140 	size_t length;
    141 
    142 	(void)ac; /* unused */
    143 	flags = Mustach_With_AllExtensions;
    144 	output = stdout;
    145 
    146 	for( ++av ; av[0] && av[0][0] == '-' && av[0][1] != 0 ; av++) {
    147 		if (!strcmp(*av, "-h") || !strcmp(*av, "--help"))
    148 			help(prog);
    149 		if (!strcmp(*av, "-s") || !strcmp(*av, "--strict"))
    150 			flags |= Mustach_With_ErrorUndefined;
    151 	}
    152 	if (*av) {
    153 		f = (av[0][0] == '-' && !av[0][1]) ? "/dev/stdin" : av[0];
    154 		s = load_json(f);
    155 		if (s < 0) {
    156 			fprintf(stderr, "Can't load json file %s\n", av[0]);
    157 			if(errmsg)
    158 				fprintf(stderr, "   reason: %s\n", errmsg);
    159 			exit(1);
    160 		}
    161 		while(*++av) {
    162 			t = readfile(*av, &length);
    163 			s = process(t, length);
    164 			free(t);
    165 			if (s != MUSTACH_OK) {
    166 				s = -s;
    167 				if (s < 1 || s >= (int)(sizeof errors / sizeof * errors))
    168 					s = 0;
    169 				fprintf(stderr, "Template error %s (file %s)\n", errors[s], *av);
    170 			}
    171 		}
    172 		close_json();
    173 	}
    174 	return 0;
    175 }
    176 
    177 #define MUSTACH_TOOL_JSON_C  1
    178 #define MUSTACH_TOOL_JANSSON 2
    179 #define MUSTACH_TOOL_CJSON   3
    180 
    181 #if TOOL == MUSTACH_TOOL_JSON_C
    182 
    183 #include "mustach-json-c.h"
    184 
    185 static struct json_object *o;
    186 static int load_json(const char *filename)
    187 {
    188 	o = json_object_from_file(filename);
    189 #if JSON_C_VERSION_NUM >= 0x000D00
    190 	errmsg = json_util_get_last_err();
    191 	if (errmsg != NULL)
    192 		return -1;
    193 #endif
    194 	if (o == NULL) {
    195 		errmsg = "null json";
    196 		return -1;
    197 	}
    198 	return 0;
    199 }
    200 static int process(const char *content, size_t length)
    201 {
    202 	return mustach_json_c_file(content, length, o, flags, output);
    203 }
    204 static void close_json()
    205 {
    206 	json_object_put(o);
    207 }
    208 
    209 #elif TOOL == MUSTACH_TOOL_JANSSON
    210 
    211 #include "mustach-jansson.h"
    212 
    213 static json_t *o;
    214 static json_error_t e;
    215 static int load_json(const char *filename)
    216 {
    217 	o = json_load_file(filename, JSON_DECODE_ANY, &e);
    218 	if (o == NULL) {
    219 		errmsg = e.text;
    220 		return -1;
    221 	}
    222 	return 0;
    223 }
    224 static int process(const char *content, size_t length)
    225 {
    226 	return mustach_jansson_file(content, length, o, flags, output);
    227 }
    228 static void close_json()
    229 {
    230 	json_decref(o);
    231 }
    232 
    233 #elif TOOL == MUSTACH_TOOL_CJSON
    234 
    235 #include "mustach-cjson.h"
    236 
    237 static cJSON *o;
    238 static int load_json(const char *filename)
    239 {
    240 	char *t;
    241 	size_t length;
    242 
    243 	t = readfile(filename, &length);
    244 	o = t ? cJSON_ParseWithLength(t, length) : NULL;
    245 	free(t);
    246 	return -!o;
    247 }
    248 static int process(const char *content, size_t length)
    249 {
    250 	return mustach_cJSON_file(content, length, o, flags, output);
    251 }
    252 static void close_json()
    253 {
    254 	cJSON_Delete(o);
    255 }
    256 
    257 #else
    258 #error "no defined json library"
    259 #endif