This is zle_misc.c in view mode; [Download] [Up]
/* * $Id: zle_misc.c,v 2.30 1996/10/15 20:16:35 hzoli Exp $ * * zle_misc.c - miscellaneous editor routines * * This file is part of zsh, the Z shell. * * Copyright (c) 1992-1996 Paul Falstad * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and to distribute modified versions of this software for any * purpose, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * In no event shall Paul Falstad or the Zsh Development Group be liable * to any party for direct, indirect, special, incidental, or consequential * damages arising out of the use of this software and its documentation, * even if Paul Falstad and the Zsh Development Group have been advised of * the possibility of such damage. * * Paul Falstad and the Zsh Development Group specifically disclaim any * warranties, including, but not limited to, the implied warranties of * merchantability and fitness for a particular purpose. The software * provided hereunder is on an "as is" basis, and Paul Falstad and the * Zsh Development Group have no obligation to provide maintenance, * support, updates, enhancements, or modifications. * */ #define ZLE #include "zsh.h" /**/ void selfinsert(void) { int ncs = cs + zmult; if (complexpect && isset(AUTOPARAMKEYS)) { if (complexpect == 2 && /*{*/ c == '}') { if (!menucmp || line[cs-1] == '/' || addedsuffix) { int i = 0; spaceinline(1); do { line[cs-i] = line[cs-i-1]; } while (++i < addedsuffix); line[cs-i] = c; cs++; return; } } else if (c == ':' || c == '[' || (complexpect == 2 && (c == '#' || c == '%' || c == '-' || c == '?' || c == '+' || c == '='))) { if (addedsuffix > 1) backdel(addedsuffix - 1); if (!menucmp || line[cs-1] == '/' || addedsuffix) { line[cs - 1] = c; return; } } } if (zmult < 0) { zmult = -zmult; ncs = cs; } if (insmode || ll == cs) spaceinline(zmult); else if (zmult + cs > ll) spaceinline(ll - (zmult + cs)); while (zmult--) line[cs++] = c; cs = ncs; } /**/ void selfinsertunmeta(void) { c &= 0x7f; if (c == '\r') c = '\n'; selfinsert(); } /**/ void deletechar(void) { if (zmult < 0) { zmult = -zmult; backwarddeletechar(); return; } if (cs + zmult <= ll) { cs += zmult; backdel(zmult); } else feep(); } /**/ void backwarddeletechar(void) { if (zmult < 0) { zmult = -zmult; deletechar(); return; } if (zmult > cs) zmult = cs; backdel(zmult); } /**/ void killwholeline(void) { int i, fg; if (zmult < 0) return; while (zmult--) { if ((fg = (cs && cs == ll))) cs--; while (cs && line[cs - 1] != '\n') cs--; for (i = cs; i != ll && line[i] != '\n'; i++); forekill(i - cs + (i != ll), fg); } } /**/ void killbuffer(void) { cs = 0; forekill(ll, 0); } /**/ void backwardkillline(void) { int i = 0; if (zmult < 0) { zmult = -zmult; killline(); return; } while (zmult--) { if (cs && line[cs - 1] == '\n') cs--, i++; else while (cs && line[cs - 1] != '\n') cs--, i++; } forekill(i, 1); } /**/ void gosmacstransposechars(void) { int cc; if (cs < 2 || line[cs - 1] == '\n' || line[cs - 2] == '\n') { if (cs == ll || line[cs] == '\n' || ((cs + 1 == ll || line[cs + 1] == '\n') && (!cs || line[cs - 1] == '\n'))) { feep(); return; } cs += (cs == 0 || line[cs - 1] == '\n') ? 2 : 1; } cc = line[cs - 2]; line[cs - 2] = line[cs - 1]; line[cs - 1] = cc; } /**/ void transposechars(void) { int cc, ct; int neg = zmult < 0; if (neg) zmult = -zmult; while (zmult--) { if (!(ct = cs) || line[cs - 1] == '\n') { if (ll == cs || line[cs] == '\n') { feep(); return; } if (!neg) cs++; ct++; } if (neg) { if (cs && line[cs - 1] != '\n') { cs--; if (ct > 1 && line[ct - 2] != '\n') ct--; } } else { if (cs != ll && line[cs] != '\n') cs++; } if (ct == ll || line[ct] == '\n') ct--; if (ct < 1 || line[ct - 1] == '\n') { feep(); return; } cc = line[ct - 1]; line[ct - 1] = line[ct]; line[ct] = cc; } } /**/ void poundinsert(void) { cs = 0; vifirstnonblank(); if (line[cs] != '#') { spaceinline(1); line[cs] = '#'; cs = findeol(); while(cs != ll) { cs++; vifirstnonblank(); spaceinline(1); line[cs] = '#'; cs = findeol(); } } else { foredel(1); cs = findeol(); while(cs != ll) { cs++; vifirstnonblank(); if(line[cs] == '#') foredel(1); cs = findeol(); } } done = 1; } /**/ void acceptline(void) { done = 1; } /**/ void acceptandhold(void) { pushnode(bufstack, metafy((char *)line, ll, META_DUP)); stackcs = cs; done = 1; } /**/ void killline(void) { int i = 0; if (zmult < 0) { zmult = -zmult; backwardkillline(); return; } while (zmult--) { if (line[cs] == '\n') cs++, i++; else while (cs != ll && line[cs] != '\n') cs++, i++; } backkill(i, 0); } /**/ void killregion(void) { if (mark > ll) mark = ll; if (mark > cs) forekill(mark - cs, 0); else backkill(cs - mark, 1); } /**/ void copyregionaskill(void) { if (mark > ll) mark = ll; if (mark > cs) cut(cs, mark - cs, 0); else cut(mark, cs - mark, 1); } static int kct, yankb, yanke; /**/ void yank(void) { Cutbuffer buf = &cutbuf; if (zmult < 0) return; if (gotvibufspec) buf = &vibuf[vibufspec]; if (!buf->buf) { feep(); return; } mark = cs; yankb = cs; while (zmult--) { kct = kringnum; spaceinline(buf->len); memcpy((char *)line + cs, buf->buf, buf->len); cs += buf->len; yanke = cs; } } /**/ void yankpop(void) { int cc; if (!(lastcmd & ZLE_YANK) || !kring[kct].buf) { feep(); return; } cs = yankb; foredel(yanke - yankb); cc = kring[kct].len; spaceinline(cc); memcpy((char *)line + cs, kring[kct].buf, cc); cs += cc; yanke = cs; kct = (kct + KRINGCT - 1) % KRINGCT; } /**/ void overwritemode(void) { insmode ^= 1; } /**/ void undefinedkey(void) { feep(); } /**/ void quotedinsert(void) { #ifndef HAS_TIO struct sgttyb sob; sob = shttyinfo.sgttyb; sob.sg_flags = (sob.sg_flags | RAW) & ~ECHO; ioctl(SHTTY, TIOCSETN, &sob); #endif c = getkey(0); #ifndef HAS_TIO setterm(); #endif if (c < 0) feep(); else selfinsert(); } /**/ void digitargument(void) { int sign = (zmult < 0) ? -1 : 1; if (!(lastcmd & ZLE_DIGIT)) zmult = 0; zmult = zmult * 10 + sign * (c & 0xf); gotmult = 1; } /**/ void negargument(void) { if (lastcmd & (ZLE_NEGARG | ZLE_DIGIT)) feep(); zmult = -1; gotmult = 1; } /**/ void universalargument(void) { if (!(lastcmd & ZLE_ARG)) zmult = 4; else zmult *= 4; gotmult = 1; } /**/ void copyprevword(void) { int len, t0; for (t0 = cs - 1; t0 >= 0; t0--) if (iword(line[t0])) break; for (; t0 >= 0; t0--) if (!iword(line[t0])) break; if (t0) t0++; len = cs - t0; spaceinline(len); memcpy((char *)&line[cs], (char *)&line[t0], len); cs += len; } /**/ void sendbreak(void) { errflag = 1; } /**/ void undo(void) { char *s; struct undoent *ue; ue = undos + undoct; if (!ue->change) { feep(); return; } line[ll] = '\0'; s = zalloc(ue->suff + 1); memcpy(s, (char *)&line[ll - ue->suff], ue->suff); sizeline(ll = ue->pref + ue->suff + ue->len); memcpy((char *)line + ue->pref, ue->change, ue->len); memcpy((char *)line + ue->pref + ue->len, s, ue->suff); zfree(s, ue->suff + 1); ue->change = NULL; undoct = (undoct + UNDOCT - 1) % UNDOCT; cs = ue->cs; } /**/ void quoteregion(void) { char *str; size_t len; if (mark > ll) mark = ll; if (mark < cs) { int tmp = mark; mark = cs; cs = tmp; } str = (char *)hcalloc(len = mark - cs); memcpy(str, (char *)&line[cs], len); foredel(len); str = makequote(str, &len); spaceinline(len); memcpy((char *)&line[cs], str, len); mark = cs; cs += len; } /**/ void quoteline(void) { char *str; size_t len = ll; str = makequote((char *)line, &len); sizeline(len); memcpy(line, str, len); cs = ll = len; } /**/ char * makequote(char *str, size_t *len) { int qtct = 0; char *l, *ol; char *end = str + *len; for (l = str; l < end; l++) if (*l == '\'') qtct++; *len += 2 + qtct*3; l = ol = (char *)halloc(*len); *l++ = '\''; for (; str < end; str++) if (*str == '\'') { *l++ = '\''; *l++ = '\\'; *l++ = '\''; *l++ = '\''; } else *l++ = *str; *l++ = '\''; return ol; } #define NAMLEN 60 /**/ int executenamedcommand(char *prmt) { int len, cmd, t0, l = strlen(prmt); char *ptr, *buf = halloc(l + NAMLEN + 2); int *obindtab = bindtab; strcpy(buf, prmt); statusline = buf; bindtab = mainbindtab; ptr = buf += l; len = 0; for (;;) { *ptr = '_'; statusll = l + len + 1; refresh(); if ((cmd = getkeycmd()) < 0 || cmd == z_sendbreak) { statusline = NULL; bindtab = obindtab; return -1; } switch (cmd) { case z_sendstring: sendstring(); break; case z_clearscreen: clearscreen(); break; case z_redisplay: redisplay(); break; case z_viquotedinsert: *ptr = '^'; refresh(); c = getkey(0); if(c == EOF || !c || len == NAMLEN) feep(); else *ptr++ = c, len++; break; case z_quotedinsert: if((c = getkey(0)) == EOF || !c || len == NAMLEN) feep(); else *ptr++ = c, len++; break; case z_backwarddeletechar: case z_vibackwarddeletechar: if (len) len--, ptr--; break; case z_killregion: case z_backwardkillword: case z_vibackwardkillword: while (len && (len--, *--ptr != '-')); break; case z_killwholeline: case z_vikillline: case z_backwardkillline: len = 0; ptr = buf; break; case z_acceptline: case z_vicmdmode: unambiguous: *ptr = 0; for (t0 = 0; t0 != ZLECMDCOUNT; t0++) if (!strcmp(buf, zlecmds[t0].name)) break; if (t0 != ZLECMDCOUNT) { statusline = NULL; bindtab = obindtab; return t0; } /* fall through */ default: if(cmd == z_selfinsertunmeta) { c &= 0x7f; if(c == '\r') c = '\n'; cmd = z_selfinsert; } if (cmd == z_listchoices || cmd == z_deletecharorlist || cmd == z_expandorcomplete || cmd == z_expandorcompleteprefix || cmd == z_completeword || cmd == z_vicmdmode || cmd == z_acceptline || c == ' ' || c == '\t') { LinkList cmdll; int ambig = 100; HEAPALLOC { cmdll = newlinklist(); *ptr = 0; for (t0 = 0; t0 != ZLECMDCOUNT; t0++) if (strpfx(buf, zlecmds[t0].name)) { int xx; addlinknode(cmdll, zlecmds[t0].name); xx = pfxlen(peekfirst(cmdll), zlecmds[t0].name); if (xx < ambig) ambig = xx; } } LASTALLOC; if (empty(cmdll)) feep(); else if (cmd == z_listchoices || cmd == z_deletecharorlist) { int zmultsav = zmult; *ptr = '_'; statusll = l + len + 1; zmult = 1; listlist(cmdll); zmult = zmultsav; } else if (!nextnode(firstnode(cmdll))) { strcpy(ptr = buf, peekfirst(cmdll)); ptr += (len = strlen(ptr)); if(cmd == z_acceptline || cmd == z_vicmdmode) goto unambiguous; } else { strcpy(buf, peekfirst(cmdll)); ptr = buf + ambig; *ptr = '_'; if (isset(AUTOLIST) && !(isset(LISTAMBIGUOUS) && ambig > len)) { int zmultsav = zmult; if (isset(LISTBEEP)) feep(); statusll = l + ambig + 1; zmult = 1; listlist(cmdll); zmult = zmultsav; } len = ambig; } } else { if (len == NAMLEN || icntrl(c) || cmd != z_selfinsert) feep(); else *ptr++ = c, len++; } } } } static char *bp; static char *truncstr; static int dontcount, lensb, trunclen; /* stradd() adds a string to the prompt, in a * * visible representation, doing truncation. */ /**/ void stradd(char *d) { /* dlen is the full length of the string we want to add */ int dlen = nicestrlen(d); char *ps, *pd, *pc, *t; int tlen, maxlen; addbufspc(dlen); /* This loop puts the nice representation of the string into the prompt * * buffer. It might be modified later. Note that bp isn't changed. */ for(ps=d, pd=bp; *ps; ps++) for(pc=nicechar(STOUC(*ps)); *pc; pc++) *pd++ = *pc; if(!trunclen || dlen <= trunclen) { /* No truncation is needed, so update bp and return, * * leaving the full string in the prompt. */ bp += dlen; return; } /* We need to truncate. t points to the truncation string -- which is * * inserted literally, without nice representation. tlen is its * * length, and maxlen is the amout of the main string that we want to * * keep. Note that if the truncation string is longer than the * * truncation length (tlen > trunclen), the truncation string is used * * in full. */ t = truncstr + 1; tlen = strlen(t); maxlen = tlen < trunclen ? trunclen - tlen : 0; addbufspc(tlen); if(*truncstr == '>') { /* '>' means truncate at the right. We just move past the first * * maxlen characters of the string, and write the truncation * * string there. */ bp += maxlen; while(*t) pputc(*t++); } else { /* Truncation at the left: ps is initialised to the start of the * * part of the string that we want to keep. pc points to the * * end of the string. The truncation string is added to the * * prompt, then the desired part of the string is copied into * * the right place. */ ps = bp + dlen - maxlen; pc = bp + dlen; while(*t) pputc(*t++); while(ps < pc) *bp++ = *ps++; } } /**/ int putstr(int d) { addbufspc(1); *bp++ = d; if (!dontcount) lensb++; return 0; } /**/ void tsetcap(int cap, int flag) { if (!(termflags & TERM_SHORT) && tcstr[cap]) { switch(flag) { case -1: tputs(tcstr[cap], 1, putraw); break; case 0: tputs(tcstr[cap], 1, putshout); break; case 1: if (!dontcount) { int t0; if (cap == TCSTANDOUTBEG || cap == TCSTANDOUTEND) t0 = tgetnum("sg"); else if (cap == TCUNDERLINEBEG || cap == TCUNDERLINEEND) t0 = tgetnum("ug"); else t0 = 0; if (t0 > 0) lensb -= t0; } tputs(tcstr[cap], 1, putstr); break; } if (txtisset(TXTDIRTY)) { txtunset(TXTDIRTY); if (txtisset(TXTBOLDFACE) && cap != TCBOLDFACEBEG) tsetcap(TCBOLDFACEBEG, flag); if (txtisset(TXTSTANDOUT)) tsetcap(TCSTANDOUTBEG, flag); if (txtisset(TXTUNDERLINE)) tsetcap(TCUNDERLINEBEG, flag); } } } /* get a prompt string */ static char *buf, *bp1, *bl0, *fm, *pmpt; static int bracepos, bufspc, pmpth; /**/ char * putprompt(char *fmin, int *lenp, int *wp, int cnt) { if (!fmin) { *lenp = 0; if (wp) *wp = 0; return ztrdup(""); } pmpth = 1; if ((termflags & TERM_UNKNOWN) && (unset(INTERACTIVE))) init_term(); bracepos = -1; fm = fmin; lensb = 0; pmpt = (dontcount = !cnt) ? NULL : fm; bp = bl0 = buf = zalloc(bufspc = 256); bp1 = NULL; clearerr(stdin); trunclen = 0; putpromptchar(1, '\0'); *lenp = bp - buf; if (wp) { *wp = bp - bl0 - lensb; if (pmpt != rpmpt) { *wp %= columns; if (*wp == columns - 1) { addbufspc(1); *wp = 0; *bp++ = ' '; ++*lenp; pmpth++; } if (!*wp && *lenp) { addbufspc(1); (*wp)++; *bp++ = ' '; ++*lenp; } } } if (pmpt == lpmpt) lppth = pmpth; return buf; } /**/ int putpromptchar(int doprint, int endchar) { char buf3[PATH_MAX], *ss; int t0, arg, test, sep; struct tm *tm; time_t timet; Nameddir nd; if (isset(PROMPTSUBST)) { int olderr = errflag; HEAPALLOC { fm = dupstring(fm); if (!parsestr(fm)) singsub(&fm); } LASTALLOC; /* Ignore errors in prompt substitution */ errflag = olderr; } for (; *fm && *fm != endchar; fm++) { arg = 0; if (*fm == '%') { if (idigit(*++fm)) { arg = zstrtol(fm, &fm, 10); } if (*fm == '(') { int tc; if (idigit(*++fm)) { arg = zstrtol(fm, &fm, 10); } test = 0; ss = pwd; switch (tc = *fm) { case 'c': case '.': case '~': if ((nd = finddir(ss))) { arg--; ss += strlen(nd->dir); } case '/': case 'C': for (; *ss; ss++) if (*ss == '/') arg--; if (arg <= 0) test = 1; break; case 't': case 'T': case 'd': case 'D': case 'w': timet = time(NULL); tm = localtime(&timet); switch (tc) { case 't': test = (arg == tm->tm_min); break; case 'T': test = (arg == tm->tm_hour); break; case 'd': test = (arg == tm->tm_mday); break; case 'D': test = (arg == tm->tm_mon); break; case 'w': test = (arg == tm->tm_wday); break; } break; case '?': if (lastval == arg) test = 1; break; case '#': if (geteuid() == arg) test = 1; break; case 'g': if (getegid() == arg) test = 1; break; case 'L': if (shlvl >= arg) test = 1; break; case 'S': if (time(NULL) - shtimer.tv_sec >= arg) test = 1; break; case 'v': if (arrlen(psvar) >= arg) test = 1; break; case '_': test = (cmdsp >= arg); break; default: test = -1; break; } if (!*fm || !(sep = *++fm)) return 0; fm++; if (!putpromptchar(test == 1 && doprint, sep) || !*++fm || !putpromptchar(test == 0 && doprint, ')')) { return 0; } continue; } if (!doprint) switch(*fm) { case '[': while(idigit(*++fm)); while(*++fm != ']'); continue; case '<': while(*++fm != '<'); continue; case '>': while(*++fm != '>'); continue; case 'D': if(fm[1]=='{') while(*++fm != '}'); continue; default: continue; } switch (*fm) { case '~': if ((nd = finddir(pwd))) { sprintf(buf3, "~%s%s", nd->nam, pwd + strlen(nd->dir)); stradd(buf3); break; } case 'd': case '/': stradd(pwd); break; case 'c': case '.': if ((nd = finddir(pwd))) sprintf(buf3, "~%s%s", nd->nam, pwd + strlen(nd->dir)); else strcpy(buf3, pwd); if (!arg) arg++; for (ss = buf3 + strlen(buf3); ss > buf3; ss--) if (*ss == '/' && !--arg) { ss++; break; } if (*ss == '/' && ss[1] && (ss != buf3)) ss++; stradd(ss); break; case 'C': strcpy(buf3, pwd); if (!arg) arg++; for (ss = buf3 + strlen(buf3); ss > buf3; ss--) if (*ss == '/' && !--arg) { ss++; break; } if (*ss == '/' && ss[1] && (ss != buf3)) ss++; stradd(ss); break; case 'h': case '!': addbufspc(DIGBUFSIZE); sprintf(bp, "%d", curhist); bp += strlen(bp); break; case 'M': stradd(hostnam); break; case 'm': if (!arg) arg++; for (ss = hostnam; *ss; ss++) if (*ss == '.' && !--arg) break; t0 = *ss; *ss = '\0'; stradd(hostnam); *ss = t0; break; case 'S': txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT); txtset(TXTSTANDOUT); tsetcap(TCSTANDOUTBEG, 1); break; case 's': txtchangeset(TXTNOSTANDOUT, TXTSTANDOUT); txtset(TXTDIRTY); txtunset(TXTSTANDOUT); tsetcap(TCSTANDOUTEND, 1); break; case 'B': txtchangeset(TXTBOLDFACE, TXTNOBOLDFACE); txtset(TXTDIRTY); txtset(TXTBOLDFACE); tsetcap(TCBOLDFACEBEG, 1); break; case 'b': txtchangeset(TXTNOBOLDFACE, TXTBOLDFACE); txtchangeset(TXTNOSTANDOUT, TXTSTANDOUT); txtchangeset(TXTNOUNDERLINE, TXTUNDERLINE); txtset(TXTDIRTY); txtunset(TXTBOLDFACE); tsetcap(TCALLATTRSOFF, 1); break; case 'U': txtchangeset(TXTUNDERLINE, TXTNOUNDERLINE); txtset(TXTUNDERLINE); tsetcap(TCUNDERLINEBEG, 1); break; case 'u': txtchangeset(TXTNOUNDERLINE, TXTUNDERLINE); txtset(TXTDIRTY); txtunset(TXTUNDERLINE); tsetcap(TCUNDERLINEEND, 1); break; case '[': if (idigit(*++fm)) trunclen = zstrtol(fm, &fm, 10); else trunclen = arg; if (trunclen) { bp1 = bp; while (*fm && *fm != ']') { if (*fm == '\\' && fm[1]) ++fm; addbufspc(1); *bp++ = *fm++; } addbufspc(2); if (bp1 == bp) *bp++ = '<'; *bp = '\0'; zsfree(truncstr); truncstr = ztrdup(bp = bp1); bp1 = NULL; } else { while (*fm && *fm != ']') { if (*fm == '\\' && fm[1]) fm++; fm++; } } if(!*fm) return 0; break; case '<': case '>': if((trunclen = arg)) { bp1 = bp; addbufspc(1); *bp++ = *fm++; while (*fm && *fm != *bp1) { if (*fm == '\\' && fm[1]) ++fm; addbufspc(1); *bp++ = *fm++; } addbufspc(1); *bp = '\0'; zsfree(truncstr); truncstr = ztrdup(bp = bp1); bp1 = NULL; } else { char ch = *fm++; while(*fm && *fm != ch) { if (*fm == '\\' && fm[1]) fm++; fm++; } } if(!*fm) return 0; break; case '{': if (!dontcount++) bracepos = bp - buf; break; case '}': if (!--dontcount && bracepos != -1) { lensb += (bp - buf) - bracepos; bracepos = -1; } break; case 't': case '@': case 'T': case '*': case 'w': case 'W': case 'D': { char *tmfmt, *dd; switch (*fm) { case 'T': tmfmt = "%k:%M"; break; case '*': tmfmt = "%k:%M:%S"; break; case 'w': tmfmt = "%a %e"; break; case 'W': tmfmt = "%m/%d/%y"; break; case 'D': tmfmt = "%y-%m-%d"; if (fm[1] == '{') { for (ss = fm + 2, dd = buf3; *ss && *ss != '}'; ++ss, ++dd) *dd = *((*ss == '\\' && ss[1]) ? ++ss : ss); if (*ss == '}') { *dd = '\0'; fm = ss; tmfmt = buf3; } } break; default: tmfmt = "%l:%M%p"; break; } timet = time(NULL); tm = localtime(&timet); addbufspc(80); /* 80 is arbitrary :-( */ ztrftime(bp, 79, tmfmt, tm); if (*bp == ' ') chuck(bp); bp += strlen(bp); break; } case 'n': stradd(get_username()); break; case 'l': if (*ttystrname) { ss = (strncmp(ttystrname, "/dev/tty", 8) ? ttystrname + 5 : ttystrname + 8); stradd(ss); } else stradd("()"); break; case '?': addbufspc(DIGBUFSIZE); sprintf(bp, "%ld", (long)lastval); bp += strlen(bp); break; case '%': addbufspc(1); *bp++ = '%'; break; case ')': addbufspc(1); *bp++ = ')'; break; case '#': addbufspc(1); *bp++ = (geteuid())? '%' : '#'; break; case 'v': if (!arg) arg = 1; if (arrlen(psvar) >= arg) stradd(psvar[arg - 1]); break; case 'E': tsetcap(TCCLEAREOL, 1); break; case '_': if (cmdsp) { if (arg > cmdsp || arg <= 0) arg = cmdsp; for (t0 = cmdsp - arg; arg--; t0++) { stradd(cmdnames[cmdstack[t0]]); if (arg) { addbufspc(1); *bp++=' '; } } } break; case 'r': if (pmpt == sprompt) { stradd(rstring); break; } case 'R': if (pmpt == sprompt) { stradd(Rstring); break; } case '\0': return 0; default: addbufspc(2); *bp++ = '%'; pputc(*fm); break; } } else if (doprint) { addbufspc(1); pputc(*fm == Meta ? *++fm ^ 32 : *fm); } } return *fm; } /**/ void pputc(char c) { if (!dontcount) { if (pmpt == rpmpt) { if (c == '\t' || c == '\n') c = ' '; } else if (c == '\t') { int t0 = 7 - (7 & (bp - bl0 - lensb)); lensb -= t0; } else if (c == '\n') { *bp++ = c; bl0 = bp; lensb = 0; pmpth++; return; } } if (bp - bl0 == columns) pmpth++; *bp++ = c; } /**/ void addbufspc(int need) { if((bp - buf) + need > bufspc) { char *oldbuf = buf; if(need & 255) need = (need | 255) + 1; buf = realloc(buf, bufspc += need); bp = buf + (bp - oldbuf); bl0 = buf + (bl0 - oldbuf); if(bp1) bp1 = buf + (bp1 - oldbuf); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.