home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
gnu
/
src
/
baseline
/
jove-4.14.6.lha
/
jove-4.14.6
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-10
|
29KB
|
1,462 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
#include "jove.h"
#include "list.h"
#include "fp.h"
#include "termcap.h"
#include "ctype.h"
#include "disp.h"
#include "scandir.h"
#ifdef IPROCS
# include <signal.h>
#endif
#ifdef MAC
# include "mac.h"
#else
# include <sys/stat.h>
#endif
#ifdef UNIX
# include <sys/file.h>
#endif
#ifdef MSDOS
# include <fcntl.h>
# include <io.h>
# include <direct.h>
# include <dos.h>
#endif /* MSDOS */
#include <errno.h>
private struct block
*lookup proto((int /* promoted short */));
private char
#ifdef MSDOS
*fixpath proto((char *)),
#endif
*getblock proto((daddr, bool));
private bool
f_getputl proto((struct line *line,struct FileStruct *fp));
private void
#ifdef MSDOS
abspath proto((char *, char *)),
#endif
file_backup proto((char *fname));
#ifdef MSDOS
private int
Dchdir proto((char *));
#endif
long io_chars; /* number of chars in this open_file */
int io_lines; /* number of lines in this open_file */
#ifdef pdp11
char *iobuff,
*genbuf,
*linebuf;
#else
char iobuff[LBSIZE],
genbuf[LBSIZE],
linebuf[LBSIZE];
#endif
#ifdef BACKUPFILES
bool BkupOnWrite = OFF;
#endif
#ifndef MSDOS
#define Dchdir(to) chdir(to)
#else /* MSDOS */
private int /* chdir + drive */
Dchdir(to)
char *to;
{
unsigned d, dd, n;
if (to[1] == ':') {
d = CharUpcase(to[0]) - 'A';
/* ??? only 16 drives? */
if (d >= 16)
complain("invalid drive");
_dos_getdrive(&dd);
if (dd != d)
_dos_setdrive(d, &n);
if (to[2] == '\0') {
/* ??? Is this correct? DHR
* Current path on this drive might not be the root.
*/
return 0;
}
}
return chdir(to);
}
private char *
fixpath(p)
char *p;
{
char *pp = p;
while (*p) {
if (*p == '\\')
*p = '/';
p++;
}
return strlwr(pp);
}
private void
abspath(so, dest)
char *so, *dest;
{
char cwd[FILESIZE], cwdD[3], cwdDIR[FILESIZE], cwdF[9], cwdEXT[5],
soD[3], soDIR[FILESIZE], soF[9], soEXT[5];
char *drive, *path;
_splitpath(fixpath(so), soD, soDIR, soF, soEXT);
getcwd(cwd, FILESIZE);
if (*soD != '\0') {
Dchdir(soD); /* this is kinda messy */
getcwd(cwdDIR, FILESIZE); /* should probably just */
Dchdir(cwd); /* call DOS to do it */
strcpy(cwd, cwdDIR);
}
(void) fixpath(cwd);
if (cwd[strlen(cwd)-1] != '/')
strcat(cwd, "/x.x"); /* need dummy filename */
_splitpath(fixpath(cwd), cwdD, cwdDIR, cwdF, cwdEXT);
drive = (*soD == '\0') ? cwdD : soD;
if (*soDIR != '/')
path = strcat(cwdDIR, soDIR);
else
path = soDIR;
_makepath(dest, drive, path, soF, soEXT);
fixpath(dest); /* can't do it often enough */
}
#endif /* MSDOS */
void
close_file(fp)
File *fp;
{
if (fp) {
if (fp->f_flags & F_TELLALL)
add_mess(" %d lines, %D characters.",
io_lines,
io_chars);
f_close(fp);
}
}
/* Write the region from line1/char1 to line2/char2 to FP. This
never CLOSES the file since we don't know if we want to. */
bool EndWNewline = 1;
void
putreg(fp, line1, char1, line2, char2, makesure)
register File *fp;
Line *line1,
*line2;
int char1,
char2;
bool makesure;
{
register int c;
register char *lp;
if (makesure)
(void) fixorder(&line1, &char1, &line2, &char2);
while (line1 != line2->l_next) {
lp = lcontents(line1) + char1;
if (line1 == line2) {
fputnchar(lp, (char2 - char1), fp);
io_chars += (char2 - char1);
} else {
while ((c = *lp++) != '\0') {
jputc(c, fp);
io_chars += 1;
}
}
if (line1 != line2) {
io_lines += 1;
io_chars += 1;
#ifdef MSDOS
jputc('\r', fp);
#endif /* MSDOS */
jputc('\n', fp);
}
line1 = line1->l_next;
char1 = 0;
}
flushout(fp);
}
private void
dofread(fp)
register File *fp;
{
char end[LBSIZE];
bool xeof;
Line *savel = curline;
int savec = curchar;
strcpy(end, linebuf + curchar);
xeof = f_gets(fp, linebuf + curchar, (size_t) (LBSIZE - curchar));
SavLine(curline, linebuf);
while(!xeof) {
curline = listput(curbuf, curline);
xeof = f_getputl(curline, fp);
}
getDOT();
linecopy(linebuf, (curchar = strlen(linebuf)), end);
SavLine(curline, linebuf);
IFixMarks(savel, savec, curline, curchar);
}
void
read_file(file, is_insert)
char *file;
bool is_insert;
{
Bufpos save;
File *fp;
int rdonly;
if (!is_insert)
curbuf->b_ntbf = NO;
fp = open_file(file, iobuff, F_READ, NO, NO);
if (fp == NULL) {
if (!is_insert && errno == ENOENT)
s_mess("(new file)");
else
s_mess(IOerr("open", file));
return;
}
rdonly = (fp->f_flags & F_READONLY)? 1 : 0;
DOTsave(&save);
dofread(fp);
if (is_insert && io_chars > 0) {
modify();
set_mark();
}
SetDot(&save);
getDOT();
close_file(fp);
/* just guessing that if this is moved here */
/* then the bug on SunOS that seems to alter */
/* mtime under our feet will disappear */
if (!is_insert) {
set_ino(curbuf);
set_arg_value(rdonly);
TogMinor(ReadOnly);
}
}
void
SaveFile()
{
if (IsModified(curbuf)) {
if (curbuf->b_fname == NULL)
WriteFile();
else {
filemunge(curbuf->b_fname);
chk_mtime(curbuf, curbuf->b_fname, "save");
file_write(curbuf->b_fname, NO);
}
} else
message("No changes need to be written.");
}
char *HomeDir; /* home directory */
size_t HomeLen; /* length of home directory string */
private List *DirStack = NULL;
#define dir_name(dp) ((char *) list_data((dp)))
#define PWD_PTR (list_data(DirStack))
#define PWD ((char *) PWD_PTR)
char *
pwd()
{
return (char *) PWD_PTR;
}
char *
pr_name(fname, okay_home)
char *fname;
int okay_home;
{
int n;
if (fname != NULL) {
n = numcomp(fname, PWD);
if ((PWD[n] == '\0') && /* Matched to end of PWD */
(fname[n] == '/'))
return fname + n + 1;
if (okay_home && strcmp(HomeDir, "/") != 0
&& strncmp(fname, HomeDir, HomeLen) == 0
&& fname[HomeLen] == '/')
{
static char name_buf[100];
swritef(name_buf, sizeof(name_buf),
"~%s", fname + HomeLen);
return name_buf;
}
}
return fname;
}
void
Chdir()
{
char dirbuf[FILESIZE];
#ifdef MSDOS
fmask = 0x10;
#endif
(void) ask_file((char *)NULL, PWD, dirbuf);
#ifdef MSDOS
fmask = 0x13;
#endif
if (Dchdir(dirbuf) == -1)
{
s_mess("cd: cannot change into %s.", dirbuf);
return;
}
UpdModLine = YES;
setCWD(dirbuf);
prCWD();
#ifdef MAC
Bufchange = YES;
#endif
}
#ifdef UNIX
# ifndef BSD4_2
char *
getwd(buffer)
char *buffer;
{
Buffer *old = curbuf;
char *ret_val;
SetBuf(do_select((Window *)NULL, "pwd-output"));
curbuf->b_type = B_PROCESS;
(void) UnixToBuf("pwd-output", (char *)NULL, NO, 0, YES,
"/bin/pwd", (char *) NULL);
ToFirst();
strcpy(buffer, linebuf);
SetBuf(old);
return buffer;
}
# endif /* not BSD4_2 */
/* Check if dn is the name of the current working directory
and that it is in cannonical form */
bool
chkCWD(dn)
char *dn;
{
char filebuf[FILESIZE];
struct stat dnstat,
dotstat;
if (dn[0] != '/')
return FALSE; /* need absolute pathname */
PathParse(dn, filebuf);
return stat(filebuf, &dnstat) == 0 &&
stat(".", &dotstat) == 0 &&
dnstat.st_dev == dotstat.st_dev &&
dnstat.st_ino == dotstat.st_ino;
}
#endif /* UNIX */
void
setCWD(d)
char *d;
{
if (DirStack == NULL)
list_push(&DirStack, (UnivPtr)NULL);
PWD_PTR = (PWD == NULL)
? (UnivPtr) emalloc((size_t) (strlen(d) + 1))
: (UnivPtr) freealloc((UnivPtr) PWD, strlen(d) + 1);
strcpy(PWD, d);
}
void
getCWD()
{
char *cwd;
char pathname[FILESIZE];
#ifndef MSDOS
cwd = getenv("CWD");
if (cwd == NULL || !chkCWD(cwd)) {
cwd = getenv("PWD");
if (cwd == NULL || !chkCWD(cwd)) {
#ifdef HAVE_GETWD
cwd = getwd(pathname);
#else
/* System Vr4, and who else? */
extern char *getcwd proto((char *, int/*!!!*/));
cwd = getcwd(pathname, (int) sizeof(pathname));
#endif /* HAVE_GETWD */
}
}
#else /* MSDOS */
{
extern char *getcwd();
cwd = fixpath(getcwd(pathname, FILESIZE));
}
#