/* revpar - reverse a file by paragraphs ** ** Copyright (C) 1991,1994,2001 by Jef Poskanzer . ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. */ #include #include #include #include static void readpars( FILE* f ); static void* malloc_check( size_t size ); static void* realloc_check( void* ptr, size_t size ); static char* strdup_check( char* str ); static void check( void* ptr ); static char* argv0; static int npars, maxpars; static char*** pars; static int nlines, maxlines; static char** lines; int main( int argc, char** argv ) { FILE* f; int i; char** lp; argv0 = argv[0]; maxpars = 100; pars = (char***) malloc_check( maxpars * sizeof(char**) ); npars = 0; if ( argc == 1 ) readpars( stdin ); else for ( i = 1; i < argc; ++i ) { if ( strcmp( argv[i], "-" ) == 0 ) readpars( stdin ); else { f = fopen( argv[i], "r" ); if ( f == (FILE*) 0 ) { perror( argv[i] ); exit( 1 ); } readpars( f ); fclose( f ); } } for ( i = npars - 1; i >= 0; --i ) { for ( lp = pars[i]; *lp != (char*) 0; ++lp ) fputs( *lp, stdout ); if ( i > 0 ) fputs( "\n", stdout ); } exit( 0 ); } static void readpars( FILE* f ) { char line[30000]; maxlines = 100; lines = (char**) malloc_check( maxlines * sizeof(char*) ); nlines = 0; while ( fgets( line, sizeof(line), f ) != NULL ) { /* Is it a blank line? */ if ( line[0] == '\n' || line[0] == '\r' ) { if ( nlines != 0 ) /* ignore multiple blank lines */ { /* Save previous paragraph. */ if ( npars >= maxpars ) { maxpars *= 2; pars = (char***) realloc_check( (void*) pars, maxpars * sizeof(char**) ); } pars[npars] = lines; ++npars; /* Start new paragraph. */ maxlines = 100; lines = (char**) malloc_check( maxlines * sizeof(char*) ); nlines = 0; } } else { /* Save this line. */ if ( nlines >= maxlines ) { maxlines *= 2; lines = (char**) realloc_check( (void*) lines, maxlines * sizeof(char*) ); } lines[nlines] = strdup_check( line ); ++nlines; } } /* Save last paragraph. */ if ( nlines != 0 ) { if ( npars >= maxpars ) { maxpars *= 2; pars = (char***) realloc_check( (void*) pars, maxpars * sizeof(char**) ); } pars[npars] = lines; ++npars; } } static void* malloc_check( size_t size ) { void* ptr = malloc( size ); check( ptr ); return ptr; } static void* realloc_check( void* ptr, size_t size ) { ptr = realloc( ptr, size ); check( ptr ); return ptr; } static char* strdup_check( char* str ) { str = strdup( str ); check( (void*) str ); return str; } static void check( void* ptr ) { if ( ptr == (void*) 0 ) { (void) fprintf( stderr, "%s: out of memory\n", argv0 ); exit( 1 ); } }