int pprompt(const char *cp, int ntruncate) { char delimiter = 0; bool doprint = (ntruncate != -1); bool indelimit = false; int columns = 0, lines = 0; /* * Undocumented AT&T ksh feature: * If the second char in the prompt string is \r then the first * char is taken to be a non-printing delimiter and any chars * between two instances of the delimiter are not considered to * be part of the prompt length */ if (*cp && cp[1] == '\r') { delimiter = *cp; cp += 2; } for (; *cp; cp++) { if (indelimit && *cp != delimiter) ; else if (*cp == '\n' || *cp == '\r') { lines += columns / x_cols + ((*cp == '\n') ? 1 : 0); columns = 0; } else if (*cp == '\t') { columns = (columns | 7) + 1; } else if (*cp == '\b') { if (columns > 0) columns--; } else if (*cp == delimiter) indelimit = !indelimit; else if (UTFMODE && ((unsigned char)*cp > 0x7F)) { const char *cp2; columns += utf_widthadj(cp, &cp2); if (doprint && (indelimit || (ntruncate < (x_cols * lines + columns)))) shf_write(cp, cp2 - cp, shl_out); cp = cp2 - /* loop increment */ 1; continue; } else columns++; if (doprint && (*cp != delimiter) && (indelimit || (ntruncate < (x_cols * lines + columns)))) shf_putc(*cp, shl_out); } if (doprint) shf_flush(shl_out); return (x_cols * lines + columns); }
static char * formatstr(struct tbl *vp, const char *s) { int olen, nlen; char *p, *q; size_t psiz; olen = (int)utf_mbswidth(s); if (vp->flag & (RJUST|LJUST)) { if (!vp->u2.field) /* default field width */ vp->u2.field = olen; nlen = vp->u2.field; } else nlen = olen; p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP); if (vp->flag & (RJUST|LJUST)) { int slen = olen, i = 0; if (vp->flag & RJUST) { const char *qq = s; int n = 0; while (i < slen) i += utf_widthadj(qq, &qq); /* strip trailing spaces (AT&T uses qq[-1] == ' ') */ while (qq > s && ksh_isspace(qq[-1])) { --qq; --slen; } if (vp->flag & ZEROFIL && vp->flag & INTEGER) { if (!s[0] || !s[1]) goto uhm_no; if (s[1] == '#') n = 2; else if (s[2] == '#') n = 3; uhm_no: if (vp->u2.field <= n) n = 0; } if (n) { memcpy(p, s, n); s += n; } while (slen > vp->u2.field) slen -= utf_widthadj(s, &s); if (vp->u2.field - slen) memset(p + n, (vp->flag & ZEROFIL) ? '0' : ' ', vp->u2.field - slen); slen -= n; shf_snprintf(p + vp->u2.field - slen, psiz - (vp->u2.field - slen), "%.*s", slen, s); } else { /* strip leading spaces/zeros */ while (ksh_isspace(*s)) s++; if (vp->flag & ZEROFIL) while (*s == '0') s++; shf_snprintf(p, nlen + 1, "%-*.*s", vp->u2.field, vp->u2.field, s); } } else memcpy(p, s, strlen(s) + 1); if (vp->flag & UCASEV_AL) { for (q = p; *q; q++) *q = ksh_toupper(*q); } else if (vp->flag & LCASEV) { for (q = p; *q; q++) *q = ksh_tolower(*q); } return (p); }