home *** CD-ROM | disk | FTP | other *** search
- /*=========================================================================*/
- /* reverse.c */
- /*=========================================================================*/
- /* Reverse a text file so that the first line becomes the last, etc. */
- /*=========================================================================*/
- /* Copyright (c) 1988 by James W. Leth */
- /*=========================================================================*/
-
- #include <stdio.h>
-
- /* Limiting parameters */
- #define VERSION 10
- #define MAX_LINES 10000
- #define LINE_LENGTH 256
-
- /*=========================================================================*/
- /* TRACE macros. If the symbol DEBUG is defined (i.e. via -DDEBUG on the */
- /* command line of the compile command), then these macros will display */
- /* messages on the standard error stream, with or without additional */
- /* fprintf-style arguments. Otherwise, they will do nothing. When the */
- /* program is debugged, these statements can all be deactivated by */
- /* compiling without the DEBUG flag set; the statements don't have to */
- /* be removed from the source code. */
- /* */
- /*=========================================================================*/
-
- #ifdef DEBUG
- #define DOTRACE fprintf(stderr, "TRACE:\t")
- #define TRACE(msg) DOTRACE;fprintf(stderr, msg)
- #define TRACE1(msg, a) DOTRACE;fprintf(stderr, msg, a)
- #define TRACE2(msg, a, b) DOTRACE;fprintf(stderr, msg, a, b)
- #define TRACE3(msg, a, b, c) DOTRACE;fprintf(stderr, msg, a, b, c)
- #define TRACE4(msg, a, b, c, d) DOTRACE;fprintf(stderr, msg, a, b, c, d)
- #else
- #define TRACE(msg)
- #define TRACE1(msg, a)
- #define TRACE2(msg, a, b)
- #define TRACE3(msg, a, b, c)
- #define TRACE4(msg, a, b, c, d)
- #endif
-
-
-
- /* This table is used to keep track of the seek position of the source
- * file at the start of each line.
- */
- long lineSeek[MAX_LINES];
-
-
- void
- usage(void)
- {
- fprintf(stderr, "REVERSE Version %d.%d\n", VERSION / 10, VERSION % 10);
- fprintf(stderr, "Usage:\treverse source-file target-file\n");
- fprintf(stderr, "\tCopies each line of source-file into target-file,\n");
- fprintf(stderr, "\tin reverse order (the first line becomes the last, etc.).\n");
- fprintf(stderr, "\tCurrent limitations: %d lines, %d chars/line.\n",
- MAX_LINES, LINE_LENGTH-1);
- }
-
-
- /*=========================================================================*/
- /* */
- /* M A I N */
- /* */
- /*=========================================================================*/
-
- void
- main (int argc, char **argv)
- {
- char line[LINE_LENGTH];
- FILE *source, *target;
- int lineNum;
- int c;
-
- if (argc != 3)
- {
- usage();
- exit(1);
- }
-
- /* Open the source and target files. */
- if ((source = fopen(argv[1], "r")) == NULL)
- {
- perror("Can't open source file");
- usage();
- exit(1);
- }
- if ((target = fopen(argv[2], "w")) == NULL)
- {
- perror("Can't create target file");
- usage();
- exit(1);
- }
-
- /* Read the source file, building a seek table for the start of each
- * line.
- */
- lineSeek[0] = 0L;
- for (lineNum = 1; lineNum < MAX_LINES;)
- {
- if ((c = getc(source)) == EOF)
- {
- break;
- }
- if (c == '\n')
- {
- lineSeek[lineNum] = ftell(source);
- TRACE2("Line %d found at position %ld\n", lineNum, lineSeek[lineNum]);
- ++lineNum;
- }
- }
-
- /* Now walk backwards through the seek table, copying the lines in
- * reverse order from the source file to the target file. LineNum
- * now contains 1 more than the highest value for which there is
- * a seek table entry.
- */
-
- while (lineNum-- > 0)
- {
- TRACE2("Seeking line %d at position %ld\n", lineNum, lineSeek[lineNum]);
- if (fseek(source, lineSeek[lineNum], SEEK_SET) != 0)
- {
- perror("Seek failed");
- break;
- }
-
- if (fgets(line,LINE_LENGTH,source) != NULL)
- {
- fputs(line, target);
- }
- }
-
- /* Close the files */
- fclose(source);
- fclose(target);
- }
-