freebsd-src/lib/libmytinfo/tputs.c
1995-05-30 05:51:47 +00:00

267 lines
4.5 KiB
C

/*
* tputs.c
*
* By Ross Ridge
* Public Domain
* 92/06/04 11:41:15
*
* Output a terminal capability string with any needed padding
*
*/
#include "defs.h"
#include <term.h>
#include <ctype.h>
#ifdef USE_SCCS_IDS
static const char SCCSid[] = "@(#) mytinfo tputs.c 3.3 92/06/04 public domain, By Ross Ridge";
#endif
#ifdef TEST
#define def_prog_mode() (OK)
#define _norm_output() ((void)(0))
#define _lit_output() (1)
#endif
/*
* BITSPERCHAR (as actually transmitted over a serial line) is usually 10
* (not 8). 1 stop bit, 1 start bit, 7 data bits, and one parity bit.
*/
#define BITSPERCHAR 10
#ifdef USE_FAKE_STDIO
#undef putchar
#endif
#ifdef USE_PROTOTYPES
#define PUTCHAR(c) (outc == (int (*)(int)) NULL ? (putchar(c)):(*outc)(c))
#else
#define PUTCHAR(c) (outc == (int (*)()) NULL ? (putchar(c)):(*outc)(c))
#endif
int
tputs(sp, count, outc)
register const char *sp;
int count;
#ifdef USE_PROTOTYPES
register int (*outc)(int);
#else
register int (*outc)();
#endif
{
register int l;
register long cnt;
int must_pad, multiply_pad;
int forced_lit = 0;
/* some programmes expect this behaviour from tputs */
if (sp == NULL) {
#ifdef DEBUG
fprintf(stderr, "tputs: NULL\n");
#endif
return 0;
}
if (cur_term->termcap) {
_figure_termcap();
}
while(*sp != '\0') {
switch(*sp) {
case '\\':
switch(*++sp) {
case 'n': PUTCHAR('\n'); sp++; break;
case 'b': PUTCHAR('\b'); sp++; break;
case 't': PUTCHAR('\t'); sp++; break;
case 'r': PUTCHAR('\r'); sp++; break;
case 'f': PUTCHAR('\f'); sp++; break;
case 'l': PUTCHAR('\012'); sp++; break;
case 's': PUTCHAR(' '); sp++; break;
case 'e': case 'E': PUTCHAR('\033'); sp++; break;
case '^':
case '\\':
case ',':
case ':':
case '\'':
case '$':
PUTCHAR(*sp++);
break;
case '0':
if (*(sp + 1) < '0' || *(sp + 1) > '7') {
PUTCHAR('\200'); /* I'd prefer \0 */
sp++;
break;
}
;/* FALLTHROUGH */
case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
l = *sp++ - '0';
if (*sp >= '0' && *sp <= '7') {
l = l * 8 + (*sp++ - '0');
if (*sp >= '0' && *sp <= '7')
l = l * 8 + (*sp++ - '0');
}
PUTCHAR(l);
break;
case '\0':
PUTCHAR('\\');
break;
case '@':
if (!forced_lit)
forced_lit = _lit_output();
sp++;
break;
default:
PUTCHAR('\\');
PUTCHAR(*sp++);
break;
}
break;
case '^':
if (*++sp == '\0')
break;
l = *sp - '@';
if (l > 31)
l -= 32;
if (l < 0 || l > 31) {
PUTCHAR('^');
PUTCHAR(*sp++);
} else {
PUTCHAR(l);
sp++;
}
break;
case '$':
if (*++sp != '<') {
PUTCHAR('$');
break;
}
must_pad = 0;
multiply_pad = 0;
l = 0;
sp++;
while (isdigit(*sp))
l = l * 10 + (*sp++ - '0');
l *= 10;
if (*sp == '.') {
sp++;
if (isdigit(*sp))
l += *sp++ - '0';
}
if (*sp == '/') {
must_pad = 1;
if (*++sp == '*') {
multiply_pad = 1;
sp++;
}
} else if (*sp == '*') {
multiply_pad = 1;
if (*++sp == '/') {
must_pad = 1;
sp++;
}
}
if (*sp != '>') {
PUTCHAR('p');
PUTCHAR('a');
PUTCHAR('d');
PUTCHAR('?');
break;
}
sp++;
#ifdef TEST
printf("\nl = %d", l);
#endif
if (cur_term->pad || must_pad) {
cnt = ((long) l * cur_term->baudrate
* (multiply_pad ? count : 1)
+ (10000L * BITSPERCHAR / 2L))
/ (10000L * BITSPERCHAR);
#ifdef TEST
printf("; cnt = %ld\n", cnt);
#endif
while(cnt--)
PUTCHAR(cur_term->padch);
}
#ifdef TEST
printf("\n");
#endif
break;
default:
PUTCHAR(*sp++);
}
}
if (forced_lit)
_norm_output();
return OK;
}
int
putp(str)
char *str; {
#ifdef USE_PROTOTYPES
return(tputs(str, 1,(int (*)(int)) NULL));
#else
return(tputs(str, 1,(int (*)()) NULL));
#endif
}
#ifdef TEST
TERMINAL test_term, *cur_term = &test_term;
int
#ifdef USE_PROTOTYPES
putch(char c)
#else
putch(c)
char c;
#endif
{
if (c & 0x80) {
printf("\\%03o", c);
} else if (c < 32) {
printf("^%c", c + '@');
} else if (c == 127) {
printf("^?");
} else {
putchar(c);
}
return 0;
}
char line[MAX_LINE];
int
main(argc, argv)
int argc;
char **argv; {
test_term.termcap = 0;
test_term.baudrate = 1200;
test_term.pad = 0;
test_term.padch = 0;
if (argc > 1)
test_term.baudrate = atoi(argv[1]);
if (argc > 2)
test_term.padch = argv[2][0];
if (argc > 3)
test_term.pad = 1;
putchar('\n');
while(fgets(line, sizeof(line), stdin) != NULL) {
line[strlen(line)-1] = '\0';
tputs(line, 7, putch);
putchar('\n');
}
return 0;
}
#endif