home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / sources / unix / 278 < prev    next >
Encoding:
Text File  |  1992-12-27  |  62.5 KB  |  3,156 lines

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