Added new interface to termcap that allows the manipulation of multiple
termcap entries simultaneously and lifts the 1024 byte limit on the termcap entry. The original termcap api is unchanged but also no longer has the 1024 byte limit if the termcap functions are used.
This commit is contained in:
parent
59873a18ee
commit
1bb0398527
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.20 1999/02/12 11:34:07 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.21 1999/08/15 10:59:01 blymn Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
|
||||
LIB= termcap
|
||||
@ -7,7 +7,10 @@ SRCS= termcap.c tgoto.c tputs.c
|
||||
|
||||
MAN= termcap.3
|
||||
MLINKS= termcap.3 tgetent.3 termcap.3 tgetflag.3 termcap.3 tgetnum.3 \
|
||||
termcap.3 tgetstr.3 termcap.3 tgoto.3 termcap.3 tputs.3
|
||||
termcap.3 tgetstr.3 termcap.3 tgoto.3 termcap.3 tputs.3 \
|
||||
termcap.3 t_getent.3 termcap.3 t_getflag.3 termcap.3 t_getnum.3 \
|
||||
termcap.3 t_getstr.3 termcap.3 t_goto.3 termcap.3 t_puts.3 \
|
||||
termcap.3 t_freent.3
|
||||
INCS= termcap.h
|
||||
INCSDIR=/usr/include
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: termcap.3,v 1.12 1999/07/02 15:46:05 simonb Exp $
|
||||
.\" $NetBSD: termcap.3,v 1.13 1999/08/15 10:59:01 blymn Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -52,6 +52,7 @@
|
||||
.Vt char *BC;
|
||||
.Vt char *UP;
|
||||
.Vt short ospeed;
|
||||
.Vt struct tinfo *info;
|
||||
.Ft int
|
||||
.Fn tgetent "char *bp" "char *name"
|
||||
.Ft int
|
||||
@ -64,6 +65,20 @@
|
||||
.Fn tgoto "char *cm" "int destcol" "int destline"
|
||||
.Ft void
|
||||
.Fn tputs "char *cp" "int affcnt" "void (*outc)(int)"
|
||||
.Ft int
|
||||
.Fn t_getent "struct tinfo **info" "char *name"
|
||||
.Ft int
|
||||
.Fn t_getnum "struct tinfo *info" "char *id"
|
||||
.Ft int
|
||||
.Fn t_getflag "struct tinfo *info" "char *id"
|
||||
.Ft char *
|
||||
.Fn t_getstr "struct tinfo *info" "char *id" "char **area" "int *limit"
|
||||
.Ft int
|
||||
.Fn t_goto "struct tinfo *info" "char *id" "int destcol" "int destline" "char *buffer" "int limit"
|
||||
.Ft int
|
||||
.Fn t_puts "struct tinfo *info" "char *cp" "int affcnt" "void (*outc)(char, void *)" "void *args"
|
||||
.Ft void
|
||||
.Fn t_freent "char *info"
|
||||
.Sh DESCRIPTION
|
||||
These functions extract and use capabilities from a terminal capability data
|
||||
base, usually
|
||||
@ -241,6 +256,133 @@ capability)
|
||||
if a null
|
||||
.Pq Sy ^@
|
||||
is inappropriate.
|
||||
.Pp
|
||||
The
|
||||
.Fn t_getent
|
||||
function operates in a similar manner to the
|
||||
.Fn tgetent
|
||||
function excepting that the
|
||||
.Fa info
|
||||
argument is a pointer to a pointer of the opaque type
|
||||
.Va tinfo .
|
||||
If the call to
|
||||
.Fn t_getent
|
||||
succeeds then the argument
|
||||
.Fa info
|
||||
will be updated with the address of an object that contains the termcap
|
||||
entry. This pointer can then be passed to calls of
|
||||
.Fn t_getnum ,
|
||||
.Fn t_getflag
|
||||
and
|
||||
.Fn t_getstr .
|
||||
When the information pointed to by
|
||||
.Fa info
|
||||
is no longer required any storage associated with the object can be
|
||||
released by calling
|
||||
.Fn t_freent .
|
||||
The functions
|
||||
.Fn t_getnum
|
||||
and
|
||||
.Fn t_getflag
|
||||
operate in the same manner as
|
||||
.Fn tgetnum
|
||||
and
|
||||
.Fn tgetflag
|
||||
with the exception that the pointer to the termcap object is passed along
|
||||
with the id of the capability required. The function
|
||||
.Fn t_getstr
|
||||
performs the same function as
|
||||
.Fn tgetstr
|
||||
but has a
|
||||
.Fa limit
|
||||
parameter that gives the number of characters that can be inserted in to
|
||||
the array pointed to by
|
||||
.Fa area .
|
||||
The
|
||||
.Fa limit
|
||||
argument is updated by the
|
||||
.Fn t_getstr
|
||||
call to give the number of characters that remain available in
|
||||
.Fa area .
|
||||
If the t_getstr call fails then
|
||||
.Sy NULL
|
||||
will be returned and errno set to indicate the failure, ENOENT indicates
|
||||
there was no termcap entry for the given
|
||||
.Fa id ,
|
||||
E2BIG indicates the retrieved entry would have overflowed
|
||||
.Fa area .
|
||||
.Pp
|
||||
The
|
||||
.Fn t_goto
|
||||
function is the same as the
|
||||
.Fn tgoto
|
||||
function excepting that the capabilities for
|
||||
.Sy up
|
||||
and
|
||||
.Sy bc
|
||||
are extracted from the
|
||||
.Fa info
|
||||
object and that the string formed by
|
||||
.Fn t_goto
|
||||
is placed in the
|
||||
.Fa buffer
|
||||
argument, the number of characters allowed to be placed in
|
||||
.Fa buffer
|
||||
is controlled by
|
||||
.Fa limit .
|
||||
If the expansion performed by
|
||||
.Fn t_goto
|
||||
would exceed the space in
|
||||
.Fa buffer
|
||||
then
|
||||
.Fn t_goto
|
||||
will return -1 and set errno to
|
||||
.Sy E2BIG .
|
||||
The function
|
||||
.Fn t_puts
|
||||
is similar to the
|
||||
.Fn tputs
|
||||
function excepting that
|
||||
.Fa info
|
||||
holds a pointer to the termcap object that was returned by a previous
|
||||
.Fn t_getent
|
||||
call, this object will be used to retrieve the
|
||||
.Sy pc
|
||||
attribute for the terminal. The
|
||||
.Fa outc
|
||||
function is a pointer to a function that will be called by
|
||||
.Fn t_puts
|
||||
to output each character in the
|
||||
.Fa cp
|
||||
string. The
|
||||
.Fa outc
|
||||
function will be called with two parameters. The first is the character
|
||||
to be printed and the second is an optional argument that was passed to
|
||||
.Fn t_puts
|
||||
in the
|
||||
.Fa args
|
||||
argument. The interpretation of the contents of
|
||||
.Fa args
|
||||
is dependent soley on the implementation of
|
||||
.Fa outc.
|
||||
.Pp
|
||||
NOTE: If the termcap entry would exceed the 1024 buffer passed to
|
||||
.Fa tgetent
|
||||
then a special capability of
|
||||
.Fa ZZ
|
||||
is added to the end of the termcap. The number that follows this entry
|
||||
is the address of the buffer allocated to hold the full termcap entry. The
|
||||
caller may retrieve the pointer to the extended buffer by performing a
|
||||
.Fn tgetstr
|
||||
to retrieve the
|
||||
.Fa ZZ
|
||||
capability, the string is the output of a
|
||||
.Fn printf
|
||||
%p and may be converted back to a pointer using
|
||||
.Fn sscanf
|
||||
or similar. The ZZ capability is only necessary if the caller wishes to
|
||||
directly manipulate the termcap entry, all the termcap function calls
|
||||
automatically use the extended buffer to retrieve terminal capabilities.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/share/misc/termcap -compact
|
||||
.It Pa /usr/lib/libtermcap.a
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: termcap.c,v 1.17 1999/07/02 15:46:05 simonb Exp $ */
|
||||
/* $NetBSD: termcap.c,v 1.18 1999/08/15 10:59:01 blymn Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: termcap.c,v 1.17 1999/07/02 15:46:05 simonb Exp $");
|
||||
__RCSID("$NetBSD: termcap.c,v 1.18 1999/08/15 10:59:01 blymn Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -50,8 +50,17 @@ __RCSID("$NetBSD: termcap.c,v 1.17 1999/07/02 15:46:05 simonb Exp $");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termcap.h>
|
||||
#include <errno.h>
|
||||
#include "pathnames.h"
|
||||
|
||||
/* internal definition of tinfo structure - just a pointer to the malloc'ed
|
||||
* buffer for now.
|
||||
*/
|
||||
struct tinfo
|
||||
{
|
||||
char *info;
|
||||
};
|
||||
|
||||
/*
|
||||
* termcap - routines for dealing with the terminal capability data base
|
||||
*
|
||||
@ -67,18 +76,21 @@ __RCSID("$NetBSD: termcap.c,v 1.17 1999/07/02 15:46:05 simonb Exp $");
|
||||
*/
|
||||
|
||||
static char *tbuf; /* termcap buffer */
|
||||
static struct tinfo *fbuf; /* untruncated termcap buffer */
|
||||
|
||||
/*
|
||||
* Get an entry for terminal name in buffer bp from the termcap file.
|
||||
* Get an extended entry for the terminal name. This differs from
|
||||
* tgetent only in a) the buffer is malloc'ed for the caller and
|
||||
* b) the termcap entry is not truncated to 1023 characters.
|
||||
*/
|
||||
|
||||
int
|
||||
tgetent(bp, name)
|
||||
char *bp;
|
||||
t_getent(bp, name)
|
||||
struct tinfo **bp;
|
||||
const char *name;
|
||||
{
|
||||
char *p;
|
||||
char *cp;
|
||||
char *dummy;
|
||||
char **fname;
|
||||
char *home;
|
||||
int i;
|
||||
@ -86,8 +98,9 @@ tgetent(bp, name)
|
||||
char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
|
||||
char *termpath;
|
||||
|
||||
if ((*bp = malloc(sizeof(struct tinfo))) == NULL) return 0;
|
||||
|
||||
fname = pathvec;
|
||||
tbuf = bp;
|
||||
p = pathbuf;
|
||||
cp = getenv("TERMCAP");
|
||||
/*
|
||||
@ -143,31 +156,58 @@ tgetent(bp, name)
|
||||
* user had setup name to be built from a path they can not
|
||||
* normally read.
|
||||
*/
|
||||
dummy = NULL;
|
||||
i = cgetent(&dummy, pathvec, name);
|
||||
(*bp)->info = NULL;
|
||||
i = cgetent(&((*bp)->info), pathvec, name);
|
||||
|
||||
if (i == 0) {
|
||||
/*
|
||||
* If the entry is too long, truncate to the last whole cap.
|
||||
*/
|
||||
strncpy(bp, dummy, 1024);
|
||||
if (strlen(dummy) > 1023 && bp[1023] != ':' ) {
|
||||
for (cp = bp+1022 ; cp > bp && *cp != ':' ; --cp)
|
||||
;
|
||||
if (cp > bp)
|
||||
cp[1] = 0;
|
||||
}
|
||||
bp[1023] = '\0';
|
||||
}
|
||||
|
||||
if (dummy)
|
||||
free(dummy);
|
||||
/* no tc reference loop return code in libterm XXX */
|
||||
if (i == -3)
|
||||
return (-1);
|
||||
return (i + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an entry for terminal name in buffer bp from the termcap file.
|
||||
*/
|
||||
int
|
||||
tgetent(bp, name)
|
||||
char *bp;
|
||||
const char *name;
|
||||
{
|
||||
int i, plen, elen, c;
|
||||
char *ptrbuf = NULL;
|
||||
|
||||
i = t_getent(&fbuf, name);
|
||||
|
||||
if (i == 1) {
|
||||
/* stash the full buffer pointer as the ZZ capability
|
||||
in the termcap buffer passed.
|
||||
*/
|
||||
plen = asprintf(&ptrbuf, ":ZZ=%p", fbuf->info);
|
||||
strncpy(bp, fbuf->info, 1024);
|
||||
bp[1023] = '\0';
|
||||
elen = strlen(bp);
|
||||
/* backup over the entry if the addition of the full
|
||||
buffer pointer will overflow the buffer passed. We
|
||||
want to truncate the termcap entry on a capability
|
||||
boundary.
|
||||
*/
|
||||
if ((elen + plen) > 1023) {
|
||||
bp[1023 - plen] = '\0';
|
||||
for (c = (elen - plen); c > 0; c--) {
|
||||
if (bp[c] == ':') {
|
||||
bp[c] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcat(bp, ptrbuf);
|
||||
tbuf = bp;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the (numeric) option id.
|
||||
* Numeric options look like
|
||||
@ -177,28 +217,44 @@ tgetent(bp, name)
|
||||
* Note that we handle octal numbers beginning with 0.
|
||||
*/
|
||||
int
|
||||
tgetnum(id)
|
||||
|
||||
t_getnum(info, id)
|
||||
struct tinfo *info;
|
||||
const char *id;
|
||||
{
|
||||
long num;
|
||||
|
||||
if (cgetnum(tbuf, id, &num) == 0)
|
||||
if (cgetnum(info->info, id, &num) == 0)
|
||||
return (int)(num);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
tgetnum(id)
|
||||
const char *id;
|
||||
{
|
||||
return t_getnum(fbuf, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a flag option.
|
||||
* Flag options are given "naked", i.e. followed by a : or the end
|
||||
* of the buffer. Return 1 if we find the option, or 0 if it is
|
||||
* not given.
|
||||
*/
|
||||
int t_getflag(info, id)
|
||||
struct tinfo *info;
|
||||
const char *id;
|
||||
{
|
||||
return (cgetcap(info->info, id, ':') != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
tgetflag(id)
|
||||
const char *id;
|
||||
{
|
||||
return (cgetcap(tbuf, id, ':') != NULL);
|
||||
return t_getflag(fbuf, id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -207,12 +263,15 @@ tgetflag(id)
|
||||
* cl=^Z
|
||||
* Much decoding is done on the strings, and the strings are
|
||||
* placed in area, which is a ref parameter which is updated.
|
||||
* No checking on area overflow.
|
||||
* limit is the number of characters allowed to be put into
|
||||
* area, this is updated.
|
||||
*/
|
||||
char *
|
||||
tgetstr(id, area)
|
||||
t_getstr(info, id, area, limit)
|
||||
struct tinfo *info;
|
||||
const char *id;
|
||||
char **area;
|
||||
int *limit;
|
||||
{
|
||||
char ids[3];
|
||||
char *s;
|
||||
@ -227,10 +286,55 @@ tgetstr(id, area)
|
||||
ids[1] = id[1];
|
||||
ids[2] = '\0';
|
||||
|
||||
if ((i = cgetstr(tbuf, ids, &s)) < 0)
|
||||
if ((i = cgetstr(info->info, ids, &s)) < 0) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/* check if there is room for the new entry to be put into area */
|
||||
if (limit != NULL && (*limit < i)) {
|
||||
errno = E2BIG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(*area, s);
|
||||
*area += i + 1;
|
||||
return (s);
|
||||
if (limit != NULL) *limit -= i;
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a string valued option.
|
||||
* These are given as
|
||||
* cl=^Z
|
||||
* Much decoding is done on the strings, and the strings are
|
||||
* placed in area, which is a ref parameter which is updated.
|
||||
* No checking on area overflow.
|
||||
*/
|
||||
char *
|
||||
tgetstr(id, area)
|
||||
const char *id;
|
||||
char **area;
|
||||
{
|
||||
struct tinfo dummy;
|
||||
|
||||
if ((id[0] == 'Z') && (id[1] == 'Z')) {
|
||||
dummy.info = tbuf;
|
||||
return t_getstr(&dummy, id, area, NULL);
|
||||
}
|
||||
else
|
||||
return t_getstr(fbuf, id, area, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the buffer allocated by t_getent
|
||||
*
|
||||
*/
|
||||
void
|
||||
t_freent(info)
|
||||
struct tinfo *info;
|
||||
{
|
||||
free(info->info);
|
||||
free(info);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: termcap.h,v 1.5 1999/08/14 13:56:48 tron Exp $ */
|
||||
/* $NetBSD: termcap.h,v 1.6 1999/08/15 10:59:01 blymn Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -41,6 +41,8 @@
|
||||
#ifndef _TERMCAP_H_
|
||||
#define _TERMCAP_H_
|
||||
|
||||
struct tinfo;
|
||||
|
||||
__BEGIN_DECLS
|
||||
int tgetent __P((char *, const char *));
|
||||
char *tgetstr __P((const char *, char **));
|
||||
@ -49,6 +51,18 @@ int tgetnum __P((const char *));
|
||||
char *tgoto __P((const char *, int, int));
|
||||
void tputs __P((const char *, int, void (*)(int)));
|
||||
|
||||
/*
|
||||
* New interface
|
||||
*/
|
||||
int t_getent __P((struct tinfo **, const char *));
|
||||
int t_getnum __P((struct tinfo *, const char *));
|
||||
int t_getflag __P((struct tinfo *, const char *));
|
||||
char *t_getstr __P((struct tinfo *, const char *, char **, int *));
|
||||
int t_goto __P((struct tinfo *, const char *, int, int, char *, int));
|
||||
int t_puts __P((struct tinfo *, const char *, int,
|
||||
void (*)(char, void *), void *));
|
||||
void t_freent __P((struct tinfo *));
|
||||
|
||||
extern char PC;
|
||||
extern char *BC;
|
||||
extern char *UP;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tgoto.c,v 1.12 1999/07/02 15:46:05 simonb Exp $ */
|
||||
/* $NetBSD: tgoto.c,v 1.13 1999/08/15 10:59:02 blymn Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
@ -38,10 +38,11 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)tgoto.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tgoto.c,v 1.12 1999/07/02 15:46:05 simonb Exp $");
|
||||
__RCSID("$NetBSD: tgoto.c,v 1.13 1999/08/15 10:59:02 blymn Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <termcap.h>
|
||||
|
||||
@ -82,27 +83,63 @@ tgoto(CM, destcol, destline)
|
||||
int destcol, destline;
|
||||
{
|
||||
static char result[MAXRETURNSIZE];
|
||||
|
||||
if (t_goto(NULL, CM, destcol, destline, result, MAXRETURNSIZE) >= 0)
|
||||
return result;
|
||||
else
|
||||
return ("OOPS");
|
||||
}
|
||||
|
||||
/*
|
||||
* New interface. Functionally the same as tgoto but uses the tinfo struct
|
||||
* to set UP and BC. The arg buffer is filled with the result string, limit
|
||||
* defines the maximum number of chars allowed in buffer. The function
|
||||
* returns 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
t_goto(info, CM, destcol, destline, buffer, limit)
|
||||
struct tinfo *info;
|
||||
const char *CM;
|
||||
int destcol;
|
||||
int destline;
|
||||
char *buffer;
|
||||
int limit;
|
||||
{
|
||||
static char added[10];
|
||||
const char *cp = CM;
|
||||
char *dp = result;
|
||||
int c;
|
||||
char *dp = buffer;
|
||||
char *old_up = UP, *old_bc = BC;
|
||||
char new_up[MAXRETURNSIZE], new_bc[MAXRETURNSIZE], *up_ptr, *bc_ptr;
|
||||
int c, count = MAXRETURNSIZE;
|
||||
int oncol = 0;
|
||||
int which = destline;
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
up_ptr = new_up;
|
||||
bc_ptr = new_bc;
|
||||
UP = t_getstr(info, "up", &up_ptr, &count);
|
||||
count = MAXRETURNSIZE;
|
||||
BC = t_getstr(info, "bc", &bc_ptr, &count);
|
||||
}
|
||||
|
||||
if (cp == 0) {
|
||||
errno = EINVAL;
|
||||
toohard:
|
||||
/*
|
||||
* ``We don't do that under BOZO's big top''
|
||||
*/
|
||||
return ("OOPS");
|
||||
UP = old_up;
|
||||
BC = old_bc;
|
||||
return -1;
|
||||
}
|
||||
added[0] = '\0';
|
||||
while ((c = *cp++) != '\0') {
|
||||
if (c != '%') {
|
||||
copy:
|
||||
*dp++ = c;
|
||||
if (dp >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
if (dp >= &buffer[limit])
|
||||
{
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
switch (c = *cp++) {
|
||||
@ -122,23 +159,32 @@ copy:
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '3':
|
||||
if (which >= 1000)
|
||||
goto toohard;
|
||||
*dp++ = (which / 100) | '0';
|
||||
if (dp >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
if (which >= 1000) {
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
*dp++ = (which / 100) | '0';
|
||||
if (dp >= &buffer[limit]) {
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
which %= 100;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '2':
|
||||
two:
|
||||
*dp++ = which / 10 | '0';
|
||||
if (dp >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
if (dp >= &buffer[limit]) {
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
one:
|
||||
*dp++ = which % 10 | '0';
|
||||
if (dp >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
if (dp >= &buffer[limit]) {
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
|
||||
swap:
|
||||
oncol = 1 - oncol;
|
||||
setwhich:
|
||||
@ -188,15 +234,22 @@ setwhich:
|
||||
*/
|
||||
do {
|
||||
if (strlen(added) + strlen(add) >= sizeof(added))
|
||||
goto toohard;
|
||||
(void)strcat(added, add);
|
||||
{
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
|
||||
(void)strcat(added, add);
|
||||
which++;
|
||||
} while (which == '\n');
|
||||
}
|
||||
}
|
||||
*dp++ = which;
|
||||
if (dp >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
if (dp >= &buffer[limit])
|
||||
{
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
goto swap;
|
||||
|
||||
case 'r':
|
||||
@ -225,11 +278,18 @@ setwhich:
|
||||
#endif
|
||||
|
||||
default:
|
||||
goto toohard;
|
||||
errno = EINVAL;
|
||||
goto toohard;
|
||||
}
|
||||
}
|
||||
if (dp + strlen(added) >= &result[MAXRETURNSIZE])
|
||||
goto toohard;
|
||||
(void)strcpy(dp, added);
|
||||
return (result);
|
||||
if (dp + strlen(added) >= &buffer[limit])
|
||||
{
|
||||
errno = E2BIG;
|
||||
goto toohard;
|
||||
}
|
||||
|
||||
(void)strcpy(dp, added);
|
||||
UP = old_up;
|
||||
BC = old_bc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tputs.c,v 1.9 1999/02/02 12:34:56 christos Exp $ */
|
||||
/* $NetBSD: tputs.c,v 1.10 1999/08/15 10:59:02 blymn Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
@ -38,14 +38,18 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)tputs.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tputs.c,v 1.9 1999/02/02 12:34:56 christos Exp $");
|
||||
__RCSID("$NetBSD: tputs.c,v 1.10 1999/08/15 10:59:02 blymn Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <termcap.h>
|
||||
#include <stdio.h>
|
||||
#undef ospeed
|
||||
|
||||
/* internal functions */
|
||||
int _tputs_convert __P((const char **, int));
|
||||
|
||||
/*
|
||||
* The following array gives the number of tens of milliseconds per
|
||||
* character for each speed as returned by gtty. Thus since 300
|
||||
@ -59,6 +63,43 @@ short tmspc10[] = {
|
||||
short ospeed;
|
||||
char PC;
|
||||
|
||||
int
|
||||
_tputs_convert(ptr, affcnt)
|
||||
const char **ptr;
|
||||
int affcnt;
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/*
|
||||
* Convert the number representing the delay.
|
||||
*/
|
||||
if (isdigit(*(*ptr))) {
|
||||
do
|
||||
i = i * 10 + *(*ptr)++ - '0';
|
||||
while (isdigit(*(*ptr)));
|
||||
}
|
||||
i *= 10;
|
||||
if (*(*ptr) == '.') {
|
||||
(*ptr)++;
|
||||
if (isdigit(*(*ptr)))
|
||||
i += *(*ptr) - '0';
|
||||
/*
|
||||
* Only one digit to the right of the decimal point.
|
||||
*/
|
||||
while (isdigit(*(*ptr)))
|
||||
(*ptr)++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the delay is followed by a `*', then
|
||||
* multiply by the affected lines count.
|
||||
*/
|
||||
if (*(*ptr) == '*')
|
||||
(*ptr)++, i *= affcnt;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the character string cp out, with padding.
|
||||
* The number of affected lines is affcnt, and the routine
|
||||
@ -76,33 +117,9 @@ tputs(cp, affcnt, outc)
|
||||
if (cp == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Convert the number representing the delay.
|
||||
*/
|
||||
if (isdigit(*cp)) {
|
||||
do
|
||||
i = i * 10 + *cp++ - '0';
|
||||
while (isdigit(*cp));
|
||||
}
|
||||
i *= 10;
|
||||
if (*cp == '.') {
|
||||
cp++;
|
||||
if (isdigit(*cp))
|
||||
i += *cp - '0';
|
||||
/*
|
||||
* Only one digit to the right of the decimal point.
|
||||
*/
|
||||
while (isdigit(*cp))
|
||||
cp++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the delay is followed by a `*', then
|
||||
* multiply by the affected lines count.
|
||||
*/
|
||||
if (*cp == '*')
|
||||
cp++, i *= affcnt;
|
||||
|
||||
/* scan and convert delay digits (if any) */
|
||||
i = _tputs_convert(&cp, affcnt);
|
||||
|
||||
/*
|
||||
* The guts of the string.
|
||||
*/
|
||||
@ -130,3 +147,66 @@ tputs(cp, affcnt, outc)
|
||||
for (i /= mspc10; i > 0; i--)
|
||||
(*outc)(PC);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
t_puts(info, cp, affcnt, outc, args)
|
||||
struct tinfo *info;
|
||||
const char *cp;
|
||||
int affcnt;
|
||||
void (*outc) __P((char, void *));
|
||||
void *args;
|
||||
{
|
||||
int i = 0, limit = 2;
|
||||
int mspc10;
|
||||
char pad[2], *pptr;
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
/*
|
||||
* if we have info then get the pad char from the
|
||||
* termcap entry if it exists, otherwise use the
|
||||
* default NUL char.
|
||||
*/
|
||||
pptr = pad;
|
||||
if (t_getstr(info, "pc", &pptr, &limit) == NULL)
|
||||
{
|
||||
pad[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (cp == 0)
|
||||
return -1;
|
||||
|
||||
/* scan and convert delay digits (if any) */
|
||||
i = _tputs_convert(&cp, affcnt);
|
||||
|
||||
/*
|
||||
* The guts of the string.
|
||||
*/
|
||||
while (*cp)
|
||||
(*outc)(*cp++, args);
|
||||
|
||||
/*
|
||||
* If no delay needed, or output speed is
|
||||
* not comprehensible, then don't try to delay.
|
||||
*/
|
||||
if (i == 0)
|
||||
return 0;
|
||||
if (ospeed <= 0 || ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Round up by a half a character frame,
|
||||
* and then do the delay.
|
||||
* Too bad there are no user program accessible programmed delays.
|
||||
* Transmitting pad characters slows many
|
||||
* terminals down and also loads the system.
|
||||
*/
|
||||
mspc10 = tmspc10[ospeed];
|
||||
i += mspc10 / 2;
|
||||
for (i /= mspc10; i > 0; i--)
|
||||
(*outc)(pad[0], args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user