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