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