PageRenderTime 27ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/usr.bin/colldef/parse.y

https://bitbucket.org/evzijst/freebsd
Happy | 384 lines | 357 code | 27 blank | 0 comment | 0 complexity | 6026bca0e1588ade8b5bf662178491bd MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, AGPL-1.0, LGPL-2.1, GPL-2.0, BSD-2-Clause, 0BSD, MPL-2.0-no-copyleft-exception
  1. %{
  2. /*-
  3. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
  4. * at Electronni Visti IA, Kiev, Ukraine.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #include <sys/cdefs.h>
  29. __FBSDID("$FreeBSD$");
  30. #include <sys/types.h>
  31. #include <arpa/inet.h>
  32. #include <err.h>
  33. #include <stdarg.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <unistd.h>
  37. #include <sysexits.h>
  38. #include "collate.h"
  39. #include "common.h"
  40. extern FILE *yyin;
  41. void yyerror(const char *fmt, ...) __printflike(1, 2);
  42. int yyparse(void);
  43. int yylex(void);
  44. static void usage(void);
  45. static void collate_print_tables(void);
  46. char map_name[FILENAME_MAX] = ".";
  47. char curr_chain[STR_LEN];
  48. char __collate_version[STR_LEN];
  49. u_char charmap_table[UCHAR_MAX + 1][CHARMAP_SYMBOL_LEN];
  50. #undef __collate_substitute_table
  51. u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
  52. #undef __collate_char_pri_table
  53. struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
  54. struct __collate_st_chain_pri *__collate_chain_pri_table;
  55. int chain_index = 0;
  56. int prim_pri = 1, sec_pri = 1;
  57. #ifdef COLLATE_DEBUG
  58. int debug;
  59. #endif
  60. const char *out_file = "LC_COLLATE";
  61. %}
  62. %union {
  63. u_char ch;
  64. u_char str[BUFSIZE];
  65. }
  66. %token SUBSTITUTE WITH ORDER RANGE
  67. %token <str> STRING
  68. %token <str> DEFN
  69. %token <ch> CHAR
  70. %%
  71. collate : statment_list
  72. ;
  73. statment_list : statment
  74. | statment_list '\n' statment
  75. ;
  76. statment :
  77. | charmap
  78. | substitute
  79. | order
  80. ;
  81. charmap : DEFN CHAR {
  82. if (strlen($1) + 1 > CHARMAP_SYMBOL_LEN)
  83. yyerror("Charmap symbol name '%s' is too long", $1);
  84. strcpy(charmap_table[$2], $1);
  85. }
  86. ;
  87. substitute : SUBSTITUTE CHAR WITH STRING {
  88. if ($2 == '\0')
  89. yyerror("NUL character can't be substituted");
  90. if (strchr($4, $2) != NULL)
  91. yyerror("Char 0x%02x substitution is recursive", $2);
  92. if (strlen($4) + 1 > STR_LEN)
  93. yyerror("Char 0x%02x substitution is too long", $2);
  94. strcpy(__collate_substitute_table[$2], $4);
  95. }
  96. ;
  97. order : ORDER order_list {
  98. FILE *fp;
  99. int ch, substed, ordered;
  100. uint32_t u32;
  101. for (ch = 0; ch < UCHAR_MAX + 1; ch++) {
  102. substed = (__collate_substitute_table[ch][0] != ch);
  103. ordered = !!__collate_char_pri_table[ch].prim;
  104. if (!ordered && !substed)
  105. yyerror("Char 0x%02x not found", ch);
  106. if (substed && ordered)
  107. yyerror("Char 0x%02x can't be ordered since substituted", ch);
  108. }
  109. if ((__collate_chain_pri_table = realloc(__collate_chain_pri_table,
  110. sizeof(*__collate_chain_pri_table) * (chain_index + 1))) == NULL)
  111. yyerror("can't grow chain table");
  112. (void)memset(&__collate_chain_pri_table[chain_index], 0,
  113. sizeof(__collate_chain_pri_table[0]));
  114. chain_index++;
  115. #ifdef COLLATE_DEBUG
  116. if (debug)
  117. collate_print_tables();
  118. #endif
  119. if ((fp = fopen(out_file, "w")) == NULL)
  120. err(EX_UNAVAILABLE, "can't open destination file %s",
  121. out_file);
  122. strcpy(__collate_version, COLLATE_VERSION1_2);
  123. if (fwrite(__collate_version, sizeof(__collate_version), 1, fp) != 1)
  124. err(EX_IOERR,
  125. "IO error writting collate version to destination file %s",
  126. out_file);
  127. u32 = htonl(chain_index);
  128. if (fwrite(&u32, sizeof(u32), 1, fp) != 1)
  129. err(EX_IOERR,
  130. "IO error writting chains number to destination file %s",
  131. out_file);
  132. if (fwrite(__collate_substitute_table,
  133. sizeof(__collate_substitute_table), 1, fp) != 1)
  134. err(EX_IOERR,
  135. "IO error writting substitute table to destination file %s",
  136. out_file);
  137. for (ch = 0; ch < UCHAR_MAX + 1; ch++) {
  138. __collate_char_pri_table[ch].prim =
  139. htonl(__collate_char_pri_table[ch].prim);
  140. __collate_char_pri_table[ch].sec =
  141. htonl(__collate_char_pri_table[ch].sec);
  142. }
  143. if (fwrite(__collate_char_pri_table,
  144. sizeof(__collate_char_pri_table), 1, fp) != 1)
  145. err(EX_IOERR,
  146. "IO error writting char table to destination file %s",
  147. out_file);
  148. for (ch = 0; ch < chain_index; ch++) {
  149. __collate_chain_pri_table[ch].prim =
  150. htonl(__collate_chain_pri_table[ch].prim);
  151. __collate_chain_pri_table[ch].sec =
  152. htonl(__collate_chain_pri_table[ch].sec);
  153. }
  154. if (fwrite(__collate_chain_pri_table,
  155. sizeof(*__collate_chain_pri_table), chain_index, fp) !=
  156. (size_t)chain_index)
  157. err(EX_IOERR,
  158. "IO error writting chain table to destination file %s",
  159. out_file);
  160. if (fclose(fp) != 0)
  161. err(EX_IOERR, "IO error closing destination file %s",
  162. out_file);
  163. exit(EX_OK);
  164. }
  165. ;
  166. order_list : item
  167. | order_list ';' item
  168. ;
  169. chain : CHAR CHAR {
  170. curr_chain[0] = $1;
  171. curr_chain[1] = $2;
  172. if (curr_chain[0] == '\0' || curr_chain[1] == '\0')
  173. yyerror("\\0 can't be chained");
  174. curr_chain[2] = '\0';
  175. }
  176. | chain CHAR {
  177. static char tb[2];
  178. tb[0] = $2;
  179. if (tb[0] == '\0')
  180. yyerror("\\0 can't be chained");
  181. if (strlen(curr_chain) + 2 > STR_LEN)
  182. yyerror("Chain '%s' grows too long", curr_chain);
  183. (void)strcat(curr_chain, tb);
  184. }
  185. ;
  186. item : CHAR {
  187. if (__collate_char_pri_table[$1].prim)
  188. yyerror("Char 0x%02x duplicated", $1);
  189. __collate_char_pri_table[$1].prim = prim_pri++;
  190. }
  191. | chain {
  192. if ((__collate_chain_pri_table = realloc(__collate_chain_pri_table,
  193. sizeof(*__collate_chain_pri_table) * (chain_index + 1))) == NULL)
  194. yyerror("can't grow chain table");
  195. (void)memset(&__collate_chain_pri_table[chain_index], 0,
  196. sizeof(__collate_chain_pri_table[0]));
  197. (void)strcpy(__collate_chain_pri_table[chain_index].str, curr_chain);
  198. __collate_chain_pri_table[chain_index].prim = prim_pri++;
  199. chain_index++;
  200. }
  201. | CHAR RANGE CHAR {
  202. u_int i;
  203. if ($3 <= $1)
  204. yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3);
  205. for (i = $1; i <= $3; i++) {
  206. if (__collate_char_pri_table[(u_char)i].prim)
  207. yyerror("Char 0x%02x duplicated", (u_char)i);
  208. __collate_char_pri_table[(u_char)i].prim = prim_pri++;
  209. }
  210. }
  211. | '{' prim_order_list '}' {
  212. prim_pri++;
  213. }
  214. | '(' sec_order_list ')' {
  215. prim_pri++;
  216. sec_pri = 1;
  217. }
  218. ;
  219. prim_order_list : prim_sub_item
  220. | prim_order_list ',' prim_sub_item
  221. ;
  222. sec_order_list : sec_sub_item
  223. | sec_order_list ',' sec_sub_item
  224. ;
  225. prim_sub_item : CHAR {
  226. if (__collate_char_pri_table[$1].prim)
  227. yyerror("Char 0x%02x duplicated", $1);
  228. __collate_char_pri_table[$1].prim = prim_pri;
  229. }
  230. | CHAR RANGE CHAR {
  231. u_int i;
  232. if ($3 <= $1)
  233. yyerror("Illegal range 0x%02x -- 0x%02x",
  234. $1, $3);
  235. for (i = $1; i <= $3; i++) {
  236. if (__collate_char_pri_table[(u_char)i].prim)
  237. yyerror("Char 0x%02x duplicated", (u_char)i);
  238. __collate_char_pri_table[(u_char)i].prim = prim_pri;
  239. }
  240. }
  241. | chain {
  242. if ((__collate_chain_pri_table = realloc(__collate_chain_pri_table,
  243. sizeof(*__collate_chain_pri_table) * (chain_index + 1))) == NULL)
  244. yyerror("can't grow chain table");
  245. (void)memset(&__collate_chain_pri_table[chain_index], 0,
  246. sizeof(__collate_chain_pri_table[0]));
  247. (void)strcpy(__collate_chain_pri_table[chain_index].str, curr_chain);
  248. __collate_chain_pri_table[chain_index].prim = prim_pri;
  249. chain_index++;
  250. }
  251. ;
  252. sec_sub_item : CHAR {
  253. if (__collate_char_pri_table[$1].prim)
  254. yyerror("Char 0x%02x duplicated", $1);
  255. __collate_char_pri_table[$1].prim = prim_pri;
  256. __collate_char_pri_table[$1].sec = sec_pri++;
  257. }
  258. | CHAR RANGE CHAR {
  259. u_int i;
  260. if ($3 <= $1)
  261. yyerror("Illegal range 0x%02x -- 0x%02x",
  262. $1, $3);
  263. for (i = $1; i <= $3; i++) {
  264. if (__collate_char_pri_table[(u_char)i].prim)
  265. yyerror("Char 0x%02x duplicated", (u_char)i);
  266. __collate_char_pri_table[(u_char)i].prim = prim_pri;
  267. __collate_char_pri_table[(u_char)i].sec = sec_pri++;
  268. }
  269. }
  270. | chain {
  271. if ((__collate_chain_pri_table = realloc(__collate_chain_pri_table,
  272. sizeof(*__collate_chain_pri_table) * (chain_index + 1))) == NULL)
  273. yyerror("can't grow chain table");
  274. (void)memset(&__collate_chain_pri_table[chain_index], 0,
  275. sizeof(__collate_chain_pri_table[0]));
  276. (void)strcpy(__collate_chain_pri_table[chain_index].str, curr_chain);
  277. __collate_chain_pri_table[chain_index].prim = prim_pri;
  278. __collate_chain_pri_table[chain_index].sec = sec_pri++;
  279. chain_index++;
  280. }
  281. ;
  282. %%
  283. int
  284. main(int ac, char **av)
  285. {
  286. int ch;
  287. #ifdef COLLATE_DEBUG
  288. while((ch = getopt(ac, av, ":do:I:")) != -1) {
  289. #else
  290. while((ch = getopt(ac, av, ":o:I:")) != -1) {
  291. #endif
  292. switch (ch)
  293. {
  294. #ifdef COLLATE_DEBUG
  295. case 'd':
  296. debug++;
  297. break;
  298. #endif
  299. case 'o':
  300. out_file = optarg;
  301. break;
  302. case 'I':
  303. strlcpy(map_name, optarg, sizeof(map_name));
  304. break;
  305. default:
  306. usage();
  307. }
  308. }
  309. ac -= optind;
  310. av += optind;
  311. if (ac > 0) {
  312. if ((yyin = fopen(*av, "r")) == NULL)
  313. err(EX_UNAVAILABLE, "can't open source file %s", *av);
  314. }
  315. for (ch = 0; ch <= UCHAR_MAX; ch++)
  316. __collate_substitute_table[ch][0] = ch;
  317. yyparse();
  318. return 0;
  319. }
  320. static void
  321. usage(void)
  322. {
  323. fprintf(stderr, "usage: colldef [-I map_dir] [-o out_file] [filename]\n");
  324. exit(EX_USAGE);
  325. }
  326. void
  327. yyerror(const char *fmt, ...)
  328. {
  329. va_list ap;
  330. char msg[128];
  331. va_start(ap, fmt);
  332. vsnprintf(msg, sizeof(msg), fmt, ap);
  333. va_end(ap);
  334. errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no);
  335. }
  336. #ifdef COLLATE_DEBUG
  337. static void
  338. collate_print_tables(void)
  339. {
  340. int i;
  341. printf("Substitute table:\n");
  342. for (i = 0; i < UCHAR_MAX + 1; i++)
  343. if (i != *__collate_substitute_table[i])
  344. printf("\t'%c' --> \"%s\"\n", i,
  345. __collate_substitute_table[i]);
  346. printf("Chain priority table:\n");
  347. for (i = 0; i < chain_index - 1; i++)
  348. printf("\t\"%s\" : %d %d\n",
  349. __collate_chain_pri_table[i].str,
  350. __collate_chain_pri_table[i].prim,
  351. __collate_chain_pri_table[i].sec);
  352. printf("Char priority table:\n");
  353. for (i = 0; i < UCHAR_MAX + 1; i++)
  354. printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
  355. __collate_char_pri_table[i].sec);
  356. }
  357. #endif