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