home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
word
/
text
/
019
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
10KB
|
468 lines
/*
* Copyright (c) 1992 John E. Davis (davis@amy.tch.harvard.edu)
* All Rights Reserved.
*/
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#ifdef VMS
#include <file.h>
#else
#include <sys/types.h>
#endif
#include "buffer.h"
#include "file.h"
#include "misc.h"
#include "sysdep.h"
#include "paste.h"
#include "slang.h"
#include "ins.h"
#include "ledit.h"
#define MAX_LINE_LEN 512
int Require_Final_Newline = 0;
/* 0 = read, 1 = write , 2 = append... */
FILE *sys_open(char *file, int access)
{
FILE *fp = NULL;
int status;
#ifdef VMS
int fd;
char *p, new[255];
#endif
status = file_status(file);
if ((status < 0) || (status > 1)) return(NULL);
/* on VMS I cheat since I do not want to deal with RMS at this point */
#ifdef VMS
strcpy(new, file);
p = new; while (*p) if (*p == ';') *p = 0; else p++;
if (access == 0)
fd = open(file, O_RDONLY, 0);
else if (access == 1)
{
fd = open(new, O_TRUNC, 0);
if (fd != -1)
{
close(fd);
return(fopen(new, "a"));
}
}
else fd = -1;
if (fd != -1) close(fd);
#endif
if (access == 0) fp = fopen(file, "r");
else if (access == 1) fp = fopen(file, "w");
else if (access == 2) fp = fopen(file, "a+");
return(fp);
}
/* Leaves Point at last line inserted */
/* returns -1 if unable to open file,
-2 if memory allocation error
otherwise returns number of lines read */
char *file_type(char *file)
{
char *p;
if ((file == (char *) NULL) || (*file == 0)) return( (char *) NULL);
p = file; while (*p != 0) p++;
while((p != file) && (*p != '.')) p--;
if (*p == '.') p++;
if (p == file) return((char *) NULL); else return(p);
}
void set_file_modes()
{
char *type;
if (CBuf == NULL) return;
CBuf->c_time = sys_time();
if (CBuf->file[0])
{
CBuf->flags |= AUTO_SAVE_BUFFER;
CBuf->hits = 0;
type = file_type(CBuf->file);
}
else type = (char *) NULL;
if (type == (char *) NULL) CBuf->modes = NO_MODE;
else if (lang_run_hooks("mode_hook", type));
else if (!strcmp("c", type)) CBuf->modes = C_MODE;
else if (!strcmp("h", type)) CBuf->modes = C_MODE;
else if (!strcmp("txt", type)) CBuf->modes = WRAP_MODE;
else if (!strcmp("tex", type)) CBuf->modes = WRAP_MODE;
else if (!strcmp("doc", type)) CBuf->modes = WRAP_MODE;
else CBuf->modes = NO_MODE;
}
int read_file_pointer(FILE *fp)
{
int i = 0; /* number of lines read in */
unsigned char *data, buffer[MAX_LINE_LEN], *b;
unsigned int n;
while(1)
{
if (NULL == fgets((char *) buffer, MAX_LINE_LEN, fp))
{
if (i == 0)
{
if (CLine == NULL) make_line(20);
CLine->next = NULL;
CLine->prev = NULL;
CBuf->beg = CBuf->end = CLine;
return(0);
}
return(i);
}
b = buffer;
while(*b != 0) b++;
n = (unsigned int) (b - buffer);
if ((CLine == NULL) || (CLine->len != 0))
{
if ((data = make_line(n + 1)) == NULL)
{
msg_error("Allocation Failure");
return (0);
}
}
else
{
if (n > CLine->space) remake_line(n + 1);
data = CLine->data;
}
b = buffer;
while(*b != 0) *data++ = *b++;
n = (unsigned int) (b - buffer);
if ((n == MAX_LINE_LEN) && (*(b-1) != '\n'))
{
msg_error("Line truncated to 512 characters.");
*data = '\n';
n++;
}
i++;
CLine->len = n;
}
}
int read_file(char *file)
{
FILE *fp;
int n, status;
if ((fp = sys_open(file, 0)) == NULL)
{
status = file_status(file);
if (!status) return(-1); /* file does not exist */
return(-2); /* exists but not readable */
}
n = read_file_pointer(fp);
fclose(fp);
eob();
if ('\n' == *(CLine->data + Point)) make_line(1);
return n;
}
int insert_file(char *file)
{
Buffer *save = CBuf, *tmp;
int n;
tmp = make_buffer();
switch_to_buffer (tmp);
if ((n = read_file(file)) >= 0)
{
switch_to_buffer(save);
insert_buffer(tmp);
}
else switch_to_buffer(save);
delete_buffer(tmp);
return(n);
}
/* returns -1 on failure */
int write_region_to_fp(FILE *fp)
{
int n = 0, pnt, last_pnt;
Line *first, *last;
if (!check_region(&Number_One)) return(-1);
last = CLine; last_pnt = Point;
pop_mark(&Number_One);
first = CLine; pnt = Point;
while (first != last)
{
fwrite((char *) (first->data + pnt), first->len - pnt, 1, fp);
first = first->next;
n++;
pnt = 0;
}
if (last_pnt != 0)
{
fwrite((char *) (last->data + pnt), last_pnt - pnt, 1, fp);
n++;
}
#ifndef VMS
if ((Require_Final_Newline) && (CBuf->end == last))
{
eob(); if (Point) fwrite("\n", 1, 1, fp);
}
#endif
pop_spot();
return(n);
}
/* write current buffer to open file pointer. Return number of lines */
int write_region(char *file)
{
FILE *fp;
int n;
char msg[255];
if ((fp = sys_open(file, 1)) == NULL)
{
sprintf(msg, "Unable to open %s for writing.", file);
msg_error(msg);
return(-1);
}
n = write_region_to_fp(fp);
fclose(fp);
return(n);
}
/* returns -1 on failure and number of lines on success */
int write_file(char *file)
{
int n;
push_spot();
bob();
push_mark();
eob();
if (-1 == (n = write_region(file))) pop_mark(&Number_Zero);
pop_spot();
return(n);
}
int append_to_file(char *file)
{
FILE *fp;
int n;
if ((fp = sys_open(file, 2)) == NULL) return(-1);
n = write_region_to_fp(fp);
fclose(fp);
check_buffers();
return(n);
}
int make_autosave_filename(char *save, char *dir, char *file)
{
if (*file == 0) return(0);
#ifndef VMS
#ifdef msdos
sprintf(save, "%s#%s", dir, file);
#endif
sprintf(save, "%s#%s#", dir, file);
#else
sprintf(save, "%s_$%s_$;1", dir, file); /* always use version 1 */
#endif
return(1);
}
int write_file_with_backup(char *dir, char *file)
{
char old[255];
char new[255]; char save[255];
int n;
int mode, do_mode;
if (*file == 0) return(-1);
sprintf(new, "%s%s", dir, file);
do_mode = sys_chmod(new, 0, &mode);
if ((do_mode < 0) || (do_mode > 1)) return(-1);
#ifndef VMS
sprintf(old, "%s%s~", dir, file);
unlink(old);
rename(new, old);
#endif
make_autosave_filename(save, dir, file);
if (-1 != (n = write_file(new)))
{
sys_delete_file(save);
if (do_mode) /* must be an existing file, so preserve mode */
{
sys_chmod (new, 1, &mode);
}
CBuf->c_time = sys_time();
}
return(n);
}
/* warning-- this saves on the narrowed part of buffer.
Here, I widen first. I need a save_restriction type of thing because
I do not narrow back.
*/
void auto_save_buffer(Buffer *b)
{
char tmp[255];
Buffer *old_buf;
if (b == NULL) return;
old_buf = CBuf;
CBuf = b;
if ((b->flags & BUFFER_TRASHED) && (b->flags & AUTO_SAVE_BUFFER))
{
if (make_autosave_filename(tmp, b->dir, b->file))
{
widen();
message("autosaving..."); flush_message();
sys_delete_file(tmp);
write_file(tmp);
message("autosaving...done");
b->hits = 0;
}
}
CBuf = old_buf;
}
void auto_save_all()
{
Buffer *b;
if (NULL == (b = CBuf)) return;
do
{
if (*b->file != 0) auto_save_buffer(b);
b = b->next;
}
while (b != CBuf);
}
void visit_file(char *dir, char *file)
{
if (NULL == find_buffer(file)) strcpy(CBuf->name, file);
strcpy(CBuf->dir, dir);
CBuf->c_time = sys_time();
strcpy(CBuf->file, file);
check_buffers();
}
void fixup_dir(char *dir)
{
#ifndef VMS
#ifdef msdos
if (dir[strlen(dir) - 1] != '\\') strcat(dir,"\\");
#else
if (dir[strlen(dir) - 1] != '/') strcat(dir,"/");
#endif
#endif
}
char *d