|
|
1.1 root 1: /*
2: * The routines in this file handle the reading and writing of disk files.
3: * All of details about the reading and writing of the disk are in "fileio.c".
4: */
5: #include <stdio.h>
6: #include "ed.h"
7:
8: /*
9: * Read a file into the current buffer.
10: * This is really easy; all you do it find the name of the file and call
11: * the standard "read a file into the current buffer" code.
12: * Bound to "C-X C-R".
13: */
14: fileread(f, n)
15: {
16: register int s;
17: uchar fname[NFILEN];
18:
19: if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
20: return (s);
21: #if GEM
22: fixname(fname);
23: #endif
24: return (readin(fname));
25: }
26:
27: /*
28: * Select a file for editing.
29: * Look around to see if you can find the file in another buffer;
30: * if you can find it just switch to the buffer. If you cannot find
31: * the file, create a new buffer, read in the text, and switch to the
32: * new buffer.
33: * Bound to C-X C-V.
34: */
35: filevisit(f, n)
36: {
37: uchar fname[NFILEN];
38: int s;
39:
40: if ((s=mlreply("Visit file: ", fname, NFILEN)) != TRUE)
41: return (s);
42: #if GEM
43: fixname(fname);
44: #endif
45: return visitfile(fname);
46: }
47:
48: /* Real file visit routine... */
49: visitfile(fname)
50: uchar fname[];
51: {
52: register BUFFER *bp;
53: register WINDOW *wp;
54: register LINE *lp;
55: register int i;
56: register int s;
57: uchar bname[NBUFN];
58:
59: for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
60: if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0) {
61: if (--curbp->b_nwnd == 0) {
62: curbp->b_dotp = curwp->w_dotp;
63: curbp->b_doto = curwp->w_doto;
64: curbp->b_markp = curwp->w_markp;
65: curbp->b_marko = curwp->w_marko;
66: }
67: curbp = bp;
68: curwp->w_bufp = bp;
69: if (bp->b_nwnd++ == 0) {
70: curwp->w_dotp = bp->b_dotp;
71: curwp->w_doto = bp->b_doto;
72: curwp->w_markp = bp->b_markp;
73: curwp->w_marko = bp->b_marko;
74: } else {
75: wp = wheadp;
76: while (wp != NULL) {
77: if (wp!=curwp && wp->w_bufp==bp) {
78: curwp->w_dotp = wp->w_dotp;
79: curwp->w_doto = wp->w_doto;
80: curwp->w_markp = wp->w_markp;
81: curwp->w_marko = wp->w_marko;
82: break;
83: }
84: wp = wp->w_wndp;
85: }
86: }
87: lp = curwp->w_dotp;
88: i = curwp->w_ntrows/2;
89: while (i-- && lback(lp)!=curbp->b_linep)
90: lp = lback(lp);
91: curwp->w_linep = lp;
92: curwp->w_flag |= WFMODE|WFHARD;
93: mlwrite("[Old buffer]");
94: return (TRUE);
95: }
96: }
97: makename(bname, fname); /* New buffer name. */
98: while ((bp=bfind(bname, FALSE, 0)) != NULL) {
99: s = mlreply("Buffer name: ", bname, NBUFN);
100: #if GEM
101: fixname(bname);
102: #endif
103: if (s == ABORT) /* ^G to just quit */
104: return (s);
105: if (s == FALSE) { /* CR to clobber it */
106: makename(bname, fname);
107: break;
108: }
109: }
110: if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
111: mlwrite("Cannot create buffer");
112: return (FALSE);
113: }
114: if (--curbp->b_nwnd == 0) { /* Undisplay. */
115: curbp->b_dotp = curwp->w_dotp;
116: curbp->b_doto = curwp->w_doto;
117: curbp->b_markp = curwp->w_markp;
118: curbp->b_marko = curwp->w_marko;
119: }
120: curbp = bp; /* Switch to it. */
121: curwp->w_bufp = bp;
122: curbp->b_nwnd++;
123: return (readin(fname)); /* Read it in. */
124: }
125:
126: /*
127: * Read file "fname" into the current buffer, blowing away any text found
128: * there. Called by both the read and visit commands. Return the final
129: * status of the read. Also called by the mainline, to read in a file
130: * specified on the command line as an argument.
131: */
132: readin(fname)
133: uchar fname[];
134: {
135: register LINE *lp1;
136: register LINE *lp2;
137: register int i;
138: register WINDOW *wp;
139: register BUFFER *bp;
140: register int s;
141: register int nbytes;
142: register int nline;
143: uchar line[NLINE];
144:
145: mlwrite(" ");
146: bp = curbp; /* Cheap. */
147: if ((s=bclear(bp)) != TRUE) /* Might be old. */
148: return (s);
149: bp->b_flag &= ~(BFTEMP|BFCHG|BFTRUNC);
150: strcpy(bp->b_fname, fname);
151: switch (s=ffropen(fname)) { /* file open */
152: case FIOERR: /* file exists but cannot read */
153: mlwrite("[Cannot read %s]", fname);
154: goto out;
155: case FIOFNF: /* File not found. */
156: mlwrite("[New file: %s]", fname);
157: goto out;
158: }
159: mlwrite("[Reading file %s]", fname);
160: nline = 0;
161: while ((s=ffgetline(line, NLINE)) == FIOSUC) {
162: nbytes = strlen(line);
163: if ((lp1=lalloc(nbytes)) == NULL) {
164: mlwrite("File too large for available memory!");
165: bp->b_flag |= BFTRUNC; /* Mark buffer truncated */
166: s = FIOERR; /* Keep message on the */
167: break; /* display. */
168: }
169: lp2 = lback(curbp->b_linep);
170: lforw(lp2) = lp1;
171: lforw(lp1) = curbp->b_linep;
172: lback(lp1) = lp2;
173: lback(curbp->b_linep) = lp1;
174: lp1->l_lnumber = ++nline;
175: #ifdef SLOW
176: for (i=0; i<nbytes; ++i)
177: lputc(lp1, i, line[i]);
178: #else
179: strncpy(lp1->l_text, line, nbytes);
180: #endif
181: }
182: ffclose(); /* Ignore errors. */
183: if (s == FIOEOF) { /* Don't zap message! */
184: if (nline == 1)
185: mlwrite("[Read 1 line]");
186: else
187: mlwrite("[Read %d lines]", nline);
188: }
189: out:
190: for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
191: if (wp->w_bufp == curbp) {
192: wp->w_linep = lforw(curbp->b_linep);
193: wp->w_dotp = lforw(curbp->b_linep);
194: wp->w_doto = 0;
195: wp->w_markp = NULL;
196: wp->w_marko = 0;
197: wp->w_flag |= WFMODE|WFHARD;
198: }
199: }
200: if (s == FIOERR) /* False if error. */
201: return (FALSE);
202: return (TRUE);
203: }
204:
205: /*
206: * Take a file name, and from it fabricate a buffer name.
207: * This routine knows about the syntax of file names on the target system.
208: * I suppose that this information could be put in a better place than a
209: * line of code.
210: */
211: makename(bname, fname)
212: uchar bname[];
213: uchar fname[];
214: {
215: register uchar *cp1;
216: register uchar *cp2;
217:
218: cp1 = &fname[0];
219: while (*cp1 != 0)
220: ++cp1;
221: #if VMS
222: while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
223: --cp1;
224: #endif
225: #if CPM
226: while (cp1!=&fname[0] && cp1[-1]!=':')
227: --cp1;
228: #endif
229: #if MSDOS || GEM
230: while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
231: --cp1;
232: #endif
233: #if V7
234: while (cp1!=&fname[0] && cp1[-1]!='/')
235: --cp1;
236: #endif
237: cp2 = &bname[0];
238: while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
239: *cp2++ = *cp1++;
240: *cp2 = 0;
241: }
242:
243: /*
244: * Ask for a file name, and write the contents of the current buffer to
245: * that file. Update the remembered file name and clear the buffer changed
246: * flag. This handling of file names is different from the earlier versions,
247: * and is more compatable with Gosling EMACS than with ITS EMACS.
248: * Bound to "C-X C-W".
249: */
250: filewrite(f, n)
251: {
252: register WINDOW *wp;
253: register int s;
254: uchar fname[NFILEN];
255:
256: if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
257: return (s);
258: #if GEM
259: fixname(fname);
260: #endif
261: if ((s=writeout(fname)) == TRUE) {
262: strcpy(curbp->b_fname, fname);
263: curbp->b_flag &= ~BFCHG;
264: wp = wheadp; /* Update mode lines. */
265: while (wp != NULL) {
266: if (wp->w_bufp == curbp)
267: wp->w_flag |= WFMODE;
268: wp = wp->w_wndp;
269: }
270: }
271: return (s);
272: }
273:
274: /*
275: * Save the contents of the current buffer in its associatd file. No nothing
276: * if nothing has changed (this may be a bug, not a feature). Error if there is
277: * no remembered file name for the buffer. Bound to "C-X C-S".
278: * May get called by "C-Z".
279: */
280: filesave(f, n)
281: {
282: register WINDOW *wp;
283: register int s;
284:
285: if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */
286: return (TRUE);
287: if (curbp->b_fname[0] == 0) { /* Must have a name. */
288: mlwrite("No file name");
289: return (FALSE);
290: }
291: if ((curbp->b_flag & BFTRUNC) != 0) { /* If file was truncated... */
292: if (mlyesno("File was truncated -- write it anyway") != TRUE)
293: return (FALSE);
294: }
295: if ((s=writeout(curbp->b_fname)) == TRUE) {
296: curbp->b_flag &= ~(BFCHG|BFTRUNC);
297: wp = wheadp; /* Update mode lines. */
298: while (wp != NULL) {
299: if (wp->w_bufp == curbp)
300: wp->w_flag |= WFMODE;
301: wp = wp->w_wndp;
302: }
303: }
304: return (s);
305: }
306:
307: /*
308: * This function performs the details of file writing.
309: * Uses the file management routines in the "fileio.c" package.
310: * The number of lines written is displayed. Sadly, it looks inside a LINE;
311: * provide a macro for this. Most of the grief is error checking of some sort.
312: */
313: writeout(fn)
314: uchar *fn;
315: {
316: register int s;
317: register LINE *lp;
318: register int nline;
319:
320: if ((s=ffwopen(fn, "w")) != FIOSUC) /* Open writes message. */
321: return (FALSE);
322: lp = lforw(curbp->b_linep); /* First line. */
323: nline = 0; /* Number of lines. */
324: while (lp != curbp->b_linep) {
325: if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
326: break;
327: ++nline;
328: lp = lforw(lp);
329: }
330: if (s == FIOSUC) { /* No write error. */
331: s = ffclose();
332: if (s == FIOSUC) { /* No close error. */
333: curbp->b_flag |= BFWRITE; /* Written... */
334: if (nline == 1)
335: mlwrite("[Wrote 1 line]");
336: else
337: mlwrite("[Wrote %d lines]", nline);
338: }
339: } else /* Ignore close error */
340: ffclose(); /* if a write error. */
341:
342: sync(); /* protect filesystem */
343:
344: if (s != FIOSUC) /* Some sort of error. */
345: return (FALSE);
346: return (TRUE);
347: }
348:
349: /*
350: * The command allows the user to modify the file name associated with
351: * the current buffer. It is like the "f" command in UNIX "ed".
352: * The operation is simple; just zap the name in the BUFFER structure,
353: * and mark the windows as needing an update. You can type a blank line at
354: * the prompt if you wish.
355: */
356: filename(f, n)
357: {
358: register WINDOW *wp;
359: register int s;
360: uchar fname[NFILEN];
361:
362: if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
363: return (s);
364: #if GEM
365: fixname(fname);
366: #endif
367: if (s == FALSE)
368: strcpy(curbp->b_fname, "");
369: else
370: strcpy(curbp->b_fname, fname);
371: wp = wheadp; /* Update mode lines. */
372: while (wp != NULL) {
373: if (wp->w_bufp == curbp)
374: wp->w_flag |= WFMODE;
375: wp = wp->w_wndp;
376: }
377: return (TRUE);
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.