📄 ellec.c
字号:
*cp++ = c; continue; } else { if(islword(c)) goto ok; unlrch(c); break; } out: lp = getln(); lp->ltyp = LT_STR; lp->lval.lvs = malloc(i+1); *cp = 0; strcpy(lp->lval.lvs, cbuf); return(lp);}islword(c){ return((040 < c && c < 0177 && c != '(' && c !=')' && c != ';' && c != '"' && c != '\\') ? 1 : 0);}struct lnode *keybind(), *keyallun(), *menuitem(), *efun(), *undefall();struct lfun { char *lfname; /* Name of list function */ struct lnode * (*lfrtn)(); /* Function address */} lfntab[] = { "keybind", keybind, "efun", efun, "menuitem", menuitem, "keyallunbind", keyallun,/* "keyunbind", keyunbind, */ /* Not yet */ "undefall", undefall,/* "undef", undef, */ /* Not yet */ 0, 0};struct lnode *eval(lp)register struct lnode *lp;{ register struct lnode *flp; register struct lfun *lfent; if(lp->ltyp != LT_LIST) return(lp); if((flp = lp->lval.lvl) == NIL) return(NIL); if(flp->ltyp != LT_STR) return(NIL); /* Look up list function and invoke it */ for(lfent = lfntab; lfent->lfname; lfent++) if(strueq(flp->lval.lvs, lfent->lfname)) return((*(lfent->lfrtn))(flp->lnxt)); lerr("unknown op: (%s)", flp->lval.lvs); return(NIL);}/* UNDEFALL - (undefall)** Undefines all functions. Typically used to clear out** predefined functions prior to compiling a set of new efuns.*/struct lnode *undefall(lp)register struct lnode *lp;{ register int i; efxmax = 0; /* Say nothing in function def table! */ for(i = 0; i < EFUNMAX; ++i) { efuntab[i].ef_idx = 0; efuntab[i].ef_name = 0; efuntab[i].ef_adr = 0; efuntab[i].ef_mod = 0; } return(LTRUE);}/* EFUN - (efun <index> <functionname> <address> <module>)** Checks out the args and if no problems, stores the function** definition in efuntab.*/struct lnode *efun(lp)register struct lnode *lp;{ struct lnode *nlp; register int c, i; register struct fun *fnp; char *fname, *faddr, *fmod; int fni, num; if(listcnt(lp) < 4) { lerr("efun - not enough args"); return(NIL); } /* First thing should be function index */ switch(lp->ltyp) { case LT_VAL: fni = lp->lval.lvi; break; case LT_STR: if(numcvt(lp->lval.lvs, &num)) { fni = num; break; } default: lerr("efun - non-value function index"); return(NIL); } /* Next thing should be function name */ lp = lp->lnxt; if(lp->ltyp != LT_STR) /* Function name not a string */ { lerr("efun - non-string function name"); return(NIL); } fname = lp->lval.lvs; /* Next thing should be function addr */ lp = lp->lnxt; if(lp->ltyp != LT_STR) /* Function addr not a string */ { lerr("efun - non-string function addr"); return(NIL); } faddr = lp->lval.lvs; /* Next thing should be function module */ lp = lp->lnxt; if(lp->ltyp != LT_STR) /* Function module not a string */ { lerr("efun - non-string function module"); return(NIL); } fmod = lp->lval.lvs; /* Now see if already exists or anything */ if(fni <= 0 || fni > EFUNMAX) { lerr("efun - bad function index %d", fni); return(NIL); } fnp = &efuntab[fni]; if(fnp->ef_idx != 0) { if (fnp->ef_idx == fni && strueq(fnp->ef_name, fname) && strueq(fnp->ef_adr, faddr) && (fnp->ef_mod == NULL || strueq(fnp->ef_mod, fmod))) goto win; /* Benign redefinition */lerr("efun - redefining function (%d \"%s\" %s %s)", fnp->ef_idx, fnp->ef_name, fnp->ef_adr, (fnp->ef_mod ? fnp->ef_mod : "unknown-module")); } for(i = 0; i < EFUNMAX; ++i) { if(efuntab[i].ef_idx == 0) continue; if(ustrcmp(efuntab[i].ef_adr,faddr) > 0 || ustrcmp(efuntab[i].ef_name, fname) > 0) { if(i == fni) continue; lerr("efun - name or address dup! \"%s\"", fname); return(NIL); } } /* No problems, store the function def in efuntab! */win: fnp->ef_idx = fni; fnp->ef_mod = fmod; fnp->ef_adr = faddr; fnp->ef_name = fname; if(efxmax < fni) efxmax = fni; return(LTRUE);}/* KEYBIND - (keybind <charspec> <functionname>) */struct lnode *keybind(lp)register struct lnode *lp;{ struct lnode *nlp; register int c, i; int fni; if(lp == NIL || (nlp = lp->lnxt)== NIL) return(NIL); switch(lp->ltyp) { case LT_VAL: c = lp->lval.lvi; break; case LT_LIST: return(NIL); case LT_STR: c = repchar(lp->lval.lvs); break; } if(c == -1) return(NIL); /* No such command char name */ lp = nlp; if(lp->ltyp != LT_STR) /* Function name not a string */ { lerr("(keybind) non-string function name"); return(NIL); } fni = findfun(lp->lval.lvs); if(fni == 0) /* No such function name */ { lerr("(keybind) no such function - \"%s\"", lp->lval.lvs); return(NIL); } if(c & CB_EXT) { c &= ~CB_EXT; /* Check for redefinition */ for(i = 0; i < extcnt; i += 2) if(c == (extptr[i]&0377)) /* Already there? */ { if((extptr[i+1]&0377) != fni) /* Yes, check fn */ lerr("(keybind) redefining X-%s as %d=\"%s\"", charep(c), fni, lp->lval.lvs); break; } if(i >= extcnt) /* Didn't find? */ { if(extcnt >= extsiz) { lerr("(keybind) too many X- commands"); return(NIL); /* Too many EXT cmds */ } i = extcnt; /* Increase size of table */ extcnt += 2; } /* Now store new binding */ extptr[i] = c; extptr[i+1] = fni; } else if(c&CB_META) { c &= ~CB_META; /* Check for redefinition */ for(i = 0; i < mtacnt; i += 2) if(c == (mtaptr[i]&0377)) /* Already there? */ { if((mtaptr[i+1]&0377) != fni) /* Yes, check fn */ lerr("(keybind) redefining M-%s as %d=\"%s\"", charep(c), fni, lp->lval.lvs); break; } if(i >= mtacnt) /* Didn't find? */ { if(mtacnt >= mtasiz) { lerr("(keybind) too many M- commands"); return(NIL); /* Too many META cmds */ } i = mtacnt; /* Increase size of table */ mtacnt += 2; } /* Now store new binding */ mtaptr[i] = c; mtaptr[i+1] = fni; } else { i = c & 0177; if (chrptr[i] && (chrptr[i]&0377) != fni) lerr("(keybind) redefining %s as %d=\"%s\"", charep(c), fni, lp->lval.lvs); chrptr[i] = fni; } return(LTRUE);}/* KEYALLUNBIND - (keyallunbind) */struct lnode *keyallun(){ register int i; register char *cp;/* fprintf(stderr, "ellec: clearing all key definitions\n"); */ for(i = 0, cp = chrptr; i < chrcnt; i++) *cp++ = 0; mtacnt = extcnt = mnucnt = 0; return(LTRUE);}/* MENUITEM - (menuitem <functionname>) */struct lnode *menuitem(lp)register struct lnode *lp;{ register int i, fni; if(lp == NIL) return(NIL); switch(lp->ltyp) { case LT_VAL: fni = lp->lval.lvi; break; case LT_LIST: return(NIL); case LT_STR: fni = findfun(lp->lval.lvs); break; } if(fni == 0) return(NIL); /* Bad val or no such function name */ for(i = 0; i < mnusiz; i++) if(fni == (mnuptr[i]&0377) || mnuptr[i] == 0) { mnuptr[i] = fni; mnucnt++; return(LTRUE); } return(NIL); /* Too many menu items */}repchar(str)register char *str;{ register int c; register int i, l; if (str == 0) return (-1); i = 0; l = strlen(str); c = (*str++)&0377; if(l == 0) return(-1); if(l == 1) return(c); /* One-char representation */ if(c == '^') if(l == 2) return((~0140) & mupcase(*str)); else return(-1); c = mupcase(c); if (*str == '-') { if(*++str == 0) return(-1); switch(c) { case 'X': return(CB_EXT | mupcase(repchar(str))); case 'M': return(CB_META | mupcase(repchar(str))); case 'C': return((~0140) & repchar(str)); } } if(c == 'S' && upcase(*str) == 'P' && l == 2) return(' '); if(c == 'D' && upcase(*str++) == 'E' && upcase(*str++) == 'L' && *str == 0) return(0177); return(-1); }struct lnode *getln(){ return((struct lnode *)calloc(1,sizeof(struct lnode)));}numcvt(str, anum)char *str;int *anum;{ register char *cp; register int i, c, sign; if((cp = str) == 0) return 0; i = sign = 0; if(*cp == '-') cp++, sign++; while(c = *cp++) if(!isdigit(c)) return(0); else i = 10*i + (c - '0'); *anum = sign ? -i : i; return(1);}listcnt(lp)register struct lnode *lp;{ register int i; i = 0; while(lp) ++i, lp = lp->lnxt; return(i);}/* FUNNAME - Given function index, return function name.** Always wins; returns "unknown" for bad indices.*/char *funname(i)register int i;{ register char *cp = NULL; if(0 < i && i <= efxmax && (cp = efuntab[i].ef_name)) return cp; return("unknown function");}findfun(name)register char *name;{ register int i; if((i = efxmax) > 0) { do { if(strueq(name, efuntab[i].ef_name)) return(i); } while(--i); return(0); } return(0);}/* FUNCNT - Scan all key bindings, counting each occurrence of every** function index.** This is used to determine which functions are actually used.*/funcnt(arr)register int *arr; /* Pointer to array of EFUNMAX ints */{ register int i; for(i = 0; i < EFUNMAX; ++i) /* Clear the array */ arr[i] = 0; for(i = 0; i < chrcnt; ++i) /* Scan bindings */ arr[chrptr[i]&0377]++; for(i = 0; i < mtacnt; i += 2) arr[mtaptr[i+1]&0377]++; for(i = 0; i < extcnt; i += 2) arr[extptr[i+1]&0377]++;}scpy(from,to,cnt)register char *from,*to;register int cnt;{ if(cnt > 0) do { *to++ = *from++; } while(--cnt);}/* STRIPSP - strip spaces from string. Returns ptr to start. */char *stripsp(cp)register char *cp;{ register char *ep, *lastp; while(*cp == ' ') ++cp; if (*cp) { ep = cp + strlen(cp); /* Point to null ending the str */ while (*--ep == ' '); *++ep = 0; /* Tie it off */ } return cp;}warn(str,a,b,c,d,e,f,g,h,i)char *str;{ fprintf(stderr, "ellec: "); fprintf(stderr, str, a,b,c,d,e,f,g,h,i); fprintf(stderr, "\n");}lerr(str,a,b,c,d,e,f,g,h,i)char *str;{ warn(str, a,b,c,d,e,f,g,h,i); *linecp = 0; /* Tie off current line buffer */ fprintf(stderr, " Line %d: %s\n", lineno, linebuf);}fatal(str,a,b,c,d,e,f,g,h,i)char *str;{ warn(str, a,b,c,d,e,f,g,h,i); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -