/************************************************************************ * * * Copyright (c) 1982, Fred Fish * * All Rights Reserved * * * * This software and/or documentation is released for public * * distribution for personal, non-commercial use only. * * Limited rights to use, modify, and redistribute are hereby * * granted for non-commercial purposes, provided that all * * copyright notices remain intact and all changes are clearly * * documented. The author makes no warranty of any kind with * * respect to this product and explicitly disclaims any implied * * warranties of merchantability or fitness for any particular * * purpose. * * * ************************************************************************ */ /* Modified: * 30-Apr-86 Mic Kaczmarczik * - Use ctype.h macros instead of the function isdigit(). * - Use VMS speed value for ospeed -- in microEmacs * this is obtainted by ttinit(). * 28-Jul-88 Tom Hageman * padding code is not compiled in if symbol NOPAD is #defined. * (NOPAD will be defined automatically for GEMDOS/MSDOS) * (See Log at end) */ #ifdef RCS_ID static const char rcsid[] = "$Id: tputs.c,v 1.6 1993/04/07 01:37:43 tom Exp tom $"; #endif /* * LIBRARY FUNCTION * * tputs output string with appropriate padding * * KEY WORDS * * termcap * * SYNOPSIS * * tputs (cp,affcnt,outc) * char *cp; * int affcnt; * int (*outc)(); * * DESCRIPTION * * Outputs string pointed to by cp, using function outc, and * following it with the appropriate number of padding characters. * Affcnt contains the number of lines affected, which is used * as a multiplier for the specified per line pad time. If * per line pad count is not applicable, affcnt should be 1, * NOT zero. * * The format of the string pointed to by cp is: * * [pad time][*] * * where: pad time => time to delay in milliseconds * * => specifies that time is per line * * The pad character is assumed to reside in the external * variable "PC". Also, the external variable "ospeed" * should contain the output speed of the terminal as * encoded in /usr/include/sgtty.h (B0-B9600). * * SYSTEM DEPENDENCIES * * On VMS, the external variable "ospeed" should contain the * output speed of the terminal as obtained from byte 3 of * the iosb status buffer, using the IO$_SENSEMODE QIO. * The table times[] compiles into the correct values for VMS, * and, happily, also handles 19200 baud. * * On MS-DOS or GEMDOS padding makes no sense, so it is not * compiled in. * * BUGS * * Return type should be void. */ /* * Miscellaneous stuff */ #include #include "_termcap.h" #define isdigit(c) ('0' <= (c) && (c) <= '9') #ifndef NOPAD # if (GEMDOS || MSDOS) # define NOPAD 1 # endif #endif #if !NOPAD extern char PC; /* Pad character to use */ extern short ospeed; /* Encoding of output speed */ #if !(vms || GEMDOS || MSDOS) /* i.e., unix or Minix */ # if _I_TERMIOS # include # else # if _I_TERMIO # include # else # include # endif # endif #endif #define INFINITY 32767 /* Infinite enough to me. */ /* Minix (1.5) has a rather peculiar speed encoding (baud/100). */ #if (B9600 == 96 && B2400 == 24) # define OSPEED_TO_10th_ms(o) ((o) ? (1000 + (o)>>1) / (o) : INFINITY) #endif #ifndef OSPEED_TO_10th_ms # ifndef B0 # define B0 0 # endif # ifndef B50 # define B50 1 # endif # if (B50 - B0 == 1) # define OSPEED_TO_10th_ms(o) (times[(o) - B0]) # else # define OSPEED_TO_10th_ms(o) ((o)==B0 ? INFINITY : times[(o)-B50+1]) # endif /* This macro converts baud rate to tenths of milliseconds. */ # define BAUD_TO_10th_ms(baud) ((int)((100000L + (baud)/2) / (baud))) static int times[] = { INFINITY, /* Tenths of ms per char 0 baud (bogus) */ BAUD_TO_10th_ms(50), BAUD_TO_10th_ms(75), BAUD_TO_10th_ms(110), BAUD_TO_10th_ms(134), BAUD_TO_10th_ms(150), #if !vms BAUD_TO_10th_ms(200), #endif BAUD_TO_10th_ms(300), BAUD_TO_10th_ms(600), #if (B900) BAUD_TO_10th_ms(900), #endif BAUD_TO_10th_ms(1200), BAUD_TO_10th_ms(1800), #if vms BAUD_TO_10th_ms(2000), #endif BAUD_TO_10th_ms(2400), #if (B3600 || vms) BAUD_TO_10th_ms(3600), #endif BAUD_TO_10th_ms(4800), #if (B7200 || vms) BAUD_TO_10th_ms(7200), #endif BAUD_TO_10th_ms(9600), BAUD_TO_10th_ms(19200), BAUD_TO_10th_ms(38400), INFINITY, /* for future extensions. */ INFINITY }; #endif /* !OSPEED_TO_10th_ms */ #endif /* !NOPAD */ /* * PSEUDO CODE * * Begin tputs * If string pointer is invalid then * Return without doing anything. * Else * For each pad digit (if any) * Accumulate the lower digit. * Do decimal left shift. * End for * If there is a fractional field * Skip the decimal point. * If there is a valid tenths digit * Accumulate the tenths. * End if * Discard remaining digits. * End if * If per line is specified then * Adjust the pad time. * Discard the per line flag char. * End if * While there are any characters left * Send them out via output function. * End while * Transmit any padding required. * End if * End tgoto * */ int tputs(cap, affcnt, outc) const char *cap; int affcnt; int (*outc)__(( int )); { register const char *cp; #if !NOPAD register int ptime = 0; /* Pad time in tenths of milliseconds */ #endif if ((cp = cap) == NULL || *cp == '\0') return; while (isdigit(*cp)) #if !NOPAD ptime = (ptime + (*cp++ - '0')) * 10; #else cp++; #endif if (*cp == '.') { cp++; #if !NOPAD if (isdigit(*cp)) ptime += (*cp++ - '0'); #endif while (isdigit(*cp)) cp++; } if (*cp == '*') { cp++; #if !NOPAD ptime *= affcnt; #endif } while (*cp) (*outc)(*cp++); #if !NOPAD if (ptime > 0) { register int tpc = OSPEED_TO_10th_ms(ospeed); ptime = (ptime + (tpc >> 1)) / tpc; while (--ptime >= 0) (*outc)(PC); } #endif } /*======================================================================* * $Log: tputs.c,v $ * Revision 1.6 1993/04/07 01:37:43 tom * fix typo in RCS Log. * *======================================================================*/