home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff256.lzh / Stevie / fileio.c < prev    next >
C/C++ Source or Header  |  1989-10-19  |  6KB  |  260 lines

  1. /*
  2.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  3.  *
  4.  * Code Contributions By : Tim Thompson           twitch!tjt
  5.  *                         Tony Andrews           onecom!wldrdg!tony 
  6.  *                         G. R. (Fred) Walter    watmath!grwalter 
  7.  */
  8.  
  9. #include "stevie.h"
  10.  
  11. void
  12. filemess(s)
  13.     char           *s;
  14. {
  15.     sprintf(IObuff, "\"%s\" %s", ((Filename == NULL) ? "" : Filename), s);
  16.     msg(IObuff);
  17. }
  18.  
  19. void
  20. renum()
  21. {
  22.     LPtr           *p;
  23.     unsigned long   l = 0;
  24.  
  25.     for (p = Filemem; p != NULL; p = nextline(p), l += LINEINC)
  26.     p->linep->num = l;
  27.  
  28.     Fileend->linep->num = 0xffffffffL;
  29. }
  30.  
  31. #ifdef  MEGAMAX
  32. overlay "fileio"
  33. #endif
  34.  
  35. bool_t
  36. readfile(fname, fromp, nochangename)
  37.     char           *fname;
  38.     LPtr           *fromp;
  39.     bool_t          nochangename;    /* if TRUE, don't change the Filename */
  40. {
  41.     FILE           *f, *fopen();
  42.     LINE           *curr;
  43.     char            buf2[80];
  44.     int             c;
  45.     int             IObuffsize = 0;
  46.     long            nchars = 0;
  47.     int             linecnt = 0;
  48.     bool_t          wasempty = bufempty();
  49.     int             nonascii = 0;    /* count garbage characters */
  50.     int             nulls = 0;    /* count nulls */
  51.     bool_t          incomplete = FALSE;    /* was the last line incomplete? */
  52.     bool_t          toolong = FALSE;    /* a line was too long */
  53.  
  54.     curr = fromp->linep;
  55.  
  56.     if (!nochangename)
  57.     Filename = strsave(fname);
  58.  
  59.     f = fopen(fname, "r");
  60.     if (f == NULL) {
  61.     s_refresh(NOT_VALID);
  62.     filemess("");
  63.     return TRUE;
  64.     }
  65.     S_NOT_VALID;
  66.  
  67.     do {
  68.     c = getc(f);
  69.  
  70.     if (c == EOF) {
  71.         if (IObuffsize == 0)/* normal loop termination */
  72.         break;
  73.  
  74.         /*
  75.          * If we get EOF in the middle of a line, note the fact and
  76.          * complete the line ourselves. 
  77.          */
  78.         incomplete = TRUE;
  79.         c = NL;
  80.     }
  81.     if (c >= 0x80) {
  82.         c -= 0x80;
  83.         nonascii++;
  84.     }
  85.     /*
  86.      * If we reached the end of the line, OR we ran out of space for it,
  87.      * then process the complete line. 
  88.      */
  89.     if (c == NL || IObuffsize == (IOSIZE - 1)) {
  90.         LINE           *lp;
  91.  
  92.         if (c != NL)
  93.         toolong = TRUE;
  94.  
  95.         IObuff[IObuffsize++] = NUL;
  96.         lp = newline(IObuffsize);
  97.         if (lp == NULL) {
  98.         fprintf(stderr, "not enough memory - should never happen");
  99.         getout(1);
  100.         }
  101.         strcpy(lp->s, IObuff);
  102.  
  103.         curr->next->prev = lp;    /* new line to next one */
  104.         lp->next = curr->next;
  105.  
  106.         curr->next = lp;    /* new line to prior one */
  107.         lp->prev = curr;
  108.  
  109.         curr = lp;        /* new line becomes current */
  110.         IObuffsize = 0;
  111.         linecnt++;
  112.     } else if (c == NUL) {
  113.         nulls++;        /* count and ignore nulls */
  114.     } else {
  115.         IObuff[IObuffsize++] = (char) c;    /* normal character */
  116.     }
  117.  
  118.     nchars++;
  119.     } while (!incomplete && !toolong);
  120.  
  121.     fclose(f);
  122.  
  123.     /*
  124.      * If the buffer was empty when we started, we have to go back and remove
  125.      * the "dummy" line at Filemem and patch up the ptrs. 
  126.      */
  127.     if (wasempty && linecnt != 0) {
  128.     LINE           *dummy = Filemem->linep;    /* dummy line ptr */
  129.  
  130.     Filemem->linep = Filemem->linep->next;
  131.     Filemem->linep->prev = Filetop->linep;
  132.     Filetop->linep->next = Filemem->linep;
  133.  
  134.     Curschar->linep = Filemem->linep;
  135.     Topchar->linep = Filemem->linep;
  136.  
  137.     free(dummy->s);        /* free string space */
  138.     free((char *) dummy);    /* free LINE struct */
  139.     }
  140.     renum();
  141.  
  142.     if (toolong) {
  143.     s_refresh(NOT_VALID);
  144.  
  145.     sprintf(IObuff, "\"%s\" Line too long", fname);
  146.     msg(IObuff);
  147.     return FALSE;
  148.     }
  149.     s_refresh(NOT_VALID);
  150.  
  151.     sprintf(IObuff, "\"%s\" %s%d line%s, %ld character%s",
  152.         fname,
  153.         incomplete ? "[Incomplete last line] " : "",
  154.         linecnt, (linecnt > 1) ? "s" : "",
  155.         nchars, (nchars > 1) ? "s" : "");
  156.  
  157.     buf2[0] = NUL;
  158.  
  159.     if (nonascii || nulls) {
  160.     if (nonascii) {
  161.         if (nulls)
  162.         sprintf(buf2, " (%d null, %d non-ASCII)",
  163.             nulls, nonascii);
  164.         else
  165.         sprintf(buf2, " (%d non-ASCII)", nonascii);
  166.     } else
  167.         sprintf(buf2, " (%d null)", nulls);
  168.     }
  169.     strcat(IObuff, buf2);
  170.     msg(IObuff);
  171.  
  172.     return FALSE;
  173. }
  174.  
  175. /*
  176.  * writeit - write to file 'fname' lines 'start' through 'end' 
  177.  *
  178.  * If either 'start' or 'end' contain null line pointers, the default is to use
  179.  * the start or end of the file respectively. 
  180.  */
  181. bool_t
  182. writeit(fname, start, end)
  183.     char           *fname;
  184.     LPtr           *start, *end;
  185. {
  186.     FILE           *f;
  187.     FILE           *fopen();
  188.     FILE           *fopenb();    /* open in binary mode, where needed */
  189.     char           *s;
  190.     long            nchars;
  191.     int             lines;
  192.     LPtr           *p;
  193.  
  194.     sprintf(IObuff, "\"%s\"", fname);
  195.     msg(IObuff);
  196.  
  197.     /*
  198.      * Form the backup file name - change foo.* to foo.bak - use IObuff to
  199.      * hold the backup file name 
  200.      */
  201.     strcpy(IObuff, fname);
  202.     for (s = IObuff; *s && *s != '.'; s++);
  203.     *s = NUL;
  204.     strcat(IObuff, ".bak");
  205.  
  206.     /*
  207.      * Delete any existing backup and move the current version to the backup.
  208.      * For safety, we don't remove the backup until the write has finished
  209.      * successfully. And if the 'backup' option is set, leave it around. 
  210.      */
  211.     rename(fname, IObuff);
  212.  
  213.     f = P(P_CR) ? fopen(fname, "w") : fopenb(fname, "w");
  214.     if (f == NULL) {
  215.     emsg("Can't open file for writing!");
  216.     return FALSE;
  217.     }
  218.     /*
  219.      * If we were given a bound, start there. Otherwise just start at the
  220.      * beginning of the file. 
  221.      */
  222.     if (start == NULL || start->linep == NULL)
  223.     p = Filemem;
  224.     else
  225.     p = start;
  226.  
  227.     lines = 0;
  228.     nchars = 0;
  229.     do {
  230.     fprintf(f, "%s\n", p->linep->s);
  231.     nchars += strlen(p->linep->s) + 1;
  232.     lines++;
  233.  
  234.     /*
  235.      * If we were given an upper bound, and we just did that line, then
  236.      * bag it now. 
  237.      */
  238.     if (end != NULL && end->linep != NULL) {
  239.         if (end->linep == p->linep)
  240.         break;
  241.     }
  242.     } while ((p = nextline(p)) != NULL);
  243.  
  244.     fclose(f);
  245.  
  246.     /*
  247.      * Remove the backup unless they want it left around 
  248.      */
  249.     if (!P(P_BK))
  250.     remove(IObuff);
  251.  
  252.     sprintf(IObuff, "\"%s\" %d line%s, %ld character%s", fname,
  253.         lines, (lines > 1) ? "s" : "",
  254.         nchars, (nchars > 1) ? "s" : "");
  255.     msg(IObuff);
  256.     UNCHANGED;
  257.  
  258.     return TRUE;
  259. }
  260.