static void unparsech(struct Strbuf *buf, Char ch) { if (ch == 0) { Strbuf_append1(buf, '^'); Strbuf_append1(buf, '@'); } else if (Iscntrl(ch)) { Strbuf_append1(buf, '^'); if (ch == CTL_ESC('\177')) Strbuf_append1(buf, '?'); else #ifdef IS_ASCII Strbuf_append1(buf, ch | 0100); #else Strbuf_append1(buf, _toebcdic[_toascii[ch]|0100]); #endif } else if (ch == '^') { Strbuf_append1(buf, '\\'); Strbuf_append1(buf, '^'); } else if (ch == '\\') { Strbuf_append1(buf, '\\'); Strbuf_append1(buf, '\\'); } else if (ch == ' ' || (Isprint(ch) && !Isspace(ch))) { Strbuf_append1(buf, ch); } else { Strbuf_append1(buf, '\\'); Strbuf_append1(buf, ((ch >> 6) & 7) + '0'); Strbuf_append1(buf, ((ch >> 3) & 7) + '0'); Strbuf_append1(buf, (ch & 7) + '0'); } }
static void dprintstr(char *str, const Char *f, const Char *t) { dprintf("%s:\"", str); while (f < t) { if (ASC(*f) & ~ASCII) dprintf("[%x]", *f++); else dprintf("%c", CTL_ESC(ASCII & ASC(*f++))); } dprintf("\"\r\n"); }
unsigned char * unparsestring(const CStr *str, const Char *sep) { unsigned char *buf, *b; Char p; int l; /* Worst-case is "\uuu" or result of wctomb() for each char from str */ buf = xmalloc((str->len + 1) * max(4, MB_LEN_MAX)); b = buf; if (sep[0]) #ifndef WINNT_NATIVE *b++ = sep[0]; #else /* WINNT_NATIVE */ *b++ = CHAR & sep[0]; #endif /* !WINNT_NATIVE */ for (l = 0; l < str->len; l++) { p = str->buf[l]; if (Iscntrl(p)) { *b++ = '^'; if (p == CTL_ESC('\177')) *b++ = '?'; else #ifdef IS_ASCII *b++ = (unsigned char) (p | 0100); #else *b++ = _toebcdic[_toascii[p]|0100]; #endif } else if (p == '^' || p == '\\') { *b++ = '\\'; *b++ = (unsigned char) p; } else if (p == ' ' || (Isprint(p) && !Isspace(p))) b += one_wctomb((char *)b, p & CHAR); else { *b++ = '\\'; *b++ = ((p >> 6) & 7) + '0'; *b++ = ((p >> 3) & 7) + '0'; *b++ = (p & 7) + '0'; } } if (sep[0] && sep[1]) #ifndef WINNT_NATIVE *b++ = sep[1]; #else /* WINNT_NATIVE */ *b++ = CHAR & sep[1]; #endif /* !WINNT_NATIVE */ *b++ = 0; return buf; /* should check for overflow */ }
static int Draw(Char *cp, int nocomb) /* draw char at cp, expand tabs, ctl chars */ { int w, i, lv, lh; Char c, attr; attr = *cp & ~CHAR; c = *cp & CHAR; w = NLSClassify(c, nocomb); switch (w) { case NLSCLASS_NL: Vdraw('\0', 0); /* assure end of line */ vcursor_h = 0; /* reset cursor pos */ vcursor_v++; break; case NLSCLASS_TAB: do { Vdraw(' ', 1); } while ((vcursor_h & 07) != 0); break; case NLSCLASS_CTRL: Vdraw('^' | attr, 1); if (c == CTL_ESC('\177')) { Vdraw('?' | attr, 1); } else { #ifdef IS_ASCII /* uncontrolify it; works only for iso8859-1 like sets */ Vdraw(c | 0100 | attr, 1); #else Vdraw(_toebcdic[_toascii[c]|0100] | attr, 1); #endif } break; case NLSCLASS_ILLEGAL: Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; case NLSCLASS_ILLEGAL2: case NLSCLASS_ILLEGAL3: case NLSCLASS_ILLEGAL4: Vdraw('\\' | attr, 1); Vdraw('U' | attr, 1); Vdraw('+' | attr, 1); for (i = 8 * NLSCLASS_ILLEGAL_SIZE(w) - 4; i >= 0; i -= 4) Vdraw("0123456789ABCDEF"[(c >> i) & 15] | attr, 1); break; case 0: lv = vcursor_v; lh = vcursor_h; for (;;) { lh--; if (lh < 0) { lv--; if (lv < 0) break; lh = Strlen(Vdisplay[lv]) - 1; } if (Vdisplay[lv][lh] != CHAR_DBWIDTH) break; } if (lv < 0) { Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; } Vdisplay[lv][lh] = MakeLiteral(cp, 1, Vdisplay[lv][lh]); break; default: Vdraw(*cp, w); break; }
eChar parseescape(const Char **ptr) { const Char *p; Char c; p = *ptr; if ((p[1] & CHAR) == 0) { xprintf(CGETS(9, 8, "Something must follow: %c\n"), (char)*p); return CHAR_ERR; } if ((*p & CHAR) == '\\') { p++; switch (*p & CHAR) { case 'a': c = CTL_ESC('\007'); /* Bell */ break; case 'b': c = CTL_ESC('\010'); /* Backspace */ break; case 'e': c = CTL_ESC('\033'); /* Escape */ break; case 'f': c = CTL_ESC('\014'); /* Form Feed */ break; case 'n': c = CTL_ESC('\012'); /* New Line */ break; case 'r': c = CTL_ESC('\015'); /* Carriage Return */ break; case 't': c = CTL_ESC('\011'); /* Horizontal Tab */ break; case 'v': c = CTL_ESC('\013'); /* Vertical Tab */ break; case '\\': c = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int cnt, val; Char ch; for (cnt = 0, val = 0; cnt < 3; cnt++) { ch = *p++ & CHAR; if (ch < '0' || ch > '7') { p--; break; } val = (val << 3) | (ch - '0'); } if ((val & ~0xff) != 0) { xprintf("%s", CGETS(9, 9, "Octal constant does not fit in a char.\n")); return 0; } #ifndef IS_ASCII if (CTL_ESC(val) != val && adrof(STRwarnebcdic)) xprintf(/*CGETS(9, 9, no NLS-String yet!*/ "Warning: Octal constant \\%3.3o is interpreted as EBCDIC value.\n", val/*)*/); #endif c = (Char) val; --p; } break; default: c = *p; break; } } else if ((*p & CHAR) == '^' && (Isalpha(p[1] & CHAR) || strchr("@^_?\\|[{]}", p[1] & CHAR))) { p++; #ifdef IS_ASCII c = ((*p & CHAR) == '?') ? CTL_ESC('\177') : ((*p & CHAR) & 0237); #else c = ((*p & CHAR) == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*p & CHAR] & 0237]; if (adrof(STRwarnebcdic)) xprintf(/*CGETS(9, 9, no NLS-String yet!*/ "Warning: Control character ^%c may be interpreted differently in EBCDIC.\n", *p & CHAR /*)*/); #endif } else c = *p; *ptr = p; return (c); }
/* draw char at cp, expand tabs, ctl chars */ static int Draw(Char *cp, int nocomb, int drawPrompt) { int w, i, lv, lh; Char c, attr; #ifdef WIDE_STRINGS if (!drawPrompt) { /* draw command-line */ attr = 0; c = *cp; } else { /* draw prompt */ /* prompt with attributes(UNDER,BOLD,STANDOUT) */ if (*cp & (UNDER | BOLD | STANDOUT)) { /* *cp >= STANDOUT */ /* example) * We can't distinguish whether (*cp=)0x02ffffff is * U+02FFFFFF or U+00FFFFFF|STANDOUT. * We handle as U+00FFFFFF|STANDOUT, only when drawing prompt. */ attr = (*cp & ATTRIBUTES); /* ~(UNDER | BOLD | STANDOUT) = 0xf1ffffff */ c = *cp & ~(UNDER | BOLD | STANDOUT); /* if c is ctrl code, we handle *cp as havnig no attributes */ if ((c < 0x20 && c >= 0) || c == 0x7f) { attr = 0; c = *cp; } } else { /* prompt without attributes */ attr = 0; c = *cp; } } #else attr = *cp & ~CHAR; c = *cp & CHAR; #endif w = NLSClassify(c, nocomb, drawPrompt); switch (w) { case NLSCLASS_NL: Vdraw('\0', 0); /* assure end of line */ vcursor_h = 0; /* reset cursor pos */ vcursor_v++; break; case NLSCLASS_TAB: do { Vdraw(' ', 1); } while ((vcursor_h & 07) != 0); break; case NLSCLASS_CTRL: Vdraw('^' | attr, 1); if (c == CTL_ESC('\177')) { Vdraw('?' | attr, 1); } else { #ifdef IS_ASCII /* uncontrolify it; works only for iso8859-1 like sets */ Vdraw(c | 0100 | attr, 1); #else Vdraw(_toebcdic[_toascii[c]|0100] | attr, 1); #endif } break; case NLSCLASS_ILLEGAL: Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; case NLSCLASS_ILLEGAL2: case NLSCLASS_ILLEGAL3: case NLSCLASS_ILLEGAL4: case NLSCLASS_ILLEGAL5: Vdraw('\\', 1); Vdraw('U', 1); Vdraw('+', 1); for (i = 16 + 4 * (-w-5); i >= 0; i -= 4) Vdraw("0123456789ABCDEF"[(c >> i) & 15] | attr, 1); break; case 0: lv = vcursor_v; lh = vcursor_h; for (;;) { lh--; if (lh < 0) { lv--; if (lv < 0) break; lh = Strlen(Vdisplay[lv]) - 1; } if (Vdisplay[lv][lh] != CHAR_DBWIDTH) break; } if (lv < 0) { Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; } Vdisplay[lv][lh] = MakeLiteral(cp, 1, Vdisplay[lv][lh]); break; default: Vdraw(*cp, w); break; }
int /*ARGSUSED*/ setdisc(int f) { #ifdef IRIS4D # ifndef POSIX struct termio termiob; # else struct termios termiob; # endif if (ioctl(f, TCGETA, (ioctl_t) & termiob) == 0) { otermiob = termiob; #if (SYSVREL < 4) || !defined(IRIS4D) if (termiob.c_line != NTTYDISC || termiob.c_cc[VSWTCH] == 0) { /*}*/ termiob.c_line = NTTYDISC; #else if (termiob.c_cc[VSWTCH] == 0) { #endif termiob.c_cc[VSWTCH] = CSWTCH; if (ioctl(f, TCSETA, (ioctl_t) & termiob) != 0) return (-1); } } else return (-1); add_discipline = 1; return (0); #endif /* IRIS4D */ #ifdef OREO # ifndef POSIX struct termio termiob; # else struct termios termiob; # endif struct ltchars ltcbuf; if (ioctl(f, TCGETA, (ioctl_t) & termiob) == 0) { int comp = getcompat(COMPAT_BSDTTY); otermiob = termiob; if ((comp & COMPAT_BSDTTY) != COMPAT_BSDTTY) { (void) setcompat(comp | COMPAT_BSDTTY); if (ioctl(f, TIOCGLTC, (ioctl_t) & ltcbuf) != 0) xprintf(CGETS(21, 1, "Couldn't get local chars.\n")); else { ltcbuf.t_suspc = CTL_ESC('\032'); /* ^Z */ ltcbuf.t_dsuspc = CTL_ESC('\031'); /* ^Y */ ltcbuf.t_rprntc = CTL_ESC('\022'); /* ^R */ ltcbuf.t_flushc = CTL_ESC('\017'); /* ^O */ ltcbuf.t_werasc = CTL_ESC('\027'); /* ^W */ ltcbuf.t_lnextc = CTL_ESC('\026'); /* ^V */ if (ioctl(f, TIOCSLTC, (ioctl_t) & ltcbuf) != 0) xprintf(CGETS(21, 2, "Couldn't set local chars.\n")); } termiob.c_cc[VSWTCH] = '\0'; if (ioctl(f, TCSETAF, (ioctl_t) & termiob) != 0) return (-1); } } else return (-1); add_discipline = 1; return (0); #endif /* OREO */ #ifdef _IBMR2 union txname tx; tx.tx_which = 0; if (ioctl(f, TXGETLD, (ioctl_t) & tx) == 0) { if (strcmp(tx.tx_name, strPOSIX) != 0) if (ioctl(f, TXADDCD, (ioctl_t) strPOSIX) == 0) { add_discipline = 1; return (0); } return (0); } else return (-1); #endif /* _IBMR2 */ #ifndef HAVE_DISC # if defined(TIOCGETD) && defined(NTTYDISC) if (ioctl(f, TIOCGETD, (ioctl_t) & oldisc) == 0) { if (oldisc != NTTYDISC) { int ldisc = NTTYDISC; if (ioctl(f, TIOCSETD, (ioctl_t) & ldisc) != 0) return (-1); add_discipline = 1; } else oldisc = -1; return (0); } else return (-1); # else USE(f); return (0); # endif /* TIOCGETD && NTTYDISC */ #endif /* !HAVE_DISC */ } /* end setdisc */ int /*ARGSUSED*/ resetdisc(int f) { if (add_discipline) { add_discipline = 0; #if defined(OREO) || defined(IRIS4D) return (ioctl(f, TCSETAF, (ioctl_t) & otermiob)); #endif /* OREO || IRIS4D */ #ifdef _IBMR2 return (ioctl(f, TXDELCD, (ioctl_t) strPOSIX)); #endif /* _IBMR2 */ #ifndef HAVE_DISC # if defined(TIOCSETD) && defined(NTTYDISC) return (ioctl(f, TIOCSETD, (ioctl_t) & oldisc)); # endif /* TIOCSETD && NTTYDISC */ #endif /* !HAVE_DISC */ } USE(f); return (0); } /* end resetdisc */
/* * tgetstr - get the string capability corresponding to id and place * it in area (advancing area at same time). Expand escape sequences * etc. Returns the string, or NULL if it can't do it. */ char * tgetstr(char *id, char **area) { char *cp; char *ret; int i; if ((cp = capab) == NULL || id == NULL) return(NULL); while (*++cp != ':') ; for (++cp ; *cp ; cp++) { while (ISSPACE(*cp)) cp++; if (strncmp(cp, id, CAPABLEN) == 0) { while (*cp && *cp != ':' && *cp != '=') cp++; if (*cp != '=') return(NULL); for (ret = *area, cp++; *cp && *cp != ':' ; (*area)++, cp++) switch(*cp) { case '^' : **area = *++cp - '@'; /* fix (efth)*/ break; case '\\' : switch(*++cp) { case 'E' : **area = CTL_ESC('\033'); break; case 'n' : **area = '\n'; break; case 'r' : **area = '\r'; break; case 't' : **area = '\t'; break; case 'b' : **area = '\b'; break; case 'f' : **area = '\f'; break; case '0' : case '1' : case '2' : case '3' : for (i=0 ; *cp && ISDIGIT(*cp) ; cp++) i = i * 8 + *cp - '0'; **area = i; cp--; break; case '^' : case '\\' : **area = *cp; break; } break; default : **area = *cp; } *(*area)++ = '\0'; return(ret); } while (*cp && *cp != ':') cp++; } return(NULL); }