froese@eric.mpr.ca (Edwin Froese) (02/27/89)
EFTH MINIX report #69 - February 1989 - expand(1) and unexpand(1)
Tools to convert tabs to/from spaces.....
Terrence W. Holm
holm@bdc.ubc.ca
----------------------------------------------------------
echo x - expand.1
sed '/^X/s///' > expand.1 << '/'
XNAME
X expand(1) - convert tabs to spaces
X
XSYNOPSIS
X expand [ -tab1,tab2,tab3,... ] [ file ... ]
X
XDESCRIPTION
X Expand(1) copies the named files to standard output,
X replacing tabs (^I) with equivalent strings of space
X characters. If no files are specified then standard
X input is used.
X
X The tab stops will be at <tab1>, <tab2>, etc. If only
X one tab is specified then the tab stop is every <tab1>
X columns. The default is "-8".
X
XSEE ALSO
X unexpand(1)
/
echo x - unexpand.1
sed '/^X/s///' > unexpand.1 << '/'
XNAME
X unexpand(1) - convert spaces to tabs
X
XSYNOPSIS
X unexpand [ -a ] [ file ... ]
X
XDESCRIPTION
X Unexpand(1) copies the named files to standard output,
X replacing strings of space characters with a tab (^I),
X where this would reduce the number of characters in the
X file. If no files are specified then standard input is
X read.
X
X If the "-a" option is used then all sequences of spaces
X are converted, otherwise only leading blanks on each line
X are compressed. The tab stop is assumed to be every 8
X columns.
X
XSEE ALSO
X expand(1)
/
echo x - expand.c
sed '/^X/s///' > expand.c << '/'
X/* expand(1) Terrence W. Holm Feb. 1989 */
X
X/* Usage: expand [ -tab1,tab2,tab3,... ] [ file ... ] */
X
X#include <stdio.h>
X#include <string.h>
X
X#define MAX_TABS 32
X
X
Xmain( argc, argv )
X int argc;
X char *argv[];
X
X {
X int tabs[ MAX_TABS ];
X int tab_index = 0; /* Default one tab */
X int i;
X FILE *f;
X
X tabs[ 0 ] = 8; /* Default tab stop */
X
X if ( argc > 1 && argv[1][0] == '-' )
X {
X char *p = argv[1];
X int last_tab_stop = 0;
X
X for ( tab_index = 0; tab_index < MAX_TABS; ++tab_index )
X {
X if ( (tabs[ tab_index ] = atoi( p+1 )) <= last_tab_stop )
X {
X fprintf( stderr, "Bad tab stop spec\n" );
X exit( 1 );
X }
X
X last_tab_stop = tabs[ tab_index ];
X
X if ( (p = strchr( p+1, ',' )) == NULL )
X break;
X }
X
X --argc;
X ++argv;
X }
X
X if ( argc == 1 )
X Expand( stdin, tab_index, tabs );
X else
X for ( i = 1; i < argc; ++i )
X {
X if ( (f = fopen( argv[i], "r" )) == NULL )
X {
X perror( argv[i] );
X exit( 1 );
X }
X
X Expand( f, tab_index, tabs );
X fclose( f );
X }
X
X exit( 0 );
X }
X
X
X
X
Xint column = 0; /* Current column, retained between files */
X
X
XExpand( f, tab_index, tabs )
X FILE *f;
X int tab_index;
X int tabs[];
X
X {
X int next;
X int c;
X int i;
X
X while ( (c = getc( f )) != EOF )
X {
X if ( c == '\t' )
X {
X if ( tab_index == 0 )
X next = ( column / tabs[0] + 1 ) * tabs[0];
X else
X {
X for ( i = 0; i <= tab_index && tabs[i] <= column; ++i );
X
X if ( i > tab_index )
X next = column + 1;
X else
X next = tabs[i];
X }
X
X do {
X ++column;
X putchar( ' ' );
X } while ( column < next );
X
X continue;
X }
X
X if ( c == '\b' )
X column = column > 0 ? column - 1 : 0;
X else if ( c == '\n' || c == '\r' )
X column = 0;
X else
X ++column;
X
X putchar( c );
X }
X }
/
echo x - unexpand.c
sed '/^X/s///' > unexpand.c << '/'
X/* unexpand(1) Terrence W. Holm Feb. 1989 */
X
X/* Usage: unexpand [ -a ] [ file ... ] */
X
X#include <stdio.h>
X
X#define TAB 8
X
X
Xint column = 0; /* Current column, retained between files */
Xint spaces = 0; /* Spaces since last tab stop */
Xint leading_blank = 1; /* Only unexpand leading blanks, */
X /* overruled by -a option */
X
X
X
Xmain( argc, argv )
X int argc;
X char *argv[];
X
X {
X int all = 0; /* -a flag means unexpand all spaces */
X int i;
X FILE *f;
X
X if ( argc > 1 && argv[1][0] == '-' )
X {
X if ( strcmp( argv[1], "-a" ) == 0 )
X all = 1;
X else
X {
X fprintf( stderr, "Usage: unexpand [ -a ] [ file ... ]\n" );
X exit( 1 );
X }
X
X --argc;
X ++argv;
X }
X
X if ( argc == 1 )
X Unexpand( stdin, all );
X else
X for ( i = 1; i < argc; ++i )
X {
X if ( (f = fopen( argv[i], "r" )) == NULL )
X {
X perror( argv[i] );
X exit( 1 );
X }
X
X Unexpand( f, all );
X fclose( f );
X }
X
X
X /* If there are pending spaces print them. */
X
X while ( spaces > 0 )
X {
X putchar( ' ' );
X --spaces;
X }
X
X exit( 0 );
X }
X
X
X
X
XUnexpand( f, all )
X FILE *f;
X int all;
X
X {
X int c;
X
X while ( (c = getc( f )) != EOF )
X {
X if ( c == ' ' && (all || leading_blank) )
X {
X ++column;
X ++spaces;
X
X /* If we have white space up to a tab stop, then output */
X /* a tab. If only one space is required, use a ' '. */
X
X if ( column % TAB == 0 )
X {
X if ( spaces == 1 )
X putchar( ' ' );
X else
X putchar( '\t' );
X
X spaces = 0;
X }
X
X continue;
X }
X
X /* If a tab character is encountered in the input then */
X /* simply echo it. Any accumulated spaces can only be */
X /* since the last tab stop, so ignore them. */
X
X if ( c == '\t' )
X {
X column = ( column / TAB + 1 ) * TAB;
X spaces = 0;
X
X putchar( '\t' );
X continue;
X }
X
X /* A non-space character is to be printed. If there */
X /* are pending spaces, then print them. There will be */
X /* at most TAB-1 spaces to print. */
X
X while ( spaces > 0 )
X {
X putchar( ' ' );
X --spaces;
X }
X
X if ( c == '\n' || c == '\r' )
X {
X column = 0;
X leading_blank = 1;
X putchar( c );
X continue;
X }
X
X if ( c == '\b' )
X column = column > 0 ? column - 1 : 0;
X else
X ++column;
X
X leading_blank = 0;
X putchar( c );
X }
X }
/
----------------------------------------------------------