home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / jove4.9 / part04 / fmt.c next >
C/C++ Source or Header  |  1988-04-25  |  8KB  |  440 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "io.h"
  10. #include "termcap.h"
  11.  
  12. #ifdef MAC
  13. #    include  "mac.h"
  14. #else
  15. #    include <varargs.h>
  16. #endif
  17.  
  18. #ifdef MAC
  19. #    undef private
  20. #    define private
  21. #endif
  22.  
  23. #ifdef    LINT_ARGS
  24. private void
  25.     doformat(File *, char *, ...),
  26.     outld(long, int),
  27.     pad(int, int),
  28.     PPchar(int, char *),
  29.     putld(long, int),
  30.     puts(char *);
  31. #else
  32. private void
  33.     doformat(),
  34.     outld(),
  35.     pad(),
  36.     PPchar(),
  37.     putld(),
  38.     puts();
  39. #endif    /* LINT_ARGS */
  40.  
  41. #ifdef MAC
  42. #    undef private
  43. #    define private static
  44. #endif
  45.  
  46.  
  47. char    mesgbuf[MESG_SIZE];
  48.  
  49. /* VARARGS2 */
  50.  
  51. void
  52. format(buf, len, fmt, ap)
  53. char    *buf,
  54.     *fmt;
  55. va_list    ap;
  56. {
  57.     File    strbuf,
  58.         *sp = &strbuf;
  59.  
  60.      sp->f_ptr = sp->f_base = buf;
  61.     sp->f_fd = -1;        /* Not legit for files */
  62.     sp->f_cnt = len;
  63.     sp->f_flags = F_STRING;
  64.     sp->f_bufsize = len;
  65.  
  66.     doformat(sp, fmt, ap);
  67.     putc('\0', sp);
  68. }
  69.  
  70. #ifdef IBMPC
  71. int    specialmap = 0,
  72.     specialkey = 0;
  73.  
  74. #define Empty ""
  75.  
  76. char *altseq[133] = {
  77. Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
  78. Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left", 
  79. "Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
  80. "Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
  81. "Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
  82. Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
  83. "Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
  84. Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5", 
  85. "F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
  86. "Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
  87. "Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4", 
  88. "Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
  89. "Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10", 
  90. "Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
  91. "Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
  92. "Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
  93. "Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp" 
  94. };
  95. #endif
  96.  
  97.  
  98. private void
  99. PPchar(c, str)
  100. int    c;
  101. char    *str;
  102. {
  103.     char    *cp = str;
  104.  
  105. #ifdef IBMPC
  106.     if (specialmap || specialkey) {
  107.         if (c < 0 || c > 132)
  108.             c = 0;
  109.         strcpy(cp, altseq[c]);
  110.     } else
  111. #endif    
  112.     if (c == '\033')
  113.         strcpy(cp, "ESC");
  114. #ifdef IBMPC                /* this character is invisible */
  115.     else if (c == '\377') {
  116.             *cp = 0;
  117.     }
  118. #endif /* IBMPC */
  119.     else if (c < ' ')
  120.         sprintf(cp, "C-%c", c + '@');
  121.     else if (c == '\177')
  122.         strcpy(cp, "^?");
  123.     else
  124.         sprintf(cp, "%c", c);
  125. }
  126.  
  127. private struct fmt_state {
  128.     int    precision,
  129.         width,
  130.         leftadj;
  131.     char    padc;
  132.     File    *iop;
  133. } current_fmt;
  134.  
  135. private void
  136. putld(d, base)
  137. long    d;
  138. {
  139.     int    length = 1;
  140.     long    tmpd = d;
  141.  
  142.     if (current_fmt.width == 0 && current_fmt.precision) {
  143.         current_fmt.width = current_fmt.precision;
  144.         current_fmt.padc = '0';
  145.     }
  146.     while (tmpd = (tmpd / base))
  147.         length += 1;
  148.     if (d < 0)
  149.         length += 1;
  150.     if (!current_fmt.leftadj)
  151.         pad(current_fmt.padc, current_fmt.width - length);
  152.     if (d < 0) {
  153.         putc('-', current_fmt.iop);
  154.         d = -d;
  155.     }
  156.     outld(d, base);
  157.     if (current_fmt.leftadj)
  158.         pad(current_fmt.padc, current_fmt.width - length);
  159. }
  160.  
  161. private void
  162. outld(d, base)
  163. long    d;
  164. {
  165.     register long    n;
  166.     static char    chars[] = {'0', '1', '2', '3', '4', '5', '6',
  167.                     '7', '8', '9', 'a', 'b', 'c', 'd',
  168.                     'e', 'f'};
  169.  
  170.     if (n = (d / base))
  171.         outld(n, base);
  172.     putc((int) (chars[(int) (d % base)]), current_fmt.iop);
  173. }
  174.  
  175. private void
  176. puts(str)
  177. char    *str;
  178. {
  179.     int    length;
  180.     register char    *cp;
  181.  
  182.     if (str == 0)
  183. #if pyr
  184.         str = "";
  185. #else
  186.         str = "(null)";
  187. #endif
  188.     length = strlen(str);
  189.     if (current_fmt.precision == 0 || length < current_fmt.precision)
  190.         current_fmt.precision = length;
  191.     else
  192.         length = current_fmt.precision;
  193.     cp = str;
  194.     if (!current_fmt.leftadj)
  195.         pad(' ', current_fmt.width - length);
  196.     while (--current_fmt.precision >= 0)
  197.         putc(*cp++, current_fmt.iop);
  198.     if (current_fmt.leftadj)
  199.         pad(' ', current_fmt.width - length);
  200. }
  201.  
  202. private void
  203. pad(c, amount)
  204. register int    c,
  205.         amount;
  206. {
  207.     while (--amount >= 0)
  208.         putc(c, current_fmt.iop);
  209. }
  210.  
  211. private void
  212. doformat(sp, fmt, ap)
  213. register File    *sp;
  214. register char    *fmt;
  215. va_list    ap;
  216. {
  217.     register char    c;
  218.     struct fmt_state    prev_fmt;
  219.  
  220.     prev_fmt = current_fmt;
  221.     current_fmt.iop = sp;
  222.  
  223.     while (c = *fmt++) {
  224.         if (c != '%') {
  225.             putc(c, current_fmt.iop);
  226.             continue;
  227.         }
  228.  
  229.         current_fmt.padc = ' ';
  230.         current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
  231.         c = *fmt++;
  232.         if (c == '-') {
  233.             current_fmt.leftadj = YES;
  234.             c = *fmt++;
  235.         }
  236.         if (c == '0') {
  237.             current_fmt.padc = '0';
  238.             c = *fmt++;
  239.         }
  240.         while (c >= '0' && c <= '9') {
  241.             current_fmt.width = current_fmt.width * 10 + (c - '0');
  242.             c = *fmt++;
  243.         }
  244.         if (c == '*') {
  245.             current_fmt.width = va_arg(ap, int);
  246.             c = *fmt++;
  247.         }
  248.         if (c == '.') {
  249.             c = *fmt++;
  250.             while (c >= '0' && c <= '9') {
  251.                 current_fmt.precision = current_fmt.precision * 10 + (c - '0');
  252.                 c = *fmt++;
  253.             }
  254.             if (c == '*') {
  255.                 current_fmt.precision = va_arg(ap, int);
  256.                 c = *fmt++;
  257.             }
  258.         }
  259.     reswitch:
  260.         /* At this point, fmt points at one past the format letter. */
  261.         switch (c) {
  262.         case '%':
  263.             putc('%', current_fmt.iop);
  264.             break;
  265.     
  266.         case 'O':
  267.         case 'D':
  268.         case 'X':
  269.             putld(va_arg(ap, long), (c == 'O') ? 8 :
  270.                         (c == 'D') ? 10 : 16);
  271.             break;
  272.     
  273.         case 'b':
  274.             {
  275.             Buffer    *b = va_arg(ap, Buffer *);
  276.  
  277.             puts(b->b_name);
  278.             break;
  279.             }
  280.  
  281.         case 'c':
  282.             putc(va_arg(ap, int), current_fmt.iop);
  283.             break;
  284.     
  285.         case 'o':
  286.         case 'd':
  287.         case 'x':
  288.             putld((long) va_arg(ap, int), (c == 'o') ? 8 :
  289.                         (c == 'd') ? 10 : 16);
  290.             break;
  291.     
  292.         case 'f':    /* current command name gets inserted here! */
  293.             puts(LastCmd->Name);
  294.             break;
  295.  
  296.         case 'l':
  297.             c = CharUpcase(*++fmt);
  298.             goto reswitch;
  299.     
  300.         case 'n':
  301.             if (va_arg(ap, int) != 1)
  302.                 puts("s");
  303.             break;
  304.  
  305.         case 'p':
  306.             {
  307.                 char    cbuf[20];
  308.  
  309.                 PPchar(va_arg(ap, int), cbuf);
  310.                 puts(cbuf);
  311.                 break;
  312.             }
  313.  
  314.         case 's':
  315.             puts(va_arg(ap, char *));
  316.             break;
  317.         
  318.         default:
  319.             complain("Unknown format directive: \"%%%c\"", c);
  320.         }
  321.     }
  322.     current_fmt = prev_fmt;
  323. }
  324.  
  325. /* VARARGS1 */
  326.  
  327. char *
  328. sprint(fmt, va_alist)
  329. char    *fmt;
  330. va_dcl
  331. {
  332.     va_list    ap;
  333.     static char    line[100];
  334.  
  335.     va_start(ap);
  336.     format(line, sizeof line, fmt, ap);
  337.     va_end(ap);
  338.     return line;
  339. }
  340.  
  341. /* VARARGS1 */
  342.  
  343. void
  344. printf(fmt, va_alist)
  345. char    *fmt;
  346. va_dcl
  347. {
  348.     va_list    ap;
  349.  
  350.     va_start(ap);
  351. #ifndef IBMPC
  352.     doformat(stdout, fmt, ap);
  353. #else /* IBMPC */
  354.     write_em(sprint(fmt, ap));
  355.     /* doformat(stdout, fmt, ap); */
  356. #endif /* IBMPC */
  357.     va_end(ap);
  358. }
  359.  
  360. /* VARARGS1 */
  361.  
  362. void
  363. fprintf(fp, fmt, va_alist)
  364. File    *fp;
  365. char    *fmt;
  366. va_dcl
  367. {
  368.     va_list    ap;
  369.  
  370.     va_start(ap);
  371.     doformat(fp, fmt, ap);
  372.     va_end(ap);
  373. }
  374.  
  375. /* VARARGS2 */
  376.  
  377. void
  378. sprintf(str, fmt, va_alist)
  379. char    *str,
  380.     *fmt;
  381. va_dcl
  382. {
  383.     va_list    ap;
  384.  
  385.     va_start(ap);
  386.     format(str, 130, fmt, ap);
  387.     va_end(ap);
  388. }
  389.  
  390. /* VARARGS1 */
  391.  
  392. void
  393. s_mess(fmt, va_alist)
  394. char    *fmt;
  395. va_dcl
  396. {
  397.     va_list    ap;
  398.  
  399.     if (InJoverc)
  400.         return;
  401.     va_start(ap);
  402.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  403.     va_end(ap);
  404.     message(mesgbuf);
  405. }
  406.  
  407. /* VARARGS1 */
  408.  
  409. void
  410. f_mess(fmt, va_alist)
  411. char    *fmt;
  412. va_dcl
  413. {
  414.     va_list    ap;
  415.  
  416.     va_start(ap);
  417.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  418.     va_end(ap);
  419.     DrawMesg(NO);
  420.     UpdMesg = YES;    /* still needs updating (for convenience) */
  421. }
  422.  
  423. /* VARARGS1 */
  424.  
  425. void
  426. add_mess(fmt, va_alist)
  427. char    *fmt;
  428. va_dcl
  429. {
  430.     int    mesg_len = strlen(mesgbuf);
  431.     va_list    ap;
  432.  
  433.     if (InJoverc)
  434.         return;
  435.     va_start(ap);
  436.     format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
  437.     va_end(ap);
  438.     message(mesgbuf);
  439. }
  440.