📄 ellec.c
字号:
/* ELLEC - Copyright 1983 by Ken Harrenstien, SRI International * This software is quasi-public; it may be used freely with * like software, but may NOT be sold or made part of licensed * products without permission of the author. *//* ELLEC - ELLE Compiler * Invoked with no arguments, acts as general ELLE compiler filter; * reads ASCII profile input, and outputs a binary profile. * Otherwise: * -Profile Compiles user's profile. * HOME/.ellepro.e -> HOME/.ellepro.bN (N = fmt version #) * NOTE: on V6, "HOME/" is left out. * -Pconf Outputs defprf.c for ELLE (accepts std in) (old -E) * -Fconf Outputs eefdef.h for ELLE (accepts std in) * -FXconf Outputs eefidx.h for ELLE (accepts std in) * -CMconf Outputs config makefile for ELLE ( " ) * -CSconf arg Outputs config file using "arg" - for V6 config.v6 file. * -Pdump Outputs defprf.e user profile (old -P) * -Fdump Outputs deffun.e */#if 0The ASCII profile file associates command chars with functions.It is simply a series of lisp-like expressions of the form (keybind <char spec> <fun spec>) e.g. (keybind "C-Y" "Yank Pop")Command char specification: Allowed prefixes: <ch> The char itself C- Controlify (zap bits 140) ^<ch> Ditto M- Meta (add bit 200) - case ignored X- Extended (add bit) - case ignored To quote a char or char spec, use quoted-string syntax.Function name specification: Function names are specified by quoted strings containing the entire long-form ASCII function name. Matching is done case-independently.#endif /*COMMENT*/#include "eesite.h" /* Site specific stuff if any */#include <stdio.h>#include <ctype.h>#include <unistd.h>#include "eeprof.h" /* Profile structure definition */#define EFUNMAX 400 /* Maximum # (+1) of functions that can be defined */#define KBTSIZ (128*2) /* Initial size of key binding tables *//* EFUN Function definition table.** Functions that were copied from the pre-defined table will** have a value of NULL in ef_mod.*/struct fun { int ef_idx; /* Function index (same as index of entry) */ char *ef_name; /* Function name */ char *ef_adr; /* C routine name in ELLE */ char *ef_mod; /* Source module that C routine lives in */};struct fun efuntab[EFUNMAX];int efxmax = 0; /* Largest function idx used */int format_ver = PROF_VER; /* Current version # of binary profile fmt *//* Keybind mapping tables. There are four separate tables:** Simple character. Always 128 single-byte items, indexed by the simple** command char. Each item is the corresponding function index.** Meta char. Variable number of 2-byte items; first is a command char** and second is its function index.** Extended char. Same format as Meta char.** Menu item (SUN only). Variable number of single-byte items, each** a function index.***/char *chrptr; /* Pointer to simple-char table */int chrsiz = 128; /* Current size of table */int chrcnt = 0; /* # bytes actually used */char *mtaptr; /* Pointer to meta-char table */int mtasiz = KBTSIZ; /* Current size (twice the # of items) */int mtacnt = 0; /* # bytes actually used */char *extptr; /* Pointer to ext-char table */int extsiz = KBTSIZ; /* Current size (twice the # of items) */int extcnt = 0; /* # bytes actually used */char *mnuptr; /* Pointer to menu-item table (SUN only) */int mnusiz = KBTSIZ; /* Current size */int mnucnt = 0; /* # bytes actually used */#define CB_EXT 0400 /* "X-" prefix on command char */#define CB_META 0200 /* "M-" prefix on command char *//* Set up the pre-defined data areas. This includes the** predefined function table plus the default profile (keyboard mappings).** Note this only contains entries for ef_name and ef_adr.*/struct fun pdfuntab[] = { /* Pre-Defined Function table */#define EFUN(rtn,rtnstr,name) 0, name, rtnstr, 0,#define EFUNHOLE 0, 0, 0, 0,#include "eefdef.h"};int npdfuns = sizeof(pdfuntab)/sizeof(struct fun); /* # of entries */#include "defprf.c" /* Insert default profile mapping */ /* This defines charmap, metamap, and extmap. *//* Stuff for feeble-minded list processor */#define NIL ((struct lnode *)0)#define LTRUE (<ruenode)#define LT_VAL 0#define LT_STR 1#define LT_LIST 2#define LT_ATOM 3 /* Should use this later instead of LT_STR */struct lnode { struct lnode *lnxt; int ltyp; union { int lvi; char *lvs; struct lnode *lvl; } lval;};struct lnode ltruenode; /* Constant TRUE */_PROTOTYPE(int main , (int argc , char **argv ));_PROTOTYPE(int doargs , (int argc , char **argv ));_PROTOTYPE(char **findkey , (char *cp , char ***aretp , char **tabp , int tabsiz , int elsize ));_PROTOTYPE(int nstrcmp , (char *s1 , char *s2 ));_PROTOTYPE(int ustrcmp , (char *s1 , char *s2 ));_PROTOTYPE(int strueq , (char *s1 , char *s2 ));_PROTOTYPE(int do_opcod , (void));_PROTOTYPE(int do_opasc , (void));_PROTOTYPE(int outkbind , (int c , int fx ));_PROTOTYPE(int do_obprof , (void));_PROTOTYPE(int mupcase , (int ch ));_PROTOTYPE(int upcase , (int ch ));_PROTOTYPE(char *qstr , (char *str ));_PROTOTYPE(char *charep , (int c ));_PROTOTYPE(int do_ocnf , (char *str ));_PROTOTYPE(int do_ofcod , (void));_PROTOTYPE(int do_ofasc , (void));_PROTOTYPE(int do_ofxcod , (void));_PROTOTYPE(int compile_stdin , (void));_PROTOTYPE(int lrch , (void));_PROTOTYPE(struct lnode *lread , (void));_PROTOTYPE(int wspfls , (void));_PROTOTYPE(struct lnode *lrstr , (int flg ));_PROTOTYPE(int islword , (int c ));_PROTOTYPE(struct lnode *eval , (struct lnode *lp ));_PROTOTYPE(struct lnode *undefall , (struct lnode *lp ));_PROTOTYPE(struct lnode *efun , (struct lnode *lp ));_PROTOTYPE(struct lnode *keybind , (struct lnode *lp ));_PROTOTYPE(struct lnode *keyallun , (void));_PROTOTYPE(struct lnode *menuitem , (struct lnode *lp ));_PROTOTYPE(int repchar , (char *str ));_PROTOTYPE(struct lnode *getln , (void));_PROTOTYPE(int numcvt , (char *str , int *anum ));_PROTOTYPE(int listcnt , (struct lnode *lp ));_PROTOTYPE(char *funname , (int i ));_PROTOTYPE(int findfun , (char *name ));_PROTOTYPE(int funcnt , (int *arr ));_PROTOTYPE(int scpy , (char *from , char *to , int cnt ));_PROTOTYPE(char *stripsp , (char *cp ));int warn();int lerr();int fatal();/* ELLEC argument stuff */char *argfile;char *outfile;int swfilter; /* If no args */int swprof; /* -P */int swelle; /* -E */int uproflg; /* Do compilation of user's profile */int swpcnf; /* Output defprf.c (C initialization of profile) */int swfcnf; /* Output eefdef.h */int swfxcnf; /* Output eefidx.h */int swcmcnf; /* Output config makefile (makecf.fun) */char *swcscnf; /* Output config specially (for V6) */int swallc; /* Do all of config stuff */int swfdmp; /* Output deffun.e */int nfiles; /* # file specs seen */main(argc,argv)int argc;char **argv;{ register int i; register char *cp; char temp[300]; /* Initialize LTRUE ** (cannot portably initialize a union at compile time) */ ltruenode.ltyp = LT_VAL; /* Set type (other fields zero) */ /* Process switches */ if(argc <= 1) swfilter++; /* If no args, assume filter */ else doargs(argc,argv); /* Initialize function definitions and key bindings from predefs */ chrptr = malloc(chrsiz); mtaptr = malloc(mtasiz); extptr = malloc(extsiz); mnuptr = malloc(mnusiz); if (!chrptr || !mtaptr || !extptr || !mnuptr) fatal("cannot init, no memory"); scpy(charmap, chrptr, (chrcnt = sizeof(charmap))); scpy(metamap, mtaptr, (mtacnt = sizeof(metamap))); scpy( extmap, extptr, (extcnt = sizeof(extmap))); if(def_prof.menuvec) scpy(def_prof.menuvec, mnuptr, (mnucnt = def_prof.menuvcnt)); for(i = 0; i < npdfuns; ++i) /* Initialize function defs */ if(pdfuntab[i].ef_name) { efuntab[i].ef_idx = i; efuntab[i].ef_name = pdfuntab[i].ef_name; efuntab[i].ef_adr = stripsp(pdfuntab[i].ef_adr); if(efxmax < i) efxmax = i; } /* Routines expect input from stdin and output their results * to stdout. */ if(argfile) if(freopen(argfile,"r",stdin) == NULL) fatal("cannot open input file \"%s\"",argfile); if(outfile) if(freopen(outfile,"w",stdout) == NULL) fatal("cannot open output file \"%s\"",outfile); /* Check for general compilation */ if(swfilter) { /* Not really implemented yet */ fatal("bad usage, see doc"); } /* Do profile hacking of some kind */ if(swprof || swelle) { if (compile_stdin()) /* Compile input profile */ { if(swprof) do_opasc(); /* Output ASCII profile (.e) */ else if(swelle) do_opcod(); /* Output bin profile (.b1) */ } exit(0); } /* Check for variousness */ if(swpcnf) { if(compile_stdin()) /* Compile input */ do_opcod(); /* Output the C initialization code */ exit(0); } if(swfxcnf) { if(compile_stdin()) /* Compile input */ do_ofxcod(); /* Output the eefidx.h code */ exit(0); } if(swfcnf) { if(compile_stdin()) /* Compile input */ do_ofcod(); /* Output the eefdef.h code */ exit(0); } if(swcmcnf || swcscnf) { if(compile_stdin()) /* Compile input */ do_ocnf(swcscnf); /* Output the makecf.fun code */ exit(0); } if(swfdmp) { if(compile_stdin()) /* Compile input */ do_ofasc(); /* Output the deffun.e code */ exit(0); } /* Hack user's profile */ if(!uproflg) exit(0); if(!argfile) { temp[0] = 0;#if !V6 if (cp = getenv("HOME")) strcat(temp, cp);#if !TOPS20 strcat(temp,"/");#endif /*-TOPS20*/#endif /*-V6*/ strcat(temp, EVPROFTEXTFILE); if(freopen(temp,"r",stdin) == NULL) fatal("cannot open profile \"%s\"",temp); } if(!outfile) { temp[0] = 0;#if !V6 if (cp = getenv("HOME")) strcat(temp, cp);#if !TOPS20 strcat(temp,"/");#endif /*-TOPS20*/#endif /*-V6*/ strcat(temp, EVPROFBINFILE); if(freopen(temp,"wb",stdout) == NULL /* Try binary 1st */ && freopen(temp,"w",stdout) == NULL) fatal("cannot open output profile \"%s\"",temp); } /* Hack user's profile */ if(compile_stdin()) /* Compile input profile */ do_obprof(); /* Output the binary */}#define SW_FLG 0#define SW_VAR 1#define SW_STR 2struct swarg { char *sw_name; long sw_type; int *sw_avar; char **sw_astr;} swtab[] = { "P", SW_FLG, &swprof, 0, /* Old stuff */ "E", SW_FLG, &swelle, 0, "Profile", SW_FLG, &uproflg, 0, "Pconf", SW_FLG, &swpcnf, 0, "Fconf", SW_FLG, &swfcnf, 0, "FXconf", SW_FLG, &swfxcnf, 0, "CMconf", SW_FLG, &swcmcnf, 0, "CSconf", SW_STR, 0, &swcscnf, "Allconf", SW_FLG, &swallc, 0, "Pdump", SW_FLG, &swprof, 0, "Fdump", SW_FLG, &swfdmp, 0};doargs(argc,argv)int argc;char **argv;{ register int cnt, c; register char **av; register int i; register struct swarg *swp; struct swarg *swp2; int swerrs = 0; av = argv; cnt = argc; nfiles = 0; while(--cnt > 0) { ++av; if(*av[0] != '-') /* If not switch, */ { /* assume it's an input filename */ nfiles++; continue; } av[0]++; /* Try to look up switch in table */ swp = (struct swarg *)findkey(av[0], &swp2, swtab, (sizeof(swtab))/(sizeof(struct swarg)), (sizeof(struct swarg))/(sizeof(char *))); if(swp2) { fprintf(stderr,"ellec: ambiguous switch: -%s = %s or %s\n", av[0], swp->sw_name, swp2->sw_name); goto swdone; } if(swp) switch(swp->sw_type) { case SW_FLG: *(swp->sw_avar) = 1; goto swdone; case SW_VAR: *(swp->sw_avar) = 1; if(cnt <= 1) goto swdone; if(isdigit(*av[1])) { *(swp->sw_avar) = atoi(av[1]); --cnt; goto swargdone; } goto swdone; case SW_STR: if(cnt <= 1) goto swdone; *(swp->sw_astr) = av[1]; goto swargdone; default: fprintf(stderr,"ellec: bad switch type: %s\n", av[0]); swerrs++; } stop: fprintf(stderr,"ellec: bad switch: %s\n",*av); swerrs++; goto swdone; swargdone: av[0] = 0; av++; swdone: av[0] = 0; } if(swerrs) exit(1); /* Stop if any problems */}char **findkey(cp, aretp, tabp, tabsiz, elsize)register char *cp;char ***aretp;register char **tabp;int tabsiz, elsize;{ register char **mp1, **mp2; register int i, res; *aretp = mp1 = mp2 = 0; for(i = 0; i < tabsiz; ++i, tabp += elsize) { if(res = ustrcmp(cp,*tabp)) { if(res > 0) return(tabp); if(!mp1) mp1 = tabp; else mp2 = tabp; } } if(mp2) *aretp = mp2; /* Ambiguous */ return(mp1);}/* NSTRCMP - New string compare. * Returns: * 2 if str2 > str1 (mismatch) * 1 if str2 counted out (str1 > str2) * 0 if full match * -1 if str1 counted out (str1 < str2) * -2 if str1 < str2 (mismatch) */nstrcmp(s1,s2)register char *s1, *s2;{ register int c, d; while(c = *s1++) { if(c != *s2) { if((d = upcase(c) - upcase(*s2)) != 0) return(*s2==0 ? 1 : (d > 0 ? 2 : -2)); } ++s2; } return(*s2 ? -1 : 0);}/* USTRCMP - uppercase string compare. * Returns 0 if mismatch,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -