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