home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / mg2a / part11 < prev    next >
Text File  |  1989-02-03  |  59KB  |  2,483 lines

  1. Path: xanth!mcnc!ncsuvx!lll-winken!lll-tis!ames!necntc!ncoast!allbery
  2. From: BLARSON@ECLA.USC.EDU (Bob Larson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i035: mg 2a part 11 of 15
  5. Message-ID: <12401301016.47.BLARSON@ECLA.USC.EDU>
  6. Date: 26 May 88 05:01:04 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
  9. Lines: 2470
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. comp.sources.misc: Volume 3, Issue 35
  13. Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
  14. Archive-Name: mg2a/Part11
  15.  
  16. #    This is a shell archive.
  17. #    Remove everything above and including the cut line.
  18. #    Then run the rest of the file through sh.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar:    Shell Archiver
  22. #    Run the following text with /bin/sh to create:
  23. #    termlib/fgetlr.c
  24. #    termlib/isdigit.c
  25. #    termlib/testtcp.c
  26. #    termlib/tgetent.c
  27. #    termlib/tgetflag.c
  28. #    termlib/tgetnum.c
  29. #    termlib/tgetstr.c
  30. #    termlib/tgoto.c
  31. #    termlib/tputs.c
  32. #    termlib/ttest.c
  33. # This archive created: Tue May 17 21:42:47 1988
  34. # By:    blarson
  35. if test -d termlib
  36. then true
  37. else mkdir termlib
  38. fi
  39. cat << \SHAR_EOF > termlib/fgetlr.c
  40. /************************************************************************
  41.  *                                      *
  42.  *              Copyright (c) 1982, Fred Fish              *
  43.  *              All Rights Reserved                  *
  44.  *                                      *
  45.  *    This software and/or documentation is released for public          *
  46.  *    distribution for personal, non-commercial use only.          *
  47.  *    Limited rights to use, modify, and redistribute are hereby      *
  48.  *    granted for non-commercial purposes, provided that all          *
  49.  *    copyright notices remain intact and all changes are clearly     *
  50.  *    documented.  The author makes no warranty of any kind with      *
  51.  *    respect to this product and explicitly disclaims any implied    *
  52.  *    warranties of merchantability or fitness for any particular     *
  53.  *    purpose.                                  *
  54.  *                                      *
  55.  ************************************************************************
  56.  */
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  *  LIBRARY FUNCTION
  63.  *
  64.  *    fgetlr    get logical record from a file
  65.  *
  66.  *  KEY WORDS
  67.  *
  68.  *    fgetlr
  69.  *    string functions
  70.  *
  71.  *  SYNOPSIS
  72.  *
  73.  *    char *fgetlr(bp,bpsize,fp)
  74.  *    char *bp;
  75.  *    int bpsize;
  76.  *    FILE *fp;
  77.  *
  78.  *  DESCRIPTION
  79.  *
  80.  *    Reads the next logical record from stream "fp" into buffer "bp"
  81.  *    until next unescaped newline, "bpsize" minus one characters
  82.  *    have been read, end of file, or read error.
  83.  *    The last character read is followed by a NULL.
  84.  *
  85.  *    A logical record may span several physical records by having
  86.  *    each newline escaped with the standard C escape character
  87.  *    (backslash).
  88.  *
  89.  *    This is particularly useful for things like the termcap
  90.  *    file, where a single entry is too long for one physical
  91.  *    line, yet needs to be treated as a single record.
  92.  *
  93.  *    Returns its first argument unless an end of file or read
  94.  *    error occurs prior to any characters being read.
  95.  *
  96.  *  BUGS
  97.  *
  98.  *    The only way to know if read was terminated due to buffer size
  99.  *    limitation is to test for a newline before the terminating
  100.  *    null.
  101.  *
  102.  */
  103.  
  104. #include <stdio.h>
  105.  
  106.  
  107.  
  108. /*
  109.  *  PSEUDO CODE
  110.  *
  111.  *    Begin fgetlr
  112.  *      If read fails then
  113.  *          Return NULL.
  114.  *      Else
  115.  *          Find out how many characters were read.
  116.  *          Initialize pointer to terminating null.
  117.  *          If last char read was newline then
  118.  *          If newline was escaped then
  119.  *              Replace backslash with the newline.
  120.  *              Replace newline with null.
  121.  *              Read and append more.
  122.  *          End if
  123.  *          End if
  124.  *          Return buffer pointer.
  125.  *      End if
  126.  *    End fgetlr
  127.  *
  128.  */
  129.  
  130. char *fgetlr(bp,bpsize,fp)
  131. char *bp;
  132. int bpsize;
  133. FILE *fp;
  134. {
  135.     int numch;
  136.     char *cp;
  137.  
  138.     if (fgets(bp,bpsize,fp) == NULL) {
  139.       return(NULL);
  140.     } else {
  141.       numch = strlen(bp);
  142.       cp = &bp[numch];
  143.       if (*--cp == '\n') {
  144.       if (numch > 1 && *--cp == '\\') {
  145.           *cp++ = '\n';
  146.           *cp = NULL;
  147.           fgetlr(cp,bpsize-numch+1,fp);
  148.       }
  149.       }
  150.       return(bp);
  151.     }
  152. }
  153. SHAR_EOF
  154. cat << \SHAR_EOF > termlib/isdigit.c
  155. /************************************************************************
  156.  *                                      *
  157.  *              Copyright (c) 1982, Fred Fish              *
  158.  *              All Rights Reserved                  *
  159.  *                                      *
  160.  *    This software and/or documentation is released for public          *
  161.  *    distribution for personal, non-commercial use only.          *
  162.  *    Limited rights to use, modify, and redistribute are hereby      *
  163.  *    granted for non-commercial purposes, provided that all          *
  164.  *    copyright notices remain intact and all changes are clearly     *
  165.  *    documented.  The author makes no warranty of any kind with      *
  166.  *    respect to this product and explicitly disclaims any implied    *
  167.  *    warranties of merchantability or fitness for any particular     *
  168.  *    purpose.                                  *
  169.  *                                      *
  170.  ************************************************************************
  171.  */
  172.  
  173.  
  174.  
  175.  
  176. /*
  177.  *  LIBRARY FUNCTION
  178.  *
  179.  *    isdigit     test character for numeric property
  180.  *
  181.  *  SYNOPSIS
  182.  *
  183.  *    int isdigit(ch)
  184.  *    char ch;
  185.  *
  186.  *  DESCRIPTION
  187.  *
  188.  *    Returns TRUE or FALSE depending upon whether the specified
  189.  *    character is a numeric character or not.
  190.  *
  191.  *  BUGS
  192.  *
  193.  *    May fail on machines in which native character set is not ASCII.
  194.  *
  195.  */
  196.  
  197. #include <stdio.h>
  198.  
  199. #define TRUE 1
  200. #define FALSE 0
  201.  
  202. int isdigit(ch)
  203. char ch;
  204. {
  205.     if (ch > '9' || ch < '0') {
  206.       return(FALSE);
  207.     } else {
  208.       return(TRUE);
  209.     }
  210. }
  211. SHAR_EOF
  212. cat << \SHAR_EOF > termlib/testtcp.c
  213. /************************************************************************
  214.  *                                      *
  215.  *              Copyright (c) 1982, Fred Fish              *
  216.  *              All Rights Reserved                  *
  217.  *                                      *
  218.  *    This software and/or documentation is released for public          *
  219.  *    distribution for personal, non-commercial use only.          *
  220.  *    Limited rights to use, modify, and redistribute are hereby      *
  221.  *    granted for non-commercial purposes, provided that all          *
  222.  *    copyright notices remain intact and all changes are clearly     *
  223.  *    documented.  The author makes no warranty of any kind with      *
  224.  *    respect to this product and explicitly disclaims any implied    *
  225.  *    warranties of merchantability or fitness for any particular     *
  226.  *    purpose.                                  *
  227.  *                                      *
  228.  ************************************************************************
  229.  */
  230.  
  231.  
  232.  
  233.  
  234. /*
  235.  *  TEST PROGRAM
  236.  *
  237.  *    testtcp    test termcap functions
  238.  *
  239.  *  KEY WORDS
  240.  *
  241.  *    test routines
  242.  *    termcap test
  243.  *
  244.  *  SYNOPSIS
  245.  *
  246.  *    termcap [-efns] terminal [capability [capability ...]]
  247.  *
  248.  *          -e  =>   expand string capability given by -s
  249.  *          -f  =>   determine boolean capabilities for terminal
  250.  *          -n  =>   determine numeric capabilities for terminal
  251.  *          -s  =>   determine string capabilities for terminal
  252.  *
  253.  *          terminal =>  terminal name as given in termcap file
  254.  *          capability => a boolean, numeric, or string capability
  255.  *
  256.  *          NOTE:  All capabilities must be of same type, as
  257.  *             given by [-fns].
  258.  *
  259.  *          If terminal is only argument then entire entry is
  260.  *          printed.
  261.  *
  262.  *  DESCRIPTION
  263.  *
  264.  *    Provides way to test termcap functions.  Can find
  265.  *    and print an entire termcap terminal entry, or various
  266.  *    capabilities from the entry.
  267.  *
  268.  *  AUTHOR
  269.  *
  270.  *    Fred Fish
  271.  *
  272.  */
  273.  
  274. #include <stdio.h>
  275.  
  276. #define TRUE 1
  277. #define FALSE 0
  278. #define NO_FILE           -1              /* Returned if can't open file */
  279. #define NO_ENTRY  0              /* Returned if can't find entry */
  280. #define SUCCESS      1              /* Returned if entry found ok */
  281. #define TRUNCATED 2              /* Returned if entry found but trunc */
  282. #define BUFFER_SIZE 1024
  283.  
  284. int eflag = FALSE;
  285. int fflag = FALSE;
  286. int nflag = FALSE;
  287. int sflag = FALSE;
  288.  
  289. int got_terminal = FALSE;
  290. int got_capability = FALSE;
  291.  
  292.  
  293.  
  294.  
  295. /*
  296.  *  FUNCTION
  297.  *
  298.  *    main   termcap test entry point
  299.  *
  300.  *  KEY WORDS
  301.  *
  302.  *    main
  303.  *
  304.  *  SYNOPSIS
  305.  *
  306.  *    main(argc,argv)
  307.  *    int argc;
  308.  *    char *argv[];
  309.  *
  310.  *  DESCRIPTION
  311.  *
  312.  *    This is where the termcap test starts executing.    All argument list
  313.  *    switches are processed first, then all the specified
  314.  *    capability identification strings are processed.
  315.  *
  316.  */
  317.  
  318.  
  319.  
  320. /*
  321.  *  PSEUDO CODE
  322.  *
  323.  *    Begin main
  324.  *      Process command line options.
  325.  *      For each argument list field
  326.  *          If field was not erased during option processing
  327.  *          If terminal name field not yet processed then
  328.  *              Process an assumed terminal name field.
  329.  *              Set terminal name processed flag.
  330.  *          Else
  331.  *              Process a capability field.
  332.  *              Set capability field processed flag.
  333.  *          End if
  334.  *          End if
  335.  *      End for
  336.  *      If no capabilities processed then
  337.  *          Simply dump buffer.
  338.  *      End if
  339.  *    End main
  340.  *
  341.  */
  342.  
  343. main(argc, argv)
  344. int argc;
  345. char *argv[];
  346. {
  347.     char *argp;
  348.     int argnum;
  349.     char buffer[BUFFER_SIZE];
  350.  
  351.     options(argc,argv);
  352.     for (argnum = 1; argnum < argc; argnum++) {
  353.     if ((argp = argv[argnum]) != NULL) {
  354.       if (!got_terminal) {
  355.           terminal(buffer,argp);
  356.           got_terminal = TRUE;
  357.       } else {
  358.           capability(argp);
  359.           got_capability = TRUE;
  360.       }
  361.     }
  362.     }
  363.     if (got_terminal && !got_capability) {
  364.       printf("%s",buffer);
  365.     }
  366. }
  367.  
  368.  
  369.  
  370. /*
  371.  *  FUNCTION
  372.  *
  373.  *    options    process command line options
  374.  *
  375.  *  SYNOPSIS
  376.  *
  377.  *    options(argc,argv)
  378.  *    int argc;
  379.  *    char *argv[];
  380.  *
  381.  *  DESCRIPTION
  382.  *
  383.  *    Scans argument list, processing each switch as it is
  384.  *    found.  The pointer to each switch string is then
  385.  *    replaced with a NULL to effectively erase the switch
  386.  *    argument.
  387.  *
  388.  */
  389.  
  390.  
  391.  
  392. /*
  393.  *  PSEUDO CODE
  394.  *
  395.  *    Begin options
  396.  *      For each argument in the argument list
  397.  *          Get pointer to first char of argument.
  398.  *          If the argument is a switch then
  399.  *          Replace argument pointer with NULL.
  400.  *          Look at next argument character.
  401.  *          While there is another argument character
  402.  *              Switch on the argument character
  403.  *              Case "EXPAND":
  404.  *              Set expand (e) flag.
  405.  *              Break out of switch.
  406.  *              Case "BOOLEAN":
  407.  *              Set boolean (f) flag.
  408.  *              Break out of switch.
  409.  *              Case "NUMERIC":
  410.  *              Set numeric flag.
  411.  *              Break out of switch.
  412.  *              Case "STRING":
  413.  *              Set string flag.
  414.  *              Break out of switch.
  415.  *              Default:
  416.  *              Abort with usage message.
  417.  *              End switch
  418.  *          End while
  419.  *          End if
  420.  *      End for
  421.  *    End options
  422.  *
  423.  */
  424.  
  425.  
  426.  
  427. options(argc, argv)
  428. int argc;
  429. char *argv[];
  430. {
  431.     int i;
  432.     char c;          /* 1st char of current command-line argument */
  433.     char *cp;          /* current argument pointer */
  434.  
  435.     for (i=1; i<argc; i++) {
  436.     cp = argv[i];
  437.     if (*cp == '-') {
  438.         argv[i] = NULL;
  439.       cp++;
  440.       while (c = *cp++) {
  441.           switch (c) {
  442.           case 'e':
  443.           eflag = TRUE;
  444.           break;
  445.           case 'f':
  446.           fflag = TRUE;
  447.           break;
  448.           case 'n':
  449.           nflag = TRUE;
  450.           break;
  451.           case 's':
  452.           sflag = TRUE;
  453.           break;
  454.           default:
  455.           usage();
  456.           }
  457.         }
  458.     }
  459.     }
  460. }
  461.  
  462.  
  463.  
  464. /*
  465.  *  FUNCTION
  466.  *
  467.  *    usage   give usage message and abort
  468.  *
  469.  *  KEY WORDS
  470.  *
  471.  *    usage
  472.  *    help processing
  473.  *    abort locations
  474.  *
  475.  *  SYNOPSIS
  476.  *
  477.  *    usage()
  478.  *
  479.  *  DESCRIPTION
  480.  *
  481.  *    Usage is typically called when a problem has been
  482.  *    detected in the argument list.
  483.  *    It prints a usage message and exits.
  484.  *
  485.  */
  486.  
  487.  
  488.  
  489. /*
  490.  *  PSEUDO CODE
  491.  *
  492.  *    Begin usage
  493.  *      Print usage message.
  494.  *      Exit.
  495.  *    End usage
  496.  *
  497.  */
  498.  
  499. usage()
  500. {
  501.     printf("Usage: termcap [-fns] terminal [capability [capability ... ]]\n");
  502.     exit();
  503. }
  504.  
  505.  
  506.  
  507.  
  508. terminal(buffer,name)
  509. char *buffer;
  510. char *name;
  511. {
  512.     int status;
  513.  
  514.     status = tgetent(buffer,name);
  515.     switch (status) {
  516.     case NO_FILE:
  517.       fprintf(stderr,"Can't find a termcap data base file.\n");
  518.       exit();
  519.     case NO_ENTRY:
  520.       fprintf(stderr,"Can't find entry \"%s\"\n",name);
  521.       exit();
  522.     case TRUNCATED:
  523.       fprintf(stderr,"Warning --- entry \"%s\" too long\n",name);
  524.       break;
  525.     case SUCCESS:
  526.     break;
  527.     default:
  528.     fprintf(stderr,"? tgetent returned illegal status %d\n",status);
  529.       exit();
  530.     }
  531. }
  532.  
  533.  
  534.  
  535. capability(id)
  536. char *id;
  537. {
  538.     int value;
  539.     char buffer[256];
  540.     char *area;
  541.     char *ep, *tgoto();
  542.  
  543.     if (fflag) {
  544.       value = tgetflag(id);
  545.       if (value) {
  546.       printf("%s TRUE\n",id);
  547.       } else {
  548.       printf("%s FALSE\n",id);
  549.       }
  550.     } else if (nflag) {
  551.       value = tgetnum(id);
  552.       printf("%s = %o octal %d decimal\n",id,value,value);
  553.     } else if (sflag) {
  554.       area = buffer;
  555.       tgetstr(id,&area);
  556.       if (eflag) {
  557.       ep = tgoto(buffer,75,23);
  558.       }
  559.       doprint(id,buffer);
  560.       if (eflag) {
  561.       doprint(id,ep);
  562.       ep = tgoto(buffer,1,2);
  563.       doprint(id,ep);
  564.       }
  565.     }
  566. }
  567.  
  568.  
  569.  
  570. doprint(id,cp)
  571. char *id;
  572. char *cp;
  573. {
  574.     printf("%s = \"",id);
  575.     for ( ; *cp != NULL; cp++) {
  576.       if (*cp < 040) {
  577.       printf("^%c",*cp |= 0100);
  578.       } else {
  579.       printf("%c",*cp);
  580.       }
  581.     }
  582.     printf("\"\n");
  583. }
  584. SHAR_EOF
  585. cat << \SHAR_EOF > termlib/tgetent.c
  586. /************************************************************************
  587.  *                                      *
  588.  *              Copyright (c) 1982, Fred Fish              *
  589.  *              All Rights Reserved                  *
  590.  *                                      *
  591.  *    This software and/or documentation is released for public          *
  592.  *    distribution for personal, non-commercial use only.          *
  593.  *    Limited rights to use, modify, and redistribute are hereby      *
  594.  *    granted for non-commercial purposes, provided that all          *
  595.  *    copyright notices remain intact and all changes are clearly     *
  596.  *    documented.  The author makes no warranty of any kind with      *
  597.  *    respect to this product and explicitly disclaims any implied    *
  598.  *    warranties of merchantability or fitness for any particular     *
  599.  *    purpose.                                  *
  600.  *                                      *
  601.  ************************************************************************
  602.  */
  603. /*
  604.  * Modified:
  605.  *    30-Apr-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  606.  *        Instead of using VAX C getenv("TERM"), which does not
  607.  *        return the value of logical name "TERM", translate the
  608.  *        logical name by hand.
  609.  *    11-Oct-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  610.  *        Support tc capability to allow the library to use standard
  611.  *        termcaps.  Rewrote tgetent to look for tc capability
  612.  *        and add new terminal definition to the caller's buffer.
  613.  *        This makes it rather possible to overflow the caller's
  614.  *        buffer, but the library doesn't make any claim that it
  615.  *        won't overwrite the buffer anyway...
  616.  *    27-Jan-88 Bob Larson  blarson@ecla.usc.edu
  617.  *        Add primos (__50SERIES) support.
  618.  *    1-Feb-88  Sandra Loosemore  (sandra@cs.utah.edu)
  619.  *          Change default termcap file for VMS to be the same place
  620.  *          that GNU puts it.
  621.  *    23-Apr-88 Bob Larson
  622.  *          merge primos and vms changes
  623.  */
  624.  
  625.  
  626.  
  627. /*
  628.  *  LIBRARY FUNCTION
  629.  *
  630.  *    tgetent    load buffer with entry for specified terminal
  631.  *
  632.  *  KEY WORDS
  633.  *
  634.  *    termcap functions
  635.  *    utility routines
  636.  *
  637.  *  SYNOPSIS
  638.  *
  639.  *    int tgetent(bp,name)
  640.  *    char *bp;
  641.  *    char *name;
  642.  *
  643.  *  DESCRIPTION
  644.  *
  645.  *    Extracts the entry for terminal <name> from the termcap file
  646.  *    and places it in the character buffer <bp>.   It is currently
  647.  *    assumed that bp is at least 1024 characters.  If the entry in
  648.  *    the termcap file is larger than 1023 characters the excess
  649.  *    characters will be discarded and appropriate status will
  650.  *    be returned.
  651.  *
  652.  *    Also note that since bp is used by other termcap
  653.  *    routines, the storage associated with the termcap entry
  654.  *    cannot be freed until all termcap calls are completed.
  655.  *
  656.  *    Tgetent can be directed to look in a file other than
  657.  *    the default (/etc/termcap) by defining an environment
  658.  *    variable called TERMCAP to be the pathname of the desired
  659.  *    termcap file.  This is useful for debugging new entries.
  660.  *    NOTE: the pathname MUST begin with a '/' character.
  661.  *
  662.  *    Also, if the string assigned to TERMCAP does not begin with
  663.  *    a '/' and if the environment variable TERM matches <name> then
  664.  *    the string assigned to TERMCAP is copied to buffer <bp>
  665.  *    instead of reading a termcap file.
  666.  *
  667.  *  RETURNS
  668.  *
  669.  *    -1  if the termcap file cannot be opened
  670.  *     0  if no entry in termcap file matches <name>
  671.  *     1  if extraction is successful with no errors
  672.  *     2  if extraction is successful but entry truncated
  673.  *
  674.  *  SEE ALSO
  675.  *
  676.  *    tgetnum    extract numeric type capability
  677.  *    tgetflag    test boolean type capability
  678.  *    tgetstr    get string value of capability
  679.  *
  680.  *  AUTHOR
  681.  *
  682.  *    Fred Fish
  683.  *
  684.  */
  685.  
  686. #include <stdio.h>
  687.  
  688. #define TRUE 1
  689. #define FALSE 0
  690. #define BUFSIZE 1024              /* Assumed size of external buffer */
  691.  
  692. #define NO_FILE           -1              /* Returned if can't open file */
  693. #define NO_ENTRY  0              /* Returned if can't find entry */
  694. #define SUCCESS      1              /* Returned if entry found ok */
  695. #define TRUNCATED 2              /* Returned if entry found but trunc */
  696.  
  697. #ifdef __50SERIES
  698. #define DEFAULT_FILE "mg*>termcap"
  699. #else
  700. #define DEFAULT_FILE "/etc/termcap"   /* default termcap filename */
  701. #ifdef          VAXC
  702. #define          index strchr
  703. #endif
  704. #endif
  705.  
  706. char *_tcpbuf;                  /* Place to remember buffer pointer */
  707. FILE *fp;                  /* Termcap file              */
  708. static FILE *find_file();
  709. extern char *index();
  710.  
  711. /*
  712.  *  PSEUDO CODE
  713.  *
  714.  *    Begin tgetent
  715.  *      Erase any previous buffer contents.
  716.  *      Remember the buffer pointer.
  717.  *      If termcap file is not found then
  718.  *          If buffer was filled anyway then
  719.  *          Return SUCCESS.
  720.  *          Else
  721.  *          Return NO_FILE.
  722.  *          End if
  723.  *      Else
  724.  *          Find entry associated with name
  725.  *          While an entry was found and limit not reached
  726.  *          If no tc capability found Then
  727.  *              Exit while loop with status = SUCCESS
  728.  *          Else
  729.  *              Call getent to get entry indicated by tc=
  730.  *              If entry not found then
  731.  *                  Exit loop with status != SUCCESS
  732.  *              End if
  733.  *              Concatenate entry into buffer
  734.  *          End If
  735.  *          End while
  736.  *      End if
  737.  *      Close termcap file
  738.  *      Return status code
  739.  *    End tgetent
  740.  *
  741.  */
  742.  
  743. static int getent();
  744.  
  745. int tgetent(bp,name)
  746. char *bp;
  747. char *name;
  748. {
  749.       char    *tc, *tcbufp, tcbuf[80], termbuf[BUFSIZE], *tgetstr();
  750.       char    *bufp, *cp;          /* current start of buffer      */
  751.       int     limit = 10;          /* maximum nesting          */
  752.       int     status;              /* return from getent()          */
  753.  
  754.       *bp = '\0';              /* clear buffer              */
  755.       _tcpbuf = bp;              /* save base of buffer          */
  756.  
  757.       /* Look for termcap file.     If NULL, find_file may have found a  */
  758.       /* a valid termcap string in the environment variable TERMCAP.  */
  759.       /* If non-null, attempt to find the entry in the termcap file   */
  760.  
  761.       if ((fp = find_file(bp)) == NULL) {
  762.           if (*bp != NULL)
  763.               return(SUCCESS);
  764.           else
  765.               return(NO_FILE);
  766.       }
  767.       status = getent(bp, name);/* look for main entry          */
  768.  
  769.       /* Start looking for tc capabilities in the termcap.  If
  770.        * found, concatenate the entry for the new terminal to the
  771.        * current buffer and try again.    To avoid infinite loops,
  772.        * allow only 10 loops through this process.
  773.        */
  774.       while ((status == SUCCESS) && limit--) {
  775.           /* look for tc capability.  If none found, exit loop    */
  776.           tcbufp = tcbuf;
  777.           if (((tc = tgetstr("tc",&tcbufp)) == NULL)
  778.             || (*tc == '\0')) {
  779.               status = SUCCESS;/* no more tc= entries */
  780.               break;
  781.           }
  782.  
  783.           /* Attempt to get next entry. Exit loop if unsuccessful */
  784.           if ((status = getent(termbuf, tcbuf)) != SUCCESS)
  785.               break;
  786.  
  787.           /* Copy new entry into buffer, right at "tc="          */
  788.           for (bufp = bp; *bufp; bufp++)          /* find tc=     */
  789.               if ((*bufp=='t') && (bufp[1]=='c') && (bufp[2]=='='))
  790.                   break;
  791.           if ((cp = index(termbuf,':')) == NULL)
  792.               cp = termbuf;
  793.           strcpy(bufp, cp + 1);
  794.       }
  795.  
  796.       /* close termcap file and return the status     */
  797.       fclose(fp);
  798.       return status;
  799. }
  800.  
  801.  
  802.  
  803.  
  804. /*
  805.  *  INTERNAL FUNCTION
  806.  *
  807.  *    getent    find termcap entry in termcap file
  808.  *
  809.  *  KEY WORDS
  810.  *
  811.  *    internal functions
  812.  *    getent
  813.  *
  814.  *  SYNOPSIS
  815.  *
  816.  *    static int getent(bp,name)
  817.  *    char *bp;
  818.  *    char *name;
  819.  *
  820.  *  DESCRIPTION
  821.  *
  822.  *    Getent is called by tgetent each time tgetent attempts to
  823.  *    read a capability from the termcap database file.     Places
  824.  *    the entry in the buffer pointed to by bp
  825.  *
  826.  *
  827.  *  PSEUDOCODE
  828.  *
  829.  *    Begin Getent
  830.  *      Seek to beginning of termcap file
  831.  *      Clear buffer
  832.  *      While records left to process
  833.  *          If this is entry is what we want then
  834.  *          If entry was truncated then
  835.  *              Return TRUNCATED status
  836.  *          Else
  837.  *              Return SUCCESS status.
  838.  *          End if
  839.  *          End if
  840.  *      End while
  841.  *      Return NO_ENTRY status.
  842.  *    End
  843.  */
  844.  
  845. static int getent(bp,name)
  846. char *bp;                  /* Pointer to buffer (1024 char min) */
  847. char *name;                  /* Pointer to terminal entry to find */
  848. {
  849.       *bp = '\0';              /* clear buffer              */
  850.       lseek(fileno(fp), 0L, 0l);      /* rewind termcap file          */
  851.  
  852.       while (fgetlr(bp,BUFSIZE,fp)) {
  853.           if (gotcha(bp,name)) {
  854.               if (bp[strlen(bp)-1] != '\n') {
  855.                   return(TRUNCATED);
  856.               } else {
  857.                   return(SUCCESS);
  858.               }
  859.           }
  860.       }
  861.       return(NO_ENTRY);
  862. }
  863.  
  864.  
  865.  
  866. /*
  867.  *  INTERNAL FUNCTION
  868.  *
  869.  *    find_file       find the termcap file and open it if possible
  870.  *
  871.  *  KEY WORDS
  872.  *
  873.  *    internal functions
  874.  *    find_file
  875.  *
  876.  *  SYNOPSIS
  877.  *
  878.  *    static FILE *find_file(bp)
  879.  *    char *bp;
  880.  *
  881.  *  DESCRIPTION
  882.  *
  883.  *    Attempts to locate and open the termcap file.  Also handles
  884.  *    using the environment TERMCAP string as the actual buffer
  885.  *    (that's why bp has to be an input parameter).
  886.  *
  887.  *    If TERMCAP is defined an begins with a '/' character then
  888.  *    it is taken to be the pathname of the termcap file and
  889.  *    an attempt is made to open it.  If this fails then
  890.  *    the default termcap file is used instead.
  891.  *
  892.  *    If TERMCAP is defined but does not begin with a '/' then
  893.  *    it is assumed to be the actual buffer contents provided
  894.  *    that <name> matches the environment variable TERM.
  895.  *
  896.  *  BUGS
  897.  *
  898.  *    There is currently no way to be sure which termcap
  899.  *    file was opened since the default will always be
  900.  *    tried.
  901.  *
  902.  */
  903.  
  904.  
  905.  
  906. /*
  907.  *  PSEUDO CODE
  908.  *
  909.  *    Begin find_file
  910.  *      If there is a TERMCAP environment string then
  911.  *          If the string is not null then
  912.  *          If the string is a pathname then
  913.  *              If that file is opened successfully then
  914.  *              Return its pointer.
  915.  *              End if
  916.  *          Else
  917.  *              If there is a TERM environment string then
  918.  *              If TERM matches <name> then
  919.  *                  Copy TERMCAP string to buffer.
  920.  *                  Return NULL for no file.
  921.  *              End if
  922.  *              End if
  923.  *          End if
  924.  *          End if
  925.  *      End if
  926.  *      Open default termcap file and return results.
  927.  *    End find_file
  928.  *
  929.  */
  930. #ifdef          __50SERIES
  931. static FILE *find_file(bp)
  932. char *bp;
  933. {
  934.     char *cp;
  935.     char *gvget();
  936.  
  937.     if((cp = gvget(".TERMCAP")) != NULL && *cp)
  938.     return fopen(cp, "r");
  939.     if((cp = gvget(".TERMCAP$")) != NULL && *cp)
  940.     return fopen(cp, "r");
  941.     return fopen(DEFAULT_FILE, "r");
  942. }
  943. #else
  944. #ifdef          VAXC
  945. char *trnlnm();
  946. #endif
  947.  
  948. static FILE *find_file(bp)
  949. char *bp;
  950. {
  951.     FILE *fp, *fopen();
  952.     char *cp, *ncp, *getenv(), vmsname[132];
  953.  
  954.     if ((cp = getenv("TERMCAP")) != NULL) {
  955.       if (*cp != NULL) {
  956.       if (*cp == '/') {
  957.           if ((fp = fopen(cp,"r")) != NULL) {
  958.           return(fp);
  959.           }
  960.       } else {
  961. #ifdef VAXC
  962.           if ((ncp = trnlnm("TERM")) != NULL) {
  963. #else
  964.           if ((ncp = getenv("TERM")) != NULL) {
  965. #endif
  966.           if (strcmp(cp,ncp) == 0) {
  967.               strcpy(bp,cp);
  968.               return((FILE *)NULL);
  969.           }
  970.           }
  971.       }
  972.       }
  973.     }
  974. #ifdef VAXC
  975.     if ((fp = fopen("emacs_library:[etc]termcap.dat","r")) != NULL)
  976.     return(fp);
  977. #endif
  978.     return(fopen(DEFAULT_FILE,"r"));
  979. }
  980. #endif /* __50SERIES */
  981.  
  982.  
  983.  
  984. /*
  985.  *  INTERNAL FUNCTION
  986.  *
  987.  *    gotcha   test to see if entry is for specified terminal
  988.  *
  989.  *  SYNOPSIS
  990.  *
  991.  *    gotcha(bp,name)
  992.  *    char *bp;
  993.  *    char *name;
  994.  *
  995.  *  DESCRIPTION
  996.  *
  997.  *    Tests to see if the entry in buffer bp matches the terminal
  998.  *    specified by name.  Returns TRUE if match is detected, FALSE
  999.  *    otherwise.
  1000.  *
  1001.  */
  1002.  
  1003.  
  1004.  
  1005. /*
  1006.  *  PSEUDO CODE
  1007.  *
  1008.  *    Begin gotcha
  1009.  *      If buffer character is comment character then
  1010.  *          Return FALSE since remainder is comment
  1011.  *      Else
  1012.  *          Initialize name scan pointer.
  1013.  *          Compare name and buffer until end or mismatch.
  1014.  *          If valid terminators for both name and buffer strings
  1015.  *          Return TRUE since a match was found.
  1016.  *          Else
  1017.  *          Find next non-name character in buffer.
  1018.  *          If not an alternate name separater character
  1019.  *              Return FALSE since no more names to check.
  1020.  *          Else
  1021.  *              Test next name and return results.
  1022.  *          End if
  1023.  *          End if
  1024.  *      End if
  1025.  *    End gotcha
  1026.  *
  1027.  */
  1028.  
  1029. gotcha(bp,name)
  1030. char *bp;
  1031. char *name;
  1032. {
  1033.     char *np;
  1034.  
  1035.     if (*bp == '#') {
  1036.       return(FALSE);
  1037.     } else {
  1038.       np = name;
  1039.       while (*np == *bp && *np != NULL) {np++; bp++;}
  1040.       if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
  1041.       return(TRUE);
  1042.       } else {
  1043.       while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
  1044.       if (*bp != '|') {
  1045.           return(FALSE);
  1046.       } else {
  1047.           return(gotcha(++bp,name));
  1048.       }
  1049.       }
  1050.     }
  1051. }
  1052. SHAR_EOF
  1053. cat << \SHAR_EOF > termlib/tgetflag.c
  1054. /************************************************************************
  1055.  *                                      *
  1056.  *              Copyright (c) 1982, Fred Fish              *
  1057.  *              All Rights Reserved                  *
  1058.  *                                      *
  1059.  *    This software and/or documentation is released for public          *
  1060.  *    distribution for personal, non-commercial use only.          *
  1061.  *    Limited rights to use, modify, and redistribute are hereby      *
  1062.  *    granted for non-commercial purposes, provided that all          *
  1063.  *    copyright notices remain intact and all changes are clearly     *
  1064.  *    documented.  The author makes no warranty of any kind with      *
  1065.  *    respect to this product and explicitly disclaims any implied    *
  1066.  *    warranties of merchantability or fitness for any particular     *
  1067.  *    purpose.                                  *
  1068.  *                                      *
  1069.  ************************************************************************
  1070.  */
  1071. /*
  1072.  * Modified:
  1073.  *    30-Apr-86 Mic Kaczmarczik
  1074.  *    #define index to strchr if VAX C
  1075.  *
  1076.  */
  1077.  
  1078.  
  1079.  
  1080.  
  1081. /*
  1082.  *  LIBRARY FUNCTION
  1083.  *
  1084.  *    tgetflag     extract boolean termcap capability
  1085.  *
  1086.  *  KEY WORDS
  1087.  *
  1088.  *    termcap
  1089.  *
  1090.  *  SYNOPSIS
  1091.  *
  1092.  *    tgetflag(id)
  1093.  *    char *id;
  1094.  *
  1095.  *  DESCRIPTION
  1096.  *
  1097.  *    Returns TRUE if specified id is present in terminal
  1098.  *    entry, FALSE otherwise.
  1099.  *
  1100.  */
  1101.  
  1102. #include <stdio.h>
  1103. #ifdef VAXC
  1104. #define index strchr
  1105. #endif
  1106.  
  1107. #define TRUE 1
  1108. #define FALSE 0
  1109.  
  1110. extern char *_tcpbuf;          /* Termcap entry buffer pointer */
  1111.  
  1112.  
  1113.  
  1114. /*
  1115.  *  PSEUDO CODE
  1116.  *
  1117.  *    Begin tgetflag
  1118.  *      Initialize pointer to the termcap entry buffer.
  1119.  *      While there is a field to process
  1120.  *          Skip over the field separator character.
  1121.  *          If this is the entry we want then
  1122.  *          If entry is identifier only then
  1123.  *              Return TRUE
  1124.  *          Else
  1125.  *              Return FALSE
  1126.  *          End if
  1127.  *          End if
  1128.  *      End while
  1129.  *      Return FALSE as default.
  1130.  *    End tgetflag
  1131.  *
  1132.  */
  1133.  
  1134. tgetflag(id)
  1135. char *id;
  1136. {
  1137.     char *bp;
  1138.     extern char *index();
  1139.  
  1140.     bp = _tcpbuf;
  1141.     while ((bp = index(bp,':')) != NULL) {
  1142.       bp++;
  1143.       if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
  1144.       if (*bp == NULL || *bp++ == ':') {
  1145.           return(TRUE);
  1146.       } else {
  1147.           return(FALSE);
  1148.       }
  1149.       }
  1150.     }
  1151.     return(FALSE);
  1152. }
  1153. SHAR_EOF
  1154. cat << \SHAR_EOF > termlib/tgetnum.c
  1155. /************************************************************************
  1156.  *                                      *
  1157.  *              Copyright (c) 1982, Fred Fish              *
  1158.  *              All Rights Reserved                  *
  1159.  *                                      *
  1160.  *    This software and/or documentation is released for public          *
  1161.  *    distribution for personal, non-commercial use only.          *
  1162.  *    Limited rights to use, modify, and redistribute are hereby      *
  1163.  *    granted for non-commercial purposes, provided that all          *
  1164.  *    copyright notices remain intact and all changes are clearly     *
  1165.  *    documented.  The author makes no warranty of any kind with      *
  1166.  *    respect to this product and explicitly disclaims any implied    *
  1167.  *    warranties of merchantability or fitness for any particular     *
  1168.  *    purpose.                                  *
  1169.  *                                      *
  1170.  ************************************************************************
  1171.  */
  1172. /* Modified:
  1173.  * 30-Apr-86 Mic Kaczmarczik
  1174.  *       Use ctype.h macros instead of the function isdigit().
  1175.  *       #define index to strchr if VAXC
  1176.  */
  1177.  
  1178.  
  1179.  
  1180. /*
  1181.  *  LIBRARY FUNCTION
  1182.  *
  1183.  *    tgetnum    extract numeric option from termcap entry
  1184.  *
  1185.  *  KEY WORDS
  1186.  *
  1187.  *    termcap
  1188.  *    ce functions
  1189.  *
  1190.  *  SYNOPSIS
  1191.  *
  1192.  *    tgetnum(id)
  1193.  *    char *id;
  1194.  *
  1195.  *  DESCRIPTION
  1196.  *
  1197.  *    Returns numeric value of capability <id>, or -1 if <id>
  1198.  *    is not found.   Knows about octal numbers, which
  1199.  *    begin with 0.
  1200.  *
  1201.  */
  1202.  
  1203. #include <stdio.h>
  1204. #include <ctype.h>
  1205. #ifdef          VAXC
  1206. #define index strchr
  1207. #endif
  1208.  
  1209. extern char *_tcpbuf;          /* Termcap entry buffer pointer */
  1210.  
  1211.  
  1212.  
  1213. /*
  1214.  *  PSEUDO CODE
  1215.  *
  1216.  *    Begin tgetnum
  1217.  *      Initialize pointer to the termcap entry buffer.
  1218.  *      While there is a field to process
  1219.  *          Skip over the field separator character.
  1220.  *          If this is the entry we want then
  1221.  *          If the entry is not a numeric then
  1222.  *              Return failure value.
  1223.  *          Else
  1224.  *              Initialize value to zero.
  1225.  *              If number begins with zero then
  1226.  *              Set accumulation base to 8.
  1227.  *              Else
  1228.  *              Set accumulation base to 10.
  1229.  *              End if
  1230.  *              While there is a numeric character
  1231.  *              Accumulate the value.
  1232.  *              End while
  1233.  *              Return value.
  1234.  *          End if
  1235.  *          End if
  1236.  *      End while
  1237.  *      Return failure value.
  1238.  *    End tgetnum
  1239.  *
  1240.  */
  1241.  
  1242. tgetnum(id)
  1243. char *id;
  1244. {
  1245.     int value, base;
  1246.     char *bp;
  1247.     extern char *index();
  1248.  
  1249.     bp = _tcpbuf;
  1250.     while ((bp = index(bp,':')) != NULL) {
  1251.       bp++;
  1252.       if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
  1253.       if (*bp != NULL && *bp++ != '#') {
  1254.           return(-1);
  1255.       } else {
  1256.           value = 0;
  1257.           if (*bp == '0') {
  1258.           base = 8;
  1259.           } else {
  1260.           base = 10;
  1261.           }
  1262.           while (isdigit(*bp)) {
  1263.           value *= base;
  1264.           value += (*bp++ - '0');
  1265.           }
  1266.           return(value);
  1267.       }
  1268.       }
  1269.     }
  1270.     return(-1);
  1271. }
  1272. SHAR_EOF
  1273. cat << \SHAR_EOF > termlib/tgetstr.c
  1274. /************************************************************************
  1275.  *                                      *
  1276.  *              Copyright (c) 1982, Fred Fish              *
  1277.  *              All Rights Reserved                  *
  1278.  *                                      *
  1279.  *    This software and/or documentation is released for public          *
  1280.  *    distribution for personal, non-commercial use only.          *
  1281.  *    Limited rights to use, modify, and redistribute are hereby      *
  1282.  *    granted for non-commercial purposes, provided that all          *
  1283.  *    copyright notices remain intact and all changes are clearly     *
  1284.  *    documented.  The author makes no warranty of any kind with      *
  1285.  *    respect to this product and explicitly disclaims any implied    *
  1286.  *    warranties of merchantability or fitness for any particular     *
  1287.  *    purpose.                                  *
  1288.  *                                      *
  1289.  ************************************************************************
  1290.  */
  1291. /* Modified:
  1292.  * 30-Apr-86 Mic Kaczmarczik
  1293.  *       Use ctype.h macros instead of the function isdigit().
  1294.  *       #define index() to be strchr() if VAX C
  1295.  */
  1296.  
  1297.  
  1298.  
  1299.  
  1300. /*
  1301.  *  LIBRARY FUNCTION
  1302.  *
  1303.  *    tgetstr    extract string capability from termcap entry
  1304.  *
  1305.  *  KEY WORDS
  1306.  *
  1307.  *    termcap
  1308.  *
  1309.  *  SYNOPSIS
  1310.  *
  1311.  *    char *tgetstr(id,area)
  1312.  *    char *id;
  1313.  *    char **area;
  1314.  *
  1315.  *  DESCRIPTION
  1316.  *
  1317.  *    Gets the string capability for <id>, placing it in
  1318.  *    the buffer at *area, and advancing *area to point
  1319.  *    to next available storage.
  1320.  *
  1321.  *    For example, if the following capabilities are
  1322.  *    in the termcap file:
  1323.  *
  1324.  *          ZZ=zzzz
  1325.  *          YY=yyyyyy
  1326.  *          WW=www
  1327.  *
  1328.  *    then successive calls using YY, ZZ, and WW will
  1329.  *    build the following buffer:
  1330.  *
  1331.  *          yyyyyy0zzzz0www0
  1332.  *
  1333.  *    The first call will return a pointer to yyyyyy, the
  1334.  *    second will return a pointer to zzzz and the third
  1335.  *    will return a pointer to www.  Note that each
  1336.  *    string is null terminated, as are all C strings.
  1337.  *
  1338.  *    Characters preceded by the carot character (\136)
  1339.  *    are mapped into the corresponding control character.
  1340.  *    For example, the two character sequence ^A becomes
  1341.  *    a single control-A (\001) character.
  1342.  *
  1343.  *    The escape character is the normal C backslash and
  1344.  *    the normal C escape sequences are recognized, along
  1345.  *    with a special sequence for the ASCII escape character
  1346.  *    (\033).  The recognized sequences are:
  1347.  *
  1348.  *          \E   =>  '\033'  (ASCII escape character)
  1349.  *          \b   =>  '\010'  (ASCII backspace character)
  1350.  *          \f   =>  '\014'  (ASCII form feed character)
  1351.  *          \n   =>  '\012'  (ASCII newline/linefeed char)
  1352.  *          \r   =>  '\015'  (ASCII carriage return char)
  1353.  *          \t   =>  '\011'  (ASCII tab character)
  1354.  *          \ddd =>  '\ddd'  (arbitrary ASCII digit)
  1355.  *          \x   =>  'x'     (ordinary ASCII character)
  1356.  *
  1357.  */
  1358.  
  1359. #include <stdio.h>
  1360. #include <ctype.h>
  1361. #ifdef VAXC
  1362. #define index strchr
  1363. #endif
  1364.  
  1365. extern char *_tcpbuf;          /* Termcap entry buffer pointer */
  1366.  
  1367.  
  1368.  
  1369. /*
  1370.  *  PSEUDO CODE
  1371.  *
  1372.  *    Begin tgetstr
  1373.  *      Initialize pointer to the termcap entry buffer.
  1374.  *      While there is a field to process
  1375.  *          Skip over the field separator character.
  1376.  *          If this is the entry we want then
  1377.  *          If the entry is not a string then
  1378.  *              Return NULL.
  1379.  *          Else
  1380.  *              Transfer string and rtn pointer.
  1381.  *          End if
  1382.  *          End if
  1383.  *      End while
  1384.  *      Return NULL
  1385.  *    End tgetstr
  1386.  *
  1387.  */
  1388.  
  1389. char *tgetstr(id,area)
  1390. char *id;
  1391. char **area;
  1392. {
  1393.     char *bp;
  1394.     extern char *index();
  1395.     static char *decode();
  1396.  
  1397.     bp = _tcpbuf;
  1398.     while ((bp = index(bp,':')) != NULL) {
  1399.       if (*++bp == NULL)
  1400.           break;
  1401.       if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
  1402.       if (*bp != NULL && *bp++ != '=') {
  1403.           return(NULL);
  1404.       } else {
  1405.           return(decode(bp,area));
  1406.       }
  1407.       }
  1408.     }
  1409.     **area = NULL;
  1410.     bp = (*area)++;
  1411.     return(bp);
  1412. }
  1413.  
  1414.  
  1415.  
  1416. /*
  1417.  *  INTERNAL FUNCTION
  1418.  *
  1419.  *    decode   transfer string capability, decoding escapes
  1420.  *
  1421.  *  SYNOPSIS
  1422.  *
  1423.  *    static char *decode(bp,area)
  1424.  *    char *bp;
  1425.  *    char **area;
  1426.  *
  1427.  *  DESCRIPTION
  1428.  *
  1429.  *    Transfers the string capability, up to the next ':'
  1430.  *    character, or null, to the buffer pointed to by
  1431.  *    the pointer in *area.  Note that the initial
  1432.  *    value of *area and *area is updated to point
  1433.  *    to the next available location after the null
  1434.  *    terminating the transfered string.
  1435.  *
  1436.  *  BUGS
  1437.  *
  1438.  *    There is no overflow checking done on the destination
  1439.  *    buffer, so it better be large enough to hold
  1440.  *    all expected strings.
  1441.  *
  1442.  */
  1443.  
  1444.  
  1445.  
  1446. /*
  1447.  *  PSEUDO CODE
  1448.  *
  1449.  *    Begin decode
  1450.  *      Initialize the transfer pointer.
  1451.  *      While there is an input character left to process
  1452.  *          Switch on input character
  1453.  *          Case ESCAPE:
  1454.  *          Decode and xfer the escaped sequence.
  1455.  *          Break
  1456.  *          Case CONTROLIFY:
  1457.  *          Controlify and xfer the next character.
  1458.  *          Advance the buffer pointer.
  1459.  *          Break
  1460.  *          Default:
  1461.  *          Xfer a normal character.
  1462.  *          End switch
  1463.  *      End while
  1464.  *      Null terminate the output string.
  1465.  *      Remember where the output string starts.
  1466.  *      Update the output buffer pointer.
  1467.  *      Return pointer to the output string.
  1468.  *    End decode
  1469.  *
  1470.  */
  1471.  
  1472. static char *decode(bp,area)
  1473. char *bp;
  1474. char **area;
  1475. {
  1476.     char *cp, *bgn;
  1477.     char *do_esc();
  1478.  
  1479.     cp = *area;
  1480.     while (*bp != NULL && *bp != ':') {
  1481.       switch(*bp) {
  1482.       case '\\':
  1483.       bp = do_esc(cp++,++bp);
  1484.       break;
  1485.       case '^':
  1486.       *cp++ = *++bp & 037;
  1487.       bp++;
  1488.       break;
  1489.       default:
  1490.       *cp++ = *bp++;
  1491.       break;
  1492.       }
  1493.     }
  1494.     *cp++ = NULL;
  1495.     bgn = *area;
  1496.     *area = cp;
  1497.     return(bgn);
  1498. }
  1499.  
  1500.  
  1501.  
  1502. /*
  1503.  *  INTERNAL FUNCTION
  1504.  *
  1505.  *    do_esc    process an escaped sequence
  1506.  *
  1507.  *  SYNOPSIS
  1508.  *
  1509.  *    char *do_esc(out,in);
  1510.  *    char *out;
  1511.  *    char *in;
  1512.  *
  1513.  *  DESCRIPTION
  1514.  *
  1515.  *    Processes an escape sequence pointed to by
  1516.  *    in, transfering it to location pointed to
  1517.  *    by out, and updating the pointer to in.
  1518.  *
  1519.  */
  1520.  
  1521.  
  1522.  
  1523. /*
  1524.  *  PSEUDO CODE
  1525.  *
  1526.  *    Begin do_esc
  1527.  *      If the first character is not a NULL then
  1528.  *          If is a digit then
  1529.  *          Set value to zero.
  1530.  *          For up to 3 digits
  1531.  *              Accumulate the sum.
  1532.  *          End for
  1533.  *          Transfer the sum.
  1534.  *          Else if character is in remap list then
  1535.  *          Transfer the remapped character.
  1536.  *          Advance the input pointer once.
  1537.  *          Else
  1538.  *          Simply transfer the character.
  1539.  *          End if
  1540.  *      End if
  1541.  *      Return updated input pointer.
  1542.  *    End do_esc
  1543.  *
  1544.  */
  1545.  
  1546. static char *maplist = {
  1547.     "E\033b\bf\fn\nr\rt\t"
  1548. };
  1549.  
  1550. char *do_esc(out,in)
  1551. char *out;
  1552. char *in;
  1553. {
  1554.     int count;
  1555.     char ch;
  1556.     extern char *index();
  1557.     char *cp;
  1558.  
  1559.     if (*in != NULL) {
  1560.       if (isdigit(*in)) {
  1561.       ch = 0;
  1562.       for (count = 0; count < 3 && isdigit(*in); in++) {
  1563.            ch <<= 3;
  1564.            ch |= (*in - '0');
  1565.       }
  1566.       *out++ = ch;
  1567.       } else if ((cp = index(maplist,*in)) != NULL) {
  1568.       *out++ = *++cp;
  1569.       in++;
  1570.       } else {
  1571.       *out++ = *in++;
  1572.       }
  1573.     }
  1574.     return(in);
  1575. }
  1576. SHAR_EOF
  1577. cat << \SHAR_EOF > termlib/tgoto.c
  1578. /************************************************************************
  1579.  *                                      *
  1580.  *              Copyright (c) 1982, Fred Fish              *
  1581.  *              All Rights Reserved                  *
  1582.  *                                      *
  1583.  *    This software and/or documentation is released for public          *
  1584.  *    distribution for personal, non-commercial use only.          *
  1585.  *    Limited rights to use, modify, and redistribute are hereby      *
  1586.  *    granted for non-commercial purposes, provided that all          *
  1587.  *    copyright notices remain intact and all changes are clearly     *
  1588.  *    documented.  The author makes no warranty of any kind with      *
  1589.  *    respect to this product and explicitly disclaims any implied    *
  1590.  *    warranties of merchantability or fitness for any particular     *
  1591.  *    purpose.                                  *
  1592.  *                                      *
  1593.  ************************************************************************
  1594.  */
  1595. /*
  1596.  * Modified:
  1597.  *    1 May 86 ...!ihnp4!ut-sally!ut-ngp!mic
  1598.  *          Now forces a '\0' at end of tgoto string.     Tgoto wasn't,
  1599.  *          and this screwed up VT100-style (i.e. variable) cursor
  1600.  *          addressing.
  1601.  */
  1602.  
  1603.  
  1604.  
  1605. /*
  1606.  *  LIBRARY FUNCTION
  1607.  *
  1608.  *    tgoto   expand cursor addressing string from cm capability
  1609.  *
  1610.  *  KEY WORDS
  1611.  *
  1612.  *    termcap
  1613.  *
  1614.  *  SYNOPSIS
  1615.  *
  1616.  *    char *tgoto(cm,destcol,destline)
  1617.  *    char *cm;
  1618.  *    int destcol;
  1619.  *    int destline;
  1620.  *
  1621.  *  DESCRIPTION
  1622.  *
  1623.  *    Returns cursor addressing string, decoded from the cm
  1624.  *    capability string, to move cursor to column destcol on
  1625.  *    line destline.
  1626.  *
  1627.  *    The following sequences uses one input argument, either
  1628.  *    line or column, and place the appropriate substitution
  1629.  *    in the output string:
  1630.  *
  1631.  *          %d      substitute decimal value (in ASCII)
  1632.  *          %2      like %d but forces field width to 2
  1633.  *          %3      like %d but forces field width to 3
  1634.  *          %.      like %c
  1635.  *          %+x     like %c but adds ASCII value of x
  1636.  *
  1637.  *    The following sequences cause processing modifications
  1638.  *    but do not "use up" one of the arguments.    If they
  1639.  *    act on an argument they act on the next one to
  1640.  *    be converted.
  1641.  *
  1642.  *          %>xy    if next value to be converted is
  1643.  *              greater than value of ASCII char x
  1644.  *              then add value of ASCII char y.
  1645.  *          %r      reverse substitution of line
  1646.  *              and column (line is substituted
  1647.  *              first by default).
  1648.  *          %i      causes input values destcol and
  1649.  *              destline to be incremented.
  1650.  *          %%      gives single % character in output.
  1651.  *
  1652.  *  BUGS
  1653.  *
  1654.  *    Does not implement some of the more arcane sequences for
  1655.  *    radically weird terminals (specifically %n, %B, & %D).
  1656.  *    If you have one of these you deserve whatever happens.
  1657.  *
  1658.  */
  1659.  
  1660.  
  1661.  
  1662. /*
  1663.  *    Miscellaneous stuff
  1664.  */
  1665.  
  1666. #include <stdio.h>
  1667.  
  1668. #define MAXARGS 2
  1669.  
  1670. static char *in;          /* Internal copy of input string pointer */
  1671. static char *out;          /* Pointer to output array */
  1672. static int args[MAXARGS];     /* Maximum number of args to convert */
  1673. static int pcount;          /* Count of args processed */
  1674. static char output[64];              /* Converted string */
  1675.  
  1676.  
  1677.  
  1678.  
  1679. /*
  1680.  *  PSEUDO CODE
  1681.  *
  1682.  *    Begin tgoto
  1683.  *      If no string to process then
  1684.  *          Return pointer to error string.
  1685.  *      Else
  1686.  *          Initialize pointer to input string.
  1687.  *          Initialize pointer to result string.
  1688.  *          First arg is line number by default.
  1689.  *          Second arg is col number by default.
  1690.  *          No arguments processed yet.
  1691.  *          While there is another character to process
  1692.  *          If character is a not a % character then
  1693.  *              Simply copy to output.
  1694.  *          Else
  1695.  *              Process the control sequence.
  1696.  *          End if
  1697.  *          End while
  1698.  *          Return pointer to static output string.
  1699.  *      End if
  1700.  *    End tgoto
  1701.  *
  1702.  */
  1703.  
  1704. char *tgoto(cm,destcol,destline)
  1705. char *cm;
  1706. int destcol;
  1707. int destline;
  1708. {
  1709.     static int process();
  1710.  
  1711.     if (cm == NULL) {
  1712.       return("OOPS");
  1713.     } else {
  1714.       in = cm;
  1715.       out = output;
  1716.       args[0] = destline;
  1717.       args[1] = destcol;
  1718.       pcount = 0;
  1719.       while (*in != NULL) {
  1720.       if (*in != '%') {
  1721.           *out++ = *in++;
  1722.       } else {
  1723.           process();
  1724.       }
  1725.       }
  1726.       *out = NULL;    /* Just to make sure */
  1727.       return(output);
  1728.     }
  1729. }
  1730.  
  1731.  
  1732.  
  1733. /*
  1734.  *  INTERNAL FUNCTION
  1735.  *
  1736.  *    process    process the conversion/command sequence
  1737.  *
  1738.  *  SYNOPSIS
  1739.  *
  1740.  *    static process()
  1741.  *
  1742.  *  DESCRIPTION
  1743.  *
  1744.  *    Processes the sequence beginning with the % character.
  1745.  *    Directly manipulates the input string pointer, the
  1746.  *    output string pointer, and the arguments.     Leaves
  1747.  *    the input string pointer pointing to the next character
  1748.  *    to be processed, and the output string pointer pointing
  1749.  *    to the next output location.  If conversion of
  1750.  *    one of the numeric arguments occurs, then the pcount
  1751.  *    is incremented.
  1752.  *
  1753.  */
  1754.  
  1755.  
  1756.  
  1757. /*
  1758.  *  PSEUDO CODE
  1759.  *
  1760.  *    Begin process
  1761.  *      Skip over the % character.
  1762.  *      Switch on next character after %
  1763.  *      Case 'd':
  1764.  *          Process %d type conversion (variable width).
  1765.  *          Reinitialize output pointer.
  1766.  *          Break;
  1767.  *      Case '2':
  1768.  *          Process %d type conversion (width 2).
  1769.  *          Reinitialize output pointer.
  1770.  *          Break;
  1771.  *      Case '3':
  1772.  *          Process %d type conversion (width 3).
  1773.  *          Reinitialize output pointer.
  1774.  *          Break;
  1775.  *      Case '.'
  1776.  *          Process %c type conversion.
  1777.  *          Break;
  1778.  *      Case '+':
  1779.  *          Process %c type conversion with offset.
  1780.  *          Break;
  1781.  *      Case '>':
  1782.  *          Process argument modification.
  1783.  *          Break;
  1784.  *      Case 'r':
  1785.  *          Process argument reversal.
  1786.  *          Break;
  1787.  *      Case 'i':
  1788.  *          Increment argument values.
  1789.  *          Break;
  1790.  *      Case '%':
  1791.  *          Copy to output, incrementing pointers.
  1792.  *          Break;
  1793.  *      End switch
  1794.  *    End process
  1795.  *
  1796.  */
  1797.  
  1798.  
  1799.  
  1800.  
  1801. static process()
  1802. {
  1803.     int temp;
  1804.  
  1805.     in++;
  1806.     switch(*in++) {
  1807.     case 'd':
  1808.       sprintf(out,"%d",args[pcount++]);
  1809.       out = &output[strlen(output)];
  1810.       break;
  1811.     case '2':
  1812.       sprintf(out,"%02d",args[pcount++]);
  1813.       out = &output[strlen(output)];
  1814.       break;
  1815.     case '3':
  1816.       sprintf(out,"%03d",args[pcount++]);
  1817.       out = &output[strlen(output)];
  1818.       break;
  1819.     case '.':
  1820.       *out++ = args[pcount++];
  1821.       break;
  1822.     case '+':
  1823.       *out++ = args[pcount++] + *in++;
  1824.       break;
  1825.     case '>':
  1826.       if (args[pcount] > *in++) {
  1827.       args[pcount] += *in++;
  1828.       } else {
  1829.       in++;
  1830.       }
  1831.       break;
  1832.     case 'r':
  1833.       temp = args[pcount];
  1834.       args[pcount] = args[pcount+1];
  1835.       args[pcount+1] = temp;
  1836.       break;
  1837.     case 'i':
  1838.       args[pcount]++;
  1839.       args[pcount+1]++;
  1840.       break;
  1841.     case '%':
  1842.       *out++ = '%';
  1843.       break;
  1844.     }
  1845. }
  1846. SHAR_EOF
  1847. cat << \SHAR_EOF > termlib/tputs.c
  1848. /************************************************************************
  1849.  *                                      *
  1850.  *              Copyright (c) 1982, Fred Fish              *
  1851.  *              All Rights Reserved                  *
  1852.  *                                      *
  1853.  *    This software and/or documentation is released for public          *
  1854.  *    distribution for personal, non-commercial use only.          *
  1855.  *    Limited rights to use, modify, and redistribute are hereby      *
  1856.  *    granted for non-commercial purposes, provided that all          *
  1857.  *    copyright notices remain intact and all changes are clearly     *
  1858.  *    documented.  The author makes no warranty of any kind with      *
  1859.  *    respect to this product and explicitly disclaims any implied    *
  1860.  *    warranties of merchantability or fitness for any particular     *
  1861.  *    purpose.                                  *
  1862.  *                                      *
  1863.  ************************************************************************
  1864.  */
  1865. /* Modified:
  1866.  * 30-Apr-86 Mic Kaczmarczik
  1867.  *       - Use ctype.h macros instead of the function isdigit().
  1868.  *       - Use VMS speed value for ospeed -- in microEmacs
  1869.  *         this is obtainted by ttinit().
  1870.  */
  1871.  
  1872.  
  1873.  
  1874.  
  1875. /*
  1876.  *  LIBRARY FUNCTION
  1877.  *
  1878.  *    tputs    output string with appropriate padding
  1879.  *
  1880.  *  KEY WORDS
  1881.  *
  1882.  *    termcap
  1883.  *
  1884.  *  SYNOPSIS
  1885.  *
  1886.  *    tputs(cp,affcnt,outc)
  1887.  *    char *cp;
  1888.  *    int affcnt;
  1889.  *    int (*outc)();
  1890.  *
  1891.  *  DESCRIPTION
  1892.  *
  1893.  *    Outputs string pointed to by cp, using function outc, and
  1894.  *    following it with the appropriate number of padding characters.
  1895.  *    Affcnt contains the number of lines affected, which is used
  1896.  *    as a multiplier for the specified per line pad time.  If
  1897.  *    per line pad count is not applicable, affcnt should be 1,
  1898.  *    NOT zero.
  1899.  *
  1900.  *    The format of the string pointed to by cp is:
  1901.  *
  1902.  *          [pad time][*]<string to send>
  1903.  *
  1904.  *          where:  pad time => time to delay in milliseconds
  1905.  *              * => specifies that time is per line
  1906.  *
  1907.  *    The pad character is assumed to reside in the external
  1908.  *    variable "PC".  Also, the external variable "ospeed"
  1909.  *    should contain the output speed of the terminal as
  1910.  *    encoded in /usr/include/sgtty.h  (B0-B9600).
  1911.  *
  1912.  * SYSTEM DEPENDENCIES
  1913.  *
  1914.  *    On VMS, the external variable "ospeed" should contain the
  1915.  *    output speed of the terminal as obtained from byte 3 of
  1916.  *    the iosb status buffer, using the IO$_SENSEMODE QIO.
  1917.  *    The table times[] compiles into the correct values for VMS,
  1918.  *    and, happily, also handles 19200 baud.
  1919.  *
  1920.  *  BUGS
  1921.  *
  1922.  *    If ospeed is 0 for some reason, there is the chance of a
  1923.  *    divide by 0 operation.
  1924.  *
  1925.  */
  1926.  
  1927.  
  1928.  
  1929. /*
  1930.  *    Miscellaneous stuff
  1931.  */
  1932.  
  1933. #include <stdio.h>
  1934. #include <ctype.h>
  1935.  
  1936. extern char PC;                  /* Pad character to use */
  1937. extern short ospeed;          /* Encoding of output speed */
  1938.  
  1939. #if   VMS
  1940. static int times[] = {
  1941.     10000,              /* Tenths of ms per char       0 baud (bogus) */
  1942.     2000,              /* Tenths of ms per char      50 baud */
  1943.     1333,              /* Tenths of ms per char      75 baud */
  1944.     909,              /* Tenths of ms per char     110 baud */
  1945.     743,              /* Tenths of ms per char     134 baud */
  1946.     666,              /* Tenths of ms per char     150 baud */
  1947.     333,              /* Tenths of ms per char     300 baud */
  1948.     166,              /* Tenths of ms per char     600 baud */
  1949.     83,                      /* Tenths of ms per char    1200 baud */
  1950.     55,                      /* Tenths of ms per char    1800 baud */
  1951.     50,                      /* Tenths of ms per char    2000 baud */
  1952.     41,                      /* Tenths of ms per char    2400 baud */
  1953.     28,                      /* Tenths of ms per char    3600 baud */
  1954.     20,                      /* Tenths of ms per char    4800 baud */
  1955.     14,                      /* Tenths of ms per char    7200 baud */
  1956.     10,                      /* Tenths of ms per char    9600 baud */
  1957.     5                  /* Tenths of ms per char 19200 baud */
  1958. };
  1959. #else
  1960. /* Times for Unix */
  1961. static int times[] = {
  1962.     0,                      /* Tenths of ms per char 0 baud */
  1963.     2000,              /* Tenths of ms per char 50 baud */
  1964.     1333,              /* Tenths of ms per char 75 baud */
  1965.     909,              /* Tenths of ms per char 110 baud */
  1966.     743,              /* Tenths of ms per char 134 baud */
  1967.     666,              /* Tenths of ms per char 150 baud */
  1968.     500,              /* Tenths of ms per char 200 baud */
  1969.     333,              /* Tenths of ms per char 300 baud */
  1970.     166,              /* Tenths of ms per char 600 baud */
  1971.     83,                      /* Tenths of ms per char 1200 baud */
  1972.     55,                      /* Tenths of ms per char 1800 baud */
  1973.     41,                      /* Tenths of ms per char 2400 baud */
  1974.     20,                      /* Tenths of ms per char 4800 baud */
  1975.     10                      /* Tenths of ms per char 9600 baud */
  1976. };
  1977. #endif
  1978.  
  1979.  
  1980.  
  1981.  
  1982. /*
  1983.  *  PSEUDO CODE
  1984.  *
  1985.  *    Begin tgoto
  1986.  *      If string pointer is invalid then
  1987.  *          Return without doing anything.
  1988.  *      Else
  1989.  *          For each pad digit (if any)
  1990.  *          Do decimal left shift.
  1991.  *          Accumulate the lower digit.
  1992.  *          End for
  1993.  *          Adjust scale to tenths of milliseconds
  1994.  *          If there is a fractional field
  1995.  *          Skip the decimal point.
  1996.  *          If there is a valid tenths digit
  1997.  *              Accumulate the tenths.
  1998.  *          End if
  1999.  *          Discard remaining digits.
  2000.  *          End if
  2001.  *          If per line is specified then
  2002.  *          Adjust the pad time.
  2003.  *          Discard the per line flag char.
  2004.  *          End if
  2005.  *          While there are any characters left
  2006.  *          Send them out via output function.
  2007.  *          End while
  2008.  *          Transmit any padding required.
  2009.  *      End if
  2010.  *    End tgoto
  2011.  *
  2012.  */
  2013.  
  2014. tputs(cp,affcnt,outc)
  2015. char *cp;
  2016. int affcnt;
  2017. int (*outc)();
  2018. {
  2019.     int ptime;                  /* Pad time in tenths of milliseconds */
  2020.     static do_padding();
  2021.  
  2022.     if (cp == NULL || *cp == NULL) {
  2023.       return;
  2024.     } else {
  2025.       for (ptime = 0; isdigit(*cp); cp++) {
  2026.       ptime *= 10;
  2027.       ptime += (*cp - '0');
  2028.       }
  2029.       ptime *= 10;
  2030.       if (*cp == '.') {
  2031.       cp++;
  2032.       if (isdigit(*cp)) {
  2033.           ptime += (*cp++ - '0');
  2034.       }
  2035.       while (isdigit(*cp)) {cp++;}
  2036.       }
  2037.       if (*cp == '*') {
  2038.       ptime *= affcnt;
  2039.       cp++;
  2040.       }
  2041.       while (*cp != NULL) {
  2042.       (*outc)(*cp++);
  2043.       }
  2044.       do_padding(ptime,outc);
  2045.     }
  2046. }
  2047.  
  2048.  
  2049.  
  2050. /*
  2051.  *  FUNCTION
  2052.  *
  2053.  *    do_padding    transmit any pad characters required
  2054.  *
  2055.  *  SYNOPSIS
  2056.  *
  2057.  *    static do_padding(ptime,outc)
  2058.  *    int ptime;
  2059.  *    int (*outc)();
  2060.  *
  2061.  *  DESCRIPTION
  2062.  *
  2063.  *    Does any padding required as specified by ptime (in tenths
  2064.  *    of milliseconds), the output speed given in the external
  2065.  *    variable ospeed, and the pad character given in the
  2066.  *    external variable PC.
  2067.  *
  2068.  */
  2069.  
  2070.  
  2071.  
  2072. /*
  2073.  *  PSEUDO CODE
  2074.  *
  2075.  *    Begin do_padding
  2076.  *      If there is a non-zero pad time then
  2077.  *          If the external speed is in range then
  2078.  *          Look up the delay per pad character.
  2079.  *          Round pad time up by half a character.
  2080.  *          Compute number of characters to send.
  2081.  *          For each pad character to send
  2082.  *              Transmit the pad character.
  2083.  *          End for
  2084.  *          End if
  2085.  *      End if
  2086.  *    End do_padding
  2087.  *
  2088.  */
  2089.  
  2090. static do_padding(ptime,outc)
  2091. int ptime;
  2092. int (*outc)();
  2093. {
  2094.     register int nchars;
  2095.     register int tpc;
  2096.  
  2097.     if (ptime >= 0) {
  2098.       if (ospeed >= 0 && ospeed <= (sizeof(times)/ sizeof(int))) {
  2099.       tpc = times[ospeed];
  2100.       ptime += (tpc / 2);
  2101.       nchars = ptime / tpc;
  2102.       for ( ; nchars > 0; --nchars) {
  2103.           (*outc)(PC);
  2104.       }
  2105.       }
  2106.     }
  2107. }
  2108. SHAR_EOF
  2109. cat << \SHAR_EOF > termlib/ttest.c
  2110. /************************************************************************
  2111.  *                                      *
  2112.  *              Copyright (c) 1982, Fred Fish              *
  2113.  *              All Rights Reserved                  *
  2114.  *                                      *
  2115.  *    This software and/or documentation is released for public          *
  2116.  *    distribution for personal, non-commercial use only.          *
  2117.  *    Limited rights to use, modify, and redistribute are hereby      *
  2118.  *    granted for non-commercial purposes, provided that all          *
  2119.  *    copyright notices remain intact and all changes are clearly     *
  2120.  *    documented.  The author makes no warranty of any kind with      *
  2121.  *    respect to this product and explicitly disclaims any implied    *
  2122.  *    warranties of merchantability or fitness for any particular     *
  2123.  *    purpose.                                  *
  2124.  *                                      *
  2125.  ************************************************************************
  2126.  */
  2127.  
  2128.  
  2129.  
  2130. /*
  2131.  *  TEST PROGRAM
  2132.  *
  2133.  *    testtcp    test termcap functions
  2134.  *
  2135.  *  KEY WORDS
  2136.  *
  2137.  *    test routines
  2138.  *    termcap test
  2139.  *
  2140.  *  SYNOPSIS
  2141.  *
  2142.  *    termcap [-efns] terminal [capability [capability ...]]
  2143.  *
  2144.  *          -e  =>   expand string capability given by -s
  2145.  *          -f  =>   determine boolean capabilities for terminal
  2146.  *          -n  =>   determine numeric capabilities for terminal
  2147.  *          -s  =>   determine string capabilities for terminal
  2148.  *
  2149.  *          terminal =>  terminal name as given in termcap file
  2150.  *          capability => a boolean, numeric, or string capability
  2151.  *
  2152.  *          NOTE:  All capabilities must be of same type, as
  2153.  *             given by [-fns].
  2154.  *
  2155.  *          If terminal is only argument then entire entry is
  2156.  *          printed.
  2157.  *
  2158.  *  DESCRIPTION
  2159.  *
  2160.  *    Provides way to test termcap functions.  Can find
  2161.  *    and print an entire termcap terminal entry, or various
  2162.  *    capabilities from the entry.
  2163.  *
  2164.  *  AUTHOR
  2165.  *
  2166.  *    Fred Fish
  2167.  *
  2168.  */
  2169.  
  2170. #include <stdio.h>
  2171.  
  2172. #define TRUE 1
  2173. #define FALSE 0
  2174. #define NO_FILE           -1              /* Returned if can't open file */
  2175. #define NO_ENTRY  0              /* Returned if can't find entry */
  2176. #define SUCCESS      1              /* Returned if entry found ok */
  2177. #define TRUNCATED 2              /* Returned if entry found but trunc */
  2178. #define BUFFER_SIZE 1024
  2179.  
  2180. int eflag = FALSE;
  2181. int fflag = FALSE;
  2182. int nflag = FALSE;
  2183. int sflag = FALSE;
  2184.  
  2185. int got_terminal = FALSE;
  2186. int got_capability = FALSE;
  2187.  
  2188. int ospeed = 15;      /* fake lots of padding */
  2189.  
  2190.  
  2191. /*
  2192.  *  FUNCTION
  2193.  *
  2194.  *    main   termcap test entry point
  2195.  *
  2196.  *  KEY WORDS
  2197.  *
  2198.  *    main
  2199.  *
  2200.  *  SYNOPSIS
  2201.  *
  2202.  *    main(argc,argv)
  2203.  *    int argc;
  2204.  *    char *argv[];
  2205.  *
  2206.  *  DESCRIPTION
  2207.  *
  2208.  *    This is where the termcap test starts executing.    All argument list
  2209.  *    switches are processed first, then all the specified
  2210.  *    capability identification strings are processed.
  2211.  *
  2212.  */
  2213.  
  2214.  
  2215. /*
  2216.  *  PSEUDO CODE
  2217.  *
  2218.  *    Begin main
  2219.  *      Process command line options.
  2220.  *      For each argument list field
  2221.  *          If field was not erased during option processing
  2222.  *          If terminal name field not yet processed then
  2223.  *              Process an assumed terminal name field.
  2224.  *              Set terminal name processed flag.
  2225.  *          Else
  2226.  *              Process a capability field.
  2227.  *              Set capability field processed flag.
  2228.  *          End if
  2229.  *          End if
  2230.  *      End for
  2231.  *      If no capabilities processed then
  2232.  *          Simply dump buffer.
  2233.  *      End if
  2234.  *    End main
  2235.  *
  2236.  */
  2237.  
  2238. main(argc, argv)
  2239. int argc;
  2240. char *argv[];
  2241. {
  2242.     char *argp;
  2243.     int argnum;
  2244.     char buffer[BUFFER_SIZE];
  2245.  
  2246.     options(argc,argv);
  2247.     for (argnum = 1; argnum < argc; argnum++) {
  2248.     if ((argp = argv[argnum]) != NULL) {
  2249.       if (!got_terminal) {
  2250.           terminal(buffer,argp);
  2251.           got_terminal = TRUE;
  2252.       } else {
  2253.           capability(argp);
  2254.           got_capability = TRUE;
  2255.       }
  2256.     }
  2257.     }
  2258.     if (got_terminal && !got_capability) {
  2259.       printf("size = %d\n%s",strlen(buffer),buffer);
  2260.     }
  2261. }
  2262.  
  2263.  
  2264. /*
  2265.  *  FUNCTION
  2266.  *
  2267.  *    options    process command line options
  2268.  *
  2269.  *  SYNOPSIS
  2270.  *
  2271.  *    options(argc,argv)
  2272.  *    int argc;
  2273.  *    char *argv[];
  2274.  *
  2275.  *  DESCRIPTION
  2276.  *
  2277.  *    Scans argument list, processing each switch as it is
  2278.  *    found.  The pointer to each switch string is then
  2279.  *    replaced with a NULL to effectively erase the switch
  2280.  *    argument.
  2281.  *
  2282.  */
  2283.  
  2284.  
  2285. /*
  2286.  *  PSEUDO CODE
  2287.  *
  2288.  *    Begin options
  2289.  *      For each argument in the argument list
  2290.  *          Get pointer to first char of argument.
  2291.  *          If the argument is a switch then
  2292.  *          Replace argument pointer with NULL.
  2293.  *          Look at next argument character.
  2294.  *          While there is another argument character
  2295.  *              Switch on the argument character
  2296.  *              Case "EXPAND":
  2297.  *              Set expand (e) flag.
  2298.  *              Break out of switch.
  2299.  *              Case "BOOLEAN":
  2300.  *              Set boolean (f) flag.
  2301.  *              Break out of switch.
  2302.  *              Case "NUMERIC":
  2303.  *              Set numeric flag.
  2304.  *              Break out of switch.
  2305.  *              Case "STRING":
  2306.  *              Set string flag.
  2307.  *              Break out of switch.
  2308.  *              Default:
  2309.  *              Abort with usage message.
  2310.  *              End switch
  2311.  *          End while
  2312.  *          End if
  2313.  *      End for
  2314.  *    End options
  2315.  *
  2316.  */
  2317.  
  2318.  
  2319. options(argc, argv)
  2320. int argc;
  2321. char *argv[];
  2322. {
  2323.     int i;
  2324.     char c;          /* 1st char of current command-line argument */
  2325.     char *cp;          /* current argument pointer */
  2326.  
  2327.     for (i=1; i<argc; i++) {
  2328.     cp = argv[i];
  2329.     if (*cp == '-') {
  2330.         argv[i] = NULL;
  2331.       cp++;
  2332.       while (c = *cp++) {
  2333.           switch (c) {
  2334.           case 'e':
  2335.           eflag = TRUE;
  2336.           break;
  2337.           case 'f':
  2338.           fflag = TRUE;
  2339.           break;
  2340.           case 'n':
  2341.           nflag = TRUE;
  2342.           break;
  2343.           case 's':
  2344.           sflag = TRUE;
  2345.           break;
  2346.           default:
  2347.           usage();
  2348.           }
  2349.         }
  2350.     }
  2351.     }
  2352. }
  2353.  
  2354.  
  2355. /*
  2356.  *  FUNCTION
  2357.  *
  2358.  *    usage   give usage message and abort
  2359.  *
  2360.  *  KEY WORDS
  2361.  *
  2362.  *    usage
  2363.  *    help processing
  2364.  *    abort locations
  2365.  *
  2366.  *  SYNOPSIS
  2367.  *
  2368.  *    usage()
  2369.  *
  2370.  *  DESCRIPTION
  2371.  *
  2372.  *    Usage is typically called when a problem has been
  2373.  *    detected in the argument list.
  2374.  *    It prints a usage message and exits.
  2375.  *
  2376.  */
  2377.  
  2378.  
  2379. /*
  2380.  *  PSEUDO CODE
  2381.  *
  2382.  *    Begin usage
  2383.  *      Print usage message.
  2384.  *      Exit.
  2385.  *    End usage
  2386.  *
  2387.  */
  2388.  
  2389. usage()
  2390. {
  2391.     printf("Usage: termcap [-fns] terminal [capability [capability ... ]]\n");
  2392.     exit();
  2393. }
  2394.  
  2395.  
  2396.  
  2397. terminal(buffer,name)
  2398. char *buffer;
  2399. char *name;
  2400. {
  2401.     int status;
  2402.  
  2403.     status = tgetent(buffer,name);
  2404.     switch (status) {
  2405.     case NO_FILE:
  2406.       fprintf(stderr,"Can't find a termcap data base file.\n");
  2407.       exit();
  2408.     case NO_ENTRY:
  2409.       fprintf(stderr,"Can't find entry \"%s\"\n",name);
  2410.       exit();
  2411.     case TRUNCATED:
  2412.       fprintf(stderr,"Warning --- entry \"%s\" too long\n",name);
  2413.       break;
  2414.     case SUCCESS:
  2415.     break;
  2416.     default:
  2417.     fprintf(stderr,"? tgetent returned illegal status %d\n",status);
  2418.       exit();
  2419.     }
  2420. }
  2421.  
  2422.  
  2423. capability(id)
  2424. char *id;
  2425. {
  2426.     int value;
  2427.     char buffer[256];
  2428.     char *area;
  2429.     char *ep, *tgoto();
  2430.  
  2431.     if (fflag) {
  2432.       value = tgetflag(id);
  2433.       if (value) {
  2434.       printf("%s TRUE\n",id);
  2435.       } else {
  2436.       printf("%s FALSE\n",id);
  2437.       }
  2438.     } else if (nflag) {
  2439.       value = tgetnum(id);
  2440.       printf("%s = %o octal %d decimal\n",id,value,value);
  2441.     } else if (sflag) {
  2442.       area = buffer;
  2443.       tgetstr(id,&area);
  2444.       if (eflag) {
  2445.       ep = tgoto(buffer,75,23);
  2446.       }
  2447.       doprint(id,buffer);
  2448.       if (eflag) {
  2449.       doprint(id,ep);
  2450.       ep = tgoto(buffer,1,2);
  2451.       doprint(id,ep);
  2452.       }
  2453.     }
  2454. }
  2455.  
  2456.  
  2457. /*
  2458.  *  Use tputs to get a clearer picture of exactly what
  2459.  *  goes out to the terminal....
  2460.  */
  2461.  
  2462. princ(c)
  2463. int c;
  2464. {
  2465.       if (c < 040)
  2466.       printf("^%c",c |= 0100);
  2467.       else
  2468.       printf("%c",c);
  2469. }
  2470.  
  2471. doprint(id,cp)
  2472. char *id;
  2473. char *cp;
  2474. {
  2475.     printf("%s = \"",id);
  2476.     tputs(cp, 1, princ);
  2477.     printf("\"\n");
  2478. }
  2479. SHAR_EOF
  2480. #    End of shell archive
  2481. exit 0
  2482. -------
  2483.