home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
pvic_10a.lzh
/
SRCE
/
fileio.c
< prev
next >
Wrap
Text File
|
1998-04-23
|
7KB
|
303 lines
/*
*
* Basic file I/O routines.
*/
#include <stdio.h>
#include "pvic.h"
#include "locdefs.h"
void
file_message(s)
char *s;
{
show_message("\"%s\" %s", (file_name == NULL) ? "" : file_name, s);
fflush(stdout);
}
void
renum()
{
LPTR *p;
unsigned long l = 0;
for (p = file_memory; p != NULL ;p = next_line(p), l += LINEINC)
p->linep->num = l;
end_of_file->linep->num = 0xffffffff;
}
#define MAXLINE 256 /* maximum size of a line */
int
read_file(fname,fromp,nochangename)
/*-------------------------------------------------
* Note that this will try to expand the file name using environment
* variables. For this reason, we copy it into an 80-byte buffer,
* so that there's room to expand it.
*
* It uses the environment-variable convention of UNIX, even
* under systems with other conventions. That is, your home directory
* would be called $HOME (even in DOS, where you might want to say %HOME%)
*-----------------------------------------------------*/
char *fname;
LPTR *fromp;
int nochangename; /* if (1), don't change the file_name */
{
FILE *f, *fopen();
register LINE *curr;
char buff[MAXLINE], buf2[80];
char namebuf[80];
register int i, c;
register long nchars = 0;
int linecnt = 0;
int wasempty = buffer_empty();
int nonascii = 0; /* count garbage characters */
int nulls = 0; /* count nulls */
int incomplete = (0); /* was the last line incomplete? */
int toolong = (0); /* a line was too long */
curr = fromp->linep;
strncpy (namebuf, fname, 80);
eval_environment (namebuf, 80);
if ( ! nochangename )
file_name = strsave(namebuf);
if ( (f=fopen(namebuf,"r")) == NULL )
return (1);
file_message("");
local_reset_control_c_pressed();
i = 0;
do {
c = getc(f);
if (c == EOF) {
if (i == 0) /* normal loop termination */
break;
/*
* If we get EOF in the middle of a line, note the
* fact and complete the line ourselves.
*/
incomplete = (1);
c = '\n';
}
/*
* Abort if we get an interrupt, but finished reading the
* current line first.
*/
if (local_control_c_pressed() && i == 0)
{
clear_screen();
update_screen(0);
break;
}
if (c<0 || c>=0x80) {
c -= 0x80;
nonascii++;
}
/*
* If we reached the end of the line, OR we ran out of
* space for it, then process the complete line.
*/
if (c == '\n' || i == (MAXLINE-1)) {
LINE *lp;
if (c != '\n')
toolong = (1);
buff[i] = '\0';
if ((lp = newline(strlen(buff))) == NULL)
exit(1);
strcpy(lp->s, buff);
curr->next->prev = lp; /* new line to next one */
lp->next = curr->next;
curr->next = lp; /* new line to prior one */
lp->prev = curr;
curr = lp; /* new line becomes current */
i = 0;
linecnt++;
} else if (c == '\0')
nulls++; /* count and ignore nulls */
else {
buff[i++] = c; /* normal character */
}
nchars++;
} while (!incomplete && !toolong);
fclose(f);
/*
* If the buffer was empty when we started, we have to go back
* and remove the "dummy" line at file_memory and patch up the ptrs.
*/
if (wasempty && nchars != 0) {
LINE *dummy = file_memory->linep; /* dummy line ptr */
free(dummy->s); /* free string space */
file_memory->linep = file_memory->linep->next;
free((char *)dummy); /* free LINE struct */
file_memory->linep->prev = top_of_file->linep;
top_of_file->linep->next = file_memory->linep;
cursor_char->linep = file_memory->linep;
top_char->linep = file_memory->linep;
}
renum();
if (local_control_c_pressed()) {
clear_screen();
update_screen(0);
show_message("\"%s\" Interrupt", namebuf);
local_reset_control_c_pressed();
return (0); /* an interrupt isn't really an error */
}
if (toolong) {
show_message("\"%s\" Line too long", namebuf);
return (0);
}
sprintf(buff, "\"%s\" %s%d line%s, %ld character%s",
namebuf,
incomplete ? "[Incomplete last line] " : "",
linecnt, (linecnt != 1) ? "s" : "",
nchars, (nchars != 1) ? "s" : "");
buf2[0] = '\0';
if (nonascii || nulls) {
if (nonascii) {
if (nulls)
sprintf(buf2, " (%d null, %d non-ASCII)",
nulls, nonascii);
else
sprintf(buf2, " (%d non-ASCII)", nonascii);
} else
sprintf(buf2, " (%d null)", nulls);
}
strcat(buff, buf2);
msg(buff);
return (0);
}
/*
* write_it - write to file 'fname' lines 'start' through 'end'
*
* If either 'start' or 'end' contain null line pointers, the default
* is to use the start or end of the file respectively.
*/
int
write_it(fname, start, end)
char *fname;
LPTR *start, *end;
{
FILE *f, *fopen();
char *backup;
register char *s;
register long nchars;
register int lines;
register LPTR *p;
show_message("\"%s\"", fname);
/* Expand any environment variables left in the name.
* fname better be in a variable big enough to handle the
* expansion (80 bytes).
*/
eval_environment (fname, 80);
/*
* Form the backup file name - change foo.* to foo.bak
*/
backup = alloc((unsigned) (strlen(fname) + 5));
if (backup == NULL) {
error_message("Can't open file for writing");
return (0);
}
strcpy(backup, fname);
for (s = backup; *s && *s != '.' ;s++)
;
*s = '\0';
strcat(backup, ".bak");
/*
* Delete any existing backup and move the current version
* to the backup. For safety, we don't remove the backup
* until the write has finished successfully. And if the
* 'backup' option is set, leave it around.
*/
rename_file(fname, backup);
f = fopen(fname, "w") ;
if (f == NULL) {
error_message("Can't open file for writing");
free(backup);
return (0);
}
/*
* If we were given a bound, start there. Otherwise just
* start at the beginning of the file.
*/
if (start == NULL || start->linep == NULL)
p = file_memory;
else
p = start;
lines = nchars = 0;
do {
fprintf(f, "%s\n", p->linep->s);
nchars += strlen(p->linep->s) + 1;
lines++;
/*
* If we were given an upper bound, and we just did that
* line, then bag it now.
*/
if (end != NULL && end->linep != NULL) {
if (end->linep == p->linep)
break;
}
} while ((p = next_line(p)) != NULL);
fclose(f);
show_message("\"%s\" %d line%s, %ld character%s", fname,
lines, (lines > 1) ? "s" : "",
nchars, (nchars > 1) ? "s" : "");
UNCHANGED;
/*
* Remove the backup unless they want it left around
*/
if (!PARAMETER_VALUE(PARAMETER_BACKUP))
unlink(backup);
free(backup);
return (1);
}