home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / mytinfo / part01 / tputs.c < prev    next >
C/C++ Source or Header  |  1992-12-26  |  4KB  |  249 lines

  1. /*
  2.  * tputs.c
  3.  *
  4.  * By Ross Ridge
  5.  * Public Domain
  6.  * 92/06/04 11:41:15
  7.  *
  8.  * Output a terminal capability string with any needed padding
  9.  *
  10.  */
  11.  
  12. #include "defs.h"
  13. #include "term.h"
  14.  
  15. #include <ctype.h>
  16.  
  17. #ifdef USE_SCCS_IDS
  18. static const char SCCSid[] = "@(#) mytinfo tputs.c 3.3 92/06/04 public domain, By Ross Ridge";
  19. #endif
  20.  
  21. #ifdef TEST
  22. #define def_prog_mode()    (OK)
  23. #define _norm_output()    ((void)(0))
  24. #define _lit_output()    (1)
  25. #endif
  26.  
  27. /*
  28.  * BITSPERCHAR (as actually transmitted over a serial line) is usually 10
  29.  * (not 8). 1 stop bit, 1 start bit, 7 data bits, and one parity bit.
  30.  */
  31.  
  32. #define BITSPERCHAR    10
  33.  
  34. #ifdef USE_FAKE_STDIO
  35. #undef putchar
  36. #endif
  37.  
  38. #define PUTCHAR(c) (outc == (int (*)()) 0 ? (putchar(c)):(*outc)(c))
  39.  
  40. int
  41. tputs(sp, count, outc)
  42. register char *sp;
  43. int count;
  44. register int (*outc)();
  45. {
  46.     register int l;
  47.     register long cnt;
  48.     int must_pad, multiply_pad;
  49.     int forced_lit = 0;
  50.  
  51.     /* some programmes expect this behaviour from tputs */
  52.     if (sp == NULL) {
  53. #ifdef DEBUG
  54.         fprintf(stderr, "tputs: NULL\n");    
  55. #endif
  56.         return 0;
  57.     }
  58.  
  59.     if (cur_term->termcap) {
  60.         _figure_termcap();
  61.     }
  62.  
  63.     while(*sp != '\0') {
  64.         switch(*sp) {
  65.         case '\\':
  66.             switch(*++sp) {
  67.             case 'n': PUTCHAR('\n'); sp++; break;
  68.             case 'b': PUTCHAR('\b'); sp++; break;
  69.             case 't': PUTCHAR('\t'); sp++; break;
  70.             case 'r': PUTCHAR('\r'); sp++; break;
  71.             case 'f': PUTCHAR('\f'); sp++; break;
  72.             case 'l': PUTCHAR('\012'); sp++; break;
  73.             case 's': PUTCHAR(' '); sp++; break;
  74.             case 'e': case 'E': PUTCHAR('\033'); sp++; break;
  75.  
  76.             case '^':
  77.             case '\\':
  78.             case ',':
  79.             case ':':
  80.             case '\'':
  81.             case '$':
  82.                 PUTCHAR(*sp++);
  83.                 break;
  84.  
  85.             case '0':
  86.                 if (*(sp + 1) < '0' || *(sp + 1) > '7') {
  87.                     PUTCHAR('\200'); /* I'd prefer \0 */
  88.                     sp++;
  89.                     break;
  90.                 }
  91.                 ;/* FALLTHROUGH */
  92.             case '1': case '2': case '3': case '4':
  93.             case '5': case '6': case '7':
  94.                 l = *sp++ - '0';
  95.                 if (*sp >= '0' && *sp <= '7') {
  96.                     l = l * 8 + (*sp++ - '0');
  97.                     if (*sp >= '0' && *sp <= '7')
  98.                         l = l * 8 + (*sp++ - '0');
  99.                 }
  100.                 PUTCHAR(l);
  101.                 break;
  102.  
  103.             case '\0':
  104.                 PUTCHAR('\\');
  105.                 break;
  106.  
  107.             case '@':
  108.                 if (!forced_lit)
  109.                     forced_lit = _lit_output();
  110.                 sp++;
  111.                 break;
  112.  
  113.             default:
  114.                 PUTCHAR('\\');
  115.                 PUTCHAR(*sp++);
  116.                 break;
  117.             }
  118.             break;
  119.         case '^':
  120.             if (*++sp == '\0')
  121.                 break;
  122.             l = *sp - '@';
  123.             if (l > 31)
  124.                 l -= 32;
  125.             if (l < 0 || l > 31) {
  126.                 PUTCHAR('^');
  127.                 PUTCHAR(*sp++);
  128.             } else {
  129.                 PUTCHAR(l);
  130.                 sp++;
  131.             }
  132.             break;
  133.         case '$':
  134.             if (*++sp != '<') {
  135.                 PUTCHAR('$');
  136.                 break;
  137.             }
  138.             must_pad = 0;
  139.             multiply_pad = 0;
  140.             l = 0;
  141.             sp++;
  142.             while (isdigit(*sp))
  143.                 l = l * 10 + (*sp++ - '0');
  144.             l *= 10;
  145.             if (*sp == '.') {
  146.                 sp++;
  147.                 if (isdigit(*sp))
  148.                     l += *sp++ - '0';
  149.             }
  150.             if (*sp == '/') {
  151.                 must_pad = 1;
  152.                 if (*++sp == '*') {
  153.                     multiply_pad = 1;
  154.                     sp++;
  155.                 }
  156.             } else if (*sp == '*') {
  157.                 multiply_pad = 1;
  158.                 if (*++sp == '/') {
  159.                     must_pad = 1;
  160.                     sp++;
  161.                 }
  162.             }
  163.             if (*sp != '>') {
  164.                 PUTCHAR('p');
  165.                 PUTCHAR('a');
  166.                 PUTCHAR('d');
  167.                 PUTCHAR('?');
  168.                 break;
  169.             }
  170.             sp++;
  171. #ifdef TEST
  172.             printf("\nl = %d", l);
  173. #endif
  174.             if (cur_term->pad || must_pad) {
  175.                 cnt = ((long) l * cur_term->baudrate
  176.                        * (multiply_pad ? count : 1) 
  177.                        + (10000L * BITSPERCHAR / 2L))
  178.                       / (10000L * BITSPERCHAR);
  179. #ifdef TEST
  180.                 printf("; cnt = %d\n", cnt);
  181. #endif
  182.                 while(cnt--)
  183.                     PUTCHAR(cur_term->padch);
  184.             }
  185. #ifdef TEST
  186.             printf("\n");
  187. #endif
  188.             break;
  189.         default:
  190.             PUTCHAR(*sp++);
  191.         }
  192.     }
  193.     if (forced_lit)
  194.         _norm_output();
  195.     return OK;
  196. }
  197.  
  198. int
  199. putp(str)
  200. char *str; {
  201.     return(tputs(str, 1,(int (*)()) 0));
  202. }
  203.  
  204. #ifdef TEST
  205.  
  206. TERMINAL test_term, *cur_term = &test_term;
  207.  
  208. void
  209. putch(c)
  210. int c; {
  211.     c &= 0xff;
  212.     if (c > 127 || c < 0) {
  213.         printf("\\%03o", c);
  214.     } else if (c < 32) {
  215.         printf("^%c", c + '@');
  216.     } else if (c == 127) {
  217.         printf("^?");
  218.     } else {
  219.         putchar(c);
  220.     }
  221. }
  222.  
  223. char line[MAX_LINE];
  224.  
  225. int
  226. main(argc, argv)
  227. int argc;
  228. char **argv; {
  229.     test_term.termcap = 0;
  230.     test_term.baudrate = 1200;
  231.     test_term.pad = 0;
  232.     test_term.padch = 0;
  233.     if (argc > 1) 
  234.         test_term.baudrate = atoi(argv[1]);
  235.     if (argc > 2)
  236.         test_term.padch = argv[2][0];
  237.     if (argc > 3)
  238.         test_term.pad = 1;
  239.  
  240.     putchar('\n');
  241.  
  242.     while(gets(line) != NULL) {
  243.         tputs(line, 7, putch);
  244.         putchar('\n');
  245.     }
  246.     return 0;
  247. }
  248. #endif
  249.