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