home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume03 / tc < prev    next >
Encoding:
Internet Message Format  |  1988-09-11  |  11.3 KB

  1. From: seismo!hao!cisden!lmc
  2. Subject: tc:  termcap capability in scripts
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 46
  7. Submitted by: seismo!hao!cisden!lmc
  8.  
  9.  
  10. tc is a program which inputs arguments denoting termcap capabilities on the
  11. command line and then executes them. It gives shell scripts the same
  12. termcap capabilities as C programs. Included is the program (tc.c) and a
  13. manual page (tc.1). It is compiled with the command:
  14.  
  15.     cc tc.c -o tc -ltermlib
  16.  
  17. : This is a shar archieve.  Extract with sh, not csh.
  18. : The rest of this file will extract:
  19. : tc.c tc.1
  20. echo extracting - tc.c
  21. sed 's/^X//' > tc.c << '~FUNKY STUFF~'
  22. X/*
  23. X *      tc - termcaps for the shell.
  24. X */
  25. X#include <stdio.h>
  26. X#include <ctype.h>
  27. X
  28. Xextern char *tgetdefstr(), *tgetstr(), *tgoto();
  29. Xextern int tgetdefnum(), tgetnum();
  30. X
  31. Xtypedef struct tbl
  32. X{   char *str;
  33. X    short val;
  34. X} lookuptbl;
  35. X
  36. X#define STRING  1
  37. X#define STR1ARG 2
  38. X#define STR2ARG 3
  39. X#define NUMBER  4
  40. X#define FLAG    5
  41. X
  42. Xlookuptbl tcaps[] = {
  43. X    "AL",  STR1ARG,
  44. X    "Bj",  STRING,
  45. X    "Bl",  STRING,
  46. X    "Br",  STRING,
  47. X    "CC",  STRING,
  48. X    "Cj",  STRING,
  49. X    "CM",  STR2ARG,
  50. X    "DC",  STR1ARG,
  51. X    "DL",  STR1ARG,
  52. X    "DO",  STR1ARG,
  53. X    "EP",  FLAG,
  54. X    "Ge",  STRING,
  55. X    "Gs",  STRING,
  56. X    "HD",  FLAG,
  57. X    "Hl",  STRING,
  58. X    "IC",  STR1ARG,
  59. X    "K1",  STRING,
  60. X    "K2",  STRING,
  61. X    "K3",  STRING,
  62. X    "K4",  STRING,
  63. X    "K5",  STRING,
  64. X    "LC",  FLAG,
  65. X    "LE",  STR1ARG,
  66. X    "Lj",  STRING,
  67. X    "NL",  FLAG,
  68. X    "OP",  FLAG,
  69. X    "RI",  STR1ARG,
  70. X    "Rj",  STRING,
  71. X    "SF",  STR1ARG,
  72. X    "SR",  STR1ARG,
  73. X    "Tj",  STRING,
  74. X    "Tl",  STRING,
  75. X    "Tr",  STRING,
  76. X    "UC",  FLAG,
  77. X    "UP",  STR1ARG,
  78. X    "Vl",  STRING,
  79. X    "Xc",  STRING,
  80. X    "ae",  STRING,
  81. X    "al",  STRING,
  82. X    "am",  FLAG,
  83. X    "as",  STRING,
  84. X    "bc",  STRING,
  85. X    "bl",  STRING,
  86. X    "bs",  FLAG,
  87. X    "bt",  STRING,
  88. X    "bw",  FLAG,
  89. X    "cd",  STRING,
  90. X    "ce",  STRING,
  91. X    "ch",  STR1ARG,
  92. X    "cl",  STRING,
  93. X    "cm",  STR2ARG,
  94. X    "co",  NUMBER,
  95. X    "cr",  STRING,
  96. X    "cs",  STR2ARG,
  97. X    "ct",  STRING,
  98. X    "cv",  STR1ARG,
  99. X    "dB",  NUMBER,
  100. X    "dC",  NUMBER,
  101. X    "dF",  NUMBER,
  102. X    "dN",  NUMBER,
  103. X    "dT",  NUMBER,
  104. X    "dV",  NUMBER,
  105. X    "da",  FLAG,
  106. X    "db",  FLAG,
  107. X    "dc",  STRING,
  108. X    "dl",  STRING,
  109. X    "dm",  STRING,
  110. X    "do",  STRING,
  111. X    "ds",  STRING,
  112. X    "ec",  STR1ARG,
  113. X    "ed",  STRING,
  114. X    "ei",  STRING,
  115. X    "eo",  FLAG,
  116. X    "es",  FLAG,
  117. X    "ff",  STRING,
  118. X    "fs",  STRING,
  119. X    "gn",  FLAG,
  120. X    "hc",  FLAG,
  121. X    "hd",  STRING,
  122. X    "ho",  STRING,
  123. X    "hs",  FLAG,
  124. X    "hu",  STRING,
  125. X    "hz",  FLAG,
  126. X    "ic",  STRING,
  127. X    "if",  STRING,
  128. X    "im",  STRING,
  129. X    "in",  FLAG,
  130. X    "ip",  STRING,
  131. X    "is",  STRING,
  132. X    "it",  NUMBER,
  133. X    "k0",  STRING,
  134. X    "k1",  STRING,
  135. X    "k2",  STRING,
  136. X    "k3",  STRING,
  137. X    "k4",  STRING,
  138. X    "k5",  STRING,
  139. X    "k6",  STRING,
  140. X    "k7",  STRING,
  141. X    "k8",  STRING,
  142. X    "k9",  STRING,
  143. X    "kA",  STRING,
  144. X    "kC",  STRING,
  145. X    "kD",  STRING,
  146. X    "kE",  STRING,
  147. X    "kF",  STRING,
  148. X    "kH",  STRING,
  149. X    "kI",  STRING,
  150. X    "kL",  STRING,
  151. X    "kM",  STRING,
  152. X    "kN",  STRING,
  153. X    "kP",  STRING,
  154. X    "kR",  STRING,
  155. X    "kS",  STRING,
  156. X    "kT",  STRING,
  157. X    "ka",  STRING,
  158. X    "kb",  STRING,
  159. X    "kd",  STRING,
  160. X    "ke",  STRING,
  161. X    "kh",  STRING,
  162. X    "kl",  STRING,
  163. X    "km",  FLAG,
  164. X    "kn",  NUMBER,
  165. X    "ko",  STRING,
  166. X    "kr",  STRING,
  167. X    "ks",  STRING,
  168. X    "kt",  STRING,
  169. X    "ku",  STRING,
  170. X    "l0",  STRING,
  171. X    "l1",  STRING,
  172. X    "l2",  STRING,
  173. X    "l3",  STRING,
  174. X    "l4",  STRING,
  175. X    "l5",  STRING,
  176. X    "l6",  STRING,
  177. X    "l7",  STRING,
  178. X    "l8",  STRING,
  179. X    "l9",  STRING,
  180. X    "le",  STRING,
  181. X    "li",  NUMBER,
  182. X    "ll",  STRING,
  183. X    "lm",  NUMBER,
  184. X    "ma",  STRING,
  185. X    "mb",  STRING,
  186. X    "md",  STRING,
  187. X    "me",  STRING,
  188. X    "mh",  STRING,
  189. X    "mi",  FLAG,
  190. X    "mk",  STRING,
  191. X    "ml",  STRING,
  192. X    "mm",  STRING,
  193. X    "mo",  STRING,
  194. X    "mp",  STRING,
  195. X    "mr",  STRING,
  196. X    "ms",  FLAG,
  197. X    "mu",  STRING,
  198. X    "nc",  FLAG,
  199. X    "nd",  STRING,
  200. X    "nl",  STRING,
  201. X    "ns",  FLAG,
  202. X    "nw",  STRING,
  203. X    "os",  FLAG,
  204. X    "pO",  STR1ARG,
  205. X    "pb",  NUMBER,
  206. X    "pc",  STRING,
  207. X    "pf",  STRING,
  208. X    "po",  STRING,
  209. X    "ps",  STRING,
  210. X    "pt",  FLAG,
  211. X    "rP",  STRING,
  212. X    "rc",  STRING,
  213. X    "rf",  STRING,
  214. X    "rp",  STR2ARG,
  215. X    "rs",  STRING,
  216. X    "sa",  STR2ARG,
  217. X    "sc",  STRING,
  218. X    "se",  STRING,
  219. X    "sf",  STRING,
  220. X    "sg",  NUMBER,
  221. X    "so",  STRING,
  222. X    "sr",  STRING,
  223. X    "st",  STRING,
  224. X    "ta",  STRING,
  225. X    "tc",  STRING,
  226. X    "te",  STRING,
  227. X    "ti",  STRING,
  228. X    "ts",  STR1ARG,
  229. X    "uc",  STRING,
  230. X    "ue",  STRING,
  231. X    "ug",  NUMBER,
  232. X    "ul",  FLAG,
  233. X    "up",  STRING,
  234. X    "us",  STRING,
  235. X    "vb",  STRING,
  236. X    "ve",  STRING,
  237. X    "vi",  STRING,
  238. X    "vs",  STRING,
  239. X    "vt",  NUMBER,
  240. X    "wi",  STRING,
  241. X    "ws",  NUMBER,
  242. X    "xb",  FLAG,
  243. X    "xn",  FLAG,
  244. X    "xo",  FLAG,
  245. X    "xr",  FLAG,
  246. X    "xs",  FLAG,
  247. X    "xt",  FLAG,
  248. X    "xv",  FLAG,
  249. X    "xx",  FLAG,
  250. X};
  251. X
  252. Xputx(c) { putchar (c); }
  253. X
  254. Xmain (argc, argv)
  255. X    int argc;
  256. X    char **argv;
  257. X{
  258. X    char tcbuf[1024];
  259. X    char *cp, *arg;
  260. X    int i, tgetnum(), tgetflag();
  261. X    static int aflag = 0;
  262. X
  263. X    if (tgetent(tcbuf, getenv ("TERM")) <= 0) {
  264. X    (void) fprintf (stderr, "tc: cannot find termcap for %s.\n", getenv ("TERM"));
  265. X    exit (1);
  266. X    }
  267. X    cp = (char *) malloc (256);
  268. X    argv++;
  269. X    while (*argv) {
  270. X    arg = *argv++;
  271. X    if (strcmp (arg, "-a") == 0) {
  272. X        aflag = 1;
  273. X        continue;
  274. X    }
  275. X    i = lookup (arg, tcaps);
  276. X    if (i < 0) {
  277. X        (void) fprintf (stderr, "tc: no such termcap: %s\n", arg);
  278. X        exit (2);
  279. X    }
  280. X    switch (tcaps[i].val & 017) {
  281. X    case STRING:
  282. X        if (aflag)
  283. X        show (tgetdefstr (arg, &cp));
  284. X        else
  285. X        tputs (tgetdefstr (arg, &cp), 1, putx);
  286. X        break;
  287. X    case STR1ARG:
  288. X        if (aflag)
  289. X        show (tgetstr (arg, &cp));
  290. X        else
  291. X        if (argv != NULL && isdigit (**argv))
  292. X            tputs (tgoto (tgetstr (arg, &cp),
  293. X            atoi (*argv++), 0), 1, putx);
  294. X        else {
  295. X            (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
  296. X            exit(3);
  297. X        }
  298. X        break;
  299. X    case STR2ARG:
  300. X        if (aflag)
  301. X        show (tgetstr (arg, &cp));
  302. X        else
  303. X        if (argv != NULL && argv[1] != NULL &&
  304. X            isdigit (**argv) && isdigit (*(argv[1])))
  305. X            tputs (tgoto (tgetstr (arg, &cp),
  306. X            atoi (*argv++), atoi (*argv++)), 1, putx);
  307. X        else {
  308. X            (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
  309. X            exit(3);
  310. X        }
  311. X        break;
  312. X    case NUMBER:
  313. X        if (aflag)
  314. X        (void) printf ("%d\n", tgetdefnum (arg));
  315. X        break;
  316. X    case FLAG:
  317. X        if (aflag)
  318. X        (void) printf (tgetflag (arg) ? "true\n" : "false\n");
  319. X        break;
  320. X    }
  321. X    }
  322. X    exit (0);
  323. X}
  324. X
  325. X
  326. X
  327. X#define MAXLUPN 3      /* longer than longest possible name */
  328. X/*  Lookup name in table.  Will take nonambiguous abbreviations.  If you
  329. X    want to insist that a certain table entry must be spelled out, enter
  330. X    it twice in the table.  Table entries must be sorted by name, and a
  331. X    name which is a substring of a longer name comes earlier in the table.
  332. X    Accepts upper or lower case if table entry is lower case.
  333. X    Returns:
  334. X     > 0 table entry index
  335. X      -1 not found
  336. X      -2 ambiguous
  337. X*/
  338. Xint lookup (name, table)
  339. X    char *name;
  340. X    lookuptbl *table;
  341. X{
  342. X    register char  *namptr,
  343. X           *tblptr;
  344. X    int ind;
  345. X    int value = 0;
  346. X    short length;
  347. X    short longest = 0;
  348. X    int ambig = 0;
  349. X    char lname[MAXLUPN];
  350. X
  351. X    if (name == NULL)
  352. X    return -1;
  353. X    namptr = name;
  354. X    tblptr = lname;
  355. X    for (;;) {
  356. X    if ((*tblptr++ = isupper (*namptr)? tolower (*namptr++): *namptr++)
  357. X        == '\0')
  358. X        break;
  359. X    if (tblptr >= &lname[MAXLUPN])
  360. X        return -1;
  361. X    }
  362. X
  363. X    for (ind = 0; (tblptr = table->str) != 0; table++, ind++) {
  364. X    namptr = lname;
  365. X    for (; *tblptr == *namptr; tblptr++, namptr++) {
  366. X        if (*tblptr == '\0')
  367. X        break;
  368. X    }
  369. X    if (*namptr == '\0') {  /* end of name or exact match */
  370. X        length = namptr - lname;
  371. X        if (longest < length) {
  372. X        longest = length;
  373. X        ambig = 0;
  374. X        value = ind;
  375. X        if (*tblptr == '\0')
  376. X            break;          /* exact match */
  377. X        }
  378. X        else /* longest == length */
  379. X        ambig = 1;
  380. X    }
  381. X    else if ( *namptr < *tblptr )
  382. X        break;
  383. X    }
  384. X    if (ambig)
  385. X    return -2;
  386. X    if (longest)
  387. X    return value;
  388. X    return -1;
  389. X}
  390. X
  391. X
  392. Xshow (str)
  393. X    char *str;
  394. X{
  395. X    char c;
  396. X
  397. X    if (str == (char *)0) {
  398. X    (void) printf ("NULL\n");
  399. X    return;
  400. X    }
  401. X    while (c = *str++ & 127)
  402. X    if (c < ' ') {
  403. X        if (c == 27)
  404. X        (void) printf ("\n");
  405. X        (void) printf ("^%c", c + '@');
  406. X    } else if (c == 127)
  407. X        (void) printf ("^?");
  408. X    else
  409. X        (void) printf ("%c", c);
  410. X    (void) printf ("\n");
  411. X    return;
  412. X}
  413. X
  414. Xchar *
  415. Xtgetdefstr (cap, ptr)
  416. X    char *cap, *ptr;
  417. X{
  418. X    char *x;
  419. X    static char *bs = "\b",
  420. X        *ht = "\t",
  421. X        *nl = "\n",
  422. X        *cr = "\r",
  423. X        *ff = "\f",
  424. X        *nu = "\0",
  425. X        *bl = "\007",
  426. X        *nlcr = "\n\r";
  427. X
  428. X    if ((x = tgetstr (cap, ptr)) != (char *) 0)
  429. X    return (x);
  430. X    if (strcmp (cap, "pc") == 0)
  431. X    return (nu);
  432. X    if (strcmp (cap, "bc") == 0)
  433. X    return (bs);
  434. X    if (strcmp (cap, "ta") == 0)
  435. X    return (ht);
  436. X    if (strcmp (cap, "nl") == 0)
  437. X    return (nl);
  438. X    if (strcmp (cap, "cr") == 0)
  439. X    return (cr);
  440. X    if (strcmp (cap, "ff") == 0)
  441. X    return (ff);
  442. X    if (strcmp (cap, "nw") == 0)
  443. X    return (nlcr);
  444. X    if (strcmp (cap, "bl") == 0)
  445. X    return (bl);
  446. X    if (strcmp (cap, "ho") == 0)
  447. X    return (tgoto (tgetstr ("cm", ptr), 0, 0));
  448. X    if (strcmp (cap, "ll") == 0)
  449. X    return (tgoto (tgetstr ("cm", ptr), tgetnum ("li") - 1, 0));
  450. X    if (strcmp (cap, "rs") == 0)
  451. X    return (tgetstr ("is", ptr));
  452. X    if (strcmp (cap, "is") == 0)
  453. X    return (tgetstr ("rs", ptr));
  454. X    if (strcmp (cap, "rf") == 0)
  455. X    return (tgetstr ("if", ptr));
  456. X    if (strcmp (cap, "if") == 0)
  457. X    return (tgetstr ("rf", ptr));
  458. X
  459. X    return ((char *) 0);
  460. X}
  461. X
  462. X
  463. Xtgetdefnum (cap)
  464. X    char *cap;
  465. X{
  466. X    int x;
  467. X
  468. X    if ((x = tgetnum (cap)) != -1)
  469. X    return (x);
  470. X    if (strcmp (cap, "ws") == 0)
  471. X    return (tgetnum ("co"));
  472. X    return (0);
  473. X}
  474. ~FUNKY STUFF~
  475. echo extracting - tc.1
  476. sed 's/^X//' > tc.1 << '~FUNKY STUFF~'
  477. X.TH TC 1 "28 October 1985"
  478. X.SH NAME
  479. Xtc \- supply termcap capabilities to shell scripts
  480. X.SH SYNOPSIS
  481. X.B tc
  482. X[ -a ] [ cap ] ...
  483. X.SH DESCRIPTION
  484. X.I Tc
  485. Xperforms termcap services at the
  486. Xshell level. Each of the arguments
  487. Xconsists of the name of a termcap
  488. Xcapability followed by optional
  489. Xarguments. There may be any number of
  490. Xarguments. The termcaps mentioned in
  491. Xthe arguments are performed left to
  492. Xright until the list is complete or
  493. Xan error occurs.
  494. X.LP
  495. XThe
  496. X.B -a
  497. Xoption specifies that the termcap is
  498. Xto be echoed to the screen in "ascii"
  499. Xmode, where control characters are
  500. Xdisplayed as ^x and escape characters
  501. X(^[) are preceeded by new-lines.
  502. XNumeric capabilities
  503. Xare displayed in this mode as numbers
  504. Xand flags by either "true" or
  505. X"false"; without the
  506. X.B -a
  507. Xflag numeric and flag capabilities
  508. Xare silently skipped.
  509. X.LP
  510. XThe capabilities that require
  511. Xarguments (like cm and ch) check the
  512. Xnext argument(s) for being
  513. Xnumeric, and if so, are used;
  514. Xotherwise an error is displayed and
  515. Xan error exit taken.
  516. X.LP
  517. XA number of defaults are used when
  518. Xcaps are not found in the terminal
  519. Xdefinition. Some of these are spelled out in
  520. Xtermcap(5), some are common sense:
  521. X
  522. X.nf
  523. X.ul
  524. X    cap     default if not found
  525. X    bc      "\\b"
  526. X    pc      "\\0"
  527. X    ta      "\\t"
  528. X    nl      "\\n"
  529. X    cr      "\\r"
  530. X    ff      "\\f"
  531. X    nw      "\\n\\r"
  532. X    ho      direct cursor motion to 0,0
  533. X    ll      direct cursor motion to tgetnum("li")-1, 0
  534. X    rs      is
  535. X    is      rs
  536. X    rf      if
  537. X    if      rf
  538. X    ws      co
  539. X    unknown numbers default to zero
  540. X
  541. X.fi
  542. X.SH "STATUS RETURNS"
  543. XReturns status of 1 if terminal name
  544. Xnot found, 2 if required cap not
  545. Xa legal capability, 3 for argument error.
  546. X.SH "SEE ALSO"
  547. Xtct(1), termcap(3), termcap(5)
  548. X.SH BUGS
  549. XContains an internal database of
  550. Xwhich capabilities exist, require arguments
  551. Xand are numeric and flags. Will
  552. Xrequire updating if list ever
  553. Xchanges.
  554. X.SH AUTHOR
  555. XLyle McElhaney
  556. ~FUNKY STUFF~
  557.  
  558.