home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / prof_c / 14view / vf_cmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-11  |  6.1 KB  |  264 lines

  1. /*
  2.  *    vf_cmd -- ViewFile command processor
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <local\std.h>
  10. #include <local\keydefs.h>
  11. #include <local\video.h>
  12. #include "vf.h"
  13. #include "message.h"
  14.  
  15. extern unsigned char Attr;
  16.  
  17. int
  18. vf_cmd(fp, fname, numbers)
  19. FILE *fp;
  20. char *fname;
  21. BOOLEAN numbers;
  22. {
  23.     register int i;        /* general index */
  24.     unsigned int offset;    /* horizontal scroll offset */
  25.     unsigned int n;        /* relative line number */
  26.     int memerr;        /* flag for memory allocation errors */
  27.     char *s, lbuf[MAXLINE];    /* input line buffer and pointer */
  28.     int k;            /* key code (see keydefs.h) */
  29.     int radix = 10;        /* base for number-to-character conversions */
  30.     char number[17];    /* buffer for conversions */
  31.     int errcount = 0;    /* error counter */
  32.     DNODE *tmp;        /* pointer to buffer control nodes */
  33.     DIRECTION srchdir;    /* search direction */
  34.     char *ss;        /* pointer to search string */
  35.     static char srchstr[MAXSTR] = { "" };    /* search string buffer */
  36.     DNODE *head;        /* pointer to starting node of text buffer list */
  37.     DNODE *current;        /* pointer to the current node (text line) */
  38.     static DNODE *freelist;    /* pointer to starting node of "free" list */
  39.                 /* initialized to 0 at runtime; retains value */
  40.  
  41.     /* function prototypes */
  42.     static void prtshift(int, int);
  43.     extern DNODE *vf_mklst();
  44.     extern DNODE *vf_alloc(int);
  45.     extern DNODE *vf_ins(DNODE *, DNODE *);
  46.     extern DNODE *vf_del(DNODE *, DNODE *);
  47.     extern DNODE *search(DNODE *, DIRECTION, char *);
  48.     extern DNODE *gotoln(DNODE *);
  49.     extern char *getxline(char *, int, FILE *);
  50.     extern char *getsstr(char *);
  51.     extern int clrscrn(unsigned char);
  52.     extern void showhelp(unsigned char);
  53.     extern void clrmsg();
  54.     extern void vf_dspy(DNODE *, DNODE *, int, BOOLEAN);
  55.     extern int putstr(char *, int);
  56.     extern int writec(char, int, int);
  57.     extern char *nlerase(char *);
  58.  
  59.     /* display the file name */
  60.     offset = 0;
  61.     putcur(HEADROW, 0, Vpage);
  62.     writec(' ', Maxcol[Vmode], Vpage);
  63.     putstr("File: ", Vpage);
  64.     putstr(fname, Vpage);
  65.  
  66.     /* establish the text buffer */
  67.     memerr = 0;
  68.     if ((head = vf_mklst()) == NULL)
  69.         ++memerr;
  70.     if (freelist == NULL && (freelist = vf_alloc(N_NODES)) == NULL)
  71.         ++memerr;
  72.     if (memerr) {
  73.         clean();
  74.         fprintf(stderr, "Memory allocation error\n");
  75.         exit(1);
  76.     }
  77.  
  78.     /* read the file into the buffer */
  79.     current = head;
  80.     n = 0;
  81.     while ((s = getxline(lbuf, MAXLINE, fp)) != NULL) {
  82.         /* add a node to the list */
  83.         if ((freelist = vf_ins(current, freelist)) == NULL)
  84.             ++memerr;
  85.         current = current->d_next;
  86.  
  87.         /* save the received text in a line buffer */
  88.         if ((current->d_line = strdup(nlerase(s))) == NULL)
  89.             ++memerr;
  90.         if (memerr) {
  91.             clean();
  92.             fprintf(stderr, "File too big to load\n");
  93.             exit(1);
  94.         }
  95.         current->d_lnum = ++n;
  96.         current->d_flags = 0;
  97.     }
  98.  
  99.     /* show the file size as a count of lines */
  100.     putstr(" (", Vpage);
  101.     putstr(itoa(current->d_lnum, number, radix), Vpage);
  102.     putstr(" lines)", Vpage);
  103.     prtshift(offset, Vpage);
  104.     current = head->d_next;
  105.     vf_dspy(head, current, offset, numbers);
  106.  
  107.     /* process user commands */
  108.     while ((k = getkey()) != K_ESC) {
  109.         clrmsg();
  110.         switch (k) {
  111.         case 'b':
  112.         case 'B':
  113.         case K_HOME:
  114.             current = head->d_next;
  115.             break;
  116.         case 'e':
  117.         case 'E':
  118.         case K_END:
  119.             current = head->d_prev;
  120.             i = NROWS - 1;
  121.             while (i-- > 0)
  122.                 if (current->d_prev != head->d_next)
  123.                     current = current->d_prev;
  124.             break;
  125.         case K_PGUP:
  126.         case 'u':
  127.         case 'U':
  128.             i = NROWS - OVERLAP;
  129.             while (i-- > 0)
  130.                 if (current != head->d_next)
  131.                     current = current->d_prev;
  132.             break;
  133.         case K_PGDN:
  134.         case 'd':
  135.         case 'D':
  136.             i = NROWS - OVERLAP;
  137.             while (i-- > 0)
  138.                 if (current != head->d_prev)
  139.                     current = current->d_next;
  140.             break;
  141.         case K_UP:
  142.         case '-':
  143.             if (current == head->d_next)
  144.                 continue;
  145.             current = current->d_prev;
  146.             break;
  147.         case K_DOWN:
  148.         case '+':
  149.             if (current == head->d_prev)
  150.                 continue;
  151.             current = current->d_next;
  152.             break;
  153.         case K_RIGHT:
  154.         case '>':
  155.         case '.':
  156.             if (offset < MAXLINE - SHIFTWIDTH)
  157.                 offset += SHIFTWIDTH;
  158.             prtshift(offset, Vpage);
  159.             break;
  160.         case K_LEFT:
  161.         case '<':
  162.         case ',':
  163.             if ((offset -= SHIFTWIDTH) < 0)
  164.                 offset = 0;
  165.             prtshift(offset, Vpage);
  166.             break;
  167.         case K_ALTG:
  168.         case 'g':
  169.         case 'G':
  170.             if ((tmp = gotoln(head)) == NULL)
  171.                 continue;
  172.             current = tmp;
  173.             break;
  174.         case K_ALTH:
  175.         case 'h':
  176.         case 'H':
  177.         case '?':
  178.             showhelp(Attr);
  179.             break;
  180.         case K_ALTN:
  181.         case 'n':
  182.         case 'N':
  183.             numbers = (numbers == TRUE) ? FALSE : TRUE;
  184.             break;
  185.         case K_ALTQ:
  186.         case 'q':
  187.         case 'Q':
  188.             clrscrn(Attr);
  189.             putcur(0, 0, Vpage);
  190.             return (-1);
  191.         case 'r':
  192.         case 'R':
  193.         case '\\':
  194.             srchdir = BACKWARD;
  195.             ss = getsstr(srchstr);
  196.             if (ss == NULL)
  197.                 /* cancel search */
  198.                 break;
  199.             if (strlen(ss) > 0)
  200.                 strcpy(srchstr, ss);
  201.             if ((tmp = search(current, srchdir, srchstr)) == NULL)
  202.                 continue;
  203.             current = tmp;
  204.             break;
  205.         case 's':
  206.         case 'S':
  207.         case '/':
  208.             srchdir = FORWARD;
  209.             ss = getsstr(srchstr);
  210.             if (ss == NULL)
  211.                 /* cancel search */
  212.                 break;
  213.             if (strlen(ss) > 0)
  214.                 strcpy(srchstr, ss);
  215.             if ((tmp = search(current, srchdir, srchstr)) == NULL)
  216.                 continue;
  217.             current = tmp;
  218.             break;
  219.         default:
  220.             /* ignore all other keys */
  221.             continue;
  222.         }
  223.         vf_dspy(head, current, offset, numbers);
  224.     }
  225.     clrmsg();
  226.  
  227.     /* release the allocated text buffer memory */
  228.     while (head->d_next != head) {
  229.         /* release text buffer */
  230.         free(head->d_next->d_line);
  231.  
  232.         /* put node back on the freelist */
  233.         freelist = vf_del(head->d_next, freelist);
  234.     }
  235.     /* release the list header node */
  236.     free((char *)head);
  237.  
  238.     return (errcount);
  239. }
  240.  
  241. /*
  242.  *    prtshift -- display the number of columns of horizontal shift
  243.  */
  244.  
  245. #define SHFTDSP    5
  246.  
  247. static void
  248. prtshift(amt, pg)
  249. int amt, pg;
  250. {
  251.     char number[17];
  252.     int radix = 10;
  253.  
  254.     /* clear the shift display area */
  255.     putcur(1, Maxcol[Vmode] - 1 - SHFTDSP, pg);
  256.     writec(' ', SHFTDSP, pg);
  257.  
  258.     /* display the new shift amount, if any */
  259.     if (amt > 0) {
  260.         putstr(itoa(amt, number, radix), pg);
  261.         putstr("->", pg);
  262.     }
  263. }
  264.