home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 5.ddi / C / STPENTAB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-05  |  5.3 KB  |  187 lines

  1. /**
  2. *
  3. * Name        stpentab -- Replace blanks with tab characters
  4. *
  5. * Synopsis    presult = stpentab(psource,pstops,incr);
  6. *
  7. *        char *presult    Pointer to converted psource
  8. *        char *psource    Pointer to the source string
  9. *        char *pstops    Pointer to table of tab stops
  10. *        int  incr    Interval separating further tab stops
  11. *                beyond the end of pstops
  12. *
  13. * Description    This function replaces blank spaces (' ') with tab
  14. *        characters ('\t') so as to possibly shorten the length
  15. *        of a string in memory.    Use of tab characters is
  16. *        minimal:  that is, whenever a single blank space will
  17. *        serve instead of a tab, the blank is used.
  18. *
  19. *        Tab stops are defined as follows:  The string pstops
  20. *        consists of Ts ('t' or 'T') and other non-control
  21. *        characters.  The Ts in pstops correspond to the
  22. *        positions of tab stops.  The value of incr tells the
  23. *        interval between tab stops beyond the last stop
  24. *        designated in pstops.
  25. *
  26. *        Special cases:    If incr is positive and no tab stops are
  27. *        designated in pstops, then tab stops are set every incr
  28. *        characters starting from position 0 (i.e., the first
  29. *        character of the line).  If incr is 0 or negative, then
  30. *        tab stops are set at each position beyond those set in
  31. *        pstops, so that further blanks and tabs in psource are
  32. *        copied intact.
  33. *
  34. *        Newline ('\n') characters in psource are copied intact.
  35. *        Then the list of tab stops is used again.
  36. *
  37. *        Existing tab characters are left intact.  They are
  38. *        regarded as advancing to the next tab stop.
  39. *
  40. *        STPENTAB regards all characters in psource (except tabs,
  41. *        NULs, and newlines) as graphic characters occupying one
  42. *        space in the result.
  43. *
  44. * Examples    In these examples, column 0 means the first column in a
  45. *        line.
  46. *
  47. *        To designate tab stops at column 8 and every 8 columns
  48. *        thereafter:
  49. *
  50. *            pstops = ""
  51. *            incr   = 8
  52. *
  53. *        To designate tab stops at columns 4 and 20 and every 5
  54. *        columns thereafter:
  55. *
  56. *            pstops = "0123t567890123456789t"
  57. *            incr   = 5
  58. *
  59. * Returns    presult     Pointer to the altered source string.
  60. *        *psource    The altered source string.
  61. *
  62. * Version    3.0 (C)Copyright Blaise Computing Inc.    1986
  63. *
  64. **/
  65.  
  66. #include <bstring.h>
  67.  
  68. #define  BLANK     ' '
  69. #define  NEWLINE '\n'
  70. #define  TAB     '\t'
  71.  
  72.                   /* Macro ADVANCE advances one step      */
  73.                   /* through the table of tab stops.      */
  74. #define  ADVANCE  {if (ptable < pmaxtab)              \
  75.                ptable++;                  \
  76.            else                       \
  77.                numbeyond++; }
  78.  
  79. char *stpentab(psource,pstops,incr)
  80. char *psource,*pstops;
  81. int  incr;
  82. {
  83.     char c;
  84.     register char *ptable;    /* Running pointer into pstops          */
  85.     char      *pmaxtab;   /* Pointer to last tab stop in pstops   */
  86.     register int numbeyond;   /* Number of spaces advanced beyond     */
  87.                   /* pmaxtab                  */
  88.     char      *pfrom = psource;
  89.     register char *pto     = psource;
  90.  
  91.     register int numblanks;   /* Number of blanks we've saved up      */
  92.  
  93.     static int is_stop(char *,char *,int,int);
  94.  
  95.     pmaxtab = pstops;
  96.     for (ptable = pstops; *ptable; ptable++)           /* Set pmaxtab */
  97.     if ((*ptable == 't') || (*ptable == 'T'))
  98.         pmaxtab = ptable;
  99.  
  100.     ptable    = pstops;
  101.     numbeyond = 0;
  102.     numblanks = 0;
  103.  
  104.     do
  105.     {
  106.     switch (c = *pfrom++)
  107.     {
  108.         case BLANK:
  109.         numblanks++;
  110.         ADVANCE;
  111.         if (is_stop(ptable,pmaxtab,numbeyond,incr))
  112.         {
  113.             if (numblanks > 1)
  114.             *pto++ = TAB;
  115.             else
  116.             *pto++ = BLANK;
  117.             numblanks = 0;
  118.         }
  119.         break;
  120.         case TAB:
  121.         do
  122.         {
  123.             ADVANCE
  124.         } while (!is_stop(ptable,pmaxtab,numbeyond,incr));
  125.         numblanks = 0;        /* Discard the saved blanks   */
  126.         *pto++      = TAB;
  127.         break;
  128.         case NEWLINE:
  129.         ptable      = pstops;
  130.         numbeyond = 0;
  131.         default:
  132.         if (c != NEWLINE)
  133.         {
  134.             ADVANCE
  135.         }
  136.         for (; numblanks; numblanks--)
  137.             *pto++ = BLANK;        /* Spill any saved blanks */
  138.         *pto++ = c;
  139.     }
  140.     } while (c);
  141.  
  142.     return psource;
  143. }
  144.  
  145. /**
  146. *
  147. * Name        is_stop -- Reveal whether we are at a tab stop.
  148. *
  149. * Synopsis    result = is_stop(ptable,pmaxtab,numbeyond,incr)
  150. *        int  result    1 if this is a tab stop, 0 if not
  151. *        char *ptable    Pointer into table of tab stops
  152. *        char *pmaxtab    Pointer to last tab in table of tab
  153. *                stops, or if table empty, to beginning
  154. *                of table.
  155. *        int  numbeyond    Number of spaces we have advanced
  156. *                beyond pmaxtab.
  157. *        int  incr    Interval between tab stops after the
  158. *                last stop specified in table
  159. *
  160. * Description    This function reveals whether we are at a tab stop.
  161. *        Ptable must point to the current position in the table
  162. *        of tab stops (e.g., if to the first position if starting
  163. *        the line), unless we're at or beyond pmaxtab, in which
  164. *        case numbeyond contains the number of positions we've
  165. *        advanced beyond pmaxtab.
  166. *
  167. *        One is returned if we are beyond pmaxtab and if no tab
  168. *        stops are set beyond that point (i.e., if incr is 0).
  169. *
  170. * Returns    int  result    1 if this is a tab stop, 0 if not.
  171. *
  172. **/
  173.  
  174. static int is_stop(ptable,pmaxtab,numbeyond,incr)
  175. register char *ptable,*pmaxtab;
  176. int          numbeyond;
  177. register int  incr;
  178. {
  179.     if (((*pmaxtab == 't') || (*pmaxtab == 'T'))
  180.     && (ptable <= pmaxtab))        /* Still within table          */
  181.     return (*ptable == 't') || (*ptable == 'T');
  182.     else if (incr > 0)               /* Beyond table              */
  183.     return (numbeyond % incr) == 0;
  184.  
  185.     return 1;                   /* Tab stops at every point    */
  186. }
  187.