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

  1. /*                      Show Text File Utility
  2.  
  3.         This program displays a text file on the screen and redisplays
  4.         it according to the user's use of the page-up, page-down,
  5.         up-arrow, down-arrow, 'u', and 'd' keys. It exits when the user
  6.         types either 'q' or ESC.
  7. */
  8.  
  9. #include <stdio.h>
  10.  
  11. #define CALIBRATE       /* If defined, display pages 21 times for timing. */
  12.  
  13. /*#define VANILLA*/     /* Define for vanilla, TTY style output. */
  14. /*#define ANSI*/        /* Define for ANSI.SYS style output. */
  15. #define ROMBIOS         /* Define for ROM BIOS style output. */
  16.  
  17. #define MAXLINES 10000  /* Maximum number of lines in file. */
  18.  
  19. #define LINESIZE 200    /* Maximum number of characters in a line. */
  20.  
  21. FILE *inFile;           /* File identifier for file to be displayed. */
  22.  
  23. int curLine;            /* Where to start displaying from. */
  24.  
  25. struct cmdType {        /* Command table entry form. */
  26.  char cmdKey;           /* The key code or ASCII value. */
  27.  int (*cmdFunc)();      /* The function to call. */
  28.  int cmdParm;           /* The parameter to pass to it. */
  29. };
  30.  
  31. int upLines(), quitIt();
  32.  
  33. struct cmdType keyTab[] = {     /* Normal key table. */
  34.         'u', upLines, 20,       /* 'u' key: scroll backward 20 lines. */
  35.         'U', upLines, 20,       /* 'U' key: scroll backward 20 lines. */
  36.         'd', upLines, -20,      /* 'd' key: scroll forward 20 lines. */
  37.         'D', upLines, -20,      /* 'D' key: scroll forward 20 lines. */
  38.         'q', quitIt, 0,         /* 'q' key: quit. */
  39.         'Q', quitIt, 0,         /* 'Q' key: quit. */
  40.         033, quitIt, 0,         /* ESC key: quit. */
  41.         0, quitIt, 0            /* End-of-table. */
  42. };
  43.  
  44. struct cmdType zKeyTab[] = {    /* Zero-prefix key table. */
  45.         72, upLines, 1,         /* Up-arrow key: scroll backward 1 line. */
  46.         73, upLines, 20,        /* Up-page key: scroll backward 20 lines. */
  47.         80, upLines, -1,        /* Down-arrow key: scroll forward 1 line. */
  48.         81, upLines, -20,       /* Down-page key: scroll forward 20 lines. */
  49.         0, quitIt, 0            /* End-of-table. */
  50. };
  51.  
  52. long lineStart[MAXLINES];       /* Offsets from start of file to lines. */
  53. long *nextStart;                /* Pointer to next available line start. */
  54.  
  55. #define TRUE 1
  56. #define FALSE 0
  57.  
  58. /*      main(argc,argv)
  59.  
  60.         Function: Display a text file on the screen.
  61.  
  62.         Algorithm: Start at the beginning of the file. Display a page, 
  63.         reading the file as needed. Then repeatedly wait for keyboard
  64.         input, and take the appropriate action based on it.
  65. */
  66.  
  67. main(argc,argv)
  68.  
  69. int argc;
  70. char *argv[];
  71.  
  72. {
  73.         int i;
  74.  
  75.         /* Check that the user gave us the right number of command
  76.            line parameters. */
  77.         if (argc != 2) {
  78.                 /* If not, tell him what's wrong and exit. */
  79.                 puts("Usage: show <filename>\n");
  80.                 exit(1);
  81.         };
  82.  
  83.         /* Open the input file, if possible. */
  84.         if ((inFile = fopen(argv[1],"r")) == NULL) {
  85.                 /* If it wouldn't open, let the user know and exit. */
  86.                 puts("Couldn't open input file.\n");
  87.                 exit(1);
  88.         };
  89.  
  90.         /* Start at the first line in the file. */
  91.         curLine = 0;
  92.         /* Set the file offset for that line in the line start array. */
  93.         lineStart[0] = 0L;
  94.         /* Set nextStart to indicate that this is the only entry we've
  95.            filled in in lineStart so far. */
  96.         nextStart = &lineStart[1];
  97.  
  98.         /* Repeatedly display a page, and then get and execute commands. */
  99.         do {
  100.  
  101. #ifdef CALIBRATE
  102.                 /* If we're going to calibrate, repeat the following page
  103.                    display 20 times. */
  104.                 for (i = 20; i > 0; i--)
  105. #endif CALIBRATE
  106.  
  107.                         showPage();
  108.         } while (!nextCommand());
  109. }
  110.  
  111. /*      nextCommand()
  112.  
  113.         Function: Get and execute the next keyboard command. Return
  114.         TRUE if it's time to quit.
  115.  
  116.         Algorithm: Get the keyboard input using getch. It then looks
  117.         the character up in the keyTab or zKeyTab tables and executes 
  118.         the function found there (if any). Finally, it returns the value 
  119.         returned by the executed function.
  120. */
  121.  
  122. nextCommand()
  123.  
  124. {
  125.         char c;                 /* The input from the user. */
  126.         struct cmdType *cPtr;   /* A pointer into the command table. */
  127.  
  128.         /* Get the command from the user. */
  129.         c = getch();
  130.         /* If it isn't an extended code, use the ASCII command table. */
  131.         if (c != 0) cPtr = keyTab;
  132.         /* Otherwise, get the second character (the scan code), and use
  133.            the scan code command table. */
  134.         else {
  135.                 c = getch();
  136.                cPtr = zKeyTab;
  137.         };
  138.  
  139.         /* Search thru the command table for the user input value. */
  140.         for (; cPtr->cmdKey != 0; cPtr++)
  141.                 if (cPtr->cmdKey == c)
  142.                         /* If we found it, execute it. */
  143.                         return((*cPtr->cmdFunc)(cPtr->cmdParm));
  144.  
  145.         /* If we didn't find it in the table, don't do anything at all. */
  146.         return(FALSE);
  147. }
  148.  
  149. /*      quitIt(dummy)
  150.  
  151.         Function: Quit command.
  152.  
  153.         Algorithm: Just return TRUE.
  154. */
  155.  
  156. quitIt(dummy)
  157.  
  158. int dummy;
  159.  
  160. {
  161.          return(TRUE);
  162. }
  163.  
  164. /*      upLines(num)
  165.  
  166.         Function: Move the window up by num lines (may be negative).
  167.  
  168.         Algorithm: Just adjust curLine.
  169.  
  170.         Comments: The actual change in the display will be done by
  171.         the showPage function.
  172. */
  173.  
  174. upLines(num)
  175.  
  176. int num;
  177.  
  178. {
  179.         /* Adjust the curLine global. */
  180.         curLine -= num;
  181.         /* But make sure we don't move back past the beginning of the file. */
  182.         if (curLine < 0) curLine = 0;
  183.         /* Return FALSE -- i.e., don't quit. */
  184.         return(FALSE);
  185. }
  186.  
  187. /*      showPage()
  188.  
  189.         Function: Display the page starting at curLine.
  190.  
  191.         Algorithm: First, clear the screen. Second, make sure that
  192.         the line start array has the first line to be displayed.
  193.         Then, starting at the first line on the screen, read and
  194.         display each visible line.
  195. */
  196.  
  197. showPage()
  198.  
  199. {
  200.         int i,j;
  201.         long *lineStPtr;        /* Pointer into the line start array. */
  202.         char line[LINESIZE];    /* Buffer into which to read lines. */
  203.  
  204.         /* Clear the screen. */
  205.         clrScreen();
  206.  
  207.         /* Make sure the first line offset is in the line start array. */
  208.         while (&lineStart[curLine] >= nextStart)
  209.                 readLine(nextStart,line);
  210.  
  211.         /* For each line to be displayed... */
  212.         for (lineStPtr = &lineStart[curLine], i = 24; i; i--, lineStPtr++) {
  213.                 /* Read the line in. */
  214.                 readLine(lineStPtr,line);
  215.                 /* And display it. */
  216.                 dispLine(line);
  217.         };
  218. }
  219.  
  220. /*      readLine(lStPtr,lBuf)
  221.  
  222.         Function: Read the line whose line start array entry is pointed
  223.         to by lStPtr into the buffer pointed to by lBuf.
  224.  
  225.         Algorithm: Use fseek to position the file to the line requested,
  226.         then read it in with fgets. Finally, set the next entry in the
  227.         line start array to the file position after the read.
  228.  
  229.         Comments: The line start array entry pointed to by lStPtr must
  230.         have been filled in already or the results of calling this
  231.         function are undefined.
  232. */
  233.  
  234. readLine(lStPtr,lBuf)
  235.  
  236. long *lStPtr;
  237. char *lBuf;
  238.  
  239. {
  240.         /* Position the file to the line requested. */
  241.         fseek(inFile,*lStPtr,0);
  242.         /* Read in the line. */
  243.         fgets(lBuf,LINESIZE,inFile);
  244.         /* Record the offset to the next line in the file. */
  245.         if (lStPtr == (nextStart-1)) *nextStart++ = ftell(inFile);
  246. }
  247.  
  248. /*      clrScreen(), dispLine(lBuf)
  249.  
  250.         Function: Clear the screen (clrScreen()) or display a line (dispLine())
  251.  
  252.         Algorithm: The algorithm depends on which of VANILLA, ANSI, and
  253.         ROMBIOS are defined. See the main text of the chapter for more
  254.         details.
  255. */
  256.  
  257. clrScreen()
  258.  
  259. {
  260. #ifdef VANILLA
  261.         int i;
  262.  
  263.         /* Write blank lines to scroll everything off the screen. */
  264.         for (i = 0; i < 25; i++) dispLine("\n");
  265. #endif VANILLA
  266.  
  267. #ifdef ANSI
  268.         /* Send the ANSI clear screen sequence. */
  269.         fputs("\033[2J",stdout);
  270. #endif ANSI
  271.  
  272. #ifdef ROMBIOS
  273.         /* Call the ROM BIOS to clear the screen for us. */
  274.         scrClr();
  275. #endif ROMBIOS
  276. }
  277.  
  278. dispLine(lBuf)
  279.  
  280. char *lBuf;
  281.  
  282. {
  283. #ifdef VANILLA
  284.         /* Use the regular standard output routines. */
  285.         fputs(lBuf,stdout);
  286. #endif VANILLA
  287.  
  288. #ifdef ANSI
  289.         /* Use the regular standard output routine. */
  290.         fputs(lBuf,stdout);
  291. #endif ANSI
  292.  
  293. #ifdef ROMBIOS
  294.         /* Call the ROM BIOS. */
  295.         scrPuts(lBuf); scrPuts("\r");
  296. #endif ROMBIOS
  297. }
  298.  
  299.