/* filter.c - Don Yang (uguu.org) Remove trailing whitespaces. Usage: filter Process stdin to stdout filter Process to stdout filter - Process stdin to filter Process to filter Modify inplace 05/11/02 */ /*@ -branchstate -compdef -usedef -usereleased @*/ #include #include #include static int Filter(FILE *infile, FILE *outfile); static int Inplace(char *filename); /******************************************************************** main */ int main(int argc, char **argv) { FILE *infile, *outfile; int status; infile = stdin; outfile = stdout; if( argc > 1 ) { if( strcmp(argv[1], "-") != 0 ) { if( (infile = fopen(argv[1], "rb")) == NULL ) return fprintf(stderr, "Can not open %s\n", argv[1]); } if( argc > 2 ) { if( infile != stdin && strcmp(argv[1], argv[2]) == 0 ) { (void)fclose(infile); return Inplace(argv[1]); } if( (outfile = fopen(argv[2], "wb+")) == NULL ) return fprintf(stderr, "Can not create %s\n", argv[2]); } } status = Filter(infile, outfile); if( infile != stdin ) (void)fclose(infile); if( outfile != stdout ) (void)fclose(outfile); return status; } /* main() */ /****************************************************************** Filter */ static int Filter(FILE *infile, FILE *outfile) { char *buffer, *tmpbuffer; size_t bufsize, bufindex; int c; if( (buffer = (char*)malloc(bufsize = 0x1000)) == NULL ) { fprintf(stderr, "Not enough memory\n"); return 1; } bufindex = 0; while( (c = fgetc(infile)) != EOF ) { if( c == (int)'\r' || c == (int)'\n' ) { if( fputc(c, outfile) == EOF ) { fprintf(stderr, "Write error\n"); free(buffer); return 1; } bufindex = 0; } else if( c == (int)' ' || c == (int)'\t' ) { buffer[bufindex++] = (char)c; if( bufindex >= bufsize ) { tmpbuffer = (char*)realloc(buffer, bufsize *= 2); if( tmpbuffer == NULL ) { if( (tmpbuffer = (char*)malloc(bufsize)) == NULL ) { fprintf(stderr, "Not enough memory\n"); free(buffer); return 1; } memcpy(tmpbuffer, buffer, bufsize / 2); free(buffer); buffer = tmpbuffer; } } } else { if( bufindex > 0 ) { if( fwrite(buffer, bufindex, 1, outfile) != 1 ) { fprintf(stderr, "Write error\n"); free(buffer); return 1; } bufindex = 0; } if( fputc(c, outfile) == EOF ) { fprintf(stderr, "Write error\n"); free(buffer); return 1; } } } free(buffer); return 0; } /* Filter() */ /***************************************************************** Inplace */ static int Inplace(char *filename) { char tmpname[16]; FILE *file, *tmpfile; int i; if( (file = fopen(filename, "rb")) == NULL ) { fprintf(stderr, "Can not open %s\n", filename); return 1; } for(i = 0; i < 32768; i++) { sprintf(tmpname, "tmp.%d", i); if( (tmpfile = fopen(tmpname, "rb")) == NULL ) { if( (tmpfile = fopen(tmpname, "wb+")) == NULL ) continue; if( Filter(file, tmpfile) != 0 ) { (void)fclose(file); (void)fclose(tmpfile); (void)remove(tmpname); return 1; } break; } } (void)fclose(file); if( i >= 32768 ) { (void)fputs("Can not create temporary file\n", stderr); return 1; } (void)fclose(tmpfile); if( remove(filename) != 0 ) { fprintf(stderr, "Can not remove %s\n", filename); return 1; } if( rename(tmpname, filename) != 0 ) { fprintf(stderr, "Can not rename %s to %s\n", tmpname, filename); return 1; } return 0; } /* Inplace() */