145e5710bSMark Peek /* $Header: /p/tcsh/cvsroot/tcsh/tc.prompt.c,v 3.67 2006/11/17 16:26:58 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * tc.prompt.c: Prompt printing stuff 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 1729301572SMark Peek * 3. Neither the name of the University nor the names of its contributors 18c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 19c80476e4SDavid E. O'Brien * without specific prior written permission. 20c80476e4SDavid E. O'Brien * 21c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31c80476e4SDavid E. O'Brien * SUCH DAMAGE. 32c80476e4SDavid E. O'Brien */ 33c80476e4SDavid E. O'Brien #include "sh.h" 34c80476e4SDavid E. O'Brien 3545e5710bSMark Peek RCSID("$tcsh: tc.prompt.c,v 3.67 2006/11/17 16:26:58 christos Exp $") 36c80476e4SDavid E. O'Brien 37c80476e4SDavid E. O'Brien #include "ed.h" 38c80476e4SDavid E. O'Brien #include "tw.h" 39c80476e4SDavid E. O'Brien 40c80476e4SDavid E. O'Brien /* 41c80476e4SDavid E. O'Brien * kfk 21oct1983 -- add @ (time) and / ($cwd) in prompt. 42c80476e4SDavid E. O'Brien * PWP 4/27/87 -- rearange for tcsh. 43c80476e4SDavid E. O'Brien * mrdch@com.tau.edu.il 6/26/89 - added ~, T and .# - rearanged to switch() 44c80476e4SDavid E. O'Brien * instead of if/elseif 45c80476e4SDavid E. O'Brien * Luke Mewburn, <lukem@cs.rmit.edu.au> 46c80476e4SDavid E. O'Brien * 6-Sep-91 changed date format 47c80476e4SDavid E. O'Brien * 16-Feb-94 rewrote directory prompt code, added $ellipsis 48c80476e4SDavid E. O'Brien * 29-Dec-96 added rprompt support 49c80476e4SDavid E. O'Brien */ 50c80476e4SDavid E. O'Brien 5123338178SMark Peek static const char *month_list[12]; 5223338178SMark Peek static const char *day_list[7]; 53c80476e4SDavid E. O'Brien 54c80476e4SDavid E. O'Brien void 5545e5710bSMark Peek dateinit(void) 56c80476e4SDavid E. O'Brien { 57c80476e4SDavid E. O'Brien #ifdef notyet 58c80476e4SDavid E. O'Brien int i; 59c80476e4SDavid E. O'Brien 60c80476e4SDavid E. O'Brien setlocale(LC_TIME, ""); 61c80476e4SDavid E. O'Brien 62c80476e4SDavid E. O'Brien for (i = 0; i < 12; i++) 63c80476e4SDavid E. O'Brien xfree((ptr_t) month_list[i]); 64c80476e4SDavid E. O'Brien month_list[0] = strsave(_time_info->abbrev_month[0]); 65c80476e4SDavid E. O'Brien month_list[1] = strsave(_time_info->abbrev_month[1]); 66c80476e4SDavid E. O'Brien month_list[2] = strsave(_time_info->abbrev_month[2]); 67c80476e4SDavid E. O'Brien month_list[3] = strsave(_time_info->abbrev_month[3]); 68c80476e4SDavid E. O'Brien month_list[4] = strsave(_time_info->abbrev_month[4]); 69c80476e4SDavid E. O'Brien month_list[5] = strsave(_time_info->abbrev_month[5]); 70c80476e4SDavid E. O'Brien month_list[6] = strsave(_time_info->abbrev_month[6]); 71c80476e4SDavid E. O'Brien month_list[7] = strsave(_time_info->abbrev_month[7]); 72c80476e4SDavid E. O'Brien month_list[8] = strsave(_time_info->abbrev_month[8]); 73c80476e4SDavid E. O'Brien month_list[9] = strsave(_time_info->abbrev_month[9]); 74c80476e4SDavid E. O'Brien month_list[10] = strsave(_time_info->abbrev_month[10]); 75c80476e4SDavid E. O'Brien month_list[11] = strsave(_time_info->abbrev_month[11]); 76c80476e4SDavid E. O'Brien 77c80476e4SDavid E. O'Brien for (i = 0; i < 7; i++) 78c80476e4SDavid E. O'Brien xfree((ptr_t) day_list[i]); 79c80476e4SDavid E. O'Brien day_list[0] = strsave(_time_info->abbrev_wkday[0]); 80c80476e4SDavid E. O'Brien day_list[1] = strsave(_time_info->abbrev_wkday[1]); 81c80476e4SDavid E. O'Brien day_list[2] = strsave(_time_info->abbrev_wkday[2]); 82c80476e4SDavid E. O'Brien day_list[3] = strsave(_time_info->abbrev_wkday[3]); 83c80476e4SDavid E. O'Brien day_list[4] = strsave(_time_info->abbrev_wkday[4]); 84c80476e4SDavid E. O'Brien day_list[5] = strsave(_time_info->abbrev_wkday[5]); 85c80476e4SDavid E. O'Brien day_list[6] = strsave(_time_info->abbrev_wkday[6]); 86c80476e4SDavid E. O'Brien #else 87c80476e4SDavid E. O'Brien month_list[0] = "Jan"; 88c80476e4SDavid E. O'Brien month_list[1] = "Feb"; 89c80476e4SDavid E. O'Brien month_list[2] = "Mar"; 90c80476e4SDavid E. O'Brien month_list[3] = "Apr"; 91c80476e4SDavid E. O'Brien month_list[4] = "May"; 92c80476e4SDavid E. O'Brien month_list[5] = "Jun"; 93c80476e4SDavid E. O'Brien month_list[6] = "Jul"; 94c80476e4SDavid E. O'Brien month_list[7] = "Aug"; 95c80476e4SDavid E. O'Brien month_list[8] = "Sep"; 96c80476e4SDavid E. O'Brien month_list[9] = "Oct"; 97c80476e4SDavid E. O'Brien month_list[10] = "Nov"; 98c80476e4SDavid E. O'Brien month_list[11] = "Dec"; 99c80476e4SDavid E. O'Brien 100c80476e4SDavid E. O'Brien day_list[0] = "Sun"; 101c80476e4SDavid E. O'Brien day_list[1] = "Mon"; 102c80476e4SDavid E. O'Brien day_list[2] = "Tue"; 103c80476e4SDavid E. O'Brien day_list[3] = "Wed"; 104c80476e4SDavid E. O'Brien day_list[4] = "Thu"; 105c80476e4SDavid E. O'Brien day_list[5] = "Fri"; 106c80476e4SDavid E. O'Brien day_list[6] = "Sat"; 107c80476e4SDavid E. O'Brien #endif 108c80476e4SDavid E. O'Brien } 109c80476e4SDavid E. O'Brien 110c80476e4SDavid E. O'Brien void 11145e5710bSMark Peek printprompt(int promptno, const char *str) 112c80476e4SDavid E. O'Brien { 11345e5710bSMark Peek static const Char *ocp = NULL; 11423338178SMark Peek static const char *ostr = NULL; 115c80476e4SDavid E. O'Brien time_t lclock = time(NULL); 11645e5710bSMark Peek const Char *cp; 117c80476e4SDavid E. O'Brien 118c80476e4SDavid E. O'Brien switch (promptno) { 119c80476e4SDavid E. O'Brien default: 120c80476e4SDavid E. O'Brien case 0: 121c80476e4SDavid E. O'Brien cp = varval(STRprompt); 122c80476e4SDavid E. O'Brien break; 123c80476e4SDavid E. O'Brien case 1: 124c80476e4SDavid E. O'Brien cp = varval(STRprompt2); 125c80476e4SDavid E. O'Brien break; 126c80476e4SDavid E. O'Brien case 2: 127c80476e4SDavid E. O'Brien cp = varval(STRprompt3); 128c80476e4SDavid E. O'Brien break; 129c80476e4SDavid E. O'Brien case 3: 130c80476e4SDavid E. O'Brien if (ocp != NULL) { 131c80476e4SDavid E. O'Brien cp = ocp; 132c80476e4SDavid E. O'Brien str = ostr; 133c80476e4SDavid E. O'Brien } 134c80476e4SDavid E. O'Brien else 135c80476e4SDavid E. O'Brien cp = varval(STRprompt); 136c80476e4SDavid E. O'Brien break; 137c80476e4SDavid E. O'Brien } 138c80476e4SDavid E. O'Brien 139c80476e4SDavid E. O'Brien if (promptno < 2) { 140c80476e4SDavid E. O'Brien ocp = cp; 141c80476e4SDavid E. O'Brien ostr = str; 142c80476e4SDavid E. O'Brien } 143c80476e4SDavid E. O'Brien 14445e5710bSMark Peek xfree(Prompt); 14545e5710bSMark Peek Prompt = NULL; 14645e5710bSMark Peek Prompt = tprintf(FMT_PROMPT, cp, str, lclock, NULL); 147c80476e4SDavid E. O'Brien if (!editing) { 14845e5710bSMark Peek for (cp = Prompt; *cp ; ) 14923338178SMark Peek (void) putwraw(*cp++); 150c80476e4SDavid E. O'Brien SetAttributes(0); 151c80476e4SDavid E. O'Brien flush(); 152c80476e4SDavid E. O'Brien } 153c80476e4SDavid E. O'Brien 15445e5710bSMark Peek xfree(RPrompt); 15545e5710bSMark Peek RPrompt = NULL; 156c80476e4SDavid E. O'Brien if (promptno == 0) { /* determine rprompt if using main prompt */ 157c80476e4SDavid E. O'Brien cp = varval(STRrprompt); 15845e5710bSMark Peek RPrompt = tprintf(FMT_PROMPT, cp, NULL, lclock, NULL); 159c80476e4SDavid E. O'Brien /* if not editing, put rprompt after prompt */ 16045e5710bSMark Peek if (!editing && RPrompt[0] != '\0') { 16145e5710bSMark Peek for (cp = RPrompt; *cp ; ) 16223338178SMark Peek (void) putwraw(*cp++); 163c80476e4SDavid E. O'Brien SetAttributes(0); 164c80476e4SDavid E. O'Brien putraw(' '); 165c80476e4SDavid E. O'Brien flush(); 166c80476e4SDavid E. O'Brien } 167c80476e4SDavid E. O'Brien } 168c80476e4SDavid E. O'Brien } 169c80476e4SDavid E. O'Brien 17045e5710bSMark Peek static void 17145e5710bSMark Peek tprintf_append_mbs(struct Strbuf *buf, const char *mbs, Char attributes) 172c80476e4SDavid E. O'Brien { 17345e5710bSMark Peek while (*mbs != 0) { 17445e5710bSMark Peek Char wc; 17545e5710bSMark Peek 17645e5710bSMark Peek mbs += one_mbtowc(&wc, mbs, MB_LEN_MAX); 17745e5710bSMark Peek Strbuf_append1(buf, wc | attributes); 17845e5710bSMark Peek } 17945e5710bSMark Peek } 18045e5710bSMark Peek 18145e5710bSMark Peek Char * 18245e5710bSMark Peek tprintf(int what, const Char *fmt, const char *str, time_t tim, ptr_t info) 18345e5710bSMark Peek { 18445e5710bSMark Peek struct Strbuf buf = Strbuf_INIT; 185c80476e4SDavid E. O'Brien Char *z, *q; 186c80476e4SDavid E. O'Brien Char attributes = 0; 187c80476e4SDavid E. O'Brien static int print_prompt_did_ding = 0; 18845e5710bSMark Peek char *cz; 189c80476e4SDavid E. O'Brien 19045e5710bSMark Peek Char *p; 191c80476e4SDavid E. O'Brien const Char *cp = fmt; 192c80476e4SDavid E. O'Brien Char Scp; 193c80476e4SDavid E. O'Brien struct tm *t = localtime(&tim); 194c80476e4SDavid E. O'Brien 195c80476e4SDavid E. O'Brien /* prompt stuff */ 19645e5710bSMark Peek static Char *olduser = NULL; 19729301572SMark Peek int updirs; 19845e5710bSMark Peek size_t pdirs; 199c80476e4SDavid E. O'Brien 20045e5710bSMark Peek cleanup_push(&buf, Strbuf_cleanup); 201c80476e4SDavid E. O'Brien for (; *cp; cp++) { 202c80476e4SDavid E. O'Brien if ((*cp == '%') && ! (cp[1] == '\0')) { 203c80476e4SDavid E. O'Brien cp++; 204c80476e4SDavid E. O'Brien switch (*cp) { 205c80476e4SDavid E. O'Brien case 'R': 20623338178SMark Peek if (what == FMT_HISTORY) { 20745e5710bSMark Peek cz = fmthist('R', info); 20845e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 20945e5710bSMark Peek xfree(cz); 21045e5710bSMark Peek } else { 21145e5710bSMark Peek if (str != NULL) 21245e5710bSMark Peek tprintf_append_mbs(&buf, str, attributes); 21323338178SMark Peek } 214c80476e4SDavid E. O'Brien break; 215c80476e4SDavid E. O'Brien case '#': 21645e5710bSMark Peek Strbuf_append1(&buf, 21745e5710bSMark Peek attributes | ((uid == 0) ? PRCHROOT : PRCH)); 218c80476e4SDavid E. O'Brien break; 219c80476e4SDavid E. O'Brien case '!': 220c80476e4SDavid E. O'Brien case 'h': 221c80476e4SDavid E. O'Brien switch (what) { 222c80476e4SDavid E. O'Brien case FMT_HISTORY: 22345e5710bSMark Peek cz = fmthist('h', info); 224c80476e4SDavid E. O'Brien break; 225c80476e4SDavid E. O'Brien case FMT_SCHED: 22645e5710bSMark Peek cz = xasprintf("%d", *(int *)info); 227c80476e4SDavid E. O'Brien break; 228c80476e4SDavid E. O'Brien default: 22945e5710bSMark Peek cz = xasprintf("%d", eventno + 1); 230c80476e4SDavid E. O'Brien break; 231c80476e4SDavid E. O'Brien } 23245e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 23345e5710bSMark Peek xfree(cz); 234c80476e4SDavid E. O'Brien break; 235c80476e4SDavid E. O'Brien case 'T': /* 24 hour format */ 236c80476e4SDavid E. O'Brien case '@': 237c80476e4SDavid E. O'Brien case 't': /* 12 hour am/pm format */ 238c80476e4SDavid E. O'Brien case 'p': /* With seconds */ 239c80476e4SDavid E. O'Brien case 'P': 240c80476e4SDavid E. O'Brien { 241c80476e4SDavid E. O'Brien char ampm = 'a'; 242c80476e4SDavid E. O'Brien int hr = t->tm_hour; 243c80476e4SDavid E. O'Brien 244c80476e4SDavid E. O'Brien /* addition by Hans J. Albertsson */ 245c80476e4SDavid E. O'Brien /* and another adapted from Justin Bur */ 246c80476e4SDavid E. O'Brien if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { 247c80476e4SDavid E. O'Brien if (hr >= 12) { 248c80476e4SDavid E. O'Brien if (hr > 12) 249c80476e4SDavid E. O'Brien hr -= 12; 250c80476e4SDavid E. O'Brien ampm = 'p'; 251c80476e4SDavid E. O'Brien } 252c80476e4SDavid E. O'Brien else if (hr == 0) 253c80476e4SDavid E. O'Brien hr = 12; 254c80476e4SDavid E. O'Brien } /* else do a 24 hour clock */ 255c80476e4SDavid E. O'Brien 256c80476e4SDavid E. O'Brien /* "DING!" stuff by Hans also */ 257c80476e4SDavid E. O'Brien if (t->tm_min || print_prompt_did_ding || 258c80476e4SDavid E. O'Brien what != FMT_PROMPT || adrof(STRnoding)) { 259c80476e4SDavid E. O'Brien if (t->tm_min) 260c80476e4SDavid E. O'Brien print_prompt_did_ding = 0; 26145e5710bSMark Peek /* 26245e5710bSMark Peek * Pad hour to 2 characters if padhour is set, 26345e5710bSMark Peek * by ADAM David Alan Martin 26445e5710bSMark Peek */ 26545e5710bSMark Peek p = Itoa(hr, adrof(STRpadhour) ? 2 : 0, attributes); 26645e5710bSMark Peek Strbuf_append(&buf, p); 26745e5710bSMark Peek xfree(p); 26845e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 26945e5710bSMark Peek p = Itoa(t->tm_min, 2, attributes); 27045e5710bSMark Peek Strbuf_append(&buf, p); 27145e5710bSMark Peek xfree(p); 272c80476e4SDavid E. O'Brien if (*cp == 'p' || *cp == 'P') { 27345e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 27445e5710bSMark Peek p = Itoa(t->tm_sec, 2, attributes); 27545e5710bSMark Peek Strbuf_append(&buf, p); 27645e5710bSMark Peek xfree(p); 277c80476e4SDavid E. O'Brien } 278c80476e4SDavid E. O'Brien if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { 27945e5710bSMark Peek Strbuf_append1(&buf, attributes | ampm); 28045e5710bSMark Peek Strbuf_append1(&buf, attributes | 'm'); 281c80476e4SDavid E. O'Brien } 282c80476e4SDavid E. O'Brien } 283c80476e4SDavid E. O'Brien else { /* we need to ding */ 28445e5710bSMark Peek size_t i; 285c80476e4SDavid E. O'Brien 28645e5710bSMark Peek for (i = 0; STRDING[i] != 0; i++) 28745e5710bSMark Peek Strbuf_append1(&buf, attributes | STRDING[i]); 288c80476e4SDavid E. O'Brien print_prompt_did_ding = 1; 289c80476e4SDavid E. O'Brien } 290c80476e4SDavid E. O'Brien } 291c80476e4SDavid E. O'Brien break; 292c80476e4SDavid E. O'Brien 293c80476e4SDavid E. O'Brien case 'M': 294c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 295c80476e4SDavid E. O'Brien if (what == FMT_WHO) 29645e5710bSMark Peek cz = who_info(info, 'M'); 297c80476e4SDavid E. O'Brien else 298c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 29945e5710bSMark Peek cz = getenv("HOST"); 300c80476e4SDavid E. O'Brien /* 301c80476e4SDavid E. O'Brien * Bug pointed out by Laurent Dami <dami@cui.unige.ch>: don't 302c80476e4SDavid E. O'Brien * derefrence that NULL (if HOST is not set)... 303c80476e4SDavid E. O'Brien */ 304c80476e4SDavid E. O'Brien if (cz != NULL) 30545e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 30645e5710bSMark Peek if (what == FMT_WHO) 30745e5710bSMark Peek xfree(cz); 308c80476e4SDavid E. O'Brien break; 309c80476e4SDavid E. O'Brien 31045e5710bSMark Peek case 'm': { 31145e5710bSMark Peek char *scz = NULL; 312c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 313c80476e4SDavid E. O'Brien if (what == FMT_WHO) 31445e5710bSMark Peek scz = cz = who_info(info, 'm'); 315c80476e4SDavid E. O'Brien else 316c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 31745e5710bSMark Peek cz = getenv("HOST"); 318c80476e4SDavid E. O'Brien 319c80476e4SDavid E. O'Brien if (cz != NULL) 32045e5710bSMark Peek while (*cz != 0 && (what == FMT_WHO || *cz != '.')) { 32145e5710bSMark Peek Char wc; 32245e5710bSMark Peek 32345e5710bSMark Peek cz += one_mbtowc(&wc, cz, MB_LEN_MAX); 32445e5710bSMark Peek Strbuf_append1(&buf, wc | attributes); 32523338178SMark Peek } 32645e5710bSMark Peek if (scz) 32745e5710bSMark Peek xfree(scz); 328c80476e4SDavid E. O'Brien break; 32945e5710bSMark Peek } 330c80476e4SDavid E. O'Brien 331c80476e4SDavid E. O'Brien /* lukem: new directory prompt code */ 332c80476e4SDavid E. O'Brien case '~': 333c80476e4SDavid E. O'Brien case '/': 334c80476e4SDavid E. O'Brien case '.': 335c80476e4SDavid E. O'Brien case 'c': 336c80476e4SDavid E. O'Brien case 'C': 337c80476e4SDavid E. O'Brien Scp = *cp; 338c80476e4SDavid E. O'Brien if (Scp == 'c') /* store format type (c == .) */ 339c80476e4SDavid E. O'Brien Scp = '.'; 340c80476e4SDavid E. O'Brien if ((z = varval(STRcwd)) == STRNULL) 341c80476e4SDavid E. O'Brien break; /* no cwd, so don't do anything */ 342c80476e4SDavid E. O'Brien 343c80476e4SDavid E. O'Brien /* show ~ whenever possible - a la dirs */ 344c80476e4SDavid E. O'Brien if (Scp == '~' || Scp == '.' ) { 34545e5710bSMark Peek static Char *olddir = NULL; 34645e5710bSMark Peek 347c80476e4SDavid E. O'Brien if (tlength == 0 || olddir != z) { 348c80476e4SDavid E. O'Brien olddir = z; /* have we changed dir? */ 349c80476e4SDavid E. O'Brien olduser = getusername(&olddir); 350c80476e4SDavid E. O'Brien } 351c80476e4SDavid E. O'Brien if (olduser) 352c80476e4SDavid E. O'Brien z = olddir; 353c80476e4SDavid E. O'Brien } 354c80476e4SDavid E. O'Brien updirs = pdirs = 0; 355c80476e4SDavid E. O'Brien 356c80476e4SDavid E. O'Brien /* option to determine fixed # of dirs from path */ 357c80476e4SDavid E. O'Brien if (Scp == '.' || Scp == 'C') { 358c80476e4SDavid E. O'Brien int skip; 3593b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 36023338178SMark Peek Char *oldz = z; 361c80476e4SDavid E. O'Brien if (z[1] == ':') { 36245e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 36345e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 364c80476e4SDavid E. O'Brien } 365c80476e4SDavid E. O'Brien if (*z == '/' && z[1] == '/') { 36645e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 36745e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 368c80476e4SDavid E. O'Brien do { 36945e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 370c80476e4SDavid E. O'Brien } while(*z != '/'); 371c80476e4SDavid E. O'Brien } 3723b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 373c80476e4SDavid E. O'Brien q = z; 374c80476e4SDavid E. O'Brien while (*z) /* calc # of /'s */ 375c80476e4SDavid E. O'Brien if (*z++ == '/') 376c80476e4SDavid E. O'Brien updirs++; 37723338178SMark Peek 37823338178SMark Peek #ifdef WINNT_NATIVE 37923338178SMark Peek /* 38023338178SMark Peek * for format type c, prompt will be following... 38123338178SMark Peek * c:/path => c:/path 38223338178SMark Peek * c:/path/to => c:to 38323338178SMark Peek * //machine/share => //machine/share 38423338178SMark Peek * //machine/share/folder => //machine:folder 38523338178SMark Peek */ 38623338178SMark Peek if (oldz[0] == '/' && oldz[1] == '/' && updirs > 1) 38745e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 38823338178SMark Peek #endif /* WINNT_NATIVE */ 389c80476e4SDavid E. O'Brien if ((Scp == 'C' && *q != '/')) 390c80476e4SDavid E. O'Brien updirs++; 391c80476e4SDavid E. O'Brien 392c80476e4SDavid E. O'Brien if (cp[1] == '0') { /* print <x> or ... */ 393c80476e4SDavid E. O'Brien pdirs = 1; 394c80476e4SDavid E. O'Brien cp++; 395c80476e4SDavid E. O'Brien } 396c80476e4SDavid E. O'Brien if (cp[1] >= '1' && cp[1] <= '9') { /* calc # to skip */ 397c80476e4SDavid E. O'Brien skip = cp[1] - '0'; 398c80476e4SDavid E. O'Brien cp++; 399c80476e4SDavid E. O'Brien } 400c80476e4SDavid E. O'Brien else 401c80476e4SDavid E. O'Brien skip = 1; 402c80476e4SDavid E. O'Brien 403c80476e4SDavid E. O'Brien updirs -= skip; 404c80476e4SDavid E. O'Brien while (skip-- > 0) { 405c80476e4SDavid E. O'Brien while ((z > q) && (*z != '/')) 406c80476e4SDavid E. O'Brien z--; /* back up */ 407c80476e4SDavid E. O'Brien if (skip && z > q) 408c80476e4SDavid E. O'Brien z--; 409c80476e4SDavid E. O'Brien } 410c80476e4SDavid E. O'Brien if (*z == '/' && z != q) 411c80476e4SDavid E. O'Brien z++; 412c80476e4SDavid E. O'Brien } /* . || C */ 413c80476e4SDavid E. O'Brien 414c80476e4SDavid E. O'Brien /* print ~[user] */ 415c80476e4SDavid E. O'Brien if ((olduser) && ((Scp == '~') || 416c80476e4SDavid E. O'Brien (Scp == '.' && (pdirs || (!pdirs && updirs <= 0))) )) { 41745e5710bSMark Peek Strbuf_append1(&buf, attributes | '~'); 41845e5710bSMark Peek for (q = olduser; *q; q++) 41945e5710bSMark Peek Strbuf_append1(&buf, attributes | *q); 420c80476e4SDavid E. O'Brien } 421c80476e4SDavid E. O'Brien 422c80476e4SDavid E. O'Brien /* RWM - tell you how many dirs we've ignored */ 423c80476e4SDavid E. O'Brien /* and add '/' at front of this */ 424c80476e4SDavid E. O'Brien if (updirs > 0 && pdirs) { 425c80476e4SDavid E. O'Brien if (adrof(STRellipsis)) { 42645e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 42745e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 42845e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 429c80476e4SDavid E. O'Brien } else { 43045e5710bSMark Peek Strbuf_append1(&buf, attributes | '/'); 43145e5710bSMark Peek Strbuf_append1(&buf, attributes | '<'); 432c80476e4SDavid E. O'Brien if (updirs > 9) { 43345e5710bSMark Peek Strbuf_append1(&buf, attributes | '9'); 43445e5710bSMark Peek Strbuf_append1(&buf, attributes | '+'); 435c80476e4SDavid E. O'Brien } else 43645e5710bSMark Peek Strbuf_append1(&buf, attributes | ('0' + updirs)); 43745e5710bSMark Peek Strbuf_append1(&buf, attributes | '>'); 438c80476e4SDavid E. O'Brien } 439c80476e4SDavid E. O'Brien } 440c80476e4SDavid E. O'Brien 44145e5710bSMark Peek while (*z) 44245e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 443c80476e4SDavid E. O'Brien break; 444c80476e4SDavid E. O'Brien /* lukem: end of new directory prompt code */ 445c80476e4SDavid E. O'Brien 446c80476e4SDavid E. O'Brien case 'n': 447c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 448c80476e4SDavid E. O'Brien if (what == FMT_WHO) { 44945e5710bSMark Peek cz = who_info(info, 'n'); 45045e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 45145e5710bSMark Peek xfree(cz); 452c80476e4SDavid E. O'Brien } 453c80476e4SDavid E. O'Brien else 454c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 455c80476e4SDavid E. O'Brien { 456c80476e4SDavid E. O'Brien if ((z = varval(STRuser)) != STRNULL) 45745e5710bSMark Peek while (*z) 45845e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 459c80476e4SDavid E. O'Brien } 460c80476e4SDavid E. O'Brien break; 461c80476e4SDavid E. O'Brien case 'l': 462c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 463c80476e4SDavid E. O'Brien if (what == FMT_WHO) { 46445e5710bSMark Peek cz = who_info(info, 'l'); 46545e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 46645e5710bSMark Peek xfree(cz); 467c80476e4SDavid E. O'Brien } 468c80476e4SDavid E. O'Brien else 469c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 470c80476e4SDavid E. O'Brien { 471c80476e4SDavid E. O'Brien if ((z = varval(STRtty)) != STRNULL) 47245e5710bSMark Peek while (*z) 47345e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 474c80476e4SDavid E. O'Brien } 475c80476e4SDavid E. O'Brien break; 476c80476e4SDavid E. O'Brien case 'd': 47745e5710bSMark Peek tprintf_append_mbs(&buf, day_list[t->tm_wday], attributes); 478c80476e4SDavid E. O'Brien break; 479c80476e4SDavid E. O'Brien case 'D': 48045e5710bSMark Peek p = Itoa(t->tm_mday, 2, attributes); 48145e5710bSMark Peek Strbuf_append(&buf, p); 48245e5710bSMark Peek xfree(p); 483c80476e4SDavid E. O'Brien break; 484c80476e4SDavid E. O'Brien case 'w': 48545e5710bSMark Peek tprintf_append_mbs(&buf, month_list[t->tm_mon], attributes); 486c80476e4SDavid E. O'Brien break; 487c80476e4SDavid E. O'Brien case 'W': 48845e5710bSMark Peek p = Itoa(t->tm_mon + 1, 2, attributes); 48945e5710bSMark Peek Strbuf_append(&buf, p); 49045e5710bSMark Peek xfree(p); 491c80476e4SDavid E. O'Brien break; 492c80476e4SDavid E. O'Brien case 'y': 49345e5710bSMark Peek p = Itoa(t->tm_year % 100, 2, attributes); 49445e5710bSMark Peek Strbuf_append(&buf, p); 49545e5710bSMark Peek xfree(p); 496c80476e4SDavid E. O'Brien break; 497c80476e4SDavid E. O'Brien case 'Y': 49845e5710bSMark Peek p = Itoa(t->tm_year + 1900, 4, attributes); 49945e5710bSMark Peek Strbuf_append(&buf, p); 50045e5710bSMark Peek xfree(p); 501c80476e4SDavid E. O'Brien break; 502c80476e4SDavid E. O'Brien case 'S': /* start standout */ 503c80476e4SDavid E. O'Brien attributes |= STANDOUT; 504c80476e4SDavid E. O'Brien break; 505c80476e4SDavid E. O'Brien case 'B': /* start bold */ 506c80476e4SDavid E. O'Brien attributes |= BOLD; 507c80476e4SDavid E. O'Brien break; 508c80476e4SDavid E. O'Brien case 'U': /* start underline */ 509c80476e4SDavid E. O'Brien attributes |= UNDER; 510c80476e4SDavid E. O'Brien break; 511c80476e4SDavid E. O'Brien case 's': /* end standout */ 512c80476e4SDavid E. O'Brien attributes &= ~STANDOUT; 513c80476e4SDavid E. O'Brien break; 514c80476e4SDavid E. O'Brien case 'b': /* end bold */ 515c80476e4SDavid E. O'Brien attributes &= ~BOLD; 516c80476e4SDavid E. O'Brien break; 517c80476e4SDavid E. O'Brien case 'u': /* end underline */ 518c80476e4SDavid E. O'Brien attributes &= ~UNDER; 519c80476e4SDavid E. O'Brien break; 520c80476e4SDavid E. O'Brien case 'L': 521c80476e4SDavid E. O'Brien ClearToBottom(); 522c80476e4SDavid E. O'Brien break; 52329301572SMark Peek 52429301572SMark Peek case 'j': 52529301572SMark Peek { 52629301572SMark Peek int njobs = -1; 52729301572SMark Peek struct process *pp; 52845e5710bSMark Peek 52929301572SMark Peek for (pp = proclist.p_next; pp; pp = pp->p_next) 53029301572SMark Peek njobs++; 53145e5710bSMark Peek p = Itoa(njobs, 1, attributes); 53245e5710bSMark Peek Strbuf_append(&buf, p); 53345e5710bSMark Peek xfree(p); 53429301572SMark Peek break; 53529301572SMark Peek } 536c80476e4SDavid E. O'Brien case '?': 537c80476e4SDavid E. O'Brien if ((z = varval(STRstatus)) != STRNULL) 53845e5710bSMark Peek while (*z) 53945e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 540c80476e4SDavid E. O'Brien break; 541c80476e4SDavid E. O'Brien case '$': 54245e5710bSMark Peek expdollar(&buf, &cp, attributes); 54345e5710bSMark Peek /* cp should point the last char of current % sequence */ 54429301572SMark Peek cp--; 545c80476e4SDavid E. O'Brien break; 546c80476e4SDavid E. O'Brien case '%': 54745e5710bSMark Peek Strbuf_append1(&buf, attributes | '%'); 548c80476e4SDavid E. O'Brien break; 549c80476e4SDavid E. O'Brien case '{': /* literal characters start */ 550c80476e4SDavid E. O'Brien #if LITERAL == 0 551c80476e4SDavid E. O'Brien /* 552c80476e4SDavid E. O'Brien * No literal capability, so skip all chars in the literal 553c80476e4SDavid E. O'Brien * string 554c80476e4SDavid E. O'Brien */ 55545e5710bSMark Peek while (*cp != '\0' && (cp[-1] != '%' || *cp != '}')) 556c80476e4SDavid E. O'Brien cp++; 557c80476e4SDavid E. O'Brien #endif /* LITERAL == 0 */ 558c80476e4SDavid E. O'Brien attributes |= LITERAL; 559c80476e4SDavid E. O'Brien break; 560c80476e4SDavid E. O'Brien case '}': /* literal characters end */ 561c80476e4SDavid E. O'Brien attributes &= ~LITERAL; 562c80476e4SDavid E. O'Brien break; 563c80476e4SDavid E. O'Brien default: 564c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 565c80476e4SDavid E. O'Brien if (*cp == 'a' && what == FMT_WHO) { 56645e5710bSMark Peek cz = who_info(info, 'a'); 56745e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 56845e5710bSMark Peek xfree(cz); 569c80476e4SDavid E. O'Brien } 570c80476e4SDavid E. O'Brien else 571c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 572c80476e4SDavid E. O'Brien { 57345e5710bSMark Peek Strbuf_append1(&buf, attributes | '%'); 57445e5710bSMark Peek Strbuf_append1(&buf, attributes | *cp); 575c80476e4SDavid E. O'Brien } 576c80476e4SDavid E. O'Brien break; 577c80476e4SDavid E. O'Brien } 578c80476e4SDavid E. O'Brien } 579c80476e4SDavid E. O'Brien else if (*cp == '\\' || *cp == '^') 58045e5710bSMark Peek Strbuf_append1(&buf, attributes | parseescape(&cp)); 581c80476e4SDavid E. O'Brien else if (*cp == HIST) { /* EGS: handle '!'s in prompts */ 582c80476e4SDavid E. O'Brien if (what == FMT_HISTORY) 58345e5710bSMark Peek cz = fmthist('h', info); 584c80476e4SDavid E. O'Brien else 58545e5710bSMark Peek cz = xasprintf("%d", eventno + 1); 58645e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 58745e5710bSMark Peek xfree(cz); 588c80476e4SDavid E. O'Brien } 589c80476e4SDavid E. O'Brien else 59045e5710bSMark Peek Strbuf_append1(&buf, attributes | *cp); /* normal character */ 591c80476e4SDavid E. O'Brien } 59245e5710bSMark Peek cleanup_ignore(&buf); 59345e5710bSMark Peek cleanup_until(&buf); 59445e5710bSMark Peek return Strbuf_finish(&buf); 595c80476e4SDavid E. O'Brien } 596c80476e4SDavid E. O'Brien 59745e5710bSMark Peek int 59845e5710bSMark Peek expdollar(struct Strbuf *buf, const Char **srcp, Char attr) 599c80476e4SDavid E. O'Brien { 600c80476e4SDavid E. O'Brien struct varent *vp; 601c80476e4SDavid E. O'Brien const Char *src = *srcp; 60245e5710bSMark Peek Char *var, *val; 60345e5710bSMark Peek size_t i; 60445e5710bSMark Peek int curly = 0; 605c80476e4SDavid E. O'Brien 606c80476e4SDavid E. O'Brien /* found a variable, expand it */ 60745e5710bSMark Peek var = xmalloc((Strlen(src) + 1) * sizeof (*var)); 60845e5710bSMark Peek for (i = 0; ; i++) { 609c80476e4SDavid E. O'Brien var[i] = *++src & TRIM; 610c80476e4SDavid E. O'Brien if (i == 0 && var[i] == '{') { 611c80476e4SDavid E. O'Brien curly = 1; 612c80476e4SDavid E. O'Brien var[i] = *++src & TRIM; 613c80476e4SDavid E. O'Brien } 61445e5710bSMark Peek if (!alnum(var[i]) && var[i] != '_') { 615c80476e4SDavid E. O'Brien 616c80476e4SDavid E. O'Brien var[i] = '\0'; 617c80476e4SDavid E. O'Brien break; 618c80476e4SDavid E. O'Brien } 619c80476e4SDavid E. O'Brien } 620c80476e4SDavid E. O'Brien if (curly && (*src & TRIM) == '}') 621c80476e4SDavid E. O'Brien src++; 622c80476e4SDavid E. O'Brien 623c80476e4SDavid E. O'Brien vp = adrof(var); 62429301572SMark Peek if (vp && vp->vec) { 625c80476e4SDavid E. O'Brien for (i = 0; vp->vec[i] != NULL; i++) { 62645e5710bSMark Peek for (val = vp->vec[i]; *val; val++) 62745e5710bSMark Peek if (*val != '\n' && *val != '\r') 62845e5710bSMark Peek Strbuf_append1(buf, *val | attr); 62945e5710bSMark Peek if (vp->vec[i+1]) 63045e5710bSMark Peek Strbuf_append1(buf, ' ' | attr); 631c80476e4SDavid E. O'Brien } 632c80476e4SDavid E. O'Brien } 633c80476e4SDavid E. O'Brien else { 63445e5710bSMark Peek val = (!vp) ? tgetenv(var) : NULL; 63545e5710bSMark Peek if (val) { 63645e5710bSMark Peek for (; *val; val++) 63745e5710bSMark Peek if (*val != '\n' && *val != '\r') 63845e5710bSMark Peek Strbuf_append1(buf, *val | attr); 63945e5710bSMark Peek } else { 640c80476e4SDavid E. O'Brien *srcp = src; 64145e5710bSMark Peek xfree(var); 64245e5710bSMark Peek return 0; 643c80476e4SDavid E. O'Brien } 64445e5710bSMark Peek } 645c80476e4SDavid E. O'Brien 646c80476e4SDavid E. O'Brien *srcp = src; 64745e5710bSMark Peek xfree(var); 64845e5710bSMark Peek return 1; 649c80476e4SDavid E. O'Brien } 650