home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 019 / file.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  10KB  |  468 lines

  1. /*
  2.  *  Copyright (c) 1992 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <limits.h>
  9. #include <stdlib.h>
  10.  
  11. #ifdef VMS
  12. #include <file.h>
  13. #else
  14. #include <sys/types.h>
  15. #endif
  16.  
  17. #include "buffer.h"
  18. #include "file.h"
  19. #include "misc.h"
  20. #include "sysdep.h"
  21. #include "paste.h"
  22. #include "slang.h"
  23. #include "ins.h"
  24. #include "ledit.h"
  25.  
  26. #define MAX_LINE_LEN 512
  27.  
  28. int Require_Final_Newline = 0;
  29.  
  30. /* 0 = read, 1 = write , 2 = append... */
  31. FILE *sys_open(char *file, int access)
  32. {
  33.    FILE *fp = NULL;
  34.  
  35.    int status;
  36. #ifdef VMS
  37.    int fd;
  38.    char *p, new[255];
  39. #endif
  40.    status = file_status(file);
  41.    if ((status < 0) || (status > 1)) return(NULL);
  42.  
  43.    /* on VMS I cheat since I do not want to deal with RMS at this point */
  44. #ifdef VMS
  45.    strcpy(new, file);
  46.    p = new; while (*p) if (*p == ';') *p = 0; else p++;
  47.  
  48.    if (access == 0)
  49.      fd = open(file, O_RDONLY, 0);
  50.    else if (access == 1)
  51.      {
  52.          fd = open(new, O_TRUNC, 0);
  53.          if (fd != -1)
  54.            {
  55.               close(fd);
  56.           return(fopen(new, "a"));
  57.        }
  58.       }
  59.     else fd = -1;
  60.  
  61.     if (fd != -1) close(fd);
  62. #endif
  63.  
  64.    if (access == 0) fp = fopen(file, "r");
  65.    else if (access == 1) fp = fopen(file, "w");
  66.    else if (access == 2) fp = fopen(file, "a+");
  67.    return(fp);
  68. }
  69.  
  70. /* Leaves Point at last line inserted */
  71. /* returns -1 if unable to open file,
  72.            -2 if memory allocation error
  73.            otherwise returns number of lines read */
  74.  
  75. char *file_type(char *file)
  76. {
  77.     char *p;
  78.     if ((file == (char *) NULL) || (*file == 0)) return( (char *) NULL);
  79.  
  80.     p = file; while (*p != 0) p++;
  81.     while((p != file) && (*p != '.')) p--;
  82.     if (*p == '.') p++;
  83.     if (p == file) return((char *) NULL); else return(p);
  84. }
  85.  
  86. void set_file_modes()
  87. {
  88.    char *type;
  89.  
  90.    if (CBuf == NULL) return;
  91.    CBuf->c_time = sys_time();
  92.    if (CBuf->file[0])
  93.      {
  94.     CBuf->flags |= AUTO_SAVE_BUFFER;
  95.     CBuf->hits = 0;
  96.     type = file_type(CBuf->file);
  97.      }
  98.    else type = (char *) NULL;
  99.  
  100.    if (type == (char *) NULL) CBuf->modes = NO_MODE;
  101.    else if (lang_run_hooks("mode_hook", type));
  102.  
  103.    else if (!strcmp("c", type)) CBuf->modes = C_MODE;
  104.    else if (!strcmp("h", type)) CBuf->modes = C_MODE;
  105.    else if (!strcmp("txt", type)) CBuf->modes = WRAP_MODE;
  106.    else if (!strcmp("tex", type)) CBuf->modes = WRAP_MODE;
  107.    else if (!strcmp("doc", type)) CBuf->modes = WRAP_MODE;
  108.    else CBuf->modes = NO_MODE;
  109. }
  110.  
  111. int read_file_pointer(FILE *fp)
  112. {
  113.    int i = 0;                      /* number of lines read in */
  114.    unsigned char *data, buffer[MAX_LINE_LEN], *b;
  115.    unsigned int n;
  116.  
  117.    while(1)
  118.      {
  119.     if (NULL == fgets((char *) buffer, MAX_LINE_LEN, fp))
  120.       {
  121.          if (i == 0)
  122.            {
  123.           if (CLine == NULL) make_line(20);
  124.           CLine->next = NULL;
  125.           CLine->prev = NULL;
  126.           CBuf->beg = CBuf->end = CLine;
  127.           return(0);
  128.            }
  129.          return(i);
  130.       }
  131.  
  132.     b = buffer;
  133.     while(*b != 0) b++;
  134.     n = (unsigned int) (b - buffer);
  135.  
  136.     if ((CLine == NULL) || (CLine->len != 0))
  137.       {
  138.          if ((data = make_line(n + 1)) == NULL)
  139.            {
  140.           msg_error("Allocation Failure");
  141.           return (0);
  142.            }
  143.       }
  144.     else
  145.       {
  146.          if (n > CLine->space) remake_line(n + 1);
  147.          data = CLine->data;
  148.       }
  149.  
  150.     b = buffer;
  151.     while(*b != 0) *data++ = *b++;
  152.     n = (unsigned int) (b - buffer);
  153.     if ((n == MAX_LINE_LEN) && (*(b-1) != '\n'))
  154.       {
  155.          msg_error("Line truncated to 512 characters.");
  156.          *data = '\n';
  157.          n++;
  158.       }
  159.  
  160.     i++;
  161.     CLine->len = n;
  162.      }
  163. }
  164.  
  165. int read_file(char *file)
  166. {
  167.    FILE *fp;
  168.    int n, status;
  169.  
  170.    if ((fp = sys_open(file, 0)) == NULL)
  171.      {
  172.     status = file_status(file);
  173.     if (!status) return(-1);  /* file does not exist */
  174.     return(-2); /* exists but not readable */
  175.      }
  176.  
  177.    n = read_file_pointer(fp);
  178.    fclose(fp);
  179.    eob();
  180.    if ('\n' == *(CLine->data + Point)) make_line(1);
  181.    return n;
  182. }
  183.  
  184. int insert_file(char *file)
  185. {
  186.    Buffer *save = CBuf, *tmp;
  187.    int n;
  188.  
  189.    tmp = make_buffer();
  190.    switch_to_buffer (tmp);
  191.  
  192.    if ((n = read_file(file)) >= 0)
  193.      {
  194.     switch_to_buffer(save);
  195.     insert_buffer(tmp);
  196.      }
  197.    else switch_to_buffer(save);
  198.  
  199.    delete_buffer(tmp);
  200.    return(n);
  201. }
  202.  
  203. /* returns -1 on failure */
  204. int write_region_to_fp(FILE *fp)
  205. {
  206.    int n = 0, pnt, last_pnt;
  207.    Line *first, *last;
  208.  
  209.    if (!check_region(&Number_One)) return(-1);
  210.    last = CLine; last_pnt = Point;
  211.  
  212.    pop_mark(&Number_One);
  213.    first = CLine; pnt = Point;
  214.  
  215.    while (first != last)
  216.      {
  217.     fwrite((char *) (first->data + pnt), first->len - pnt, 1, fp);
  218.     first = first->next;
  219.     n++;
  220.     pnt = 0;
  221.      }
  222.  
  223.    if (last_pnt != 0)
  224.      {
  225.     fwrite((char *) (last->data + pnt), last_pnt - pnt, 1, fp);
  226.     n++;
  227.      }
  228. #ifndef VMS
  229.    if ((Require_Final_Newline) && (CBuf->end == last))
  230.      {
  231.     eob(); if (Point) fwrite("\n", 1, 1, fp);
  232.      }
  233. #endif
  234.    pop_spot();
  235.    return(n);
  236. }
  237.  
  238. /* write current buffer to open file pointer. Return number of lines */
  239.  
  240. int write_region(char *file)
  241. {
  242.    FILE *fp;
  243.    int n;
  244.    char msg[255];
  245.  
  246.    if ((fp = sys_open(file, 1)) == NULL)
  247.      {
  248.     sprintf(msg, "Unable to open %s for writing.", file);
  249.     msg_error(msg);
  250.     return(-1);
  251.      }
  252.    n = write_region_to_fp(fp);
  253.    fclose(fp);
  254.  
  255.    return(n);
  256. }
  257.  
  258.  
  259.  
  260. /* returns -1 on failure and number of lines on success */
  261.  
  262. int write_file(char *file)
  263. {
  264.    int n;
  265.    push_spot();
  266.    bob();
  267.    push_mark();
  268.    eob();
  269.    if (-1 == (n = write_region(file))) pop_mark(&Number_Zero);
  270.    pop_spot();
  271.    return(n);
  272. }
  273.  
  274. int append_to_file(char *file)
  275. {
  276.    FILE *fp;
  277.    int n;
  278.  
  279.    if ((fp = sys_open(file, 2)) == NULL) return(-1);
  280.    n = write_region_to_fp(fp);
  281.    fclose(fp);
  282.    check_buffers();
  283.    return(n);
  284. }
  285.  
  286. int make_autosave_filename(char *save, char *dir, char *file)
  287. {
  288.     if (*file == 0) return(0);
  289. #ifndef VMS
  290. #ifdef msdos
  291.     sprintf(save, "%s#%s", dir, file);
  292. #endif
  293.     sprintf(save, "%s#%s#", dir, file);
  294. #else
  295.     sprintf(save, "%s_$%s_$;1", dir, file);   /* always use version 1 */
  296. #endif
  297.     return(1);
  298. }
  299.  
  300. int write_file_with_backup(char *dir, char *file)
  301. {
  302.    char old[255];
  303.    char new[255]; char save[255];
  304.    int n;
  305.    int mode, do_mode;
  306.  
  307.    if (*file == 0) return(-1);
  308.  
  309.    sprintf(new, "%s%s", dir, file);
  310.  
  311.    do_mode = sys_chmod(new, 0, &mode);
  312.    if ((do_mode < 0) ||  (do_mode > 1)) return(-1);
  313.  
  314. #ifndef VMS
  315.    sprintf(old, "%s%s~", dir, file);
  316.    unlink(old);
  317.    rename(new, old);
  318. #endif
  319.    make_autosave_filename(save, dir, file);
  320.    if (-1 != (n = write_file(new)))
  321.      {
  322.     sys_delete_file(save);
  323.     if (do_mode) /* must be an existing file, so preserve mode */
  324.       {
  325.          sys_chmod (new, 1, &mode);
  326.       }
  327.     CBuf->c_time = sys_time();
  328.      }
  329.    return(n);
  330. }
  331.  
  332. /* warning-- this saves on the narrowed part of buffer.
  333.    Here, I widen first.  I need a save_restriction type of thing because
  334.    I do not narrow back.
  335.    */
  336. void auto_save_buffer(Buffer *b)
  337. {
  338.     char tmp[255];
  339.     Buffer *old_buf;
  340.  
  341.    if (b == NULL) return;
  342.     old_buf = CBuf;
  343.     CBuf = b;
  344.  
  345.     if ((b->flags & BUFFER_TRASHED) && (b->flags & AUTO_SAVE_BUFFER))
  346.       {
  347.       if (make_autosave_filename(tmp, b->dir, b->file))
  348.         {
  349.            widen();
  350.            message("autosaving..."); flush_message();
  351.            sys_delete_file(tmp);
  352.            write_file(tmp);
  353.            message("autosaving...done");
  354.            b->hits = 0;
  355.         }
  356.       }
  357.  
  358.     CBuf = old_buf;
  359. }
  360.  
  361. void auto_save_all()
  362. {
  363.     Buffer *b;
  364.  
  365.     if (NULL == (b = CBuf)) return;
  366.     do
  367.       {
  368.       if (*b->file != 0) auto_save_buffer(b);
  369.           b = b->next;
  370.       }
  371.     while (b != CBuf);
  372. }
  373.  
  374. void visit_file(char *dir, char *file)
  375. {
  376.    if (NULL == find_buffer(file)) strcpy(CBuf->name, file);
  377.    strcpy(CBuf->dir, dir);
  378.    CBuf->c_time = sys_time();
  379.    strcpy(CBuf->file, file);
  380.    check_buffers();
  381. }
  382.  
  383. void fixup_dir(char *dir)
  384. {
  385. #ifndef VMS
  386. #ifdef msdos
  387.    if (dir[strlen(dir) - 1] != '\\') strcat(dir,"\\");
  388. #else
  389.    if (dir[strlen(dir) - 1] != '/') strcat(dir,"/");
  390. #endif
  391. #endif
  392. }
  393.  
  394. char *d