home *** CD-ROM | disk | FTP | other *** search
- /*
- * File commands.
- */
- #include "def.h"
-
- char load_file ();
- char readin ();
- void makename ();
- bool writeout ();
- bool parse_f_name ();
-
- extern char MSG_rd_file[];
- extern char MSG_trash[];
- extern char MSG_ins_file[];
- extern char MSG_not_fnd[];
- extern char MSG_visit[];
- extern char MSG_view[];
- extern char MSG_buf_ex[];
- extern char MSG_old_buf[];
- extern char MSG_buf_nam[];
- extern char MSG_cnt_cr[];
- extern char MSG_reading[];
- extern char MSG_read_lx[];
- extern char MSG_no_mem_rd[];
- extern char MSG_wr_file[];
- extern char MSG_no_fn[];
- extern char MSG_bk_err[];
- extern char MSG_writing[];
- extern char MSG_wrot_1[];
- extern char MSG_wrot_n[];
- extern char MSG_fil_nam[];
- extern char MSG_null[];
- extern char ERR_parse_fn[];
- extern char ERR_addr_neg[];
- extern char ERR_f_size[];
-
- #include "lintfunc.dec"
-
- static int ughlyflag = FALSE;
-
- /*
- * Read a file into the current
- * buffer. This is really easy; all you do it
- * find the name of the file, and call the standard
- * "read a file into the current buffer" code.
- */
- char fileread ()
- {
- register char s;
- char fname[NFILEN];
- A32 start, end;
-
- if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE)
- return (s);
- if (parse_f_name (fname, &start, &end))
- {
- adjustcase (fname);
- return (readin (fname, start, end));
- }
- return (TRUE);
- }
-
-
- /* insert file into current buffer - use readin, and yank
- */
- char fileinsert ()
- {
- register char s;
- char bname[NBUFN],
- fname[NFILEN];
- A32 start, end;
- register char *trash = MSG_trash;
-
- strcpy (bname, curbp -> b_bname);/* save current buffer */
- if ((s = _usebuffer (trash)) == 0)/* temp buffer */
- return (s);
- if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE)
- return (s);
- /* if file name and starting and ending addresses are good */
- if (parse_f_name (fname, &start, &end))
- {
- adjustcase (fname);
- if ((s = readin (fname, start, end)) == 0)
- {
- writ_echo (MSG_not_fnd);
- _usebuffer (bname);
- _killbuffer (trash);
- return (s);
- }
- if ((s = _usebuffer (bname)) == 0)
- {
- _killbuffer (trash);
- return (s);
- }
- if ((s = _yankbuffer (trash)) == 0)
- {
- _killbuffer (trash);
- return (s);
- }
- writ_echo (okmsg);
- }
- else
- {
- _usebuffer (bname);
- _killbuffer (trash);
- return (FALSE);
- }
- if ((s = _killbuffer (trash)) == 0)
- return (s);
- wind_on_dot (curwp);
- return (s);
- }
-
-
- /*
- * Select a file for editing.
- * Look around to see if you can find the
- * fine in another buffer; if you can find it
- * just switch to the buffer. If you cannot find
- * the file, create a new buffer, read in the
- * text, and switch to the new buffer.
- *
- * also various hacked versions for auto load, and
- * file-vist with auto window split, and readonly (view-file) (jam)
- */
- char file_visit (f, n, k)
- {
- char fname[NFILEN];
- char s;
- A32 start, end;
- if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
- return (s);
- if (!parse_f_name (fname, &start, &end))
- return (FALSE);
-
- splitwind ();
- return (load_file (fname, start, end));
- }
-
-
- /* like filevisit, only read only
- */
- char viewfile ()
- {
- char fname[NFILEN];
- char s;
- A32 start, end;
-
- if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE)
- return (s);
- ughlyflag = TRUE;
- if (!parse_f_name (fname, &start, &end))
- return (FALSE);
-
- s = load_file (fname, start, end);
- if (s)
- curbp -> b_flag |= BFVIEW;
- ughlyflag = FALSE;
- return (s);
- }
-
-
- char filevisit ()
- {
- char fname[NFILEN];
- char s;
- A32 start, end;
-
- if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
- return (s);
- if (!parse_f_name (fname, &start, &end))
- return (FALSE);
-
- return (load_file (fname, start, end));
- }
-
-
- char load_file (fname, start, end) /* jam */
- char *fname;
- A32 start, end;
- {
- register BUFFER * bp;
- register WINDOW * wp;
- register LINE * lp;
- register int i;
- char s;
- char bname[NBUFN];
- extern int initial_load; /* jam */
- static int append = 0;
-
- adjustcase (fname);
- for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
- {
- if (strcmp (bp -> b_fname, fname) == 0)
- {
- if (ughlyflag == TRUE)
- {
- writ_echo (MSG_buf_ex);
- return (FALSE);
- }
- if (--curbp -> b_nwnd == 0)
- {
- curbp -> buf_type = BFILE;
- curbp -> b_dotp = curwp -> w_dotp;
- curbp -> b_doto = curwp -> w_doto;
- curbp -> b_unit_offset = curwp -> w_unit_offset;
- curbp -> b_markp = curwp -> w_markp;
- curbp -> b_marko = curwp -> w_marko;
- }
- curbp = bp;
- curwp -> w_bufp = bp;
- if (bp -> b_nwnd++ == 0)
- {
- curwp -> w_dotp = bp -> b_dotp;
- curwp -> w_doto = bp -> b_doto;
- curwp -> w_unit_offset = bp -> b_unit_offset;
- curwp -> w_markp = bp -> b_markp;
- curwp -> w_marko = bp -> b_marko;
- }
- else
- {
- wp = wheadp;
- while (wp != NULL)
- {
- if (wp != curwp && wp -> w_bufp == bp)
- {
- curwp -> w_dotp = wp -> w_dotp;
- curwp -> w_doto = wp -> w_doto;
- curwp -> w_unit_offset = wp -> w_unit_offset;
- curwp -> w_markp = wp -> w_markp;
- curwp -> w_marko = wp -> w_marko;
- break;
- }
- wp = wp -> w_wndp;
- }
- }
- lp = curwp -> w_dotp;
- i = curwp -> w_ntrows / 2;
- while (i-- && lback (lp) != curbp -> b_linep)
- lp = lback (lp);
- curwp -> w_linep = lp;
- curwp -> w_flag |= WFMODE | WFHARD;
- if (kbdmop == NULL)
- {
- writ_echo (MSG_old_buf);
- }
- return (TRUE);
- }
- }
-
- makename (bname, fname); /* New buffer name. */
- while ((bp = bfind (bname, FALSE)) != NULL)
- {
- if (initial_load) /* patch old name */
- {
- funky_name (bname, append++);
- bp = NULL;
- break;
- }
- s = ereply (MSG_buf_nam, bname, NBUFN, NULL);
- if (s == ABORT) /* ^G to just quit */
- return (s);
- if (strcmp (bp -> b_bname, bname) == 0 || s == FALSE)
- {
- /* CR to clobber it */
- makename (bname, fname);
- break;
- }
- }
- if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL)
- {
- writ_echo (MSG_cnt_cr);
- return (FALSE);
- }
- if (--curbp -> b_nwnd == 0)
- {
- /* Undisplay. */
- curbp -> buf_type = BFILE;
- curbp -> b_dotp = curwp -> w_dotp;
- curbp -> b_doto = curwp -> w_doto;
- curbp -> b_unit_offset = curwp -> w_unit_offset;
- curbp -> b_markp = curwp -> w_markp;
- curbp -> b_marko = curwp -> w_marko;
- }
- curbp = bp; /* Switch to it. */
- curwp -> w_bufp = bp;
- curbp -> b_nwnd++;
- return (readin (fname, start, end)); /* Read it in. */
- }
-
-
- /*
- * Read the file "fname" into the current buffer.
- * Make all of the text in the buffer go away, after checking
- * for unsaved changes. This is called by the "read" command, the
- * "visit" command, and the mainline (for "beav file"). If the
- * BACKUP conditional is set, then this routine also does the read
- * end of backup processing. The BFBAK flag, if set in a buffer,
- * says that a backup should be taken. It is set when a file is
- * read in, but not on a new file (you don't need to make a backup
- * copy of nothing). Return a standard status. Print a summary
- * (lines read, error message) out as well.
- */
- char readin (fname, start, end)
- char fname[];
- A32 start, end;
- {
- register LINE * lp1;
- register LINE * lp2;
- register char i;
- register WINDOW * wp;
- register BUFFER * bp;
- register char s, m;
- long byte_cnt;
- char line[NLINE];
- int num_chars, req_chars;
- char buf[80], buf1[80];
- A32 temp;
-
- m = TRUE;
- byte_cnt = 0;
- bp = curbp; /* Cheap. */
- if ((s = bclear (bp)) != TRUE)/* Might be old. */
- return (s);
- #if BACKUP
- bp -> b_flag &= ~(BFCHG | BFBAK);/* No change, backup. */
- #else
- bp -> b_flag &= ~BFCHG; /* No change. */
- #endif
- if ((start == 0L) && (end == MAXPOS))
- strcpy (bp -> b_fname, fname);
- else
- strcpy (bp -> b_fname, MSG_null);
- if ((s = ffropen (fname)) == FIOERR || s == FIOFNF)/* jam */
- goto out;
- bp -> b_file_size = file_len (); /* get the file lenth */
- sprintf (buf, MSG_reading, fname);/* jam */
- writ_echo (buf);
- temp = ffseek (start);
- if (temp != start)
- {
- sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
- sprintf (buf, buf1, temp);
- writ_echo (buf);
- return (FALSE);
- }
- /* only read the requested number of characters */
- if ((end - start) > NLINE)
- req_chars = NLINE;
- else
- req_chars = (int)(end - start);
-
- while ((s = ffgetline (line, req_chars, &num_chars)) == FIOSUC)
- {
- if ((lp1 = lalloc(num_chars)) == NULL)
- {
- bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */
- m = FALSE; /* flag memory allocation error */
- break;
- }
- /* this code breaks rules for knowing how lines * are stored and linked
- together, oh well */
- lp2 = lback (curbp -> b_linep);
- lp2 -> l_fp = lp1;
- lp1 -> l_fp = curbp -> b_linep;
- lp1 -> l_bp = lp2;
- curbp -> b_linep -> l_bp = lp1;
- for (i = 0; i < num_chars; ++i)
- lputc (lp1, i, line[i]);
- lp1 -> l_used = num_chars; /* number of bytes in this line */
- lp1 -> l_file_offset = byte_cnt; /* file offset from begining */
- byte_cnt += (long) num_chars; /* number of bytes read in */
- start += (long) num_chars;
- if (end <= start)
- break;
- /* stop reading after the requested number of characters */
- if (end < start + req_chars)
- {
- req_chars = end - start;
- }
- }
- ffclose (); /* Ignore errors. */
- if (s == FIOEOF && kbdmop == NULL)
- {
- /* Don't zap an error. */
- sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp));
- sprintf (buf, buf1, byte_cnt);
- writ_echo (buf);
- }
- if (m == FALSE && kbdmop == NULL)
- {
- /* Don't zap an error. */
- sprintf (buf1, MSG_no_mem_rd, R_POS_FMT(curwp));
- sprintf (buf, buf1, byte_cnt);
- writ_echo (buf);
- }
-
- #if BACKUP
- curbp -> b_flag |= BFBAK; /* Need a backup. */
- #endif
- out:
- for (wp = wheadp; wp != NULL; wp = wp -> w_wndp)
- {
- if (wp -> w_bufp == curbp)
- {
- wp -> w_linep = lforw (curbp -> b_linep);
- wp -> w_dotp = lforw (curbp -> b_linep);
- wp -> w_doto = 0;
- wp -> w_unit_offset = 0;
- wp -> w_markp = NULL;
- wp -> w_marko = 0;
- wp -> w_flag |= WFMODE | WFHARD;
- }
- }
- if (s == FIOERR || s == FIOFNF)/* False if error. */
- return (FALSE);
- /* so tell yank-buffer about it */
- if (blistp -> b_nwnd != 0) /* update buffer display */
- listbuffers ();
- return (TRUE);
- }
-
-
- /*
- * Take a file name, and from it
- * fabricate a buffer name. This routine knows
- * about the syntax of file names on the target system.
- * BDC1 left scan delimiter.
- * BDC2 optional second left scan delimiter.
- * BDC3 optional right scan delimiter.
- */
- void makename (bname, fname)
- char bname[];
- char fname[];
- {
- register char *cp1;
- register char *cp2;
-
- cp1 = &fname[0];
- while (*cp1 != 0)
- ++cp1;
- #ifdef BDC2
- while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2)
- --cp1;
- #else
- while (cp1 != &fname[0] && cp1[-1] != BDC1)
- --cp1;
- #endif
- cp2 = &bname[0];
- #ifdef BDC3
- while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3)
- *cp2++ = *cp1++;
- #else
- while (cp2 != &bname[NBUFN - 1] && *cp1 != 0)
- *cp2++ = *cp1++;
- #endif
- *cp2 = 0;
- }
-
-
- /*
- * Ask for a file name, and write the
- * contents of the current buffer to that file.
- * Update the remembered file name and clear the
- * buffer changed flag. This handling of file names
- * is different from the earlier versions, and
- * is more compatable with Gosling EMACS than
- * with ITS EMACS.
- */
- char filewrite ()
- {
- register WINDOW * wp;
- register char s;
- char fname[NFILEN];
- A32 start, end;
-
- if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE)
- return (s);
- if (!parse_f_name (fname, &start, &end))
- return (FALSE);
-
- adjustcase (fname);
- if ((s = writeout (fname, start, end)) == TRUE)
- {
- strcpy (curbp -> b_fname, fname);
- curbp -> b_flag &= ~BFCHG;
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp -> w_bufp == curbp)
- wp -> w_flag |= WFMODE;
- wp = wp -> w_wndp;
- }
- }
-
- #if BACKUP
- curbp -> b_flag &= ~BFBAK; /* No backup. */
- #endif
- return (s);
- }
-
-
- /*
- * Save the contents of the current buffer back into
- * its associated file. Do nothing if there have been no changes
- * (is this a bug, or a feature). Error if there is no remembered
- * file name. If this is the first write since the read or visit,
- * thet a backup copy of the file is made.
- */
- char filesave ()
- {
- register WINDOW * wp;
- register char s;
-
- if ((curbp -> b_flag & BFCHG) == 0)/* Return, no changes. */
- return (TRUE);
- if (curbp -> b_fname[0] == 0)/* Must have a name. */
- {
- if (!(curbp -> b_flag & BFSAV))/* yanked buffer */
- {
- writ_echo (MSG_no_fn);
- }
- return (FALSE);
- }
- #if BACKUP
- if ((curbp -> b_flag & BFBAK) != 0)
- {
- s = fbackupfile (curbp -> b_fname);
- if (s == ABORT) /* Hard error. */
- return (s);
- if (s == FALSE /* Softer error. */
- && (s = eyesno (MSG_bk_err)) != TRUE)
- return (s);
- }
-
- #endif
- if ((s = writeout (curbp -> b_fname, 0L, MAXPOS)) == TRUE)
- {
- curbp -> b_flag &= ~BFCHG;/* No change. */
- curbp -> b_flag &= ~BFBAD;/* if it was trashed, forget it now */
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp -> w_bufp == curbp)
- wp -> w_flag |= WFMODE;
- wp = wp -> w_wndp;
- }
- }
-
- #if BACKUP
- curbp -> b_flag &= ~BFBAK; /* No backup. */
- #endif
- return (s);
- }
-
- /*
- * This function performs the details of file
- * writing. Uses the file management routines in the
- * "fileio.c" package. The number of lines written is
- * displayed. Sadly, it looks inside a LINE; provide
- * a macro for this. Most of the grief is error
- * checking of some sort.
- */
- bool writeout (fn, start, end)
- char *fn;
- A32 start, end;
- {
- register int s, num_chars;
- register LINE * lp;
- register long nbytes;
- char buf[80], buf1[80];
- A32 temp;
-
- if ((s = ffwopen (fn)) != FIOSUC)/* Open writes message. */
- return (FALSE);
- temp = ffseek (start);
- if (temp != start)
- {
- sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
- sprintf (buf, buf1, temp);
- writ_echo (buf);
- return (FALSE);
- }
- sprintf (buf, MSG_writing, fn);/* jam */
- writ_echo (buf);
- lp = lforw (curbp -> b_linep);/* First line. */
- nbytes = 0; /* Number of bytes. */
- temp = end - start; /* number of bytes to write */
- while (lp != curbp -> b_linep)
- {
- if (nbytes + (long)llength (lp) > temp)
- num_chars = (int)(temp - nbytes);
- else
- num_chars = llength (lp);
-
- if ((s = ffputline (&lp -> l_text[0], num_chars)) != FIOSUC)
- break;
- nbytes += num_chars;
- if (temp <= nbytes)
- break;
- lp = lforw (lp);
- }
- if (s == FIOSUC)
- {
- /* No write error. */
- s = ffclose ();
- if (s == FIOSUC && kbdmop == NULL)
- {
- if (nbytes == 1)
- {
- writ_echo (MSG_wrot_1);
- }
- else
- {
- sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
- sprintf (buf, buf1, (long) nbytes);
- writ_echo (buf);
- }
- }
- }
- else /* Ignore close error */
- ffclose (); /* if a write error. */
- if (s != FIOSUC) /* Some sort of error. */
- return (FALSE);
- curbp -> b_file_size = nbytes; /* update file size */
- if (blistp -> b_nwnd != 0) /* update buffer display */
- listbuffers ();
- return (TRUE);
- }
-
- /*
- * The command allows the user
- * to modify the file name associated with
- * the current buffer. It is like the "f" command
- * in UNIX "ed". The operation is simple; just zap
- * the name in the BUFFER structure, and mark the windows
- * as needing an update. You can type a blank line at the
- * prompt if you wish.
- */
- char filename ()
- {
- register WINDOW * wp;
- register char s;
- char fname[NFILEN];
- A32 start, end;
-
- if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT)
- return (s);
- if (!parse_f_name (fname, &start, &end))
- return (FALSE);
-
- adjustcase (fname);
- curbp -> b_flag |= BFCHG; /* jam - on name change, set modify */
- BUF_START(curwp) = start;
- l_fix_up (NULL); /* adjust file offsets from first line */
- strcpy (curbp -> b_fname, fname);/* Fix name. */
- wp = wheadp; /* Update mode lines. */
- while (wp != NULL)
- {
- if (wp -> w_bufp == curbp)
- wp -> w_flag |= WFMODE;
- wp = wp -> w_wndp;
- }
- #if BACKUP
- curbp -> b_flag &= ~BFBAK; /* No backup. */
- #endif
- return (TRUE);
- }
-
- /*
- * Get the length parameters that were entered with the file name.
- * There can be the file name only.
- * There can be a file name and a starting position.
- * There can be a name a starting position and an ending position.
- * There can be a name a starting position and a length.
- *
- * input:
- * fn pointer to file name string to parse.
- *
- * output:
- * fn pointer to null terminated file name.
- * start pointer to the starting point in file (default = 0)
- * end pointer to the end point in file (default = -1)
- * return FALSE if file name or addresses are bad.
- */
- bool parse_f_name (fn, start, end)
- char *fn;
- A32 *start, *end;
- {
- char buf[NFILEN], buf1[80], fmt[10];
- int i_cnt;
- A32 temp;
-
- /* build up format string according to the current screen format */
- sprintf (fmt, "%s %s %s", "%s", R_POS_FMT(curwp), R_POS_FMT(curwp));
-
- *start = 0L;
- *end = MAXPOS;
- sscanf (fn, fmt, buf, start, end);
-
- if (*end != MAXPOS)
- {
- for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--)
- {
- if (fn[i_cnt] == '+')
- {
- *end += *start;
- break;
- }
- }
- }
- /* start should preceed end */
- if (*start > *end)
- {
- sprintf (buf1, ERR_parse_fn, R_POS_FMT(curwp), R_POS_FMT(curwp));
- sprintf (buf, buf1, *start, *end);
- writ_echo (buf);
- return (FALSE);
- }
-
- /* error if addresses are negative */
- if ((*start < 0) || (*end < 0))
- {
- writ_echo (ERR_addr_neg);
- return (FALSE);
- }
-
- /* deposit null terminated file name */
- strcpy (fn, buf);
- return (TRUE);
- }
-