183 lines
4 KiB
C
183 lines
4 KiB
C
|
/*
|
||
|
** DETAB - replaces tabs with multiple spaces as appropriate
|
||
|
** tab width defaults to 8 but may be anything
|
||
|
** Steve Salisbury 1988-03-09 Wed
|
||
|
**
|
||
|
** 1989 Aug 30 Wed -- arg parsing was wrong
|
||
|
** 1989 Nov 01 Wed 12:00 add selection of non-space fill character
|
||
|
** 1991 Jan 14 Mon 18:20 fix selection of non-space fill character
|
||
|
** 1991 Jan 17 Thu 12:00 change message every 4KB to every 16KB
|
||
|
** allow command line argument for input file
|
||
|
** do not use big output buffer if stdout=con
|
||
|
**
|
||
|
** cl -G2s -Oaltr detab.c -o detab.exr -link slibcr libh /nod:slibce;
|
||
|
** cl detab -link slibcp libh /nod:slibce, detab;
|
||
|
*/
|
||
|
|
||
|
#include <fcntl.h>
|
||
|
#include <io.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#define SPACE ' '
|
||
|
#define TAB '\t'
|
||
|
#define TABWIDTH 8
|
||
|
|
||
|
#define REG register
|
||
|
|
||
|
#define NEWLINE(c) ( (c) == '\n' || (c) == '\r' || (c) == '\f' )
|
||
|
|
||
|
#ifndef BIGBUFSIZE
|
||
|
#define BIGBUFSIZE 8192
|
||
|
#endif
|
||
|
|
||
|
char inbuf [ BIGBUFSIZE ] ;
|
||
|
char outbuf [ BIGBUFSIZE ] ;
|
||
|
|
||
|
static char MsgInternalError [ ] = "detab: internal error: %s(%s)\n" ;
|
||
|
static char MsgOpenError [ ] = "detab: cannot open `%s' for input\n" ;
|
||
|
static char MsgWriteError [ ] = "detab: error writing to `%s'\n" ;
|
||
|
static char MsgStdin [ ] = "<stdin>" ;
|
||
|
static char MsgStdout [ ] = "<stdout>" ;
|
||
|
static char MsgSetmode [ ] = "setmode" ;
|
||
|
static char MsgSetvbuf [ ] = "setvbuf" ;
|
||
|
|
||
|
int main ( int argc , char * * argv )
|
||
|
{
|
||
|
REG int column ;
|
||
|
REG int ch ;
|
||
|
REG int spcount ;
|
||
|
FILE * input ;
|
||
|
char * MsgInput ;
|
||
|
int tabwidth = TABWIDTH ;
|
||
|
int countflag = 0 ;
|
||
|
long kilobytes ;
|
||
|
unsigned bytecount ;
|
||
|
char * cp ;
|
||
|
int FillChar = SPACE ; /* default character to use when detabbing */
|
||
|
|
||
|
while ( -- argc > 0 && * ( cp = * ++ argv ) == '-' )
|
||
|
{
|
||
|
++cp;
|
||
|
while (*cp)
|
||
|
{
|
||
|
if ( * cp == 'k' )
|
||
|
++ countflag , ++ cp ;
|
||
|
else if ( '0' <= * cp && * cp <= '9' )
|
||
|
{
|
||
|
tabwidth = * cp ++ - '0' ;
|
||
|
while ( '0' <= * cp && * cp <= '9' )
|
||
|
tabwidth = 10 * tabwidth + * cp ++ - '0' ;
|
||
|
}
|
||
|
else if ( * cp == 'c' )
|
||
|
{
|
||
|
FillChar = * ++ cp ;
|
||
|
++ cp ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Usage :
|
||
|
fprintf ( stderr ,
|
||
|
|
||
|
"Usage: detab [-cX -k -###] [inputfile]\n"
|
||
|
"where ### is the number of colums per tab stop (default=8)\n"
|
||
|
"-k selects progress reports (written to stderr) every 16 Kbytes\n"
|
||
|
"and X is the character to use for tabs (default is space)\n"
|
||
|
) ;
|
||
|
|
||
|
exit ( 1 ) ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( argc == 0 )
|
||
|
{
|
||
|
MsgInput = MsgStdin ;
|
||
|
input = stdin ;
|
||
|
|
||
|
if ( _setmode ( _fileno(stdin) , O_BINARY ) == -1 )
|
||
|
{
|
||
|
fprintf ( stderr , MsgInternalError , MsgSetmode , MsgStdin ) ;
|
||
|
exit ( -1 ) ;
|
||
|
}
|
||
|
}
|
||
|
else if ( argc == 1 )
|
||
|
{
|
||
|
MsgInput = * argv ;
|
||
|
if ( ! ( input = fopen ( MsgInput , "rb" ) ) )
|
||
|
{
|
||
|
fprintf ( stderr , MsgOpenError , MsgInput ) ;
|
||
|
exit ( 1 ) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
goto Usage ;
|
||
|
|
||
|
if ( setvbuf ( input , inbuf , _IOFBF , BIGBUFSIZE ) )
|
||
|
{
|
||
|
fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgInput ) ;
|
||
|
exit ( -1 ) ;
|
||
|
}
|
||
|
|
||
|
if ( _setmode ( _fileno(stdout) , O_BINARY ) == -1 )
|
||
|
{
|
||
|
fprintf ( stderr , MsgInternalError , MsgSetmode , MsgStdout ) ;
|
||
|
exit ( -1 ) ;
|
||
|
}
|
||
|
|
||
|
if ( ! _isatty ( _fileno ( stdin ) )
|
||
|
&& setvbuf ( stdout , outbuf , _IOFBF , BIGBUFSIZE ) )
|
||
|
{
|
||
|
fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgStdout ) ;
|
||
|
exit ( -1 ) ;
|
||
|
}
|
||
|
|
||
|
kilobytes = bytecount = 0 ;
|
||
|
|
||
|
column = 0 ;
|
||
|
|
||
|
while ( ( ch = getc ( input ) ) != EOF )
|
||
|
{
|
||
|
if ( ch == TAB )
|
||
|
{
|
||
|
do
|
||
|
putchar ( FillChar ) ;
|
||
|
while ( ++ column < tabwidth ) ;
|
||
|
column = 0 ;
|
||
|
}
|
||
|
else {
|
||
|
putchar ( ch ) ;
|
||
|
if ( NEWLINE(ch) )
|
||
|
column = 0 ;
|
||
|
else if ( ++ column == tabwidth )
|
||
|
column = 0 ;
|
||
|
else if ( column > tabwidth )
|
||
|
{
|
||
|
fprintf ( stderr , MsgInternalError , "" , "column>tabwidth" ) ;
|
||
|
return 1 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ++ bytecount >= 16384 )
|
||
|
{
|
||
|
bytecount -= 16384 ;
|
||
|
|
||
|
if ( countflag )
|
||
|
fprintf ( stderr , "%ldK\r" , kilobytes += 16 ) ;
|
||
|
|
||
|
if ( ferror ( stdout) )
|
||
|
{
|
||
|
fprintf ( stderr , MsgWriteError , MsgStdout ) ;
|
||
|
return 1 ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ferror ( stdout) || fflush ( stdout ) )
|
||
|
{
|
||
|
fprintf ( stderr , MsgWriteError , MsgStdout ) ;
|
||
|
return 1 ;
|
||
|
}
|
||
|
|
||
|
return 0 ;
|
||
|
}
|