home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / telecomm / uemlsrc / extmac.c < prev    next >
C/C++ Source or Header  |  1987-08-24  |  13KB  |  377 lines

  1. /* EXTMAC.C support program for uemail.ttp.  Reads macro files created
  2.  * in uemail format and creates C source prototypes.
  3.  */
  4.  
  5. #include <stdio.h>
  6.  
  7. #define NFILEN  80                      /* # of bytes, file name        */
  8. #define NBUFN   16                      /* # of bytes, buffer name      */
  9. #define NLINE   256                     /* # of bytes, line             */
  10. #define NKBDM   256                     /* # of strokes, keyboard macro */
  11. #define NPAT    80                      /* # of bytes, pattern          */
  12. #define HUGE    1000                    /* Huge number                  */
  13. #define CTRL    0x0100                  /* Control flag, or'ed in       */
  14. #define META    0x0200                  /* Meta flag, or'ed in          */
  15. #define CTLX    0x0400                  /* ^X flag, or'ed in            */
  16. #define SPEC    0x0800                  /* Special scancode keys        */
  17. #define FLEN    15
  18.  
  19. short *kbdmop;
  20. short kbdm[NKBDM];
  21. FILE  *bmacrp, *fopen();
  22.  
  23. unsigned long _STKSIZ = 32 * 1024;
  24. typedef struct KEYTAB {
  25.         short   k_code;
  26.         char    k_mfunc[FLEN];
  27. } KEYTAB;
  28. /*
  29.  * Command table.
  30.  * This table  is *roughly* in ASCII
  31.  * order, left to right across the characters
  32.  * of the command. This expains the funny
  33.  * location of the control-X commands.
  34.  */
  35. KEYTAB  keytab[] = {
  36.         CTRL|'@',       "setmark",
  37.         CTRL|'A',       "gotobol",
  38.         CTRL|'B',       "backchar",
  39.         CTRL|'C',       "shell",
  40.         CTRL|'D',       "forwdel",
  41.         CTRL|'E',       "gotoeol",
  42.         CTRL|'F',       "forwchar",
  43.         CTRL|'G',       "ctrlg",
  44.         CTRL|'H',       "backchar",
  45.         CTRL|'I',       "tab",
  46.         CTRL|'J',       "indent",
  47.         CTRL|'K',       "mdeleln",
  48.         CTRL|'L',       "refresh",
  49.         CTRL|'M',       "newline",
  50.         CTRL|'N',       "forwline",
  51.         CTRL|'O',       "openline",
  52.         CTRL|'P',       "backline",
  53.         CTRL|'Q',       "quote",
  54.         CTRL|'R',       "backsearch",
  55.         CTRL|'S',       "forwsearch",
  56.         CTRL|'T',       "twiddle",
  57.         CTRL|'V',       "forwpage",
  58.         CTRL|'W',       "killregion",
  59.         CTRL|'Y',       "yank",
  60.         CTRL|'Z',       "quickexit",
  61.         CTRL|'\\',      "unkncom",
  62.         CTRL|'_',       "kermit",
  63.         CTRL|'^',       "unkncom",
  64.         CTLX|CTRL|'A',  "unkncom",
  65.         CTLX|CTRL|'B',  "listbuffers",
  66.         CTLX|CTRL|'C',  "quit",
  67.         CTLX|CTRL|'D',  "unkncom",
  68.         CTLX|CTRL|'E',  "commfil",
  69.         CTLX|CTRL|'F',  "filename",
  70.         CTLX|CTRL|'G',  "ctrlg",
  71.         CTLX|CTRL|'H',  "unkncom",
  72.         CTLX|CTRL|'I',  "print",
  73.         CTLX|CTRL|'J',  "unkncom",
  74.         CTLX|CTRL|'K',  "unkncom",
  75.         CTLX|CTRL|'L',  "lowerregion",
  76.         CTLX|CTRL|'M',  "unkncom",
  77.         CTLX|CTRL|'N',  "mvdnwind",
  78.         CTLX|CTRL|'O',  "deblank",
  79.         CTLX|CTRL|'P',  "mvupwind",
  80.         CTLX|CTRL|'Q',  "unkncom",
  81.         CTLX|CTRL|'R',  "fileread",
  82.         CTLX|CTRL|'S',  "filesave",
  83.         CTLX|CTRL|'T',  "showtime",
  84.         CTLX|CTRL|'U',  "upperregion",
  85.         CTLX|CTRL|'V',  "filevisit",
  86.         CTLX|CTRL|'W',  "filewrite",
  87.         CTLX|CTRL|'X',  "swapmark",
  88.         CTLX|CTRL|'Y',  "unkncom",
  89.         CTLX|CTRL|'Z',  "shrinkwind",
  90.         CTLX|'!',       "paginate",
  91.         CTLX|'#',       "setpage",
  92.         CTLX|'+',       "pageforw",
  93.         CTLX|'-',       "pageback",
  94.         CTLX|'.',       "setindcol",
  95.         CTLX|'(',       "ctlxlp",
  96.         CTLX|')',       "ctlxrp",
  97.         CTLX|'*',       "retversion",
  98.         CTLX|'<',       "btopunct",
  99.         CTLX|'=',       "showcpos",
  100.         CTLX|'>',       "ftopunct",
  101.         CTLX|'0',       "unkncom",
  102.         CTLX|'1',       "onlywind",
  103.         CTLX|'2',       "splitwind",
  104.         CTLX|'3',       "unkncom",
  105.         CTLX|'4',       "unkncom",
  106.         CTLX|'5',       "unkncom",
  107.         CTLX|'6',       "unkncom",
  108.         CTLX|'7',       "unkncom",
  109.         CTLX|'8',       "unkncom",
  110.         CTLX|'9',       "unkncom",
  111.         CTLX|'A',       "unkncom",
  112.         CTLX|'B',       "usebuffer",
  113.         CTLX|'C',       "paintbuffer",
  114.         CTLX|'D',       "setpath",
  115.         CTLX|'E',       "ctlxe",
  116.         CTLX|'F',       "setfillcol",
  117.         CTLX|'H',       "unkncom",
  118.         CTLX|'I',       "fileinsert",
  119.         CTLX|'J',       "unkncom",
  120.         CTLX|'K',       "killbuffer",
  121.         CTLX|'L',       "unkncom",
  122.         CTLX|'M',       "setmode",
  123.         CTLX|'N',       "nextwind",
  124.         CTLX|'O',       "prevwind",
  125.         CTLX|'P',       "prevwind",
  126.         CTLX|'Q',       "unkncom",
  127.         CTLX|'R',       "writereg",
  128.         CTLX|'S',       "gospell",
  129.         CTLX|'T',       "unkncom",
  130.         CTLX|'U',       "unkncom",
  131.         CTLX|'V',       "unkncom",
  132.         CTLX|'W',       "wc",
  133.         CTLX|'Y',       "unkncom",
  134.         CTLX|'Z',       "enlargewind",
  135.         CTLX|'\\',      "grtw",
  136.         CTLX|'`',       "getmacro",
  137.         CTLX|'~',       "shell",
  138.         CTLX|SPEC|'p',  "swapmark",
  139.         META|CTRL|'B',  "backword",
  140.         META|CTRL|'C',  "mcenter",
  141.         META|CTRL|'F',  "forwword",
  142.         META|CTRL|'G',  "ctrlg",
  143.         META|CTRL|'H',  "backword",
  144.         META|CTRL|'I',  "kill",
  145.         META|CTRL|'K',  "mdelwln",
  146.         META|CTRL|'M',  "unkncom",
  147.         META|CTRL|'N',  "enumerate",
  148.         META|CTRL|'O',  "clowsp",
  149.         META|CTRL|'P',  "tglcase",
  150.         META|CTRL|'R',  "mrflush",
  151.         META|CTRL|'S',  "forwisearch",
  152.         META|CTRL|'T',  "backisearch",
  153.         META|'!',       "reposition",
  154.         META|'.',       "gotoeob",
  155.         META|',',       "gotobob",
  156.         META|'>',       "gotoeob",
  157.         META|'<',       "gotobob",
  158.         META|' ',       "setmark",
  159.         META|'@',       "rettpa",
  160.         META|'A',       "backsent",
  161.         META|'B',       "backword",
  162.         META|'C',       "capword",
  163.         META|'D',       "delfword",
  164.         META|'E',       "forwsent",
  165.         META|'F',       "forwword",
  166.         META|'G',       "goline",
  167.         META|'H',       "markpar",
  168.         META|'I',       "unkncom",
  169.         META|'J',       "mindnl",
  170.         META|'K',       "killsent",
  171.         META|'L',       "lowerword",
  172.         META|'M',       "sglmode",
  173.         META|'N',       "goteop",
  174.         META|'O',       "mdropln",
  175.         META|'P',       "gotbop",
  176.         META|'Q',       "fillpar",
  177.         META|'R',       "replace",
  178.         META|'S',       "unkncom",
  179.         META|'T',       "twaddle",
  180.         META|'U',       "upperword",
  181.         META|'V',       "backpage",
  182.         META|'W',       "copyregion",
  183.         META|'X',       "mdoncom",
  184.         META|'Y',       "unkncom",
  185.         META|'Z',       "unkncom",
  186.         META|'\\',      "mdelind",
  187.         META|'~',       "clearflag",
  188.         META|0x7F,      "delbword",
  189.         SPEC|'H',       "backline",
  190.         SPEC|'P',       "forwline",
  191.         SPEC|'K',       "backchar",
  192.         SPEC|'M',       "forwchar",
  193.         SPEC|'b',       "kermit",
  194.         SPEC|'a',       "yank",
  195.         SPEC|'R',       "openline",
  196.         SPEC|'S',       "backdel",
  197.         SPEC|'G',       "refresh",
  198.         SPEC|'q',       "forwdel",
  199.         SPEC|'r',       "indent",
  200.         SPEC|'c',       "backword",
  201.         SPEC|'d',       "forwword",
  202.         SPEC|'e',       "grtw",
  203.         SPEC|'f',       "retversion",
  204.         SPEC|'g',       "gotobol",
  205.         SPEC|'h',       "gotoeol",
  206.         SPEC|'i',       "unkncom",
  207.         SPEC|'J',       "pageback",
  208.         SPEC|'N',       "pageforw",
  209.         SPEC|'j',       "backsent",
  210.         SPEC|'k',       "forwsent",
  211.         SPEC|'l',       "unkncom",
  212.         SPEC|'m',       "gotbop",
  213.         SPEC|'n',       "goteop",
  214.         SPEC|'o',       "unkncom",
  215.         SPEC|'D',       "quickexit",
  216.         SPEC|'C',       "filesave",
  217.         SPEC|'B',       "filewrite",
  218.         SPEC|'A',       "filevisit",
  219.         SPEC|'@',       "fileread",
  220.         SPEC|'?',       "fileinsert",
  221.         SPEC|'>',       "writereg",
  222.         SPEC|'=',       "filename",
  223.         SPEC|'<',       "listbuffers",
  224.         SPEC|';',       "setmark",
  225.         0x60,           "putmacro",
  226.         0x7F,           "backdel"
  227. };
  228.  
  229. #define NKEYTAB (sizeof(keytab)/sizeof(keytab[0]))
  230.  
  231. main(argc,argv)
  232. int argc;
  233. char *argv[];
  234. {
  235.         register int err;
  236.  
  237.         if (argc < 3)
  238.                 {
  239.                 fprintf(stderr,"usage: %s infile outfile\n",argv[0]);
  240.                 exit(-1);
  241.                 }
  242.         if ((bmacrp=fopen(argv[2], "w"))==NULL)
  243.                 {
  244.                 err = perror("open failure");
  245.                 exit(err);
  246.                 }
  247.         err=loadmac(argv[1]);
  248.         fclose(bmacrp);
  249.         exit(err);
  250. }
  251.  
  252. /* LOADMAC read a uemail macro file and produce a prototype C source file.
  253.  */
  254. loadmac(macfile)
  255. char macfile[];
  256. {
  257.         register int d,i;
  258.         register short s;
  259.         register FILE   *mp;
  260.         extern void extrct_macro();
  261.  
  262.         if ((mp=fopen(macfile,"r"))==NULL)
  263.                 {
  264.                 fprintf(stderr,"Cannot open %s",macfile);
  265.                 return(-1);
  266.                 }
  267.         if ((s=getw(mp))!=(CTLX|'('))
  268.                 {
  269.                 fprintf(stderr,"Macro file format error: %s",macfile);
  270.                 fclose(mp);
  271.                 return(-1);
  272.                 }
  273.         while((d=fgetc(mp))!=EOF)
  274.                 {
  275.                 i=0;
  276.                 while ((s=getw(mp))!=(CTLX|')'))
  277.                         {
  278.                         if (feof(mp))
  279.                                 {
  280.                                 fprintf(stderr,"Read error on: %s",macfile);
  281.                                 fclose(mp);
  282.                                 return(-11);    /* read error */
  283.                                 }
  284.                         kbdm[i++]=s;
  285.                         }
  286.                 kbdm[i] = CTLX|')';
  287.                 extrct_macro(d);
  288.                 }
  289.         fclose(mp);
  290.         return(NULL);
  291. }
  292.  
  293. /* Look at the current keyboard macro.  Send each bitcode to writmacro()
  294.  * so it can look up the function calling sequence in the KEYTAB.  These
  295.  * functions allow you to record keyboard macros in C source code for
  296.  * later compilation.
  297.  */
  298. void
  299. extrct_macro(d)
  300. {
  301.         register int    c;
  302.         register int    an;
  303.         register int    s;
  304.  
  305.         fprintf(bmacrp,"%c(f,n)\n",d);
  306.         fputs("int f,n;\n",bmacrp);     /* default uEmail parameters */
  307.         fputs("{\n",bmacrp);            /* begin definition */
  308.         fputs("        if (n < 0)\n",bmacrp);
  309.         fputs("                return(0);\n",bmacrp);
  310.         fputs("        while(n--)\n",bmacrp);
  311.         fputs("                {\n",bmacrp);
  312.         kbdmop = &kbdm[0];
  313.         do
  314.                 {
  315.                 an = 1;
  316.                 if ((c = *kbdmop++) == (CTRL|'U'))
  317.                         {
  318.                         an = *kbdmop++;
  319.                         c  = *kbdmop++;
  320.                         }
  321.                 s = TRUE;
  322.                 } while (c!=(CTLX|')') && (s=writmacro(c,an))==TRUE);
  323.         kbdmop = NULL;
  324.         fputs("                }\n",bmacrp);    /* end the while statement */
  325.         fputs("        return(1);\n",bmacrp);
  326.         fputs("}\n\n",bmacrp);
  327.         return;
  328. }
  329.  
  330. /* Look up function name based on bitcode found in extrct_macro().  No errors
  331.  * because a running macro that uses one of the "get-string" routines would
  332.  * return an error and extrct_macro() would abort.  Watch when using with
  333.  * functions that use mlreply() or readpattern() that the read-in text does
  334.  * not return FALSE.
  335.  */
  336.  
  337. writmacro(c,n)
  338. register int c,n;
  339. {
  340.  
  341.         char funam[FLEN];
  342.         register int f;
  343.  
  344.         if (n != 1)
  345.                 f = TRUE;
  346.         else
  347.                 f = FALSE;
  348.         if(getfname((short)c,funam)!=FALSE)
  349.                 fprintf(bmacrp,"                if(!%s(%d,%d))\n",funam,f,n);
  350.         else
  351.                 fprintf(bmacrp,"                if(!linsert(%d,'%c'))\n",n,c);
  352.         fputs("                        return(0);\n",bmacrp);
  353.         return(TRUE);   /* bad keycode, but we want it anyway */
  354. }
  355.  
  356. /* given a keycode value, return TRUE
  357.  * and get the function's name into `name'.
  358.  */
  359. getfname(kcode,name)
  360. register short kcode;
  361. char name[];
  362. {
  363.         register KEYTAB *ktp;
  364.  
  365.         ktp = &keytab[0];       /* the function to find */
  366.         /* look through to find keytab assoc with "code" */
  367.         while (ktp < &keytab[NKEYTAB]) {
  368.                 if (ktp->k_code == kcode)
  369.                         {
  370.                         strcpy(name,ktp->k_mfunc);
  371.                         return(TRUE);
  372.                         }
  373.                 ++ktp;
  374.         }
  375.         return(FALSE);  /* not found */
  376. }
  377.