home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / SUPER_C.ZIP / RSORT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1980-01-01  |  6.7 KB  |  220 lines

  1. /*             RAM Sort Main Program
  2.  
  3.         This program reads the standard input into RAM, sorts
  4.         it by line, and writes it back out again.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "rsort.h"
  10.  
  11. /*      main(argc,argv)
  12.  
  13.         Function: Read the standard input into memory, sort it, and
  14.         write it to the standard output. If there's a switch "/+<n>",
  15.         then sort starting at column <n>.
  16.  
  17.         Algorithm: Call readLines to read it in, offLines to adjust
  18.         the sort column if the appropriate switch is present, sortLines
  19.         to sort it, and writeLines to write it out. If CALIBRATE is
  20.         defined, skip the reading and writing and fill the buffer up
  21.         with hard-to-sort stuff; this is used to check the timing.
  22. */
  23.  
  24. main(argc,argv)
  25.  
  26. int argc;
  27. char *argv[];
  28.  
  29. {
  30.         int i;
  31.  
  32.         /* Read in the lines, or fill up the buffer with test data. */
  33. #ifdef CALIBRATE
  34.         fillLines();
  35.         puts("Starting sort...");
  36. #ifdef HIST
  37.         startH();
  38. #endif HIST
  39. #else CALIBRATE
  40.         readLines();
  41. #endif CALIBRATE
  42.  
  43.         /* Check for a starting column parameter. */
  44.         for (i = 1; i < argc; i++)
  45.                 if ((argv[i][0] == '/') && (argv[i][1] == '+'))
  46.                         /* Column sort switch found, so set the
  47.                            columns to sort from. */
  48.                         offLines(atoi(&argv[i][2])-1);
  49.  
  50.         /* Sort the lines. */
  51.         sortLines();
  52.  
  53.         /* Write the lines back out again. */
  54. #ifdef CALIBRATE
  55. #ifdef HIST
  56.         endH();
  57. #endif HIST
  58.         puts("done.\n");
  59. #else CALIBRATE
  60.         writeLines();
  61. #endif CALIBRATE
  62. }
  63.  
  64. /*      fillLines()
  65.  
  66.         Function: Fill the buffer with fake (and hard-to-sort) data.
  67.  
  68.         Algorithm: Fill up ten-character lines until out of buffer space.
  69.  
  70.         Comments: Remember, this is intended to calibrate the speed
  71.         of the sort, not to test it. This isn't necessarily the worst
  72.         case for the program, just a case that takes time.
  73. */
  74.  
  75. fillLines()
  76.  
  77. {
  78.         char *bPtr;             /* Pointer into buffer. */
  79.         char fakeIn[10];        /* Current fill string. */
  80.         char *fPtr;             /* Pointer into fakeIn. */
  81.  
  82.         /* Start with "ZZZZZZZZZZ". */
  83.         for (fPtr = fakeIn; fPtr < &fakeIn[9]; *fPtr++ = 'Z');
  84.         fakeIn[9] = 0;
  85.  
  86.         /* Fill in the buffer. */
  87.         for (bPtr = buffer, nextLPtr = lPtr;
  88.              (bPtr < &buffer[BUFSIZE-10]) &&
  89.               (nextLPtr < &lPtr[LPTRSIZE]);
  90.              nextLPtr++) {
  91.                 /* Set the line pointer entry for this line. */
  92.                 nextLPtr->start = nextLPtr->sortAt = bPtr;
  93.                 /* Get the next string ("Z...ZZ" -> "Z...ZY", etc.). */
  94.                 for (fPtr = &fakeIn[8]; fPtr >= fakeIn; fPtr--)
  95.                         if ((*fPtr)-- == 'A') *fPtr = 'Z';
  96.                         else break;
  97.                 /* Copy it into the buffer. */
  98.                 strcpy(bPtr,fakeIn);
  99.                 bPtr += 10;
  100.         };
  101. }
  102.  
  103. /*      readLines()
  104.  
  105.         Function: Read all the lines on the standard input into
  106.         the buffer array, and set the lPtr array to point to each
  107.         line in the buffer.
  108.  
  109.         Algorithm: Repeatedly call gets() until we've read the
  110.         whole thing in. But make sure we don't overflow any of
  111.         the arrays in the process.
  112.  
  113.         Comments: Note that there is no way with gets() to ensure
  114.         that it doesn't overflow the buffer. For example, suppose
  115.         we've almost filled up the buffer, and then get a very long
  116.         line. Whatever is in memory after the buffer will get
  117.         overwritten. This is a flaw in the standard I/O library,
  118.         but not one we'll take the time to fix here. We will simply
  119.         exit ASAP so it can't do very much damage.
  120. */
  121.  
  122. readLines()
  123.  
  124. {
  125.         char *bPtr;   /* Pointer into buffer. */
  126.  
  127.         /* Fill in the buffer from standard input. */
  128.         for (bPtr = buffer, nextLPtr = lPtr;
  129.              (bPtr < &buffer[BUFSIZE]) &&
  130.               (nextLPtr < &lPtr[LPTRSIZE]) &&
  131.               (gets(bPtr) != NULL);
  132.              nextLPtr->start = nextLPtr->sortAt = bPtr, nextLPtr++,
  133.               bPtr += strlen(bPtr)+1);
  134.         /* Check for errors. */
  135.         if (bPtr >= &buffer[BUFSIZE])
  136.                 fatal("Input too large for RAM sort");
  137.         if (nextLPtr >= &lPtr[LPTRSIZE])
  138.                 fatal("Input has too many lines");
  139. }
  140.  
  141. /*      writeLines()
  142.  
  143.         Function: Write all the lines pointed to by the lPtr array
  144.         (presumably they're in the buffer) to the standard output.
  145.  
  146.         Algorithm: Cycle thru the lines and call puts() for each one.
  147.  
  148.         Comments: This routine does not depend on the lines being in
  149.         the buffer; they could be anywhere in the data segment. We
  150.         don't use this feature - or rather lack of restriction - here,
  151.         but it could be useful at some future date.
  152. */
  153.  
  154. writeLines()
  155.  
  156. {
  157.         struct linePtr *lPPtr;  /* Line pointer pointer. */
  158.  
  159.         /* Write out each line. */
  160.         for (lPPtr = lPtr; lPPtr < nextLPtr; puts((lPPtr++)->start));
  161. }
  162.  
  163. /*      offLines(offset)
  164.  
  165.         Function: Start search from offset characters after the
  166.         start of the line.
  167.  
  168.         Algorithm: Go thru the line pointer table and bump the
  169.         sortAt field to point offset bytes past the start field;
  170.         make sure, however, that it doesn't end up pointing past
  171.         the end of the line.
  172. */
  173.  
  174. offLines(offset)
  175.  
  176. int offset;
  177.  
  178. {
  179.         struct linePtr *lPPtr;  /* Line pointer pointer. */
  180.         int i;                  /* Byte count. */
  181.         char *cp;               /* Pointer into line. */
  182.  
  183.         /* If there's nothing to do, don't do it. */
  184.         if (offset <= 0) return;
  185.  
  186.         /* Update each line in the array. */
  187.         for (lPPtr = lPtr; lPPtr < nextLPtr; lPPtr++) {
  188.                 /* Find the byte, correcting for end-of-line. */
  189.                 for (i = offset, cp = lPPtr->start;
  190.                      (i > 0) && (*cp != 0); i--, cp++);
  191.                 /* Set the sortAt pointer. */
  192.                 lPPtr->sortAt = cp;
  193.         };
  194. }
  195.  
  196. /*      fatal(s)
  197.  
  198.         Function: Report fatal errors and then exit to the system.
  199.         s is a pointer to a string that describes the error.
  200.  
  201.         Algorithm: Calls fputs() to write the error message to the
  202.         standard error output stream. Then call exit() to abort
  203.         execution.
  204.  
  205.         Comments: The C library has perror() and abort() routines,
  206.         but this is slightly more portable.
  207. */
  208.  
  209. fatal(s)
  210.  
  211. char *s;
  212.  
  213. {
  214.         fputs("Fatal error: ",stderr);
  215.         fputs(s,stderr);
  216.         fputs(".\n",stderr);
  217.         exit(1);
  218. }
  219.  
  220.