1 /**************************************************************************** 2 * Copyright (c) 2000 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29 /**************************************************************************** 30 * Author: Thomas E. Dickey * 31 ****************************************************************************/ 32 33 #include <curses.priv.h> 34 35 #include <ctype.h> 36 #include <termcap.h> 37 38 MODULE_ID("$Id: lib_tgoto.c,v 1.2 2000/09/24 00:19:14 tom Exp $") 39 40 #if !PURE_TERMINFO 41 static bool 42 is_termcap(const char *string) 43 { 44 bool result = TRUE; 45 46 while ((*string != '\0') && result) { 47 if (*string == '%') { 48 switch (*++string) { 49 case 'p': 50 result = FALSE; 51 break; 52 case '\0': 53 string--; 54 break; 55 } 56 } else if (string[0] == '$' && string[1] == '<') { 57 result = FALSE; 58 } 59 string++; 60 } 61 return result; 62 } 63 64 static char * 65 tgoto_internal(const char *string, int x, int y) 66 { 67 static char *result; 68 static size_t length; 69 70 int swap_arg; 71 int param[3]; 72 size_t used = 0; 73 size_t need = 10; 74 int *value = param; 75 bool need_BC = FALSE; 76 77 if (BC) 78 need += strlen(BC); 79 80 param[0] = y; 81 param[1] = x; 82 param[2] = 0; 83 84 while (*string != 0) { 85 if ((used + need) > length) { 86 length += (used + need); 87 if ((result = _nc_doalloc(result, length)) == 0) { 88 length = 0; 89 break; 90 } 91 } 92 if (*string == '%') { 93 char *fmt = 0; 94 95 switch (*++string) { 96 case '\0': 97 string--; 98 break; 99 case 'd': 100 fmt = "%d"; 101 break; 102 case '2': 103 fmt = "%02d"; 104 *value %= 100; 105 break; 106 case '3': 107 fmt = "%03d"; 108 *value %= 1000; 109 break; 110 case '+': 111 *value += (*++string & 0xff); 112 /* FALLTHRU */ 113 case '.': 114 /* 115 * Guard against tputs() seeing a truncated string. The 116 * termcap documentation refers to a similar fixup for \n 117 * and \r, but I don't see that it could work -TD 118 */ 119 if (*value == 0) { 120 if (BC != 0) { 121 *value += 1; 122 need_BC = TRUE; 123 } else { 124 *value = 0200; /* tputs will treat this as \0 */ 125 } 126 } 127 result[used++] = *value++; 128 break; 129 case '%': 130 result[used++] = *string; 131 break; 132 case 'r': 133 swap_arg = param[0]; 134 param[0] = param[1]; 135 param[1] = swap_arg; 136 break; 137 case 'i': 138 param[0] += 1; 139 param[1] += 1; 140 break; 141 case '>': 142 if (*value > string[1]) 143 *value += string[2]; 144 string += 2; 145 break; 146 case 'n': /* Datamedia 2500 */ 147 param[0] ^= 0140; 148 param[1] ^= 0140; 149 break; 150 case 'B': /* BCD */ 151 *value = 16 * (*value / 10) + (*value % 10); 152 break; 153 case 'D': /* Reverse coding (Delta Data) */ 154 *value -= 2 * (*value / 16); 155 break; 156 } 157 if (fmt != 0) { 158 sprintf(result + used, fmt, *value++); 159 used += strlen(result + used); 160 fmt = 0; 161 } 162 if (value - param > 2) { 163 value = param + 2; 164 *value = 0; 165 } 166 } else { 167 result[used++] = *string; 168 } 169 string++; 170 } 171 if (need_BC) { 172 strcpy(result + used, BC); 173 used += strlen(BC); 174 } 175 result[used] = '\0'; 176 return result; 177 } 178 #endif 179 180 /* 181 * Retained solely for upward compatibility. Note the intentional reversing of 182 * the last two arguments when invoking tparm(). 183 */ 184 char * 185 tgoto(const char *string, int x, int y) 186 { 187 char *result; 188 189 T((T_CALLED("tgoto(%s, %d, %d)"), _nc_visbuf(string), x, y)); 190 #if !PURE_TERMINFO 191 if (is_termcap(string)) 192 result = tgoto_internal(string, x, y); 193 else 194 #endif 195 result = tparm((NCURSES_CONST char *) string, y, x); 196 returnPtr(result); 197 } 198