diff options
author | mp <mp@FreeBSD.org> | 2007-03-11 22:33:41 +0000 |
---|---|---|
committer | mp <mp@FreeBSD.org> | 2007-03-11 22:33:41 +0000 |
commit | a40980339b13e3b506c2317b5b4864127039eb2c (patch) | |
tree | 34aefea92d30b614247ef1f2671f2362f4761785 /contrib/tcsh/tc.prompt.c | |
parent | 32837fb336d4709f0a121130a3a78f29be0db5ed (diff) | |
download | FreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.zip FreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.tar.gz |
Import of tcsh-6.15.00
Diffstat (limited to 'contrib/tcsh/tc.prompt.c')
-rw-r--r-- | contrib/tcsh/tc.prompt.c | 410 |
1 files changed, 191 insertions, 219 deletions
diff --git a/contrib/tcsh/tc.prompt.c b/contrib/tcsh/tc.prompt.c index 147b809..f63fdf0 100644 --- a/contrib/tcsh/tc.prompt.c +++ b/contrib/tcsh/tc.prompt.c @@ -1,4 +1,4 @@ -/* $Header: /src/pub/tcsh/tc.prompt.c,v 3.53 2005/01/05 18:06:43 christos Exp $ */ +/* $Header: /p/tcsh/cvsroot/tcsh/tc.prompt.c,v 3.67 2006/11/17 16:26:58 christos Exp $ */ /* * tc.prompt.c: Prompt printing stuff */ @@ -32,7 +32,7 @@ */ #include "sh.h" -RCSID("$Id: tc.prompt.c,v 3.53 2005/01/05 18:06:43 christos Exp $") +RCSID("$tcsh: tc.prompt.c,v 3.67 2006/11/17 16:26:58 christos Exp $") #include "ed.h" #include "tw.h" @@ -52,7 +52,7 @@ static const char *month_list[12]; static const char *day_list[7]; void -dateinit() +dateinit(void) { #ifdef notyet int i; @@ -108,14 +108,12 @@ dateinit() } void -printprompt(promptno, str) - int promptno; - const char *str; +printprompt(int promptno, const char *str) { - static Char *ocp = NULL; + static const Char *ocp = NULL; static const char *ostr = NULL; time_t lclock = time(NULL); - Char *cp; + const Char *cp; switch (promptno) { default: @@ -143,22 +141,24 @@ printprompt(promptno, str) ostr = str; } - PromptBuf[0] = '\0'; - tprintf(FMT_PROMPT, PromptBuf, cp, 2 * INBUFSIZE - 2, str, lclock, NULL); + xfree(Prompt); + Prompt = NULL; + Prompt = tprintf(FMT_PROMPT, cp, str, lclock, NULL); if (!editing) { - for (cp = PromptBuf; *cp ; ) + for (cp = Prompt; *cp ; ) (void) putwraw(*cp++); SetAttributes(0); flush(); } - RPromptBuf[0] = '\0'; + xfree(RPrompt); + RPrompt = NULL; if (promptno == 0) { /* determine rprompt if using main prompt */ cp = varval(STRrprompt); - tprintf(FMT_PROMPT, RPromptBuf, cp, INBUFSIZE - 2, NULL, lclock, NULL); + RPrompt = tprintf(FMT_PROMPT, cp, NULL, lclock, NULL); /* if not editing, put rprompt after prompt */ - if (!editing && RPromptBuf[0] != '\0') { - for (cp = RPromptBuf; *cp ; ) + if (!editing && RPrompt[0] != '\0') { + for (cp = RPrompt; *cp ; ) (void) putwraw(*cp++); SetAttributes(0); putraw(' '); @@ -167,83 +167,70 @@ printprompt(promptno, str) } } -void -tprintf(what, buf, fmt, siz, str, tim, info) - int what; - Char *buf; - const Char *fmt; - size_t siz; - const char *str; - time_t tim; - ptr_t info; +static void +tprintf_append_mbs(struct Strbuf *buf, const char *mbs, Char attributes) +{ + while (*mbs != 0) { + Char wc; + + mbs += one_mbtowc(&wc, mbs, MB_LEN_MAX); + Strbuf_append1(buf, wc | attributes); + } +} + +Char * +tprintf(int what, const Char *fmt, const char *str, time_t tim, ptr_t info) { + struct Strbuf buf = Strbuf_INIT; Char *z, *q; Char attributes = 0; static int print_prompt_did_ding = 0; - Char buff[BUFSIZE]; - /* Need to be unsigned to avoid sign extension */ - const unsigned char *cz; - unsigned char cbuff[BUFSIZE]; + char *cz; - Char *p = buf; - Char *ep = &p[siz]; + Char *p; const Char *cp = fmt; Char Scp; struct tm *t = localtime(&tim); /* prompt stuff */ - static Char *olddir = NULL, *olduser = NULL; + static Char *olduser = NULL; int updirs; - size_t pdirs, sz; - int l; + size_t pdirs; + cleanup_push(&buf, Strbuf_cleanup); for (; *cp; cp++) { - if (p >= ep) - break; - l = NLSSize(cp, -1); - if (l > 1) { - while (l--) - *p++ = attributes | *cp++; - cp--; - continue; - } if ((*cp == '%') && ! (cp[1] == '\0')) { cp++; switch (*cp) { case 'R': if (what == FMT_HISTORY) { - fmthist('R', info, (char *) cbuff, sizeof(cbuff)); - cz = cbuff; - } else - cz = (const unsigned char *) str; - if (cz != NULL) - for (; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + cz = fmthist('R', info); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); + } else { + if (str != NULL) + tprintf_append_mbs(&buf, str, attributes); + } break; case '#': - *p++ = attributes | ((uid == 0) ? PRCHROOT : PRCH); + Strbuf_append1(&buf, + attributes | ((uid == 0) ? PRCHROOT : PRCH)); break; case '!': case 'h': switch (what) { case FMT_HISTORY: - fmthist('h', info, (char *) cbuff, sizeof(cbuff)); + cz = fmthist('h', info); break; case FMT_SCHED: - (void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d", - *(int *)info); + cz = xasprintf("%d", *(int *)info); break; default: - (void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d", - eventno + 1); + cz = xasprintf("%d", eventno + 1); break; } - for (cz = cbuff; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); break; case 'T': /* 24 hour format */ case '@': @@ -254,8 +241,6 @@ tprintf(what, buf, fmt, siz, str, tim, info) char ampm = 'a'; int hr = t->tm_hour; - if (p >= ep - 10) break; - /* addition by Hans J. Albertsson */ /* and another adapted from Justin Bur */ if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { @@ -273,25 +258,33 @@ tprintf(what, buf, fmt, siz, str, tim, info) what != FMT_PROMPT || adrof(STRnoding)) { if (t->tm_min) print_prompt_did_ding = 0; - p = Itoa(hr, p, 0, attributes); - *p++ = attributes | ':'; - p = Itoa(t->tm_min, p, 2, attributes); + /* + * Pad hour to 2 characters if padhour is set, + * by ADAM David Alan Martin + */ + p = Itoa(hr, adrof(STRpadhour) ? 2 : 0, attributes); + Strbuf_append(&buf, p); + xfree(p); + Strbuf_append1(&buf, attributes | ':'); + p = Itoa(t->tm_min, 2, attributes); + Strbuf_append(&buf, p); + xfree(p); if (*cp == 'p' || *cp == 'P') { - *p++ = attributes | ':'; - p = Itoa(t->tm_sec, p, 2, attributes); + Strbuf_append1(&buf, attributes | ':'); + p = Itoa(t->tm_sec, 2, attributes); + Strbuf_append(&buf, p); + xfree(p); } if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { - *p++ = attributes | ampm; - *p++ = attributes | 'm'; + Strbuf_append1(&buf, attributes | ampm); + Strbuf_append1(&buf, attributes | 'm'); } } else { /* we need to ding */ - int i = 0; + size_t i; - (void) Strcpy(buff, STRDING); - while (buff[i]) { - *p++ = attributes | buff[i++]; - } + for (i = 0; STRDING[i] != 0; i++) + Strbuf_append1(&buf, attributes | STRDING[i]); print_prompt_did_ding = 1; } } @@ -300,38 +293,40 @@ tprintf(what, buf, fmt, siz, str, tim, info) case 'M': #ifndef HAVENOUTMP if (what == FMT_WHO) - cz = (const unsigned char *) who_info(info, 'M', - (char *) cbuff, sizeof(cbuff)); + cz = who_info(info, 'M'); else #endif /* HAVENOUTMP */ - cz = (const unsigned char *) getenv("HOST"); + cz = getenv("HOST"); /* * Bug pointed out by Laurent Dami <dami@cui.unige.ch>: don't * derefrence that NULL (if HOST is not set)... */ if (cz != NULL) - for (; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + tprintf_append_mbs(&buf, cz, attributes); + if (what == FMT_WHO) + xfree(cz); break; - case 'm': + case 'm': { + char *scz = NULL; #ifndef HAVENOUTMP if (what == FMT_WHO) - cz = (const unsigned char *) who_info(info, 'm', - (char *) cbuff, sizeof(cbuff)); - else + scz = cz = who_info(info, 'm'); + else #endif /* HAVENOUTMP */ - cz = (const unsigned char *) getenv("HOST"); + cz = getenv("HOST"); if (cz != NULL) - for (; *cz && (what == FMT_WHO || *cz != '.') && p < ep; - p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; + while (*cz != 0 && (what == FMT_WHO || *cz != '.')) { + Char wc; + + cz += one_mbtowc(&wc, cz, MB_LEN_MAX); + Strbuf_append1(&buf, wc | attributes); } + if (scz) + xfree(scz); break; + } /* lukem: new directory prompt code */ case '~': @@ -347,6 +342,8 @@ tprintf(what, buf, fmt, siz, str, tim, info) /* show ~ whenever possible - a la dirs */ if (Scp == '~' || Scp == '.' ) { + static Char *olddir = NULL; + if (tlength == 0 || olddir != z) { olddir = z; /* have we changed dir? */ olduser = getusername(&olddir); @@ -362,16 +359,16 @@ tprintf(what, buf, fmt, siz, str, tim, info) #ifdef WINNT_NATIVE Char *oldz = z; if (z[1] == ':') { - *p++ = attributes | *z++; - *p++ = attributes | *z++; + Strbuf_append1(&buf, attributes | *z++); + Strbuf_append1(&buf, attributes | *z++); + } + if (*z == '/' && z[1] == '/') { + Strbuf_append1(&buf, attributes | *z++); + Strbuf_append1(&buf, attributes | *z++); + do { + Strbuf_append1(&buf, attributes | *z++); + } while(*z != '/'); } - if (*z == '/' && z[1] == '/') { - *p++ = attributes | *z++; - *p++ = attributes | *z++; - do { - *p++ = attributes | *z++; - }while(*z != '/'); - } #endif /* WINNT_NATIVE */ q = z; while (*z) /* calc # of /'s */ @@ -387,7 +384,7 @@ tprintf(what, buf, fmt, siz, str, tim, info) * //machine/share/folder => //machine:folder */ if (oldz[0] == '/' && oldz[1] == '/' && updirs > 1) - *p++ = attributes | ':'; + Strbuf_append1(&buf, attributes | ':'); #endif /* WINNT_NATIVE */ if ((Scp == 'C' && *q != '/')) updirs++; @@ -417,103 +414,90 @@ tprintf(what, buf, fmt, siz, str, tim, info) /* print ~[user] */ if ((olduser) && ((Scp == '~') || (Scp == '.' && (pdirs || (!pdirs && updirs <= 0))) )) { - *p++ = attributes | '~'; - if (p >= ep) break; - for (q = olduser; *q; *p++ = attributes | *q++) - if (p >= ep) break; + Strbuf_append1(&buf, attributes | '~'); + for (q = olduser; *q; q++) + Strbuf_append1(&buf, attributes | *q); } /* RWM - tell you how many dirs we've ignored */ /* and add '/' at front of this */ if (updirs > 0 && pdirs) { - if (p >= ep - 5) break; if (adrof(STRellipsis)) { - *p++ = attributes | '.'; - *p++ = attributes | '.'; - *p++ = attributes | '.'; + Strbuf_append1(&buf, attributes | '.'); + Strbuf_append1(&buf, attributes | '.'); + Strbuf_append1(&buf, attributes | '.'); } else { - *p++ = attributes | '/'; - *p++ = attributes | '<'; + Strbuf_append1(&buf, attributes | '/'); + Strbuf_append1(&buf, attributes | '<'); if (updirs > 9) { - *p++ = attributes | '9'; - *p++ = attributes | '+'; + Strbuf_append1(&buf, attributes | '9'); + Strbuf_append1(&buf, attributes | '+'); } else - *p++ = attributes | ('0' + updirs); - *p++ = attributes | '>'; + Strbuf_append1(&buf, attributes | ('0' + updirs)); + Strbuf_append1(&buf, attributes | '>'); } } - - for (; *z ; *p++ = attributes | *z++) - if (p >= ep) break; + + while (*z) + Strbuf_append1(&buf, attributes | *z++); break; /* lukem: end of new directory prompt code */ case 'n': #ifndef HAVENOUTMP if (what == FMT_WHO) { - cz = (const unsigned char *) who_info(info, 'n', - (char *) cbuff, sizeof(cbuff)); - for (; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + cz = who_info(info, 'n'); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); } else #endif /* HAVENOUTMP */ { if ((z = varval(STRuser)) != STRNULL) - for (; *z; *p++ = attributes | *z++) - if (p >= ep) break; + while (*z) + Strbuf_append1(&buf, attributes | *z++); } break; case 'l': #ifndef HAVENOUTMP if (what == FMT_WHO) { - cz = (const unsigned char *) who_info(info, 'l', - (char *) cbuff, sizeof(cbuff)); - for (; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + cz = who_info(info, 'l'); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); } else #endif /* HAVENOUTMP */ { if ((z = varval(STRtty)) != STRNULL) - for (; *z; *p++ = attributes | *z++) - if (p >= ep) break; + while (*z) + Strbuf_append1(&buf, attributes | *z++); } break; case 'd': - for (cz = (const unsigned char *) day_list[t->tm_wday]; - *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + tprintf_append_mbs(&buf, day_list[t->tm_wday], attributes); break; case 'D': - if (p >= ep - 3) break; - p = Itoa(t->tm_mday, p, 2, attributes); + p = Itoa(t->tm_mday, 2, attributes); + Strbuf_append(&buf, p); + xfree(p); break; case 'w': - if (p >= ep - 5) break; - for (cz = (const unsigned char *) month_list[t->tm_mon]; - *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + tprintf_append_mbs(&buf, month_list[t->tm_mon], attributes); break; case 'W': - if (p >= ep - 3) break; - p = Itoa(t->tm_mon + 1, p, 2, attributes); + p = Itoa(t->tm_mon + 1, 2, attributes); + Strbuf_append(&buf, p); + xfree(p); break; case 'y': - if (p >= ep - 3) break; - p = Itoa(t->tm_year % 100, p, 2, attributes); + p = Itoa(t->tm_year % 100, 2, attributes); + Strbuf_append(&buf, p); + xfree(p); break; case 'Y': - if (p >= ep - 5) break; - p = Itoa(t->tm_year + 1900, p, 4, attributes); + p = Itoa(t->tm_year + 1900, 4, attributes); + Strbuf_append(&buf, p); + xfree(p); break; case 'S': /* start standout */ attributes |= STANDOUT; @@ -539,30 +523,28 @@ tprintf(what, buf, fmt, siz, str, tim, info) case 'j': { - Char xbuf[128], *ebuf, *xq; int njobs = -1; struct process *pp; + for (pp = proclist.p_next; pp; pp = pp->p_next) njobs++; - /* make sure we have space */ - ebuf = Itoa(njobs, buf, 1, attributes); - for (xq = xbuf; xq < ebuf; *p++ = *xq++) - if (p >= ep) break; + p = Itoa(njobs, 1, attributes); + Strbuf_append(&buf, p); + xfree(p); break; } case '?': if ((z = varval(STRstatus)) != STRNULL) - for (; *z; *p++ = attributes | *z++) - if (p >= ep) break; + while (*z) + Strbuf_append1(&buf, attributes | *z++); break; case '$': - sz = ep - p; - (void) expdollar(&p, &cp, &sz, attributes); - /* cp should point the last char of currnet % sequence */ + expdollar(&buf, &cp, attributes); + /* cp should point the last char of current % sequence */ cp--; break; case '%': - *p++ = attributes | '%'; + Strbuf_append1(&buf, attributes | '%'); break; case '{': /* literal characters start */ #if LITERAL == 0 @@ -570,7 +552,7 @@ tprintf(what, buf, fmt, siz, str, tim, info) * No literal capability, so skip all chars in the literal * string */ - while (*cp != '\0' && (*cp != '%' || cp[1] != '}')) + while (*cp != '\0' && (cp[-1] != '%' || *cp != '}')) cp++; #endif /* LITERAL == 0 */ attributes |= LITERAL; @@ -581,64 +563,56 @@ tprintf(what, buf, fmt, siz, str, tim, info) default: #ifndef HAVENOUTMP if (*cp == 'a' && what == FMT_WHO) { - cz = (const unsigned char *) who_info(info, 'a', - (char *) cbuff, sizeof(cbuff)); - for (; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + cz = who_info(info, 'a'); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); } - else + else #endif /* HAVENOUTMP */ { - if (p >= ep - 3) break; - *p++ = attributes | '%'; - *p++ = attributes | *cp; + Strbuf_append1(&buf, attributes | '%'); + Strbuf_append1(&buf, attributes | *cp); } break; } } - else if (*cp == '\\' || *cp == '^') - *p++ = attributes | parseescape(&cp); + else if (*cp == '\\' || *cp == '^') + Strbuf_append1(&buf, attributes | parseescape(&cp)); else if (*cp == HIST) { /* EGS: handle '!'s in prompts */ - if (what == FMT_HISTORY) - fmthist('h', info, (char *) cbuff, sizeof(cbuff)); + if (what == FMT_HISTORY) + cz = fmthist('h', info); else - (void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d", eventno + 1); - for (cz = cbuff; *cz && p < ep; p++) { - cz += one_mbtowc(p, (const char *)cz, MB_LEN_MAX); - *p |= attributes; - } + cz = xasprintf("%d", eventno + 1); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); } - else - *p++ = attributes | *cp; /* normal character */ + else + Strbuf_append1(&buf, attributes | *cp); /* normal character */ } - *p = '\0'; + cleanup_ignore(&buf); + cleanup_until(&buf); + return Strbuf_finish(&buf); } -Char * -expdollar(dstp, srcp, spp, attr) - Char **dstp; - const Char **srcp; - size_t *spp; - int attr; +int +expdollar(struct Strbuf *buf, const Char **srcp, Char attr) { struct varent *vp; - Char var[MAXVARLEN]; const Char *src = *srcp; - Char *val; - Char *dst = *dstp; - int i, curly = 0; + Char *var, *val; + size_t i; + int curly = 0; /* found a variable, expand it */ - for (i = 0; i < MAXVARLEN; i++) { + var = xmalloc((Strlen(src) + 1) * sizeof (*var)); + for (i = 0; ; i++) { var[i] = *++src & TRIM; if (i == 0 && var[i] == '{') { curly = 1; var[i] = *++src & TRIM; } - if (!alnum(var[i])) { - + if (!alnum(var[i]) && var[i] != '_') { + var[i] = '\0'; break; } @@ -647,31 +621,29 @@ expdollar(dstp, srcp, spp, attr) src++; vp = adrof(var); - val = (!vp) ? tgetenv(var) : NULL; if (vp && vp->vec) { for (i = 0; vp->vec[i] != NULL; i++) { - for (val = vp->vec[i]; *spp > 0 && *val; (*spp)--) - *dst++ = *val++ | attr; - if (vp->vec[i+1] && *spp > 0) { - *dst++ = ' ' | attr; - (*spp)--; - } + for (val = vp->vec[i]; *val; val++) + if (*val != '\n' && *val != '\r') + Strbuf_append1(buf, *val | attr); + if (vp->vec[i+1]) + Strbuf_append1(buf, ' ' | attr); } } - else if (val) { - for (; *spp > 0 && *val; (*spp)--) - *dst++ = *val++ | attr; - } else { - **dstp = '\0'; - *srcp = src; - return NULL; + val = (!vp) ? tgetenv(var) : NULL; + if (val) { + for (; *val; val++) + if (*val != '\n' && *val != '\r') + Strbuf_append1(buf, *val | attr); + } else { + *srcp = src; + xfree(var); + return 0; + } } - *dst = '\0'; - val = *dstp; *srcp = src; - *dstp = dst; - - return val; + xfree(var); + return 1; } |