home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff254.lzh / Etale / parseline.c < prev    next >
C/C++ Source or Header  |  1989-10-19  |  7KB  |  220 lines

  1. /*  parseline.c  -- (part of efr)  Copyright © 1989 by William F. Hammond  */
  2. /*               --  breaks a string into LineParts                        */
  3. #ifndef TDM_H
  4. #include "tdm.h"
  5. #endif
  6. /*********************************************************************/
  7. struct LinePart *parseline(lpstr, lpp)
  8. UBYTE *lpstr;
  9. struct LinePart *lpp;             /*  address of previous LinePart        */
  10. {
  11. struct LinePart *lp, *lpn;        /*  lp points to the LinePart herein    */
  12.                                   /*      allocated; it is the return     */
  13.                                   /*  lpn points to the successor of lp   */
  14. register USHORT i;
  15. SHORT lastclear, lpl, controlcount;
  16. int isl;
  17. UBYTE *nstr;                       /*  for recursive call to self          */
  18. USHORT clearcount, lnctlseq, ctladj;
  19. UBYTE drawflag, fontflag;
  20. if(lpstr == NULL) return NULL;
  21. if(strlen(lpstr) == 0) return NULL; 
  22. lp = (struct LinePart *)AllocMem(LPSZ, MEMF_CLEAR);
  23. if (lp == NULL)
  24.    {
  25.    fputs("parseline: Insufficient memory for LinePart\xa", stderr);
  26.    if(lpp != NULL)
  27.       {
  28.       lp = lpp;
  29.       while (lp)
  30.          {
  31.          lpn = lp->lp_Prev;
  32.          FreeMem(lp, LPSZ);
  33.          lp = lpn;
  34.          }
  35.       }
  36.    return NULL;
  37.    }
  38. lp->lp_Address = (ULONG)lpstr;
  39. lp->lp_Length = NULB;
  40. lp->lp_Move = NULB;
  41. lp->lp_FontStyle = NULB;
  42. lp->lp_DrawStyle = NULB;
  43. lp->lp_Next = (struct LinePart *)NULL;
  44. lp->lp_Prev = lpp;
  45. lp->lp_Trans = 0L;
  46. /*  Examine the characters in lpstr;  */
  47. isl = strlen(lpstr);
  48. if(lpstr[isl-1] == '\n')
  49.    {
  50.    lpstr[isl-1] = '\0';
  51.    isl --;
  52.    }
  53. lastclear = -1;
  54. i = 0;
  55. /******************    controlcount is the offset to lpstr for lp->lp_Address
  56.  *  lnctlseq detects the controlcount contribution of the current character
  57.  *  clearcount is the number of clear characters including accessory controls
  58.  *  ctladj is the number of accessory controls
  59.  *  clearcount and ctladj are used to set lp->lp_Length  *******************/
  60. clearcount = 0; controlcount = 0; lnctlseq = 0, ctladj = 0;
  61. drawflag = NULB; fontflag = NULB;
  62. while (i < isl)
  63.    {
  64.    switch (lpstr[i])
  65.       {
  66.       case 0x08:
  67.          {
  68.          lnctlseq = 1;
  69.          if(lastclear <0)
  70.             {
  71.             lp->lp_Trans -- ;
  72.             controlcount += lnctlseq;
  73.             ctladj += (lnctlseq -1); 
  74.             }
  75.          break;
  76.          }
  77.       case 0x09:
  78.          {
  79.          lnctlseq = 1;
  80.          if(lastclear <0)
  81.             {
  82.             lp->lp_Trans += 3;
  83.             controlcount += lnctlseq;
  84.             ctladj += (lnctlseq -1); 
  85.             }
  86.          break;
  87.          }
  88.       case 0x1B:
  89.          {
  90.          if((lpstr[i+1] == '[') && (lpstr[i+3] == 'm'))
  91.             {
  92.             switch (lpstr[i+2])
  93.                {
  94.                case '0':      /*  plain font style and drawing style  */
  95.                   {
  96.                   lnctlseq = 4;
  97.                   if(lastclear <0)
  98.                      {
  99.                      fontflag = 1;
  100.                      lp->lp_FontStyle = FS_NORMAL;
  101.                      drawflag = 1;
  102.                      lp->lp_DrawStyle = JAMX;
  103.                      controlcount += lnctlseq;
  104.                      ctladj += (lnctlseq -1); 
  105.                      }
  106.                   break;
  107.                   }
  108.                case '1':      /*  boldface font style                 */
  109.                   {
  110.                   lnctlseq = 4;
  111.                   if(lastclear <0)
  112.                      {
  113.                      fontflag = 1;
  114.                      lp->lp_FontStyle = lp->lp_FontStyle | FSF_BOLD;
  115.                      controlcount += lnctlseq;
  116.                      ctladj += (lnctlseq -1); 
  117.                      }
  118.                   break;
  119.                   }
  120.                case '3':      /*  italic font style                   */
  121.                   {
  122.                   lnctlseq = 4;
  123.                   if(lastclear <0)
  124.                      {
  125.                      fontflag = 1;
  126.                      lp->lp_FontStyle = lp->lp_FontStyle | FSF_ITALIC;
  127.                      controlcount += lnctlseq;
  128.                      ctladj += (lnctlseq -1); 
  129.                      }
  130.                   break;
  131.                   }
  132.                case '4':      /*  underlined font style                */
  133.                   {
  134.                   lnctlseq = 4;
  135.                   if(lastclear <0)
  136.                      {
  137.                      fontflag = 1;
  138.                      lp->lp_FontStyle = lp->lp_FontStyle | FSF_UNDERLINED;
  139.                      controlcount += lnctlseq;
  140.                      ctladj += (lnctlseq -1); 
  141.                      }
  142.                   break;
  143.                   }
  144.                case '7':      /*  inverse video drawing style         */
  145.                   {
  146.                   lnctlseq = 4;
  147.                   if(lastclear <0)
  148.                      {
  149.                      drawflag = 1;
  150.                      lp->lp_DrawStyle = (JAMX|INVERSVID);
  151.                      controlcount += lnctlseq;
  152.                      ctladj += (lnctlseq -1); 
  153.                      }
  154.                   break;
  155.                   }
  156.                default:
  157.                   {
  158.                   lnctlseq = 0; lastclear = i;  clearcount ++;  break;
  159.                   }
  160.                }
  161.             }
  162.          else
  163.             {
  164.             lnctlseq = 0; lastclear = i;  clearcount ++;  break;
  165.             }
  166.          break;
  167.          }
  168.       case 0x86:                                         /*  move down  */
  169.       case 0x88:
  170.          {
  171.          lnctlseq = 1;
  172.          if(lastclear <0)
  173.             {
  174.             lp->lp_Move = lp->lp_Move + 1;
  175.             controlcount += lnctlseq;
  176.             ctladj += (lnctlseq -1); 
  177.             }
  178.          break;
  179.          }
  180.       case 0x87:                                         /*  move up    */
  181.       case 0x8A:
  182.          {
  183.          lnctlseq = 1;
  184.          if(lastclear <0)
  185.             {
  186.             lp->lp_Move = lp->lp_Move - 1;
  187.             controlcount += lnctlseq;
  188.             ctladj += (lnctlseq -1); 
  189.             }
  190.          break;
  191.          }
  192.       default:
  193.          {
  194.          lnctlseq = 0; lastclear = i;  clearcount ++;  break;
  195.          }
  196.       }        /***  switch end  ***/
  197.    if( (lnctlseq) && (lastclear >= 0) ) break;
  198.    i ++;    
  199.    }         /***  loop (i < strlen(lpstr))  ***/
  200. lpl = lastclear + 1;     /*  offset of first char. in next LinePart  */
  201. lp->lp_Address = (ULONG)lpstr + (ULONG)controlcount;
  202. if(controlcount > 0) clearcount = clearcount - ctladj;
  203. lp->lp_Length = (UBYTE)(clearcount);
  204. if(drawflag) lp->lp_DrawStyle ++;
  205. if(fontflag) lp->lp_FontStyle ++;
  206. if (lpl < isl)
  207.    {
  208.    if (lastclear >=0)
  209.       {                /*  At least one more LinePart required      */
  210.       nstr = &lpstr[lpl];
  211.       lp->lp_Next = parseline(nstr, lp);
  212.       }
  213.    else        /*  Nothing but control chars in lpstr, thus lpl = 0    */
  214.       {
  215.       lp->lp_Length = NULB;     /*  Signals "control changes only"  */
  216.       }
  217.    }
  218. return lp;
  219. }
  220.