Home | History | Annotate | Download | only in libtermcap
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 /* Copyright (c) 1979 Regents of the University of California */
     31 
     32 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     33 
     34 /*LINTLIBRARY*/
     35 
     36 #include <sys/types.h>
     37 #include <string.h>
     38 #include <sys/ttychars.h>
     39 
     40 #if 0
     41 static char
     42 sccsid[] = "@(#)tgoto.c 1.5 88/02/08 SMI"; /* from UCB 4.1 6/27/83 */
     43 #endif
     44 
     45 #define	MAXRETURNSIZE 64
     46 
     47 char	*UP;
     48 char	*BC;
     49 
     50 /*
     51  * Routine to perform cursor addressing.
     52  * CM is a string containing printf type escapes to allow
     53  * cursor addressing.  We start out ready to print the destination
     54  * line, and switch each time we print row or column.
     55  * The following escapes are defined for substituting row/column:
     56  *
     57  *	%d	as in printf
     58  *	%2	like %2d
     59  *	%3	like %3d
     60  *	%.	gives %c hacking special case characters
     61  *	%+x	like %c but adding x first
     62  *
     63  *	The codes below affect the state but don't use up a value.
     64  *
     65  *	%>xy	if value > x add y
     66  *	%r	reverses row/column
     67  *	%i	increments row/column (for one origin indexing)
     68  *	%%	gives %
     69  *	%B	BCD (2 decimal digits encoded in one byte)
     70  *	%D	Delta Data (backwards bcd)
     71  *
     72  * all other characters are ``self-inserting''.
     73  */
     74 
     75 char *
     76 tgoto(char *CM, int destcol, int destline)
     77 {
     78 	static char result[MAXRETURNSIZE];
     79 	static char added[10];
     80 	char *cp = CM;
     81 	char *dp = result;
     82 	int c;
     83 	int oncol = 0;
     84 	int which = destline;
     85 
     86 	if (cp == 0) {
     87 toohard:
     88 		/*
     89 		 * ``We don't do that under BOZO's big top''
     90 		 */
     91 		return ("OOPS");
     92 	}
     93 	added[0] = 0;
     94 	while ((c = *cp++) != 0) {
     95 		if (c != '%') {
     96 			*dp++ = (char) c;
     97 			continue;
     98 		}
     99 		switch (c = *cp++) {
    100 
    101 #ifdef CM_N
    102 		case 'n':
    103 			destcol ^= 0140;
    104 			destline ^= 0140;
    105 			goto setwhich;
    106 #endif
    107 
    108 		case 'd':
    109 			if (which < 10)
    110 				goto one;
    111 			if (which < 100)
    112 				goto two;
    113 			/*FALLTHRU*/
    114 
    115 		case '3':
    116 			*dp++ = (which / 100) | '0';
    117 			which %= 100;
    118 			/*FALLTHRU*/
    119 
    120 		case '2':
    121 two:
    122 			*dp++ = which / 10 | '0';
    123 one:
    124 			*dp++ = which % 10 | '0';
    125 swap:
    126 			oncol = 1 - oncol;
    127 setwhich:
    128 			which = oncol ? destcol : destline;
    129 			continue;
    130 
    131 #ifdef CM_GT
    132 		case '>':
    133 			if (which > *cp++)
    134 				which += *cp++;
    135 			else
    136 				cp++;
    137 			continue;
    138 #endif
    139 
    140 		case '+':
    141 			which += *cp++;
    142 			/*FALLTHRU*/
    143 
    144 		case '.':
    145 			/*
    146 			 * This code is worth scratching your head at for a
    147 			 * while.  The idea is that various weird things can
    148 			 * happen to nulls, EOT's, tabs, and newlines by the
    149 			 * tty driver, arpanet, and so on, so we don't send
    150 			 * them if we can help it.
    151 			 *
    152 			 * Tab is taken out to get Ann Arbors to work, otherwise
    153 			 * when they go to column 9 we increment which is wrong
    154 			 * because bcd isn't continuous.  We should take out
    155 			 * the rest too, or run the thing through more than
    156 			 * once until it doesn't make any of these, but that
    157 			 * would make termlib (and hence pdp-11 ex) bigger,
    158 			 * and also somewhat slower.  This requires all
    159 			 * programs which use termlib to stty tabs so they
    160 			 * don't get expanded.  They should do this anyway
    161 			 * because some terminals use ^I for other things,
    162 			 * like nondestructive space.
    163 			 */
    164 			if (which == 0 || which == CTRL('d') || which == '\n') {
    165 				if (oncol || UP)
    166 					/* Assumption: backspace works */
    167 					/*
    168 					 * Loop needed because newline happens
    169 					 * to be the successor of tab.
    170 					 */
    171 					do {
    172 						(void) strcat(added, oncol ?
    173 							(BC ? BC : "\b") : UP);
    174 						which++;
    175 					} while (which == '\n');
    176 			}
    177 			*dp++ = (char) which;
    178 			goto swap;
    179 
    180 		case 'r':
    181 			oncol = 1;
    182 			goto setwhich;
    183 
    184 		case 'i':
    185 			destcol++;
    186 			destline++;
    187 			which++;
    188 			continue;
    189 
    190 		case '%':
    191 			*dp++ = (char) c;
    192 			continue;
    193 
    194 #ifdef CM_B
    195 		case 'B':
    196 			which = (which/10 << 4) + which%10;
    197 			continue;
    198 #endif
    199 
    200 #ifdef CM_D
    201 		case 'D':
    202 			which = which - 2 * (which%16);
    203 			continue;
    204 #endif
    205 
    206 		default:
    207 			goto toohard;
    208 		}
    209 	}
    210 	(void) strcpy(dp, added);
    211 	return (result);
    212 }
    213