xref: /original-bsd/contrib/ed/w.c (revision 044d1bee)
1 /*-
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rodney Ruddock of the University of Guelph.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)w.c	5.2 (Berkeley) 01/23/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 
17 #include <db.h>
18 #include <regex.h>
19 #include <setjmp.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "ed.h"
25 #include "extern.h"
26 
27 /*
28  * Write the contents of the buffer out to the real file (spec'd or
29  * remembered). If 'w' then overwrite, if 'W' append to the file. 'W'
30  * is probably _the_ command that most editors don't have, and it's
31  * so(!) useful. The 'wq' works as 'w' but 'q' immediately follows.
32  * Shame on POSIX for not including 'W' and 'wq', they're not that
33  * hard to implement; yaaa! BSD for keeping it! :-)
34  */
35 void
36 w(inputt, errnum)
37 	FILE *inputt;
38 	int *errnum;
39 {
40 	FILE *fp;
41 	int l_ttl = 0, l_q_flag = 0, l_sl;
42 	char *filename_read, *temp;
43 
44 	if (start_default && End_default) {
45 		start = top;
46 		End = bottom;
47 	} else
48 		if (start_default)
49 			start = End;
50 	if (start == NULL) {
51 		strcpy(help_msg, "bad address");
52 		*errnum = -1;
53 		return;
54 	}
55 	start_default = End_default = 0;
56 
57 	l_sl = ss;
58 	ss = getc(inputt);
59 
60 	if (ss == 'q')		/* "wq" and "Wq" command */
61 		l_q_flag = 1;
62 	else
63 		ungetc(ss, inputt);
64 
65 	temp = filename(inputt, errnum);
66 	if (sigint_flag)
67 		SIGINT_ACTION;
68 	if (*errnum == 1)
69 		filename_read = temp;
70 	else
71 		if (*errnum == -2) {
72 			while (((ss = getc(inputt)) != '\n') || (ss == EOF));
73 			filename_read = filename_current;
74 		} else
75 			if (*errnum < 0)
76 				return;
77 	*errnum = 0;
78 
79 	if (filename_current == NULL) {
80 		if (filename_read == NULL) {
81 			strcpy(help_msg, "no filename given");
82 			*errnum = -1;
83 			ungetc('\n', inputt);
84 			return;
85 		} else
86 			filename_current = filename_read;
87 	}
88 	if (l_sl == 'W')
89 		fp = fopen(filename_read, "a");
90 	else
91 		fp = fopen(filename_read, "w");
92 
93 	if (fp == NULL) {
94 		strcpy(help_msg, "cannot write to file");
95 		*errnum = -1;
96 		ungetc('\n', inputt);
97 		return;
98 	}
99 	if (sigint_flag)
100 		goto point;
101 
102 	/* Write it out and get a report on the number of bytes written. */
103 	l_ttl = edwrite(fp, start, End);
104 	if (explain_flag != 0)		/* For -s option. */
105 		printf("%d\n", l_ttl);
106 
107 point:	fclose(fp);
108 	if (sigint_flag)
109 		SIGINT_ACTION;
110 	if (filename_read != filename_current)
111 		free(filename_read);
112 	change_flag = 0L;
113 	*errnum = 1;
114 	if (l_q_flag) {			/* For "wq". */
115 		ungetc('\n', inputt);
116 		ss = (int) 'q';
117 		q(inputt, errnum);
118 	}
119 }
120 
121 /*
122  * Actually writes out the contents of the buffer to the specified
123  * STDIO file pointer for the range of lines specified.
124  */
125 int
126 edwrite(fp, begi, fini)
127 	FILE *fp;
128 	LINE *begi, *fini;
129 {
130 	register int l_ttl = 0;
131 
132 	for (;;) {
133 		get_line(begi->handle, begi->len);
134 
135 		/* Fwrite is about 20+% faster than fprintf -- no surprise. */
136 		fwrite(text, sizeof(char), begi->len, fp);
137 		fputc('\n', fp);
138 		l_ttl = l_ttl + (begi->len) + 1;
139 		if (begi == fini)
140 			break;
141 		else
142 			begi = begi->below;
143 		if (sigint_flag)
144 			return (l_ttl);
145 	}
146 	return (l_ttl);
147 }
148