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