1fdd4e1e0SJan Lentfer /**************************************************************************** 2*00d8f3c4SJohn Marino * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. * 3fdd4e1e0SJan Lentfer * * 4fdd4e1e0SJan Lentfer * Permission is hereby granted, free of charge, to any person obtaining a * 5fdd4e1e0SJan Lentfer * copy of this software and associated documentation files (the * 6fdd4e1e0SJan Lentfer * "Software"), to deal in the Software without restriction, including * 7fdd4e1e0SJan Lentfer * without limitation the rights to use, copy, modify, merge, publish, * 8fdd4e1e0SJan Lentfer * distribute, distribute with modifications, sublicense, and/or sell * 9fdd4e1e0SJan Lentfer * copies of the Software, and to permit persons to whom the Software is * 10fdd4e1e0SJan Lentfer * furnished to do so, subject to the following conditions: * 11fdd4e1e0SJan Lentfer * * 12fdd4e1e0SJan Lentfer * The above copyright notice and this permission notice shall be included * 13fdd4e1e0SJan Lentfer * in all copies or substantial portions of the Software. * 14fdd4e1e0SJan Lentfer * * 15fdd4e1e0SJan Lentfer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16fdd4e1e0SJan Lentfer * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17fdd4e1e0SJan Lentfer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18fdd4e1e0SJan Lentfer * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19fdd4e1e0SJan Lentfer * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20fdd4e1e0SJan Lentfer * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21fdd4e1e0SJan Lentfer * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22fdd4e1e0SJan Lentfer * * 23fdd4e1e0SJan Lentfer * Except as contained in this notice, the name(s) of the above copyright * 24fdd4e1e0SJan Lentfer * holders shall not be used in advertising or otherwise to promote the * 25fdd4e1e0SJan Lentfer * sale, use or other dealings in this Software without prior written * 26fdd4e1e0SJan Lentfer * authorization. * 27fdd4e1e0SJan Lentfer ****************************************************************************/ 28fdd4e1e0SJan Lentfer 29fdd4e1e0SJan Lentfer /**************************************************************************** 30fdd4e1e0SJan Lentfer * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 31fdd4e1e0SJan Lentfer * and: Eric S. Raymond <esr@snark.thyrsus.com> * 321d102085SJan Lentfer * and: Thomas E. Dickey 1996-on * 33fdd4e1e0SJan Lentfer ****************************************************************************/ 34fdd4e1e0SJan Lentfer 35fdd4e1e0SJan Lentfer /* 36fdd4e1e0SJan Lentfer * captoinfo.c --- conversion between termcap and terminfo formats 37fdd4e1e0SJan Lentfer * 38fdd4e1e0SJan Lentfer * The captoinfo() code was swiped from Ross Ridge's mytinfo package, 39fdd4e1e0SJan Lentfer * adapted to fit ncurses by Eric S. Raymond <esr@snark.thyrsus.com>. 40fdd4e1e0SJan Lentfer * 41fdd4e1e0SJan Lentfer * There is just one entry point: 42fdd4e1e0SJan Lentfer * 43fdd4e1e0SJan Lentfer * char *_nc_captoinfo(n, s, parameterized) 44fdd4e1e0SJan Lentfer * 45fdd4e1e0SJan Lentfer * Convert value s for termcap string capability named n into terminfo 46fdd4e1e0SJan Lentfer * format. 47fdd4e1e0SJan Lentfer * 48fdd4e1e0SJan Lentfer * This code recognizes all the standard 4.4BSD %-escapes: 49fdd4e1e0SJan Lentfer * 50fdd4e1e0SJan Lentfer * %% output `%' 51fdd4e1e0SJan Lentfer * %d output value as in printf %d 52fdd4e1e0SJan Lentfer * %2 output value as in printf %2d 53fdd4e1e0SJan Lentfer * %3 output value as in printf %3d 54fdd4e1e0SJan Lentfer * %. output value as in printf %c 55fdd4e1e0SJan Lentfer * %+x add x to value, then do %. 56fdd4e1e0SJan Lentfer * %>xy if value > x then add y, no output 57fdd4e1e0SJan Lentfer * %r reverse order of two parameters, no output 58fdd4e1e0SJan Lentfer * %i increment by one, no output 59fdd4e1e0SJan Lentfer * %n exclusive-or all parameters with 0140 (Datamedia 2500) 60fdd4e1e0SJan Lentfer * %B BCD (16*(value/10)) + (value%10), no output 61fdd4e1e0SJan Lentfer * %D Reverse coding (value - 2*(value%16)), no output (Delta Data). 62fdd4e1e0SJan Lentfer * 63fdd4e1e0SJan Lentfer * Also, %02 and %03 are accepted as synonyms for %2 and %3. 64fdd4e1e0SJan Lentfer * 65fdd4e1e0SJan Lentfer * Besides all the standard termcap escapes, this translator understands 66fdd4e1e0SJan Lentfer * the following extended escapes: 67fdd4e1e0SJan Lentfer * 68fdd4e1e0SJan Lentfer * used by GNU Emacs termcap libraries 69fdd4e1e0SJan Lentfer * %a[+*-/=][cp]x GNU arithmetic. 70fdd4e1e0SJan Lentfer * %m xor the first two parameters by 0177 71fdd4e1e0SJan Lentfer * %b backup to previous parameter 72fdd4e1e0SJan Lentfer * %f skip this parameter 73fdd4e1e0SJan Lentfer * 74fdd4e1e0SJan Lentfer * used by the University of Waterloo (MFCF) termcap libraries 75fdd4e1e0SJan Lentfer * %-x subtract parameter FROM char x and output it as a char 76fdd4e1e0SJan Lentfer * %ax add the character x to parameter 77fdd4e1e0SJan Lentfer * 78fdd4e1e0SJan Lentfer * If #define WATERLOO is on, also enable these translations: 79fdd4e1e0SJan Lentfer * 80fdd4e1e0SJan Lentfer * %sx subtract parameter FROM the character x 81fdd4e1e0SJan Lentfer * 82fdd4e1e0SJan Lentfer * By default, this Waterloo translations are not compiled in, because 83fdd4e1e0SJan Lentfer * the Waterloo %s conflicts with the way terminfo uses %s in strings for 84fdd4e1e0SJan Lentfer * function programming. 85fdd4e1e0SJan Lentfer * 86fdd4e1e0SJan Lentfer * Note the two definitions of %a: the GNU definition is translated if the 87fdd4e1e0SJan Lentfer * characters after the 'a' are valid for it, otherwise the UW definition 88fdd4e1e0SJan Lentfer * is translated. 89fdd4e1e0SJan Lentfer */ 90fdd4e1e0SJan Lentfer 91fdd4e1e0SJan Lentfer #include <curses.priv.h> 92fdd4e1e0SJan Lentfer 93fdd4e1e0SJan Lentfer #include <ctype.h> 94fdd4e1e0SJan Lentfer #include <tic.h> 95fdd4e1e0SJan Lentfer 96*00d8f3c4SJohn Marino MODULE_ID("$Id: captoinfo.c,v 1.58 2010/12/04 20:08:19 tom Exp $") 97fdd4e1e0SJan Lentfer 98fdd4e1e0SJan Lentfer #define MAX_PUSHED 16 /* max # args we can push onto the stack */ 99fdd4e1e0SJan Lentfer 100fdd4e1e0SJan Lentfer static int stack[MAX_PUSHED]; /* the stack */ 101fdd4e1e0SJan Lentfer static int stackptr; /* the next empty place on the stack */ 102fdd4e1e0SJan Lentfer static int onstack; /* the top of stack */ 103fdd4e1e0SJan Lentfer static int seenm; /* seen a %m */ 104fdd4e1e0SJan Lentfer static int seenn; /* seen a %n */ 105fdd4e1e0SJan Lentfer static int seenr; /* seen a %r */ 106fdd4e1e0SJan Lentfer static int param; /* current parameter */ 107fdd4e1e0SJan Lentfer static char *dp; /* pointer to end of the converted string */ 108fdd4e1e0SJan Lentfer 109fdd4e1e0SJan Lentfer static char *my_string; 110fdd4e1e0SJan Lentfer static size_t my_length; 111fdd4e1e0SJan Lentfer 112fdd4e1e0SJan Lentfer static char * 113fdd4e1e0SJan Lentfer init_string(void) 114fdd4e1e0SJan Lentfer /* initialize 'my_string', 'my_length' */ 115fdd4e1e0SJan Lentfer { 116fdd4e1e0SJan Lentfer if (my_string == 0) 117fdd4e1e0SJan Lentfer my_string = typeMalloc(char, my_length = 256); 118fdd4e1e0SJan Lentfer if (my_string == 0) 119fdd4e1e0SJan Lentfer _nc_err_abort(MSG_NO_MEMORY); 120fdd4e1e0SJan Lentfer 121fdd4e1e0SJan Lentfer *my_string = '\0'; 122fdd4e1e0SJan Lentfer return my_string; 123fdd4e1e0SJan Lentfer } 124fdd4e1e0SJan Lentfer 125fdd4e1e0SJan Lentfer static char * 126fdd4e1e0SJan Lentfer save_string(char *d, const char *const s) 127fdd4e1e0SJan Lentfer { 128*00d8f3c4SJohn Marino size_t have = (size_t) (d - my_string); 129fdd4e1e0SJan Lentfer size_t need = have + strlen(s) + 2; 130fdd4e1e0SJan Lentfer if (need > my_length) { 131*00d8f3c4SJohn Marino my_string = (char *) _nc_doalloc(my_string, my_length = (need + need)); 132fdd4e1e0SJan Lentfer if (my_string == 0) 133fdd4e1e0SJan Lentfer _nc_err_abort(MSG_NO_MEMORY); 134fdd4e1e0SJan Lentfer d = my_string + have; 135fdd4e1e0SJan Lentfer } 136fdd4e1e0SJan Lentfer (void) strcpy(d, s); 137fdd4e1e0SJan Lentfer return d + strlen(d); 138fdd4e1e0SJan Lentfer } 139fdd4e1e0SJan Lentfer 1401d102085SJan Lentfer static NCURSES_INLINE char * 141fdd4e1e0SJan Lentfer save_char(char *s, int c) 142fdd4e1e0SJan Lentfer { 143fdd4e1e0SJan Lentfer static char temp[2]; 144fdd4e1e0SJan Lentfer temp[0] = (char) c; 145fdd4e1e0SJan Lentfer return save_string(s, temp); 146fdd4e1e0SJan Lentfer } 147fdd4e1e0SJan Lentfer 148fdd4e1e0SJan Lentfer static void 149fdd4e1e0SJan Lentfer push(void) 150fdd4e1e0SJan Lentfer /* push onstack on to the stack */ 151fdd4e1e0SJan Lentfer { 1521d102085SJan Lentfer if (stackptr >= MAX_PUSHED) 153fdd4e1e0SJan Lentfer _nc_warning("string too complex to convert"); 154fdd4e1e0SJan Lentfer else 155fdd4e1e0SJan Lentfer stack[stackptr++] = onstack; 156fdd4e1e0SJan Lentfer } 157fdd4e1e0SJan Lentfer 158fdd4e1e0SJan Lentfer static void 159fdd4e1e0SJan Lentfer pop(void) 160fdd4e1e0SJan Lentfer /* pop the top of the stack into onstack */ 161fdd4e1e0SJan Lentfer { 162fdd4e1e0SJan Lentfer if (stackptr == 0) { 163fdd4e1e0SJan Lentfer if (onstack == 0) 164fdd4e1e0SJan Lentfer _nc_warning("I'm confused"); 165fdd4e1e0SJan Lentfer else 166fdd4e1e0SJan Lentfer onstack = 0; 167fdd4e1e0SJan Lentfer } else 168fdd4e1e0SJan Lentfer onstack = stack[--stackptr]; 169fdd4e1e0SJan Lentfer param++; 170fdd4e1e0SJan Lentfer } 171fdd4e1e0SJan Lentfer 172fdd4e1e0SJan Lentfer static int 173fdd4e1e0SJan Lentfer cvtchar(register const char *sp) 174fdd4e1e0SJan Lentfer /* convert a character to a terminfo push */ 175fdd4e1e0SJan Lentfer { 176fdd4e1e0SJan Lentfer unsigned char c = 0; 177fdd4e1e0SJan Lentfer int len; 178fdd4e1e0SJan Lentfer 179fdd4e1e0SJan Lentfer switch (*sp) { 180fdd4e1e0SJan Lentfer case '\\': 181fdd4e1e0SJan Lentfer switch (*++sp) { 182fdd4e1e0SJan Lentfer case '\'': 183fdd4e1e0SJan Lentfer case '$': 184fdd4e1e0SJan Lentfer case '\\': 185fdd4e1e0SJan Lentfer case '%': 1861d102085SJan Lentfer c = (unsigned char) (*sp); 187fdd4e1e0SJan Lentfer len = 2; 188fdd4e1e0SJan Lentfer break; 189fdd4e1e0SJan Lentfer case '\0': 190fdd4e1e0SJan Lentfer c = '\\'; 191fdd4e1e0SJan Lentfer len = 1; 192fdd4e1e0SJan Lentfer break; 193fdd4e1e0SJan Lentfer case '0': 194fdd4e1e0SJan Lentfer case '1': 195fdd4e1e0SJan Lentfer case '2': 196fdd4e1e0SJan Lentfer case '3': 197fdd4e1e0SJan Lentfer len = 1; 198fdd4e1e0SJan Lentfer while (isdigit(UChar(*sp))) { 199*00d8f3c4SJohn Marino c = (unsigned char) (8 * c + (*sp++ - '0')); 200fdd4e1e0SJan Lentfer len++; 201fdd4e1e0SJan Lentfer } 202fdd4e1e0SJan Lentfer break; 203fdd4e1e0SJan Lentfer default: 2041d102085SJan Lentfer c = (unsigned char) (*sp); 205fdd4e1e0SJan Lentfer len = 2; 206fdd4e1e0SJan Lentfer break; 207fdd4e1e0SJan Lentfer } 208fdd4e1e0SJan Lentfer break; 209fdd4e1e0SJan Lentfer case '^': 210*00d8f3c4SJohn Marino c = (unsigned char) (*++sp & 0x1f); 211fdd4e1e0SJan Lentfer len = 2; 212fdd4e1e0SJan Lentfer break; 213fdd4e1e0SJan Lentfer default: 2141d102085SJan Lentfer c = (unsigned char) (*sp); 215fdd4e1e0SJan Lentfer len = 1; 216fdd4e1e0SJan Lentfer } 217fdd4e1e0SJan Lentfer if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') { 218fdd4e1e0SJan Lentfer dp = save_string(dp, "%\'"); 219fdd4e1e0SJan Lentfer dp = save_char(dp, c); 220fdd4e1e0SJan Lentfer dp = save_char(dp, '\''); 221fdd4e1e0SJan Lentfer } else { 222fdd4e1e0SJan Lentfer dp = save_string(dp, "%{"); 223fdd4e1e0SJan Lentfer if (c > 99) 224fdd4e1e0SJan Lentfer dp = save_char(dp, c / 100 + '0'); 225fdd4e1e0SJan Lentfer if (c > 9) 226fdd4e1e0SJan Lentfer dp = save_char(dp, ((int) (c / 10)) % 10 + '0'); 227fdd4e1e0SJan Lentfer dp = save_char(dp, c % 10 + '0'); 228fdd4e1e0SJan Lentfer dp = save_char(dp, '}'); 229fdd4e1e0SJan Lentfer } 230fdd4e1e0SJan Lentfer return len; 231fdd4e1e0SJan Lentfer } 232fdd4e1e0SJan Lentfer 233fdd4e1e0SJan Lentfer static void 234fdd4e1e0SJan Lentfer getparm(int parm, int n) 235fdd4e1e0SJan Lentfer /* push n copies of param on the terminfo stack if not already there */ 236fdd4e1e0SJan Lentfer { 237fdd4e1e0SJan Lentfer if (seenr) { 238fdd4e1e0SJan Lentfer if (parm == 1) 239fdd4e1e0SJan Lentfer parm = 2; 240fdd4e1e0SJan Lentfer else if (parm == 2) 241fdd4e1e0SJan Lentfer parm = 1; 242fdd4e1e0SJan Lentfer } 243fdd4e1e0SJan Lentfer if (onstack == parm) { 244fdd4e1e0SJan Lentfer if (n > 1) { 245fdd4e1e0SJan Lentfer _nc_warning("string may not be optimal"); 246fdd4e1e0SJan Lentfer dp = save_string(dp, "%Pa"); 247fdd4e1e0SJan Lentfer while (n--) { 248fdd4e1e0SJan Lentfer dp = save_string(dp, "%ga"); 249fdd4e1e0SJan Lentfer } 250fdd4e1e0SJan Lentfer } 251fdd4e1e0SJan Lentfer return; 252fdd4e1e0SJan Lentfer } 253fdd4e1e0SJan Lentfer if (onstack != 0) 254fdd4e1e0SJan Lentfer push(); 255fdd4e1e0SJan Lentfer 256fdd4e1e0SJan Lentfer onstack = parm; 257fdd4e1e0SJan Lentfer 258fdd4e1e0SJan Lentfer while (n--) { 259fdd4e1e0SJan Lentfer dp = save_string(dp, "%p"); 260fdd4e1e0SJan Lentfer dp = save_char(dp, '0' + parm); 261fdd4e1e0SJan Lentfer } 262fdd4e1e0SJan Lentfer 263fdd4e1e0SJan Lentfer if (seenn && parm < 3) { 264fdd4e1e0SJan Lentfer dp = save_string(dp, "%{96}%^"); 265fdd4e1e0SJan Lentfer } 266fdd4e1e0SJan Lentfer 267fdd4e1e0SJan Lentfer if (seenm && parm < 3) { 268fdd4e1e0SJan Lentfer dp = save_string(dp, "%{127}%^"); 269fdd4e1e0SJan Lentfer } 270fdd4e1e0SJan Lentfer } 271fdd4e1e0SJan Lentfer 272fdd4e1e0SJan Lentfer /* 273fdd4e1e0SJan Lentfer * Convert a termcap string to terminfo format. 274fdd4e1e0SJan Lentfer * 'cap' is the relevant terminfo capability index. 275fdd4e1e0SJan Lentfer * 's' is the string value of the capability. 276fdd4e1e0SJan Lentfer * 'parameterized' tells what type of translations to do: 277fdd4e1e0SJan Lentfer * % translations if 1 278fdd4e1e0SJan Lentfer * pad translations if >=0 279fdd4e1e0SJan Lentfer */ 2801d102085SJan Lentfer NCURSES_EXPORT(char *) 281fdd4e1e0SJan Lentfer _nc_captoinfo(const char *cap, const char *s, int const parameterized) 282fdd4e1e0SJan Lentfer { 283fdd4e1e0SJan Lentfer const char *capstart; 284fdd4e1e0SJan Lentfer 285fdd4e1e0SJan Lentfer stackptr = 0; 286fdd4e1e0SJan Lentfer onstack = 0; 287fdd4e1e0SJan Lentfer seenm = 0; 288fdd4e1e0SJan Lentfer seenn = 0; 289fdd4e1e0SJan Lentfer seenr = 0; 290fdd4e1e0SJan Lentfer param = 1; 291fdd4e1e0SJan Lentfer 292fdd4e1e0SJan Lentfer dp = init_string(); 293fdd4e1e0SJan Lentfer 294fdd4e1e0SJan Lentfer /* skip the initial padding (if we haven't been told not to) */ 295fdd4e1e0SJan Lentfer capstart = 0; 296fdd4e1e0SJan Lentfer if (s == 0) 297fdd4e1e0SJan Lentfer s = ""; 298fdd4e1e0SJan Lentfer if (parameterized >= 0 && isdigit(UChar(*s))) 299fdd4e1e0SJan Lentfer for (capstart = s;; s++) 300fdd4e1e0SJan Lentfer if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.')) 301fdd4e1e0SJan Lentfer break; 302fdd4e1e0SJan Lentfer 303fdd4e1e0SJan Lentfer while (*s != '\0') { 304fdd4e1e0SJan Lentfer switch (*s) { 305fdd4e1e0SJan Lentfer case '%': 306fdd4e1e0SJan Lentfer s++; 307fdd4e1e0SJan Lentfer if (parameterized < 1) { 308fdd4e1e0SJan Lentfer dp = save_char(dp, '%'); 309fdd4e1e0SJan Lentfer break; 310fdd4e1e0SJan Lentfer } 311fdd4e1e0SJan Lentfer switch (*s++) { 312fdd4e1e0SJan Lentfer case '%': 313fdd4e1e0SJan Lentfer dp = save_char(dp, '%'); 314fdd4e1e0SJan Lentfer break; 315fdd4e1e0SJan Lentfer case 'r': 316fdd4e1e0SJan Lentfer if (seenr++ == 1) { 317fdd4e1e0SJan Lentfer _nc_warning("saw %%r twice in %s", cap); 318fdd4e1e0SJan Lentfer } 319fdd4e1e0SJan Lentfer break; 320fdd4e1e0SJan Lentfer case 'm': 321fdd4e1e0SJan Lentfer if (seenm++ == 1) { 322fdd4e1e0SJan Lentfer _nc_warning("saw %%m twice in %s", cap); 323fdd4e1e0SJan Lentfer } 324fdd4e1e0SJan Lentfer break; 325fdd4e1e0SJan Lentfer case 'n': 326fdd4e1e0SJan Lentfer if (seenn++ == 1) { 327fdd4e1e0SJan Lentfer _nc_warning("saw %%n twice in %s", cap); 328fdd4e1e0SJan Lentfer } 329fdd4e1e0SJan Lentfer break; 330fdd4e1e0SJan Lentfer case 'i': 331fdd4e1e0SJan Lentfer dp = save_string(dp, "%i"); 332fdd4e1e0SJan Lentfer break; 333fdd4e1e0SJan Lentfer case '6': 334fdd4e1e0SJan Lentfer case 'B': 335fdd4e1e0SJan Lentfer getparm(param, 1); 336fdd4e1e0SJan Lentfer dp = save_string(dp, "%{10}%/%{16}%*"); 337fdd4e1e0SJan Lentfer getparm(param, 1); 338fdd4e1e0SJan Lentfer dp = save_string(dp, "%{10}%m%+"); 339fdd4e1e0SJan Lentfer break; 340fdd4e1e0SJan Lentfer case '8': 341fdd4e1e0SJan Lentfer case 'D': 342fdd4e1e0SJan Lentfer getparm(param, 2); 343fdd4e1e0SJan Lentfer dp = save_string(dp, "%{2}%*%-"); 344fdd4e1e0SJan Lentfer break; 345fdd4e1e0SJan Lentfer case '>': 346fdd4e1e0SJan Lentfer getparm(param, 2); 347fdd4e1e0SJan Lentfer /* %?%{x}%>%t%{y}%+%; */ 348fdd4e1e0SJan Lentfer dp = save_string(dp, "%?"); 349fdd4e1e0SJan Lentfer s += cvtchar(s); 350fdd4e1e0SJan Lentfer dp = save_string(dp, "%>%t"); 351fdd4e1e0SJan Lentfer s += cvtchar(s); 352fdd4e1e0SJan Lentfer dp = save_string(dp, "%+%;"); 353fdd4e1e0SJan Lentfer break; 354fdd4e1e0SJan Lentfer case 'a': 355fdd4e1e0SJan Lentfer if ((*s == '=' || *s == '+' || *s == '-' 356fdd4e1e0SJan Lentfer || *s == '*' || *s == '/') 357fdd4e1e0SJan Lentfer && (s[1] == 'p' || s[1] == 'c') 358fdd4e1e0SJan Lentfer && s[2] != '\0') { 359fdd4e1e0SJan Lentfer int l; 360fdd4e1e0SJan Lentfer l = 2; 361fdd4e1e0SJan Lentfer if (*s != '=') 362fdd4e1e0SJan Lentfer getparm(param, 1); 363fdd4e1e0SJan Lentfer if (s[1] == 'p') { 364fdd4e1e0SJan Lentfer getparm(param + s[2] - '@', 1); 365fdd4e1e0SJan Lentfer if (param != onstack) { 366fdd4e1e0SJan Lentfer pop(); 367fdd4e1e0SJan Lentfer param--; 368fdd4e1e0SJan Lentfer } 369fdd4e1e0SJan Lentfer l++; 370fdd4e1e0SJan Lentfer } else 371fdd4e1e0SJan Lentfer l += cvtchar(s + 2); 372fdd4e1e0SJan Lentfer switch (*s) { 373fdd4e1e0SJan Lentfer case '+': 374fdd4e1e0SJan Lentfer dp = save_string(dp, "%+"); 375fdd4e1e0SJan Lentfer break; 376fdd4e1e0SJan Lentfer case '-': 377fdd4e1e0SJan Lentfer dp = save_string(dp, "%-"); 378fdd4e1e0SJan Lentfer break; 379fdd4e1e0SJan Lentfer case '*': 380fdd4e1e0SJan Lentfer dp = save_string(dp, "%*"); 381fdd4e1e0SJan Lentfer break; 382fdd4e1e0SJan Lentfer case '/': 383fdd4e1e0SJan Lentfer dp = save_string(dp, "%/"); 384fdd4e1e0SJan Lentfer break; 385fdd4e1e0SJan Lentfer case '=': 386fdd4e1e0SJan Lentfer if (seenr) { 387fdd4e1e0SJan Lentfer if (param == 1) 388fdd4e1e0SJan Lentfer onstack = 2; 389fdd4e1e0SJan Lentfer else if (param == 2) 390fdd4e1e0SJan Lentfer onstack = 1; 391fdd4e1e0SJan Lentfer else 392fdd4e1e0SJan Lentfer onstack = param; 393fdd4e1e0SJan Lentfer } else 394fdd4e1e0SJan Lentfer onstack = param; 395fdd4e1e0SJan Lentfer break; 396fdd4e1e0SJan Lentfer } 397fdd4e1e0SJan Lentfer s += l; 398fdd4e1e0SJan Lentfer break; 399fdd4e1e0SJan Lentfer } 400fdd4e1e0SJan Lentfer getparm(param, 1); 401fdd4e1e0SJan Lentfer s += cvtchar(s); 402fdd4e1e0SJan Lentfer dp = save_string(dp, "%+"); 403fdd4e1e0SJan Lentfer break; 404fdd4e1e0SJan Lentfer case '+': 405fdd4e1e0SJan Lentfer getparm(param, 1); 406fdd4e1e0SJan Lentfer s += cvtchar(s); 407fdd4e1e0SJan Lentfer dp = save_string(dp, "%+%c"); 408fdd4e1e0SJan Lentfer pop(); 409fdd4e1e0SJan Lentfer break; 410fdd4e1e0SJan Lentfer case 's': 411fdd4e1e0SJan Lentfer #ifdef WATERLOO 412fdd4e1e0SJan Lentfer s += cvtchar(s); 413fdd4e1e0SJan Lentfer getparm(param, 1); 414fdd4e1e0SJan Lentfer dp = save_string(dp, "%-"); 415fdd4e1e0SJan Lentfer #else 416fdd4e1e0SJan Lentfer getparm(param, 1); 417fdd4e1e0SJan Lentfer dp = save_string(dp, "%s"); 418fdd4e1e0SJan Lentfer pop(); 419fdd4e1e0SJan Lentfer #endif /* WATERLOO */ 420fdd4e1e0SJan Lentfer break; 421fdd4e1e0SJan Lentfer case '-': 422fdd4e1e0SJan Lentfer s += cvtchar(s); 423fdd4e1e0SJan Lentfer getparm(param, 1); 424fdd4e1e0SJan Lentfer dp = save_string(dp, "%-%c"); 425fdd4e1e0SJan Lentfer pop(); 426fdd4e1e0SJan Lentfer break; 427fdd4e1e0SJan Lentfer case '.': 428fdd4e1e0SJan Lentfer getparm(param, 1); 429fdd4e1e0SJan Lentfer dp = save_string(dp, "%c"); 430fdd4e1e0SJan Lentfer pop(); 431fdd4e1e0SJan Lentfer break; 432fdd4e1e0SJan Lentfer case '0': /* not clear any of the historical termcaps did this */ 433fdd4e1e0SJan Lentfer if (*s == '3') 434fdd4e1e0SJan Lentfer goto see03; 435fdd4e1e0SJan Lentfer else if (*s != '2') 436fdd4e1e0SJan Lentfer goto invalid; 437fdd4e1e0SJan Lentfer /* FALLTHRU */ 438fdd4e1e0SJan Lentfer case '2': 439fdd4e1e0SJan Lentfer getparm(param, 1); 440fdd4e1e0SJan Lentfer dp = save_string(dp, "%2d"); 441fdd4e1e0SJan Lentfer pop(); 442fdd4e1e0SJan Lentfer break; 443fdd4e1e0SJan Lentfer case '3': 444fdd4e1e0SJan Lentfer see03: 445fdd4e1e0SJan Lentfer getparm(param, 1); 446fdd4e1e0SJan Lentfer dp = save_string(dp, "%3d"); 447fdd4e1e0SJan Lentfer pop(); 448fdd4e1e0SJan Lentfer break; 449fdd4e1e0SJan Lentfer case 'd': 450fdd4e1e0SJan Lentfer getparm(param, 1); 451fdd4e1e0SJan Lentfer dp = save_string(dp, "%d"); 452fdd4e1e0SJan Lentfer pop(); 453fdd4e1e0SJan Lentfer break; 454fdd4e1e0SJan Lentfer case 'f': 455fdd4e1e0SJan Lentfer param++; 456fdd4e1e0SJan Lentfer break; 457fdd4e1e0SJan Lentfer case 'b': 458fdd4e1e0SJan Lentfer param--; 459fdd4e1e0SJan Lentfer break; 460fdd4e1e0SJan Lentfer case '\\': 461fdd4e1e0SJan Lentfer dp = save_string(dp, "%\\"); 462fdd4e1e0SJan Lentfer break; 463fdd4e1e0SJan Lentfer default: 464fdd4e1e0SJan Lentfer invalid: 465fdd4e1e0SJan Lentfer dp = save_char(dp, '%'); 466fdd4e1e0SJan Lentfer s--; 467fdd4e1e0SJan Lentfer _nc_warning("unknown %% code %s (%#x) in %s", 468fdd4e1e0SJan Lentfer unctrl((chtype) *s), UChar(*s), cap); 469fdd4e1e0SJan Lentfer break; 470fdd4e1e0SJan Lentfer } 471fdd4e1e0SJan Lentfer break; 472fdd4e1e0SJan Lentfer #ifdef REVISIBILIZE 473fdd4e1e0SJan Lentfer case '\\': 474fdd4e1e0SJan Lentfer dp = save_char(dp, *s++); 475fdd4e1e0SJan Lentfer dp = save_char(dp, *s++); 476fdd4e1e0SJan Lentfer break; 477fdd4e1e0SJan Lentfer case '\n': 478fdd4e1e0SJan Lentfer dp = save_string(dp, "\\n"); 479fdd4e1e0SJan Lentfer s++; 480fdd4e1e0SJan Lentfer break; 481fdd4e1e0SJan Lentfer case '\t': 482fdd4e1e0SJan Lentfer dp = save_string(dp, "\\t"); 483fdd4e1e0SJan Lentfer s++; 484fdd4e1e0SJan Lentfer break; 485fdd4e1e0SJan Lentfer case '\r': 486fdd4e1e0SJan Lentfer dp = save_string(dp, "\\r"); 487fdd4e1e0SJan Lentfer s++; 488fdd4e1e0SJan Lentfer break; 489fdd4e1e0SJan Lentfer case '\200': 490fdd4e1e0SJan Lentfer dp = save_string(dp, "\\0"); 491fdd4e1e0SJan Lentfer s++; 492fdd4e1e0SJan Lentfer break; 493fdd4e1e0SJan Lentfer case '\f': 494fdd4e1e0SJan Lentfer dp = save_string(dp, "\\f"); 495fdd4e1e0SJan Lentfer s++; 496fdd4e1e0SJan Lentfer break; 497fdd4e1e0SJan Lentfer case '\b': 498fdd4e1e0SJan Lentfer dp = save_string(dp, "\\b"); 499fdd4e1e0SJan Lentfer s++; 500fdd4e1e0SJan Lentfer break; 501fdd4e1e0SJan Lentfer case ' ': 502fdd4e1e0SJan Lentfer dp = save_string(dp, "\\s"); 503fdd4e1e0SJan Lentfer s++; 504fdd4e1e0SJan Lentfer break; 505fdd4e1e0SJan Lentfer case '^': 506fdd4e1e0SJan Lentfer dp = save_string(dp, "\\^"); 507fdd4e1e0SJan Lentfer s++; 508fdd4e1e0SJan Lentfer break; 509fdd4e1e0SJan Lentfer case ':': 510fdd4e1e0SJan Lentfer dp = save_string(dp, "\\:"); 511fdd4e1e0SJan Lentfer s++; 512fdd4e1e0SJan Lentfer break; 513fdd4e1e0SJan Lentfer case ',': 514fdd4e1e0SJan Lentfer dp = save_string(dp, "\\,"); 515fdd4e1e0SJan Lentfer s++; 516fdd4e1e0SJan Lentfer break; 517fdd4e1e0SJan Lentfer default: 518fdd4e1e0SJan Lentfer if (*s == '\033') { 519fdd4e1e0SJan Lentfer dp = save_string(dp, "\\E"); 520fdd4e1e0SJan Lentfer s++; 521fdd4e1e0SJan Lentfer } else if (*s > 0 && *s < 32) { 522fdd4e1e0SJan Lentfer dp = save_char(dp, '^'); 523fdd4e1e0SJan Lentfer dp = save_char(dp, *s + '@'); 524fdd4e1e0SJan Lentfer s++; 525fdd4e1e0SJan Lentfer } else if (*s <= 0 || *s >= 127) { 526fdd4e1e0SJan Lentfer dp = save_char(dp, '\\'); 527fdd4e1e0SJan Lentfer dp = save_char(dp, ((*s & 0300) >> 6) + '0'); 528fdd4e1e0SJan Lentfer dp = save_char(dp, ((*s & 0070) >> 3) + '0'); 529fdd4e1e0SJan Lentfer dp = save_char(dp, (*s & 0007) + '0'); 530fdd4e1e0SJan Lentfer s++; 531fdd4e1e0SJan Lentfer } else 532fdd4e1e0SJan Lentfer dp = save_char(dp, *s++); 533fdd4e1e0SJan Lentfer break; 534fdd4e1e0SJan Lentfer #else 535fdd4e1e0SJan Lentfer default: 536fdd4e1e0SJan Lentfer dp = save_char(dp, *s++); 537fdd4e1e0SJan Lentfer break; 538fdd4e1e0SJan Lentfer #endif 539fdd4e1e0SJan Lentfer } 540fdd4e1e0SJan Lentfer } 541fdd4e1e0SJan Lentfer 542fdd4e1e0SJan Lentfer /* 543fdd4e1e0SJan Lentfer * Now, if we stripped off some leading padding, add it at the end 544fdd4e1e0SJan Lentfer * of the string as mandatory padding. 545fdd4e1e0SJan Lentfer */ 546fdd4e1e0SJan Lentfer if (capstart) { 547fdd4e1e0SJan Lentfer dp = save_string(dp, "$<"); 548fdd4e1e0SJan Lentfer for (s = capstart;; s++) 549fdd4e1e0SJan Lentfer if (isdigit(UChar(*s)) || *s == '*' || *s == '.') 550fdd4e1e0SJan Lentfer dp = save_char(dp, *s); 551fdd4e1e0SJan Lentfer else 552fdd4e1e0SJan Lentfer break; 553fdd4e1e0SJan Lentfer dp = save_string(dp, "/>"); 554fdd4e1e0SJan Lentfer } 555fdd4e1e0SJan Lentfer 556fdd4e1e0SJan Lentfer (void) save_char(dp, '\0'); 557fdd4e1e0SJan Lentfer return (my_string); 558fdd4e1e0SJan Lentfer } 559fdd4e1e0SJan Lentfer 560fdd4e1e0SJan Lentfer /* 561fdd4e1e0SJan Lentfer * Check for an expression that corresponds to "%B" (BCD): 562fdd4e1e0SJan Lentfer * (parameter / 10) * 16 + (parameter % 10) 563fdd4e1e0SJan Lentfer */ 564fdd4e1e0SJan Lentfer static int 565fdd4e1e0SJan Lentfer bcd_expression(const char *str) 566fdd4e1e0SJan Lentfer { 567fdd4e1e0SJan Lentfer /* leave this non-const for HPUX */ 568fdd4e1e0SJan Lentfer static char fmt[] = "%%p%c%%{10}%%/%%{16}%%*%%p%c%%{10}%%m%%+"; 569fdd4e1e0SJan Lentfer int len = 0; 570fdd4e1e0SJan Lentfer char ch1, ch2; 571fdd4e1e0SJan Lentfer 572fdd4e1e0SJan Lentfer if (sscanf(str, fmt, &ch1, &ch2) == 2 573fdd4e1e0SJan Lentfer && isdigit(UChar(ch1)) 574fdd4e1e0SJan Lentfer && isdigit(UChar(ch2)) 575fdd4e1e0SJan Lentfer && (ch1 == ch2)) { 576fdd4e1e0SJan Lentfer len = 28; 577fdd4e1e0SJan Lentfer #ifndef NDEBUG 578fdd4e1e0SJan Lentfer { 579fdd4e1e0SJan Lentfer char buffer[80]; 580fdd4e1e0SJan Lentfer int tst; 581fdd4e1e0SJan Lentfer sprintf(buffer, fmt, ch1, ch2); 582fdd4e1e0SJan Lentfer tst = strlen(buffer) - 1; 583fdd4e1e0SJan Lentfer assert(len == tst); 584fdd4e1e0SJan Lentfer } 585fdd4e1e0SJan Lentfer #endif 586fdd4e1e0SJan Lentfer } 587fdd4e1e0SJan Lentfer return len; 588fdd4e1e0SJan Lentfer } 589fdd4e1e0SJan Lentfer 590fdd4e1e0SJan Lentfer static char * 591fdd4e1e0SJan Lentfer save_tc_char(char *bufptr, int c1) 592fdd4e1e0SJan Lentfer { 593fdd4e1e0SJan Lentfer char temp[80]; 594fdd4e1e0SJan Lentfer 595fdd4e1e0SJan Lentfer if (is7bits(c1) && isprint(c1)) { 596fdd4e1e0SJan Lentfer if (c1 == ':' || c1 == '\\') 597fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, '\\'); 598fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, c1); 599fdd4e1e0SJan Lentfer } else { 600fdd4e1e0SJan Lentfer if (c1 == (c1 & 0x1f)) /* iscntrl() returns T on 255 */ 601fdd4e1e0SJan Lentfer (void) strcpy(temp, unctrl((chtype) c1)); 602fdd4e1e0SJan Lentfer else 603fdd4e1e0SJan Lentfer (void) sprintf(temp, "\\%03o", c1); 604fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, temp); 605fdd4e1e0SJan Lentfer } 606fdd4e1e0SJan Lentfer return bufptr; 607fdd4e1e0SJan Lentfer } 608fdd4e1e0SJan Lentfer 609fdd4e1e0SJan Lentfer static char * 610fdd4e1e0SJan Lentfer save_tc_inequality(char *bufptr, int c1, int c2) 611fdd4e1e0SJan Lentfer { 612fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%>"); 613fdd4e1e0SJan Lentfer bufptr = save_tc_char(bufptr, c1); 614fdd4e1e0SJan Lentfer bufptr = save_tc_char(bufptr, c2); 615fdd4e1e0SJan Lentfer return bufptr; 616fdd4e1e0SJan Lentfer } 617fdd4e1e0SJan Lentfer 618fdd4e1e0SJan Lentfer /* 619fdd4e1e0SJan Lentfer * Here are the capabilities infotocap assumes it can translate to: 620fdd4e1e0SJan Lentfer * 621fdd4e1e0SJan Lentfer * %% output `%' 622fdd4e1e0SJan Lentfer * %d output value as in printf %d 623fdd4e1e0SJan Lentfer * %2 output value as in printf %2d 624fdd4e1e0SJan Lentfer * %3 output value as in printf %3d 625fdd4e1e0SJan Lentfer * %. output value as in printf %c 626fdd4e1e0SJan Lentfer * %+c add character c to value, then do %. 627fdd4e1e0SJan Lentfer * %>xy if value > x then add y, no output 628fdd4e1e0SJan Lentfer * %r reverse order of two parameters, no output 629fdd4e1e0SJan Lentfer * %i increment by one, no output 630fdd4e1e0SJan Lentfer * %n exclusive-or all parameters with 0140 (Datamedia 2500) 631fdd4e1e0SJan Lentfer * %B BCD (16*(value/10)) + (value%10), no output 632fdd4e1e0SJan Lentfer * %D Reverse coding (value - 2*(value%16)), no output (Delta Data). 633fdd4e1e0SJan Lentfer * %m exclusive-or all parameters with 0177 (not in 4.4BSD) 634fdd4e1e0SJan Lentfer */ 635fdd4e1e0SJan Lentfer 636fdd4e1e0SJan Lentfer /* 637fdd4e1e0SJan Lentfer * Convert a terminfo string to termcap format. Parameters are as in 638fdd4e1e0SJan Lentfer * _nc_captoinfo(). 639fdd4e1e0SJan Lentfer */ 6401d102085SJan Lentfer NCURSES_EXPORT(char *) 641fdd4e1e0SJan Lentfer _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized) 642fdd4e1e0SJan Lentfer { 643fdd4e1e0SJan Lentfer int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0; 644fdd4e1e0SJan Lentfer const char *padding; 645fdd4e1e0SJan Lentfer const char *trimmed = 0; 646*00d8f3c4SJohn Marino int in0, in1, in2; 647fdd4e1e0SJan Lentfer char ch1 = 0, ch2 = 0; 648fdd4e1e0SJan Lentfer char *bufptr = init_string(); 649fdd4e1e0SJan Lentfer int len; 650fdd4e1e0SJan Lentfer bool syntax_error = FALSE; 651fdd4e1e0SJan Lentfer 652fdd4e1e0SJan Lentfer /* we may have to move some trailing mandatory padding up front */ 653fdd4e1e0SJan Lentfer padding = str + strlen(str) - 1; 654fdd4e1e0SJan Lentfer if (padding > str && *padding == '>' && *--padding == '/') { 655fdd4e1e0SJan Lentfer --padding; 656fdd4e1e0SJan Lentfer while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*') 657fdd4e1e0SJan Lentfer padding--; 658fdd4e1e0SJan Lentfer if (padding > str && *padding == '<' && *--padding == '$') 659fdd4e1e0SJan Lentfer trimmed = padding; 660fdd4e1e0SJan Lentfer padding += 2; 661fdd4e1e0SJan Lentfer 662fdd4e1e0SJan Lentfer while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*') 663fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, *padding++); 664fdd4e1e0SJan Lentfer } 665fdd4e1e0SJan Lentfer 666fdd4e1e0SJan Lentfer for (; *str && str != trimmed; str++) { 667fdd4e1e0SJan Lentfer int c1, c2; 668fdd4e1e0SJan Lentfer char *cp = 0; 669fdd4e1e0SJan Lentfer 670*00d8f3c4SJohn Marino if (str[0] == '^') { 671*00d8f3c4SJohn Marino if (str[1] == '\0' || (str + 1) == trimmed) { 672*00d8f3c4SJohn Marino bufptr = save_string(bufptr, "\\136"); 673*00d8f3c4SJohn Marino ++str; 674*00d8f3c4SJohn Marino } else { 675*00d8f3c4SJohn Marino bufptr = save_char(bufptr, *str++); 676*00d8f3c4SJohn Marino bufptr = save_char(bufptr, *str); 677*00d8f3c4SJohn Marino } 678*00d8f3c4SJohn Marino } else if (str[0] == '\\') { 679*00d8f3c4SJohn Marino if (str[1] == '\0' || (str + 1) == trimmed) { 680*00d8f3c4SJohn Marino bufptr = save_string(bufptr, "\\134"); 681*00d8f3c4SJohn Marino ++str; 682*00d8f3c4SJohn Marino } else if (str[1] == '^') { 683*00d8f3c4SJohn Marino bufptr = save_string(bufptr, "\\136"); 684*00d8f3c4SJohn Marino ++str; 685*00d8f3c4SJohn Marino } else if (str[1] == ',') { 686fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, *++str); 687*00d8f3c4SJohn Marino } else { 688*00d8f3c4SJohn Marino bufptr = save_char(bufptr, *str++); 689*00d8f3c4SJohn Marino bufptr = save_char(bufptr, *str); 690*00d8f3c4SJohn Marino } 691fdd4e1e0SJan Lentfer } else if (str[0] == '$' && str[1] == '<') { /* discard padding */ 692fdd4e1e0SJan Lentfer str += 2; 693fdd4e1e0SJan Lentfer while (isdigit(UChar(*str)) 694fdd4e1e0SJan Lentfer || *str == '.' 695fdd4e1e0SJan Lentfer || *str == '*' 696fdd4e1e0SJan Lentfer || *str == '/' 697fdd4e1e0SJan Lentfer || *str == '>') 698fdd4e1e0SJan Lentfer str++; 699fdd4e1e0SJan Lentfer --str; 700*00d8f3c4SJohn Marino } else if (sscanf(str, 701*00d8f3c4SJohn Marino "[%%?%%p1%%{8}%%<%%t%d%%p1%%d%%e%%p1%%{16}%%<%%t%d%%p1%%{8}%%-%%d%%e%d;5;%%p1%%d%%;m", 702*00d8f3c4SJohn Marino &in0, &in1, &in2) == 3 703*00d8f3c4SJohn Marino && ((in0 == 4 && in1 == 10 && in2 == 48) 704*00d8f3c4SJohn Marino || (in0 == 3 && in1 == 9 && in2 == 38))) { 705*00d8f3c4SJohn Marino /* dumb-down an optimized case from xterm-256color for termcap */ 706*00d8f3c4SJohn Marino str = strstr(str, ";m"); 707*00d8f3c4SJohn Marino ++str; 708*00d8f3c4SJohn Marino if (in2 == 48) { 709*00d8f3c4SJohn Marino bufptr = save_string(bufptr, "[48;5;%dm"); 710*00d8f3c4SJohn Marino } else { 711*00d8f3c4SJohn Marino bufptr = save_string(bufptr, "[38;5;%dm"); 712*00d8f3c4SJohn Marino } 713fdd4e1e0SJan Lentfer } else if (str[0] == '%' && str[1] == '%') { /* escaped '%' */ 714fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%%"); 7151d102085SJan Lentfer ++str; 716fdd4e1e0SJan Lentfer } else if (*str != '%' || (parameterized < 1)) { 717fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, *str); 718fdd4e1e0SJan Lentfer } else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1, &c2) == 2) { 719fdd4e1e0SJan Lentfer str = strchr(str, ';'); 720fdd4e1e0SJan Lentfer bufptr = save_tc_inequality(bufptr, c1, c2); 721fdd4e1e0SJan Lentfer } else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1, &ch2) == 2) { 722fdd4e1e0SJan Lentfer str = strchr(str, ';'); 723fdd4e1e0SJan Lentfer bufptr = save_tc_inequality(bufptr, c1, c2); 724fdd4e1e0SJan Lentfer } else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1, &c2) == 2) { 725fdd4e1e0SJan Lentfer str = strchr(str, ';'); 726fdd4e1e0SJan Lentfer bufptr = save_tc_inequality(bufptr, c1, c2); 727fdd4e1e0SJan Lentfer } else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2) { 728fdd4e1e0SJan Lentfer str = strchr(str, ';'); 729fdd4e1e0SJan Lentfer bufptr = save_tc_inequality(bufptr, c1, c2); 730fdd4e1e0SJan Lentfer } else if ((len = bcd_expression(str)) != 0) { 731fdd4e1e0SJan Lentfer str += len; 732fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%B"); 733fdd4e1e0SJan Lentfer } else if ((sscanf(str, "%%{%d}%%+%%c", &c1) == 1 734fdd4e1e0SJan Lentfer || sscanf(str, "%%'%c'%%+%%c", &ch1) == 1) 735fdd4e1e0SJan Lentfer && (cp = strchr(str, '+'))) { 736fdd4e1e0SJan Lentfer str = cp + 2; 737fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%+"); 738fdd4e1e0SJan Lentfer 739fdd4e1e0SJan Lentfer if (ch1) 740fdd4e1e0SJan Lentfer c1 = ch1; 741fdd4e1e0SJan Lentfer bufptr = save_tc_char(bufptr, c1); 742fdd4e1e0SJan Lentfer } 743fdd4e1e0SJan Lentfer /* FIXME: this "works" for 'delta' */ 744fdd4e1e0SJan Lentfer else if (strncmp(str, "%{2}%*%-", 8) == 0) { 745fdd4e1e0SJan Lentfer str += 7; 746fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%D"); 747fdd4e1e0SJan Lentfer } else if (strncmp(str, "%{96}%^", 7) == 0) { 748fdd4e1e0SJan Lentfer str += 6; 749fdd4e1e0SJan Lentfer if (saw_m++ == 0) { 750fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%n"); 751fdd4e1e0SJan Lentfer } 752fdd4e1e0SJan Lentfer } else if (strncmp(str, "%{127}%^", 8) == 0) { 753fdd4e1e0SJan Lentfer str += 7; 754fdd4e1e0SJan Lentfer if (saw_n++ == 0) { 755fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%m"); 756fdd4e1e0SJan Lentfer } 757fdd4e1e0SJan Lentfer } else { /* cm-style format element */ 758fdd4e1e0SJan Lentfer str++; 759fdd4e1e0SJan Lentfer switch (*str) { 760fdd4e1e0SJan Lentfer case '%': 761fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, '%'); 762fdd4e1e0SJan Lentfer break; 763fdd4e1e0SJan Lentfer 764fdd4e1e0SJan Lentfer case '0': 765fdd4e1e0SJan Lentfer case '1': 766fdd4e1e0SJan Lentfer case '2': 767fdd4e1e0SJan Lentfer case '3': 768fdd4e1e0SJan Lentfer case '4': 769fdd4e1e0SJan Lentfer case '5': 770fdd4e1e0SJan Lentfer case '6': 771fdd4e1e0SJan Lentfer case '7': 772fdd4e1e0SJan Lentfer case '8': 773fdd4e1e0SJan Lentfer case '9': 774fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, '%'); 775fdd4e1e0SJan Lentfer while (isdigit(UChar(*str))) 776fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, *str++); 777fdd4e1e0SJan Lentfer if (strchr("doxX.", *str)) { 778fdd4e1e0SJan Lentfer if (*str != 'd') /* termcap doesn't have octal, hex */ 779fdd4e1e0SJan Lentfer return 0; 780fdd4e1e0SJan Lentfer } 781fdd4e1e0SJan Lentfer break; 782fdd4e1e0SJan Lentfer 783fdd4e1e0SJan Lentfer case 'd': 784fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%d"); 785fdd4e1e0SJan Lentfer break; 786fdd4e1e0SJan Lentfer 787fdd4e1e0SJan Lentfer case 'c': 788fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%."); 789fdd4e1e0SJan Lentfer break; 790fdd4e1e0SJan Lentfer 791fdd4e1e0SJan Lentfer /* 792fdd4e1e0SJan Lentfer * %s isn't in termcap, but it's convenient to pass it through 793fdd4e1e0SJan Lentfer * so we can represent things like terminfo pfkey strings in 794fdd4e1e0SJan Lentfer * termcap notation. 795fdd4e1e0SJan Lentfer */ 796fdd4e1e0SJan Lentfer case 's': 797fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%s"); 798fdd4e1e0SJan Lentfer break; 799fdd4e1e0SJan Lentfer 800fdd4e1e0SJan Lentfer case 'p': 801fdd4e1e0SJan Lentfer str++; 802fdd4e1e0SJan Lentfer if (*str == '1') 803fdd4e1e0SJan Lentfer seenone = 1; 804fdd4e1e0SJan Lentfer else if (*str == '2') { 805fdd4e1e0SJan Lentfer if (!seenone && !seentwo) { 806fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%r"); 807fdd4e1e0SJan Lentfer seentwo++; 808fdd4e1e0SJan Lentfer } 809fdd4e1e0SJan Lentfer } else if (*str >= '3') 810fdd4e1e0SJan Lentfer return (0); 811fdd4e1e0SJan Lentfer break; 812fdd4e1e0SJan Lentfer 813fdd4e1e0SJan Lentfer case 'i': 814fdd4e1e0SJan Lentfer bufptr = save_string(bufptr, "%i"); 815fdd4e1e0SJan Lentfer break; 816fdd4e1e0SJan Lentfer 817fdd4e1e0SJan Lentfer default: 818fdd4e1e0SJan Lentfer bufptr = save_char(bufptr, *str); 819fdd4e1e0SJan Lentfer syntax_error = TRUE; 820fdd4e1e0SJan Lentfer break; 821fdd4e1e0SJan Lentfer } /* endswitch (*str) */ 822fdd4e1e0SJan Lentfer } /* endelse (*str == '%') */ 823fdd4e1e0SJan Lentfer 8241d102085SJan Lentfer /* 8251d102085SJan Lentfer * 'str' always points to the end of what was scanned in this step, 8261d102085SJan Lentfer * but that may not be the end of the string. 8271d102085SJan Lentfer */ 8281d102085SJan Lentfer assert(str != 0); 829fdd4e1e0SJan Lentfer if (*str == '\0') 830fdd4e1e0SJan Lentfer break; 831fdd4e1e0SJan Lentfer 832fdd4e1e0SJan Lentfer } /* endwhile (*str) */ 833fdd4e1e0SJan Lentfer 834fdd4e1e0SJan Lentfer return (syntax_error ? NULL : my_string); 835fdd4e1e0SJan Lentfer } 836fdd4e1e0SJan Lentfer 837fdd4e1e0SJan Lentfer #ifdef MAIN 838fdd4e1e0SJan Lentfer 839fdd4e1e0SJan Lentfer int curr_line; 840fdd4e1e0SJan Lentfer 841fdd4e1e0SJan Lentfer int 842fdd4e1e0SJan Lentfer main(int argc, char *argv[]) 843fdd4e1e0SJan Lentfer { 844fdd4e1e0SJan Lentfer int c, tc = FALSE; 845fdd4e1e0SJan Lentfer 846fdd4e1e0SJan Lentfer while ((c = getopt(argc, argv, "c")) != EOF) 847fdd4e1e0SJan Lentfer switch (c) { 848fdd4e1e0SJan Lentfer case 'c': 849fdd4e1e0SJan Lentfer tc = TRUE; 850fdd4e1e0SJan Lentfer break; 851fdd4e1e0SJan Lentfer } 852fdd4e1e0SJan Lentfer 853fdd4e1e0SJan Lentfer curr_line = 0; 854fdd4e1e0SJan Lentfer for (;;) { 855fdd4e1e0SJan Lentfer char buf[BUFSIZ]; 856fdd4e1e0SJan Lentfer 857fdd4e1e0SJan Lentfer ++curr_line; 858fdd4e1e0SJan Lentfer if (fgets(buf, sizeof(buf), stdin) == 0) 859fdd4e1e0SJan Lentfer break; 860fdd4e1e0SJan Lentfer buf[strlen(buf) - 1] = '\0'; 861fdd4e1e0SJan Lentfer _nc_set_source(buf); 862fdd4e1e0SJan Lentfer 863fdd4e1e0SJan Lentfer if (tc) { 864fdd4e1e0SJan Lentfer char *cp = _nc_infotocap("to termcap", buf, 1); 865fdd4e1e0SJan Lentfer 866fdd4e1e0SJan Lentfer if (cp) 867fdd4e1e0SJan Lentfer (void) fputs(cp, stdout); 868fdd4e1e0SJan Lentfer } else 869fdd4e1e0SJan Lentfer (void) fputs(_nc_captoinfo("to terminfo", buf, 1), stdout); 870fdd4e1e0SJan Lentfer (void) putchar('\n'); 871fdd4e1e0SJan Lentfer } 872fdd4e1e0SJan Lentfer return (0); 873fdd4e1e0SJan Lentfer } 874fdd4e1e0SJan Lentfer #endif /* MAIN */ 875fdd4e1e0SJan Lentfer 8761d102085SJan Lentfer #if NO_LEAKS 8771d102085SJan Lentfer NCURSES_EXPORT(void) 8781d102085SJan Lentfer _nc_captoinfo_leaks(void) 8791d102085SJan Lentfer { 8801d102085SJan Lentfer if (my_string != 0) { 8811d102085SJan Lentfer FreeAndNull(my_string); 8821d102085SJan Lentfer } 8831d102085SJan Lentfer my_length = 0; 8841d102085SJan Lentfer } 8851d102085SJan Lentfer #endif 886