home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 419b.lha / TERMLIB / tgoto.c < prev    next >
C/C++ Source or Header  |  1990-10-05  |  4KB  |  155 lines

  1. /* TERMLIB: Terminal independant database.
  2.  *
  3.  * Module: tgoto
  4.  *
  5.  * Purpose: decode cm cursor motion string.
  6.  *
  7.  * Calling conventions: cm is cursor motion string.
  8.  *            line, col, are the desired destination.
  9.  *
  10.  * Returned values: a string pointing to the decoded string, or
  11.  *            "OOPS" if it cannot be decoded.
  12.  *
  13.  * Notes
  14.  *        The accepted escapes are:
  15.  *            %d     as in printf, 0 origin.
  16.  *            %2, %3     like %02d, %03d in printf.
  17.  *            %.     like %c
  18.  *            %+x     adds <x> to value, then %.
  19.  *            %>xy     if value>x, adds y. No output.
  20.  *            %i     increments line& col, no output.
  21.  *            %r     reverses order of line&col. No output.
  22.  *            %%     prints as a single %.
  23.  *            %n     exclusive or row & col with 0140.
  24.  *            %B     BCD, no output.
  25.  *            %D     reverse coding (x-2*(x%16)), no output.
  26.  */
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include "termlib.h"
  30.  
  31. /* tgoto.c (libtermlib.a)
  32.  *
  33.  */
  34.  
  35. char *
  36. tgoto(cm, col, line)
  37. char    *cm;                                      /* cm string, from termcap */
  38. int    col,                                           /* column, x position */
  39.     line;                                            /* line, y position */
  40. {
  41.     char    *_addfmt(),
  42.         gx, gy,                                           /*    x, y */
  43.         *ptr,                                     /* pointer in 'cm' */
  44.         reverse = 0,                                 /* reverse flag */
  45.         *bufp,                         /* pointer in returned string */
  46.         addup = 0,                                     /* add upline */
  47.         addbak = 0,                                    /* add backup */
  48.         c;
  49.     static char buffer[32];
  50.  
  51.     if(!cm)
  52.         return "OOPS";                       /* Kludge, but standard */
  53.  
  54.     bufp = buffer;
  55.     ptr = cm;
  56.  
  57.     while(*ptr) {
  58.         if((c = *ptr++) != '%') {                     /* normal char */
  59.             *bufp++ = c;
  60.         } else {                                         /* % escape */
  61.             switch(c = *ptr++) {
  62.             case 'd':                                 /* decimal */
  63.                 bufp = _addfmt(bufp, "%d", line);
  64.                 line = col;
  65.                 break;
  66.             case '2':                         /* 2 digit decimal */
  67.                 bufp = _addfmt(bufp, "%02d", line);
  68.                 line = col;
  69.                 break;
  70.             case '3':                         /* 3 digit decimal */
  71.                 bufp = _addfmt(bufp, "%03d", line);
  72.                 line = col;
  73.                 break;
  74.             case '>':                      /* %>xy: if >x, add y */
  75.                 gx = *ptr++;
  76.                 gy = *ptr++;
  77.                 if(col>gx) col += gy;
  78.                 if(line>gx) line += gy;
  79.                 break;
  80.             case '+':                              /* %+c: add c */
  81.                 line += *ptr++;
  82.             case '.':                               /* print x/y */
  83.                 if(line=='\t' ||                /* these are */
  84.                    line == '\n' ||             /* chars that */
  85.                    line=='\004' ||             /* UNIX hates */
  86.                    line=='\0') {
  87.                     line++;         /* so go to next pos */
  88.                     if(reverse==(line==col))
  89.                         addup=1;      /* and mark UP */
  90.                     else
  91.                         addbak=1;           /* or BC */
  92.                 }
  93.                 *bufp++=line;
  94.                 line = col;
  95.                 break;
  96.             case 'r':                              /* r: reverse */
  97.                 gx = line; 
  98.                 line = col; 
  99.                 col = gx;
  100.                 reverse = 1;
  101.                 break;
  102.             case 'i':             /* increment (1-origin screen) */
  103.                 col++;
  104.                 line++;
  105.                 break;
  106.             case '%':                          /* %%=% literally */
  107.                 *bufp++='%';
  108.                 break;
  109.             case 'n':                       /* magic DM2500 code */
  110.                 line ^= 0140;
  111.                 col ^= 0140;
  112.                 break;
  113.             case 'B':                            /* bcd encoding */
  114.                 line = line/10<<4+line%10;
  115.                 col = col/10<<4+col%10;
  116.                 break;
  117.             case 'D':                   /* magic Delta Data code */
  118.                 line = line-2*(line&15);
  119.                 col = col-2*(col&15);
  120.                 break;
  121.             default:                           /* Unknown escape */
  122.                 return "OOPS";
  123.             }
  124.         }
  125.     }
  126.  
  127.     if(addup)                                              /* add upline */
  128.         if(UP) {
  129.             ptr=UP;
  130.             while(isdigit(*ptr) || *ptr=='.')
  131.                 ptr++;
  132.             if(*ptr=='*')
  133.                 ptr++;
  134.             while(*ptr)
  135.                 *bufp++ = *ptr++;
  136.         }
  137.  
  138.     if(addbak)                                          /* add backspace */
  139.         if(BC) {
  140.             ptr=BC;
  141.             while(isdigit(*ptr) || *ptr=='.')
  142.                 ptr++;
  143.             if(*ptr=='*')
  144.                 ptr++;
  145.             while(*ptr)
  146.                 *bufp++ = *ptr++;
  147.         } 
  148.         else
  149.             *bufp++='\b';
  150.  
  151.     *bufp = 0;
  152.  
  153.     return(buffer);
  154. }
  155.