xref: /csrg-svn/contrib/ed/w.c (revision 59475)
157703Sbostic /*-
257703Sbostic  * Copyright (c) 1992 The Regents of the University of California.
357703Sbostic  * All rights reserved.
457703Sbostic  *
557703Sbostic  * This code is derived from software contributed to Berkeley by
657703Sbostic  * Rodney Ruddock of the University of Guelph.
757703Sbostic  *
857703Sbostic  * %sccs.include.redist.c%
957703Sbostic  */
1057703Sbostic 
1157703Sbostic #ifndef lint
12*59475Sbostic static char sccsid[] = "@(#)w.c	5.6 (Berkeley) 04/28/93";
1357703Sbostic #endif /* not lint */
1457703Sbostic 
1557710Sbostic #include <sys/types.h>
1657710Sbostic 
17*59475Sbostic #include <limits.h>
1857710Sbostic #include <regex.h>
1957710Sbostic #include <setjmp.h>
2057710Sbostic #include <stdio.h>
2157710Sbostic #include <stdlib.h>
2257710Sbostic #include <string.h>
2357710Sbostic 
2458315Sbostic #ifdef DBI
2558315Sbostic #include <db.h>
2658315Sbostic #endif
2758315Sbostic 
2857703Sbostic #include "ed.h"
2957710Sbostic #include "extern.h"
3057703Sbostic 
3157703Sbostic /*
3257703Sbostic  * Write the contents of the buffer out to the real file (spec'd or
3357703Sbostic  * remembered). If 'w' then overwrite, if 'W' append to the file. 'W'
3457703Sbostic  * is probably _the_ command that most editors don't have, and it's
3557703Sbostic  * so(!) useful. The 'wq' works as 'w' but 'q' immediately follows.
3657703Sbostic  * Shame on POSIX for not including 'W' and 'wq', they're not that
3757703Sbostic  * hard to implement; yaaa! BSD for keeping it! :-)
3857703Sbostic  */
3957703Sbostic void
4057703Sbostic w(inputt, errnum)
4157710Sbostic 	FILE *inputt;
4257710Sbostic 	int *errnum;
4357703Sbostic {
44*59475Sbostic 	FILE *l_fp;
45*59475Sbostic 	int l_ttl = 0, l_q_flag = 0, l_sl, l_bang_flag=0;
46*59475Sbostic 	char *filename_read=NULL, *l_temp;
4757703Sbostic 
4858564Sralph 	if (Start_default && End_default) {
4958564Sralph 		Start = top;
5057710Sbostic 		End = bottom;
5157710Sbostic 	} else
5258564Sralph 		if (Start_default)
5358564Sralph 			Start = End;
5458564Sralph 	if (Start == NULL) {
5558315Sbostic 		strcpy(help_msg, "buffer empty");
5657710Sbostic 		*errnum = -1;
5757710Sbostic 		return;
5857710Sbostic 	}
5958564Sralph 	Start_default = End_default = 0;
6057703Sbostic 
6157710Sbostic 	l_sl = ss;
6257710Sbostic 	ss = getc(inputt);
6357703Sbostic 
6457710Sbostic 	if (ss == 'q')		/* "wq" and "Wq" command */
6557710Sbostic 		l_q_flag = 1;
6657710Sbostic 	else
6757710Sbostic 		ungetc(ss, inputt);
6857703Sbostic 
69*59475Sbostic 	l_temp = filename(inputt, errnum);
7057710Sbostic 	if (*errnum == 1)
71*59475Sbostic 		filename_read = l_temp;
7257710Sbostic 	else
7357710Sbostic 		if (*errnum == -2) {
7457710Sbostic 			while (((ss = getc(inputt)) != '\n') || (ss == EOF));
7557710Sbostic 			filename_read = filename_current;
7657710Sbostic 		} else
7757710Sbostic 			if (*errnum < 0)
7857710Sbostic 				return;
7957710Sbostic 	*errnum = 0;
8057703Sbostic 
8157710Sbostic 	if (filename_current == NULL) {
8257710Sbostic 		if (filename_read == NULL) {
8357710Sbostic 			strcpy(help_msg, "no filename given");
8457710Sbostic 			*errnum = -1;
8557710Sbostic 			ungetc('\n', inputt);
8657710Sbostic 			return;
8757710Sbostic 		} else
8857710Sbostic 			filename_current = filename_read;
8957710Sbostic 	}
9058315Sbostic 	sigspecial++;
91*59475Sbostic 	if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */
92*59475Sbostic 		FILE *popen();
93*59475Sbostic 
94*59475Sbostic 		if (l_temp[0] == '\0') {
95*59475Sbostic 			strcpy(help_msg, "no command given");
96*59475Sbostic 			*errnum = -1;
97*59475Sbostic 			sigspecial--;
98*59475Sbostic 			return;
99*59475Sbostic 		}
100*59475Sbostic 		if ((l_fp = popen(l_temp, "w")) == NULL) {
101*59475Sbostic 			strcpy(help_msg, "error executing command");
102*59475Sbostic 			*errnum = -1;
103*59475Sbostic 			if (l_fp != NULL)
104*59475Sbostic 				pclose(l_fp);
105*59475Sbostic 			sigspecial--;
106*59475Sbostic 			return;
107*59475Sbostic 		}
108*59475Sbostic 		l_bang_flag = 1;
109*59475Sbostic 	}
110*59475Sbostic 	else if (l_sl == 'W')
111*59475Sbostic 		l_fp = fopen(filename_read, "a");
11257710Sbostic 	else
113*59475Sbostic 		l_fp = fopen(filename_read, "w");
11457703Sbostic 
115*59475Sbostic 	if (l_fp == NULL) {
11657710Sbostic 		strcpy(help_msg, "cannot write to file");
11757710Sbostic 		*errnum = -1;
11857710Sbostic 		ungetc('\n', inputt);
119*59475Sbostic 		sigspecial--;
12057710Sbostic 		return;
12157710Sbostic 	}
12258315Sbostic 	sigspecial--;
12358315Sbostic 	if (sigint_flag && (!sigspecial))
12457710Sbostic 		goto point;
12557703Sbostic 
12657710Sbostic 	/* Write it out and get a report on the number of bytes written. */
127*59475Sbostic 	l_ttl = edwrite(l_fp, Start, End);
12858710Sbostic 	if (explain_flag > 0)		/* For -s option. */
12957710Sbostic 		printf("%d\n", l_ttl);
13057703Sbostic 
131*59475Sbostic point:	if (l_bang_flag)
132*59475Sbostic 		pclose(l_fp);
133*59475Sbostic 	else
134*59475Sbostic 		fclose(l_fp);
13557710Sbostic 	if (filename_read != filename_current)
13657710Sbostic 		free(filename_read);
13757710Sbostic 	change_flag = 0L;
13857710Sbostic 	*errnum = 1;
13958315Sbostic 	if (l_q_flag) {			/* For "wq" and "Wq". */
14057710Sbostic 		ungetc('\n', inputt);
14157710Sbostic 		ss = (int) 'q';
14257710Sbostic 		q(inputt, errnum);
14357710Sbostic 	}
14457703Sbostic }
14557703Sbostic 
14657703Sbostic /*
14757703Sbostic  * Actually writes out the contents of the buffer to the specified
14857703Sbostic  * STDIO file pointer for the range of lines specified.
14957703Sbostic  */
15057703Sbostic int
15157703Sbostic edwrite(fp, begi, fini)
15257710Sbostic 	FILE *fp;
15357710Sbostic 	LINE *begi, *fini;
15457710Sbostic {
15557710Sbostic 	register int l_ttl = 0;
15657703Sbostic 
15757710Sbostic 	for (;;) {
15857710Sbostic 		get_line(begi->handle, begi->len);
15958315Sbostic 		if (sigint_flag && (!sigspecial))
16058315Sbostic 			break;
16157703Sbostic 
16258315Sbostic 		sigspecial++;
16357710Sbostic 		/* Fwrite is about 20+% faster than fprintf -- no surprise. */
16457710Sbostic 		fwrite(text, sizeof(char), begi->len, fp);
16557710Sbostic 		fputc('\n', fp);
16657710Sbostic 		l_ttl = l_ttl + (begi->len) + 1;
16757710Sbostic 		if (begi == fini)
16857710Sbostic 			break;
16957710Sbostic 		else
17057710Sbostic 			begi = begi->below;
17158315Sbostic 		sigspecial--;
17258315Sbostic 		if (sigint_flag && (!sigspecial))
17358315Sbostic 			break;
17457710Sbostic 	}
17557710Sbostic 	return (l_ttl);
17657710Sbostic }
177