home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / DOS_50 / PVIC.ZIP / FILEIO.C < prev    next >
C/C++ Source or Header  |  1993-04-21  |  7KB  |  303 lines

  1. /* 
  2.  *
  3.  * Basic file I/O routines.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "pvic.h"
  8. #include "locdefs.h"
  9.  
  10. void
  11. file_message(s)
  12. char    *s;
  13. {
  14.     show_message("\"%s\" %s", (file_name == NULL) ? "" : file_name, s);
  15.     fflush(stdout);
  16. }
  17.  
  18. void
  19. renum()
  20. {
  21.     LPTR    *p;
  22.     unsigned long l = 0;
  23.  
  24.     for (p = file_memory; p != NULL ;p = next_line(p), l += LINEINC)
  25.         p->linep->num = l;
  26.  
  27.     end_of_file->linep->num = 0xffffffff;
  28. }
  29.  
  30. #define MAXLINE 256     /* maximum size of a line */
  31.  
  32. int
  33. read_file(fname,fromp,nochangename)
  34. /*-------------------------------------------------
  35.  * Note that this will try to expand the file name using environment
  36.  * variables.  For this reason, we copy it into an 80-byte buffer,
  37.  * so that there's room to expand it.
  38.  *
  39.  * It uses the environment-variable convention of UNIX, even
  40.  * under systems with other conventions.  That is, your home directory
  41.  * would be called $HOME (even in DOS, where you might want to say %HOME%)
  42.  *-----------------------------------------------------*/
  43. char    *fname;
  44. LPTR    *fromp;
  45. int     nochangename;   /* if (1), don't change the file_name */
  46. {
  47.     FILE    *f, *fopen();
  48.     register LINE   *curr;
  49.     char    buff[MAXLINE], buf2[80];
  50.     char    namebuf[80];
  51.     register int    i, c;
  52.     register long   nchars = 0;
  53.     int     linecnt = 0;
  54.     int     wasempty = buffer_empty();
  55.     int     nonascii = 0;           /* count garbage characters */
  56.     int     nulls = 0;              /* count nulls */
  57.     int     incomplete = (0);       /* was the last line incomplete? */
  58.     int     toolong = (0);  /* a line was too long */
  59.  
  60.     curr = fromp->linep;
  61.  
  62.     strncpy (namebuf, fname, 80);
  63.     eval_environment (namebuf, 80);
  64.  
  65.     if ( ! nochangename )
  66.         file_name = strsave(namebuf);
  67.  
  68.     if ( (f=fopen(namebuf,"r")) == NULL )
  69.         return (1);
  70.  
  71.     file_message("");
  72.  
  73.     local_reset_control_c_pressed();
  74.  
  75.     i = 0;
  76.     do {
  77.         c = getc(f);
  78.  
  79.         if (c == EOF) {
  80.             if (i == 0)     /* normal loop termination */
  81.                 break;
  82.  
  83.             /*
  84.              * If we get EOF in the middle of a line, note the
  85.              * fact and complete the line ourselves.
  86.              */
  87.             incomplete = (1);
  88.             c = '\n';
  89.         }
  90.  
  91.         /*
  92.          * Abort if we get an interrupt, but finished reading the
  93.          * current line first.
  94.          */
  95.         if (local_control_c_pressed() && i == 0)
  96.         {
  97.             clear_screen();
  98.             update_screen(0);
  99.             break;
  100.         }
  101.  
  102.         if (c<0 || c>=0x80) {
  103.             c -= 0x80;
  104.             nonascii++;
  105.         }
  106.  
  107.         /*
  108.          * If we reached the end of the line, OR we ran out of
  109.          * space for it, then process the complete line.
  110.          */
  111.         if (c == '\n' || i == (MAXLINE-1)) {
  112.             LINE    *lp;
  113.  
  114.             if (c != '\n')
  115.                 toolong = (1);
  116.  
  117.             buff[i] = '\0';
  118.             if ((lp = newline(strlen(buff))) == NULL)
  119.                 exit(1);
  120.  
  121.             strcpy(lp->s, buff);
  122.  
  123.             curr->next->prev = lp;  /* new line to next one */
  124.             lp->next = curr->next;
  125.  
  126.             curr->next = lp;        /* new line to prior one */
  127.             lp->prev = curr;
  128.  
  129.             curr = lp;              /* new line becomes current */
  130.             i = 0;
  131.             linecnt++;
  132.  
  133.         } else if (c == '\0')
  134.             nulls++;                /* count and ignore nulls */
  135.         else {
  136.             buff[i++] = c;          /* normal character */
  137.         }
  138.  
  139.         nchars++;
  140.  
  141.     } while (!incomplete && !toolong);
  142.  
  143.     fclose(f);
  144.  
  145.     /*
  146.      * If the buffer was empty when we started, we have to go back
  147.      * and remove the "dummy" line at file_memory and patch up the ptrs.
  148.      */
  149.     if (wasempty && nchars != 0) {
  150.         LINE    *dummy = file_memory->linep;        /* dummy line ptr */
  151.  
  152.         free(dummy->s);                         /* free string space */
  153.         file_memory->linep = file_memory->linep->next;
  154.         free((char *)dummy);                    /* free LINE struct */
  155.         file_memory->linep->prev = top_of_file->linep;
  156.         top_of_file->linep->next = file_memory->linep;
  157.  
  158.         cursor_char->linep = file_memory->linep;
  159.         top_char->linep  = file_memory->linep;
  160.     }
  161.  
  162.     renum();
  163.  
  164.     if (local_control_c_pressed()) {
  165.         clear_screen();
  166.         update_screen(0);
  167.         show_message("\"%s\" Interrupt", namebuf);
  168.         local_reset_control_c_pressed();
  169.         return (0);             /* an interrupt isn't really an error */
  170.     }
  171.  
  172.     if (toolong) {
  173.         show_message("\"%s\" Line too long", namebuf);
  174.         return (0);
  175.     }
  176.  
  177.     sprintf(buff, "\"%s\" %s%d line%s, %ld character%s",
  178.         namebuf,
  179.         incomplete ? "[Incomplete last line] " : "",
  180.         linecnt, (linecnt != 1) ? "s" : "",
  181.         nchars, (nchars != 1) ? "s" : "");
  182.  
  183.     buf2[0] = '\0';
  184.  
  185.     if (nonascii || nulls) {
  186.         if (nonascii) {
  187.             if (nulls)
  188.                 sprintf(buf2, " (%d null, %d non-ASCII)",
  189.                     nulls, nonascii);
  190.             else
  191.                 sprintf(buf2, " (%d non-ASCII)", nonascii);
  192.         } else
  193.             sprintf(buf2, " (%d null)", nulls);
  194.     }
  195.     strcat(buff, buf2);
  196.     msg(buff);
  197.  
  198.     return (0);
  199. }
  200.  
  201.  
  202. /*
  203.  * write_it - write to file 'fname' lines 'start' through 'end'
  204.  *
  205.  * If either 'start' or 'end' contain null line pointers, the default
  206.  * is to use the start or end of the file respectively.
  207.  */
  208. int
  209. write_it(fname, start, end)
  210. char    *fname;
  211. LPTR    *start, *end;
  212. {
  213.     FILE    *f, *fopen();
  214.     char    *backup;
  215.     register char   *s;
  216.     register long   nchars;
  217.     register int    lines;
  218.     register LPTR   *p;
  219.  
  220.     show_message("\"%s\"", fname);
  221.  
  222.     /* Expand any environment variables left in the name.
  223.      * fname better be in a variable big enough to handle the
  224.      * expansion (80 bytes).
  225.      */
  226.     eval_environment (fname, 80);
  227.  
  228.     /*
  229.      * Form the backup file name - change foo.* to foo.bak
  230.      */
  231.     backup = alloc((unsigned) (strlen(fname) + 5));
  232.     if (backup == NULL) {
  233.         error_message("Can't open file for writing");
  234.         return (0);
  235.     }
  236.  
  237.     strcpy(backup, fname);
  238.     for (s = backup; *s && *s != '.' ;s++)
  239.         ;
  240.     *s = '\0';
  241.     strcat(backup, ".bak");
  242.  
  243.     /*
  244.      * Delete any existing backup and move the current version
  245.      * to the backup. For safety, we don't remove the backup
  246.      * until the write has finished successfully. And if the
  247.      * 'backup' option is set, leave it around.
  248.      */
  249.     rename_file(fname, backup);
  250.  
  251.  
  252.     f =  fopen(fname, "w") ;
  253.  
  254.     if (f == NULL) {
  255.         error_message("Can't open file for writing");
  256.         free(backup);
  257.         return (0);
  258.     }
  259.  
  260.     /*
  261.      * If we were given a bound, start there. Otherwise just
  262.      * start at the beginning of the file.
  263.      */
  264.     if (start == NULL || start->linep == NULL)
  265.         p = file_memory;
  266.     else
  267.         p = start;
  268.  
  269.     lines = nchars = 0;
  270.     do {
  271.         fprintf(f, "%s\n", p->linep->s);
  272.         nchars += strlen(p->linep->s) + 1;
  273.         lines++;
  274.  
  275.         /*
  276.          * If we were given an upper bound, and we just did that
  277.          * line, then bag it now.
  278.          */
  279.         if (end != NULL && end->linep != NULL) {
  280.             if (end->linep == p->linep)
  281.                 break;
  282.         }
  283.  
  284.     } while ((p = next_line(p)) != NULL);
  285.  
  286.     fclose(f);
  287.     show_message("\"%s\" %d line%s, %ld character%s", fname,
  288.         lines, (lines > 1) ? "s" : "",
  289.         nchars, (nchars > 1) ? "s" : "");
  290.  
  291.     UNCHANGED;
  292.  
  293.     /*
  294.      * Remove the backup unless they want it left around
  295.      */
  296.     if (!PARAMETER_VALUE(PARAMETER_BACKUP))
  297.         unlink(backup);
  298.  
  299.     free(backup);
  300.  
  301.     return (1);
  302. }
  303.