⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.c

📁 STEVIE文本文件编缉器的C 语言源程序
💻 C
字号:
/* $Header: /nw2/tony/src/stevie/src/RCS/fileio.c,v 1.12 89/08/06 09:50:01 tony Exp $
 *
 * Basic file I/O routines.
 */

#include "stevie.h"

void
filemess(s)
char	*s;
{
	smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s);
	flushbuf();
}

void
renum()
{
	LPTR	*p;
	unsigned long l = 0;

	for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC)
		p->linep->num = l;

	Fileend->linep->num = 0xffffffff;
}

#define	MAXLINE	256	/* maximum size of a line */

bool_t
readfile(fname,fromp,nochangename)
char	*fname;
LPTR	*fromp;
bool_t	nochangename;	/* if TRUE, don't change the Filename */
{
	FILE	*f, *fopen();
	register LINE	*curr;
	char	buff[MAXLINE], buf2[80];
	register int	i, c;
	register long	nchars = 0;
	int	linecnt = 0;
	bool_t	wasempty = bufempty();
	int	nonascii = 0;		/* count garbage characters */
	int	nulls = 0;		/* count nulls */
	bool_t	incomplete = FALSE;	/* was the last line incomplete? */
	bool_t	toolong = FALSE;	/* a line was too long */

	curr = fromp->linep;

	if ( ! nochangename )
		Filename = strsave(fname);

	if ( (f=fopen(fixname(fname),"r")) == NULL )
		return TRUE;

	filemess("");

	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 = TRUE;
			c = NL;
		}

		/*
		 * Abort if we get an interrupt, but finished reading the
		 * current line first.
		 */
		if (got_int && i == 0)
			break;

		if (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 == NL || i == (MAXLINE-1)) {
			LINE	*lp;

			if (c != NL)
				toolong = TRUE;

			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 == NUL)
			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 Filemem and patch up the ptrs.
	 */
	if (wasempty && nchars != 0) {
		LINE	*dummy = Filemem->linep;	/* dummy line ptr */

		free(dummy->s);				/* free string space */
		Filemem->linep = Filemem->linep->next;
		free((char *)dummy);			/* free LINE struct */
		Filemem->linep->prev = Filetop->linep;
		Filetop->linep->next = Filemem->linep;

		Curschar->linep = Filemem->linep;
		Topchar->linep  = Filemem->linep;
	}

	renum();

	if (got_int) {
		smsg("\"%s\" Interrupt", fname);
		got_int = FALSE;
		return FALSE;		/* an interrupt isn't really an error */
	}

	if (toolong) {
		smsg("\"%s\" Line too long", fname);
		return FALSE;
	}

	sprintf(buff, "\"%s\" %s%d line%s, %ld character%s",
		fname,
		incomplete ? "[Incomplete last line] " : "",
		linecnt, (linecnt != 1) ? "s" : "",
		nchars, (nchars != 1) ? "s" : "");

	buf2[0] = NUL;

	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 FALSE;
}


/*
 * writeit - 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.
 */
bool_t
writeit(fname, start, end)
char	*fname;
LPTR	*start, *end;
{
	FILE	*f, *fopen();
	FILE	*fopenb();		/* open in binary mode, where needed */
	char	*backup;
	register char	*s;
	register long	nchars;
	register int	lines;
	register LPTR	*p;

	smsg("\"%s\"", fname);

	/*
	 * Form the backup file name - change foo.* to foo.bak
	 */
	backup = alloc((unsigned) (strlen(fname) + 5));
	strcpy(backup, fname);
	for (s = backup; *s && *s != '.' ;s++)
		;
	*s = NUL;
	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(fname, backup);


	f = P(P_CR) ? fopen(fixname(fname), "w") : fopenb(fixname(fname), "w");

	if (f == NULL) {
		emsg("Can't open file for writing!");
		free(backup);
		return FALSE;
	}

	/*
	 * If we were given a bound, start there. Otherwise just
	 * start at the beginning of the file.
	 */
	if (start == NULL || start->linep == NULL)
		p = Filemem;
	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 = nextline(p)) != NULL);

	fclose(f);
	smsg("\"%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 (!P(P_BK))
		remove(backup);

	free(backup);

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -