Back to index

tetex-bin  3.0
lib_tgoto.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 2000-2002,2003 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Thomas E. Dickey                                                *
00031  ****************************************************************************/
00032 
00033 #include <curses.priv.h>
00034 
00035 #include <ctype.h>
00036 #include <termcap.h>
00037 
00038 MODULE_ID("$Id: lib_tgoto.c,v 1.11 2003/11/30 00:22:18 Juha.Jarvi Exp $")
00039 
00040 #if !PURE_TERMINFO
00041 static bool
00042 is_termcap(const char *string)
00043 {
00044     bool result = TRUE;
00045 
00046     if (string == 0 || *string == '\0') {
00047        result = FALSE;             /* tparm() handles empty strings */
00048     } else {
00049        while ((*string != '\0') && result) {
00050            if (*string == '%') {
00051               switch (*++string) {
00052               case 'p':
00053                   result = FALSE;
00054                   break;
00055               case '\0':
00056                   string--;
00057                   break;
00058               }
00059            } else if (string[0] == '$' && string[1] == '<') {
00060               result = FALSE;
00061            }
00062            string++;
00063        }
00064     }
00065     return result;
00066 }
00067 
00068 static char *
00069 tgoto_internal(const char *string, int x, int y)
00070 {
00071     static char *result;
00072     static size_t length;
00073 
00074     int swap_arg;
00075     int param[3];
00076     size_t used = 0;
00077     size_t need = 10;
00078     int *value = param;
00079     bool need_BC = FALSE;
00080 
00081     if (BC)
00082        need += strlen(BC);
00083 
00084     param[0] = y;
00085     param[1] = x;
00086     param[2] = 0;
00087 
00088     while (*string != 0) {
00089        if ((used + need) > length) {
00090            length += (used + need);
00091            if ((result = typeRealloc(char, length, result)) == 0) {
00092               length = 0;
00093               break;
00094            }
00095        }
00096        if (*string == '%') {
00097            const char *fmt = 0;
00098 
00099            switch (*++string) {
00100            case '\0':
00101               string--;
00102               break;
00103            case 'd':
00104               fmt = "%d";
00105               break;
00106            case '2':
00107               fmt = "%02d";
00108               *value %= 100;
00109               break;
00110            case '3':
00111               fmt = "%03d";
00112               *value %= 1000;
00113               break;
00114            case '+':
00115               *value += UChar(*++string);
00116               /* FALLTHRU */
00117            case '.':
00118               /*
00119                * Guard against tputs() seeing a truncated string.  The
00120                * termcap documentation refers to a similar fixup for \n
00121                * and \r, but I don't see that it could work -TD
00122                */
00123               if (*value == 0) {
00124                   if (BC != 0) {
00125                      *value += 1;
00126                      need_BC = TRUE;
00127                   } else {
00128                      *value = 0200;       /* tputs will treat this as \0 */
00129                   }
00130               }
00131               result[used++] = *value++;
00132               break;
00133            case '%':
00134               result[used++] = *string;
00135               break;
00136            case 'r':
00137               swap_arg = param[0];
00138               param[0] = param[1];
00139               param[1] = swap_arg;
00140               break;
00141            case 'i':
00142               param[0] += 1;
00143               param[1] += 1;
00144               break;
00145            case '>':
00146               if (*value > string[1])
00147                   *value += string[2];
00148               string += 2;
00149               break;
00150            case 'n':        /* Datamedia 2500 */
00151               param[0] ^= 0140;
00152               param[1] ^= 0140;
00153               break;
00154            case 'B':        /* BCD */
00155               *value = 16 * (*value / 10) + (*value % 10);
00156               break;
00157            case 'D':        /* Reverse coding (Delta Data) */
00158               *value -= 2 * (*value % 16);
00159               break;
00160            }
00161            if (fmt != 0) {
00162               sprintf(result + used, fmt, *value++);
00163               used += strlen(result + used);
00164               fmt = 0;
00165            }
00166            if (value - param > 2) {
00167               value = param + 2;
00168               *value = 0;
00169            }
00170        } else {
00171            result[used++] = *string;
00172        }
00173        string++;
00174     }
00175     if (result != 0) {
00176        if (need_BC) {
00177            strcpy(result + used, BC);
00178            used += strlen(BC);
00179        }
00180        result[used] = '\0';
00181     }
00182     return result;
00183 }
00184 #endif
00185 
00186 /*
00187  * Retained solely for upward compatibility.  Note the intentional reversing of
00188  * the last two arguments when invoking tparm().
00189  */
00190 NCURSES_EXPORT(char *)
00191 tgoto(const char *string, int x, int y)
00192 {
00193     char *result;
00194 
00195     T((T_CALLED("tgoto(%s, %d, %d)"), _nc_visbuf(string), x, y));
00196 #if !PURE_TERMINFO
00197     if (is_termcap(string))
00198        result = tgoto_internal(string, x, y);
00199     else
00200 #endif
00201        result = tparm((NCURSES_CONST char *) string, y, x);
00202     returnPtr(result);
00203 }