summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/tc.prompt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/tc.prompt.c')
-rw-r--r--contrib/tcsh/tc.prompt.c410
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;
}
OpenPOWER on IntegriCloud