home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / DOANSI_1.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  14KB  |  489 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  DOANSI_1.C - Portable ANSI screen code interpreter
  5. **
  6. **  From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever
  7. **  purposes by author: Mark Kimes
  8. */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "doansi.h"
  14.  
  15. #ifdef __WATCOMC__
  16.  #pragma off (unreferenced);
  17. #endif
  18.  
  19. #ifdef __TURBOC__   /* shut up 'Parameter not used' warnings        */
  20.  #pragma warn -par  /* in the BC3.1 IDE the setting of Options,     */
  21. #endif              /* Compiler,Messages,Display must NOT be 'All'. */
  22.  
  23. /*
  24.  * to initialize:
  25.  *   call set_screensize(<# lines to reserve>);
  26.  * to print through ansi interpreter:
  27.  *   call ansi_out(<string>);
  28.  */
  29.  
  30. char               curattr = 7;
  31. int                curx = 0,cury = 0;
  32. int                maxx = 80, maxy = 25;  /* size of ansi output window */
  33. int                realmaxy,realmaxx;     /* real screen size */
  34. char               useansi = 1;           /* while true, interp ansi seqs */
  35. int                tabspaces = 8;
  36. static int         savx,savy,issaved = 0;
  37. static char        ansi_terminators[] = "HFABCDnsuJKmp";
  38.  
  39. #define MAXARGLEN       128
  40.  
  41. #define NOTHING         0
  42. #define WASESCAPE       1
  43. #define WASBRKT         2
  44.  
  45. /* "generic" support functions closely related to ansi_out */
  46.  
  47. void set_pos (char *argbuf,int arglen,char cmd)
  48. {
  49.       int   y,x;
  50.       char *p;
  51.  
  52.       if (!*argbuf || !arglen)
  53.       {
  54.             curx = cury = 0;
  55.       }
  56.       y = atoi(argbuf) - 1;
  57.       p = strchr(argbuf,';');
  58.       if (y >= 0 && p)
  59.       {
  60.             x = atoi(p + 1) - 1;
  61.             if(x >= 0)
  62.             {
  63.                   curx = x;
  64.                   cury = y;
  65.             }
  66.       }
  67. }
  68.  
  69. void go_up (char *argbuf,int arglen,char cmd)
  70. {
  71.       int x;
  72.  
  73.       x = atoi(argbuf);
  74.       if (!x)
  75.             x = 1;
  76.       for ( ; x ; x--)
  77.       {
  78.             if (!cury)
  79.                   break;
  80.             cury--;
  81.       }
  82. }
  83.  
  84. void go_down (char *argbuf,int arglen,char cmd)
  85. {
  86.       int x;
  87.  
  88.       x = atoi(argbuf);
  89.       if (!x)
  90.             x = 1;
  91.       for ( ; x ; x--)
  92.       {
  93.             if (cury == maxy - 1)
  94.                   break;
  95.             cury++;
  96.       }
  97. }
  98.  
  99. void go_left (char *argbuf,int arglen,char cmd)
  100. {
  101.       int x;
  102.  
  103.       x = atoi(argbuf);
  104.       if (!x)
  105.             x = 1;
  106.       for ( ; x ; x--)
  107.       {
  108.             if(!curx)
  109.                   break;
  110.             curx--;
  111.       }
  112. }
  113.  
  114. void go_right (char *argbuf,int arglen,char cmd)
  115. {
  116.       int x;
  117.  
  118.       x = atoi(argbuf);
  119.       if (!x)
  120.             x = 1;
  121.       for ( ; x ; x--)
  122.       {
  123.             if (curx == maxx - 1)
  124.                   break;
  125.             curx++;
  126.       }
  127. }
  128.  
  129. void report (char *argbuf,int arglen,char cmd)
  130. {
  131.       /* you figure out how to implement it ... */
  132. }
  133.  
  134. void save_pos (char *argbuf,int arglen,char cmd)
  135. {
  136.       savx = curx;
  137.       savy = cury;
  138.       issaved = 1;
  139. }
  140.  
  141. void restore_pos (char *argbuf,int arglen,char cmd)
  142. {
  143.       if(issaved)
  144.       {
  145.             curx = savx;
  146.             cury = savy;
  147.             issaved = 0;
  148.       }
  149. }
  150.  
  151. void clear_screen (char *argbuf,int arglen,char cmd)
  152. {
  153.       /* needs error checking */
  154.  
  155.       clearwindow(0,0,maxx - 1,maxy - 1,curattr);
  156.       curx = cury = 0;
  157. }
  158.  
  159. void kill_line (char *argbuf,int arglen,char cmd)
  160. {
  161.       cleartoeol(curx,cury,maxx - 1,curattr);
  162. }
  163.  
  164.  
  165. void set_colors (char *argbuf,int arglen,char cmd)
  166. {
  167.       char *p,*pp;
  168.  
  169.       if (*argbuf && arglen)
  170.       {
  171.             pp = argbuf;
  172.             do
  173.             {
  174.                   p = strchr(pp,';');
  175.                   if (p && *p)
  176.                   {
  177.                         *p = 0;
  178.                         p++;
  179.                   }
  180.                   switch (atoi(pp))
  181.                   {
  182.                   case 0: /* all attributes off */
  183.                         curattr = 7;
  184.                         break;
  185.  
  186.                   case 1: /* bright on */
  187.                         curattr |= 8;
  188.                         break;
  189.  
  190.                   case 2: /* faint on */
  191.                         curattr &= (~8);
  192.                         break;
  193.  
  194.                   case 3: /* italic on */
  195.                         break;
  196.  
  197.                   case 5: /* blink on */
  198.                         curattr |= 128;
  199.                         break;
  200.  
  201.                   case 6: /* rapid blink on */
  202.                         break;
  203.  
  204.                   case 7: /* reverse video on */
  205.                         curattr = 112;
  206.                         break;
  207.  
  208.                   case 8: /* concealed on */
  209.                         curattr = 0;
  210.                         break;
  211.  
  212.                   case 30: /* black fg */
  213.                         curattr &= (~7);
  214.                         break;
  215.  
  216.                   case 31: /* red fg */
  217.                         curattr &= (~7);
  218.                         curattr |= 4;
  219.                         break;
  220.  
  221.                   case 32: /* green fg */
  222.                         curattr &= (~7);
  223.                         curattr |= 2;
  224.                         break;
  225.  
  226.                   case 33: /* yellow fg */
  227.                         curattr &= (~7);
  228.                         curattr |= 6;
  229.                         break;
  230.  
  231.                   case 34: /* blue fg */
  232.                         curattr &= (~7);
  233.                         curattr |= 1;
  234.                         break;
  235.  
  236.                   case 35: /* magenta fg */
  237.                         curattr &= (~7);
  238.                         curattr |= 5;
  239.                         break;
  240.  
  241.                   case 36: /* cyan fg */
  242.                         curattr &= (~7);
  243.                         curattr |= 3;
  244.                         break;
  245.  
  246.                   case 37: /* white fg */
  247.                         curattr |= 7;
  248.                         break;
  249.  
  250.                   case 40: /* black bg */
  251.                         curattr &= (~112);
  252.                         break;
  253.  
  254.                   case 41: /* red bg */
  255.                         curattr &= (~112);
  256.                         curattr |= (4 << 4);
  257.                         break;
  258.  
  259.                   case 42: /* green bg */
  260.                         curattr &= (~112);
  261.                         curattr |= (2 << 4);
  262.                         break;
  263.  
  264.                   case 43: /* yellow bg */
  265.                         curattr &= (~112);
  266.                         curattr |= (6 << 4);
  267.                         break;
  268.  
  269.                   case 44: /* blue bg */
  270.                         curattr &= (~112);
  271.                         curattr |= (1 << 4);
  272.                         break;
  273.  
  274.                   case 45: /* magenta bg */
  275.                         curattr &= (~112);
  276.                         curattr |= (5 << 4);
  277.                         break;
  278.  
  279.                   case 46: /* cyan bg */
  280.                         curattr &= (~112);
  281.                         curattr |= (3 << 4);
  282.                         break;
  283.  
  284.                   case 47: /* white bg */
  285.                         curattr |= 112;
  286.                         break;
  287.  
  288.                   case 48: /* subscript bg */
  289.                         break;
  290.  
  291.                   case 49: /* superscript bg */
  292.                         break;
  293.  
  294.                   default: /* unsupported */
  295.                         break;
  296.                   }
  297.                   pp = p;
  298.             } while (p);
  299.       }
  300. }
  301.  
  302. int ansi_out (char *buf)
  303. {
  304.       int  arglen = 0, ansistate = NOTHING, x;
  305.       char *b = buf, argbuf[MAXARGLEN] = "";
  306.  
  307.       /* cursor is off while string is being displayed so we don't have
  308.          to keep updating it.  works to our detriment only if using
  309.          BIOS writes under MS-DOS
  310.       */
  311.  
  312.       hardcursor_off();
  313.  
  314.       if (!useansi)                       /* is ANSI interp on? */
  315.       {
  316.             ansistate = NOTHING;
  317.             arglen = 0;
  318.             *argbuf = 0;
  319.       }
  320.  
  321.       while (*b)
  322.       {
  323.             switch (ansistate)
  324.             {
  325.             case NOTHING:
  326.                   switch (*b)
  327.                   {
  328.                   case '\x1b':
  329.                         if (useansi)
  330.                         {
  331.                               ansistate = WASESCAPE;
  332.                               break;
  333.                         }
  334.  
  335.                   case '\r':
  336.                         curx = 0;
  337.                         break;
  338.  
  339.                   case '\n':
  340.                         cury++;
  341.                         if (cury > maxy - 1)
  342.                         {
  343.                               scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  344.                               cury--;
  345.                         }
  346.                         break;
  347.  
  348.                   case '\t':     /* so _you_ figure out what to do... */
  349.                         for (x = 0; x < tabspaces; x++)
  350.                         {
  351.                               put_char(' ',curattr,curx,cury);
  352.                               curx++;
  353.                               if (curx > maxx - 1)
  354.                               {
  355.                                     curx = 0;
  356.                                     cury++;
  357.                                     if (cury > maxy - 1)
  358.                                     {
  359.                                           scroll_up(0, 0, maxx - 1, maxy - 1,
  360.                                                 curattr);
  361.                                           cury--;
  362.                                     }
  363.                               }
  364.                         }
  365.                         break;
  366.  
  367.                   case '\b':
  368.                         if (curx)
  369.                         {
  370.                               curx--;
  371.                         }
  372.                         break;
  373.  
  374.                   case '\07':     /* usually a console bell */
  375.                         putchar('\07');
  376.                         break;
  377.  
  378.                   default:
  379.                         put_char(*b,curattr,curx,cury);
  380.                         curx++;
  381.                         if (curx > maxx - 1)
  382.                         {
  383.                               curx = 0;
  384.                               cury++;
  385.                               if (cury > maxy - 1)
  386.                               {
  387.                                     scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  388.                                     cury--;
  389.                               }
  390.                         }
  391.                         break;
  392.                   }
  393.                   break;
  394.  
  395.             case WASESCAPE:
  396.                   if (*b == '[')
  397.                   {
  398.                         ansistate = WASBRKT;
  399.                         arglen = 0;
  400.                         *argbuf = 0;
  401.                         break;
  402.                   }
  403.                   ansistate = NOTHING;
  404.                   break;
  405.  
  406.             case WASBRKT:
  407.                   if (strchr(ansi_terminators, (int)*b))
  408.                   {
  409.                         switch ((int)*b)
  410.                         {
  411.                         case 'H':   /* set cursor position */
  412.                         case 'F':
  413.                               set_pos(argbuf,arglen,*b);
  414.                               break;
  415.  
  416.                         case 'A':   /* up */
  417.                               go_up(argbuf,arglen,*b);
  418.                               break;
  419.  
  420.                         case 'B':   /* down */
  421.                               go_down(argbuf,arglen,*b);
  422.                               break;
  423.  
  424.                         case 'C':   /* right */
  425.                               go_right(argbuf,arglen,*b);
  426.                               break;
  427.  
  428.                         case 'D':   /* left */
  429.                               go_left(argbuf,arglen,*b);
  430.                               break;
  431.  
  432.                         case 'n':   /* report pos */
  433.                               report(argbuf,arglen,*b);
  434.                               break;
  435.  
  436.                         case 's':   /* save pos */
  437.                               save_pos(argbuf,arglen,*b);
  438.                               break;
  439.  
  440.                         case 'u':   /* restore pos */
  441.                               restore_pos(argbuf,arglen,*b);
  442.                               break;
  443.  
  444.                         case 'J':   /* clear screen */
  445.                               clear_screen(argbuf,arglen,*b);
  446.                               break;
  447.  
  448.                         case 'K':   /* delete to eol */
  449.                               kill_line(argbuf,arglen,*b);
  450.                               break;
  451.  
  452.                         case 'm':   /* set video attribs */
  453.                               set_colors(argbuf,arglen,*b);
  454.                               break;
  455.  
  456.                         case 'p':   /* keyboard redef -- disallowed */
  457.                               break;
  458.  
  459.                         default:    /* unsupported */
  460.                               break;
  461.                         }
  462.                         ansistate = NOTHING;
  463.                         arglen = 0;
  464.                         *argbuf = 0;
  465.                   }
  466.                   else
  467.                   {
  468.                         if (arglen < MAXARGLEN)
  469.                         {
  470.                               argbuf[arglen] = *b;
  471.                               argbuf[arglen + 1] = 0;
  472.                               arglen++;
  473.                         }
  474.                   }
  475.                   break;
  476.  
  477.             default:
  478.                   pos_hardcursor(curx,cury);
  479.                   fputs("\n **Error in ANSI state machine.\n",stderr);
  480.                   break;
  481.             }
  482.             b++;
  483.       }
  484.       pos_hardcursor(curx,cury);
  485.       hardcursor_on(curx,cury);
  486.  
  487.       return ((int)b - (int)buf);
  488. }
  489.