[comp.os.minix] expand

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  }
/
----------------------------------------------------------