xref: /minix3/lib/libterminfo/tputs.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /* $NetBSD: tputs.c,v 1.3 2013/06/07 13:16:18 roy Exp $ */
251e66a47SVivek Prakash 
351e66a47SVivek Prakash /*
451e66a47SVivek Prakash  * Copyright (c) 2009 The NetBSD Foundation, Inc.
551e66a47SVivek Prakash  *
651e66a47SVivek Prakash  * This code is derived from software contributed to The NetBSD Foundation
751e66a47SVivek Prakash  * by Roy Marples.
851e66a47SVivek Prakash  *
951e66a47SVivek Prakash  * Redistribution and use in source and binary forms, with or without
1051e66a47SVivek Prakash  * modification, are permitted provided that the following conditions
1151e66a47SVivek Prakash  * are met:
1251e66a47SVivek Prakash  * 1. Redistributions of source code must retain the above copyright
1351e66a47SVivek Prakash  *    notice, this list of conditions and the following disclaimer.
1451e66a47SVivek Prakash  * 2. Redistributions in binary form must reproduce the above copyright
1551e66a47SVivek Prakash  *    notice, this list of conditions and the following disclaimer in the
1651e66a47SVivek Prakash  *    documentation and/or other materials provided with the distribution.
1751e66a47SVivek Prakash  *
1851e66a47SVivek Prakash  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1951e66a47SVivek Prakash  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2051e66a47SVivek Prakash  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2151e66a47SVivek Prakash  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2251e66a47SVivek Prakash  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2351e66a47SVivek Prakash  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2451e66a47SVivek Prakash  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2551e66a47SVivek Prakash  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2651e66a47SVivek Prakash  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2751e66a47SVivek Prakash  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2851e66a47SVivek Prakash  */
2951e66a47SVivek Prakash 
3051e66a47SVivek Prakash #include <sys/cdefs.h>
31*84d9c625SLionel Sambuc __RCSID("$NetBSD: tputs.c,v 1.3 2013/06/07 13:16:18 roy Exp $");
3251e66a47SVivek Prakash 
3351e66a47SVivek Prakash #include <assert.h>
3451e66a47SVivek Prakash #include <ctype.h>
3551e66a47SVivek Prakash #include <stdio.h>
3651e66a47SVivek Prakash #include <string.h>
3751e66a47SVivek Prakash #include <term_private.h>
3851e66a47SVivek Prakash #include <term.h>
3951e66a47SVivek Prakash 
4051e66a47SVivek Prakash /*
4151e66a47SVivek Prakash  * The following array gives the number of tens of milliseconds per
4251e66a47SVivek Prakash  * character for each speed as returned by gtty.  Thus since 300
4351e66a47SVivek Prakash  * baud returns a 7, there are 33.3 milliseconds per char at 300 baud.
4451e66a47SVivek Prakash  */
4551e66a47SVivek Prakash static const short tmspc10[] = {
4651e66a47SVivek Prakash 	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
4751e66a47SVivek Prakash };
4851e66a47SVivek Prakash 
4951e66a47SVivek Prakash short ospeed;
5051e66a47SVivek Prakash char PC;
5151e66a47SVivek Prakash 
5251e66a47SVivek Prakash static int
_ti_calcdelay(const char ** str,int affcnt,int * mand)5351e66a47SVivek Prakash _ti_calcdelay(const char **str, int affcnt, int *mand)
5451e66a47SVivek Prakash {
5551e66a47SVivek Prakash 	int i;
5651e66a47SVivek Prakash 
5751e66a47SVivek Prakash 	i = 0;
5851e66a47SVivek Prakash 	/* Convert the delay */
5951e66a47SVivek Prakash 	while (isdigit(*(const unsigned char *)*str))
6051e66a47SVivek Prakash 		i = i * 10 + *(*str)++ - '0';
6151e66a47SVivek Prakash 	i *= 10;
6251e66a47SVivek Prakash 	if (*(*str) == '.') {
6351e66a47SVivek Prakash 		(*str)++;
6451e66a47SVivek Prakash 		if (isdigit(*(const unsigned char *)*str))
6551e66a47SVivek Prakash 			i += *(*str) - '0';
6651e66a47SVivek Prakash 		while (isdigit(*(const unsigned char *)*str))
6751e66a47SVivek Prakash 			(*str)++;
6851e66a47SVivek Prakash 	}
6951e66a47SVivek Prakash 	if (*(*str) == '*') {
7051e66a47SVivek Prakash 		(*str)++;
7151e66a47SVivek Prakash 		i *= affcnt;
7251e66a47SVivek Prakash 	} else if (*(*str) == '/') {
7351e66a47SVivek Prakash 		(*str)++;
7451e66a47SVivek Prakash 		if (mand != NULL)
7551e66a47SVivek Prakash 			*mand = 1;
7651e66a47SVivek Prakash 	}
7751e66a47SVivek Prakash 	return i;
7851e66a47SVivek Prakash }
7951e66a47SVivek Prakash 
8051e66a47SVivek Prakash static void
_ti_outputdelay(int delay,short os,char pc,int (* outc)(int,void *),void * args)8151e66a47SVivek Prakash _ti_outputdelay(int delay, short os, char pc,
8251e66a47SVivek Prakash     int (*outc)(int, void *), void *args)
8351e66a47SVivek Prakash {
8451e66a47SVivek Prakash 	int mspc10;
8551e66a47SVivek Prakash 
8651e66a47SVivek Prakash 	if (delay < 1 || os < 1 || (size_t)os >= __arraycount(tmspc10))
8751e66a47SVivek Prakash 		return;
8851e66a47SVivek Prakash 
8951e66a47SVivek Prakash 	mspc10 = tmspc10[os];
9051e66a47SVivek Prakash 	delay += mspc10 / 2;
9151e66a47SVivek Prakash 	for (delay /= mspc10; delay > 0; delay--)
9251e66a47SVivek Prakash 		outc(pc, args);
9351e66a47SVivek Prakash }
9451e66a47SVivek Prakash 
9551e66a47SVivek Prakash static int
_ti_puts(int dodelay,int os,int pc,const char * str,int affcnt,int (* outc)(int,void *),void * args)9651e66a47SVivek Prakash _ti_puts(int dodelay, int os, int pc,
9751e66a47SVivek Prakash     const char *str, int affcnt, int (*outc)(int, void *), void *args)
9851e66a47SVivek Prakash {
9951e66a47SVivek Prakash 	int taildelay, delay, mand;
10051e66a47SVivek Prakash 
10151e66a47SVivek Prakash 	if (str == NULL)
10251e66a47SVivek Prakash 		return OK;
10351e66a47SVivek Prakash 
10451e66a47SVivek Prakash 	taildelay = _ti_calcdelay(&str, affcnt, NULL);
10551e66a47SVivek Prakash 
10651e66a47SVivek Prakash 	/* Output the string with embedded delays */
10751e66a47SVivek Prakash 	for (; *str != '\0'; str++) {
10851e66a47SVivek Prakash 		if (str[0] != '$' ||
10951e66a47SVivek Prakash 		    str[1] != '<' ||
11051e66a47SVivek Prakash 		    !(isdigit((const unsigned char)str[2]) || str[2] == '.') ||
11151e66a47SVivek Prakash 		    strchr(str + 3, '>') == NULL)
11251e66a47SVivek Prakash 		{
11351e66a47SVivek Prakash 			outc(*str, args);
11451e66a47SVivek Prakash 		} else {
11551e66a47SVivek Prakash 			str += 2;
11651e66a47SVivek Prakash 			mand = 0;
11751e66a47SVivek Prakash 			delay = _ti_calcdelay(&str, affcnt, &mand);
11851e66a47SVivek Prakash 			if (dodelay != 0 || mand != 0)
11951e66a47SVivek Prakash 				_ti_outputdelay(delay, os, pc, outc, args);
12051e66a47SVivek Prakash 		}
12151e66a47SVivek Prakash 	}
12251e66a47SVivek Prakash 
12351e66a47SVivek Prakash 	/* Delay if needed */
12451e66a47SVivek Prakash 	if (dodelay)
12551e66a47SVivek Prakash 		_ti_outputdelay(taildelay, os, pc, outc, args);
12651e66a47SVivek Prakash 
12751e66a47SVivek Prakash 	return OK;
12851e66a47SVivek Prakash }
12951e66a47SVivek Prakash 
13051e66a47SVivek Prakash int
ti_puts(const TERMINAL * term,const char * str,int affcnt,int (* outc)(int,void *),void * args)13151e66a47SVivek Prakash ti_puts(const TERMINAL *term, const char *str, int affcnt,
13251e66a47SVivek Prakash     int (*outc)(int, void *), void *args)
13351e66a47SVivek Prakash {
13451e66a47SVivek Prakash 	int dodelay;
13551e66a47SVivek Prakash 	char pc;
13651e66a47SVivek Prakash 
13751e66a47SVivek Prakash 	_DIAGASSERT(term != NULL);
13851e66a47SVivek Prakash 	_DIAGASSERT(str != NULL);
13951e66a47SVivek Prakash 	_DIAGASSERT(outc != NULL);
14051e66a47SVivek Prakash 
14151e66a47SVivek Prakash 	dodelay = (str == t_bell(term) ||
14251e66a47SVivek Prakash 	    str == t_flash_screen(term) ||
14351e66a47SVivek Prakash 	    (t_xon_xoff(term) == 0 && t_padding_baud_rate(term) != 0));
14451e66a47SVivek Prakash 
14551e66a47SVivek Prakash 	if (t_pad_char(term) == NULL)
14651e66a47SVivek Prakash 	    pc = '\0';
14751e66a47SVivek Prakash 	else
14851e66a47SVivek Prakash 	    pc = *t_pad_char(term);
14951e66a47SVivek Prakash 	return _ti_puts(dodelay, term->_ospeed, pc,
15051e66a47SVivek Prakash 	    str, affcnt, outc, args);
15151e66a47SVivek Prakash }
15251e66a47SVivek Prakash 
15351e66a47SVivek Prakash int
ti_putp(const TERMINAL * term,const char * str)15451e66a47SVivek Prakash ti_putp(const TERMINAL *term, const char *str)
15551e66a47SVivek Prakash {
15651e66a47SVivek Prakash 
15751e66a47SVivek Prakash 	_DIAGASSERT(term != NULL);
15851e66a47SVivek Prakash 	_DIAGASSERT(str != NULL);
15951e66a47SVivek Prakash 	return ti_puts(term, str, 1, (int (*)(int, void *))putchar, NULL);
16051e66a47SVivek Prakash }
16151e66a47SVivek Prakash 
16251e66a47SVivek Prakash int
tputs(const char * str,int affcnt,int (* outc)(int))16351e66a47SVivek Prakash tputs(const char *str, int affcnt, int (*outc)(int))
16451e66a47SVivek Prakash {
16551e66a47SVivek Prakash 
16651e66a47SVivek Prakash 	_DIAGASSERT(str != NULL);
16751e66a47SVivek Prakash 	_DIAGASSERT(outc != NULL);
16851e66a47SVivek Prakash 	return _ti_puts(1, ospeed, PC, str, affcnt,
16951e66a47SVivek Prakash 	    (int (*)(int, void *))outc, NULL);
17051e66a47SVivek Prakash }
17151e66a47SVivek Prakash 
17251e66a47SVivek Prakash int
putp(const char * str)17351e66a47SVivek Prakash putp(const char *str)
17451e66a47SVivek Prakash {
17551e66a47SVivek Prakash 
17651e66a47SVivek Prakash 	_DIAGASSERT(str != NULL);
17751e66a47SVivek Prakash 	return tputs(str, 1, putchar);
17851e66a47SVivek Prakash }
179