* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)ex_read.c 8.21 (Berkeley) 1/23/94";
* ex_read -- :read [file]
* Read from a file or utility.
* If "read !", it's a pipe from a utility.
* Historical vi wouldn't undo a filter read, for no apparent
if (F_ISSET(cmdp
, E_FORCE
)) {
/* Expand the user's argument. */
cmdp
, cmdp
->argv
[0]->bp
, cmdp
->argv
[0]->len
, 0))
/* If argc still 1, there wasn't anything to expand. */
msgq(sp
, M_ERR
, "Usage: %s.", cmdp
->cmd
->usage
);
/* Redisplay the user's argument if it's changed. */
if (F_ISSET(cmdp
, E_MODIFY
) && IN_VI_MODE(sp
)) {
len
= cmdp
->argv
[1]->len
;
GET_SPACE_RET(sp
, bp
, blen
, len
+ 2);
memmove(bp
+ 1, cmdp
->argv
[1], cmdp
->argv
[1]->len
+ 1);
(void)sp
->s_busy(sp
, bp
);
FREE_SPACE(sp
, bp
, blen
);
&cmdp
->addr1
, NULL
, &rm
, cmdp
->argv
[1]->bp
, FILTER_READ
))
/* Expand the user's argument. */
cmdp
, cmdp
->argv
[0]->bp
, cmdp
->argv
[0]->len
, 0))
* No arguments, read the current file.
* Doesn't set the alternate file name.
name
= FILENAME(sp
->frp
);
* Sets the alternate file name.
name
= cmdp
->argv
[1]->bp
;
/* If expanded to more than one argument, object. */
"%s expanded into too many file names", cmdp
->argv
[0]->bp
);
msgq(sp
, M_ERR
, "Usage: %s.", cmdp
->cmd
->usage
);
* Historically, vi did not permit reads from non-regular files,
* nor did it distinguish between "read !" and "read!", so there
* was no way to "force" it.
if ((fp
= fopen(name
, "r")) == NULL
|| fstat(fileno(fp
), &sb
)) {
msgq(sp
, M_SYSERR
, name
);
if (!S_ISREG(sb
.st_mode
)) {
msgq(sp
, M_ERR
, "Only regular files may be read.");
rval
= ex_readfp(sp
, ep
, name
, fp
, &cmdp
->addr1
, &nlines
, 1);
* Set the cursor to the first line read in, if anything read
* in, otherwise, the address. (Historic vi set it to the
* line after the address regardless, but since that line may
* not exist we don't bother.)
sp
->lno
= cmdp
->addr1
.lno
;
F_SET(EXP(sp
), EX_AUTOPRINT
);
* Read lines into the file.
ex_readfp(sp
, ep
, name
, fp
, fm
, nlinesp
, success_msg
)
* Add in the lines from the output. Insertion starts at the line
for (lno
= fm
->lno
; !ex_getline(sp
, fp
, &len
); ++lno
) {
if (file_aline(sp
, ep
, 1, lno
, exp
->ibp
, len
)) {
msgq(sp
, M_SYSERR
, name
);
msgq(sp
, M_SYSERR
, name
);
/* Return the number of lines read in. */
msgq(sp
, M_INFO
, "%s: %lu line%s, %lu characters.",
name
, nlines
, nlines
== 1 ? "" : "s", ccnt
);