166963Speter/**************************************************************************** 2184989Srafan * Copyright (c) 2000-2006,2008 Free Software Foundation, Inc. * 366963Speter * * 466963Speter * Permission is hereby granted, free of charge, to any person obtaining a * 566963Speter * copy of this software and associated documentation files (the * 666963Speter * "Software"), to deal in the Software without restriction, including * 766963Speter * without limitation the rights to use, copy, modify, merge, publish, * 866963Speter * distribute, distribute with modifications, sublicense, and/or sell * 966963Speter * copies of the Software, and to permit persons to whom the Software is * 1066963Speter * furnished to do so, subject to the following conditions: * 1166963Speter * * 1266963Speter * The above copyright notice and this permission notice shall be included * 1366963Speter * in all copies or substantial portions of the Software. * 1466963Speter * * 1566963Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1666963Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1766963Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1866963Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1966963Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2066963Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2166963Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2266963Speter * * 2366963Speter * Except as contained in this notice, the name(s) of the above copyright * 2466963Speter * holders shall not be used in advertising or otherwise to promote the * 2566963Speter * sale, use or other dealings in this Software without prior written * 2666963Speter * authorization. * 2766963Speter ****************************************************************************/ 2866963Speter 2966963Speter/**************************************************************************** 3066963Speter * Author: Thomas E. Dickey * 3166963Speter ****************************************************************************/ 3266963Speter 3366963Speter#include <curses.priv.h> 3466963Speter 3566963Speter#include <ctype.h> 3666963Speter#include <termcap.h> 3766963Speter 38184989SrafanMODULE_ID("$Id: lib_tgoto.c,v 1.13 2008/08/16 19:29:32 tom Exp $") 3966963Speter 4066963Speter#if !PURE_TERMINFO 4166963Speterstatic bool 4266963Speteris_termcap(const char *string) 4366963Speter{ 4466963Speter bool result = TRUE; 4566963Speter 4676726Speter if (string == 0 || *string == '\0') { 4776726Speter result = FALSE; /* tparm() handles empty strings */ 4876726Speter } else { 4976726Speter while ((*string != '\0') && result) { 5076726Speter if (*string == '%') { 5176726Speter switch (*++string) { 5276726Speter case 'p': 5376726Speter result = FALSE; 5476726Speter break; 5576726Speter case '\0': 5676726Speter string--; 5776726Speter break; 5876726Speter } 5976726Speter } else if (string[0] == '$' && string[1] == '<') { 6066963Speter result = FALSE; 6166963Speter } 6276726Speter string++; 6366963Speter } 6466963Speter } 6566963Speter return result; 6666963Speter} 6766963Speter 6866963Speterstatic char * 6966963Spetertgoto_internal(const char *string, int x, int y) 7066963Speter{ 7166963Speter static char *result; 7266963Speter static size_t length; 7366963Speter 7466963Speter int swap_arg; 7566963Speter int param[3]; 7666963Speter size_t used = 0; 7766963Speter size_t need = 10; 7866963Speter int *value = param; 7966963Speter bool need_BC = FALSE; 8066963Speter 8166963Speter if (BC) 8266963Speter need += strlen(BC); 8366963Speter 8466963Speter param[0] = y; 8566963Speter param[1] = x; 8666963Speter param[2] = 0; 8766963Speter 8866963Speter while (*string != 0) { 8966963Speter if ((used + need) > length) { 9066963Speter length += (used + need); 91166124Srafan if ((result = typeRealloc(char, length, result)) == 0) { 9266963Speter length = 0; 9366963Speter break; 9466963Speter } 9566963Speter } 9666963Speter if (*string == '%') { 9776726Speter const char *fmt = 0; 9866963Speter 9966963Speter switch (*++string) { 10066963Speter case '\0': 10166963Speter string--; 10266963Speter break; 10366963Speter case 'd': 10466963Speter fmt = "%d"; 10566963Speter break; 10666963Speter case '2': 10766963Speter fmt = "%02d"; 10866963Speter *value %= 100; 10966963Speter break; 11066963Speter case '3': 11166963Speter fmt = "%03d"; 11266963Speter *value %= 1000; 11366963Speter break; 11466963Speter case '+': 11597049Speter *value += UChar(*++string); 11666963Speter /* FALLTHRU */ 11766963Speter case '.': 11866963Speter /* 11966963Speter * Guard against tputs() seeing a truncated string. The 12066963Speter * termcap documentation refers to a similar fixup for \n 12166963Speter * and \r, but I don't see that it could work -TD 12266963Speter */ 12366963Speter if (*value == 0) { 12466963Speter if (BC != 0) { 12566963Speter *value += 1; 12666963Speter need_BC = TRUE; 12766963Speter } else { 12866963Speter *value = 0200; /* tputs will treat this as \0 */ 12966963Speter } 13066963Speter } 131184989Srafan result[used++] = (char) *value++; 13266963Speter break; 13366963Speter case '%': 13466963Speter result[used++] = *string; 13566963Speter break; 13666963Speter case 'r': 13766963Speter swap_arg = param[0]; 13866963Speter param[0] = param[1]; 13966963Speter param[1] = swap_arg; 14066963Speter break; 14166963Speter case 'i': 14266963Speter param[0] += 1; 14366963Speter param[1] += 1; 14466963Speter break; 14566963Speter case '>': 14666963Speter if (*value > string[1]) 14766963Speter *value += string[2]; 14866963Speter string += 2; 14966963Speter break; 15066963Speter case 'n': /* Datamedia 2500 */ 15166963Speter param[0] ^= 0140; 15266963Speter param[1] ^= 0140; 15366963Speter break; 15466963Speter case 'B': /* BCD */ 15566963Speter *value = 16 * (*value / 10) + (*value % 10); 15666963Speter break; 15766963Speter case 'D': /* Reverse coding (Delta Data) */ 158166124Srafan *value -= 2 * (*value % 16); 15966963Speter break; 16066963Speter } 16166963Speter if (fmt != 0) { 16266963Speter sprintf(result + used, fmt, *value++); 16366963Speter used += strlen(result + used); 16466963Speter fmt = 0; 16566963Speter } 16666963Speter if (value - param > 2) { 16766963Speter value = param + 2; 16866963Speter *value = 0; 16966963Speter } 17066963Speter } else { 17166963Speter result[used++] = *string; 17266963Speter } 17366963Speter string++; 17466963Speter } 175166124Srafan if (result != 0) { 176166124Srafan if (need_BC) { 177166124Srafan strcpy(result + used, BC); 178166124Srafan used += strlen(BC); 179166124Srafan } 180166124Srafan result[used] = '\0'; 18166963Speter } 18266963Speter return result; 18366963Speter} 18466963Speter#endif 18566963Speter 18666963Speter/* 18766963Speter * Retained solely for upward compatibility. Note the intentional reversing of 18866963Speter * the last two arguments when invoking tparm(). 18966963Speter */ 19076726SpeterNCURSES_EXPORT(char *) 191166124Srafantgoto(const char *string, int x, int y) 19266963Speter{ 19366963Speter char *result; 19466963Speter 19566963Speter T((T_CALLED("tgoto(%s, %d, %d)"), _nc_visbuf(string), x, y)); 19666963Speter#if !PURE_TERMINFO 19766963Speter if (is_termcap(string)) 19866963Speter result = tgoto_internal(string, x, y); 19966963Speter else 20066963Speter#endif 201166124Srafan result = TPARM_2((NCURSES_CONST char *) string, y, x); 20266963Speter returnPtr(result); 20366963Speter} 204