1139826Simp/* Copyright (c) 2013, Vsevolod Stakhov
253541Sshin * All rights reserved.
353541Sshin *
453541Sshin * Redistribution and use in source and binary forms, with or without
553541Sshin * modification, are permitted provided that the following conditions are met:
653541Sshin *       * Redistributions of source code must retain the above copyright
753541Sshin *         notice, this list of conditions and the following disclaimer.
853541Sshin *       * Redistributions in binary form must reproduce the above copyright
953541Sshin *         notice, this list of conditions and the following disclaimer in the
1053541Sshin *         documentation and/or other materials provided with the distribution.
1153541Sshin *
1253541Sshin * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
1353541Sshin * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1453541Sshin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1553541Sshin * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
1653541Sshin * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1753541Sshin * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1853541Sshin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1953541Sshin * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2053541Sshin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2153541Sshin * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2253541Sshin */
2353541Sshin
2453541Sshin/**
2553541Sshin * @file this utility generates character table for ucl
2653541Sshin */
2753541Sshin
28174510Sobrien#include <stdio.h>
29174510Sobrien#include <ctype.h>
3053541Sshin#include <stdbool.h>
3153541Sshin
32174510Sobrienstatic inline int
33174510Sobrienprint_flag (const char *flag, bool *need_or, char *val)
34174510Sobrien{
3553541Sshin	int res;
3653541Sshin	res = sprintf (val, "%s%s", *need_or ? "|" : "", flag);
3753541Sshin
3853541Sshin	*need_or |= true;
3953541Sshin
4053541Sshin	return res;
4153541Sshin}
4253541Sshin
4353541Sshinint
4453541Sshinmain (int argc, char **argv)
4553541Sshin{
4653541Sshin	int i, col, r;
4753541Sshin	const char *name = "ucl_chartable";
4853541Sshin	bool need_or;
4953541Sshin	char valbuf[2048];
5053541Sshin
5153541Sshin	col = 0;
5262587Sitojun
5353541Sshin	if (argc > 1) {
5462587Sitojun		name = argv[1];
55121684Sume	}
56121684Sume
5753541Sshin	printf ("static const unsigned int %s[255] = {\n", name);
5853541Sshin
5953541Sshin	for (i = 0; i < 255; i ++) {
6053541Sshin		need_or = false;
6153541Sshin		r = 0;
6253541Sshin		/* UCL_CHARACTER_VALUE_END */
6362587Sitojun
6453541Sshin		if (i == ' ' || i == '\t') {
6562587Sitojun			r += print_flag ("UCL_CHARACTER_WHITESPACE", &need_or, valbuf + r);
6662587Sitojun		}
6762587Sitojun		if (isspace (i)) {
6862587Sitojun			r += print_flag ("UCL_CHARACTER_WHITESPACE_UNSAFE", &need_or, valbuf + r);
6962587Sitojun		}
7053541Sshin		if (isalnum (i) || i >= 0x80 || i == '/' || i == '_') {
71121346Sume			r += print_flag ("UCL_CHARACTER_KEY_START", &need_or, valbuf + r);
72121346Sume		}
73121346Sume		if (isalnum (i) || i == '-' || i == '_' || i == '/' || i == '.' || i >= 0x80) {
74121346Sume			r += print_flag ("UCL_CHARACTER_KEY", &need_or, valbuf + r);
75121346Sume		}
76121346Sume		if (i == 0 || i == '\r' || i == '\n' || i == ']' || i == '}' || i == ';' || i == ',' || i == '#') {
77121346Sume			r += print_flag ("UCL_CHARACTER_VALUE_END", &need_or, valbuf + r);
7853541Sshin		}
79121346Sume		else {
80121346Sume			if (isprint (i) || i >= 0x80) {
81121346Sume				r += print_flag ("UCL_CHARACTER_VALUE_STR", &need_or, valbuf + r);
82121355Sume			}
83121346Sume			if (isdigit (i) || i == '-') {
84121345Sume				r += print_flag ("UCL_CHARACTER_VALUE_DIGIT_START", &need_or, valbuf + r);
8569774Sphk			}
8662587Sitojun			if (isalnum (i) || i == '.' || i == '-' || i == '+') {
8753541Sshin				r += print_flag ("UCL_CHARACTER_VALUE_DIGIT", &need_or, valbuf + r);
8853541Sshin			}
8953541Sshin		}
90157927Sps		if (i == '"' || i == '\\' || i == '/' || i == 'b' ||
91157927Sps			i == 'f' || i == 'n' || i == 'r' || i == 't' || i == 'u') {
92157927Sps			r += print_flag ("UCL_CHARACTER_ESCAPE", &need_or, valbuf + r);
93157927Sps		}
94157927Sps		if (i == ' ' || i == '\t' || i == ':' || i == '=') {
95157927Sps			r += print_flag ("UCL_CHARACTER_KEY_SEP", &need_or, valbuf + r);
96157927Sps		}
97157927Sps		if (i == '\n' || i == '\r' || i == '\\' || i == '\b' || i == '\t' ||
9853541Sshin				i == '"' || i == '\f') {
99171259Sdelphij			r += print_flag ("UCL_CHARACTER_JSON_UNSAFE", &need_or, valbuf + r);
10053541Sshin		}
10153541Sshin		if (i == '\n' || i == '\r' || i == '\\' || i == '\b' || i == '\t' ||
10277969Sjesper				i == '"' || i == '\f' || i == '=' || i == ':' || i == '{' || i == '[' || i == ' ') {
103121345Sume			r += print_flag ("UCL_CHARACTER_UCL_UNSAFE", &need_or, valbuf + r);
104157927Sps		}
105157927Sps
10677969Sjesper		if (!need_or) {
107121346Sume			r += print_flag ("UCL_CHARACTER_DENIED", &need_or, valbuf + r);
108121346Sume		}
10953541Sshin
11053541Sshin		if (isprint (i)) {
11153541Sshin			r += sprintf (valbuf + r, " /* %c */", i);
11253541Sshin		}
11362587Sitojun		if (i != 254) {
11462587Sitojun			r += sprintf (valbuf + r, ", ");
11562587Sitojun		}
11662587Sitojun		col += r;
11762587Sitojun		if (col > 80) {
11862587Sitojun			printf ("\n%s", valbuf);
11962587Sitojun			col = r;
12062587Sitojun		}
12162587Sitojun		else {
12262587Sitojun			printf ("%s", valbuf);
12362587Sitojun		}
12462587Sitojun	}
12562587Sitojun	printf ("\n}\n");
12662587Sitojun
12762587Sitojun	return 0;
12862587Sitojun}
12962587Sitojun