home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / option.c < prev    next >
C/C++ Source or Header  |  2001-02-23  |  40KB  |  1,410 lines

  1. /* -*-C-*-
  2.  
  3. $Id: option.c,v 1.56 2001/02/24 04:08:28 cph Exp $
  4.  
  5. Copyright (c) 1990-2001 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. /* Command-line option processing */
  23.  
  24. #include <ctype.h>
  25. #include "scheme.h"
  26. #include "fasl.h"
  27. #include "osenv.h"
  28. #include "osfs.h"
  29. #include <sys/stat.h>
  30.  
  31. extern char * getenv ();
  32. extern void free ();
  33. #define xfree(p) free ((PTR) (p))
  34. extern int atoi ();
  35.  
  36. #ifdef HAVE_UNISTD_H
  37. #  include <unistd.h>
  38. #endif
  39.  
  40. #ifdef STDC_HEADERS
  41. #  include <stdlib.h>
  42. #  include <string.h>
  43. #endif
  44.  
  45. #ifdef HAVE_MALLOC_H
  46. #  include <malloc.h>
  47. #endif
  48.  
  49. #ifdef __WIN32__
  50. #  include <io.h>
  51. #  include "nt.h"
  52. #  include "ntio.h"
  53. #endif
  54.  
  55. #ifndef NULL
  56. # define NULL 0
  57. #endif
  58.  
  59. #if defined(__WIN32__) || defined(__OS2__)
  60. #  define DOS_LIKE_FILENAMES
  61. #endif
  62.  
  63. extern struct obstack scratch_obstack;
  64. extern CONST char * scheme_program_name;
  65. extern void EXFUN (termination_init_error, (void));
  66.  
  67. #ifndef SUB_DIRECTORY_DELIMITER
  68. #  ifdef DOS_LIKE_FILENAMES
  69. #    define SUB_DIRECTORY_DELIMITER '\\'
  70. #  else
  71. #    define SUB_DIRECTORY_DELIMITER '/'
  72. #  endif
  73. #endif
  74.  
  75. #ifndef PATH_DELIMITER
  76. #  ifdef DOS_LIKE_FILENAMES
  77. #    define PATH_DELIMITER ';'
  78. #  else
  79. #    define PATH_DELIMITER ':'
  80. #  endif
  81. #endif
  82.  
  83. #ifdef DOS_LIKE_FILENAMES
  84. #  define FILE_ABSOLUTE(filename)            \
  85.      ((((filename) [0]) == SUB_DIRECTORY_DELIMITER)    \
  86.       || (((filename) [1]) == ':'))
  87. #else
  88. #  define FILE_ABSOLUTE(filename) (((filename) [0]) == SUB_DIRECTORY_DELIMITER)
  89. #endif
  90.  
  91. #define FILE_READABLE(filename) (OS_file_access ((filename), 4))
  92.  
  93. static int option_summary;
  94. static int option_large_sizes;
  95.  
  96. #ifdef HAS_COMPILER_SUPPORT
  97. static int option_compiler_defaults;
  98. static int option_edwin_defaults;
  99. #endif
  100.  
  101. static CONST char * option_raw_library = 0;
  102. static CONST char * option_raw_utabmd = 0;
  103. static CONST char * option_raw_utab = 0;
  104. static CONST char * option_raw_band = 0;
  105. static CONST char * option_raw_heap = 0;
  106. static CONST char * option_raw_constant = 0;
  107. static CONST char * option_raw_stack = 0;
  108.  
  109. /* Command-line arguments */
  110. int option_saved_argc;
  111. CONST char ** option_saved_argv;
  112. int option_unused_argc;
  113. CONST char ** option_unused_argv;
  114.  
  115. /* Boolean options */
  116. int option_emacs_subprocess;
  117. int option_force_interactive;
  118. int option_disable_core_dump;
  119. int option_band_specified;
  120. int option_empty_list_eq_false;
  121.  
  122. /* String options */
  123. CONST char ** option_library_path = 0;
  124. CONST char * option_band_file = 0;
  125. CONST char * option_fasl_file = 0;
  126. CONST char * option_utabmd_file = 0;
  127.  
  128. /* Numeric options */
  129. unsigned int option_heap_size;
  130. unsigned int option_constant_size;
  131. unsigned int option_stack_size;
  132.  
  133. /* These only matter for bchscheme */
  134. static CONST char * option_raw_gc_end_position = 0;
  135. static CONST char * option_raw_gc_file = 0;
  136. static CONST char * option_raw_gc_read_overlap = 0;
  137. static CONST char * option_raw_gc_start_position = 0;
  138. static CONST char * option_raw_gc_window_size = 0;
  139. static CONST char * option_raw_gc_write_overlap = 0;
  140. CONST char * option_gc_directory = 0;
  141. CONST char * option_gc_drone = 0;
  142. CONST char * option_gc_file = 0;
  143. int option_gc_keep;
  144. int option_gc_read_overlap;
  145. int option_gc_window_size;
  146. int option_gc_write_overlap;
  147. long option_gc_start_position;
  148. long option_gc_end_position;
  149. /*
  150. Scheme accepts the following command-line options.  The options may
  151. appear in any order, but they must all appear before any other
  152. arguments on the command line.
  153.  
  154. -library PATH
  155.   Sets the library search path to PATH.  This is a colon-separated
  156.   list of directories that is searched to find various library files,
  157.   such as bands.  If this option is not given, the value of the
  158.   environment variable MITSCHEME_LIBRARY_PATH is used; it that isn't
  159.   defined, "/usr/local/lib/mit-scheme" is used.
  160.  
  161. -band FILENAME
  162.   Specifies the initial band to be loaded.  Searches for FILENAME in
  163.   the working directory and the library directories, returning the
  164.   full pathname of the first readable file of that name.  If this
  165.   option isn't given, the filename is the value of the environment
  166.   variable MITSCHEME_BAND, or if that isn't defined, "runtime.com"; in
  167.   these cases the library directories are searched, but not the
  168.   working directory.
  169.  
  170. -fasl FILENAME
  171.   Specifies that a cold load should be performed, using FILENAME as
  172.   the initial file to be loaded.  If this option isn't given, a normal
  173.   load is performed instead.  This option may not be used together
  174.   with the "-band" option.
  175.  
  176. -utabmd FILENAME
  177.   Specifies the name of the microcode tables file.  The file is
  178.   searched for in the working directory and the library directories.
  179.   If this option isn't given, the filename is the value of the
  180.   environment variable MITSCHEME_UTABMD_FILE, or if that isn't
  181.   defined, "utabmd.bin"; in these cases the library directories are
  182.   searched, but not the working directory.
  183.  
  184. -utab FILENAME
  185.   An alternate name for the "-utabmd" option.  At most one of these
  186.   options may be given.
  187.  
  188. -large
  189.   Specifies that large heap, constant, and stack default sizes should
  190.   be used.  These are specified by the environment variables
  191.   MITSCHEME_LARGE_HEAP, MITSCHEME_LARGE_CONSTANT, and
  192.   MITSCHEME_LARGE_STACK.  If this option isn't given, the small sizes
  193.   are used, specified by the environment variables
  194.   MITSCHEME_SMALL_HEAP, MITSCHEME_SMALL_CONSTANT, and
  195.   MITSCHEME_SMALL_STACK.  There are reasonable built-in defaults for
  196.   these environment variables, should any of them be undefined.  [The
  197.   Scheme procedure `(print-gc-statistics)' shows how much heap and
  198.   constant space is available and in use.]
  199.  
  200. -heap BLOCKS
  201.   Specifies the size of the heap in 1024-word blocks.  Overrides any
  202.   default.  Normally two such heaps are allocated; `bchscheme'
  203.   allocates only one.
  204.  
  205. -constant BLOCKS
  206.   Specifies the size of constant space in 1024-word blocks.  Overrides
  207.   any default.
  208.  
  209. -stack BLOCKS
  210.   Specifies the size of the stack in 1024-word blocks.  Overrides any
  211.   default.
  212.  
  213. -option-summary
  214.   Causes Scheme to write option information to standard error.
  215.  
  216. -emacs
  217.   Specifies that Scheme is running as a subprocess of GNU Emacs.
  218.   This option is automatically supplied by GNU Emacs, and should not
  219.   be given under other circumstances.
  220.  
  221. -interactive
  222.   If this option isn't specified, and Scheme's standard I/O is not a
  223.   terminal, Scheme will detach itself from its controlling terminal.
  224.   This will prevent it from getting signals sent to the process group
  225.   of that terminal.  If this option is specified, Scheme will not
  226.   detach itself from the controlling terminal.
  227.  
  228. -nocore
  229.   Specifies that Scheme should not generate a core dump under any
  230.   circumstances.
  231.  
  232. The following options are available only on machines with
  233. compiled-code support:
  234.  
  235. -compiler
  236.   This option specifies defaults appropriate for loading the compiler.
  237.   It changes the defaults for "-band": the environment variable
  238.   MITSCHEME_COMPILER_BAND is used, otherwise "compiler.com" is used.
  239.   It also specifies the use of large sizes, exactly like "-large".
  240.  
  241. -edwin
  242.   This option specifies defaults appropriate for loading the editor.
  243.   It changes the defaults for "-band": the environment variable
  244.   MITSCHEME_EDWIN_BAND is used, otherwise "edwin.com" is used.  It
  245.   also specifies the use of large sizes, exactly like "-large".
  246.  
  247. The following options are only meaningful to bchscheme:
  248.  
  249. -gc-directory DIRECTORY
  250.   Specifies what directory to use to allocate the garbage collection file.
  251.  
  252. -gc-drone FILENAME
  253.   Specifies the program to use as the gc drones for overlapped I/O.
  254.  
  255. -gc-end-position N
  256.   Specifies a position into the gc file past which bchscheme should not use.
  257.  
  258. -gc-file FILENAME
  259.   Specifies that FILENAME should be used garbage collection.  Overrides
  260.   -gc-directory if it is an absolute pathname.  -gcfile means the same thing,
  261.   but is deprecated.
  262.  
  263. -gc-keep
  264.   Specifles that newly allocated gc files should be kept rather than deleted.
  265.  
  266. -gc-read-overlap N
  267.   Specifies the number of additional GC windows to use when reading
  268.   for overlapped I/O.  Each implies a drone process to manage it,
  269.   if supported.
  270.  
  271. -gc-start-position N
  272.   Specifies a position into the gc file before which bchscheme should not use.
  273.  
  274. -gc-window-size BLOCKS
  275.   Specifies the size in 1024-word blocks of each GC window.
  276.  
  277. -gc-write-overlap N
  278.   Specifies the number of additional GC windows to use when writing for
  279.   overlapped I/O.  Each implies a drone process to manage it, if supported.
  280. */
  281.  
  282. #ifndef LIBRARY_PATH_VARIABLE
  283. #define LIBRARY_PATH_VARIABLE "MITSCHEME_LIBRARY_PATH"
  284. #endif
  285.  
  286. #ifndef DEFAULT_LIBRARY_PATH
  287. #ifdef DOS_LIKE_FILENAMES
  288. #define DEFAULT_LIBRARY_PATH "\\scheme\\lib"
  289. #else
  290. #define DEFAULT_LIBRARY_PATH "/usr/local/lib/mit-scheme"
  291. #endif
  292. #endif
  293.  
  294. #ifndef BAND_VARIABLE
  295. #define BAND_VARIABLE "MITSCHEME_BAND"
  296. #endif
  297.  
  298. #ifndef DEFAULT_BAND
  299. #define DEFAULT_BAND "runtime.com"
  300. #endif
  301.  
  302. #ifndef COMPILER_BAND_VARIABLE
  303. #define COMPILER_BAND_VARIABLE "MITSCHEME_COMPILER_BAND"
  304. #endif
  305.  
  306. #ifndef COMPILER_DEFAULT_BAND
  307. #define COMPILER_DEFAULT_BAND "compiler.com"
  308. #endif
  309.  
  310. #ifndef EDWIN_BAND_VARIABLE
  311. #define EDWIN_BAND_VARIABLE "MITSCHEME_EDWIN_BAND"
  312. #endif
  313.  
  314. #ifndef EDWIN_DEFAULT_BAND
  315. #define EDWIN_DEFAULT_BAND "edwin.com"
  316. #endif
  317.  
  318. #ifndef ALL_BAND_VARIABLE
  319. #define ALL_BAND_VARIABLE "MITSCHEME_ALL_BAND"
  320. #endif
  321.  
  322. #ifndef ALL_DEFAULT_BAND
  323. #define ALL_DEFAULT_BAND "all.com"
  324. #endif
  325.  
  326. #ifndef UTABMD_FILE_VARIABLE
  327. #define UTABMD_FILE_VARIABLE "MITSCHEME_UTABMD_FILE"
  328. #endif
  329.  
  330. #ifndef DEFAULT_UTABMD_FILE
  331. #define DEFAULT_UTABMD_FILE "utabmd.bin"
  332. #endif
  333.  
  334. #ifdef HAS_COMPILER_SUPPORT
  335.  
  336. #if defined(hp9000s800) || defined(__hp9000s800)
  337. /* HPPA compiled binaries are large! */
  338.  
  339. #ifndef DEFAULT_SMALL_CONSTANT
  340. #define DEFAULT_SMALL_CONSTANT 600
  341. #endif
  342.  
  343. #ifndef DEFAULT_LARGE_CONSTANT
  344. #define DEFAULT_LARGE_CONSTANT 1400
  345. #endif
  346.  
  347. #endif /* hp9000s800 */
  348.  
  349. #ifdef mips
  350. /* MIPS compiled binaries are large! */
  351.  
  352. #ifndef DEFAULT_SMALL_CONSTANT
  353. #define DEFAULT_SMALL_CONSTANT 700
  354. #endif
  355.  
  356. #ifndef DEFAULT_LARGE_CONSTANT
  357. #define DEFAULT_LARGE_CONSTANT 1500
  358. #endif
  359.  
  360. #endif /* mips */
  361.  
  362. #ifdef __IA32__
  363. /* 386 code is large too! */
  364.  
  365. #ifndef DEFAULT_SMALL_CONSTANT
  366. #define DEFAULT_SMALL_CONSTANT 600
  367. #endif
  368.  
  369. #ifndef DEFAULT_LARGE_CONSTANT
  370. #define DEFAULT_LARGE_CONSTANT 1200
  371. #endif
  372.  
  373. #endif /* __IA32__ */
  374.  
  375. #endif /* HAS_COMPILER_SUPPORT */
  376.  
  377. #ifndef DEFAULT_SMALL_HEAP
  378. #define DEFAULT_SMALL_HEAP 250
  379. #endif
  380.  
  381. #ifndef SMALL_HEAP_VARIABLE
  382. #define SMALL_HEAP_VARIABLE "MITSCHEME_SMALL_HEAP"
  383. #endif
  384.  
  385. #ifndef DEFAULT_SMALL_CONSTANT
  386. #define DEFAULT_SMALL_CONSTANT 450
  387. #endif
  388.  
  389. #ifndef SMALL_CONSTANT_VARIABLE
  390. #define SMALL_CONSTANT_VARIABLE "MITSCHEME_SMALL_CONSTANT"
  391. #endif
  392.  
  393. #ifndef DEFAULT_SMALL_STACK
  394. #define    DEFAULT_SMALL_STACK 100
  395. #endif
  396.  
  397. #ifndef SMALL_STACK_VARIABLE
  398. #define SMALL_STACK_VARIABLE "MITSCHEME_SMALL_STACK"
  399. #endif
  400.  
  401. #ifndef DEFAULT_LARGE_HEAP
  402. #define DEFAULT_LARGE_HEAP 1000
  403. #endif
  404.  
  405. #ifndef LARGE_HEAP_VARIABLE
  406. #define LARGE_HEAP_VARIABLE "MITSCHEME_LARGE_HEAP"
  407. #endif
  408.  
  409. #ifndef DEFAULT_LARGE_CONSTANT
  410. #define DEFAULT_LARGE_CONSTANT 1000
  411. #endif
  412.  
  413. #ifndef LARGE_CONSTANT_VARIABLE
  414. #define LARGE_CONSTANT_VARIABLE "MITSCHEME_LARGE_CONSTANT"
  415. #endif
  416.  
  417. #ifndef DEFAULT_LARGE_STACK
  418. #define DEFAULT_LARGE_STACK DEFAULT_SMALL_STACK
  419. #endif
  420.  
  421. #ifndef LARGE_STACK_VARIABLE
  422. #define LARGE_STACK_VARIABLE "MITSCHEME_LARGE_STACK"
  423. #endif
  424.  
  425. /* These are only meaningful for bchscheme */
  426.  
  427. #ifndef DEFAULT_GC_DIRECTORY
  428. #ifdef DOS_LIKE_FILENAMES
  429. #define DEFAULT_GC_DIRECTORY        "\\tmp"
  430. #else
  431. #define DEFAULT_GC_DIRECTORY        "/tmp"
  432. #endif
  433. #endif
  434.  
  435. #ifndef GC_DIRECTORY_VARIABLE
  436. #define GC_DIRECTORY_VARIABLE        "MITSCHEME_GC_DIRECTORY"
  437. #endif
  438.  
  439. #ifndef DEFAULT_GC_DRONE
  440. #define DEFAULT_GC_DRONE        "gcdrone"
  441. #endif
  442.  
  443. #ifndef GC_DRONE_VARIABLE
  444. #define GC_DRONE_VARIABLE        "MITSCHEME_GC_DRONE"
  445. #endif
  446.  
  447. #ifndef DEFAULT_GC_END_POSITION
  448. #define DEFAULT_GC_END_POSITION        -1
  449. #endif
  450.  
  451. #ifndef GC_END_POSITION_VARIABLE
  452. #define GC_END_POSITION_VARIABLE    "MITSCHEME_GC_END_POSITION"
  453. #endif
  454.  
  455. #ifndef DEFAULT_GC_FILE
  456. #define DEFAULT_GC_FILE            "GCXXXXXX"
  457. #endif
  458.  
  459. #ifndef GC_FILE_VARIABLE
  460. #define GC_FILE_VARIABLE        "MITSCHEME_GC_FILE"
  461. #endif
  462.  
  463. #ifndef DEFAULT_GC_READ_OVERLAP
  464. #define DEFAULT_GC_READ_OVERLAP        0
  465. #endif
  466.  
  467. #ifndef GC_READ_OVERLAP_VARIABLE
  468. #define GC_READ_OVERLAP_VARIABLE    "MITSCHEME_GC_READ_OVERLAP"
  469. #endif
  470.  
  471. #ifndef DEFAULT_GC_START_POSITION
  472. #define DEFAULT_GC_START_POSITION    0
  473. #endif
  474.  
  475. #ifndef GC_START_POSITION_VARIABLE
  476. #define GC_START_POSITION_VARIABLE    "MITSCHEME_GC_START_POSITION"
  477. #endif
  478.  
  479. #ifndef DEFAULT_GC_WINDOW_SIZE
  480. #define DEFAULT_GC_WINDOW_SIZE        16
  481. #endif
  482.  
  483. #ifndef GC_WINDOW_SIZE_VARIABLE
  484. #define GC_WINDOW_SIZE_VARIABLE        "MITSCHEME_GC_WINDOW_SIZE"
  485. #endif
  486.  
  487. #ifndef DEFAULT_GC_WRITE_OVERLAP
  488. #define DEFAULT_GC_WRITE_OVERLAP    0
  489. #endif
  490.  
  491. #ifndef GC_WRITE_OVERLAP_VARIABLE
  492. #define GC_WRITE_OVERLAP_VARIABLE    "MITSCHEME_GC_WRITE_OVERLAP"
  493. #endif
  494.  
  495. static int
  496. DEFUN (string_compare_ci, (string1, string2),
  497.        CONST char * string1 AND
  498.        CONST char * string2)
  499. {
  500.   CONST char * scan1 = string1;
  501.   unsigned int length1 = (strlen (string1));
  502.   CONST char * scan2 = string2;
  503.   unsigned int length2 = (strlen (string2));
  504.   unsigned int length = ((length1 < length2) ? length1 : length2);
  505.   CONST char * end1 = (scan1 + length);
  506.   CONST char * end2 = (scan2 + length);
  507.   while ((scan1 < end1) && (scan2 < end2))
  508.     {
  509.       int c1 = (*scan1++);
  510.       int c2 = (*scan2++);
  511.       if (islower (c1))
  512.     {
  513.       if (! (islower (c2)))
  514.         c1 = (toupper (c1));
  515.     }
  516.       else
  517.     {
  518.       if (islower (c2))
  519.         c2 = (toupper (c2));
  520.     }
  521.       if (c1 != c2)
  522.     return ((c1 < c2) ? (-1) : 1);
  523.     }
  524.   return
  525.     ((length1 == length2)
  526.      ? 0
  527.      : ((length1 < length2) ? (-1) : 1));
  528. }
  529.  
  530. #if 0
  531. static char *
  532. DEFUN (strchr, (s, c), CONST char * s AND int c)
  533. {
  534.   while (1)
  535.     {
  536.       int c1 = (*s++);
  537.       if (c1 == c) return ((char *) (s - 1));
  538.       if (c1 == '\0') return (0);
  539.     }
  540. }
  541. #endif
  542.  
  543. static PTR
  544. DEFUN (xmalloc, (n), unsigned long n)
  545. {
  546.   PTR result = (malloc (n));
  547.   if (result == 0)
  548.     {
  549.       outf_fatal ("%s: unable to allocate space while parsing options.\n",
  550.            scheme_program_name);
  551.       termination_init_error ();
  552.     }
  553.   return (result);
  554. }
  555.  
  556. static char *
  557. DEFUN (string_copy, (s), CONST char * s)
  558. {
  559.   char * result = (xmalloc ((strlen (s)) + 1));
  560.   {
  561.     CONST char * s1 = s;
  562.     char * s2 = result;
  563.     while (((*s2++) = (*s1++)) != '\0') ;
  564.   }
  565.   return (result);
  566. }
  567.  
  568. struct option_descriptor
  569. {
  570.   CONST char * option;
  571.   int argument_p;
  572.   PTR value_cell;
  573. };
  574.  
  575. static void
  576. DEFUN (option_argument, (option, argument_p, value_cell),
  577.        CONST char * option AND
  578.        int argument_p AND
  579.        CONST PTR value_cell)
  580. {
  581.   struct option_descriptor descriptor;
  582.   (descriptor . option) = option;
  583.   (descriptor . argument_p) = argument_p;
  584.   (descriptor . value_cell) = ((PTR) value_cell);
  585.   obstack_grow ((&scratch_obstack), (&descriptor), (sizeof (descriptor)));
  586. }
  587.  
  588. static void
  589. DEFUN (parse_options, (argc, argv), int argc AND CONST char ** argv)
  590. {
  591.   CONST char ** scan_argv = (argv + 1);
  592.   CONST char ** end_argv = (scan_argv + (argc - 1));
  593.   unsigned int n_descriptors =
  594.     ((obstack_object_size (&scratch_obstack))
  595.      / (sizeof (struct option_descriptor)));
  596.   struct option_descriptor * descriptors = (obstack_finish (&scratch_obstack));
  597.   struct option_descriptor * end_desc = (descriptors + n_descriptors);
  598.   struct option_descriptor * scan_desc;
  599.   for (scan_desc = descriptors; (scan_desc < end_desc); scan_desc += 1)
  600.     if (scan_desc -> argument_p)
  601.       {
  602.     CONST char ** value_cell = (scan_desc -> value_cell);
  603.     (*value_cell) = 0;
  604.       }
  605.     else
  606.       {
  607.     int * value_cell = (scan_desc -> value_cell);
  608.     (*value_cell) = 0;
  609.       }
  610.   while (scan_argv < end_argv)
  611.     {
  612.       CONST char * option = (*scan_argv++);
  613.       for (scan_desc = descriptors; (scan_desc < end_desc); scan_desc += 1)
  614.     if ((string_compare_ci (option, (scan_desc -> option))) == 0)
  615.       {
  616.         if (scan_desc -> argument_p)
  617.           {
  618.         CONST char ** value_cell = (scan_desc -> value_cell);
  619.         if (scan_argv < end_argv)
  620.           (*value_cell) = (*scan_argv++);
  621.         else
  622.           {
  623.             outf_fatal ("%s: option %s requires an argument.\n",
  624.                  scheme_program_name, option);
  625.             termination_init_error ();
  626.           }
  627.           }
  628.         else
  629.           {
  630.         int * value_cell = (scan_desc -> value_cell);
  631.         (*value_cell) = 1;
  632.           }
  633.         break;
  634.       }
  635.       if (scan_desc == end_desc)
  636.     {
  637.       scan_argv -= 1;
  638.       break;
  639.     }
  640.     }
  641.   obstack_free ((&scratch_obstack), descriptors);
  642.   option_saved_argc = argc;
  643.   option_saved_argv = argv;
  644.   option_unused_argc = (end_argv - scan_argv);
  645.   option_unused_argv = scan_argv;
  646. }
  647.  
  648. static void
  649. DEFUN (parse_standard_options, (argc, argv), int argc AND CONST char ** argv)
  650. {
  651.   option_argument ("-band", 1, (&option_raw_band));
  652.   option_argument ("-constant", 1, (&option_raw_constant));
  653.   option_argument ("-emacs", 0, (&option_emacs_subprocess));
  654.   option_argument ("-fasl", 1, (&option_fasl_file));
  655.   option_argument ("-heap", 1, (&option_raw_heap));
  656.   option_argument ("-interactive", 0, (&option_force_interactive));
  657.   option_argument ("-large", 0, (&option_large_sizes));
  658.   option_argument ("-library", 1, (&option_raw_library));
  659.   option_argument ("-nocore", 0, (&option_disable_core_dump));
  660.   option_argument ("-option-summary", 0, (&option_summary));
  661.   option_argument ("-stack", 1, (&option_raw_stack));
  662.   option_argument ("-utab", 1, (&option_raw_utab));
  663.   option_argument ("-utabmd", 1, (&option_raw_utabmd));
  664.   option_argument ("-empty-list-eq-false", 0, (&option_empty_list_eq_false));
  665. #ifdef HAS_COMPILER_SUPPORT
  666.   option_argument ("-compiler", 0, (&option_compiler_defaults));
  667.   option_argument ("-edwin", 0, (&option_edwin_defaults));
  668. #endif
  669.   /* The following options are only meaningful to bchscheme. */
  670.   option_argument ("-gc-directory", 1, (&option_gc_directory));
  671.   option_argument ("-gc-drone", 1, (&option_gc_drone));
  672.   option_argument ("-gc-end-position", 1, (&option_raw_gc_end_position));
  673.   option_argument ("-gc-file", 1, (&option_gc_file));
  674.   option_argument ("-gc-keep", 0, (&option_gc_keep));
  675.   option_argument ("-gc-start-position", 1, (&option_raw_gc_start_position));
  676.   option_argument ("-gc-read-overlap", 1, (&option_raw_gc_read_overlap));
  677.   option_argument ("-gc-window-size", 1, (&option_raw_gc_window_size));
  678.   option_argument ("-gc-write-overlap", 1, (&option_raw_gc_write_overlap));
  679.   option_argument ("-gcfile", 1, (&option_raw_gc_file)); /* Obsolete */
  680.   parse_options (argc, argv);
  681. }
  682.  
  683. static CONST char *
  684. DEFUN (string_option, (option, defval),
  685.        CONST char * option AND CONST char * defval)
  686. {
  687.   return ((option == ((char *) NULL)) ? defval : option);
  688. }
  689.  
  690. static CONST char *
  691. DEFUN (environment_default, (variable, defval),
  692.        CONST char * variable AND CONST char * defval)
  693. {
  694.   CONST char * temp = (getenv (variable));
  695.   return ((temp == ((char *) NULL)) ? defval : temp);
  696. }
  697.  
  698. static CONST char *
  699. DEFUN (standard_string_option, (option, variable, defval),
  700.        CONST char * option AND
  701.        CONST char * variable AND
  702.        CONST char * defval)
  703. {
  704.   if (option != 0)
  705.     return (option);
  706.   {
  707.     CONST char * t = (getenv (variable));
  708.     return ((t != 0) ? t : defval);
  709.   }
  710. }
  711.  
  712. static long
  713. DEFUN (non_negative_numeric_option, (option, optval, variable, defval),
  714.        CONST char * option AND
  715.        CONST char * optval AND
  716.        CONST char * variable AND
  717.        long defval)
  718. {
  719.   if (optval != 0)
  720.     {
  721.       long n = (strtol (optval, ((char **) NULL), 0));
  722.       if (n < 0)
  723.     {
  724.       outf_fatal ("%s: illegal argument %s for option %s.\n",
  725.            scheme_program_name, optval, option);
  726.       termination_init_error ();
  727.     }
  728.       return (n);
  729.     }
  730.   {
  731.     CONST char * t = (getenv (variable));
  732.     if (t != 0)
  733.       {
  734.     long n = (strtol (t, ((char **) NULL), 0));
  735.     if (n < 0)
  736.       {
  737.         outf_fatal ("%s: illegal value %s for variable %s.\n",
  738.              scheme_program_name, t, variable);
  739.         termination_init_error ();
  740.       }
  741.     return (n);
  742.       }
  743.   }
  744.   return (defval);
  745. }
  746.  
  747. static unsigned int
  748. DEFUN (standard_numeric_option, (option, optval, variable, defval),
  749.        CONST char * option AND
  750.        CONST char * optval AND
  751.        CONST char * variable AND
  752.        unsigned int defval)
  753. {
  754.   if (optval != 0)
  755.     {
  756.       int n = (atoi (optval));
  757.       if (n <= 0)
  758.     {
  759.       outf_fatal ("%s: illegal argument %s for option %s.\n",
  760.            scheme_program_name, optval, option);
  761.       termination_init_error ();
  762.     }
  763.       return (n);
  764.     }
  765.   {
  766.     CONST char * t = (getenv (variable));
  767.     if (t != 0)
  768.       {
  769.     int n = (atoi (t));
  770.     if (n <= 0)
  771.       {
  772.         outf_fatal ("%s: illegal value %s for variable %s.\n",
  773.              scheme_program_name, t, variable);
  774.         termination_init_error ();
  775.       }
  776.     return (n);
  777.       }
  778.   }
  779.   return (defval);
  780. }
  781.  
  782. static CONST char *
  783. DEFUN_VOID (get_wd)
  784. {
  785.   CONST char * wd = (OS_working_dir_pathname ());
  786.   unsigned int len = (strlen (wd));
  787.   if ((wd [len - 1]) == SUB_DIRECTORY_DELIMITER)
  788.     len -= 1;
  789.   {
  790.     char * result = (xmalloc (len + 1));
  791.     char * scan_result = result;
  792.     CONST char * scan_wd = wd;
  793.     CONST char * end_wd = (scan_wd + len);
  794.     while (scan_wd < end_wd)
  795.       (*scan_result++) = (*scan_wd++);
  796.     (*scan_result) = '\0';
  797.     return (result);
  798.   }
  799. }
  800.  
  801. static CONST char **
  802. DEFUN (parse_path_string, (path), CONST char * path)
  803. {
  804.   CONST char * start = path;
  805.   /* It is important that this get_wd be called here to make sure that
  806.      the the unix getcwd is called now, before it allocates heap space
  807.      This is because getcwd forks off a new process and we want to do
  808.      that before the scheme process gets too big
  809.   */
  810.   CONST char * wd = (get_wd ());
  811.   unsigned int lwd = (strlen (wd));
  812.   while (1)
  813.     {
  814.       CONST char * scan = start;
  815.       CONST char * end;
  816.       while (1)
  817.     {
  818.       int c = (*scan++);
  819.       if ((c == '\0') || (c == PATH_DELIMITER))
  820.         {
  821.           end = (scan - 1);
  822.           break;
  823.         }
  824.     }
  825.       if ((start < end) && ((* (end - 1)) == SUB_DIRECTORY_DELIMITER))
  826.     end -= 1;
  827.       if (end == start)
  828.     obstack_ptr_grow ((&scratch_obstack), (string_copy (wd)));
  829.       else
  830.     {
  831.       int absolute = (FILE_ABSOLUTE (start));
  832.       {
  833.         char * element =
  834.           (xmalloc ((absolute ? 0 : (lwd + 1)) + (end - start) + 1));
  835.         char * scan_element = element;
  836.         if (!absolute)
  837.           {
  838.         CONST char * s = wd;
  839.         CONST char * e = (wd + lwd);
  840.         while (s < e)
  841.           (*scan_element++) = (*s++);
  842.         (*scan_element++) = SUB_DIRECTORY_DELIMITER;
  843.           }
  844.         {
  845.           CONST char * s = start;
  846.           while (s < end)
  847.         (*scan_element++) = (*s++);
  848.         }
  849.         (*scan_element) = '\0';
  850.         obstack_ptr_grow ((&scratch_obstack), element);
  851.       }
  852.     }
  853.       if ((* (scan - 1)) == '\0')
  854.     break;
  855.       start = scan;
  856.     }
  857.   obstack_ptr_grow ((&scratch_obstack), 0);
  858.   if (wd != 0)
  859.     xfree (wd);
  860.   {
  861.     unsigned int n_bytes = (obstack_object_size (&scratch_obstack));
  862.     CONST char ** elements = (obstack_finish (&scratch_obstack));
  863.     CONST char ** scan = elements;
  864.     CONST char ** end = (scan + (n_bytes / (sizeof (char *))));
  865.     CONST char ** result = (xmalloc (n_bytes));
  866.     CONST char ** scan_result = result;
  867.     while (scan < end)
  868.       (*scan_result++) = (*scan++);
  869.     obstack_free ((&scratch_obstack), elements);
  870.     return (result);
  871.   }
  872. }
  873.  
  874. static void
  875. DEFUN (free_parsed_path, (path), CONST char ** path)
  876. {
  877.   CONST char ** scan = path;
  878.   while (1)
  879.     {
  880.       CONST char * element = (*scan++);
  881.       if (element == 0)
  882.     break;
  883.       xfree (element);
  884.     }
  885.   xfree (path);
  886. }
  887.  
  888. CONST char *
  889. DEFUN (search_for_library_file, (filename), CONST char * filename)
  890. {
  891.   unsigned int flen = (strlen (filename));
  892.   CONST char ** scan_path = option_library_path;
  893.   while (1)
  894.     {
  895.       CONST char * directory = (*scan_path++);
  896.       unsigned int dlen;
  897.       CONST char * fullname;
  898.       if (directory == 0)
  899.     return ((char *) NULL);
  900.       dlen = (strlen (directory));
  901.       if (dlen > 0)
  902.     {
  903.       obstack_grow ((&scratch_obstack), directory, dlen);
  904.       obstack_1grow ((&scratch_obstack), SUB_DIRECTORY_DELIMITER);
  905.     }
  906.       obstack_grow ((&scratch_obstack), filename, flen);
  907.       obstack_1grow ((&scratch_obstack), '\0');
  908.       fullname = (obstack_finish (&scratch_obstack));
  909.       if (FILE_READABLE (fullname))
  910.     {
  911.       CONST char * result = (string_copy (fullname));
  912.       obstack_free ((&scratch_obstack), ((char *) fullname));
  913.       return (result);
  914.     }
  915.       obstack_free ((&scratch_obstack), ((char *) fullname));
  916.     }
  917. }
  918.  
  919. CONST char *
  920. DEFUN (search_path_for_file, (option, filename, default_p, fail_p),
  921.        CONST char * option AND
  922.        CONST char * filename AND
  923.        int default_p AND
  924.        int fail_p)
  925. {
  926.   CONST char * result;
  927.  
  928.   if ((result = (search_for_library_file (filename))) != ((char *) NULL))
  929.     return (result);
  930.   if (!fail_p)
  931.     return (filename);
  932.   else
  933.   {
  934.     CONST char ** scan_path = option_library_path;
  935.  
  936.     outf_fatal ("%s: can't find a readable %s",
  937.          scheme_program_name, (default_p ? "default" : "file"));
  938.     if (option != 0)
  939.       outf_fatal (" for option %s", option);
  940.     outf_fatal (".\n");
  941.     outf_fatal ("\tsearched for file %s in these directories:\n",
  942.          filename);
  943.     if (!default_p)
  944.       outf_fatal ("\t.\n");
  945.     while (1)
  946.     {
  947.       CONST char * element = (*scan_path++);
  948.       if (element == 0)
  949.     break;
  950.       outf_fatal ("\t%s\n", element);
  951.     }
  952.     termination_init_error ();
  953.     /*NOTREACHED*/
  954.     return (0);
  955.   }
  956. }
  957.  
  958. static CONST char *
  959. DEFUN (standard_filename_option, (option, optval, variable, defval, fail_p),
  960.        CONST char * option AND
  961.        CONST char * optval AND
  962.        CONST char * variable AND
  963.        CONST char * defval AND
  964.        int fail_p)
  965. {
  966.   if (optval != 0)
  967.     {
  968.       if (FILE_READABLE (optval))
  969.     return (string_copy (optval));
  970.       if (FILE_ABSOLUTE (optval))
  971.     {
  972.       if (fail_p)
  973.         {
  974.           outf_fatal ("%s: can't read file %s for option %s.\n",
  975.                scheme_program_name, optval, option);
  976.           termination_init_error ();
  977.         }
  978.       return (string_copy (optval));
  979.     }
  980.       return (search_path_for_file (option, optval, 0, fail_p));
  981.     }
  982.   {
  983.     CONST char * filename = (getenv (variable));
  984.     if (filename == 0)
  985.       filename = defval;
  986.     if (FILE_ABSOLUTE (filename))
  987.       {
  988.     if ((! (FILE_READABLE (filename))) && fail_p)
  989.       {
  990.         outf_fatal ("%s: can't read default file %s for option %s.\n",
  991.              scheme_program_name, filename, option);
  992.         termination_init_error ();
  993.       }
  994.     return (string_copy (filename));
  995.       }
  996.     else
  997.       return (search_path_for_file (option, filename, 1, fail_p));
  998.   }
  999. }
  1000.  
  1001. static void
  1002. DEFUN (conflicting_options, (option1, option2),
  1003.        CONST char * option1 AND
  1004.        CONST char * option2)
  1005. {
  1006.   outf_fatal ("%s: can't specify both options %s and %s.\n",
  1007.        scheme_program_name, option1, option2);
  1008.   termination_init_error ();
  1009. }
  1010.  
  1011. #define SCHEME_WORDS_TO_BLOCKS(n) (((n) + 1023) / 1024)
  1012.  
  1013. static int
  1014. DEFUN (read_band_header, (filename, header),
  1015.        CONST char * filename AND
  1016.        SCHEME_OBJECT * header)
  1017. {
  1018. #ifdef __WIN32__
  1019.  
  1020.   HANDLE handle
  1021.     = (CreateFile (filename,
  1022.            GENERIC_READ,
  1023.            (FILE_SHARE_READ | FILE_SHARE_WRITE),
  1024.            0,
  1025.            OPEN_EXISTING,
  1026.            (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN),
  1027.            0));
  1028.   DWORD bytes_to_read = ((sizeof (SCHEME_OBJECT)) * FASL_HEADER_LENGTH);
  1029.   DWORD bytes_read;
  1030.   if (handle == INVALID_HANDLE_VALUE)
  1031.     return (0);
  1032.   if (! ((ReadFile (handle, header, bytes_to_read, (&bytes_read), 0))
  1033.      && (bytes_read == bytes_to_read)))
  1034.     {
  1035.       CloseHandle (handle);
  1036.       return (0);
  1037.     }
  1038.   CloseHandle (handle);
  1039.   return (1);
  1040.  
  1041. #else /* not __WIN32__ */
  1042.  
  1043.   FILE * stream = (fopen (filename, "r"));
  1044.   if (stream == 0)
  1045.     return (0);
  1046.   if ((fread (header, (sizeof (SCHEME_OBJECT)), FASL_HEADER_LENGTH, stream))
  1047.       != FASL_HEADER_LENGTH)
  1048.     {
  1049.       fclose (stream);
  1050.       return (0);
  1051.     }
  1052.   fclose (stream);
  1053.   return (1);
  1054.  
  1055. #endif /* not __WIN32__ */
  1056. }
  1057.  
  1058. static int
  1059. DEFUN (read_band_sizes, (filename, constant_size, heap_size),
  1060.        CONST char * filename AND
  1061.        unsigned long * constant_size AND
  1062.        unsigned long * heap_size)
  1063. {
  1064.   SCHEME_OBJECT header [FASL_HEADER_LENGTH];
  1065.   if (!read_band_header (filename, header))
  1066.     return (0);
  1067.   (*constant_size)
  1068.     = (SCHEME_WORDS_TO_BLOCKS
  1069.        (OBJECT_DATUM (header [FASL_Offset_Const_Count])));
  1070.   (*heap_size)
  1071.     = (SCHEME_WORDS_TO_BLOCKS
  1072.        (OBJECT_DATUM (header [FASL_Offset_Heap_Count])));
  1073.   return (1);
  1074. }
  1075.  
  1076. static void
  1077. DEFUN (describe_boolean_option, (name, value),
  1078.        CONST char * name AND
  1079.        int value)
  1080. {
  1081.   outf_fatal ("  %s: %s\n", name, (value ? "yes" : "no"));
  1082. }
  1083.  
  1084. static void
  1085. DEFUN (describe_string_option, (name, value),
  1086.        CONST char * name AND
  1087.        CONST char * value)
  1088. {
  1089.   outf_fatal ("  %s: %s\n", name, value);
  1090. }
  1091.  
  1092. static void
  1093. DEFUN (describe_numeric_option, (name, value),
  1094.        CONST char * name AND
  1095.        int value)
  1096. {
  1097.   outf_fatal ("  %s: %d\n", name, value);
  1098. }
  1099.  
  1100. static void
  1101. DEFUN (describe_size_option, (name, value),
  1102.        CONST char * name AND
  1103.        unsigned int value)
  1104. {
  1105.   outf_fatal ("  %s size: %d\n", name, value);
  1106. }
  1107.  
  1108. static void
  1109. DEFUN (describe_path_option, (name, value),
  1110.        CONST char * name AND
  1111.        CONST char ** value)
  1112. {
  1113.   outf_fatal ("  %s: ", name);
  1114.   {
  1115.     CONST char ** scan = value;
  1116.     outf_fatal ("%s", (*scan++));
  1117.     while (1)
  1118.       {
  1119.     CONST char * element = (*scan++);
  1120.     if (element == 0) break;
  1121.     outf_fatal (":%s", element);
  1122.       }
  1123.   }
  1124.   outf_fatal ("\n");
  1125. }
  1126.  
  1127. static void
  1128. DEFUN_VOID (describe_options)
  1129. {
  1130.   outf_fatal ("Summary of configuration options:\n");
  1131.   describe_size_option ("heap", option_heap_size);
  1132.   describe_size_option ("constant-space", option_constant_size);
  1133.   describe_size_option ("stack", option_stack_size);
  1134.   describe_path_option ("library path", option_library_path);
  1135.   if (option_fasl_file != 0)
  1136.     describe_string_option ("FASL file", option_fasl_file);
  1137.   else
  1138.     describe_string_option ("band", option_band_file);
  1139.   describe_string_option ("microcode tables", option_utabmd_file);
  1140.   {
  1141.     /* These are only relevant to bchscheme. */
  1142.     if (option_gc_directory != DEFAULT_GC_DIRECTORY)
  1143.       describe_string_option ("GC directory", option_gc_directory);
  1144.     if (option_gc_drone != DEFAULT_GC_DRONE)
  1145.       describe_string_option ("GC drone program", option_gc_drone);
  1146.     if (option_raw_gc_end_position)
  1147.       describe_numeric_option ("GC end position", option_gc_end_position);
  1148.     if (option_gc_file != DEFAULT_GC_FILE)
  1149.       describe_string_option ("GC file", option_gc_file);
  1150.     if (option_raw_gc_read_overlap)
  1151.       describe_numeric_option ("GC read overlap", option_gc_read_overlap);
  1152.     if (option_raw_gc_start_position)
  1153.       describe_numeric_option ("GC start position", option_gc_start_position);
  1154.     if (option_raw_gc_window_size)
  1155.       describe_size_option ("GC window size", option_gc_window_size);
  1156.     if (option_raw_gc_write_overlap)
  1157.       describe_numeric_option ("GC write overlap", option_gc_write_overlap);
  1158.     if (option_gc_keep)
  1159.       describe_boolean_option ("keep GC file", option_gc_keep);
  1160.   }
  1161.   describe_boolean_option ("emacs subprocess", option_emacs_subprocess);
  1162.   describe_boolean_option ("force interactive", option_force_interactive);
  1163.   describe_boolean_option ("disable core dump", option_disable_core_dump);
  1164.   if (option_unused_argc == 0)
  1165.     outf_fatal ("  no unused arguments\n");
  1166.   else
  1167.     {
  1168.       CONST char ** scan = option_unused_argv;
  1169.       CONST char ** end = (scan + option_unused_argc);
  1170.       outf_fatal ("  unused arguments:");
  1171.       while (scan < end)
  1172.     outf_fatal (" %s", (*scan++));
  1173.       outf_fatal ("\n");
  1174.     }
  1175. }
  1176.  
  1177. void
  1178. DEFUN (read_command_line_options, (argc, argv),
  1179.        int argc AND
  1180.        CONST char ** argv)
  1181. {
  1182.   int band_sizes_valid = 0;
  1183.   unsigned long band_constant_size;
  1184.   unsigned long band_heap_size;
  1185.  
  1186.   parse_standard_options (argc, argv);
  1187.   if (option_library_path != 0)
  1188.     free_parsed_path (option_library_path);
  1189.   option_library_path =
  1190.     (parse_path_string
  1191.      (standard_string_option (option_raw_library,
  1192.                   LIBRARY_PATH_VARIABLE,
  1193.                   DEFAULT_LIBRARY_PATH)));
  1194.   {
  1195.     CONST char * band_variable = BAND_VARIABLE;
  1196.     CONST char * default_band = DEFAULT_BAND;
  1197.  
  1198. #ifdef HAS_COMPILER_SUPPORT
  1199.     struct band_descriptor
  1200.       {
  1201.     CONST char * band;
  1202.     CONST char * envvar;
  1203.     int large_p;
  1204.     int compiler_support_p;
  1205.     int edwin_support_p;
  1206.       };
  1207.     struct band_descriptor available_bands [] =
  1208.       {
  1209.     { DEFAULT_BAND, BAND_VARIABLE, 0, 0, 0 },
  1210.     { COMPILER_DEFAULT_BAND, COMPILER_BAND_VARIABLE, 1, 1, 0 },
  1211.     { EDWIN_DEFAULT_BAND, EDWIN_BAND_VARIABLE, 1, 0, 1 },
  1212.     { ALL_DEFAULT_BAND, ALL_BAND_VARIABLE, 1, 1, 1 },
  1213.     { "6001.com", EDWIN_BAND_VARIABLE, 1, 0, 1 },
  1214.     { "mechanics.com", COMPILER_BAND_VARIABLE, 1, 1, 0 },
  1215.     { "edwin-mechanics.com", ALL_BAND_VARIABLE, 1, 1, 1 },
  1216.     { 0, 0, 0, 0, 0 }
  1217.       };
  1218.     struct band_descriptor * scan = available_bands;
  1219. #endif
  1220.  
  1221.     option_band_specified = 0;
  1222.     if (option_band_file != 0)
  1223.       xfree (option_band_file);
  1224.  
  1225. #ifdef HAS_COMPILER_SUPPORT
  1226.     while ((scan -> band) != 0)
  1227.       {
  1228.     if ((option_compiler_defaults ? (scan -> compiler_support_p) : 1)
  1229.         && (option_edwin_defaults ? (scan -> edwin_support_p) : 1)
  1230.         && (search_for_library_file (scan -> band)))
  1231.       {
  1232.         option_band_specified = 1;
  1233.         band_variable = (scan -> envvar);
  1234.         default_band = (scan -> band);
  1235.         if (scan -> large_p)
  1236.           option_large_sizes = 1;
  1237.         break;
  1238.       }
  1239.     scan += 1;
  1240.       }
  1241. #endif
  1242.  
  1243.     if (option_fasl_file != 0)
  1244.       {
  1245.     if (option_raw_band != 0)
  1246.       conflicting_options ("-fasl", "-band");
  1247. #ifndef NATIVE_CODE_IS_C
  1248.     if (! (FILE_READABLE (option_fasl_file)))
  1249.       {
  1250.         outf_fatal ("%s: can't read option file: -fasl %s\n",
  1251.              scheme_program_name, option_fasl_file);
  1252.         termination_init_error ();
  1253.       }
  1254. #endif /* NATIVE_CODE_IS_C */
  1255.     option_large_sizes = 1;
  1256.     option_band_specified = 1;
  1257.     option_band_file = 0;
  1258.       }
  1259.     else
  1260.       {
  1261.     if (option_raw_band != 0)
  1262.       option_band_specified = 1;
  1263.     option_band_file =
  1264.       (standard_filename_option ("-band",
  1265.                      option_raw_band,
  1266.                      band_variable,
  1267.                      default_band,
  1268.                      1));
  1269.       }
  1270.   }
  1271.   if (option_band_file != 0)
  1272.     band_sizes_valid
  1273.       = (read_band_sizes (option_band_file,
  1274.               (&band_constant_size),
  1275.               (&band_heap_size)));
  1276.   option_heap_size
  1277.     = ((standard_numeric_option ("-heap",
  1278.                  option_raw_heap,
  1279.                  (option_large_sizes
  1280.                   ? LARGE_HEAP_VARIABLE
  1281.                   : SMALL_HEAP_VARIABLE),
  1282.                  (option_large_sizes
  1283.                   ? DEFAULT_LARGE_HEAP
  1284.                   : DEFAULT_SMALL_HEAP)))
  1285.        + (band_sizes_valid ? band_heap_size : 0));
  1286.   option_constant_size
  1287.     = (standard_numeric_option ("-constant",
  1288.                 option_raw_constant,
  1289.                 (option_large_sizes
  1290.                  ? LARGE_CONSTANT_VARIABLE
  1291.                  : SMALL_CONSTANT_VARIABLE),
  1292.                 (band_sizes_valid
  1293.                  ? band_constant_size
  1294.                  : option_large_sizes
  1295.                  ? DEFAULT_LARGE_CONSTANT
  1296.                  : DEFAULT_SMALL_CONSTANT)));
  1297.   option_stack_size
  1298.     = (standard_numeric_option ("-stack",
  1299.                 option_raw_stack,
  1300.                 (option_large_sizes
  1301.                  ? LARGE_STACK_VARIABLE
  1302.                  : SMALL_STACK_VARIABLE),
  1303.                 (option_large_sizes
  1304.                  ? DEFAULT_LARGE_STACK
  1305.                  : DEFAULT_SMALL_STACK)));
  1306.   if (option_utabmd_file != 0)
  1307.     xfree (option_utabmd_file);
  1308.   if (option_raw_utabmd != 0)
  1309.     {
  1310.       if (option_raw_utab != 0)
  1311.     conflicting_options ("-utabmd", "-utab");
  1312.       option_utabmd_file =
  1313.     (standard_filename_option ("-utabmd",
  1314.                    option_raw_utabmd,
  1315.                    UTABMD_FILE_VARIABLE,
  1316.                    DEFAULT_UTABMD_FILE,
  1317.                    (option_fasl_file != 0)));
  1318.     }
  1319.   else
  1320.     option_utabmd_file =
  1321.       (standard_filename_option ("-utab",
  1322.                  option_raw_utab,
  1323.                  UTABMD_FILE_VARIABLE,
  1324.                  DEFAULT_UTABMD_FILE,
  1325.                  (option_fasl_file != 0)));
  1326.  
  1327.   /* These are only meaningful for bchscheme. */
  1328.  
  1329.   if (option_raw_gc_file != ((char *) 0))
  1330.   {
  1331.     if (option_gc_file != ((char *) 0))
  1332.       conflicting_options ("-gcfile", "-gc-file");
  1333.     else
  1334.       option_gc_file = option_raw_gc_file;
  1335.   }
  1336.  
  1337.   {
  1338.     CONST char * dir = (environment_default (GC_DIRECTORY_VARIABLE, 0));
  1339.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1340.       dir = (environment_default ("TMPDIR", 0));
  1341.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1342.       dir = (environment_default ("TEMP", 0));
  1343.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1344.       dir = (environment_default ("TMP", 0));
  1345.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1346.       dir = (environment_default ("TMP", 0));
  1347. #ifdef __unix__
  1348.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1349.       {
  1350.     if (OS_file_directory_p ("/var/tmp"))
  1351.       dir = "/var/tmp";
  1352.     if (OS_file_directory_p ("/usr/tmp"))
  1353.       dir = "/usr/tmp";
  1354.     if (OS_file_directory_p ("/tmp"))
  1355.       dir = "/tmp";
  1356.       }
  1357. #endif /* __unix__ */
  1358.     if ((dir == 0) || (!OS_file_directory_p (dir)))
  1359.       dir = DEFAULT_GC_DIRECTORY;
  1360.     option_gc_directory = (string_option (option_gc_directory, dir));
  1361.   }
  1362.   option_gc_drone =
  1363.     (standard_filename_option ("-gc-drone",
  1364.                    option_gc_drone,
  1365.                    GC_DRONE_VARIABLE,
  1366.                    DEFAULT_GC_DRONE,
  1367.                    0));
  1368.  
  1369.   option_gc_end_position =
  1370.     (non_negative_numeric_option ("-gc-end-position",
  1371.                   option_raw_gc_end_position,
  1372.                   GC_END_POSITION_VARIABLE,
  1373.                   DEFAULT_GC_END_POSITION));
  1374.  
  1375.   option_gc_file =
  1376.     (standard_string_option (option_gc_file,
  1377.                  GC_FILE_VARIABLE,
  1378.                  DEFAULT_GC_FILE));
  1379.  
  1380.   option_gc_read_overlap =
  1381.     ((int)
  1382.      (non_negative_numeric_option ("-gc-read-overlap",
  1383.                    option_raw_gc_read_overlap,
  1384.                    GC_READ_OVERLAP_VARIABLE,
  1385.                    DEFAULT_GC_READ_OVERLAP)));
  1386.  
  1387.   option_gc_start_position =
  1388.     (non_negative_numeric_option ("-gc-start-position",
  1389.                   option_raw_gc_start_position,
  1390.                   GC_START_POSITION_VARIABLE,
  1391.                   DEFAULT_GC_START_POSITION));
  1392.  
  1393.   option_gc_window_size =
  1394.     (standard_numeric_option ("-gc-window-size",
  1395.                   option_raw_gc_window_size,
  1396.                   GC_WINDOW_SIZE_VARIABLE,
  1397.                   DEFAULT_GC_WINDOW_SIZE));
  1398.  
  1399.   option_gc_write_overlap =
  1400.     ((int)
  1401.      (non_negative_numeric_option ("-gc-write-overlap",
  1402.                    option_raw_gc_write_overlap,
  1403.                    GC_WRITE_OVERLAP_VARIABLE,
  1404.                    DEFAULT_GC_WRITE_OVERLAP)));
  1405.  
  1406.   if (option_summary)
  1407.     describe_options ();
  1408.  
  1409. }
  1410.