int chrexp(register const char* s, char** p, int* m, register int flags) { register const char* q; register int c; const char* e; const char* b; char* r; int n; int w; w = 0; for (;;) { b = s; switch (c = mbchar(s)) { case 0: s--; break; case '\\': switch (c = *s++) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c -= '0'; q = s + 2; while (s < q) switch (*s) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c = (c << 3) + *s++ - '0'; break; default: q = s; break; } break; case 'a': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = CC_bel; break; case 'b': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = '\b'; break; case 'c': /*DEPRECATED*/ case 'C': if (!(flags & FMT_EXP_CHAR)) goto noexpand; if (c = *s) { s++; if (c == '\\') { c = chrexp(s - 1, &r, 0, flags); s = (const char*)r; } if (islower(c)) c = toupper(c); c = ccmapc(c, CC_NATIVE, CC_ASCII); c ^= 0x40; c = ccmapc(c, CC_ASCII, CC_NATIVE); } break; case 'e': /*DEPRECATED*/ case 'E': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = CC_esc; break; case 'f': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = '\f'; break; case 'M': if (!(flags & FMT_EXP_CHAR)) goto noexpand; if (*s == '-') { s++; c = CC_esc; } break; case 'n': if (flags & FMT_EXP_NONL) continue; if (!(flags & FMT_EXP_LINE)) goto noexpand; c = '\n'; break; case 'r': if (flags & FMT_EXP_NOCR) continue; if (!(flags & FMT_EXP_LINE)) goto noexpand; c = '\r'; break; case 't': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = '\t'; break; case 'v': if (!(flags & FMT_EXP_CHAR)) goto noexpand; c = CC_vt; break; case 'u': case 'U': case 'x': if (q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0) { if (!(flags & FMT_EXP_WIDE)) goto noexpand; w = 1; } b = e = s; n = 0; c = 0; while (!e || !q || s < q) { switch (*s) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': c = (c << 4) + *s++ - 'a' + 10; n++; continue; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': c = (c << 4) + *s++ - 'A' + 10; n++; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': c = (c << 4) + *s++ - '0'; n++; continue; case '{': case '[': if (s != e) break; e = 0; s++; continue; case '}': case ']': if (!e) s++; break; default: break; } break; } if (n <= 2 && !(flags & FMT_EXP_CHAR) || n > 2 && (w = 1) && !(flags & FMT_EXP_WIDE)) { c = '\\'; s = b; } break; case 0: s--; break; } break; default: if ((s - b) > 1) w = 1; break; } break; } normal: if (p) *p = (char*)s; if (m) *m = w; return c; noexpand: c = '\\'; s--; goto normal; }
static void output(struct termios *sp, int flags) { const Tty_t *tp; struct termios tty; register int delim = ' '; register int i,off,off2; char schar[2]; unsigned int ispeed = cfgetispeed(sp); unsigned int ospeed = cfgetospeed(sp); if(flags&G_FLAG) { gout(sp); return; } tty = *sp; sane(&tty); for(i=0; i < elementsof(Ttable); i++) { tp= &Ttable[i]; if(tp->flags&IG) { if(tp->flags&NL) sfputc(sfstdout,'\n'); continue; } switch(tp->type) { case BIT: case BITS: off = off2 = 1; switch(tp->field) { case C_FLAG: if(sp->c_cflag&tp->mask) off = 0; if(tty.c_cflag&tp->mask) off2 = 0; break; case I_FLAG: if(sp->c_iflag&tp->mask) off = 0; if(tty.c_iflag&tp->mask) off2 = 0; break; case O_FLAG: if((sp->c_oflag&tp->mask)==tp->val) off = 0; if(tty.c_oflag&tp->mask) off2 = 0; break; case L_FLAG: if(sp->c_lflag&tp->mask) off = 0; if(tty.c_lflag&tp->mask) off2 = 0; } if(tp->flags&NL) delim = '\n'; if(!flags && off==off2) continue; if(!off) sfprintf(sfstdout,"%s%c",tp->name,delim); else if(tp->type==BIT) sfprintf(sfstdout,"-%s%c",tp->name,delim); delim = ' '; break; case CHAR: off = sp->c_cc[tp->mask]; if(tp->flags&NL) delim = '\n'; if(!flags && off==(unsigned char)tty.c_cc[tp->mask]) continue; if(off==_POSIX_VDISABLE) sfprintf(sfstdout,"%s = <undef>;%c",tp->name,delim); else if(isprint(off&0xff)) sfprintf(sfstdout,"%s = %c;%c",tp->name,off,delim); else #if CC_NATIVE == CC_ASCII sfprintf(sfstdout,"%s = ^%c;%c",tp->name,off==0177?'?':(off^0100),delim); #else { off = ccmapc(off, CC_NATIVE, CC_ASCII); sfprintf(sfstdout,"%s = ^%c;%c",tp->name,off==0177?'?':ccmapc(off^0100,CC_ASCII,CC_NATIVE),delim); } #endif delim = ' '; break; case SIZE: if((sp->c_cflag&CSIZE)!=tp->mask) continue; if(flags || (sp->c_cflag&CSIZE) != (tty.c_cflag&CSIZE)) sfprintf(sfstdout,"%s ",tp->name); break; case SPEED: if(tp->mask==ispeed) { if(ispeed!=ospeed) schar[0]='i'; else schar[0]=0; } else if(tp->mask==ospeed) schar[0]='o'; else continue; schar[1] = 0; #ifdef TIOCSWINSZ { struct winsize win; off = ioctl(0,TIOCGWINSZ,&win); if(off>=0) sfprintf(sfstdout,"%sspeed %s baud; rows %d; columns %d;\n",schar,tp->name,win.ws_row,win.ws_col); } if(off<0) #endif sfprintf(sfstdout,"%sspeed %s baud;\n",schar,tp->name); } } if(delim=='\n') sfputc(sfstdout,'\n'); }