home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / mytinfo / part03 < prev    next >
Encoding:
Text File  |  1992-12-26  |  62.2 KB  |  3,149 lines

  1. Newsgroups: comp.sources.unix
  2. From: ross@zooid.guild.org (Ross Ridge)
  3. Subject: v26i079: mytinfo - a replacement for terminfo and termcap, Part03/03
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: ross@zooid.guild.org (Ross Ridge)
  8. Posting-Number: Volume 26, Issue 79
  9. Archive-Name: mytinfo/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 3)."
  18. # Contents:  tconv.c tparm.c tset.c
  19. # Wrapped by vixie@cognition.pa.dec.com on Sun Dec 27 14:45:20 1992
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'tconv.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'tconv.c'\"
  23. else
  24. echo shar: Extracting \"'tconv.c'\" \(26474 characters\)
  25. sed "s/^X//" >'tconv.c' <<'END_OF_FILE'
  26. X/*
  27. X * tconv.c
  28. X *
  29. X * Ross Ridge 
  30. X * Public Domain
  31. X * 92/02/01 07:30:23
  32. X *
  33. X * tconv [-b] [-c [-OUGd]] [-i] [-B [-D dir]] [-I] [-k] [-V] [-t term] [file]
  34. X *
  35. X * -c        convert from termcap
  36. X * -i        convert from terminfo source
  37. X * -b        convert from terminfo binary
  38. X * -B        convert to terminfo binary
  39. X * -I        convert to terminfo source
  40. X * -V        print version info
  41. X *
  42. X * The following switches are available when converting from termcap:
  43. X * -d        don't supply any defaults for missing capabilities
  44. X * -O        include obsolete termcap capabilities
  45. X * -G        include GNU capabilities
  46. X * -U        include UW capabilities
  47. X *
  48. X * -k        keep comments
  49. X * -D dir    directory to put terminfo binaries in
  50. X *
  51. X * -t term    name of terminal to translate
  52. X * file        filename of termcap/terminfo database to use 
  53. X *
  54. X * If a file is specifed and no terminal is given the entire file we be
  55. X * translated.
  56. X * If no terminal and no file is specified then the terminal name will be
  57. X * taken from the environment variable TERM.
  58. X * Unless compiling to a terminfo binary, output is to stdout.
  59. X *
  60. X */
  61. X
  62. X#define NOTLIB
  63. X#include "defs.h"
  64. X#define SINGLE
  65. X#include "term.h"
  66. X
  67. X#include <ctype.h>
  68. X#include <fcntl.h>
  69. X#ifdef USE_STDDEF
  70. X#include <sys/types.h>
  71. X#endif
  72. X#include <sys/stat.h>
  73. X
  74. X#include "strtok.c"
  75. X#include "mkdir.c"
  76. X
  77. X#ifndef lint
  78. static const char SCCSid[] = "@(#) mytinfo tconv.c 3.2 92/02/01 public domain, By Ross Ridge";
  79. X#endif
  80. X
  81. extern int errno;
  82. X
  83. X/* the right margin of the output */
  84. X#define LINELEN 76
  85. X
  86. struct term_path *path;    /* returned from _buildpath */
  87. X
  88. TERMINAL _term_buf;
  89. char buf[MAX_BUF+1];    /* buffer for the termcap entry */
  90. X
  91. int noOT = 1;        /* -O */
  92. int noGNU = 1;        /* -G */
  93. int noUW = 1;        /* -W */
  94. int dodefault = 1;    /* -d */
  95. int keepcomments = 0;    /* -k */
  96. int compile = 0;    /* -B */
  97. int from_tcap = 0;    /* -c */
  98. int from_tinfo = 0;    /* -i */
  99. int from_tbin = 0;    /* -b */
  100. char *directory = NULL; /* -D */
  101. X
  102. int continued = 0;
  103. int termcap = 1;
  104. X
  105. int lineno = 0;        /* current line number */
  106. X
  107. X/* print the first part of a warning message */
  108. void
  109. warn() {
  110. X    if (lineno == 0)
  111. X        fprintf(stderr, "warning: ");
  112. X    else
  113. X        fprintf(stderr, "(%s)%d: warning: ",
  114. X            _term_buf.name_long, lineno);
  115. X}
  116. X
  117. X/* output a string indenting at the beginning of a line, and wraping
  118. X * at the right margin. 
  119. X */
  120. void
  121. putstr(s)
  122. char *s; {
  123. X    static pos = 0;
  124. X    int l;
  125. X
  126. X    if (s == NULL) {
  127. X        if (pos != 0) {
  128. X            pos = 0;
  129. X            putchar('\n');
  130. X        }
  131. X        return;
  132. X    }
  133. X    
  134. X    if (termcap && noOT && *s == 'O')
  135. X        return;
  136. X    if (termcap && noGNU && *s == 'G')
  137. X        return;
  138. X    if (termcap && noUW && *s == 'U')
  139. X        return;
  140. X
  141. X    l = strlen(s) + 2;
  142. X
  143. X    if (l + pos > LINELEN && pos != 0) {
  144. X        putchar('\n');
  145. X        pos = 0;
  146. X    }
  147. X
  148. X    if (pos == 0) {
  149. X        putchar('\t');
  150. X        pos = 8;
  151. X    } else
  152. X        putchar(' ');
  153. X
  154. X    printf("%s,", s);
  155. X
  156. X    pos += l;
  157. X}
  158. X
  159. X#ifndef MAX_PUSHED
  160. X/* maximum # of parameters that can be pushed onto the stack */
  161. X#define MAX_PUSHED 16
  162. X#endif
  163. X
  164. int stack[MAX_PUSHED];    /* the stack */
  165. int stackptr;        /* the next empty place on the stack */
  166. int onstack;        /* the top of stack */
  167. int seenm;        /* seen a %m */
  168. int seenn;        /* seen a %n */
  169. int seenr;        /* seen a %r */
  170. int param;        /* current parameter */
  171. char *dp;        /* pointer to the end of the converted string */
  172. X
  173. X/* push onstack on to the stack */
  174. void
  175. push() {
  176. X    if (stackptr > MAX_PUSHED) {
  177. X        warn();
  178. X        fprintf(stderr, "string to complex to covert\n");
  179. X    } else
  180. X        stack[stackptr++] = onstack;
  181. X}
  182. X
  183. X/* pop the top of the stack into onstack */
  184. void
  185. pop() {
  186. X    if (stackptr == 0) 
  187. X        if (onstack == 0) {
  188. X            warn();
  189. X            fprintf(stderr, "I'm confused\n");
  190. X        } else
  191. X            onstack = 0;
  192. X    else
  193. X        onstack = stack[--stackptr];
  194. X    param++;
  195. X}
  196. X
  197. X/* convert a character to a terminfo push */
  198. static int
  199. cvtchar(sp)
  200. register char *sp; {
  201. X    char c;
  202. X    int l;
  203. X
  204. X    switch(*sp) {
  205. X    case '\\':
  206. X        switch(*++sp) {
  207. X        case '\'':
  208. X        case '$':
  209. X        case '\\':
  210. X        case '%':
  211. X            c = *sp;
  212. X            l = 2;
  213. X            break;
  214. X        case '\0':
  215. X            c = '\\';
  216. X            l = 1;
  217. X            break;
  218. X        case '0':
  219. X            if (sp[1] == '0' && sp[2] == '0') {
  220. X                c = '\0';
  221. X                l = 4;
  222. X            } else {
  223. X                c = '\200'; /* '\0' ???? */
  224. X                l = 2;
  225. X            }
  226. X            break;
  227. X        default:
  228. X            c = *sp;
  229. X            l = 2;
  230. X            break;
  231. X        }
  232. X        break;
  233. X    default:
  234. X        c = *sp;
  235. X        l = 1;
  236. X    }
  237. X    c &= 0177;
  238. X    if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
  239. X        *dp++ = '%'; *dp++ = '\''; *dp++ = c; *dp++ = '\'';
  240. X    } else {
  241. X        *dp++ = '%'; *dp++ = '{';
  242. X        if (c > 99)
  243. X            *dp++ = c / 100 + '0';
  244. X        if (c > 9)
  245. X            *dp++ = (c / 10) % 10 + '0';
  246. X        *dp++ = c % 10 + '0';
  247. X        *dp++ = '}';
  248. X    }
  249. X    return l;
  250. X}
  251. X
  252. X/* push n copies of param on the terminfo stack if not already there */
  253. void
  254. getparm(parm, n)
  255. int parm;
  256. int n; {
  257. X    if (seenr)  {
  258. X        if (parm == 1)
  259. X            parm = 2;
  260. X        else if (parm == 2)
  261. X            parm = 1;
  262. X    }
  263. X    if (onstack == parm) {
  264. X        if (n > 1) {
  265. X            warn();
  266. X            fprintf(stderr, "string may not be optimal");
  267. X            *dp++ = '%'; *dp++ = 'P'; *dp++ = 'a';
  268. X            while(n--) {
  269. X                *dp++ = '%'; *dp++ = 'g'; *dp++ = 'a';
  270. X            }
  271. X        }
  272. X        return;
  273. X    }
  274. X    if (onstack != 0)
  275. X        push();
  276. X
  277. X    onstack = parm;
  278. X    
  279. X    while(n--) {        /* %p0 */
  280. X        *dp++ = '%'; *dp++ = 'p'; *dp++ = '0' + parm;
  281. X    }
  282. X
  283. X    if (seenn && parm < 3) { /* %{96}%^ */
  284. X        *dp++ = '%'; *dp++ = '{'; *dp++ = '9'; *dp++ = '6'; *dp++ = '}';
  285. X        *dp++ = '%'; *dp++ = '^';
  286. X    }
  287. X    
  288. X    if (seenm && parm < 3) { /* %{127}%^ */
  289. X        *dp++ = '%'; *dp++ = '{'; *dp++ = '1'; *dp++ = '2'; *dp++ = '7';
  290. X        *dp++ = '}'; *dp++ = '%'; *dp++ = '^';
  291. X    }
  292. X}
  293. X
  294. X/* convert a string to terminfo format */
  295. char *
  296. convstr(s, i)
  297. register char *s;
  298. int i; {
  299. X    static char line[MAX_LINE];
  300. X    register char *cap;
  301. X    int nocode = 0;
  302. X
  303. X    stackptr = 0;
  304. X    onstack = 0;
  305. X    seenm = 0;
  306. X    seenn = 0;
  307. X    seenr = 0;
  308. X    param = 1;
  309. X
  310. X    dp = line;
  311. X    cap = strnames[i];
  312. X#if 0
  313. X    if (cap[0] == 'k'
  314. X        || ((cap[0] == 'i' || cap[0] == 'r') && cap[1] == 's'
  315. X        && (cap[2] == '1' || cap[2] == '2' || cap[2] == '3')))
  316. X    /* if (k.* || [ir]s[123]) */
  317. X        nocode = 1;
  318. X#else
  319. X    if (_strflags[i] != 'G')
  320. X        nocode = 1;
  321. X#endif
  322. X    if (!nocode) {
  323. X        char *d = s;
  324. X        while(*s != '\0') {
  325. X            if (s[0] == '\\' && s[1] != '\0')
  326. X                s++;
  327. X            else if (s[0] == '%' && s[1] != '\0') {
  328. X                if (s[1] == 'p') {
  329. X                    if (termcap) {
  330. X                        warn();
  331. X                        fprintf(stderr,
  332. X"string '%s' already in terminfo format\n", strcodes[i]);
  333. X                        nocode = 1;
  334. X                        break;
  335. X                    } else
  336. X                        nocode = 1;
  337. X                }
  338. X                s++;
  339. X            }
  340. X            s++;
  341. X        }
  342. X        if (!nocode && !termcap) {
  343. X            warn();
  344. X            fprintf(stderr,
  345. X"string '%s' not in terminfo format, converting...\n", cap);
  346. X        }
  347. X        s = d;
  348. X    }
  349. X    while(*s != '\0') {
  350. X        switch(*s) {
  351. X        case '%':
  352. X            s++;
  353. X            if (nocode) {
  354. X                *dp++ = '%';
  355. X                break;
  356. X            }
  357. X            switch(*s++) {
  358. X            case '%': *dp++ = '%'; break;
  359. X            case 'r':
  360. X                if (seenr++ == 1) {
  361. X                    warn();
  362. X                    fprintf(stderr, "seen %%r twice\n");
  363. X                }
  364. X                break;
  365. X            case 'm':
  366. X                if (seenm++ == 1) {
  367. X                    warn();
  368. X                    fprintf(stderr, "seen %%m twice\n");
  369. X                }
  370. X                break;
  371. X            case 'n':
  372. X                if (seenn++ == 1) {
  373. X                    warn();
  374. X                    fprintf(stderr, "seen %%n twice\n");
  375. X                }
  376. X                break;
  377. X            case 'i': *dp++ = '%'; *dp++ = 'i'; break;
  378. X            case '6': 
  379. X            case 'B':
  380. X                getparm(param, 2);
  381. X                /* %{6}%*%+ */
  382. X                *dp++ = '%'; *dp++ = '{'; *dp++ = '6';
  383. X                *dp++ = '}'; *dp++ = '%'; *dp++ = '*';
  384. X                *dp++ = '%'; *dp++ = '+';
  385. X                break;
  386. X            case '8':
  387. X            case 'D':
  388. X                getparm(param, 2);
  389. X                /* %{2}%*%- */
  390. X                *dp++ = '%'; *dp++ = '{'; *dp++ = '2';
  391. X                *dp++ = '}'; *dp++ = '%'; *dp++ = '*';
  392. X                *dp++ = '%'; *dp++ = '-';
  393. X                break;
  394. X            case '>':
  395. X                getparm(param, 2);
  396. X                /* %?%{x}%>%t%{y}%+%; */
  397. X                *dp++ = '%'; *dp++ = '?'; 
  398. X                s += cvtchar(s);
  399. X                *dp++ = '%'; *dp++ = '>';
  400. X                *dp++ = '%'; *dp++ = 't';
  401. X                s += cvtchar(s);
  402. X                *dp++ = '%'; *dp++ = '+';
  403. X                *dp++ = '%'; *dp++ = ';';
  404. X                break;
  405. X            case 'a':
  406. X                if ((*s == '=' || *s == '+' || *s == '-'
  407. X                     || *s == '*' || *s == '/')
  408. X                    && (s[1] == 'p' || s[1] == 'c')
  409. X                        && s[2] != '\0') {
  410. X                    int l;
  411. X                    l = 2;
  412. X                    if (*s != '=')
  413. X                        getparm(param, 1);
  414. X                    if (s[1] == 'p') {
  415. X                        getparm(param + s[2] - '@', 1);
  416. X                        if (param != onstack) {
  417. X                            pop();
  418. X                            param--;
  419. X                        }
  420. X                        l++;
  421. X                    } else
  422. X                        l += cvtchar(s + 2);
  423. X                    switch(*s) {
  424. X                    case '+':
  425. X                        *dp++ = '%'; *dp++ = '+';
  426. X                        break;
  427. X                    case '-':
  428. X                        *dp++ = '%'; *dp++ = '-';
  429. X                        break;
  430. X                    case '*':
  431. X                        *dp++ = '%'; *dp++ = '*';
  432. X                        break;
  433. X                    case '/':
  434. X                        *dp++ = '%'; *dp++ = '/';
  435. X                        break;
  436. X                    case '=':
  437. X                        if (seenr)
  438. X                            if (param == 1)
  439. X                                onstack = 2;
  440. X                            else if (param == 2)
  441. X                                onstack = 1;
  442. X                            else
  443. X                                onstack = param;
  444. X                        else
  445. X                            onstack = param;
  446. X                        break;
  447. X                    }
  448. X                    s += l;
  449. X                    break;
  450. X                }
  451. X                getparm(param, 1);
  452. X                s += cvtchar(s);
  453. X                *dp++ = '%'; *dp++ = '+';
  454. X                break;
  455. X            case '+':
  456. X                getparm(param, 1);
  457. X                s += cvtchar(s);
  458. X                *dp++ = '%'; *dp++ = '+';
  459. X                *dp++ = '%'; *dp++ = 'c';
  460. X                pop();
  461. X                break;
  462. X            case 's':
  463. X                s += cvtchar(s);
  464. X                getparm(param, 1);
  465. X                *dp++ = '%'; *dp++ = '-';
  466. X                break;
  467. X            case '-':
  468. X                s += cvtchar(s);
  469. X                getparm(param, 1);
  470. X                *dp++ = '%'; *dp++ = '-';
  471. X                *dp++ = '%'; *dp++ = 'c';
  472. X                pop();
  473. X                break;
  474. X            case '.':
  475. X                getparm(param, 1);
  476. X                *dp++ = '%'; *dp++ = 'c';
  477. X                pop();
  478. X                break;
  479. X            case '2':
  480. X                getparm(param, 1);
  481. X                *dp++ = '%'; *dp++ = '0';
  482. X                *dp++ = '2'; *dp++ = 'd';
  483. X                pop();
  484. X                break;
  485. X            case '3':
  486. X                getparm(param, 1);
  487. X                *dp++ = '%'; *dp++ = '0';
  488. X                *dp++ = '3'; *dp++ = 'd';
  489. X                pop();
  490. X                break;
  491. X            case 'd':
  492. X                getparm(param, 1);
  493. X                *dp++ = '%'; *dp++ = 'd';
  494. X                pop();
  495. X                break;
  496. X            case 'f':
  497. X                param++;
  498. X                break;
  499. X            case 'b':
  500. X                param--;
  501. X                break;
  502. X            default:
  503. X                warn();
  504. X                *dp++ = '%';
  505. X                s--;
  506. X                fprintf(stderr, "'%s' unknown %% code %%c",
  507. X                    strcodes[i], *s);
  508. X                if (*s >= 0 && *s < 32)
  509. X                    fprintf(stderr, "^%c\n", *s + '@');
  510. X                else if (*s < 0 || *s >= 127)
  511. X                    fprintf(stderr, "\\%03o\n", *s & 0377);
  512. X                else
  513. X                    fprintf(stderr, "%c\n", *s);
  514. X                break;
  515. X            }
  516. X            break;
  517. X        case '\\':
  518. X            if (!compile) {*dp++ = *s++; *dp++ = *s++; break;}
  519. X            /* FALLTHROUGH */
  520. X        case '\n':
  521. X            if (!compile) {*dp++ = '\\'; *dp++ = 'n'; s++; break;}
  522. X            /* FALLTHROUGH */
  523. X        case '\t':
  524. X            if (!compile) {*dp++ = '\\'; *dp++ = 't'; s++; break;}
  525. X            /* FALLTHROUGH */
  526. X        case '\r':
  527. X            if (!compile) {*dp++ = '\\'; *dp++ = 'r'; s++; break;}
  528. X            /* FALLTHROUGH */
  529. X        case '\200':
  530. X            if (!compile) {*dp++ = '\\'; *dp++ = '0'; s++; break;}
  531. X            /* FALLTHROUGH */
  532. X        case '\f':
  533. X            if (!compile) {*dp++ = '\\'; *dp++ = 'f'; s++; break;}
  534. X            /* FALLTHROUGH */
  535. X        case '\b':
  536. X            if (!compile) {*dp++ = '\\'; *dp++ = 'b'; s++; break;}
  537. X            /* FALLTHROUGH */
  538. X        case ' ':
  539. X            if (!compile) {*dp++ = '\\'; *dp++ = 's'; s++; break;}
  540. X            /* FALLTHROUGH */
  541. X        case '^':
  542. X            if (!compile) {*dp++ = '\\'; *dp++ = '^'; s++; break;}
  543. X            /* FALLTHROUGH */
  544. X        case ':':
  545. X            if (!compile) {*dp++ = '\\'; *dp++ = ':'; s++; break;}
  546. X            /* FALLTHROUGH */
  547. X        case ',':
  548. X            if (!compile) {*dp++ = '\\'; *dp++ = ','; s++; break;}
  549. X            /* FALLTHROUGH */
  550. X#if 0
  551. X        case '\'':
  552. X            if (!compile) {*dp++ = '\\'; *dp++ = '\''; s++; break;}
  553. X            /* FALLTHROUGH */
  554. X#endif
  555. X        default:
  556. X            if (compile) 
  557. X                *dp++ = *s++;
  558. X            else if (*s > 0 && *s < 32) {
  559. X                *dp++ = '^';
  560. X                *dp++ = *s + '@';
  561. X                s++;
  562. X            } else if (*s <= 0 || *s >= 127) {
  563. X                *dp++ = '\\';
  564. X                *dp++ = ((*s & 0300) >> 6) + '0';
  565. X                *dp++ = ((*s & 0070) >> 3) + '0';
  566. X                *dp++ = (*s & 0007) + '0';
  567. X                s++;
  568. X            } else
  569. X                *dp++ = *s++;
  570. X            break;
  571. X        }
  572. X    }
  573. X    *dp = '\0';
  574. X    return line;
  575. X}
  576. X
  577. X#define LSB(n) ((unsigned) (n) & 0377)
  578. X#define MSB(n) (((unsigned) (n) >> 8) & 0377)
  579. X
  580. void
  581. writebin(fd, name)
  582. int fd;
  583. char *name; {
  584. X    static char bin[MAX_BUF + 1];
  585. X    register char *s;
  586. X    register char *d;
  587. X    register int i;
  588. X    register char *t;
  589. X    register int n;
  590. X    char *strtbl;
  591. X    int sz_name, n_bools, n_nums, n_offs, sz_strs;
  592. X    extern int _boolorder[], _numorder[], _strorder[];
  593. X
  594. X    strncpy(bin + 12, name, 127);
  595. X    bin[12 + 128] = '\0';
  596. X    sz_name = strlen(name) + 1;
  597. X    if (sz_name > 128)
  598. X        sz_name = 128;
  599. X
  600. X    s = bin + 12 + sz_name;
  601. X    for(i = 0; _boolorder[i] != -1; i++) {
  602. X        switch(_term_buf.bools[i]) {
  603. X        case -1: *s++ = 0; break;
  604. X        case  0: *s++ = 0377; break;
  605. X        default: *s++ = 1; break;
  606. X        }
  607. X    }
  608. X    n_bools = i;
  609. X    if ((sz_name + n_bools) & 1)
  610. X        n_bools++;
  611. X
  612. X    s = bin + 12 + sz_name + n_bools;
  613. X    for(i = 0; _numorder[i] != -1; i++) {
  614. X        n = _term_buf.nums[_numorder[i]];
  615. X        switch(n) {
  616. X        case -2: *s++ = 0377; *s++ = 0377; break;
  617. X        case -1: *s++ = 0376; *s++ = 0377; break;
  618. X        default:
  619. X            *s++ = LSB(n);
  620. X            *s++ = MSB(n);
  621. X        }
  622. X    }
  623. X    n_nums = i;
  624. X
  625. X    s = bin + 12 + sz_name + n_bools + n_nums * 2;
  626. X    for(i = 0; _strorder[i] != -1; i++) {
  627. X        if (_term_buf.strs[_strorder[i]] == (char *) 0) {
  628. X            *s++ = 0376; *s++ = 0377;
  629. X        } else {
  630. X            *s++ = 0377; *s++ = 0377;
  631. X        }
  632. X    }
  633. X    n_offs = i;
  634. X
  635. X    s = bin + 12 + sz_name + n_bools + n_nums * 2;
  636. X    strtbl = d = s + n_offs * 2;
  637. X    for(i = 0; _strorder[i] != -1; i++) {
  638. X        t = _term_buf.strs[_strorder[i]];
  639. X        if (t == (char *) -1 || t == (char *)  0)
  640. X            s += 2;
  641. X        else {
  642. X            n = d - strtbl;
  643. X            *s++ = LSB(n);
  644. X            *s++ = MSB(n);
  645. X            t = convstr(t, _strorder[i]);
  646. X            while(*t != '\0') {
  647. X                *d++ = *t++;
  648. X                if (d >= bin + MAX_BUF - 1) {
  649. X                    warn();
  650. X                    fprintf(stderr,
  651. X                    "compiled entry to big\n");
  652. X                    *d++ = '\0';
  653. X                    goto toobig;
  654. X                }
  655. X            }
  656. X            *d++ = '\0';
  657. X        }
  658. X    }
  659. X
  660. toobig:
  661. X    sz_strs = d - strtbl;
  662. X
  663. X    bin[0] = 032;
  664. X    bin[1] = 01;
  665. X    bin[2] = LSB(sz_name);
  666. X    bin[3] = MSB(sz_name);
  667. X    bin[4] = LSB(n_bools);
  668. X    bin[5] = MSB(n_bools);
  669. X    bin[6] = LSB(n_nums);
  670. X    bin[7] = MSB(n_nums);
  671. X    bin[8] = LSB(n_offs);
  672. X    bin[9] = MSB(n_offs);
  673. X    bin[10] = LSB(sz_strs);
  674. X    bin[11] = MSB(sz_strs);
  675. X
  676. X    if (write(fd, bin, d - bin) == -1) 
  677. X        quit(errno, "can't write binary file");
  678. X
  679. X    return;
  680. X}
  681. X
  682. void
  683. find_directory() {
  684. X    struct term_path *p;
  685. X    struct stat st;
  686. X
  687. X    if (directory != NULL)
  688. X        return;
  689. X
  690. X    p = path;
  691. X    while(p->type != -1 && p->file != NULL) {
  692. X        if (stat(p->file, &st) == 0) {
  693. X            if ((st.st_mode & 0170000) == 0040000) {
  694. X                directory = p->file;
  695. X                return;
  696. X            }
  697. X        }
  698. X        p++;
  699. X    }
  700. X    quit(-1, "can't find a terminfo directory");
  701. X}
  702. X
  703. X/* convert a terminal name to a binary filename */
  704. char *
  705. binfile(name)
  706. char *name; {
  707. X    static char line[MAX_LINE+1];
  708. X
  709. X    sprintf(line, "%s/%c/%s", directory, *name, name);
  710. X    return line;
  711. X}
  712. X
  713. char *
  714. bindir(name)
  715. char *name; {
  716. X    static char line[MAX_LINE+1];
  717. X
  718. X    sprintf(line, "%s/%c", directory, *name);
  719. X    return line;
  720. X}
  721. X
  722. int
  723. badname(name)
  724. char *name; {
  725. X    while(*name) {
  726. X        if (*name == '/' || !isgraph(*name))
  727. X            return 1;
  728. X        name++;
  729. X    }
  730. X    return 0;
  731. X}
  732. X
  733. X/* output a terminfo binary */
  734. void
  735. outputbin(name)
  736. char *name; {
  737. X    register char *s, *d, *last;
  738. X    char tmp[MAX_LINE+1];
  739. X    char line[MAX_LINE+1];
  740. X    int fd;
  741. X
  742. X    find_directory();
  743. X
  744. X    s = name;
  745. X    d = line;
  746. X    while(*s != '\0' && d < line + MAX_LINE) {
  747. X        *d++ = *s++;
  748. X    }
  749. X
  750. X    while(d > line && d[-1] == '|') {
  751. X        d--;
  752. X    }
  753. X
  754. X    *d = '\0';
  755. X
  756. X    s = strtok(line, "|");
  757. X    last = NULL;
  758. X
  759. X    while(s != NULL && last == NULL) {
  760. X        if (*s == '\0') {
  761. X            ;
  762. X        } else if (badname(s)) {
  763. X            if (lineno)
  764. X                warn();
  765. X            fprintf(stderr, "bad terminal name '%s', ingored.\n",
  766. X                s);
  767. X        } else {
  768. X            if (access(bindir(s), 2) == -1) {
  769. X                if (errno != ENOENT) 
  770. X                    quit(errno,
  771. X                         "can't access directory '%s'",
  772. X                         bindir(s));
  773. X                if (mkdir(bindir(s), 0777) == -1) 
  774. X                    quit(errno, "can't make directory '%s'",
  775. X                         bindir(s));
  776. X            }
  777. X            fd = open(binfile(s), O_WRONLY | O_CREAT | O_EXCL,
  778. X                  0666);
  779. X            if (fd == -1) {
  780. X                if (errno != EEXIST)
  781. X                    quit(errno, "can't open file '%s'",
  782. X                         binfile(s));
  783. X                if (unlink(binfile(s)) == -1) 
  784. X                    quit(errno, "can't unlink file '%s'",
  785. X                         binfile(s));
  786. X                fd = open(binfile(s),
  787. X                      O_WRONLY | O_CREAT | O_EXCL, 0666);
  788. X                if (fd == -1)
  789. X                    quit(errno, "can't create file '%s'",
  790. X                         binfile(s));
  791. X            }
  792. X            writebin(fd, name);
  793. X            close(fd);
  794. X            last = s;
  795. X        }
  796. X        s = strtok(NULL, "|");
  797. X    }
  798. X
  799. X    if (last == NULL) {
  800. X        if (lineno)
  801. X            warn();
  802. X        fprintf(stderr, "no terminal name, entry ignored.\n");
  803. X        return;
  804. X    }
  805. X
  806. X    while(s != NULL && s + strlen(s) != d) {
  807. X        if (*s == '\0' || strcmp(s, last) == 0) {
  808. X            ;
  809. X        } else if (badname(s)) {
  810. X            if (lineno)
  811. X                warn();
  812. X            fprintf(stderr, "bad terminal name '%s', ingored.\n",
  813. X                s);
  814. X        } else {
  815. X            if (access(bindir(s), 2) == -1) {
  816. X                if (errno != ENOENT) 
  817. X                    quit(errno,
  818. X                         "can't access directory '%s'",
  819. X                         bindir(s));
  820. X                if (mkdir(bindir(s), 0777) == -1) 
  821. X                    quit(errno, "can't make directory '%s'",
  822. X                         bindir(s));
  823. X            }
  824. X            if (access(binfile(s), 0) == -1) {
  825. X                if (errno != ENOENT)
  826. X                    quit(errno, "can't access file '%s'",
  827. X                         binfile(s));
  828. X            } else if (unlink(binfile(s)) == -1) {
  829. X                    quit(errno, "can't unlink file '%s'",
  830. X                         binfile(s));
  831. X            }
  832. X            strcpy(tmp, binfile(last));
  833. X            if (link(tmp, binfile(s)) == -1) {
  834. X                quit(errno, "can't link '%s' to '%s'",
  835. X                     last, binfile(s));
  836. X            }
  837. X        }
  838. X        s = strtok(NULL, "|");
  839. X    }
  840. X    return;
  841. X}
  842. X
  843. X/* output an entry in terminfo source format */
  844. void
  845. outputinfo(name)
  846. char *name; {
  847. X    int i;
  848. X    char line[MAX_LINE];
  849. X
  850. X    printf("%s,\n", name);
  851. X
  852. X    for(i = 0; i < NUM_OF_BOOLS; i++)
  853. X        if (_term_buf.bools[i] == 0) {
  854. X            sprintf(line, "%s@", boolnames[i]);
  855. X            putstr(line);
  856. X        } else if (_term_buf.bools[i] != -1)
  857. X            putstr(boolnames[i]);
  858. X
  859. X    for(i = 0; i < NUM_OF_NUMS; i++)
  860. X        if (_term_buf.nums[i] == -1) {
  861. X            sprintf(line, "%s@", numnames[i]);
  862. X            putstr(line);
  863. X        } else if (_term_buf.nums[i] != -2) {
  864. X            sprintf(line, "%s#%d", numnames[i], _term_buf.nums[i]);
  865. X            putstr(line);
  866. X        }
  867. X
  868. X    for(i = 0; i < NUM_OF_STRS; i++)
  869. X        if (_term_buf.strs[i] == NULL) {
  870. X            sprintf(line, "%s@", strnames[i]);
  871. X            putstr(line);
  872. X        } else if (_term_buf.strs[i] != (char *) -1) {
  873. X            sprintf(line, "%s=%s", strnames[i],
  874. X                convstr(_term_buf.strs[i], i));
  875. X            putstr(line);
  876. X        }
  877. X    putstr(NULL);
  878. X}
  879. X
  880. X/* convert a terminfo entry to binary format */
  881. void
  882. convtinfo() {
  883. X    int i, r;
  884. X
  885. X    termcap = 0;
  886. X
  887. X    for(i = 0; i < NUM_OF_BOOLS; i++)
  888. X        _term_buf.bools[i] = -1;
  889. X    for(i = 0; i < NUM_OF_NUMS; i++)
  890. X        _term_buf.nums[i] = -2;
  891. X    for(i = 0; i < NUM_OF_STRS; i++)
  892. X        _term_buf.strs[i] = (char *) -1;
  893. X
  894. X    _term_buf.name_all = NULL;
  895. X
  896. X    r = _gettinfo(buf, &_term_buf, path);
  897. X    if (r != 0) {
  898. X        if (lineno == 0)
  899. X            quit(-1, "problem reading entry");
  900. X        else {
  901. X            warn();
  902. X            fprintf(stderr, "problem reading entry\n");
  903. X        }
  904. X    }
  905. X
  906. X    if (compile)
  907. X        outputbin(_term_buf.name_all);
  908. X    else
  909. X        outputinfo(_term_buf.name_all);
  910. X    return;
  911. X}
  912. X
  913. X/* convert a terminfo binary to terminfo source */
  914. void
  915. convtbin() {
  916. X    int i, r;
  917. X
  918. X    termcap = 0;
  919. X
  920. X    for(i = 0; i < NUM_OF_BOOLS; i++)
  921. X        _term_buf.bools[i] = -1;
  922. X    for(i = 0; i < NUM_OF_NUMS; i++)
  923. X        _term_buf.nums[i] = -2;
  924. X    for(i = 0; i < NUM_OF_STRS; i++)
  925. X        _term_buf.strs[i] = (char *) -1;
  926. X
  927. X    _term_buf.name_all = NULL;
  928. X
  929. X    r = _gettbin(buf, &_term_buf);
  930. X    if (r != 0) {
  931. X        if (lineno == 0)
  932. X            quit(-1, "problem reading entry");
  933. X        else {
  934. X            warn();
  935. X            fprintf(stderr, "problem reading entry\n");
  936. X        }
  937. X    }
  938. X
  939. X    outputinfo(_term_buf.name_all);
  940. X
  941. X    return;
  942. X}
  943. X
  944. X/* convert a termcap entry to terminfo format */
  945. void
  946. convtcap() {
  947. X    int i, r;
  948. X    char *name;
  949. X
  950. X    termcap = 1;
  951. X
  952. X    for(i = 0; i < NUM_OF_BOOLS; i++)
  953. X        _term_buf.bools[i] = -1;
  954. X    for(i = 0; i < NUM_OF_NUMS; i++)
  955. X        _term_buf.nums[i] = -2;
  956. X    for(i = 0; i < NUM_OF_STRS; i++)
  957. X        _term_buf.strs[i] = (char *) -1;
  958. X
  959. X    _term_buf.name_all = NULL;
  960. X
  961. X
  962. X#if DEBUG
  963. X    printf("%s\n", buf);
  964. X#endif
  965. X    r = _gettcap(buf, &_term_buf, path);
  966. X    if (r != 0) {
  967. X        if (lineno == 0)
  968. X            quit(-1, "problem reading entry");
  969. X        else {
  970. X            warn();
  971. X            fprintf(stderr, "problem reading entry\n");
  972. X        }
  973. X    }
  974. X
  975. X    if (dodefault && !continued)
  976. X        _tcapdefault();
  977. X
  978. X    _tcapconv();
  979. X
  980. X    name = _term_buf.name_all;
  981. X#if DEBUG
  982. X    printf("...%s\n", name);
  983. X#endif
  984. X    if (name[0] != '\0' && name[1] != '\0' && name[2] == '|')
  985. X        name += 3;    /* skip the 2 letter code */
  986. X
  987. X    if (compile) 
  988. X        outputbin(name);
  989. X    else
  990. X        outputinfo(name);
  991. X}
  992. X
  993. void
  994. convbinfile(file)
  995. char *file; {
  996. X    register FILE *f;
  997. X    int r;
  998. X
  999. X    f = fopen(file, "r");
  1000. X
  1001. X    if (f == NULL)
  1002. X        quit(errno, "can't open '%s'", file);
  1003. X
  1004. X    r = fread(buf, sizeof(char), MAX_BUF, f);
  1005. X    if (r < 12 || buf[0] != 032 || buf[1] != 01)
  1006. X        quit(-1, "file '%s' corrupted", file);
  1007. X
  1008. X    convtbin();
  1009. X}
  1010. X
  1011. X/* convert a termcap file to terminfo format */
  1012. void
  1013. convtcfile(file)
  1014. char *file; {
  1015. X    int nocolon;
  1016. X    register int c;
  1017. X    register char *d;
  1018. X    register FILE *f;
  1019. X
  1020. X    f = fopen(file, "r");
  1021. X
  1022. X    if (f == NULL)
  1023. X        quit(errno, "can't open '%s'", file);
  1024. X
  1025. X    d = buf;
  1026. X    c = getc(f);
  1027. X    while(c != EOF) {
  1028. X        lineno++;
  1029. X        if (c == '#') {
  1030. X            if (keepcomments) {
  1031. X                do {
  1032. X                    putchar(c);
  1033. X                    c = getc(f);
  1034. X                } while(c != '\n' && c != EOF);
  1035. X                putchar('\n');
  1036. X            } else
  1037. X                do
  1038. X                    c = getc(f);
  1039. X                while(c != '\n' && c != EOF);
  1040. X            if (c != EOF)
  1041. X                c = getc(f);
  1042. X            continue;
  1043. X        }
  1044. X        while(isspace(c) && c != '\n')
  1045. X            c = getc(f);
  1046. X        if (c == '\n' && buf == d) {
  1047. X            c = getc(f);
  1048. X            continue;
  1049. X        }
  1050. X
  1051. X        while(c != EOF) {
  1052. X            if (c == '\\') {
  1053. X                c = getc(f);
  1054. X                if (c == EOF) 
  1055. X                    break;
  1056. X                if (c == '\n') {
  1057. X                    c = getc(f);
  1058. X                    break;
  1059. X                }
  1060. X                *d++ = '\\';
  1061. X                *d++ = c;
  1062. X            } else if (c == '\n') {
  1063. X                *d = '\0';
  1064. X                if (*--d == ':') {
  1065. X                    nocolon = 0;
  1066. X                    *d-- = '\0';
  1067. X                } else {
  1068. X                    nocolon = 1;
  1069. X                }
  1070. X                while(d > buf && *d != ':')
  1071. X                    d--;
  1072. X                if (d[1] == 't' && d[2] == 'c' && d[3] == '=') {
  1073. X                    continued = 1;
  1074. X                    d[1] = '\0';
  1075. X                } else
  1076. X                    continued = 0;
  1077. X                convtcap();
  1078. X                if (nocolon) {
  1079. X                    warn();
  1080. X                    fprintf(stderr,
  1081. X                        "entry doesn't end with :\n");
  1082. X                }
  1083. X                _term_buf.strbuf = _endstr();
  1084. X                _del_strs(&_term_buf);
  1085. X                if (continued) {
  1086. X                    printf("\tuse=%s,\n", d + 4);
  1087. X                }
  1088. X                d = buf;
  1089. X                c = getc(f);
  1090. X                break;
  1091. X            } else
  1092. X                *d++ = c;
  1093. X            c = getc(f);
  1094. X        }
  1095. X    }
  1096. X}
  1097. X
  1098. static int
  1099. getln(f, buf, len)
  1100. XFILE *f;
  1101. register char *buf;
  1102. int len; {
  1103. X    register int c, i = 0;
  1104. X
  1105. X    while((c = getc(f)) == '#') {
  1106. X        lineno++;
  1107. X        if (keepcomments) {
  1108. X            putchar('#');
  1109. X            while((c = getc(f)) != '\n') {
  1110. X                if (c == EOF)
  1111. X                    return -1;
  1112. X                putchar(c);
  1113. X            }
  1114. X            putchar('\n');
  1115. X        } else {
  1116. X            while((c = getc(f)) != '\n')
  1117. X                if (c == EOF)
  1118. X                    return -1;
  1119. X        }
  1120. X    }
  1121. X
  1122. X    lineno++;
  1123. X    while(c != '\n') {
  1124. X        if (c == EOF)
  1125. X            return -1;
  1126. X        if (i < len) {
  1127. X            i++;
  1128. X            *buf++ = c;
  1129. X        }
  1130. X        c = getc(f);
  1131. X    }
  1132. X
  1133. X    while(isspace(*(buf-1))) {
  1134. X        buf--;
  1135. X        i--;
  1136. X    }
  1137. X
  1138. X    *buf = '\0';
  1139. X    return i;
  1140. X}
  1141. X
  1142. void
  1143. convtifile(file)
  1144. char *file; {
  1145. X    static char line[MAX_LINE+1];
  1146. X    int l;
  1147. X    int n;
  1148. X    register FILE *f;
  1149. X
  1150. X    f = fopen(file, "r");
  1151. X
  1152. X    if (f == NULL)
  1153. X        quit(errno, "can't open '%s'", file);
  1154. X
  1155. X    lineno = 0;
  1156. X
  1157. X    l = getln(f, line, MAX_LINE);
  1158. X    while(l != -1) {
  1159. X        if (line[l-1] == ':') {
  1160. X            strncpy(buf, line, MAX_BUF);
  1161. X            convtcap();
  1162. X        } else if (line[l-1] == '\\') {
  1163. X            n = MAX_BUF;
  1164. X            do {
  1165. X                line[--l] = '\0';
  1166. X                if (n > 0)
  1167. X                    strncpy(buf + MAX_BUF - n, line, n);
  1168. X                n -= l;
  1169. X                l = getln(f, line, MAX_LINE);
  1170. X            } while(l != -1 && line[l-1] == '\\');
  1171. X            if (n > 0 && l != -1)
  1172. X                strncpy(buf + MAX_BUF - n, line, n);
  1173. X            convtcap();
  1174. X        } else if (line[l-1] == ',') {
  1175. X            n = MAX_BUF;
  1176. X            do {
  1177. X                if (n > 0)
  1178. X                    strncpy(buf + MAX_BUF - n, line, n);
  1179. X                n -= l;
  1180. X                l = getln(f, line, MAX_LINE);
  1181. X            } while(l != -1 && isspace(line[0]));
  1182. X#if 0
  1183. X            printf("buf = '%s'\n", buf);
  1184. X#endif
  1185. X            convtinfo();
  1186. X            continue;
  1187. X        } else if (line[0] != '\0') {
  1188. X            warn();
  1189. X            fprintf(stderr, "malformed line\n");
  1190. X            if (keepcomments) {
  1191. X                printf("%s\n", line);
  1192. X            }
  1193. X        }
  1194. X        l = getln(f, line, MAX_LINE);
  1195. X    }
  1196. X    return;
  1197. X}
  1198. X
  1199. X/* dummy routine for quit */
  1200. X/* ARGSUSED */
  1201. void
  1202. do_cleanup(e)
  1203. int e; {
  1204. X    return;
  1205. X}
  1206. X
  1207. X/* print out usage, called by quit */
  1208. X/* ARGSUSED */
  1209. void
  1210. usage(e)
  1211. int e; {
  1212. X    fprintf(stderr,
  1213. X"usage: %s [-b] [-c [-OUGd]] [-i] [-B [-D dir]] [-I] [-k] [-V]\n\t[-t term] [file]\n",
  1214. X        prg_name);
  1215. X    return;
  1216. X}
  1217. X
  1218. int
  1219. main(argc, argv)
  1220. int argc;
  1221. char **argv; {
  1222. X    extern char *optarg;
  1223. X    extern int optind;
  1224. X    extern int opterr;
  1225. X    char *term = NULL;
  1226. X    char *file = NULL;
  1227. X    int r;
  1228. X    char c;
  1229. X    int pversion = 0;
  1230. X
  1231. X    prg_name = strrchr(argv[0], '/');
  1232. X    if (prg_name == NULL)
  1233. X        prg_name = argv[0];
  1234. X    else
  1235. X        prg_name++;
  1236. X
  1237. X    cleanup = usage;
  1238. X
  1239. X    opterr = 0;
  1240. X
  1241. X    if (strcmp(prg_name, "tic") == 0)
  1242. X        compile = 1;
  1243. X
  1244. X    while ((c = getopt(argc, argv, "bciBIOGUdkVD:t:")) != -1) {
  1245. X        switch(c) {
  1246. X        case 'O':
  1247. X            noOT = 0;
  1248. X            break;
  1249. X        case 'G':
  1250. X            noGNU = 0;
  1251. X            break;
  1252. X        case 'U':
  1253. X            noUW = 0;
  1254. X            break;
  1255. X        case 'D':
  1256. X            if (directory != NULL)
  1257. X                quit(-1, "more than one directory specified");
  1258. X            directory = optarg;
  1259. X            break;
  1260. X        case 't':
  1261. X            if (term != NULL)
  1262. X                quit(-1, "more than one terminal specified");
  1263. X            term = optarg;
  1264. X            break;
  1265. X        case 'd': dodefault = 0; break;
  1266. X        case 'k': keepcomments = 1; break;
  1267. X        case 'b': from_tbin = 1; break;
  1268. X        case 'c': from_tcap = 1; break;
  1269. X        case 'i': from_tinfo = 1; break;
  1270. X        case 'B': compile = 1; break;
  1271. X        case 'I': compile = 0; break;
  1272. X        case 'V': pversion = 1; break;
  1273. X        case '?': 
  1274. X        default:
  1275. X            quit(-1, "bad or missing command line argument");
  1276. X        }
  1277. X    }
  1278. X
  1279. X    if (pversion) {
  1280. X        quit(0, "%s\n%s", _mytinfo_version, SCCSid);
  1281. X    }
  1282. X
  1283. X    if (optind == argc - 1)
  1284. X        file = argv[optind];
  1285. X    else if (optind != argc)
  1286. X        quit(-1, "wrong number of arguments");
  1287. X
  1288. X    if (from_tbin + from_tcap + from_tinfo > 1) 
  1289. X        quit(-1, "more than one input file type specified");
  1290. X
  1291. X    if (!from_tcap && !from_tinfo && !from_tbin && file != NULL) {
  1292. X        if (strcmp(prg_name, "cap2info") == 0
  1293. X            || strcmp(prg_name, "captoinfo") == 0)
  1294. X            from_tcap = 1;
  1295. X        else if (strcmp(prg_name, "tic") == 0)
  1296. X            from_tinfo = 1;
  1297. X        else 
  1298. X            quit(-1, "no input file type specified");
  1299. X    }
  1300. X
  1301. X    if (from_tbin && compile) 
  1302. X        quit(-1, "can't convert from binary to binary");
  1303. X
  1304. X    if (file != NULL) {
  1305. X        if (from_tbin) {
  1306. X            cleanup = do_cleanup;
  1307. X            convbinfile(file);
  1308. X            exit(0);
  1309. X        }
  1310. X        if (!compile)
  1311. X            path = _buildpath(file, 0, NULL, -1);
  1312. X        else {
  1313. X            path = _buildpath(file, 0,
  1314. X                      "$TERMINFO", 2,
  1315. X                      "$MYTERMINFO", 2,
  1316. X#ifdef TERMINFODIR
  1317. X                      TERMINFODIR, 0,
  1318. X#endif
  1319. X                      NULL, -1);
  1320. X        }
  1321. X        if (path == NULL)
  1322. X            quit(-1, "can't build path");
  1323. X        if (term == NULL) {
  1324. X            cleanup = do_cleanup;
  1325. X            if (from_tcap && !compile)
  1326. X                convtcfile(file);
  1327. X            else 
  1328. X                convtifile(file);
  1329. X            exit(0);
  1330. X        }
  1331. X    } else if (from_tcap && !compile)
  1332. X        path = _buildpath("$TERMCAP", 1,
  1333. X#ifdef TERMCAPFILE
  1334. X                  TERMCAPFILE, 0,
  1335. X#endif
  1336. X                  NULL, -1);
  1337. X    else if (from_tinfo || from_tbin)
  1338. X        path = _buildpath("$TERMINFO", 2,
  1339. X                  "$MYTERMINFO", 2,
  1340. X#ifdef TERMINFODIR
  1341. X                  TERMINFODIR, 0,
  1342. X#endif
  1343. X#ifdef TERMINFOSRC
  1344. X                  TERMINFOSRC, 0,
  1345. X#endif
  1346. X                  NULL, -1);
  1347. X    else if (from_tcap)
  1348. X        path = _buildpath("$TERMCAP", 1,
  1349. X#ifdef TERMCAPFILE
  1350. X                  TERMCAPFILE, 0,
  1351. X#endif
  1352. X                  "$TERMINFO", 2,
  1353. X                  "$MYTERMINFO", 2,
  1354. X#ifdef TERMINFODIR
  1355. X                  TERMINFODIR, 0,
  1356. X#endif
  1357. X                  NULL, -1);
  1358. X    else 
  1359. X        path = _buildpath("$TERMINFO", 2,
  1360. X                  "$MYTERMINFO", 2,
  1361. X                  "$TERMCAP", 1,
  1362. X#ifdef TERMINFODIR
  1363. X                  TERMINFODIR, 0,
  1364. X#endif
  1365. X#ifdef TERMINFOSRC
  1366. X                  TERMINFOSRC, 0,
  1367. X#endif
  1368. X#ifdef TERMCAPFILE
  1369. X                  TERMCAPFILE, 0,
  1370. X#endif
  1371. X                  NULL, -1);
  1372. X    if (term == NULL) {
  1373. X        term = getenv("TERM");
  1374. X        if (term == NULL)
  1375. X            quit(-1, "no terminal type given");
  1376. X    }
  1377. X
  1378. X    cleanup = do_cleanup;
  1379. X
  1380. X    r = _findterm(term, path, buf);
  1381. X    switch(r) {
  1382. X    case 1:
  1383. X        convtcap();
  1384. X        break;
  1385. X    case 2:
  1386. X        convtinfo();
  1387. X        break;
  1388. X    case 3:
  1389. X        if (compile)
  1390. X            quit(-1, "entry is already compiled");
  1391. X        convtbin();
  1392. X        break;
  1393. X    default:
  1394. X        quit(-1, "can't find a terminal entry for '%s'", term);
  1395. X    }
  1396. X
  1397. X    exit(0);
  1398. X    return 0;
  1399. X}
  1400. END_OF_FILE
  1401. if test 26474 -ne `wc -c <'tconv.c'`; then
  1402.     echo shar: \"'tconv.c'\" unpacked with wrong size!
  1403. fi
  1404. # end of 'tconv.c'
  1405. fi
  1406. if test -f 'tparm.c' -a "${1}" != "-c" ; then 
  1407.   echo shar: Will not clobber existing file \"'tparm.c'\"
  1408. else
  1409. echo shar: Extracting \"'tparm.c'\" \(16639 characters\)
  1410. sed "s/^X//" >'tparm.c' <<'END_OF_FILE'
  1411. X/*
  1412. X * tparm.c
  1413. X *
  1414. X * By Ross Ridge
  1415. X * Public Domain
  1416. X * 92/02/01 07:30:36
  1417. X *
  1418. X */
  1419. X
  1420. X#include "defs.h"
  1421. X#include "term.h"
  1422. X
  1423. X#include <ctype.h>
  1424. X
  1425. X#ifdef USE_SCCS_IDS
  1426. static const char SCCSid[] = "@(#) mytinfo tparm.c 3.2 92/02/01 public domain, By Ross Ridge";
  1427. X#endif
  1428. X
  1429. X#ifndef MAX_PUSHED
  1430. X#define MAX_PUSHED    32
  1431. X#endif
  1432. X
  1433. X#define ARG    1
  1434. X#define NUM    2
  1435. X
  1436. X#define INTEGER    1
  1437. X#define STRING    2
  1438. X
  1439. typedef struct stack_str {
  1440. X    int    type;
  1441. X    int    argnum;
  1442. X    int    value;
  1443. X} stack;
  1444. X
  1445. static stack S[MAX_PUSHED];
  1446. static stack vars['z'-'a'+1];
  1447. static int pos = 0;
  1448. X
  1449. static struct arg_str {
  1450. X    int type;
  1451. X    int    integer;
  1452. X    char    *string;
  1453. X} arg_list[10];
  1454. X
  1455. static int argcnt;
  1456. X
  1457. static va_list tparm_args;
  1458. X
  1459. static int
  1460. pusharg(arg)
  1461. int arg; {
  1462. X    if (pos == MAX_PUSHED)
  1463. X        return 1;
  1464. X    S[pos].type = ARG;
  1465. X    S[pos++].argnum = arg;
  1466. X    return 0;
  1467. X}
  1468. X
  1469. static int
  1470. pushnum(num)
  1471. int num; {
  1472. X    if (pos == MAX_PUSHED)
  1473. X        return 1;
  1474. X    S[pos].type = NUM;
  1475. X    S[pos++].value = num;
  1476. X    return 0;
  1477. X}
  1478. X
  1479. X/* VARARGS2 */
  1480. static int
  1481. getarg(argnum, type, p)
  1482. int argnum, type;
  1483. anyptr p; {
  1484. X    while (argcnt < argnum) {
  1485. X        arg_list[argcnt].type = INTEGER;
  1486. X        arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
  1487. X    }
  1488. X    if (argcnt > argnum) {
  1489. X        if (arg_list[argnum].type != type)
  1490. X            return 1;
  1491. X        else if (type == STRING)
  1492. X            *(char **)p = arg_list[argnum].string;
  1493. X        else 
  1494. X            *(int *)p = arg_list[argnum].integer;
  1495. X    } else {
  1496. X        arg_list[argcnt].type = type;
  1497. X        if (type == STRING)
  1498. X            *(char **)p = arg_list[argcnt++].string
  1499. X                = (char *) va_arg(tparm_args, char *);
  1500. X        else
  1501. X            *(int *)p = arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
  1502. X    }
  1503. X    return 0;
  1504. X}
  1505. X
  1506. X
  1507. static int
  1508. popstring(str)
  1509. char **str; {
  1510. X    if (pos-- == 0)
  1511. X        return 1;
  1512. X    if (S[pos].type != ARG)
  1513. X        return 1;
  1514. X    return(getarg(S[pos].argnum, STRING, (anyptr) str));
  1515. X}
  1516. X
  1517. static int
  1518. popnum(num)
  1519. int *num; {
  1520. X    if (pos-- == 0)
  1521. X        return 1;
  1522. X    switch (S[pos].type) {
  1523. X    case ARG:
  1524. X        return (getarg(S[pos].argnum, INTEGER, (anyptr) num));
  1525. X    case NUM:
  1526. X        *num = S[pos].value;
  1527. X        return 0;
  1528. X    }
  1529. X    return 1;
  1530. X}
  1531. X
  1532. static int
  1533. cvtchar(sp, c)
  1534. register char *sp, *c; {
  1535. X    switch(*sp) {
  1536. X    case '\\':
  1537. X        switch(*++sp) {
  1538. X        case '\'':
  1539. X        case '$':
  1540. X        case '\\':
  1541. X        case '%':
  1542. X            *c = *sp;
  1543. X            return 2;
  1544. X        case '\0':
  1545. X            *c = '\\';
  1546. X            return 1;
  1547. X        case '0':
  1548. X            if (sp[1] == '0' && sp[2] == '0') {
  1549. X                *c = '\0';
  1550. X                return 4;
  1551. X            }
  1552. X            *c = '\200'; /* '\0' ???? */
  1553. X            return 2;
  1554. X        default:
  1555. X            *c = *sp;
  1556. X            return 2;
  1557. X        }
  1558. X    default:
  1559. X        *c = *sp;
  1560. X        return 1;
  1561. X    }
  1562. X}
  1563. X
  1564. static int termcap;
  1565. X
  1566. X/* sigh... this has got to be the ugliest code I've ever written.
  1567. X   Trying to handle everything has its cost, I guess.
  1568. X
  1569. X   It actually isn't to hard to figure out if a given % code is supposed
  1570. X   to be interpeted with its termcap or terminfo meaning since almost
  1571. X   all terminfo codes are invalid unless something has been pushed on
  1572. X   the stack and termcap strings will never push things on the stack
  1573. X   (%p isn't used by termcap). So where we have a choice we make the
  1574. X   decision by wether or not somthing has been pushed on the stack.
  1575. X   The static variable termcap keeps track of this; it starts out set
  1576. X   to 1 and is incremented as each argument processed by a termcap % code,
  1577. X   however if something is pushed on the stack it's set to 0 and the
  1578. X   rest of the % codes are interpeted as terminfo % codes. Another way
  1579. X   of putting it is that if termcap equals one we haven't decided either
  1580. X   way yet, if it equals zero we're looking for terminfo codes, and if
  1581. X   its greater than 1 we're looking for termcap codes.
  1582. X
  1583. X   Terminfo % codes:
  1584. X
  1585. X    %%    output a '%'
  1586. X    %[[:][-+# ][width][.precision]][doxXs]
  1587. X        output pop according to the printf format
  1588. X    %c    output pop as a char
  1589. X    %'c'    push character constant c.
  1590. X    %{n}    push decimal constant n.
  1591. X    %p[1-9] push paramter [1-9]
  1592. X    %g[a-z] push variable [a-z]
  1593. X    %P[a-z] put pop in variable [a-z]
  1594. X    %l    push the length of pop (a string)
  1595. X    %+    add pop to pop and push the result
  1596. X    %-    subtract pop from pop and push the result
  1597. X    %*    multiply pop and pop and push the result
  1598. X    %&    bitwise and pop and pop and push the result
  1599. X    %|    bitwise or pop and pop and push the result
  1600. X    %^    bitwise xor pop and pop and push the result
  1601. X    %~    push the bitwise not of pop
  1602. X    %=    compare if pop and pop are equal and push the result
  1603. X    %>    compare if pop is less than pop and push the result
  1604. X    %<    compare if pop is greater than pop and push the result
  1605. X    %A    logical and pop and pop and push the result
  1606. X    %O    logical or pop and pop and push the result
  1607. X    %!    push the logical not of pop
  1608. X    %? condition %t if_true [%e if_false] %;
  1609. X        if condtion evaulates as true then evaluate if_true,
  1610. X        else evaluate if_false. elseif's can be done:
  1611. X%? cond %t true [%e cond2 %t true2] ... [%e condN %t trueN] [%e false] %;
  1612. X    %i    add one to parameters 1 and 2. (ANSI)
  1613. X
  1614. X  Termcap Codes:
  1615. X
  1616. X    %%    output a %
  1617. X    %.    output parameter as a character
  1618. X    %d    output parameter as a decimal number
  1619. X    %2    output parameter in printf format %02d
  1620. X    %3    output parameter in printf format %03d
  1621. X    %+x    add the character x to parameter and output it as a character
  1622. X(UW)    %-x    subtract parameter FROM the character x and output it as a char
  1623. X(UW)    %ax    add the character x to parameter
  1624. X(GNU)    %a[+*-/=][cp]x
  1625. X        GNU arithmetic. 
  1626. X(UW)    %sx    subtract parameter FROM the character x
  1627. X    %>xy    if parameter > character x then add character y to parameter
  1628. X    %B    convert to BCD (parameter = (parameter/10)*16 + parameter%16)
  1629. X    %D    Delta Data encode (parameter = parameter - 2*(paramter%16))
  1630. X    %i    increment the first two parameters by one
  1631. X    %n    xor the first two parameters by 0140
  1632. X(GNU)    %m    xor the first two parameters by 0177
  1633. X    %r    swap the first two parameters
  1634. X(GNU)    %b    backup to previous parameter
  1635. X(GNU)    %f    skip this parameter
  1636. X
  1637. X  Note the two definitions of %a, the GNU defintion is used if the characters
  1638. X  after the 'a' are valid, otherwise the UW definition is used.
  1639. X
  1640. X  (GNU) used by GNU Emacs termcap libraries
  1641. X  (UW) used by the University of Waterloo (MFCF) termcap libraries
  1642. X
  1643. X*/
  1644. X
  1645. X#ifdef lint
  1646. X/* VARARGS1 */
  1647. char *
  1648. tparm(str)
  1649. char *str; {
  1650. X#else /* lint */
  1651. X#ifdef USE_STDARG
  1652. X#ifdef USE_PROTOTYPES
  1653. char *tparm(char *str, ...) {
  1654. X#else /* USE_PROTOTYPES */
  1655. char *tparm(str)
  1656. char *str; {
  1657. X#endif /* USE_PROTOTYPES */
  1658. X#else /* USE_STDARG */
  1659. char *tparm(va_alist)
  1660. va_dcl {
  1661. X    char *str;
  1662. X#endif
  1663. X#endif
  1664. X    static char OOPS[] = "OOPS";
  1665. X    static char buf[MAX_LINE];
  1666. X    register char *sp, *dp;
  1667. X    register char *fmt;
  1668. X    char conv_char;
  1669. X    char scan_for;
  1670. X    int scan_depth, if_depth;
  1671. X    static int i, j;
  1672. X    static char *s, c;
  1673. X    char fmt_buf[MAX_LINE];
  1674. X    char sbuf[MAX_LINE];
  1675. X
  1676. X#ifdef lint
  1677. X    scan_depth = 0;
  1678. X#else
  1679. X#ifdef USE_STDARG
  1680. X    va_start(tparm_args, str);
  1681. X#else
  1682. X    va_start(tparm_args);
  1683. X    str = (char *) va_arg(tparm_args, char *);
  1684. X#endif
  1685. X#endif
  1686. X
  1687. X    sp = str;
  1688. X    dp = buf;
  1689. X    scan_for = 0;
  1690. X    if_depth = 0;
  1691. X    argcnt = 0;
  1692. X    pos = 0;
  1693. X    termcap = 1;
  1694. X    while(*sp != '\0') {
  1695. X        switch(*sp) {
  1696. X        case '\\':
  1697. X            if (scan_for) {
  1698. X                if (*++sp != '\0')
  1699. X                    sp++;
  1700. X                break;
  1701. X            }
  1702. X            *dp++ = *sp++;
  1703. X            if (*sp != '\0')
  1704. X                *dp++ = *sp++;
  1705. X            break;
  1706. X        case '%':
  1707. X            sp++;
  1708. X            if (scan_for) {
  1709. X                if (*sp == scan_for && if_depth == scan_depth) {
  1710. X                    if (scan_for == ';')
  1711. X                        if_depth--;
  1712. X                    scan_for = 0;
  1713. X                } else if (*sp == '?')
  1714. X                    if_depth++;
  1715. X                else if (*sp == ';') {
  1716. X                    if (if_depth == 0)
  1717. X                        return OOPS;
  1718. X                    else
  1719. X                        if_depth--;
  1720. X                }
  1721. X                sp++;
  1722. X                break;
  1723. X            }
  1724. X            fmt = NULL;
  1725. X            switch(*sp) {
  1726. X            case '%':
  1727. X                *dp++ = *sp++;
  1728. X                break;
  1729. X            case '+':
  1730. X                if (!termcap) {
  1731. X                    if (popnum(&j) || popnum(&i))
  1732. X                        return OOPS;
  1733. X                    i += j;
  1734. X                    if (pushnum(i))
  1735. X                        return OOPS;
  1736. X                    sp++;
  1737. X                    break;
  1738. X                }
  1739. X                ;/* FALLTHROUGH */
  1740. X            case 'C':
  1741. X                if (*sp == 'C') { 
  1742. X                    if (getarg(termcap - 1, INTEGER, &i))
  1743. X                        return OOPS;
  1744. X                    if (i >= 96) {
  1745. X                        i /= 96;
  1746. X                        if (i == '$')
  1747. X                            *dp++ = '\\';
  1748. X                        *dp++ = i;
  1749. X                    }
  1750. X                }
  1751. X                fmt = "%c";
  1752. X                /* FALLTHROUGH */
  1753. X            case 'a':
  1754. X                if (!termcap)
  1755. X                    return OOPS;
  1756. X                if (getarg(termcap - 1, INTEGER, (anyptr) &i))
  1757. X                    return OOPS;
  1758. X                if (*++sp == '\0')
  1759. X                    return OOPS;
  1760. X                if ((sp[1] == 'p' || sp[1] == 'c')
  1761. X                        && sp[2] != '\0' && fmt == NULL) {
  1762. X                    /* GNU aritmitic parameter, what they
  1763. X                       realy need is terminfo.          */
  1764. X                    int val, lc;
  1765. X                    if (sp[1] == 'p'
  1766. X                        && getarg(termcap - 1 + sp[2] - '@',
  1767. X                              INTEGER, (anyptr) &val))
  1768. X                        return OOPS;
  1769. X                    if (sp[1] == 'c') {
  1770. X                        lc = cvtchar(sp + 2, &c) + 2;
  1771. X                    /* Mask out 8th bit so \200 can be
  1772. X                       used for \0 as per GNU doc's    */
  1773. X                        val = c & 0177;
  1774. X                    } else
  1775. X                        lc = 2;
  1776. X                    switch(sp[0]) {
  1777. X                    case '=':
  1778. X                        break;
  1779. X                    case '+':
  1780. X                        val = i + val;
  1781. X                        break;
  1782. X                    case '-':
  1783. X                        val = i - val;
  1784. X                        break;
  1785. X                    case '*':
  1786. X                        val = i * val;
  1787. X                        break;
  1788. X                    case '/':
  1789. X                        val = i / val;
  1790. X                        break;
  1791. X                    default:
  1792. X                    /* Not really GNU's %a after all... */
  1793. X                        lc = cvtchar(sp, &c);
  1794. X                        val = c + i;
  1795. X                        break;
  1796. X                    }
  1797. X                    arg_list[termcap - 1].integer = val;
  1798. X                    sp += lc;
  1799. X                    break;
  1800. X                }
  1801. X                sp += cvtchar(sp, &c);
  1802. X                arg_list[termcap - 1].integer = c + i;
  1803. X                if (fmt == NULL)
  1804. X                    break;
  1805. X                sp--;
  1806. X                /* FALLTHROUGH */
  1807. X            case '-':
  1808. X                if (!termcap) {
  1809. X                    if (popnum(&j) || popnum(&i))
  1810. X                        return OOPS;
  1811. X                    i -= j;
  1812. X                    if (pushnum(i))
  1813. X                        return OOPS;
  1814. X                    sp++;
  1815. X                    break;
  1816. X                }
  1817. X                fmt = "%c";
  1818. X                /* FALLTHROUGH */
  1819. X            case 's':
  1820. X                if (termcap && (fmt == NULL || *sp == '-')) {
  1821. X                    if (getarg(termcap - 1, INTEGER, &i))
  1822. X                        return OOPS;
  1823. X                    if (*++sp == '\0')
  1824. X                        return OOPS;
  1825. X                    sp += cvtchar(sp, &c);
  1826. X                    arg_list[termcap - 1].integer = c - i;
  1827. X                    if (fmt == NULL)
  1828. X                        break;
  1829. X                    sp--;
  1830. X                }
  1831. X                if (!termcap)
  1832. X                    return OOPS;
  1833. X                ;/* FALLTHROUGH */
  1834. X            case '.':
  1835. X                if (termcap && fmt == NULL) 
  1836. X                    fmt = "%c";
  1837. X                ;/* FALLTHROUGH */
  1838. X            case 'd':
  1839. X                if (termcap && fmt == NULL) 
  1840. X                    fmt = "%d";
  1841. X                ;/* FALLTHROUGH */
  1842. X            case '2':
  1843. X                if (termcap && fmt == NULL)
  1844. X                    fmt = "%02d";
  1845. X                ;/* FALLTHROUGH */
  1846. X            case '3':
  1847. X                if (termcap && fmt == NULL) 
  1848. X                    fmt = "%03d";
  1849. X                ;/* FALLTHROUGH */
  1850. X            case ':': case ' ': case '#': case 'u':
  1851. X            case 'x': case 'X': case 'o': case 'c':
  1852. X            case '0': case '1': case '4': case '5':
  1853. X            case '6': case '7': case '8': case '9':
  1854. X                if (fmt == NULL) {
  1855. X                    if (termcap)
  1856. X                        return OOPS;
  1857. X                    if (*sp == ':')
  1858. X                        sp++;
  1859. X                    fmt = fmt_buf;
  1860. X                    *fmt++ = '%';
  1861. X                    while(*sp != 's' && *sp != 'x' && *sp != 'X' && *sp != 'd' && *sp != 'o' && *sp != 'c' && *sp != 'u') {
  1862. X                        if (*sp == '\0')
  1863. X                            return OOPS;
  1864. X                        *fmt++ = *sp++;
  1865. X                    }
  1866. X                    *fmt++ = *sp;
  1867. X                    *fmt = '\0';
  1868. X                    fmt = fmt_buf;
  1869. X                }
  1870. X                conv_char = fmt[strlen(fmt) - 1];
  1871. X                if (conv_char == 's') {
  1872. X                    if (popstring(&s))
  1873. X                        return OOPS;
  1874. X                    sprintf(sbuf, fmt, s);
  1875. X                } else {
  1876. X                    if (termcap) {
  1877. X                        if (getarg(termcap++ - 1,
  1878. X                               INTEGER, &i))
  1879. X                            return OOPS;
  1880. X                    } else
  1881. X                        if (popnum(&i))
  1882. X                            return OOPS;
  1883. X                    if (i == 0 && conv_char == 'c')
  1884. X                        strcpy(sbuf, "\000");
  1885. X                    else
  1886. X                        sprintf(sbuf, fmt, i);
  1887. X                }
  1888. X                sp++;
  1889. X                fmt = sbuf;
  1890. X                while(*fmt != '\0') {
  1891. X                    if (*fmt == '$') 
  1892. X                        *dp++ = '\\';
  1893. X                    *dp++ = *fmt++;
  1894. X                }
  1895. X                break;
  1896. X            case 'r':
  1897. X                if (!termcap || getarg(1, INTEGER, &i))
  1898. X                    return OOPS;
  1899. X                arg_list[1].integer = arg_list[0].integer;
  1900. X                arg_list[0].integer = i;
  1901. X                sp++;
  1902. X                break;
  1903. X            case 'i':
  1904. X                if (getarg(1, INTEGER, &i)
  1905. X                    || arg_list[0].type != INTEGER)
  1906. X                    return OOPS;
  1907. X                arg_list[1].integer++;
  1908. X                arg_list[0].integer++;
  1909. X                sp++;
  1910. X                break;
  1911. X            case 'n':
  1912. X                if (!termcap || getarg(1, INTEGER, &i))
  1913. X                    return OOPS;
  1914. X                arg_list[0].integer ^= 0140;
  1915. X                arg_list[1].integer ^= 0140;
  1916. X                sp++;
  1917. X                break;
  1918. X            case '>':
  1919. X                if (!termcap) {
  1920. X                    if (popnum(&j) || popnum(&i))
  1921. X                        return OOPS;
  1922. X                    i = (i > j);
  1923. X                    if (pushnum(i))
  1924. X                        return OOPS;
  1925. X                    sp++;
  1926. X                    break;
  1927. X                }
  1928. X                if (getarg(termcap-1, INTEGER, &i))
  1929. X                    return OOPS;
  1930. X                sp += cvtchar(sp, &c);
  1931. X                if (i > c) {
  1932. X                    sp += cvtchar(sp, &c);
  1933. X                    arg_list[termcap-1].integer += c;
  1934. X                } else
  1935. X                    sp += cvtchar(sp, &c);
  1936. X                sp++;
  1937. X                break;
  1938. X            case 'B':
  1939. X                if (!termcap || getarg(termcap-1, INTEGER, &i))
  1940. X                    return OOPS;
  1941. X                arg_list[termcap-1].integer = 16*(i/10)+i%10;
  1942. X                sp++;
  1943. X                break;
  1944. X            case 'D':
  1945. X                if (!termcap || getarg(termcap-1, INTEGER, &i))
  1946. X                    return OOPS;
  1947. X                arg_list[termcap-1].integer = i - 2 * (i % 16);
  1948. X                sp++;
  1949. X                break;
  1950. X            case 'p':
  1951. X                if (termcap > 1)
  1952. X                    return OOPS;
  1953. X                if (*++sp == '\0')
  1954. X                    return OOPS;
  1955. X                if (*sp == '0')
  1956. X                    i = 9;
  1957. X                else
  1958. X                    i = *sp - '1';
  1959. X                if (i < 0 || i > 9)
  1960. X                    return OOPS;
  1961. X                if (pusharg(i))
  1962. X                    return OOPS;
  1963. X                termcap = 0;
  1964. X                sp++;
  1965. X                break;
  1966. X            case 'P':
  1967. X                if (termcap || *++sp == '\0')
  1968. X                    return OOPS;
  1969. X                i = *sp++ - 'a';
  1970. X                if (i < 0 || i > 25)
  1971. X                    return OOPS;
  1972. X                if (pos-- == 0)
  1973. X                    return OOPS;
  1974. X                switch(vars[i].type = S[pos].type) {
  1975. X                case ARG:
  1976. X                    vars[i].argnum = S[pos].argnum;
  1977. X                    break;
  1978. X                case NUM:
  1979. X                    vars[i].value = S[pos].value;
  1980. X                    break;
  1981. X                }
  1982. X                break;
  1983. X            case 'g':
  1984. X                if (termcap || *++sp == '\0')
  1985. X                    return OOPS;
  1986. X                i = *sp++ - 'a';
  1987. X                if (i < 0 || i > 25)
  1988. X                    return OOPS;
  1989. X                switch(vars[i].type) {
  1990. X                case ARG:
  1991. X                    if (pusharg(vars[i].argnum))
  1992. X                        return OOPS;
  1993. X                    break;
  1994. X                case NUM:
  1995. X                    if (pushnum(vars[i].value))
  1996. X                        return OOPS;
  1997. X                    break;
  1998. X                }
  1999. X                break;
  2000. X            case '\'':
  2001. X                if (termcap > 1)
  2002. X                    return OOPS;
  2003. X                if (*++sp == '\0')
  2004. X                    return OOPS;
  2005. X                sp += cvtchar(sp, &c);
  2006. X                if (pushnum(c) || *sp++ != '\'')
  2007. X                    return OOPS;
  2008. X                termcap = 0;
  2009. X                break;
  2010. X            case '{':
  2011. X                if (termcap > 1)
  2012. X                    return OOPS;
  2013. X                i = 0;
  2014. X                sp++;
  2015. X                while(isdigit(*sp))
  2016. X                    i = 10 * i + *sp++ - '0';
  2017. X                if (*sp++ != '}' || pushnum(i))
  2018. X                    return OOPS;
  2019. X                termcap = 0;
  2020. X                break;
  2021. X            case 'l':
  2022. X                if (termcap || popstring(&s))
  2023. X                    return OOPS;
  2024. X                i = strlen(s);
  2025. X                if (pushnum(i))
  2026. X                    return OOPS;
  2027. X                sp++;
  2028. X                break;
  2029. X            case '*':
  2030. X                if (termcap || popnum(&j) || popnum(&i))
  2031. X                    return OOPS;
  2032. X                i *= j;
  2033. X                if (pushnum(i))
  2034. X                    return OOPS;
  2035. X                sp++;
  2036. X                break;
  2037. X            case '/':
  2038. X                if (termcap || popnum(&j) || popnum(&i))
  2039. X                    return OOPS;
  2040. X                i /= j;
  2041. X                if (pushnum(i))
  2042. X                    return OOPS;
  2043. X                sp++;
  2044. X                break;
  2045. X            case 'm':
  2046. X                if (termcap) {
  2047. X                    if (getarg(1, INTEGER, &i))
  2048. X                        return OOPS;
  2049. X                    arg_list[0].integer ^= 0177;
  2050. X                    arg_list[1].integer ^= 0177;
  2051. X                    sp++;
  2052. X                    break;
  2053. X                }
  2054. X                if (popnum(&j) || popnum(&i))
  2055. X                    return OOPS;
  2056. X                i %= j;
  2057. X                if (pushnum(i))
  2058. X                    return OOPS;
  2059. X                sp++;
  2060. X                break;
  2061. X            case '&':
  2062. X                if (popnum(&j) || popnum(&i))
  2063. X                    return OOPS;
  2064. X                i &= j;
  2065. X                if (pushnum(i))
  2066. X                    return OOPS;
  2067. X                sp++;
  2068. X                break;
  2069. X            case '|':
  2070. X                if (popnum(&j) || popnum(&i))
  2071. X                    return OOPS;
  2072. X                i |= j;
  2073. X                if (pushnum(i))
  2074. X                    return OOPS;
  2075. X                sp++;
  2076. X                break;
  2077. X            case '^':
  2078. X                if (popnum(&j) || popnum(&i))
  2079. X                    return OOPS;
  2080. X                i ^= j;
  2081. X                if (pushnum(i))
  2082. X                    return OOPS;
  2083. X                sp++;
  2084. X                break;
  2085. X            case '=':
  2086. X                if (popnum(&j) || popnum(&i))
  2087. X                    return OOPS;
  2088. X                i = (i == j);
  2089. X                if (pushnum(i))
  2090. X                    return OOPS;
  2091. X                sp++;
  2092. X                break;
  2093. X            case '<':
  2094. X                if (popnum(&j) || popnum(&i))
  2095. X                    return OOPS;
  2096. X                i = (i < j);
  2097. X                if (pushnum(i))
  2098. X                    return OOPS;
  2099. X                sp++;
  2100. X                break;
  2101. X            case 'A':
  2102. X                if (popnum(&j) || popnum(&i))
  2103. X                    return OOPS;
  2104. X                i = (i && j);
  2105. X                if (pushnum(i))
  2106. X                    return OOPS;
  2107. X                sp++;
  2108. X                break;
  2109. X            case 'O':
  2110. X                if (popnum(&j) || popnum(&i))
  2111. X                    return OOPS;
  2112. X                i = (i || j);
  2113. X                if (pushnum(i))
  2114. X                    return OOPS;
  2115. X                sp++;
  2116. X                break;
  2117. X            case '!':
  2118. X                if (popnum(&i))
  2119. X                    return OOPS;
  2120. X                i = !i;
  2121. X                if (pushnum(i))
  2122. X                    return OOPS;
  2123. X                sp++;
  2124. X                break;
  2125. X            case '~':
  2126. X                if (popnum(&i))
  2127. X                    return OOPS;
  2128. X                i = ~i;
  2129. X                if (pushnum(i))
  2130. X                    return OOPS;
  2131. X                sp++;
  2132. X                break;
  2133. X            case '?':
  2134. X                if (termcap > 1)
  2135. X                    return OOPS;
  2136. X                termcap = 0;
  2137. X                if_depth++;
  2138. X                sp++;
  2139. X                break;
  2140. X            case 't':
  2141. X                if (popnum(&i) || if_depth == 0)
  2142. X                    return OOPS;
  2143. X                if (!i) {
  2144. X                    scan_for = 'e';
  2145. X                    scan_depth = if_depth;
  2146. X                }
  2147. X                sp++;
  2148. X                break;
  2149. X            case 'e':
  2150. X                if (if_depth == 0)
  2151. X                    return OOPS;
  2152. X                scan_for = ';';
  2153. X                scan_depth = if_depth;
  2154. X                sp++;
  2155. X                break;
  2156. X            case ';':
  2157. X                if (if_depth-- == 0)
  2158. X                    return OOPS;
  2159. X                sp++;
  2160. X                break;
  2161. X            case 'b':
  2162. X                if (--termcap < 1)
  2163. X                    return OOPS;
  2164. X                sp++;
  2165. X                break;
  2166. X            case 'f':
  2167. X                if (!termcap++)
  2168. X                    return OOPS;
  2169. X                sp++;
  2170. X                break;
  2171. X            }
  2172. X            break;
  2173. X        default:
  2174. X            if (scan_for)
  2175. X                sp++;
  2176. X            else
  2177. X                *dp++ = *sp++;
  2178. X            break;
  2179. X        }
  2180. X    }
  2181. X    va_end(tparm_args);
  2182. X    *dp = '\0';
  2183. X    return buf;
  2184. X}
  2185. X
  2186. X#ifdef TEST
  2187. X
  2188. void
  2189. putch(c)
  2190. int c; {
  2191. X    c &= 0xff;
  2192. X    if (c > 127 || c < 0) {
  2193. X        printf("\\%03o", c);
  2194. X    } else if (c < 32) {
  2195. X        printf("^%c", c + '@');
  2196. X    } else if (c == 127) {
  2197. X        printf("^?");
  2198. X    } else {
  2199. X        putchar(c);
  2200. X    }
  2201. X}
  2202. X
  2203. char line[MAX_LINE];
  2204. X
  2205. int
  2206. main(argc, argv)
  2207. int argc;
  2208. char **argv; {
  2209. X    register char *sp;
  2210. X    putchar('\n');
  2211. X
  2212. X    while(gets(line) != NULL) {
  2213. X        sp = tparm(line, 1, -2, 30, 0, "bob was here");
  2214. X        while(*sp)
  2215. X            putch(*sp++);
  2216. X        putchar('\n');
  2217. X    }
  2218. X    return 0;
  2219. X}
  2220. X#endif
  2221. END_OF_FILE
  2222. if test 16639 -ne `wc -c <'tparm.c'`; then
  2223.     echo shar: \"'tparm.c'\" unpacked with wrong size!
  2224. fi
  2225. # end of 'tparm.c'
  2226. fi
  2227. if test -f 'tset.c' -a "${1}" != "-c" ; then 
  2228.   echo shar: Will not clobber existing file \"'tset.c'\"
  2229. else
  2230. echo shar: Extracting \"'tset.c'\" \(15371 characters\)
  2231. sed "s/^X//" >'tset.c' <<'END_OF_FILE'
  2232. X/*
  2233. X * tset.c
  2234. X * 
  2235. X * By Ross Ridge
  2236. X * Public Domain
  2237. X * 92/02/19 18:53:12
  2238. X *
  2239. X */
  2240. X
  2241. X#define NOTLIB
  2242. X
  2243. X#include "defs.h"
  2244. X
  2245. static const char SCCSid[] = "@(#) mytinfo tset.c 3.3 92/02/19 public domain, By Ross Ridge";
  2246. X
  2247. X#define SINGLE
  2248. X#include "term.h"
  2249. X
  2250. X#include <ctype.h>
  2251. X
  2252. X#ifdef USE_TERMIO
  2253. X
  2254. X#ifndef ICANON
  2255. X#include <termio.h>
  2256. X#endif
  2257. X
  2258. X#undef USE_SUSPEND
  2259. X#ifdef VSUSP
  2260. X#define USE_SUSPEND
  2261. X#endif
  2262. X
  2263. X#define USE_INTERRUPT
  2264. X
  2265. X#ifdef TCSETS
  2266. X#define USE_TERMIOS
  2267. X#else
  2268. X#undef USE_SUSPEND
  2269. X#endif
  2270. X
  2271. X#else /* USE_TERMIO */
  2272. X#ifdef USE_SGTTY
  2273. X
  2274. X#ifndef CBREAK
  2275. X#include <sgtty.h>
  2276. X#endif
  2277. X
  2278. X#undef USE_INTERRUPT
  2279. X#ifdef TIOCGETC
  2280. X#define USE_INTERRUPT
  2281. X#endif
  2282. X
  2283. X#undef USE_SUSPEND
  2284. X#ifdef TIOCGLTC
  2285. X#define USE_SUSPEND
  2286. X#endif
  2287. X
  2288. X#undef USE_NEWBSDTTY
  2289. X#ifdef TIOCSETD
  2290. X#ifdef NTTYDISC
  2291. X#define USE_NEWBSDTTY
  2292. X#endif
  2293. X#endif
  2294. X
  2295. X#else /* USE_SGTTY */
  2296. X
  2297. X#undef USE_SUSPEND
  2298. X#define USE_NOTTY
  2299. X
  2300. X#endif /* else USE_SGTTY */
  2301. X#endif /* else USE_TERMIO */
  2302. X
  2303. X#ifndef key_interrupt_char
  2304. X#undef USE_INTERRUPT
  2305. X#endif
  2306. X
  2307. X#ifndef key_suspend_char
  2308. X#undef USE_SUSPEND
  2309. X#endif
  2310. X
  2311. char *term;
  2312. int asked = 0;
  2313. long baudrate;
  2314. X
  2315. X#ifndef USE_STDLIB
  2316. X#ifdef USE_PROTOTYPES
  2317. long atol(char const *);
  2318. X#else
  2319. long atol();
  2320. X#endif
  2321. X#endif
  2322. X
  2323. X#define OUTPUT_TERM    1
  2324. X#define OUTPUT_SHELL    2
  2325. X#define OUTPUT_TERMCAP    3
  2326. X
  2327. X#define PUTS(s)        tputs(s, 1, putch)
  2328. X#define PUTCHAR(c)    putc(c, stderr)
  2329. X#define FLUSH        fflush(stderr)
  2330. X
  2331. X#ifdef USE_SMALLMEM
  2332. extern unsigned short _baud_tbl[];
  2333. X#else
  2334. extern long _baud_tbl[];
  2335. X#endif
  2336. X
  2337. extern void (*cleanup)();
  2338. X
  2339. static void
  2340. clean(e)
  2341. int e; {
  2342. X    return;
  2343. X}
  2344. X
  2345. static int
  2346. putch(c)
  2347. int c; {
  2348. X    return putc(c, stderr);
  2349. X}
  2350. X
  2351. void
  2352. set_term(name, query)
  2353. char *name;
  2354. int query; {
  2355. X    static char buf[MAX_LINE];
  2356. X    char *s, *t;
  2357. X
  2358. X    if (query) {
  2359. X        fprintf(stderr, "TERM = (%s) ", name);
  2360. X        fflush(stderr);
  2361. X        asked = 1;
  2362. X        if (gets(buf) != NULL) {
  2363. X            s = buf;
  2364. X            while(*s != '\0' && isspace(*s))
  2365. X                s++;
  2366. X            t = s;
  2367. X            while(*s != '\0' && !isspace(*s))
  2368. X                s++;
  2369. X            *s = '\0';
  2370. X            if (*t != '\0') {
  2371. X                term = t;
  2372. X                return;
  2373. X            }
  2374. X        }
  2375. X    }
  2376. X    term = strcpy(buf, name);
  2377. X}
  2378. X
  2379. int
  2380. map_term(map, ask)
  2381. char *map;
  2382. int ask; {
  2383. X    char *type;
  2384. X    char test = 0;
  2385. X    char *baud = NULL;
  2386. X
  2387. X    type = map;
  2388. X#ifndef USE_NOTTY
  2389. X    while(*map && strchr(">@<!:?", *map) == NULL)
  2390. X        map++;
  2391. X    if (*map != '\0' && *map != ':' && *map != '?') {
  2392. X        if (*map == '!') {
  2393. X            switch(*++map) {
  2394. X            case '>': test = 'g'; break;
  2395. X            case '@': test = 'n'; break;
  2396. X            case '<': test = 'l'; break;
  2397. X            default:
  2398. X                quit(-1, "bad argument to 'm' switch");
  2399. X            }
  2400. X        } else
  2401. X            test = *map;
  2402. X        *map++ = '\0';
  2403. X        baud = map;
  2404. X        while(*map && *map != ':')
  2405. X            map++;
  2406. X    }
  2407. X
  2408. X#else
  2409. X    while(*map && *map != ':' && *map != '?')
  2410. X        map++;
  2411. X#endif
  2412. X
  2413. X    if (*map == ':')
  2414. X        *map++ = '\0';
  2415. X    if (*map == '?') {
  2416. X        ask = 1;
  2417. X        *map++ = '\0';
  2418. X    }
  2419. X    if (*map == '\0') 
  2420. X        quit(-1, "bad argument to 'm' switch");
  2421. X
  2422. X    if (type[0] != '\0' && strcmp(type, term) != 0) {
  2423. X        return 0;
  2424. X    }
  2425. X
  2426. X#ifndef USE_NOTTY
  2427. X    switch(test) {
  2428. X    case '>':
  2429. X        if (baudrate <= atol(baud))
  2430. X            return 0;
  2431. X        break;
  2432. X    case '<':
  2433. X        if (baudrate >= atol(baud))
  2434. X            return 0;
  2435. X        break;
  2436. X    case '@':
  2437. X        if (baudrate != atol(baud))
  2438. X            return 0;
  2439. X        break;
  2440. X    case 'l':
  2441. X        if (baudrate < atol(baud))
  2442. X            return 0;
  2443. X        break;
  2444. X    case 'g':
  2445. X        if (baudrate > atol(baud))
  2446. X            return 0;
  2447. X        break;
  2448. X    case 'n':
  2449. X        if (baudrate == atol(baud))
  2450. X            return 0;
  2451. X        break;
  2452. X    }
  2453. X#endif
  2454. X
  2455. X    set_term(map, ask);
  2456. X    return 1;
  2457. X}
  2458. X
  2459. int
  2460. conv_char(s)
  2461. char *s; {
  2462. X    if (s[0] == '^' && s[1] >= '@' && s[1] <= '\177')
  2463. X        return s[1] & 31;
  2464. X    else if (s[0] == '^' && s[1] == '?')
  2465. X        return '\177';
  2466. X    else if (s[0] != '\0')
  2467. X        return s[0];
  2468. X    else
  2469. X        return -2;
  2470. X}
  2471. X
  2472. char *
  2473. expand_char(c)
  2474. int c; {
  2475. X    static char buf[5];
  2476. X
  2477. X    if (c < 0 || c > 127) {
  2478. X        sprintf(buf, "\\%03o", c & 0177);
  2479. X    } else if (c == 127) {
  2480. X        return "DEL";
  2481. X    } else if (c < 32) {
  2482. X        buf[0] = '^';
  2483. X        buf[1] = c + 64;
  2484. X        buf[2] = '\0';
  2485. X    } else {
  2486. X        buf[0] = c;
  2487. X        buf[1] = '\0';
  2488. X    }
  2489. X
  2490. X    return buf;
  2491. X}
  2492. X
  2493. X#define START     1
  2494. X#define COPY    2
  2495. X#define ESCAPE    3
  2496. X
  2497. void
  2498. compress_buf(buf)
  2499. char *buf; {
  2500. X    char *s, *d;
  2501. X    int state = START;
  2502. X
  2503. X    d = s = buf;
  2504. X
  2505. X    while(*s) {
  2506. X        switch(state) {
  2507. X        case START:
  2508. X            if (isspace(*s) || *s == ':') {
  2509. X                s++;
  2510. X                break;
  2511. X            }
  2512. X            state = COPY;
  2513. X            /* FALLTHROUGH */
  2514. X        case COPY:
  2515. X            switch(*s) {
  2516. X            case '^':
  2517. X            case '\\':
  2518. X                state = ESCAPE;
  2519. X                break;
  2520. X            case ':':
  2521. X                state = START;
  2522. X                break;
  2523. X            }
  2524. X            *d++ = *s++;
  2525. X            break;
  2526. X
  2527. X        case ESCAPE:
  2528. X            *d++ = *s++;
  2529. X            state = COPY;
  2530. X            break;
  2531. X        }
  2532. X    }
  2533. X}
  2534. X
  2535. static void
  2536. usage(e)
  2537. int e; {
  2538. X#ifdef USE_ANSIC
  2539. X    fprintf(stderr, "usage: %s [-] [-"
  2540. X#define ARG(s)    s
  2541. X#else
  2542. X    fprintf(stderr, "usage: %s [-] [-", prg_name);
  2543. X#define ARG(s)    fputs(s, stderr);
  2544. X#endif
  2545. X            ARG("l")
  2546. X#ifndef USE_NOTTY
  2547. X#ifdef USE_NEWBSDTTY
  2548. X            ARG("n")
  2549. X#endif
  2550. X#endif
  2551. X            ARG("rsAI")
  2552. X#ifndef USE_NOTTY
  2553. X            ARG("Q")
  2554. X#endif
  2555. X            ARG("S")
  2556. X#ifndef USE_NOTTY
  2557. X            ARG("T")
  2558. X#endif
  2559. X            ARG("]")
  2560. X#ifndef USE_NOTTY
  2561. X            ARG(" [-e[c]] [-E[c]] [-k[c]]")
  2562. X#ifdef USE_INTERRUPT
  2563. X            ARG(" [-i[c]]")
  2564. X#endif
  2565. X#ifdef USE_SUSPEND
  2566. X            ARG(" [-z[c]]")
  2567. X#endif
  2568. X#endif
  2569. X            ARG("\n\t[-m ident")
  2570. X#ifndef USE_NOTTY
  2571. X            ARG("[[!][<@>]speed]")
  2572. X#endif
  2573. X            ARG(":[?]term] [term]\n")
  2574. X#ifdef USE_ANSIC
  2575. X            , prg_name);
  2576. X#endif
  2577. X
  2578. X#undef ARG
  2579. X
  2580. X    return;
  2581. X}
  2582. X
  2583. int
  2584. main(argc, argv)
  2585. int argc;
  2586. char **argv; {
  2587. X    char *s;
  2588. X    int i, j, r, c;
  2589. X    int ask = 0;
  2590. X#ifndef USE_NOTTY
  2591. X    int erase_char = -1;
  2592. X    int erase_if_bs = 0;
  2593. X    int kill_char = -1;
  2594. X#ifdef USE_INTERRUPT
  2595. X    int interrupt_char = -1;
  2596. X#endif
  2597. X#ifdef USE_SUSPEND
  2598. X    int suspend_char = -1;
  2599. X#endif
  2600. X#ifdef USE_NEWBSDTTY
  2601. X    int newbsdtty = 0;
  2602. X#endif
  2603. X#endif /* !USE_NOTTY */
  2604. X    int output_type = 0;
  2605. X    int no_term_init = 0;
  2606. X    int term_type_is = 0;
  2607. X    int no_set_to = 0;
  2608. X    int reset = 0;
  2609. X    int matched = 0;
  2610. X    int expand_tabs = -1;
  2611. X    int is_csh;
  2612. X#ifndef USE_NOTTTY
  2613. X#ifdef USE_TERMIO
  2614. X#ifdef USE_TERMIOS
  2615. X    struct termios tty;
  2616. X#else
  2617. X    struct termio tty;
  2618. X#endif
  2619. X#else
  2620. X#ifdef USE_SGTTY
  2621. X    struct sgttyb tty;
  2622. X#ifdef USE_INTERRUPT
  2623. X    struct tchars tty2;
  2624. X#endif
  2625. X#ifdef USE_SUSPEND
  2626. X    struct ltchars tty3;
  2627. X#endif
  2628. X#endif /* USE_SGTTY */
  2629. X#endif /* else USE_TERMIO */
  2630. X#endif /* !USE_NOTTY */
  2631. X    struct term_path *path;
  2632. X    char buf[MAX_BUF];
  2633. X    FILE *f;
  2634. X    int datatype;
  2635. X
  2636. X    prg_name = argv[0];
  2637. X    s = strrchr(prg_name, '/');
  2638. X    if (s != NULL && *++s != '\0') {
  2639. X        if (strcmp(s, "reset") == 0) {
  2640. X            reset = 1;
  2641. X        }
  2642. X        prg_name = s;
  2643. X    }
  2644. X
  2645. X    cleanup = clean;
  2646. X
  2647. X#ifndef USE_NOTTY
  2648. X#ifdef USE_TERMIO
  2649. X#ifdef USE_TERMIOS
  2650. X    if (ioctl(2, TCGETS, &tty) == -1)
  2651. X#else
  2652. X    if (ioctl(2, TCGETA, &tty) == -1)
  2653. X#endif
  2654. X    {
  2655. X        quit(errno, "ioctl failed");
  2656. X    }
  2657. X    baudrate = _baud_tbl[tty.c_cflag & CBAUD];
  2658. X#else
  2659. X#ifdef USE_SGTTY
  2660. X    if (gtty(2, &tty) == -1) {
  2661. X        quit(errno, "gtty failed");
  2662. X    }
  2663. X    baudrate = _baud_tbl[tty.sg_ospeed];
  2664. X#ifdef USE_INTERRUPT
  2665. X    if (ioctl(2, TIOCGETC, &tty2) == -1) {
  2666. X        quit(errno, "ioctl failed");
  2667. X    }
  2668. X#endif
  2669. X#ifdef USE_SUSPEND
  2670. X    if (ioctl(2, TIOCGLTC, &tty3) == -1) {
  2671. X        quit(errno, "ioctl failed");
  2672. X    }
  2673. X#endif
  2674. X#endif /* USE_SGTTY */
  2675. X#endif /* else USE_TERMIO */
  2676. X#endif /* !USE_NOTTY */
  2677. X
  2678. X    term = getenv("TERM");
  2679. X
  2680. X    cleanup = usage;
  2681. X
  2682. X    for(i = 1; i < argc; i++) {
  2683. X        if (argv[i][0] != '-') {
  2684. X            if (term == NULL) {
  2685. X                term = argv[i];
  2686. X            }
  2687. X            continue;
  2688. X        }
  2689. X        s = argv[i] + 1;
  2690. X        if (*s == '\0') {
  2691. X            output_type = OUTPUT_TERM;
  2692. X            continue;
  2693. X        }
  2694. X        while (*s != '\0') {
  2695. X            switch(*s++) {
  2696. X            case 'A':
  2697. X                ask = 1;
  2698. X                continue;
  2699. X#ifndef USE_NOTTY
  2700. X            case 'E':
  2701. X                erase_if_bs = 1;
  2702. X                /* FALLTHROUGH */
  2703. X            case 'e':
  2704. X                erase_char = conv_char(s);
  2705. X                break;
  2706. X            case 'k':
  2707. X                kill_char = conv_char(s);
  2708. X                break;
  2709. X#ifdef USE_INTERRUPT
  2710. X            case 'i':
  2711. X                interrupt_char = conv_char(s);
  2712. X                break;
  2713. X#endif
  2714. X#ifdef USE_SUSPEND
  2715. X            case 'z':
  2716. X                suspend_char = conv_char(s);
  2717. X                break;
  2718. X#endif
  2719. X            case 'T':
  2720. X                erase_char = kill_char
  2721. X#ifdef USE_INTERRUPT
  2722. X                    = interrupt_char
  2723. X#endif
  2724. X#ifdef USE_SUSPEND
  2725. X                    = suspend_char
  2726. X#endif
  2727. X                    = -2;
  2728. X                continue;
  2729. X#ifdef USE_NEWBSDTTY
  2730. X            case 'n':
  2731. X                newbsdtty = 1;
  2732. X                continue;
  2733. X#endif
  2734. X            case 'Q':
  2735. X                no_set_to = 1;
  2736. X                continue;
  2737. X#endif /* !USE_NOTTY */
  2738. X            case 'l':
  2739. X            case 'I':
  2740. X                no_term_init = 1;
  2741. X                continue;
  2742. X            case 'r':
  2743. X                term_type_is = 1;
  2744. X                continue;
  2745. X            case 's':
  2746. X                output_type = OUTPUT_SHELL;
  2747. X                continue;
  2748. X            case 'S':
  2749. X                output_type = OUTPUT_TERMCAP;
  2750. X                continue;
  2751. X            case 'm':
  2752. X                if (*s == '\0') {
  2753. X                    if (i == argc - 1) {
  2754. X                        quit(-1, "'m' switch requires an argument.");
  2755. X                    }
  2756. X                    s = argv[++i];
  2757. X                }
  2758. X                if (!matched) {
  2759. X                    matched = map_term(s, ask);
  2760. X                }
  2761. X                break;
  2762. X            default:
  2763. X                quit(-1, "unknown switch '%c'", s[-1]);
  2764. X                break;
  2765. X            }
  2766. X            break;
  2767. X        }
  2768. X    }
  2769. X    
  2770. X    cleanup = clean;
  2771. X
  2772. X    path = _buildpath("$MYTERMINFO", 2,
  2773. X              "$TERMINFO", 2,
  2774. X              "$TERMCAP", 1,
  2775. X#ifdef TERMINFODIR
  2776. X              TERMINFODIR, 0,
  2777. X#endif
  2778. X#ifdef TERMCAPFILE
  2779. X              TERMCAPFILE, 0,
  2780. X#endif
  2781. X#ifdef TERMINFOSRC
  2782. X              TERMINFOSRC, 0,
  2783. X#endif
  2784. X              NULL, -1);
  2785. X
  2786. X    if (path == NULL) {
  2787. X        quit(-1, "malloc error");
  2788. X    }
  2789. X
  2790. X    do {
  2791. X        if (term == NULL) {
  2792. X            term = "unknown";
  2793. X        }
  2794. X
  2795. X        if (ask && !asked) {
  2796. X            set_term(term, 1);
  2797. X        }
  2798. X
  2799. X        datatype = _fillterm(term, path, buf);
  2800. X
  2801. X        switch(datatype) {
  2802. X        case -3:
  2803. X            quit(-1, "malloc error");
  2804. X            /* NOTREACHED */
  2805. X        case -2:
  2806. X            quit(-1, "database in bad format");
  2807. X            /* NOTREACHED */
  2808. X        case -1:
  2809. X            /* quit(-1, "database not found"); */
  2810. X        case 0:
  2811. X            if (ask || asked) {
  2812. X                fprintf(stderr, "terminal type '%s' unknown.\n",
  2813. X                    term);
  2814. X                term = NULL;
  2815. X                ask = 1;
  2816. X                asked = 0;
  2817. X            } else {
  2818. X                quit(-1, "terminal type '%s' unknown.\n", term);
  2819. X            }
  2820. X            break;
  2821. X        case 1:
  2822. X        case 2:
  2823. X        case 3:
  2824. X            break;
  2825. X        default:
  2826. X            quit(-1, "oops...");
  2827. X        }
  2828. X    } while(term == NULL);
  2829. X
  2830. X    _delpath(path);
  2831. X
  2832. X    cur_term->baudrate = baudrate;
  2833. X
  2834. X    if (!no_term_init) {
  2835. X
  2836. X        if (init_prog != NULL) {
  2837. X            system(init_prog);
  2838. X        }
  2839. X        FLUSH;
  2840. X
  2841. X        if (reset && reset_1string != NULL) {
  2842. X            PUTS(reset_1string);
  2843. X        } else if (init_1string != NULL) {
  2844. X            PUTS(init_1string);
  2845. X        }
  2846. X        FLUSH;
  2847. X
  2848. X        if (reset && reset_2string != NULL) {
  2849. X            PUTS(reset_2string);
  2850. X        } else if (init_2string != NULL) {
  2851. X            PUTS(init_2string);
  2852. X        }
  2853. X        FLUSH;
  2854. X
  2855. X        if (set_lr_margin != NULL) {
  2856. X            PUTS(tparm(set_lr_margin, 0, columns - 1));
  2857. X        } else if (set_left_margin_parm != NULL
  2858. X               && set_right_margin_parm != NULL) {
  2859. X            PUTS(tparm(set_left_margin_parm, 0));
  2860. X            PUTS(tparm(set_right_margin_parm, columns - 1));
  2861. X        } else if (clear_margins != NULL && set_left_margin != NULL
  2862. X               && set_right_margin != NULL) {
  2863. X            PUTS(clear_margins);
  2864. X            if (carriage_return != NULL) {
  2865. X                PUTS(carriage_return);
  2866. X            } else {
  2867. X                PUTCHAR('\r');
  2868. X            }
  2869. X            PUTS(set_left_margin);
  2870. X            if (parm_right_cursor) {
  2871. X                PUTS(tparm(parm_right_cursor, columns - 1));
  2872. X            } else {
  2873. X                for(i = 0; i < columns - 1; i++) {
  2874. X                    PUTCHAR(' ');
  2875. X                }
  2876. X            }
  2877. X            PUTS(set_right_margin);
  2878. X            if (carriage_return != NULL) {
  2879. X                PUTS(carriage_return);
  2880. X            } else {
  2881. X                PUTCHAR('\r');
  2882. X            }
  2883. X        }
  2884. X        FLUSH;
  2885. X
  2886. X        if (init_tabs != 8) {
  2887. X            if (clear_all_tabs != NULL && set_tab != NULL) {
  2888. X                if (carriage_return != NULL) {
  2889. X                    PUTS(carriage_return);
  2890. X                } else {
  2891. X                    PUTCHAR('\r');
  2892. X                }
  2893. X                PUTS(clear_all_tabs);
  2894. X                PUTS(set_tab);
  2895. X                for(i = 8; i < columns - 1; i += 8) {
  2896. X                    if (parm_right_cursor) {
  2897. X                        PUTS(tparm(parm_right_cursor,
  2898. X                             8));
  2899. X                    } else {
  2900. X                        for(j = 0; j < 8; j++) {
  2901. X                            PUTCHAR(' ');
  2902. X                        }
  2903. X                    }
  2904. X                    PUTS(set_tab);
  2905. X                }
  2906. X                if (carriage_return != NULL) {
  2907. X                    PUTS(carriage_return);
  2908. X                } else {
  2909. X                    PUTCHAR('\r');
  2910. X                }
  2911. X                expand_tabs = 0;
  2912. X                FLUSH;
  2913. X            } else {
  2914. X                expand_tabs = 1;
  2915. X            }
  2916. X        } else {
  2917. X            expand_tabs = 0;
  2918. X        }
  2919. X
  2920. X        if (reset && reset_file != NULL) {
  2921. X            f = fopen(reset_file, "r");
  2922. X            if (f == NULL) {
  2923. X                quit(errno, "Can't open reset_file: '%s'",
  2924. X                     reset_file);
  2925. X            }
  2926. X            while((c = fgetc(f)) != EOF) {
  2927. X                PUTCHAR(c);
  2928. X            }
  2929. X            fclose(f);
  2930. X        } else if (init_file != NULL) {
  2931. X            f = fopen(init_file, "r");
  2932. X            if (f == NULL) {
  2933. X                quit(errno, "Can't open init_file: '%s'",
  2934. X                     init_file);
  2935. X            }
  2936. X            while((c = fgetc(f)) != EOF) {
  2937. X                PUTCHAR(c);
  2938. X            }
  2939. X            fclose(f);
  2940. X        }
  2941. X        FLUSH;
  2942. X
  2943. X        if (reset && reset_3string != NULL) {
  2944. X            PUTS(reset_3string);
  2945. X        } else if (init_2string != NULL) {
  2946. X            PUTS(init_3string);
  2947. X        }
  2948. X        FLUSH;
  2949. X    }
  2950. X
  2951. X    if (term_type_is) {
  2952. X        fprintf(stderr, "Terminal type is %s\n", term);
  2953. X    }
  2954. X
  2955. X#ifndef USE_NOTTY
  2956. X#ifdef USE_TERMIO
  2957. X
  2958. X    if (expand_tabs == 0 && (tty.c_cflag & TABDLY) == TAB3) {
  2959. X        tty.c_cflag = tty.c_cflag & ~TABDLY;
  2960. X    } else if (expand_tabs == 1) {
  2961. X        tty.c_cflag = (tty.c_cflag & ~TABDLY) | TAB3;
  2962. X    }
  2963. X
  2964. X#define SETTO(v, m, t, c) (c != tty.c_cc[v] ? (tty.c_cc[v] = c,          \
  2965. X               !no_set_to ? fprintf(stderr, "%s set to %s\n", t, \
  2966. X                         expand_char(c)) : 0) : 0)
  2967. X
  2968. X#endif
  2969. X#ifdef USE_SGTTY
  2970. X    
  2971. X#ifdef USE_NEWBSDTTY
  2972. X    if (newbsdtty) {
  2973. X        if (ioctl(2, TIOCSETD, NTTYDISC) == -1) {
  2974. X            quit(errno, "Can't switch tty to new line disc.");
  2975. X        }
  2976. X    }
  2977. X#endif
  2978. X
  2979. X    if (expand_tabs == 0) {
  2980. X        tty.sg_flags &= ~XTABS;
  2981. X    } else if (expand_tabs == 1) {
  2982. X        tty.sg_flags |= XTABS;
  2983. X    }
  2984. X
  2985. X#define SETTO(v, m, t, c) (c != m ? (m = c,                  \
  2986. X               !no_set_to ? fprintf(stderr, "%s set to %s\n", t, \
  2987. X                         expand_char(c)) : 0) : 0)
  2988. X#endif
  2989. X
  2990. X    if (erase_char != -1
  2991. X            && (!erase_if_bs || backspaces_with_bs
  2992. X            || (cursor_left == NULL && cursor_left[0] != '\b'))) {
  2993. X        if (erase_char != -2) {
  2994. X            c = erase_char;
  2995. X        } else if (cursor_left == NULL || cursor_left[0] == '\0'
  2996. X             || cursor_left[1] != '\0') {
  2997. X            c = '\b';
  2998. X        } else {
  2999. X            c = cursor_left[0];
  3000. X        }
  3001. X        SETTO(VERASE, tty.sg_erase, "Erase", c);
  3002. X    }
  3003. X
  3004. X    if (kill_char != -1) {
  3005. X        if (kill_char != -2) {
  3006. X            c = kill_char;
  3007. X        } else if (key_kill_char == NULL || key_kill_char[0] == '\0'
  3008. X               || key_kill_char[1] != '\0') {
  3009. X            c = '\025';
  3010. X        } else {
  3011. X            c = key_kill_char[0];
  3012. X        }
  3013. X        SETTO(VKILL, tty.sg_kill, "Kill", c);
  3014. X    }
  3015. X
  3016. X    
  3017. X#ifdef USE_INTERRUPT
  3018. X    if (interrupt_char != -1) {
  3019. X        if (interrupt_char != -2) {
  3020. X            c = interrupt_char;
  3021. X        } else if (key_interrupt_char == NULL
  3022. X               || key_interrupt_char[0] == '\0'
  3023. X               || key_interrupt_char[1] != '\0') {
  3024. X            c = '\177';
  3025. X        } else {
  3026. X            c = key_interrupt_char[0];
  3027. X        }
  3028. X        SETTO(VINTR, tty2.t_intrc, "Interrupt", c);
  3029. X    }
  3030. X#endif
  3031. X
  3032. X#ifdef USE_SUSPEND
  3033. X    if (suspend_char != -1) {
  3034. X        if (suspend_char != -2) {
  3035. X            c = suspend_char;
  3036. X        } else if (key_suspend_char == NULL
  3037. X               || key_suspend_char[0] == '\0'
  3038. X               || key_suspend_char[1] != '\0') {
  3039. X            c = '\032';
  3040. X        } else {
  3041. X            c = key_suspend_char[0];
  3042. X        }
  3043. X        SETTO(VSUSP, tty3.t_suspc, "Suspend", c);
  3044. X    }
  3045. X#endif
  3046. X
  3047. X#ifdef USE_TERMIO
  3048. X#ifdef USE_TERMIOS
  3049. X    if (ioctl(2, TCSETS, &tty) == -1)
  3050. X#else
  3051. X    if (ioctl(2, TCSETA, &tty) == -1)
  3052. X#endif
  3053. X    {
  3054. X        quit(errno, "ioctl failed");
  3055. X    }
  3056. X#else
  3057. X#ifdef USE_SGTTY
  3058. X    if (stty(2, &tty) == -1) {
  3059. X        quit(errno, "stty failed");
  3060. X    }
  3061. X#ifdef USE_INTERRUPT
  3062. X    if (ioctl(2, TIOCSETC, &tty2) == -1) {
  3063. X        quit(errno, "ioctl failed");
  3064. X    }
  3065. X#endif
  3066. X#ifdef USE_SUSPEND
  3067. X    if (ioctl(2, TIOCSLTC, &tty3) == -1) {
  3068. X        quit(errno, "ioctl failed");
  3069. X    }
  3070. X#endif
  3071. X#endif /* USE_SGTTY */
  3072. X#endif /* else USE_TERMIO */
  3073. X#endif /* !USE_NOTTY */
  3074. X
  3075. X    s = getenv("SHELL");
  3076. X    r = strlen(s);
  3077. X
  3078. X    if (r >= 3 && strcmp("csh", s + r - 3) == 0) {
  3079. X        is_csh = 1;
  3080. X    } else {
  3081. X        is_csh = 0;
  3082. X    }
  3083. X
  3084. X    switch(output_type) {
  3085. X    case OUTPUT_TERM:
  3086. X        fprintf(stdout, "%s\n", term);
  3087. X        break;
  3088. X
  3089. X    case OUTPUT_TERMCAP:
  3090. X        if (is_csh) {
  3091. X            if (datatype == 1) {
  3092. X                compress_buf(buf);
  3093. X                fprintf(stdout, "%s %s", term, buf);
  3094. X            } else {
  3095. X                s = getenv("TERMCAP");
  3096. X                if (s == NULL || *s == '\0') {
  3097. X                    s = ":";
  3098. X                }
  3099. X                fprintf(stdout, "%s %s", term, s);
  3100. X            }
  3101. X            break;
  3102. X        }
  3103. X        /* FALLTHROUGH */
  3104. X    case OUTPUT_SHELL:
  3105. X        if (is_csh) {
  3106. X            fprintf(stdout, "set noglob;\n");
  3107. X            fprintf(stdout, "setenv TERM '%s';\n", term);
  3108. X            if (datatype == 1) {
  3109. X                compress_buf(buf);
  3110. X                fprintf(stdout, "setenv TERMCAP '%s';\n", buf);
  3111. X            }
  3112. X            fprintf(stdout, "unset noglob;\n");
  3113. X        } else {
  3114. X            fprintf(stdout, "export TERM TERMCAP;\n");
  3115. X            fprintf(stdout, "TERM='%s';\n", term);
  3116. X            if (datatype == 1) {
  3117. X                compress_buf(buf);
  3118. X                fprintf(stdout, "TERMCAP='%s';\n", buf);
  3119. X            }
  3120. X        }
  3121. X        break;
  3122. X    }
  3123. X    
  3124. X    return 0;
  3125. X}
  3126. END_OF_FILE
  3127. if test 15371 -ne `wc -c <'tset.c'`; then
  3128.     echo shar: \"'tset.c'\" unpacked with wrong size!
  3129. fi
  3130. # end of 'tset.c'
  3131. fi
  3132. echo shar: End of archive 3 \(of 3\).
  3133. cp /dev/null ark3isdone
  3134. MISSING=""
  3135. for I in 1 2 3 ; do
  3136.     if test ! -f ark${I}isdone ; then
  3137.     MISSING="${MISSING} ${I}"
  3138.     fi
  3139. done
  3140. if test "${MISSING}" = "" ; then
  3141.     echo You have unpacked all 3 archives.
  3142.     rm -f ark[1-9]isdone
  3143. else
  3144.     echo You still need to unpack the following archives:
  3145.     echo "        " ${MISSING}
  3146. fi
  3147. ##  End of shell archive.
  3148. exit 0
  3149.