home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name stpentab -- Replace blanks with tab characters
- *
- * Synopsis presult = stpentab(psource,pstops,incr);
- *
- * char *presult Pointer to converted psource
- * char *psource Pointer to the source string
- * char *pstops Pointer to table of tab stops
- * int incr Interval separating further tab stops
- * beyond the end of pstops
- *
- * Description This function replaces blank spaces (' ') with tab
- * characters ('\t') so as to possibly shorten the length
- * of a string in memory. Use of tab characters is
- * minimal: that is, whenever a single blank space will
- * serve instead of a tab, the blank is used.
- *
- * Tab stops are defined as follows: The string pstops
- * consists of Ts ('t' or 'T') and other non-control
- * characters. The Ts in pstops correspond to the
- * positions of tab stops. The value of incr tells the
- * interval between tab stops beyond the last stop
- * designated in pstops.
- *
- * Special cases: If incr is positive and no tab stops are
- * designated in pstops, then tab stops are set every incr
- * characters starting from position 0 (i.e., the first
- * character of the line). If incr is 0 or negative, then
- * tab stops are set at each position beyond those set in
- * pstops, so that further blanks and tabs in psource are
- * copied intact.
- *
- * Newline ('\n') characters in psource are copied intact.
- * Then the list of tab stops is used again.
- *
- * Existing tab characters are left intact. They are
- * regarded as advancing to the next tab stop.
- *
- * STPENTAB regards all characters in psource (except tabs,
- * NULs, and newlines) as graphic characters occupying one
- * space in the result.
- *
- * Examples In these examples, column 0 means the first column in a
- * line.
- *
- * To designate tab stops at column 8 and every 8 columns
- * thereafter:
- *
- * pstops = ""
- * incr = 8
- *
- * To designate tab stops at columns 4 and 20 and every 5
- * columns thereafter:
- *
- * pstops = "0123t567890123456789t"
- * incr = 5
- *
- * Returns presult Pointer to the altered source string.
- * *psource The altered source string.
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <bstring.h>
-
- #define BLANK ' '
- #define NEWLINE '\n'
- #define TAB '\t'
-
- /* Macro ADVANCE advances one step */
- /* through the table of tab stops. */
- #define ADVANCE {if (ptable < pmaxtab) \
- ptable++; \
- else \
- numbeyond++; }
-
- char *stpentab(psource,pstops,incr)
- char *psource,*pstops;
- int incr;
- {
- char c;
- register char *ptable; /* Running pointer into pstops */
- char *pmaxtab; /* Pointer to last tab stop in pstops */
- register int numbeyond; /* Number of spaces advanced beyond */
- /* pmaxtab */
- char *pfrom = psource;
- register char *pto = psource;
-
- register int numblanks; /* Number of blanks we've saved up */
-
- static int is_stop(char *,char *,int,int);
-
- pmaxtab = pstops;
- for (ptable = pstops; *ptable; ptable++) /* Set pmaxtab */
- if ((*ptable == 't') || (*ptable == 'T'))
- pmaxtab = ptable;
-
- ptable = pstops;
- numbeyond = 0;
- numblanks = 0;
-
- do
- {
- switch (c = *pfrom++)
- {
- case BLANK:
- numblanks++;
- ADVANCE;
- if (is_stop(ptable,pmaxtab,numbeyond,incr))
- {
- if (numblanks > 1)
- *pto++ = TAB;
- else
- *pto++ = BLANK;
- numblanks = 0;
- }
- break;
- case TAB:
- do
- {
- ADVANCE
- } while (!is_stop(ptable,pmaxtab,numbeyond,incr));
- numblanks = 0; /* Discard the saved blanks */
- *pto++ = TAB;
- break;
- case NEWLINE:
- ptable = pstops;
- numbeyond = 0;
- default:
- if (c != NEWLINE)
- {
- ADVANCE
- }
- for (; numblanks; numblanks--)
- *pto++ = BLANK; /* Spill any saved blanks */
- *pto++ = c;
- }
- } while (c);
-
- return psource;
- }
-
- /**
- *
- * Name is_stop -- Reveal whether we are at a tab stop.
- *
- * Synopsis result = is_stop(ptable,pmaxtab,numbeyond,incr)
- * int result 1 if this is a tab stop, 0 if not
- * char *ptable Pointer into table of tab stops
- * char *pmaxtab Pointer to last tab in table of tab
- * stops, or if table empty, to beginning
- * of table.
- * int numbeyond Number of spaces we have advanced
- * beyond pmaxtab.
- * int incr Interval between tab stops after the
- * last stop specified in table
- *
- * Description This function reveals whether we are at a tab stop.
- * Ptable must point to the current position in the table
- * of tab stops (e.g., if to the first position if starting
- * the line), unless we're at or beyond pmaxtab, in which
- * case numbeyond contains the number of positions we've
- * advanced beyond pmaxtab.
- *
- * One is returned if we are beyond pmaxtab and if no tab
- * stops are set beyond that point (i.e., if incr is 0).
- *
- * Returns int result 1 if this is a tab stop, 0 if not.
- *
- **/
-
- static int is_stop(ptable,pmaxtab,numbeyond,incr)
- register char *ptable,*pmaxtab;
- int numbeyond;
- register int incr;
- {
- if (((*pmaxtab == 't') || (*pmaxtab == 'T'))
- && (ptable <= pmaxtab)) /* Still within table */
- return (*ptable == 't') || (*ptable == 'T');
- else if (incr > 0) /* Beyond table */
- return (numbeyond % incr) == 0;
-
- return 1; /* Tab stops at every point */
- }