tabgen.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /*
  6. chtabgen - character table generator
  7. Author: Erik Baalbergen (..tjalk!erikb)
  8. Many mods by Ceriel Jacobs
  9. */
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #ifndef NORCSID
  14. static char *RcsId = "$Id$";
  15. #endif
  16. #define MAXBUF 256
  17. #define MAXTAB 10000
  18. #define COMCOM '-'
  19. #define FILECOM '%'
  20. int InputForm = 'c'; /* default input format (and, currently, only one) */
  21. char OutputForm[MAXBUF] = "%s,\n";
  22. /* format for spitting out a string */
  23. char *Table[MAXTAB];
  24. char *ProgCall; /* callname of this program */
  25. int TabSize = 128; /* default size of generated table */
  26. char *InitialValue; /* initial value of all table entries */
  27. main(argc, argv)
  28. char *argv[];
  29. {
  30. ProgCall = *argv++;
  31. argc--;
  32. while (argc-- > 0) {
  33. if (**argv == COMCOM) {
  34. option(*argv++);
  35. }
  36. else {
  37. if (! process(*argv++, InputForm)) {
  38. exit(1);
  39. }
  40. }
  41. }
  42. exit(0);
  43. /*NOTREACHED*/
  44. }
  45. char *
  46. Salloc(s)
  47. char *s;
  48. {
  49. char *ns = malloc((unsigned)strlen(s) + 1);
  50. if (ns) {
  51. strcpy(ns, s);
  52. }
  53. else {
  54. fprintf(stderr, "%s: out of memory\n", ProgCall);
  55. exit(1);
  56. }
  57. return ns;
  58. }
  59. option(str)
  60. char *str;
  61. {
  62. /* note that *str indicates the source of the option:
  63. either COMCOM (from command line) or FILECOM (from a file).
  64. */
  65. switch (*++str) {
  66. case ' ': /* command */
  67. case '\t':
  68. case '\0':
  69. break;
  70. case 'I': /* for future extension */
  71. InputForm = *++str;
  72. break;
  73. case 'f': /* input from file ... */
  74. if (*++str == '\0') {
  75. fprintf(stderr, "%s: -f: name expected\n", ProgCall);
  76. exit(1);
  77. }
  78. DoFile(str);
  79. break;
  80. case 'F': /* new output format string */
  81. sprintf(OutputForm, "%s\n", ++str);
  82. break;
  83. case 'T': /* insert text literally */
  84. printf("%s\n", ++str);
  85. break;
  86. case 'p': /* print table */
  87. PrintTable();
  88. break;
  89. case 'C': /* clear table */
  90. InitTable((char *)0);
  91. break;
  92. case 'i': /* initialize table with given value */
  93. if (*++str == '\0') {
  94. InitTable((char *)0);
  95. }
  96. else InitTable(str);
  97. break;
  98. case 'S':
  99. {
  100. int i = atoi(++str);
  101. if (i <= 0 || i > MAXTAB) {
  102. fprintf(stderr, "%s: size would exceed maximum\n",
  103. ProgCall);
  104. }
  105. else {
  106. TabSize = i;
  107. }
  108. break;
  109. }
  110. default:
  111. fprintf(stderr, "%s: bad option -%s\n", ProgCall, str);
  112. }
  113. }
  114. InitTable(ival)
  115. char *ival;
  116. {
  117. int i;
  118. for (i = 0; i < TabSize; i++) {
  119. Table[i] = 0;
  120. }
  121. InitialValue = 0;
  122. if (ival) {
  123. InitialValue = Salloc(ival);
  124. }
  125. }
  126. PrintTable()
  127. {
  128. int i;
  129. for (i = 0; i < TabSize; i++) {
  130. if (Table[i]) {
  131. printf(OutputForm, Table[i]);
  132. }
  133. else if (InitialValue) {
  134. printf(OutputForm, InitialValue);
  135. }
  136. else {
  137. printf(OutputForm, "0");
  138. }
  139. }
  140. }
  141. int
  142. process(str, format)
  143. char *str;
  144. {
  145. char *cstr = str;
  146. char *Name = cstr; /* overwrite original string! */
  147. /* strip of the entry name
  148. */
  149. while (*str && *str != ':') {
  150. if (*str == '\\') {
  151. ++str;
  152. }
  153. *cstr++ = *str++;
  154. }
  155. if (*str != ':') {
  156. fprintf(stderr, "%s: bad specification: \"%s\", ignored\n",
  157. ProgCall, Name);
  158. return 0;
  159. }
  160. *cstr = '\0';
  161. str++;
  162. switch (format) {
  163. case 'c':
  164. return c_proc(str, Name);
  165. default:
  166. fprintf(stderr, "%s: bad input format\n", ProgCall);
  167. }
  168. return 0;
  169. }
  170. c_proc(str, Name)
  171. char *str;
  172. char *Name;
  173. {
  174. int ch, ch2;
  175. int quoted();
  176. char *name = Salloc(Name);
  177. while (*str) {
  178. if (*str == '\\') {
  179. ch = quoted(&str);
  180. }
  181. else {
  182. ch = *str++ & 0377;
  183. }
  184. if (*str == '-') {
  185. if (*++str == '\\') {
  186. ch2 = quoted(&str);
  187. }
  188. else {
  189. if (ch2 = (*str++ & 0377));
  190. else str--;
  191. }
  192. if (ch > ch2) {
  193. fprintf(stderr, "%s: bad range\n", ProgCall);
  194. return 0;
  195. }
  196. while (ch <= ch2) {
  197. if (! setval(ch, name)) return 0;
  198. ch++;
  199. }
  200. }
  201. else {
  202. if (! setval(ch, name)) return 0;
  203. }
  204. }
  205. return 1;
  206. }
  207. int
  208. setval(ch, nm)
  209. char *nm;
  210. {
  211. char **p = &Table[ch];
  212. if (ch < 0 || ch >= TabSize) {
  213. fprintf(stderr, "Illegal index: %d\n", ch);
  214. return 0;
  215. }
  216. if (*(p = &Table[ch])) {
  217. fprintf(stderr, "Warning: redefinition of index %d\n", ch);
  218. }
  219. *p = nm;
  220. return 1;
  221. }
  222. int
  223. quoted(pstr)
  224. char **pstr;
  225. {
  226. int ch;
  227. int i;
  228. char *str = *pstr;
  229. if ((*++str >= '0') && (*str <= '9')) {
  230. ch = 0;
  231. for (i = 0; i < 3; i++) {
  232. ch = 8 * ch + (*str - '0');
  233. if (*++str < '0' || *str > '9')
  234. break;
  235. }
  236. }
  237. else {
  238. switch (*str++) {
  239. case 'n':
  240. ch = '\n';
  241. break;
  242. case 't':
  243. ch = '\t';
  244. break;
  245. case 'b':
  246. ch = '\b';
  247. break;
  248. case 'r':
  249. ch = '\r';
  250. break;
  251. case 'f':
  252. ch = '\f';
  253. break;
  254. case 'v':
  255. ch = 013;
  256. break;
  257. default :
  258. ch = *(str - 1);
  259. break;
  260. }
  261. }
  262. *pstr = str;
  263. return ch & 0377;
  264. }
  265. char *
  266. getline(s, n, fp)
  267. char *s;
  268. FILE *fp;
  269. {
  270. int c = getc(fp);
  271. char *str = s;
  272. while (n--) {
  273. if (c == EOF) {
  274. return NULL;
  275. }
  276. else
  277. if (c == '\n') {
  278. *str++ = '\0';
  279. return s;
  280. }
  281. *str++ = c;
  282. c = getc(fp);
  283. }
  284. s[n - 1] = '\0';
  285. return s;
  286. }
  287. #define BUFSIZE 1024
  288. DoFile(name)
  289. char *name;
  290. {
  291. char text[BUFSIZE];
  292. FILE *fp;
  293. if ((fp = fopen(name, "r")) == NULL) {
  294. fprintf(stderr, "%s: cannot read file %s\n", ProgCall, name);
  295. exit(1);
  296. }
  297. while (getline(text, BUFSIZE, fp) != NULL) {
  298. if (text[0] == FILECOM) {
  299. option(text);
  300. }
  301. else {
  302. if (! process(text, InputForm)) {
  303. exit(1);
  304. }
  305. }
  306. }
  307. }