/* ** TOLWRUPR - translate [a-z] to [A-Z] or vice versa or both (!) ** ** 1994-08-19 Fri - original version, based on DTOX, which translated ** If the output is the console, case line buffering is used. ** CR+LF newlines (MS-DOS) to LF-only newlines (XENIX). ** ** This program (tolwrupr) is equivalent to: ** ** tolwrupr -L: tr "[a-z]" "[A-Z]" ** tolwrupr -U: tr "[A-Z]" "[a-z]" ** tolwrupr -X: tr "[A-Z][a-z]" "[a-z][A-Z]" */ #include #include #include #include #define CR '\r' #define LF '\n' #define REG register #ifndef BIGBUFSIZE #define BIGBUFSIZE 16384 #endif char inbuf [ BIGBUFSIZE ] ; char outbuf [ BIGBUFSIZE ] ; int LineBuf; static char MsgInternalError [ ] = "tolwrupr: internal error: %s(%s)\n" ; static char MsgOpenError [ ] = "tolwrupr: cannot open `%s' for input\n" ; static char MsgStdin [ ] = "stdin" ; static char MsgStdout [ ] = "stdout" ; static char MsgSetmode [ ] = "setmode" ; static char MsgSetvbuf [ ] = "setvbuf" ; static char MsgFflush [ ] = "fflush" ; static unsigned char map [ 256 ] ; int main ( int argc , char * * argv ) ; void Usage ( void ) ; int main ( int argc , char * * argv ) { REG int ch ; int countflag = 0 ; int toupperflag = -1 ; unsigned kilobytes ; unsigned bytecount ; char * MsgInput ; FILE * input ; char * cp ; -- argc ; ++ argv ; while ( argc > 0 && * ( cp = * argv ) == '-' ) { while ( * ++ cp ) { if ( * cp == 'k' ) { if ( countflag != 0 ) Usage ( ) ; countflag = 1 ; } else if ( * cp == 'L' ) { if ( toupperflag != -1 ) Usage ( ) ; toupperflag = 0 ; } else if ( * cp == 'U' ) { if ( toupperflag != -1 ) Usage ( ) ; toupperflag = 1 ; } else if ( * cp == 'X' ) { if ( toupperflag != -1 ) Usage ( ) ; toupperflag = 2 ; } else { Usage ( ) ; } } -- argc ; ++ argv ; } /* * Either -U or -L must be specified! */ if ( toupperflag == -1 ) Usage ( ) ; for ( ch = 0 ; ch < 256 ; ++ ch ) map [ ch ] = ch ; /* * Set the case map */ if ( toupperflag == 1 || toupperflag == 2 ) { for ( ch = 'a' ; ch <= 'z' ; ++ ch ) map [ ch ] -= 'a' - 'A' ; } if ( toupperflag == 0 || toupperflag == 2 ) { for ( ch = 'A' ; ch <= 'Z' ; ++ ch ) map [ ch ] += 'a' - 'A' ; } /* * Open the Input */ 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 Usage ( ) ; if ( _setmode ( _fileno ( stdout ) , _O_BINARY ) == -1 ) { fprintf ( stderr , MsgInternalError , MsgSetmode , MsgStdout ) ; exit ( -1 ) ; } if ( setvbuf ( input , inbuf , _IOFBF , BIGBUFSIZE ) ) { fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgInput ) ; exit ( -1 ) ; } if ( setvbuf ( stdout , outbuf , _IOFBF , BIGBUFSIZE ) ) { fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgStdout ) ; exit ( -1 ) ; } /* check for the need for line buffering */ LineBuf = _isatty ( _fileno ( stdout ) ) ; /* * Process the Input */ kilobytes = bytecount = 0 ; while ( ( ch = getc ( input ) ) != EOF ) { ch = map [ ch ] ; putc ( ch , stdout ) ; if (ch == '\n' && LineBuf) fflush ( stdout ) ; if ( countflag ) if ( ++ bytecount >= BIGBUFSIZE ) { bytecount -= BIGBUFSIZE ; fprintf ( stderr , "%uK\r" , kilobytes += ( BIGBUFSIZE / 1024 ) ) ; } } if ( fflush ( stdout ) ) { fprintf ( stderr , MsgInternalError , MsgFflush , MsgStdout ) ; return 1 ; } return 0 ; } void Usage ( void ) { fprintf ( stderr , "Usage: tolwrupr [-k] -(L|U|X) [ ]\n" "-k means echo progress in kilobytes to stderr\n" "-L means map lowercase characters to uppercase (tr \"[A-Z]\" \"[a-z]\")\n" "-U means map uppercase characters to lowercase (tr \"[a-z]\" \"[A-Z]\")\n" "-X means swap uppercase and lowercase (tr \"[a-z][A-Z]\" \"[A-Z][a-z]\")\n" "Exactly one of -L or -U or -X must be specified\n" ) ; exit ( 1 ) ; }