home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume1 / pcurses / part04 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  51.3 KB

  1. Subject:  Terminfo/Curses Part 4 of 11
  2.  
  3. : Run this shell script with "sh" not "csh"
  4. PATH=:/bin:/usr/bin:/usr/ucb
  5. export PATH
  6. if test ! -d =src
  7. then
  8.     echo 'Making directory "=src"'
  9.     mkdir =src
  10. fi
  11. echo 'x - =src/comp_captab.c'
  12. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_captab.c
  13. X/*
  14.  *    comp_captab.c -- The names of the capabilities in a form ready for
  15.  *                 the making of a hash table for the compiler.
  16.  *
  17.  */
  18.  
  19.  
  20. #include "compiler.h"
  21. #include "term.h"
  22.  
  23.  
  24. struct name_table_entry    cap_table[] =
  25. {
  26.     0,           "bw",    BOOLEAN,      0,
  27.     0,           "am",    BOOLEAN,      1,
  28.     0,          "xsb",    BOOLEAN,      2,
  29.     0,          "xhp",    BOOLEAN,      3,
  30.     0,         "xenl",    BOOLEAN,      4,
  31.     0,           "eo",    BOOLEAN,      5,
  32.     0,           "gn",    BOOLEAN,      6,
  33.     0,           "hc",    BOOLEAN,      7,
  34.     0,           "km",    BOOLEAN,      8,
  35.     0,           "hs",    BOOLEAN,      9,
  36.     0,           "in",    BOOLEAN,     10,
  37.     0,           "da",    BOOLEAN,     11,
  38.     0,           "db",    BOOLEAN,     12,
  39.     0,          "mir",    BOOLEAN,     13,
  40.     0,         "msgr",    BOOLEAN,     14,
  41.     0,           "os",    BOOLEAN,     15,
  42.     0,        "eslok",    BOOLEAN,     16,
  43.     0,           "xt",    BOOLEAN,     17,
  44.     0,           "hz",    BOOLEAN,     18,
  45.     0,           "ul",    BOOLEAN,     19,
  46.     0,          "xon",    BOOLEAN,     20,
  47.     0,         "cols",    NUMBER,          0,
  48.     0,           "it",    NUMBER,          1,
  49.     0,        "lines",    NUMBER,          2,
  50.     0,           "lm",    NUMBER,          3,
  51.     0,          "xmc",    NUMBER,          4,
  52.     0,           "pb",    NUMBER,          5,
  53.     0,           "vt",    NUMBER,          6,
  54.     0,          "wsl",    NUMBER,          7,
  55.     0,         "nlab",    NUMBER,          8,
  56.     0,           "lh",    NUMBER,          9,
  57.     0,           "lw",    NUMBER,         10,
  58.     0,          "cbt",    STRING,          0,
  59.     0,          "bel",    STRING,          1,
  60.     0,           "cr",    STRING,          2,
  61.     0,          "csr",    STRING,          3,
  62.     0,          "tbc",    STRING,          4,
  63.     0,        "clear",    STRING,          5,
  64.     0,           "el",    STRING,          6,
  65.     0,           "ed",    STRING,          7,
  66.     0,          "hpa",    STRING,          8,
  67.     0,           "CC",    STRING,          9,
  68.     0,          "cup",    STRING,         10,
  69.     0,         "cud1",    STRING,         11,
  70.     0,         "home",    STRING,         12,
  71.     0,        "civis",    STRING,         13,
  72.     0,         "cub1",    STRING,         14,
  73.     0,        "mrcup",    STRING,         15,
  74.     0,        "cnorm",    STRING,         16,
  75.     0,         "cuf1",    STRING,         17,
  76.     0,           "ll",    STRING,         18,
  77.     0,         "cuu1",    STRING,         19,
  78.     0,        "cvvis",    STRING,         20,
  79.     0,         "dch1",    STRING,         21,
  80.     0,          "dl1",    STRING,         22,
  81.     0,          "dsl",    STRING,         23,
  82.     0,           "hd",    STRING,         24,
  83.     0,        "smacs",    STRING,         25,
  84.     0,        "blink",    STRING,         26,
  85.     0,         "bold",    STRING,         27,
  86.     0,        "smcup",    STRING,         28,
  87.     0,         "smdc",    STRING,         29,
  88.     0,          "dim",    STRING,         30,
  89.     0,         "smir",    STRING,         31,
  90.     0,        "invis",    STRING,         32,
  91.     0,         "prot",    STRING,         33,
  92.     0,          "rev",    STRING,         34,
  93.     0,         "smso",    STRING,         35,
  94.     0,         "smul",    STRING,         36,
  95.     0,          "ech",    STRING,         37,
  96.     0,        "rmacs",    STRING,         38,
  97.     0,         "sgr0",    STRING,         39,
  98.     0,        "rmcup",    STRING,         40,
  99.     0,         "rmdc",    STRING,         41,
  100.     0,         "rmir",    STRING,         42,
  101.     0,         "rmso",    STRING,         43,
  102.     0,         "rmul",    STRING,         44,
  103.     0,        "flash",    STRING,         45,
  104.     0,           "ff",    STRING,         46,
  105.     0,          "fsl",    STRING,         47,
  106.     0,          "is1",    STRING,         48,
  107.     0,          "is2",    STRING,         49,
  108.     0,          "is3",    STRING,         50,
  109.     0,           "if",    STRING,         51,
  110.     0,         "ich1",    STRING,         52,
  111.     0,          "il1",    STRING,         53,
  112.     0,           "ip",    STRING,         54,
  113.     0,          "kbs",    STRING,         55,
  114.     0,         "ktbc",    STRING,         56,
  115.     0,         "kclr",    STRING,         57,
  116.     0,        "kctab",    STRING,         58,
  117.     0,        "kdch1",    STRING,         59,
  118.     0,         "kdl1",    STRING,         60,
  119.     0,        "kcud1",    STRING,         61,
  120.     0,        "krmir",    STRING,         62,
  121.     0,          "kel",    STRING,         63,
  122.     0,          "ked",    STRING,         64,
  123.     0,          "kf0",    STRING,         65,
  124.     0,          "kf1",    STRING,         66,
  125.     0,         "kf10",    STRING,         67,
  126.     0,          "kf2",    STRING,         68,
  127.     0,          "kf3",    STRING,         69,
  128.     0,          "kf4",    STRING,         70,
  129.     0,          "kf5",    STRING,         71,
  130.     0,          "kf6",    STRING,         72,
  131.     0,          "kf7",    STRING,         73,
  132.     0,          "kf8",    STRING,         74,
  133.     0,          "kf9",    STRING,         75,
  134.     0,        "khome",    STRING,         76,
  135.     0,        "kich1",    STRING,         77,
  136.     0,         "kil1",    STRING,         78,
  137.     0,        "kcub1",    STRING,         79,
  138.     0,          "kll",    STRING,         80,
  139.     0,          "knp",    STRING,         81,
  140.     0,          "kpp",    STRING,         82,
  141.     0,        "kcuf1",    STRING,         83,
  142.     0,         "kind",    STRING,         84,
  143.     0,          "kri",    STRING,         85,
  144.     0,         "khts",    STRING,         86,
  145.     0,        "kcuu1",    STRING,         87,
  146.     0,         "rmkx",    STRING,         88,
  147.     0,         "smkx",    STRING,         89,
  148.     0,          "lf0",    STRING,         90,
  149.     0,          "lf1",    STRING,         91,
  150.     0,         "lf10",    STRING,         92,
  151.     0,          "lf2",    STRING,         93,
  152.     0,          "lf3",    STRING,         94,
  153.     0,          "lf4",    STRING,         95,
  154.     0,          "lf5",    STRING,         96,
  155.     0,          "lf6",    STRING,         97,
  156.     0,          "lf7",    STRING,         98,
  157.     0,          "lf8",    STRING,         99,
  158.     0,          "lf9",    STRING,        100,
  159.     0,          "rmm",    STRING,        101,
  160.     0,          "smm",    STRING,        102,
  161.     0,          "nel",    STRING,        103,
  162.     0,          "pad",    STRING,        104,
  163.     0,          "dch",    STRING,        105,
  164.     0,           "dl",    STRING,        106,
  165.     0,          "cud",    STRING,        107,
  166.     0,          "ich",    STRING,        108,
  167.     0,         "indn",    STRING,        109,
  168.     0,           "il",    STRING,        110,
  169.     0,          "cub",    STRING,        111,
  170.     0,          "cuf",    STRING,        112,
  171.     0,          "rin",    STRING,        113,
  172.     0,          "cuu",    STRING,        114,
  173.     0,        "pfkey",    STRING,        115,
  174.     0,        "pfloc",    STRING,        116,
  175.     0,          "pfx",    STRING,        117,
  176.     0,          "mc0",    STRING,        118,
  177.     0,          "mc4",    STRING,        119,
  178.     0,          "mc5",    STRING,        120,
  179.     0,          "rep",    STRING,        121,
  180.     0,          "rs1",    STRING,        122,
  181.     0,          "rs2",    STRING,        123,
  182.     0,          "rs3",    STRING,        124,
  183.     0,           "rf",    STRING,        125,
  184.     0,           "rc",    STRING,        126,
  185.     0,          "vpa",    STRING,        127,
  186.     0,           "sc",    STRING,        128,
  187.     0,          "ind",    STRING,        129,
  188.     0,           "ri",    STRING,        130,
  189.     0,          "sgr",    STRING,        131,
  190.     0,          "hts",    STRING,        132,
  191.     0,         "wind",    STRING,        133,
  192.     0,           "ht",    STRING,        134,
  193.     0,          "tsl",    STRING,        135,
  194.     0,           "uc",    STRING,        136,
  195.     0,           "hu",    STRING,        137,
  196.     0,        "iprog",    STRING,        138,
  197.     0,          "ka1",    STRING,        139,
  198.     0,          "ka3",    STRING,        140,
  199.     0,          "kb2",    STRING,        141,
  200.     0,          "kc1",    STRING,        142,
  201.     0,          "kc3",    STRING,        143,
  202.     0,         "mc5p",    STRING,        144,
  203.     0,          "rmp",    STRING,        145,
  204.     0,         "acsc",    STRING,        146,
  205.     0,          "pln",    STRING,        147,
  206. };
  207.  
  208. struct name_table_entry *cap_hash_table[360];
  209.  
  210. int    Hashtabsize = 360;
  211. int    Captabsize = 180;
  212.  
  213.  
  214. #if (BOOLCOUNT!=21)||(NUMCOUNT!=11)||(STRCOUNT!=148)
  215.     --> term.h and comp_captab.c disagree about the <--
  216.     --> numbers of booleans, numbers and/or strings <--
  217. #endif
  218. //go.sysin dd *
  219. echo 'x - =src/comp_error.c'
  220. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_error.c
  221. X/*********************************************************************
  222. *                         COPYRIGHT NOTICE                           *
  223. **********************************************************************
  224. *        This software is copyright (C) 1982 by Pavel Curtis         *
  225. *                                                                    *
  226. *        Permission is granted to reproduce and distribute           *
  227. *        this file by any means so long as no fee is charged         *
  228. *        above a nominal handling fee and so long as this            *
  229. *        notice is always included in the copies.                    *
  230. *                                                                    *
  231. *        Other rights are reserved except as explicitly granted      *
  232. *        by written permission of the author.                        *
  233. *                Pavel Curtis                                        *
  234. *                Computer Science Dept.                              *
  235. *                405 Upson Hall                                      *
  236. *                Cornell University                                  *
  237. *                Ithaca, NY 14853                                    *
  238. *                                                                    *
  239. *                Ph- (607) 256-4934                                  *
  240. *                                                                    *
  241. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  242. *                decvax!cornell!pavel       (UUCPnet)                *
  243. *********************************************************************/
  244.  
  245. X/*
  246.  *    comp_error.c -- Error message routines
  247.  *
  248.  *  $Log:    RCS/comp_error.v $
  249.  * Revision 2.1  82/10/25  14:45:31  pavel
  250.  * Added Copyright Notice
  251.  * 
  252.  * Revision 2.0  82/10/24  15:16:32  pavel
  253.  * Beta-one Test Release
  254.  * 
  255.  * Revision 1.3  82/08/23  22:29:31  pavel
  256.  * The REAL Alpha-one Release Version
  257.  * 
  258.  * Revision 1.2  82/08/19  19:09:44  pavel
  259.  * Alpha Test Release One
  260.  * 
  261.  * Revision 1.1  82/08/12  18:36:02  pavel
  262.  * Initial revision
  263.  * 
  264.  *
  265.  */
  266.  
  267. static char RCSid[] =
  268.     "$Header:   RCS/comp_error.v  Revision 2.1  82/10/25  14:45:31  pavel  Exp$";
  269.  
  270. #include "compiler.h"
  271.  
  272. extern char *string_table;
  273. extern short term_names;
  274.  
  275. warning(fmt, a1, a2, a3, a4, a5, a6)
  276. char    *fmt, *a1, *a2, *a3, *a4, *a5, *a6;
  277. {
  278.     fprintf (stderr, "compile: Warning: near line %d: ", curr_line);
  279.     fprintf (stderr, "terminal '%s', ", string_table+term_names);
  280.     fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
  281.     fprintf (stderr, "\n");
  282. }
  283.  
  284.  
  285. err_abort(fmt, a1, a2, a3, a4, a5, a6)
  286. char    *fmt, *a1, *a2, *a3, *a4, *a5, *a6;
  287. {
  288.     fprintf (stderr, "compile: Line %d: ", curr_line);
  289.     fprintf (stderr, "terminal '%s', ", string_table+term_names);
  290.     fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
  291.     fprintf (stderr, "\n");
  292.     exit(1);
  293. }
  294.  
  295.  
  296. syserr_abort(fmt, a1, a2, a3, a4, a5, a6)
  297. char    *fmt, *a1, *a2, *a3, *a4, *a5, *a6;
  298. {
  299.     fprintf (stderr, "PROGRAM ERROR: Line %d: ", curr_line);
  300.     fprintf (stderr, "terminal '%s', ", string_table+term_names);
  301.     fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
  302.     fprintf (stderr, "\n");
  303.     abort();
  304. }
  305. //go.sysin dd *
  306. echo 'x - =src/comp_hash.c'
  307. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_hash.c
  308. X/*********************************************************************
  309. *                         COPYRIGHT NOTICE                           *
  310. **********************************************************************
  311. *        This software is copyright (C) 1982 by Pavel Curtis         *
  312. *                                                                    *
  313. *        Permission is granted to reproduce and distribute           *
  314. *        this file by any means so long as no fee is charged         *
  315. *        above a nominal handling fee and so long as this            *
  316. *        notice is always included in the copies.                    *
  317. *                                                                    *
  318. *        Other rights are reserved except as explicitly granted      *
  319. *        by written permission of the author.                        *
  320. *                Pavel Curtis                                        *
  321. *                Computer Science Dept.                              *
  322. *                405 Upson Hall                                      *
  323. *                Cornell University                                  *
  324. *                Ithaca, NY 14853                                    *
  325. *                                                                    *
  326. *                Ph- (607) 256-4934                                  *
  327. *                                                                    *
  328. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  329. *                decvax!cornell!pavel       (UUCPnet)                *
  330. *********************************************************************/
  331.  
  332. X/*
  333.  *    comp_hash.c --- Routines to deal with the hashtable of capability
  334.  *            names.
  335.  *
  336.  *  $Log:    RCS/comp_hash.v $
  337.  * Revision 2.1  82/10/25  14:45:34  pavel
  338.  * Added Copyright Notice
  339.  * 
  340.  * Revision 2.0  82/10/24  15:16:34  pavel
  341.  * Beta-one Test Release
  342.  * 
  343.  * Revision 1.3  82/08/23  22:29:33  pavel
  344.  * The REAL Alpha-one Release Version
  345.  * 
  346.  * Revision 1.2  82/08/19  19:09:46  pavel
  347.  * Alpha Test Release One
  348.  * 
  349.  * Revision 1.1  82/08/12  18:36:23  pavel
  350.  * Initial revision
  351.  * 
  352.  *
  353.  */
  354.  
  355. static char RCSid[] =
  356.     "$Header:   RCS/comp_hash.v  Revision 2.1  82/10/25  14:45:34  pavel  Exp$";
  357.  
  358. #include "compiler.h"
  359. #include "term.h"
  360.  
  361.  
  362.  
  363. X/*
  364.  *    make_hash_table()
  365.  *
  366.  *    Takes the entries in cap_table[] and hashes them into cap_hash_table[]
  367.  *    by name.  There are Captabsize entries in cap_table[] and Hashtabsize
  368.  *    slots in cap_hash_table[].
  369.  *
  370.  */
  371.  
  372. make_hash_table()
  373. {
  374.     int    i;
  375.     int    hashvalue;
  376.     int    collisions = 0;
  377.  
  378.     for (i=0; i < Captabsize; i++)
  379.     {
  380.         hashvalue = hash_function(cap_table[i].nte_name);       
  381.         DEBUG(9, "%d\n", hashvalue);
  382.  
  383.         if (cap_hash_table[hashvalue] != (struct name_table_entry *) 0)
  384.         collisions++;
  385.  
  386.         cap_table[i].nte_link = cap_hash_table[hashvalue];
  387.         cap_hash_table[hashvalue] = &cap_table[i];
  388.     }
  389.  
  390.     DEBUG(3, "Hash table complete\n%d collisions ", collisions);
  391.     DEBUG(3, "out of %d entries\n", Captabsize);
  392. }
  393.  
  394.  
  395.  
  396. X/*
  397.  *    int hash_function(string)
  398.  *
  399.  *    Computes the hashing function on the given string.
  400.  *
  401.  *    The current hash function is the sum of each consectutive pair
  402.  *    of characters, taken as two-byte integers, mod Hashtabsize.
  403.  *
  404.  */
  405.  
  406. static
  407. int
  408. hash_function(string)
  409. char    *string;
  410. {
  411.     long    sum = 0;
  412.  
  413.     while (*string)
  414.     {
  415.         sum += *string + (*(string + 1) << 8);
  416.         string++;
  417.     }
  418.  
  419.     return (sum % Hashtabsize);
  420. }
  421.  
  422.  
  423.  
  424. X/*
  425.  *    struct name_table_entry *
  426.  *    find_entry(string)
  427.  *
  428.  *    Finds the entry for the given string in the hash table if present.
  429.  *    Returns a pointer to the entry in the table or 0 if not found.
  430.  *
  431.  */
  432.  
  433. struct name_table_entry *
  434. find_entry(string)
  435. char    *string;
  436. {
  437.     int    hashvalue;
  438.     struct name_table_entry    *ptr;
  439.  
  440.     hashvalue = hash_function(string);
  441.  
  442.     ptr = cap_hash_table[hashvalue];
  443.  
  444.     while (ptr != (struct name_table_entry *) 0  &&
  445.                                   strcmp(ptr->nte_name, string) != 0)
  446.         ptr = ptr->nte_link;
  447.  
  448.     return (ptr);
  449. }
  450. //go.sysin dd *
  451. echo 'x - =src/comp_main.c'
  452. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_main.c
  453. X/*********************************************************************
  454. *                         COPYRIGHT NOTICE                           *
  455. **********************************************************************
  456. *        This software is copyright (C) 1982 by Pavel Curtis         *
  457. *                                                                    *
  458. *        Permission is granted to reproduce and distribute           *
  459. *        this file by any means so long as no fee is charged         *
  460. *        above a nominal handling fee and so long as this            *
  461. *        notice is always included in the copies.                    *
  462. *                                                                    *
  463. *        Other rights are reserved except as explicitly granted      *
  464. *        by written permission of the author.                        *
  465. *                Pavel Curtis                                        *
  466. *                Computer Science Dept.                              *
  467. *                405 Upson Hall                                      *
  468. *                Cornell University                                  *
  469. *                Ithaca, NY 14853                                    *
  470. *                                                                    *
  471. *                Ph- (607) 256-4934                                  *
  472. *                                                                    *
  473. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  474. *                decvax!cornell!pavel       (UUCPnet)                *
  475. *********************************************************************/
  476.  
  477. X/*
  478.  *    comp_main.c --- Main program for terminfo compiler
  479.  *
  480.  *  $Log:    RCS/comp_main.v $
  481.  * Revision 2.1  82/10/25  14:45:37  pavel
  482.  * Added Copyright Notice
  483.  * 
  484.  * Revision 2.0  82/10/24  15:16:37  pavel
  485.  * Beta-one Test Release
  486.  * 
  487.  * Revision 1.3  82/08/23  22:29:36  pavel
  488.  * The REAL Alpha-one Release Version
  489.  * 
  490.  * Revision 1.2  82/08/19  19:09:49  pavel
  491.  * Alpha Test Release One
  492.  * 
  493.  * Revision 1.1  82/08/12  18:36:55  pavel
  494.  * Initial revision
  495.  * 
  496.  *
  497.  */
  498.  
  499. static char RCSid[] =
  500.     "$Header:   RCS/comp_main.v  Revision 2.1  82/10/25  14:45:37  pavel  Exp$";
  501.  
  502.  
  503. #include <sys/types.h>
  504. #include <sys/stat.h>
  505. #include "compiler.h"
  506.  
  507. char    *source_file = "/etc/terminfo";
  508. char    *destination = SRCDIR;
  509. char    *usage_string = "\tcompile [-v[n]] source-file\n";
  510. char    check_only = 0;
  511.  
  512.  
  513. main (argc, argv)
  514. int    argc;
  515. char    *argv[];
  516. {
  517.     int    i;
  518.     int    argflag = FALSE;
  519.  
  520.     debug_level = 0;
  521.  
  522.     for (i=1; i < argc; i++)
  523.     {
  524.         if (argv[i][0] == '-')
  525.         {
  526.         switch (argv[i][1])
  527.         {
  528.             case 'c':
  529.             check_only = 1;
  530.             break;
  531.  
  532.             case 'v':
  533.             debug_level = argv[i][2]  ?  atoi(&argv[i][2])  :  1;
  534.             break;
  535.  
  536.             default:
  537.             fprintf(stderr, "%s: Unknown option. Usage is:\n\t%s\n",
  538.                                argv[0], usage_string);
  539.             exit(1);
  540.         }
  541.         }
  542.         else if (argflag)
  543.         {
  544.         fprintf(stderr, "%s: Too many file names.  Usage is:\n\t%s\n",
  545.                             argv[0], usage_string);
  546.         exit(1);
  547.         }
  548.         else
  549.         {
  550.         argflag = TRUE;
  551.         source_file = argv[i];
  552.         }
  553.     }
  554.  
  555.     init(argv[0]);
  556.     make_hash_table();
  557.     compile();
  558.  
  559.     exit(0);
  560. }
  561.  
  562.  
  563.  
  564.  
  565. X/*
  566.  *    init(progname)
  567.  *
  568.  *    Miscelaneous initialisations
  569.  *
  570.  *    Open source file as standard input
  571.  *    Check for access rights to destination directories
  572.  *    Create any directories which don't exist.
  573.  *
  574.  */
  575.  
  576. init(progname)
  577. char    *progname;
  578. {
  579.     struct stat    statbuf;
  580.     char        *dirnames = "abcdefghijklmnopqrstuvwxyz0123456789";
  581.     char        *getenv();
  582.     char        dir[2];
  583.  
  584.     start_time = time(0);
  585.  
  586.     curr_line = 0;
  587.  
  588.     if (freopen(source_file, "r", stdin) == NULL)
  589.     {
  590.         fprintf(stderr, "%s: Can't open %s\n", progname, source_file);
  591.         exit(1);
  592.     }
  593.  
  594.     if (getenv("TERMINFO") != NULL)
  595.         destination = getenv("TERMINFO");
  596.  
  597.     if (access(destination, 7) < 0)
  598.     {
  599.         fprintf(stderr, "%s: %s non-existant or permission denied\n",
  600.                             progname, destination);
  601.         exit(1);
  602.     }
  603.  
  604.     if (chdir(destination) < 0)
  605.     {
  606.         fprintf(stderr, "%s: %s is not a directory\n",
  607.                             progname, destination);
  608.         exit(1);
  609.     }
  610.     
  611.     dir[1] = '\0';
  612.     for (dir[0] = *dirnames; *dirnames != '\0'; dir[0] = *(++dirnames))
  613.     {
  614.         if (stat(dir, &statbuf) < 0)
  615.         {
  616.         mkdir(dir);
  617.         chmod(dir, 0755);
  618.         }
  619.         else if (access(dir, 7) < 0)
  620.         {
  621.         fprintf(stderr, "%s: %s/%s: Permission denied\n",
  622.                             progname, destination, dir);
  623.         exit(1);
  624.         }
  625.         else if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
  626.         {
  627.         fprintf(stderr, "%s: %s/%s: Not a directory\n",
  628.                             progname, destination, dir);
  629.         exit(1);
  630.         }
  631.     }
  632. }
  633.  
  634.  
  635.  
  636. X/*
  637.  *    mkdir(dirname)
  638.  *
  639.  *    forks and execs the mkdir program to create the given directory
  640.  *
  641.  */
  642.  
  643. mkdir(dirname)
  644. char    *dirname;
  645. {
  646.     int    fork_rtn;
  647.     int    status;
  648.  
  649.     fork_rtn = fork();
  650.  
  651.     switch (fork_rtn)
  652.     {
  653.         case 0:        /* Child */
  654.         execl("/bin/mkdir", "mkdir", dirname, 0);
  655.         exit(1);
  656.  
  657.         case -1:        /* Error */
  658.         fprintf(stderr, "compile: SYSTEM ERROR!! Fork failed!!!\n");
  659.         abort();
  660.  
  661.         default:
  662.         wait(&status);
  663.         if (status != 0)
  664.             syserr_abort("mkdir returned bad status");
  665.         break;
  666.     }
  667. }
  668. //go.sysin dd *
  669. echo 'x - =src/comp_parse.c'
  670. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_parse.c
  671. X/*********************************************************************
  672. *                         COPYRIGHT NOTICE                           *
  673. **********************************************************************
  674. *        This software is copyright (C) 1982 by Pavel Curtis         *
  675. *                                                                    *
  676. *        Permission is granted to reproduce and distribute           *
  677. *        this file by any means so long as no fee is charged         *
  678. *        above a nominal handling fee and so long as this            *
  679. *        notice is always included in the copies.                    *
  680. *                                                                    *
  681. *        Other rights are reserved except as explicitly granted      *
  682. *        by written permission of the author.                        *
  683. *                Pavel Curtis                                        *
  684. *                Computer Science Dept.                              *
  685. *                405 Upson Hall                                      *
  686. *                Cornell University                                  *
  687. *                Ithaca, NY 14853                                    *
  688. *                                                                    *
  689. *                Ph- (607) 256-4934                                  *
  690. *                                                                    *
  691. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  692. *                decvax!cornell!pavel       (UUCPnet)                *
  693. *********************************************************************/
  694.  
  695. X/*
  696.  *    comp_parse.c -- The high-level (ha!) parts of the compiler,
  697.  *            that is, the routines which drive the scanner,
  698.  *            etc.
  699.  *
  700.  *   $Log:    comp_parse.c,v $
  701.  * Revision 3.1  84/12/13  11:19:32  john
  702.  * Revisions by Mark Horton
  703.  * 
  704.  * Revision 2.1  82/10/25  14:45:43  pavel
  705.  * Added Copyright Notice
  706.  * 
  707.  * Revision 2.0  82/10/24  15:16:39  pavel
  708.  * Beta-one Test Release
  709.  * 
  710.  * Revision 1.3  82/08/23  22:29:39  pavel
  711.  * The REAL Alpha-one Release Version
  712.  * 
  713.  * Revision 1.2  82/08/19  19:09:53  pavel
  714.  * Alpha Test Release One
  715.  * 
  716.  * Revision 1.1  82/08/12  18:37:12  pavel
  717.  * Initial revision
  718.  * 
  719.  *
  720.  */
  721.  
  722. static char RCSid[] =
  723.     "$Header: comp_parse.c,v 3.1 84/12/13 11:19:32 john Exp $";
  724.  
  725. #include <sys/types.h>
  726. #include <sys/stat.h>
  727. #include <stdio.h>
  728. #include <ctype.h>
  729. #include "compiler.h"
  730. #include "term.h"
  731. #include "object.h"
  732.  
  733.  
  734. char    *string_table;
  735. int    next_free;    /* next free character in string_table */
  736. int    table_size = 0; /* current string_table size */
  737. short    term_names;    /* string table offset - current terminal */
  738. int    part2 = 0;    /* set to allow old compiled defns to be used */
  739. int    complete = 0;    /* 1 if entry done with no forward uses */
  740.  
  741. struct use_item
  742. {
  743.     long    offset;
  744.     struct use_item    *fptr, *bptr;
  745. };
  746.  
  747. struct use_header
  748. {
  749.     struct use_item    *head, *tail;
  750. };
  751.  
  752. struct use_header    use_list = {NULL, NULL};
  753. int            use_count = 0;
  754.  
  755. X/*
  756.  *  The use_list is a doubly-linked list with NULLs terminating the lists:
  757.  *
  758.  *       use_item    use_item    use_item
  759.  *      ---------   ---------   ---------
  760.  *      |       |   |       |   |       |   offset
  761.  *        |-------|   |-------|   |-------|
  762.  *      |   ----+-->|   ----+-->|  NULL |   fptr
  763.  *      |-------|   |-------|   |-------|
  764.  *      |  NULL |<--+----   |<--+----   |   bptr
  765.  *      ---------   ---------   ---------
  766.  *      ^                       ^
  767.  *      |  ------------------   |
  768.  *      |  |       |        |   |
  769.  *      +--+----   |    ----+---+
  770.  *         |       |        |
  771.  *         ------------------
  772.  *           head     tail
  773.  *              use_list
  774.  *
  775.  */
  776.  
  777.  
  778. X/*
  779.  *    compile()
  780.  *
  781.  *    Main loop of the compiler.
  782.  *
  783.  *    get_token()
  784.  *    if curr_token != NAMES
  785.  *        err_abort()
  786.  *    while (not at end of file)
  787.  *        do an entry
  788.  *
  789.  */
  790.  
  791. compile()
  792. {
  793.     char            line[1024];
  794.     int            token_type;
  795.     struct use_item    *ptr;
  796.     int            old_use_count;
  797.  
  798.     token_type = get_token();
  799.  
  800.     if (token_type != NAMES)
  801.         err_abort("File does not start with terminal names in column one");
  802.     
  803.     while (token_type != EOF)
  804.         token_type = do_entry(NULL);
  805.  
  806.     DEBUG(2, "Starting handling of forward USE's\n", "");
  807.  
  808.     for (part2=0; part2<2; part2++) {
  809.         old_use_count = -1;
  810.     DEBUG(2, "\n\nPART %d\n\n", part2);
  811.         while (use_list.head != NULL  &&  old_use_count != use_count)
  812.         {
  813.         old_use_count = use_count;
  814.         for (ptr = use_list.tail; ptr != NULL; ptr = ptr->bptr)
  815.         {
  816.             fseek(stdin, ptr->offset, 0);
  817.             reset_input();
  818.             if ((token_type = get_token()) != NAMES)
  819.             syserr_abort("Token after a seek not NAMES");
  820.             (void) do_entry(ptr);
  821.             if (complete)
  822.             dequeue(ptr);
  823.         }
  824.  
  825.         for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
  826.         {
  827.             fseek(stdin, ptr->offset, 0);
  828.             reset_input();
  829.             if ((token_type = get_token()) != NAMES)
  830.             syserr_abort("Token after a seek not NAMES");
  831.             (void) do_entry(ptr);
  832.             if (complete)
  833.             dequeue(ptr);
  834.         }
  835.         
  836.         DEBUG(2, "Finished a pass through enqueued forward USE's\n", "");
  837.         }
  838.     }
  839.  
  840.     if (use_list.head != NULL)
  841.     {
  842.         fprintf(stderr, "\nError in following up use-links.  Either there is\n");
  843.         fprintf(stderr, "a loop in the links or they reference non-existant\n");
  844.         fprintf(stderr, "terminals.  The following is a list of the entries\n");
  845.         fprintf(stderr, "involved:\n\n");
  846.  
  847.         for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
  848.         {
  849.         fseek(stdin, ptr->offset, 0);
  850.         fgets(line, 1024, stdin);
  851.         fprintf(stderr, "%s", line);
  852.         }
  853.  
  854.         exit(1);
  855.     }
  856. }
  857.  
  858. dump_list(str)
  859. char *str;
  860. {
  861.     struct use_item *ptr;
  862.     char line[512];
  863.  
  864.     fprintf(stderr, "dump_list %s\n", str);
  865.     for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
  866.     {
  867.         fseek(stdin, ptr->offset, 0);
  868.         fgets(line, 1024, stdin);
  869.         fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
  870.         ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
  871.     }
  872.     fprintf(stderr, "\n");
  873. }
  874.  
  875.  
  876.  
  877. X/*
  878.  *    int
  879.  *    do_entry(item_ptr)
  880.  *
  881.  *    Compile one entry.  During the first pass, item_ptr is NULL.  In pass
  882.  *    two, item_ptr points to the current entry in the use_list.
  883.  *
  884.  *    found-forward-use = FALSE
  885.  *    re-initialise internal arrays
  886.  *    save names in string_table
  887.  *    get_token()
  888.  *    while (not EOF and not NAMES)
  889.  *        if found-forward-use
  890.  *        do nothing
  891.  *        else if 'use'
  892.  *        if handle_use() < 0
  893.  *            found-forward-use = TRUE
  894.  *          else
  895.  *            check for existance and type-correctness
  896.  *            enter cap into structure
  897.  *            if STRING
  898.  *                save string in string_table
  899.  *        get_token()
  900.  *      if ! found-forward-use
  901.  *        clear CANCELS out of the structure
  902.  *        dump compiled entry into filesystem
  903.  *
  904.  */
  905.  
  906. int
  907. do_entry(item_ptr)
  908. struct use_item    *item_ptr;
  909. {
  910.     long                    entry_offset;
  911.     int                    i;
  912.     register int                token_type;
  913.     register struct name_table_entry    *entry_ptr;
  914.     int                    found_forward_use = FALSE;
  915.     char                    Booleans[BOOLCOUNT];
  916.     short                    Numbers[NUMCOUNT],
  917.                         Strings[STRCOUNT];
  918.  
  919.     init_structure(Booleans, Numbers, Strings);
  920.     complete = 0;
  921.     term_names = save_str(curr_token.tk_name);
  922.     DEBUG(2, "Starting '%s'\n", curr_token.tk_name);
  923.     entry_offset = curr_file_pos;
  924.  
  925.     for (token_type = get_token();
  926.         token_type != EOF  &&  token_type != NAMES;
  927.         token_type = get_token())
  928.     {
  929.         if (found_forward_use)
  930.         /* do nothing */ ;
  931.         else if (strcmp(curr_token.tk_name, "use") == 0)
  932.         {
  933.         if (handle_use(item_ptr, entry_offset,
  934.                     Booleans, Numbers, Strings) < 0)
  935.             found_forward_use = TRUE;
  936.         }
  937.         else
  938.         {
  939.         entry_ptr = find_entry(curr_token.tk_name);
  940.  
  941.         if (entry_ptr == NOTFOUND) {
  942.             warning("Unknown Capability - '%s'",
  943.                                                           curr_token.tk_name);
  944.             continue;
  945.         }
  946.  
  947.  
  948.         if (token_type != CANCEL
  949.                                         &&  entry_ptr->nte_type != token_type)
  950.             warning("Wrong type used for capability '%s'",
  951.                               curr_token.tk_name);
  952.         switch (token_type)
  953.         {
  954.             case CANCEL:
  955.             switch (entry_ptr->nte_type)
  956.             {
  957.                 case BOOLEAN:
  958.                 Booleans[entry_ptr->nte_index] = -2;
  959.                 break;
  960.  
  961.                 case NUMBER:
  962.                 Numbers[entry_ptr->nte_index] = -2;
  963.                 break;
  964.  
  965.                 case STRING:
  966.                 Strings[entry_ptr->nte_index] = -2;
  967.                 break;
  968.             }
  969.             break;
  970.         
  971.             case BOOLEAN:
  972.             Booleans[entry_ptr->nte_index] = TRUE;
  973.             break;
  974.             
  975.             case NUMBER:
  976.             Numbers[entry_ptr->nte_index] =
  977.                                                       curr_token.tk_valnumber;
  978.             break;
  979.  
  980.             case STRING:
  981.             Strings[entry_ptr->nte_index] =
  982.                                             save_str(curr_token.tk_valstring);
  983.             break;
  984.  
  985.             default:
  986.             warning("Unknown token type");
  987.             panic_mode(',');
  988.             continue;
  989.         }
  990.         } /* end else cur_token.name != "use" */
  991.  
  992.     } /* endwhile (not EOF and not NAMES) */
  993.  
  994.     if (found_forward_use)
  995.         return(token_type);
  996.  
  997.     for (i=0; i < BOOLCOUNT; i++)
  998.     {
  999.         if (Booleans[i] == -2)
  1000.         Booleans[i] = FALSE;
  1001.     }
  1002.  
  1003.     for (i=0; i < NUMCOUNT; i++)
  1004.     {
  1005.         if (Numbers[i] == -2)
  1006.         Numbers[i] = -1;
  1007.     }
  1008.  
  1009.     for (i=0; i < STRCOUNT; i++)
  1010.     {
  1011.         if (Strings[i] == -2)
  1012.         Strings[i] = -1;
  1013.     }
  1014.  
  1015.     dump_structure(term_names, Booleans, Numbers, Strings);
  1016.  
  1017.     complete = 1;
  1018.     return(token_type);
  1019. }
  1020.  
  1021.  
  1022.  
  1023.  
  1024. X/*
  1025.  *    enqueue(offset)
  1026.  *
  1027.  *      Put a record of the given offset onto the use-list.
  1028.  *
  1029.  */
  1030.  
  1031. enqueue(offset)
  1032. long    offset;
  1033. {
  1034.     struct use_item    *item;
  1035.     char            *malloc();
  1036.  
  1037.     item = (struct use_item *) malloc(sizeof(struct use_item));
  1038.  
  1039.     if (item == NULL)
  1040.         syserr_abort("Not enough memory for use_list element");
  1041.  
  1042.     item->offset = offset;
  1043.  
  1044.     if (use_list.head != NULL)
  1045.     {
  1046.         item->bptr = use_list.tail;
  1047.         use_list.tail->fptr = item;
  1048.         item->fptr = NULL;
  1049.         use_list.tail = item;
  1050.     }
  1051.     else
  1052.     {
  1053.         use_list.tail = use_list.head = item;
  1054.         item->fptr = item->bptr = NULL;
  1055.     }
  1056.  
  1057.     use_count ++;
  1058. }
  1059.  
  1060.  
  1061.  
  1062.  
  1063. X/*
  1064.  *    dequeue(ptr)
  1065.  *
  1066.  *    remove the pointed-to item from the use_list
  1067.  *
  1068.  */
  1069.  
  1070. dequeue(ptr)
  1071. struct use_item    *ptr;
  1072. {
  1073.     if (ptr->fptr == NULL)
  1074.         use_list.tail = ptr->bptr;
  1075.     else
  1076.         (ptr->fptr)->bptr = ptr->bptr;
  1077.  
  1078.     if (ptr->bptr == NULL)
  1079.         use_list.head = ptr->fptr;
  1080.     else
  1081.         (ptr->bptr)->fptr = ptr->fptr;
  1082.     
  1083.     use_count --;
  1084. }
  1085.  
  1086.  
  1087.  
  1088. X/*
  1089.  *    dump_structure()
  1090.  *
  1091.  *    Save the compiled version of a description in the filesystem.
  1092.  *
  1093.  *    make a copy of the name-list
  1094.  *    break it up into first-name and all-but-last-name
  1095.  *    creat(first-name)
  1096.  *    write object information to first-name
  1097.  *    close(first-name)
  1098.  *      for each name in all-but-last-name
  1099.  *        link to first-name
  1100.  *
  1101.  */
  1102.  
  1103. dump_structure(term_names, Booleans, Numbers, Strings)
  1104. short    term_names;
  1105. char    Booleans[];
  1106. short    Numbers[];
  1107. short    Strings[];
  1108. {
  1109.     struct stat    statbuf;
  1110.     FILE        *fp;
  1111.     char        name_list[1024];
  1112.     register char    *first_name, *other_names;
  1113.     register char    *ptr;
  1114.     char        filename[50];
  1115.     char        linkname[50];
  1116.     extern char check_only;
  1117.  
  1118.     strcpy(name_list, term_names + string_table);
  1119.     DEBUG(7, "Name list = '%s'\n", name_list);
  1120.  
  1121.     first_name = name_list;
  1122.  
  1123.     ptr = &name_list[strlen(name_list) - 1];
  1124.     other_names = ptr + 1;
  1125.  
  1126.     while (ptr > name_list  &&  *ptr != '|')
  1127.         ptr--;
  1128.  
  1129.     if (ptr != name_list)
  1130.     {
  1131.         *ptr = '\0';
  1132.  
  1133.         for (ptr = name_list; *ptr != '\0'  &&  *ptr != '|'; ptr++)
  1134.         ;
  1135.         
  1136.         if (*ptr == '\0')
  1137.         other_names = ptr;
  1138.         else
  1139.         {
  1140.         *ptr = '\0';
  1141.         other_names = ptr + 1;
  1142.         }
  1143.     }
  1144.  
  1145.     if (check_only) {
  1146.         DEBUG(1, "Checked %s\n", first_name);
  1147.         return;
  1148.     }
  1149.  
  1150.     DEBUG(7, "First name = '%s'\n", first_name);
  1151.     DEBUG(7, "Other names = '%s'\n", other_names);
  1152.  
  1153.     if (strlen(first_name) > 100)
  1154.         warning("'%s': terminal name too long.", first_name);
  1155.  
  1156.     check_name(first_name);
  1157.  
  1158.     sprintf(filename, "%c/%s", first_name[0], first_name);
  1159.  
  1160.     if (stat(filename, &statbuf) >= 0  &&  statbuf.st_mtime >= start_time)
  1161.     {
  1162.         warning("'%s' defined in more than one entry.", first_name);
  1163.         fprintf(stderr, "Entry being used is '%s'.\n",
  1164.                 (unsigned) term_names + string_table);
  1165.     }
  1166.  
  1167.     unlink(filename);
  1168.     fp = fopen(filename, "w");
  1169.     if (fp == NULL)
  1170.     {
  1171.         perror(filename);
  1172.         syserr_abort("Can't open %s/%s\n", destination, filename);
  1173.     }
  1174.     DEBUG(1, "Created %s\n", filename);
  1175.  
  1176.     if (write_object(fp, term_names, Booleans, Numbers, Strings) < 0)
  1177.     {
  1178.         syserr_abort("Error in writing %s/%s", destination, filename);
  1179.     }
  1180.     fclose(fp);
  1181.  
  1182.     while (*other_names != '\0')
  1183.     {
  1184.         ptr = other_names++;
  1185.         while (*other_names != '|'  &&  *other_names != '\0')
  1186.         other_names++;
  1187.  
  1188.         if (*other_names != '\0')
  1189.         *(other_names++) = '\0';
  1190.  
  1191.         if (strlen(ptr) > 100)
  1192.         {
  1193.         warning("'%s': terminal name too long.", ptr);
  1194.         continue;
  1195.         }
  1196.  
  1197.         sprintf(linkname, "%c/%s", ptr[0], ptr);
  1198.  
  1199.         if (strcmp(filename, linkname) == 0)
  1200.         {
  1201.         warning("Terminal name '%s' synonym for itself", first_name);
  1202.         }
  1203.         else if (stat(linkname, &statbuf) >= 0  &&
  1204.                         statbuf.st_mtime >= start_time)
  1205.         {
  1206.         warning("'%s' defined in more than one entry.", ptr);
  1207.         fprintf(stderr, "Entry being used is '%s'.\n",
  1208.                 (unsigned) term_names + string_table);
  1209.         }
  1210.         else
  1211.         {
  1212.         unlink(linkname);
  1213.         if (link(filename, linkname) < 0)
  1214.             syserr_abort("Can't link %s to %s", filename, linkname);
  1215.         DEBUG(1, "Linked %s\n", linkname);
  1216.         }
  1217.     }
  1218. }
  1219.  
  1220.  
  1221.  
  1222.  
  1223. X/*
  1224.  *    int
  1225.  *    write_object(fp, term_names, Booleans, Numbers, Strings)
  1226.  *
  1227.  *    Write out the compiled entry to the given file.
  1228.  *    Return 0 if OK or -1 if not.
  1229.  *
  1230.  */
  1231.  
  1232. #define swap(x)        (((x >> 8) & 0377) + 256 * (x & 0377))
  1233.  
  1234. #define might_swap(x)    (must_swap()  ?  swap(x)  :  (x))
  1235.  
  1236.  
  1237. int
  1238. write_object(fp, term_names, Booleans, Numbers, Strings)
  1239. XFILE    *fp;
  1240. short    term_names;
  1241. char    Booleans[];
  1242. short    Numbers[];
  1243. short    Strings[];
  1244. {
  1245.         struct header    header;
  1246.     char        *namelist;
  1247.     short        namelen;
  1248.     char        zero = '\0';
  1249.     int        i;
  1250.  
  1251.     namelist = term_names + string_table;
  1252.     namelen = strlen(namelist) + 1;
  1253.  
  1254.     if (must_swap())
  1255.     {
  1256.         header.magic = swap(MAGIC);
  1257.         header.name_size = swap(namelen);
  1258.         header.bool_count = swap(BOOLCOUNT);
  1259.         header.num_count = swap(NUMCOUNT);
  1260.         header.str_count = swap(STRCOUNT);
  1261.         header.str_size = swap(next_free);
  1262.     }
  1263.     else
  1264.     {
  1265.         header.magic = MAGIC;
  1266.         header.name_size = namelen;
  1267.         header.bool_count = BOOLCOUNT;
  1268.         header.num_count = NUMCOUNT;
  1269.         header.str_count = STRCOUNT;
  1270.         header.str_size = next_free;
  1271.     }
  1272.  
  1273.     if (fwrite(&header, sizeof(header), 1, fp) != 1
  1274.         ||  fwrite(namelist, sizeof(char), namelen, fp) != namelen
  1275.         ||  fwrite(Booleans, sizeof(char), BOOLCOUNT, fp) != BOOLCOUNT)
  1276.         return(-1);
  1277.     
  1278.     if ((namelen+BOOLCOUNT) % 2 != 0  &&  fwrite(&zero, sizeof(char), 1, fp) != 1)
  1279.         return(-1);
  1280.  
  1281.     if (must_swap())
  1282.     {
  1283.         for (i=0; i < NUMCOUNT; i++)
  1284.         Numbers[i] = swap(Numbers[i]);
  1285.         for (i=0; i < STRCOUNT; i++)
  1286.         Strings[i] = swap(Strings[i]);
  1287.     }
  1288.  
  1289.     if (fwrite(Numbers, sizeof(short), NUMCOUNT, fp) != NUMCOUNT
  1290.            ||  fwrite(Strings, sizeof(short), STRCOUNT, fp) != STRCOUNT
  1291.            ||  fwrite(string_table, sizeof(char), next_free, fp)
  1292.                                   != next_free)
  1293.         return(-1);
  1294.  
  1295. }
  1296.  
  1297.  
  1298.  
  1299. X/*
  1300.  *    check_name(name)
  1301.  *
  1302.  *    Generate an error message if given name does not begin with a
  1303.  *    digit or lower-case letter.
  1304.  *
  1305.  */
  1306.  
  1307. check_name(name)
  1308. char    *name;
  1309. {
  1310.     if (! isdigit(name[0])  &&  ! islower(name[0]))
  1311.     {
  1312.         fprintf(stderr, "compile: Line %d: Illegal terminal name - '%s'\n",
  1313.                                 curr_line, name);
  1314.         fprintf(stderr,
  1315.             "Terminal names must start with lowercase or digit\n");
  1316.         exit(1);
  1317.     }
  1318. }
  1319.  
  1320.  
  1321.  
  1322. X/*
  1323.  *    int
  1324.  *    save_str(string)
  1325.  *
  1326.  *    copy string into next free part of string_table, doing a realloc()
  1327.  *    if necessary.  return offset of beginning of string from start of
  1328.  *    string_table.
  1329.  *
  1330.  */
  1331.  
  1332. int
  1333. save_str(string)
  1334. char    *string;
  1335. {
  1336.     char    *malloc(), *realloc();
  1337.     int    old_next_free = next_free;
  1338.  
  1339.     if (table_size == 0)
  1340.     {
  1341.         if ((string_table = malloc(1024)) == NULL)
  1342.         syserr_abort("Out of memory");
  1343.         table_size = 1024;
  1344.         DEBUG(5, "Made initial string table allocation.  Size is %d\n",
  1345.                                     table_size);
  1346.     }
  1347.  
  1348.     while (table_size < next_free + strlen(string))
  1349.     {
  1350.         if ((string_table = realloc(string_table, table_size + 1024))
  1351.                                     == NULL)
  1352.         syserr_abort("Out of memory");
  1353.         table_size += 1024;
  1354.         DEBUG(5, "Extended string table.  Size now %d\n", table_size);
  1355.     }
  1356.  
  1357.     strcpy(&string_table[next_free], string);
  1358.     DEBUG(7, "Saved string '%s' ", string);
  1359.     DEBUG(7, "at location %d\n", next_free);
  1360.     next_free += strlen(string) + 1;
  1361.  
  1362.     return(old_next_free);
  1363. }
  1364.  
  1365.  
  1366.  
  1367. X/*
  1368.  *    init_structure(Booleans, Numbers, Strings)
  1369.  *
  1370.  *    Initialise the given arrays
  1371.  *    Reset the next_free counter to zero.
  1372.  *
  1373.  */
  1374.  
  1375. init_structure(Booleans, Numbers, Strings)
  1376. char    Booleans[];
  1377. short    Numbers[], Strings[];
  1378. {
  1379.     int    i;
  1380.  
  1381.     for (i=0; i < BOOLCOUNT; i++)
  1382.         Booleans[i] = FALSE;
  1383.     
  1384.     for (i=0; i < NUMCOUNT; i++)
  1385.         Numbers[i] = -1;
  1386.  
  1387.     for (i=0; i < STRCOUNT; i++)
  1388.         Strings[i] = -1;
  1389.  
  1390.     next_free = 0;
  1391. }
  1392.  
  1393.  
  1394.  
  1395. X/*
  1396. **    int
  1397. **    handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
  1398. **
  1399. **    Merge the compiled file whose name is in cur_token.valstring
  1400. **    with the current entry.
  1401. **
  1402. **        if it's a forward use-link
  1403. **                if item_ptr == NULL
  1404. **                queue it up for later handling
  1405. **                else
  1406. **                ignore it (we're already going through the queue)
  1407. **            else it's a backward use-link
  1408. **                read in the object file for that terminal
  1409. **                merge contents with current structure
  1410. **
  1411. **    Returned value is 0 if it was a backward link and we
  1412. **    successfully read it in, -1 if a forward link.
  1413. */
  1414.  
  1415. int
  1416. handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
  1417. long        entry_offset;
  1418. struct use_item    *item_ptr;
  1419. char        Booleans[];
  1420. short        Numbers[];
  1421. short        Strings[];
  1422. {
  1423.     struct term    use_term;
  1424.     struct stat    statbuf;
  1425.     char        filename[50];
  1426.         int             i;
  1427.  
  1428.     check_name(curr_token.tk_valstring);
  1429.  
  1430.     sprintf(filename, "%c/%s", curr_token.tk_valstring[0],
  1431.                                                      curr_token.tk_valstring);
  1432.  
  1433.     if (stat(filename, &statbuf) < 0  ||  part2==0 && statbuf.st_mtime < start_time)
  1434.     {
  1435.         DEBUG(2, "Forward USE to %s", curr_token.tk_valstring);
  1436.  
  1437.          if (item_ptr == NULL)
  1438.          {
  1439.          DEBUG(2, " (enqueued)\n", "");
  1440.          enqueue(entry_offset);
  1441.          }
  1442.          else 
  1443.          DEBUG(2, " (skipped)\n", "");
  1444.         
  1445.         return(-1);
  1446.     }
  1447.     else
  1448.     {
  1449.         DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring);
  1450.         if (read_entry(filename, &use_term) < 0)
  1451.         syserr_abort("Error in re-reading compiled file %s", filename);
  1452.  
  1453.         for (i=0; i < BOOLCOUNT; i++)
  1454.         {
  1455.         if (Booleans[i] == FALSE  &&  use_term.Booleans[i] == TRUE)
  1456.             Booleans[i] = TRUE;
  1457.         }
  1458.  
  1459.         for (i=0; i < NUMCOUNT; i++)
  1460.         {
  1461.         if (Numbers[i] == -1  &&  use_term.Numbers[i] != -1)
  1462.             Numbers[i] = use_term.Numbers[i];
  1463.         }
  1464.  
  1465.         for (i=0; i < STRCOUNT; i++)
  1466.         {
  1467.         if (Strings[i] == -1  &&  use_term.Strings[i] != (char *) 0)
  1468.             Strings[i] = save_str(use_term.Strings[i]);
  1469.         }
  1470.  
  1471.     }
  1472. }
  1473. //go.sysin dd *
  1474. echo 'x - =src/comp_scan.c'
  1475. sed 's/^X//' <<'//go.sysin dd *' >=src/comp_scan.c
  1476. X/*********************************************************************
  1477. *                         COPYRIGHT NOTICE                           *
  1478. **********************************************************************
  1479. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1480. *                                                                    *
  1481. *        Permission is granted to reproduce and distribute           *
  1482. *        this file by any means so long as no fee is charged         *
  1483. *        above a nominal handling fee and so long as this            *
  1484. *        notice is always included in the copies.                    *
  1485. *                                                                    *
  1486. *        Other rights are reserved except as explicitly granted      *
  1487. *        by written permission of the author.                        *
  1488. *                Pavel Curtis                                        *
  1489. *                Computer Science Dept.                              *
  1490. *                405 Upson Hall                                      *
  1491. *                Cornell University                                  *
  1492. *                Ithaca, NY 14853                                    *
  1493. *                                                                    *
  1494. *                Ph- (607) 256-4934                                  *
  1495. *                                                                    *
  1496. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1497. *                decvax!cornell!pavel       (UUCPnet)                *
  1498. *********************************************************************/
  1499.  
  1500. X/*
  1501.  *    comp_scan.c --- Lexical scanner for terminfo compiler.
  1502.  *
  1503.  *   $Log:    RCS/comp_scan.v $
  1504.  * Revision 2.1  82/10/25  14:45:55  pavel
  1505.  * Added Copyright Notice
  1506.  * 
  1507.  * Revision 2.0  82/10/24  15:17:12  pavel
  1508.  * Beta-one Test Release
  1509.  * 
  1510.  * Revision 1.3  82/08/23  22:30:03  pavel
  1511.  * The REAL Alpha-one Release Version
  1512.  * 
  1513.  * Revision 1.2  82/08/19  19:10:06  pavel
  1514.  * Alpha Test Release One
  1515.  * 
  1516.  * Revision 1.1  82/08/12  18:37:46  pavel
  1517.  * Initial revision
  1518.  * 
  1519.  *
  1520.  */
  1521.  
  1522. static char RCSid[] =
  1523.     "$Header:   RCS/comp_scan.v  Revision 2.1  82/10/25  14:45:55  pavel  Exp$";
  1524.  
  1525. #include <stdio.h>
  1526. #include <ctype.h>
  1527. #include "compiler.h"
  1528.  
  1529. #define iswhite(ch)    (ch == ' '  ||  ch == '\t')
  1530.  
  1531.  
  1532. static int    first_column;        /* See 'next_char()' below */
  1533.  
  1534.  
  1535.  
  1536. X/*
  1537.  *    int
  1538.  *    get_token()
  1539.  *
  1540.  *    Scans the input for the next token, storing the specifics in the
  1541.  *    global structure 'curr_token' and returning one of the following:
  1542.  *
  1543.  *        NAMES        A line beginning in column 1.  'name'
  1544.  *                will be set to point to everything up to
  1545.  *                but not including the first comma on the line.
  1546.  *        BOOLEAN        An entry consisting of a name followed by
  1547.  *                a comma.  'name' will be set to point to the
  1548.  *                name of the capability.
  1549.  *        NUMBER        An entry of the form
  1550.  *                    name#digits,
  1551.  *                'name' will be set to point to the capability
  1552.  *                name and 'valnumber' to the number given.
  1553.  *        STRING        An entry of the form
  1554.  *                    name=characters,
  1555.  *                'name' is set to the capability name and
  1556.  *                'valstring' to the string of characters, with
  1557.  *                input translations done.
  1558.  *        CANCEL        An entry of the form
  1559.  *                    name@,
  1560.  *                'name' is set to the capability name and
  1561.  *                'valnumber' to -1.
  1562.  *        EOF        The end of the file has been reached.
  1563.  *
  1564.  */
  1565.  
  1566. int
  1567. get_token()
  1568. {
  1569.     long        number;
  1570.     int        type;
  1571.     register char    ch;
  1572.     static char    buffer[1024];
  1573.     register char    *ptr;
  1574.     int        dot_flag = FALSE;
  1575.  
  1576.     while ((ch = next_char()) == '\n'  ||  iswhite(ch))
  1577.         ;
  1578.     
  1579.     if (ch == EOF)
  1580.         type = EOF;
  1581.     else
  1582.     {
  1583.         if (ch == '.')
  1584.         {
  1585.         dot_flag = TRUE;
  1586.  
  1587.         while ((ch = next_char()) == ' '  ||  ch == '\t')
  1588.             ;
  1589.         }
  1590.  
  1591.         if (! isalnum(ch))
  1592.         {
  1593.          warning("Illegal character - '%c'", ch);
  1594.          panic_mode(',');
  1595.         }
  1596.  
  1597.         ptr = buffer;
  1598.         *(ptr++) = ch;
  1599.  
  1600.         if (first_column)
  1601.         {
  1602.         while ((ch = next_char()) != ',' && ch != '\n' && ch != EOF)
  1603.             *(ptr++) = ch;
  1604.         
  1605.         if (ch == EOF)
  1606.             err_abort("Premature EOF");
  1607.         else if (ch == '\n') {
  1608.             warning("Newline in middle of terminal name");
  1609.             panic_mode(',');
  1610.         }
  1611.         
  1612.         *ptr = '\0';
  1613.         curr_token.tk_name = buffer;
  1614.         type = NAMES;
  1615.         }
  1616.         else
  1617.         {
  1618.         ch = next_char();
  1619.         while (isalnum(ch))
  1620.         {
  1621.             *(ptr++) = ch;
  1622.             ch = next_char();
  1623.         }
  1624.  
  1625.         *ptr++ = '\0';
  1626.         switch (ch)
  1627.         {
  1628.             case ',':
  1629.             curr_token.tk_name = buffer;
  1630.             type = BOOLEAN;
  1631.             break;
  1632.  
  1633.             case '@':
  1634.             if (next_char() != ',')
  1635.                 warning("Missing comma");
  1636.             curr_token.tk_name = buffer;
  1637.             type = CANCEL;
  1638.             break;
  1639.  
  1640.             case '#':
  1641.             number = 0;
  1642.             while (isdigit(ch = next_char()))
  1643.                 number = number * 10 + ch - '0';
  1644.             if (ch != ',')
  1645.                 warning("Missing comma");
  1646.             curr_token.tk_name = buffer;
  1647.             curr_token.tk_valnumber = number;
  1648.             type = NUMBER;
  1649.             break;
  1650.             
  1651.             case '=':
  1652.             ch = trans_string(ptr);
  1653.             if (ch != ',')
  1654.                 warning("Missing comma");
  1655.             curr_token.tk_name = buffer;
  1656.             curr_token.tk_valstring = ptr;
  1657.             type = STRING;
  1658.             break;
  1659.  
  1660.             default:
  1661.             warning("Illegal character - '%c'", ch);
  1662.         }
  1663.         } /* end else (first_column == FALSE) */
  1664.     } /* end else (ch != EOF) */
  1665.  
  1666.     if (dot_flag == TRUE)
  1667.         DEBUG(8, "Commented out ", "");
  1668.  
  1669.     if (debug_level >= 8)
  1670.     {
  1671.         fprintf(stderr, "Token: ");
  1672.         switch (type)
  1673.         {
  1674.         case BOOLEAN:
  1675.             fprintf(stderr, "Boolean;  name='%s'\n",
  1676.                                                           curr_token.tk_name);
  1677.             break;
  1678.         
  1679.         case NUMBER:
  1680.             fprintf(stderr, "Number; name='%s', value=%d\n",
  1681.                 curr_token.tk_name, curr_token.tk_valnumber);
  1682.             break;
  1683.         
  1684.         case STRING:
  1685.             fprintf(stderr, "String; name='%s', value='%s'\n",
  1686.                 curr_token.tk_name, curr_token.tk_valstring);
  1687.             break;
  1688.         
  1689.         case CANCEL:
  1690.             fprintf(stderr, "Cancel; name='%s'\n",
  1691.                                                           curr_token.tk_name);
  1692.             break;
  1693.         
  1694.         case NAMES:
  1695.  
  1696.             fprintf(stderr, "Names; value='%s'\n",
  1697.                                                           curr_token.tk_name);
  1698.             break;
  1699.  
  1700.         case EOF:
  1701.             fprintf(stderr, "End of file\n");
  1702.             break;
  1703.  
  1704.         default:
  1705.             warning("Bad token type");
  1706.         }
  1707.     }
  1708.  
  1709.     if (dot_flag == TRUE)        /* if commented out, use the next one */
  1710.         type = get_token();
  1711.  
  1712.     return(type);
  1713. }
  1714.  
  1715.  
  1716.  
  1717. X/*
  1718.  *    char
  1719.  *    next_char()
  1720.  *
  1721.  *    Returns the next character in the input stream.  Comments and leading
  1722.  *    white space are stripped.  The global state variable 'firstcolumn' is
  1723.  *    set TRUE if the character returned is from the first column of the input
  1724.  *     line.  The global variable curr_line is incremented for each new line.
  1725.  *    The global variable curr_file_pos is set to the file offset of the
  1726.  *    beginning of each line.
  1727.  *
  1728.  */
  1729.  
  1730. int    curr_column = -1;
  1731. char    line[1024];
  1732.  
  1733. char
  1734. next_char()
  1735. {
  1736.     char    *rtn_value;
  1737.     long    ftell();
  1738.  
  1739.     if (curr_column < 0  ||  curr_column > 1023  ||
  1740.                             line[curr_column] == '\0')
  1741.     {
  1742.         do
  1743.         {
  1744.         curr_file_pos = ftell(stdin);
  1745.  
  1746.         if ((rtn_value = fgets(line, 1024, stdin)) != NULL)
  1747.             curr_line++;
  1748.         } while (rtn_value != NULL  &&  line[0] == '#');
  1749.  
  1750.         if (rtn_value == NULL)
  1751.         return (EOF);
  1752.  
  1753.         curr_column = 0;
  1754.         while (iswhite(line[curr_column]))
  1755.         curr_column++;
  1756.     }
  1757.  
  1758.     if (curr_column == 0  &&  line[0] != '\n')
  1759.         first_column = TRUE;
  1760.     else
  1761.         first_column = FALSE;
  1762.     
  1763.     return (line[curr_column++]);
  1764. }
  1765.  
  1766.  
  1767. backspace()
  1768. {
  1769.     curr_column--;
  1770.  
  1771.     if (curr_column < 0)
  1772.         syserr_abort("Backspaced off beginning of line");
  1773. }
  1774.  
  1775.  
  1776.  
  1777. X/*
  1778.  *    reset_input()
  1779.  *
  1780.  *    Resets the input-reading routines.  Used after a seek has been done.
  1781.  *
  1782.  */
  1783.  
  1784. reset_input()
  1785. {
  1786.     curr_column = -1;
  1787. }
  1788.  
  1789.  
  1790.  
  1791. X/*
  1792.  *    char
  1793.  *    trans_string(ptr)
  1794.  *
  1795.  *    Reads characters using next_char() until encountering a comma, newline
  1796.  *    or end-of-file.  The returned value is the character which caused
  1797.  *    reading to stop.  The following translations are done on the input:
  1798.  *
  1799.  *        ^X  goes to  ctrl-X (i.e. X & 037)
  1800.  *        {\E,\n,\r,\b,\t,\f}  go to
  1801.  *            {ESCAPE,newline,carriage-return,backspace,tab,formfeed}
  1802.  *        {\^,\\}  go to  {carat,backslash}
  1803.  *        \ddd (for ddd = up to three octal digits)  goes to
  1804.  *                            the character ddd
  1805.  *
  1806.  *        \e == \E
  1807.  *        \0 == \200
  1808.  *
  1809.  */
  1810.  
  1811. char
  1812. trans_string(ptr)
  1813. char    *ptr;
  1814. {
  1815.     register int    count = 0;
  1816.     int        number;
  1817.     int        i;
  1818.         char        ch;
  1819.  
  1820.     while ((ch = next_char()) != ','  &&  ch != EOF)
  1821.     {
  1822.         if (ch == '^')
  1823.         {
  1824.         ch = next_char();
  1825.         if (ch == EOF)
  1826.             err_abort("Premature EOF");
  1827.  
  1828.         if (! isprint(ch))
  1829.         {
  1830.             warning("Illegal ^ character - '%c'", ch);
  1831.         }
  1832.  
  1833.         *(ptr++) = ch & 037;
  1834.         }
  1835.         else if (ch == '\\')
  1836.         {
  1837.         ch = next_char();
  1838.         if (ch == EOF)
  1839.             err_abort("Premature EOF");
  1840.         
  1841.         if (ch >= '0'  &&  ch <= '7')
  1842.         {
  1843.             number = ch - '0';
  1844.             for (i=0; i < 2; i++)
  1845.             {
  1846.             ch = next_char();
  1847.             if (ch == EOF)
  1848.                 err_abort("Premature EOF");
  1849.             
  1850.             if (ch < '0'  ||  ch > '7')
  1851.             {
  1852.                 backspace();
  1853.                 break;
  1854.             }
  1855.  
  1856.             number = number * 8 + ch - '0';
  1857.             }
  1858.  
  1859.             if (number == 0)
  1860.             number = 0200;
  1861.             *(ptr++) = (char) number;
  1862.         }
  1863.         else
  1864.         {
  1865.             switch (ch)
  1866.             {
  1867.             case 'E':
  1868.             case 'e':    *(ptr++) = '\033';    break;
  1869.             
  1870.             case 'l':
  1871.             case 'n':    *(ptr++) = '\n';    break;
  1872.             
  1873.             case 'r':    *(ptr++) = '\r';    break;
  1874.             
  1875.             case 'b':    *(ptr++) = '\008';    break;
  1876.  
  1877.             case 's':    *(ptr++) = ' ';        break;
  1878.             
  1879.             case 'f':    *(ptr++) = '\014';    break;
  1880.             
  1881.             case 't':    *(ptr++) = '\t';    break;
  1882.             
  1883.             case '\\':    *(ptr++) = '\\';    break;
  1884.             
  1885.             case '^':    *(ptr++) = '^';        break;
  1886.  
  1887.             case ',':    *(ptr++) = ',';        break;
  1888.  
  1889.             case ':':    *(ptr++) = ':';        break;
  1890.  
  1891.             default:
  1892.                 warning("Illegal character in \\ sequence");
  1893.                 *(ptr++) = ch;
  1894.             } /* endswitch (ch) */
  1895.         } /* endelse (ch < '0' ||  ch > '7') */
  1896.         } /* end else if (ch == '\\') */
  1897.         else
  1898.         {
  1899.         *(ptr++) = ch;
  1900.         }
  1901.         
  1902.         count ++;
  1903.  
  1904.         if (count > 500)
  1905.         warning("Very long string found.  Missing comma?");
  1906.     } /* end while */
  1907.  
  1908.     *ptr = '\0';
  1909.  
  1910.     return(ch);
  1911. }
  1912.  
  1913. X/*
  1914.  * Panic mode error recovery - skip everything until a "ch" is found.
  1915.  */
  1916. panic_mode(ch)
  1917. char ch;
  1918. {
  1919.     int c;
  1920.  
  1921.     for (;;) {
  1922.         c = next_char();
  1923.         if (c == ch)
  1924.             return;
  1925.         if (c == EOF);
  1926.             return;
  1927.     }
  1928. }
  1929. //go.sysin dd *
  1930. echo 'x - =src/compiler.h'
  1931. sed 's/^X//' <<'//go.sysin dd *' >=src/compiler.h
  1932. X/*********************************************************************
  1933. *                         COPYRIGHT NOTICE                           *
  1934. **********************************************************************
  1935. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1936. *                                                                    *
  1937. *        Permission is granted to reproduce and distribute           *
  1938. *        this file by any means so long as no fee is charged         *
  1939. *        above a nominal handling fee and so long as this            *
  1940. *        notice is always included in the copies.                    *
  1941. *                                                                    *
  1942. *        Other rights are reserved except as explicitly granted      *
  1943. *        by written permission of the author.                        *
  1944. *                Pavel Curtis                                        *
  1945. *                Computer Science Dept.                              *
  1946. *                405 Upson Hall                                      *
  1947. *                Cornell University                                  *
  1948. *                Ithaca, NY 14853                                    *
  1949. *                                                                    *
  1950. *                Ph- (607) 256-4934                                  *
  1951. *                                                                    *
  1952. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1953. *                decvax!cornell!pavel       (UUCPnet)                *
  1954. *********************************************************************/
  1955.  
  1956. X/*
  1957.  *    compiler.h - Global variables and structures for the terminfo
  1958.  *            compiler.
  1959.  *
  1960.  *  $Header:   RCS/compiler.v  Revision 2.1  82/10/25  14:46:04  pavel  Exp$
  1961.  *
  1962.  *  $Log:    RCS/compiler.v $
  1963. Revision 2.1  82/10/25  14:46:04  pavel
  1964. Added Copyright Notice
  1965.  
  1966. Revision 2.0  82/10/24  15:17:20  pavel
  1967. Beta-one Test Release
  1968.  
  1969. Revision 1.3  82/08/23  22:30:09  pavel
  1970. The REAL Alpha-one Release Version
  1971.  
  1972. Revision 1.2  82/08/19  19:10:10  pavel
  1973. Alpha Test Release One
  1974.  
  1975. Revision 1.1  82/08/12  18:38:11  pavel
  1976. Initial revision
  1977.  
  1978.  *
  1979.  */
  1980.  
  1981. #include <stdio.h>
  1982.  
  1983. #ifndef TRUE
  1984. #define TRUE    1
  1985. #define FALSE    0
  1986. #endif
  1987.  
  1988. #define SINGLE            /* only one terminal (actually none) */
  1989.  
  1990. char    *destination;        /* destination directory for object files */
  1991.  
  1992. long    start_time;        /* time at start of compilation */
  1993. long    time();
  1994.  
  1995. int    curr_line;        /* current line # in input */
  1996. long    curr_file_pos;        /* file offset of current line */
  1997.  
  1998. int    debug_level;        /* level of debugging output */
  1999.  
  2000. #define DEBUG(level, fmt, a1) \
  2001.         if (debug_level >= level)\
  2002.             fprintf(stderr, fmt, a1);
  2003.  
  2004.     /*
  2005.      *    These are the types of tokens returned by the scanner.
  2006.      *    The first three are also used in the hash table of capability
  2007.      *    names.  The scanner returns one of these values after loading
  2008.      *    the specifics into the global structure curr_token.
  2009.      *
  2010.      */
  2011.  
  2012. #define BOOLEAN 0        /* Boolean capability */
  2013. #define NUMBER 1        /* Numeric capability */
  2014. #define STRING 2        /* String-valued capability */
  2015. #define CANCEL 3        /* Capability to be cancelled in following tc's */
  2016. #define NAMES  4        /* The names for a terminal type */
  2017.  
  2018.     /*
  2019.      *    The global structure in which the specific parts of a
  2020.      *    scanned token are returned.
  2021.      *
  2022.      */
  2023.  
  2024. struct token
  2025. {
  2026.     char    *tk_name;        /* name of capability */
  2027.     int    tk_valnumber;    /* value of capability (if a number) */
  2028.     char    *tk_valstring;    /* value of capability (if a string) */
  2029. };
  2030.  
  2031. struct token    curr_token;
  2032.  
  2033.     /*
  2034.      *    The file comp_captab.c contains an array of these structures,
  2035.      *    one per possible capability.  These are then made into a hash
  2036.      *    table array of the same structures for use by the parser.
  2037.      *
  2038.      */
  2039.  
  2040. struct name_table_entry
  2041. {
  2042.     struct name_table_entry *nte_link;
  2043.     char    *nte_name;    /* name to hash on */
  2044.     int    nte_type;    /* BOOLEAN, NUMBER or STRING */
  2045.     short    nte_index;    /* index of associated variable in its array */
  2046. };
  2047.  
  2048. extern struct name_table_entry    cap_table[];
  2049. extern struct name_table_entry    *cap_hash_table[];
  2050.  
  2051. extern int    Captabsize;
  2052. extern int    Hashtabsize;
  2053.  
  2054. #define NOTFOUND    ((struct name_table_entry *) 0)
  2055.     /*
  2056.      *    Function types
  2057.      *
  2058.      */
  2059.  
  2060. struct name_table_entry    *find_entry();    /* look up entry in hash table */
  2061.  
  2062. char    next_char();
  2063. char    trans_string();
  2064. //go.sysin dd *
  2065. exit
  2066.