/* EXTMAC.C support program for uemail.ttp. Reads macro files created * in uemail format and creates C source prototypes. */ #include #define NFILEN 80 /* # of bytes, file name */ #define NBUFN 16 /* # of bytes, buffer name */ #define NLINE 256 /* # of bytes, line */ #define NKBDM 256 /* # of strokes, keyboard macro */ #define NPAT 80 /* # of bytes, pattern */ #define HUGE 1000 /* Huge number */ #define CTRL 0x0100 /* Control flag, or'ed in */ #define META 0x0200 /* Meta flag, or'ed in */ #define CTLX 0x0400 /* ^X flag, or'ed in */ #define SPEC 0x0800 /* Special scancode keys */ #define FLEN 15 short *kbdmop; short kbdm[NKBDM]; FILE *bmacrp, *fopen(); unsigned long _STKSIZ = 32 * 1024; typedef struct KEYTAB { short k_code; char k_mfunc[FLEN]; } KEYTAB; /* * Command table. * This table is *roughly* in ASCII * order, left to right across the characters * of the command. This expains the funny * location of the control-X commands. */ KEYTAB keytab[] = { CTRL|'@', "setmark", CTRL|'A', "gotobol", CTRL|'B', "backchar", CTRL|'C', "shell", CTRL|'D', "forwdel", CTRL|'E', "gotoeol", CTRL|'F', "forwchar", CTRL|'G', "ctrlg", CTRL|'H', "backchar", CTRL|'I', "tab", CTRL|'J', "indent", CTRL|'K', "mdeleln", CTRL|'L', "refresh", CTRL|'M', "newline", CTRL|'N', "forwline", CTRL|'O', "openline", CTRL|'P', "backline", CTRL|'Q', "quote", CTRL|'R', "backsearch", CTRL|'S', "forwsearch", CTRL|'T', "twiddle", CTRL|'V', "forwpage", CTRL|'W', "killregion", CTRL|'Y', "yank", CTRL|'Z', "quickexit", CTRL|'\\', "unkncom", CTRL|'_', "kermit", CTRL|'^', "unkncom", CTLX|CTRL|'A', "unkncom", CTLX|CTRL|'B', "listbuffers", CTLX|CTRL|'C', "quit", CTLX|CTRL|'D', "unkncom", CTLX|CTRL|'E', "commfil", CTLX|CTRL|'F', "filename", CTLX|CTRL|'G', "ctrlg", CTLX|CTRL|'H', "unkncom", CTLX|CTRL|'I', "print", CTLX|CTRL|'J', "unkncom", CTLX|CTRL|'K', "unkncom", CTLX|CTRL|'L', "lowerregion", CTLX|CTRL|'M', "unkncom", CTLX|CTRL|'N', "mvdnwind", CTLX|CTRL|'O', "deblank", CTLX|CTRL|'P', "mvupwind", CTLX|CTRL|'Q', "unkncom", CTLX|CTRL|'R', "fileread", CTLX|CTRL|'S', "filesave", CTLX|CTRL|'T', "showtime", CTLX|CTRL|'U', "upperregion", CTLX|CTRL|'V', "filevisit", CTLX|CTRL|'W', "filewrite", CTLX|CTRL|'X', "swapmark", CTLX|CTRL|'Y', "unkncom", CTLX|CTRL|'Z', "shrinkwind", CTLX|'!', "paginate", CTLX|'#', "setpage", CTLX|'+', "pageforw", CTLX|'-', "pageback", CTLX|'.', "setindcol", CTLX|'(', "ctlxlp", CTLX|')', "ctlxrp", CTLX|'*', "retversion", CTLX|'<', "btopunct", CTLX|'=', "showcpos", CTLX|'>', "ftopunct", CTLX|'0', "unkncom", CTLX|'1', "onlywind", CTLX|'2', "splitwind", CTLX|'3', "unkncom", CTLX|'4', "unkncom", CTLX|'5', "unkncom", CTLX|'6', "unkncom", CTLX|'7', "unkncom", CTLX|'8', "unkncom", CTLX|'9', "unkncom", CTLX|'A', "unkncom", CTLX|'B', "usebuffer", CTLX|'C', "paintbuffer", CTLX|'D', "setpath", CTLX|'E', "ctlxe", CTLX|'F', "setfillcol", CTLX|'H', "unkncom", CTLX|'I', "fileinsert", CTLX|'J', "unkncom", CTLX|'K', "killbuffer", CTLX|'L', "unkncom", CTLX|'M', "setmode", CTLX|'N', "nextwind", CTLX|'O', "prevwind", CTLX|'P', "prevwind", CTLX|'Q', "unkncom", CTLX|'R', "writereg", CTLX|'S', "gospell", CTLX|'T', "unkncom", CTLX|'U', "unkncom", CTLX|'V', "unkncom", CTLX|'W', "wc", CTLX|'Y', "unkncom", CTLX|'Z', "enlargewind", CTLX|'\\', "grtw", CTLX|'`', "getmacro", CTLX|'~', "shell", CTLX|SPEC|'p', "swapmark", META|CTRL|'B', "backword", META|CTRL|'C', "mcenter", META|CTRL|'F', "forwword", META|CTRL|'G', "ctrlg", META|CTRL|'H', "backword", META|CTRL|'I', "kill", META|CTRL|'K', "mdelwln", META|CTRL|'M', "unkncom", META|CTRL|'N', "enumerate", META|CTRL|'O', "clowsp", META|CTRL|'P', "tglcase", META|CTRL|'R', "mrflush", META|CTRL|'S', "forwisearch", META|CTRL|'T', "backisearch", META|'!', "reposition", META|'.', "gotoeob", META|',', "gotobob", META|'>', "gotoeob", META|'<', "gotobob", META|' ', "setmark", META|'@', "rettpa", META|'A', "backsent", META|'B', "backword", META|'C', "capword", META|'D', "delfword", META|'E', "forwsent", META|'F', "forwword", META|'G', "goline", META|'H', "markpar", META|'I', "unkncom", META|'J', "mindnl", META|'K', "killsent", META|'L', "lowerword", META|'M', "sglmode", META|'N', "goteop", META|'O', "mdropln", META|'P', "gotbop", META|'Q', "fillpar", META|'R', "replace", META|'S', "unkncom", META|'T', "twaddle", META|'U', "upperword", META|'V', "backpage", META|'W', "copyregion", META|'X', "mdoncom", META|'Y', "unkncom", META|'Z', "unkncom", META|'\\', "mdelind", META|'~', "clearflag", META|0x7F, "delbword", SPEC|'H', "backline", SPEC|'P', "forwline", SPEC|'K', "backchar", SPEC|'M', "forwchar", SPEC|'b', "kermit", SPEC|'a', "yank", SPEC|'R', "openline", SPEC|'S', "backdel", SPEC|'G', "refresh", SPEC|'q', "forwdel", SPEC|'r', "indent", SPEC|'c', "backword", SPEC|'d', "forwword", SPEC|'e', "grtw", SPEC|'f', "retversion", SPEC|'g', "gotobol", SPEC|'h', "gotoeol", SPEC|'i', "unkncom", SPEC|'J', "pageback", SPEC|'N', "pageforw", SPEC|'j', "backsent", SPEC|'k', "forwsent", SPEC|'l', "unkncom", SPEC|'m', "gotbop", SPEC|'n', "goteop", SPEC|'o', "unkncom", SPEC|'D', "quickexit", SPEC|'C', "filesave", SPEC|'B', "filewrite", SPEC|'A', "filevisit", SPEC|'@', "fileread", SPEC|'?', "fileinsert", SPEC|'>', "writereg", SPEC|'=', "filename", SPEC|'<', "listbuffers", SPEC|';', "setmark", 0x60, "putmacro", 0x7F, "backdel" }; #define NKEYTAB (sizeof(keytab)/sizeof(keytab[0])) main(argc,argv) int argc; char *argv[]; { register int err; if (argc < 3) { fprintf(stderr,"usage: %s infile outfile\n",argv[0]); exit(-1); } if ((bmacrp=fopen(argv[2], "w"))==NULL) { err = perror("open failure"); exit(err); } err=loadmac(argv[1]); fclose(bmacrp); exit(err); } /* LOADMAC read a uemail macro file and produce a prototype C source file. */ loadmac(macfile) char macfile[]; { register int d,i; register short s; register FILE *mp; extern void extrct_macro(); if ((mp=fopen(macfile,"r"))==NULL) { fprintf(stderr,"Cannot open %s",macfile); return(-1); } if ((s=getw(mp))!=(CTLX|'(')) { fprintf(stderr,"Macro file format error: %s",macfile); fclose(mp); return(-1); } while((d=fgetc(mp))!=EOF) { i=0; while ((s=getw(mp))!=(CTLX|')')) { if (feof(mp)) { fprintf(stderr,"Read error on: %s",macfile); fclose(mp); return(-11); /* read error */ } kbdm[i++]=s; } kbdm[i] = CTLX|')'; extrct_macro(d); } fclose(mp); return(NULL); } /* Look at the current keyboard macro. Send each bitcode to writmacro() * so it can look up the function calling sequence in the KEYTAB. These * functions allow you to record keyboard macros in C source code for * later compilation. */ void extrct_macro(d) { register int c; register int an; register int s; fprintf(bmacrp,"%c(f,n)\n",d); fputs("int f,n;\n",bmacrp); /* default uEmail parameters */ fputs("{\n",bmacrp); /* begin definition */ fputs(" if (n < 0)\n",bmacrp); fputs(" return(0);\n",bmacrp); fputs(" while(n--)\n",bmacrp); fputs(" {\n",bmacrp); kbdmop = &kbdm[0]; do { an = 1; if ((c = *kbdmop++) == (CTRL|'U')) { an = *kbdmop++; c = *kbdmop++; } s = TRUE; } while (c!=(CTLX|')') && (s=writmacro(c,an))==TRUE); kbdmop = NULL; fputs(" }\n",bmacrp); /* end the while statement */ fputs(" return(1);\n",bmacrp); fputs("}\n\n",bmacrp); return; } /* Look up function name based on bitcode found in extrct_macro(). No errors * because a running macro that uses one of the "get-string" routines would * return an error and extrct_macro() would abort. Watch when using with * functions that use mlreply() or readpattern() that the read-in text does * not return FALSE. */ writmacro(c,n) register int c,n; { char funam[FLEN]; register int f; if (n != 1) f = TRUE; else f = FALSE; if(getfname((short)c,funam)!=FALSE) fprintf(bmacrp," if(!%s(%d,%d))\n",funam,f,n); else fprintf(bmacrp," if(!linsert(%d,'%c'))\n",n,c); fputs(" return(0);\n",bmacrp); return(TRUE); /* bad keycode, but we want it anyway */ } /* given a keycode value, return TRUE * and get the function's name into `name'. */ getfname(kcode,name) register short kcode; char name[]; { register KEYTAB *ktp; ktp = &keytab[0]; /* the function to find */ /* look through to find keytab assoc with "code" */ while (ktp < &keytab[NKEYTAB]) { if (ktp->k_code == kcode) { strcpy(name,ktp->k_mfunc); return(TRUE); } ++ktp; } return(FALSE); /* not found */ }