home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / VILE327.ZIP / VILE327.TAR / vile3.27 / mktbls.c < prev    next >
C/C++ Source or Header  |  1992-12-14  |  9KB  |  409 lines

  1. /* This standalone utility program constructs the function, key and command
  2.  *    binding tables for vile.  The input is a data file containing the
  3.  *    desired default relationships among the three entities.  Output
  4.  *    is nebind.h, nefunc.h, and nename.h, all of which are then included
  5.  *    in main.c
  6.  *    This code written by Paul Fox, (c)1990
  7.  *    
  8.  *    See the file "cmdtbls" for input data formats, and "estruct.h" for
  9.  *    the output structures.
  10.  *
  11.  * $Log: mktbls.c,v $
  12.  * Revision 1.9  1992/07/17  19:12:44  foxharp
  13.  * explicit int return on func
  14.  *
  15.  * Revision 1.8  1992/07/08  08:35:09  foxharp
  16.  * don't report duplicate keymaps if the pre-processor conditionals are
  17.  * both present, and they don't match -- in that case, they're unlikely
  18.  * to both compile in at the same time.
  19.  *
  20.  * also, be sure to emit backslash escapes when printing ' and \ character
  21.  * constants, i.e. '\'' and '\\'
  22.  *
  23.  * Revision 1.7  1992/05/29  08:34:01  foxharp
  24.  * prototypes, gcc -W cleanups
  25.  *
  26.  * Revision 1.6  1991/11/07  03:29:12  pgf
  27.  * lint cleanup
  28.  *
  29.  * Revision 1.5  1991/11/01  14:38:00  pgf
  30.  * saber cleanup
  31.  *
  32.  * Revision 1.4  1991/08/07  12:35:07  pgf
  33.  * added RCS log messages
  34.  *
  35.  * revision 1.3
  36.  * date: 1991/06/03 17:34:57;
  37.  * switch from "meta" etc. to "ctla" etc.
  38.  * 
  39.  * revision 1.2
  40.  * date: 1991/06/03 10:26:03;
  41.  * commentary change
  42.  * 
  43.  * revision 1.1
  44.  * date: 1990/09/21 10:25:40;
  45.  * initial vile RCS revision
  46.  */
  47.  
  48. #include <stdio.h>
  49. #include <string.h>
  50.  
  51. char *progcreat = "/* %s: this header file was produced automatically by\n\
  52.  * the %s program, based on input from the file %s\n */\n";
  53.  
  54. #define    DIFCNTRL    0x40
  55. #define tocntrl(c)    ((c)^DIFCNTRL)
  56. #define toalpha(c)    ((c)^DIFCNTRL)
  57. #define    DIFCASE        0x20
  58. #define toupper(c)    ((c)^DIFCASE)
  59. #define tolower(c)    ((c)^DIFCASE)
  60.  
  61. int l = 0;
  62. FILE *nebind, *nefunc, *nename, *cmdtbl;
  63.  
  64. #if __STDC__
  65. # define P(a) a
  66. #else
  67. # define P(a) ()
  68. #endif
  69.  
  70. int main P(( int, char *[]));
  71. void badfmt P(( char * ));
  72. void savenames P(( char *, char *, char * ));
  73. void savebindings P(( char *, char *, char * ));
  74. void dumpnames P((void));
  75. void dumpbindings P((void));
  76. char *formcond P(( char *, char * ));
  77. extern char *malloc();
  78.  
  79.  
  80. struct stringl {
  81.     char *s1;
  82.     char *s2;
  83.     char *s3;
  84.     struct stringl *nst;
  85. };
  86.     
  87. int
  88. main(argc, argv)
  89. int    argc;
  90. char    *argv[];
  91. {
  92.     char line[100];
  93.     char func[50];
  94.     char flags[50];
  95.     char english[50];
  96.     char fcond[50];
  97.     char ncond[50];
  98.     char key[50];
  99.     int r;
  100.     
  101.     if (argc != 2) {
  102.         fprintf(stderr, "usage: mktbls cmd-file\n");
  103.         exit(1);
  104.     }
  105.     
  106.     if ((cmdtbl = fopen(argv[1],"r")) == NULL ) {
  107.         fprintf(stderr,"mktbls: couldn't open cmd-file\n");
  108.         exit(1);
  109.     }
  110.     
  111.     if ( (nebind = fopen("nebind.h","w")) == NULL ||
  112.         (nefunc = fopen("nefunc.h","w")) == NULL ||
  113.         (nename = fopen("nename.h","w")) == NULL ) {
  114.         fprintf(stderr,"mktbls: couldn't open header files\n");
  115.         exit(1);
  116.     }
  117.     
  118.     fprintf(nebind,progcreat,"nebind.h",argv[0],argv[1]);
  119.     fprintf(nefunc,progcreat,"nefunc.h",argv[0],argv[1]);
  120.     fprintf(nename,progcreat,"nename.h",argv[0],argv[1]);
  121.     
  122.     
  123.     /* process each input line */
  124.     while (fgets(line,100,cmdtbl) != NULL) {
  125.         l++;
  126.         if (line[0] == '#') {  /* comment */
  127.             continue;
  128.         } else if (line[0] == '\n') { /* empty line */
  129.             continue;
  130.         } else if (line[0] != '\t') { /* then it's a new func */
  131.             /* we can spill information about funcs right away */
  132.             r = sscanf(line,"%s %s %s",func,flags,fcond);
  133.             if (r < 2 || r > 3)
  134.                 badfmt("looking for new function");
  135.             if (r != 3)
  136.                 fcond[0] = '\0';
  137.                 
  138.             if (fcond[0])
  139.                 fprintf(nefunc,"#if %s\n",fcond);
  140.             fprintf(nefunc,"extern int %s();\n", func);
  141.             fprintf(nefunc,"\tCMDFUNC f_%s = { %s,\t%s };\n",
  142.                 func, func, flags);
  143.             if (fcond[0])
  144.                 fprintf(nefunc,"#endif\n");
  145.                 
  146.         } else if (line[1] == '"') { /* then it's an english name */
  147.         
  148.             r = sscanf(line, " \"%[^\"]\"    %s", english,ncond);
  149.             if (r < 1 || r > 2)
  150.                 badfmt("looking for english name");
  151.             if (r != 2)
  152.                 ncond[0] = '\0';
  153.                 
  154.             savenames(english, func, formcond(fcond,ncond));
  155.                 
  156.         } else if (line[1] == '\'') { /* then it's a key */
  157.             r = sscanf(&line[2], "%[^']' %s", key, ncond);
  158.             if (r < 1 || r > 2)
  159.                 badfmt("looking for key binding");
  160.             if (r != 2)
  161.                 ncond[0] = '\0';
  162.                 
  163.             savebindings(key, func, formcond(fcond,ncond));
  164.             
  165.         } else {
  166.             badfmt("bad line");
  167.         }
  168.     }
  169.     
  170.     dumpnames();
  171.     dumpbindings();
  172.     
  173.     return 0;
  174. }
  175.  
  176. char *
  177. formcond(c1,c2)
  178. char *c1, *c2;
  179. {
  180.     static char cond[50];
  181.     if (c1[0] && c2[0])
  182.         sprintf(cond,"#if (%s) & (%s)\n",c1,c2);
  183.     else if (c1[0] || c2[0])
  184.         sprintf(cond,"#if (%s%s)\n",c1,c2);
  185.     else
  186.         cond[0] = '\0';
  187.     return cond;
  188. }
  189.  
  190. void
  191. badfmt(s)
  192. char *s;
  193. {
  194.     fprintf(stderr,"\"cmdtbl\", line %d: bad format:",l);
  195.     fprintf(stderr,"    %s\n",s);
  196.     exit(1);
  197. }
  198.  
  199. #define ASCIIBIND 0
  200. #define CTLXBIND 1
  201. #define CTLABIND 2
  202. #define SPECBIND 3
  203. char *bindings[4][128];
  204. char *conditions[4][128];
  205. char *tblname[] = {"asciitbl", "ctlxtbl", "metatbl", "spectbl" };
  206. char *prefname[] = {"", "CTLX|", "CTLA|", "SPEC|" };
  207.  
  208. int
  209. two_conds(btype,c,cond)
  210. int btype,c;
  211. char *cond;
  212. {
  213.     /* return true if both bindings have different
  214.      conditions associated with them */
  215.     return (cond[0] != 0 && 
  216.         conditions[btype][c] != NULL && 
  217.         strcmp(cond, conditions[btype][c]) != 0);
  218. }
  219.  
  220. /* prc2kcod: translate printable code to C-language keycode */
  221. void
  222. savebindings(s,func,cond)
  223. char *s, *func, *cond;
  224. {
  225.     int btype, c;
  226.     
  227.     btype = ASCIIBIND;
  228.     
  229.     if (*s == '^' && *(s+1) == 'A'&& *(s+2) == '-') {
  230.         btype = CTLABIND;
  231.         s += 3;
  232.     } else if (*s == 'F' && *(s+1) == 'N' && *(s+2) == '-') {
  233.         btype = SPECBIND;
  234.         s += 3;
  235.     } else if (*s == '^' && *(s+1) == 'X'&& *(s+2) == '-') {
  236.         btype = CTLXBIND;
  237.         s += 3;
  238.     }
  239.     
  240.     if (*s == '\\') { /* try for an octal value */
  241.         c = 0;
  242.         while (*++s < '8' && *s >= '0')
  243.             c = (c*8) + *s - '0';
  244.         if (c > 127)
  245.             badfmt("octal character too big");
  246.         if (bindings[btype][c] != NULL && !two_conds(btype,c,cond))
  247.             badfmt("duplicate key binding");
  248.         bindings[btype][c] = malloc(strlen(func)+1);
  249.         strcpy(bindings[btype][c], func);
  250.     } else if (*s == '^' && (c = *(s+1)) != '\0') { /* a control char? */
  251.         if (c > 'a' &&  c < 'z')
  252.             c = toupper(c);
  253.         c = tocntrl(c);
  254.         if (bindings[btype][c] != NULL && !two_conds(btype,c,cond))
  255.             badfmt("duplicate key binding");
  256.         bindings[btype][c] = malloc(strlen(func)+1);
  257.         strcpy(bindings[btype][c], func);
  258.         s += 2;
  259.     } else if (c = *s) {
  260.         if (bindings[btype][c] != NULL && !two_conds(btype,c,cond))
  261.             badfmt("duplicate key binding");
  262.         bindings[btype][c] = malloc(strlen(func)+1);
  263.         strcpy(bindings[btype][c], func);
  264.         s++;
  265.     } else {
  266.         badfmt("getting binding");
  267.     }
  268.     if (cond[0]) {
  269.         conditions[btype][c] = malloc(strlen(cond)+1);
  270.         strcpy(conditions[btype][c], cond);
  271.     } else {
  272.         conditions[btype][c] = NULL;
  273.     }
  274.     
  275.     if (*s != '\0')
  276.         badfmt("got extra characters");
  277.     
  278. }
  279.  
  280. void
  281. dumpbindings()
  282. {
  283.     char *sctl;
  284.     int i, c, btype;
  285.     
  286.     btype = ASCIIBIND;
  287.     
  288.     fprintf(nebind,"\nCMDFUNC *%s[128] = {\n",tblname[btype]);
  289.     for (i = 0; i < 128; i++) {
  290.         if (conditions[btype][i]) {
  291.             fprintf(nebind,"%s", conditions[btype][i]);
  292.         }
  293.         if (i < ' ' || i > '~' ) {
  294.             sctl = "ctrl-";
  295.             c = toalpha(i);
  296.         } else {
  297.             sctl = "";
  298.             c = i;
  299.         }
  300.             
  301.         if (bindings[btype][i])
  302.             fprintf(nebind,"    &f_%s,    /* %s%c */\n",
  303.                 bindings[btype][i], sctl, c);
  304.         else
  305.             fprintf(nebind,"    NULL,    /* %s%c */\n", sctl, c);
  306.         if (conditions[btype][i]) {
  307.             fprintf(nebind,"#else\n    NULL,\n#endif\n");
  308.         }
  309.             
  310.     }
  311.     fprintf(nebind,"};\n");
  312.     
  313.     
  314.     fprintf(nebind,"\nKBIND kbindtbl[NBINDS] = {\n");
  315.     for (btype = 1; btype <= 3; btype++) {
  316.         for (i = 0; i < 128; i++) {
  317.             if (bindings[btype][i]) {
  318.                 if (conditions[btype][i]) {
  319.                     fprintf(nebind,"%s",
  320.                         conditions[btype][i]);
  321.                 }
  322.                 if (i < ' ') {
  323.                     fprintf(nebind,
  324.                     "    { %stocntrl('%c'), &f_%s },\n",
  325.                         prefname[btype],
  326.                         toalpha(i),bindings[btype][i]);
  327.                 } else {
  328.                     fprintf(nebind,
  329.                     "    { %s'%s%c', &f_%s },\n",
  330.                         prefname[btype],
  331.                         (i == '\'' || i == '\\') ?
  332.                             "\\":"",
  333.                         i, bindings[btype][i]);
  334.                 }
  335.                 if (conditions[btype][i]) {
  336.                     fprintf(nebind,"#endif\n");
  337.                 }
  338.             }
  339.         }
  340.     }
  341.     fprintf(nebind,"    { 0, NULL }\n");
  342.     fprintf(nebind,"};\n");
  343. }
  344.  
  345. struct stringl lastname = {"\177\177\177\177\177\177", "", "", NULL};
  346. struct stringl firstname = {"", "", "", &lastname};
  347.  
  348. void
  349. savenames(name,func,cond)
  350. char *name, *func, *cond;
  351. {
  352.     char tmpline[80];
  353.     struct stringl *n, *m;
  354.     int r;
  355.     
  356.     n = (struct stringl *)malloc(sizeof (struct stringl));
  357.     
  358.     n->s1 = (char *)malloc(strlen(name)+1);
  359.     strcpy(n->s1, name);
  360.     
  361.     sprintf(tmpline,"\t{ \"%s\",\t&f_%s },\n",
  362.         name, func);
  363.     n->s2 = (char *)malloc(strlen(func)+1);
  364.     strcpy(n->s2, func);
  365.     
  366.     n->s3 = (char *)malloc(strlen(cond)+1);
  367.     strcpy(n->s3, cond);
  368.     
  369.     for (m = &firstname; m->nst != NULL; m = m->nst) {
  370.         if ((r = strcmp(n->s1, m->nst->s1)) < 0) { /* insert it here */
  371.             n->nst = m->nst;
  372.             m->nst = n;
  373.             break;
  374.         } else if (r == 0) {
  375.             badfmt("duplicate english name");
  376.         }
  377.     }
  378. }
  379.  
  380. void
  381. dumpnames()
  382. {
  383.     struct stringl *m;
  384.     
  385.     fprintf(nename,"\n/* if you maintain this by hand, keep it in */\n");
  386.     fprintf(nename,"/* alphabetical order!!!! */\n\n");
  387.     fprintf(nename,"NTAB nametbl[] = {\n");
  388.     for (m = firstname.nst; m->nst != NULL; m = m->nst) {
  389.         if (m->s3[0])
  390.             fprintf(nename,"%s",m->s3);
  391.         fprintf(nename,"\t{ \"%s\",\t&f_%s },\n", m->s1, m->s2);
  392.         if (m->s3[0])
  393.             fprintf(nename,"#endif\n");
  394.     }
  395.     fprintf(nename,"    { NULL, NULL }\n};\n");
  396. }
  397.  
  398. #ifdef NEEDED
  399. strtolower(s)
  400. char *s;
  401. {
  402.     while (*s) {
  403.         if (*s >= 'A' && *s <= 'Z')
  404.             *s = tolower(*s);
  405.         s++;
  406.     }
  407. }
  408. #endif
  409.