Blame | Last modification | View Log | RSS feed
/*
* This code contains changes by
* Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
*
* Conditions 1, 2, and 4 and the no-warranty notice below apply
* to these changes.
*
*
* Copyright (c) 1980, 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
* are met:
* 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
* SUCH DAMAGE.
*
*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* Redistributions of source code and documentation must retain the
* above copyright notice, this list of conditions and the following
* disclaimer.
* 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.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed or owned by Caldera
* International, Inc.
* Neither the name of Caldera International, Inc. nor the names of
* other contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
* INTERNATIONAL, INC. 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 CALDERA INTERNATIONAL, INC. 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 SUCH DAMAGE.
*/
#ifndef lint
#ifdef DOSCCS
static char sccsid[] = "@(#)ex_get.c 1.17 (gritter) 2/17/05";
#endif
#endif
/* from ex_get.c 7.6 (Berkeley) 6/7/85 */
#include "ex.h"
#include "ex_tty.h"
/*
* Input routines for command mode.
* Since we translate the end of reads into the implied ^D's
* we have different flavors of routines which do/don't return such.
*/
static bool junkbs;
int lastc = '\n';
void
ignchar(void)
{
ignore(getchar());
}
int
getach(void)
{
register int c;
static char in_line[BUFSIZ];
/* struct stat statb; */
c = peekc;
if (c != 0) {
peekc = 0;
return (c);
}
if (globp) {
if (*globp)
return (*globp++&0377);
globp = 0;
return (lastc = EOF);
}
top:
if (input) {
if (c = *input++&0377) {
if (verbose && !intty)
write(2, &input[-1], 1);
if (c &= TRIM)
return (lastc = c);
goto top;
}
input = 0;
}
flush();
if (intty) {
c = read(0, in_line, sizeof in_line - 4);
if (c < 0)
return (lastc = EOF);
if (c == 0 || in_line[c-1] != '\n')
in_line[c++] = CTRL('d');
if (in_line[c-1] == '\n')
noteinp();
in_line[c] = 0;
for (c--; c >= 0; c--)
if (in_line[c] == 0)
#ifndef BIT8
in_line[c] = QUOTE;
#else
in_line[c] = '\200';
#endif
input = in_line;
goto top;
}
c = read(0, in_line, sizeof in_line - 1);
if(c <= 0)
return(lastc = EOF);
in_line[c] = '\0';
input = in_line;
goto top;
}
int
getchar(void)
{
register int c;
do
c = getcd();
while (!globp && c == CTRL('d'));
return (c);
}
void
checkjunk(int c)
{
if (junkbs == 0 && c == '\b') {
write(2, cntrlhm, 13);
junkbs = 1;
}
}
int
getcd(void)
{
register int c;
again:
c = getach();
if (c == EOF)
return (c);
c &= TRIM;
if (!inopen)
if (!globp && c == CTRL('d'))
setlastchar('\n');
else if (junk(c)) {
checkjunk(c);
goto again;
}
return (c);
}
int
peekchar(void)
{
if (peekc == 0)
peekc = getchar();
return (peekc);
}
int
peekcd(void)
{
if (peekc == 0)
peekc = getcd();
return (peekc);
}
/*
* Crunch the indent.
* Hard thing here is that in command mode some of the indent
* is only implicit, so we must seed the column counter.
* This should really be done differently so as to use the whitecnt routine
* and also to hack indenting for LISP.
*/
int
smunch(register int col, char *ocp)
{
register char *cp;
cp = ocp;
for (;;)
switch (*cp++) {
case ' ':
col++;
continue;
case '\t':
col += value(TABSTOP) - (col % value(TABSTOP));
continue;
default:
cp--;
CP(ocp, cp);
return (col);
}
}
/*
* Input routine for insert/append/change in command mode.
* Most work here is in handling autoindent.
*/
static short lastin;
int
gettty(void)
{
register int c = 0;
register char *cp = genbuf;
char hadup = 0;
int offset = Pline == numbline ? 8 : 0;
int ch;
if (intty && !inglobal) {
if (offset) {
holdcm = 1;
printf(" %4d ", lineDOT() + 1);
flush();
holdcm = 0;
}
if (value(AUTOINDENT) ^ aiflag) {
holdcm = 1;
#ifdef LISPCODE
if (value(LISP))
lastin = lindent(dot + 1);
#endif
tab(lastin + offset);
while ((c = getcd()) == CTRL('d')) {
if (lastin == 0 && isatty(0) == -1) {
holdcm = 0;
return (EOF);
}
lastin = backtab(lastin);
tab(lastin + offset);
}
switch (c) {
case '^':
case '0':
ch = getcd();
if (ch == CTRL('d')) {
if (c == '0')
lastin = 0;
if (!OS) {
putchar('\b' | QUOTE);
putchar(' ' | QUOTE);
putchar('\b' | QUOTE);
}
tab(offset);
hadup = 1;
c = getchar();
} else
ungetchar(ch);
break;
case '.':
if (peekchar() == '\n') {
ignchar();
noteinp();
holdcm = 0;
return (EOF);
}
break;
case '\n':
hadup = 1;
break;
}
}
flush();
holdcm = 0;
}
if (c == 0)
c = getchar();
while (c != EOF && c != '\n') {
if (cp > &genbuf[LBSIZE - 2])
error(catgets(catd, 1, 71, "Input line too long"));
*cp++ = c;
c = getchar();
}
if (c == EOF) {
if (inglobal)
ungetchar(EOF);
return (EOF);
}
*cp = 0;
cp = linebuf;
if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
lastin = c = smunch(lastin, genbuf);
for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP))
*cp++ = '\t';
for (; c > 0; c--)
*cp++ = ' ';
}
CP(cp, genbuf);
if (linebuf[0] == '.' && linebuf[1] == 0)
return (EOF);
return (0);
}
void
setin(line *addr)
{
if (addr == zero)
lastin = 0;
else
getline(*addr), lastin = smunch(0, linebuf);
}