1 /* Copyright (C) 2002-2003 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 95 runtime library (libgfor).
6 Libgfor is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 Libgfor is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libgfor; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 #include "libgfortran.h"
30 /* Environment scanner. Examine the environment for controlling minor
31 * aspects of the program's execution. Our philosophy here that the
32 * environment should not prevent the program from running, so an
33 * environment variable with a messed-up value will be interpreted in
36 * Most of the environment is checked early in the startup sequence,
37 * but other variables are checked during execution of the user's
40 options_t options = { };
42 extern char **environ;
44 typedef struct variable
48 void (*init) (struct variable *);
49 void (*show) (struct variable *);
56 /* print_spaces()-- Print a particular number of spaces */
67 for (i = 0; i < n; i++)
76 /* var_source()-- Return a string that describes where the value of a
77 * variable comes from */
80 var_source (variable * v)
82 if (getenv (v->name) == NULL)
92 /* init_integer()-- Initialize an integer environment variable */
95 init_integer (variable * v)
119 /* show_integer()-- Show an integer environment variable */
122 show_integer (variable * v)
124 st_printf ("%s %d\n", var_source (v), *v->var);
128 /* init_boolean()-- Initialize a boolean environment variable. We
129 * only look at the first letter of the variable. */
132 init_boolean (variable * v)
136 p = getenv (v->name);
140 if (*p == '1' || *p == 'Y' || *p == 'y')
146 if (*p == '0' || *p == 'N' || *p == 'n')
160 /* show_boolean()-- Show a boolean environment variable */
163 show_boolean (variable * v)
165 st_printf ("%s %s\n", var_source (v), *v->var ? "Yes" : "No");
169 /* init_mem()-- Initialize environment variables that have to do with
170 * how memory from an ALLOCATE statement is filled. A single flag
171 * enables filling and a second variable gives the value that is used
172 * to initialize the memory. */
175 init_mem (variable * v)
180 p = getenv (v->name);
182 options.allocate_init_flag = 0; /* The default */
187 if (strcasecmp (p, "NONE") == 0)
190 /* IEEE-754 Quiet Not-a-Number that will work for single and double
191 * precision. Look for the 'f95' mantissa in debug dumps. */
193 if (strcasecmp (p, "NaN") == 0)
195 options.allocate_init_flag = 1;
196 options.allocate_init_value = 0xfff80f95;
200 /* Interpret the string as a hexadecimal constant */
217 n = (n << 4) | (*p++ - offset);
220 options.allocate_init_flag = 1;
221 options.allocate_init_value = n;
226 show_mem (variable * v)
230 p = getenv (v->name);
232 st_printf ("%s ", var_source (v));
234 if (options.allocate_init_flag)
235 st_printf ("0x%x", options.allocate_init_value);
242 init_sep (variable * v)
247 p = getenv (v->name);
252 options.separator = p;
253 options.separator_len = strlen (p);
255 /* Make sure the separator is valid */
257 if (options.separator_len == 0)
280 options.separator = " ";
281 options.separator_len = 1;
286 show_sep (variable * v)
288 st_printf ("%s \"%s\"\n", var_source (v), options.separator);
293 init_string (variable * v)
298 show_string (variable * v)
302 p = getenv (v->name);
306 st_printf ("%s \"%s\"\n", var_source (v), p);
310 /* Structure for associating names and values. */
321 { FP_ROUND_NEAREST, FP_ROUND_UP, FP_ROUND_DOWN, FP_ROUND_ZERO };
323 static choice rounding[] = {
324 {"NEAREST", FP_ROUND_NEAREST},
326 {"DOWN", FP_ROUND_DOWN},
327 {"ZERO", FP_ROUND_ZERO},
331 static choice precision[] =
339 static choice signal_choices[] =
348 init_choice (variable * v, choice * c)
352 p = getenv (v->name);
357 if (strcasecmp (c->name, p) == 0)
375 show_choice (variable * v, choice * c)
377 st_printf ("%s ", var_source (v));
380 if (c->value == *v->var)
384 st_printf ("%s\n", c->name);
386 st_printf ("(Unknown)\n");
391 init_round (variable * v)
393 init_choice (v, rounding);
397 show_round (variable * v)
399 show_choice (v, rounding);
403 init_precision (variable * v)
405 init_choice (v, precision);
409 show_precision (variable * v)
411 show_choice (v, precision);
415 init_signal (variable * v)
417 init_choice (v, signal_choices);
421 show_signal (variable * v)
423 show_choice (v, signal_choices);
427 static variable variable_table[] = {
428 {"GFORTRAN_STDIN_UNIT", 5, &options.stdin_unit, init_integer, show_integer,
429 "Unit number that will be preconnected to standard input\n"
430 "(No preconnection if negative)"},
432 {"GFORTRAN_STDOUT_UNIT", 6, &options.stdout_unit, init_integer,
434 "Unit number that will be preconnected to standard output\n"
435 "(No preconnection if negative)"},
437 {"GFORTRAN_USE_STDERR", 1, &options.use_stderr, init_boolean,
439 "Sends library output to standard error instead of standard output."},
441 {"GFORTRAN_TMPDIR", 0, NULL, init_string, show_string,
442 "Directory for scratch files. Overrides the TMP environment variable\n"
443 "If TMP is not set " DEFAULT_TEMPDIR " is used."},
445 {"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean,
447 "If TRUE, all output is unbuffered. This will slow down large writes "
448 "but can be\nuseful for forcing data to be displayed immediately."},
450 {"GFORTRAN_SHOW_LOCUS", 1, &options.locus, init_boolean, show_boolean,
451 "If TRUE, print filename and line number where runtime errors happen."},
453 /* GFORTRAN_NAME_xx (where xx is a unit number) gives the names of files
454 * preconnected to those units. */
456 /* GFORTRAN_UNBUFFERED_xx (where xx is a unit number) gives a boolean that is used
457 * to turn off buffering for that unit. */
459 {"GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean, show_boolean,
460 "Print optional plus signs in numbers where permitted. Default FALSE."},
462 {"GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl,
463 init_integer, show_integer,
464 "Default maximum record length for sequential files. Most useful for\n"
465 "adjusting line length of preconnected units. Default "
466 stringize (DEFAULT_RECL)},
468 {"GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep, show_sep,
469 "Separatator to use when writing list output. May contain any number of "
470 "spaces\nand at most one comma. Default is a single space."},
472 /* Memory related controls */
474 {"GFORTRAN_MEM_INIT", 0, NULL, init_mem, show_mem,
475 "How to initialize allocated memory. Default value is NONE for no "
476 "initialization\n(faster), NAN for a Not-a-Number with the mantissa "
477 "0x40f95 or a custom\nhexadecimal value"},
479 {"GFORTRAN_MEM_CHECK", 0, &options.mem_check, init_boolean, show_boolean,
480 "Whether memory still allocated will be reported when the program ends."},
482 /* Signal handling (Unix). */
484 {"GFORTRAN_SIGHUP", 0, &options.sighup, init_signal, show_signal,
485 "Whether the program will IGNORE or ABORT on SIGHUP."},
487 {"GFORTRAN_SIGINT", 0, &options.sigint, init_signal, show_signal,
488 "Whether the program will IGNORE or ABORT on SIGINT."},
490 /* Floating point control */
492 {"GFORTRAN_FPU_ROUND", 0, &options.fpu_round, init_round, show_round,
493 "Set floating point rounding. Values are NEAREST, UP, DOWN, ZERO."},
495 {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision, init_precision,
497 "Precision of intermediate results. Values are 24, 53 and 64."},
499 {"GFORTRAN_FPU_INVALID", 1, &options.fpu_invalid, init_boolean,
501 "Raise a floating point exception on invalid FP operation."},
503 {"GFORTRAN_FPU_DENORMAL", 1, &options.fpu_denormal, init_boolean,
505 "Raise a floating point exception when denormal numbers are encountered."},
507 {"GFORTRAN_FPU_ZERO", 0, &options.fpu_zerodiv, init_boolean, show_boolean,
508 "Raise a floating point exception when dividing by zero."},
510 {"GFORTRAN_FPU_OVERFLOW", 0, &options.fpu_overflow, init_boolean,
512 "Raise a floating point exception on overflow."},
514 {"GFORTRAN_FPU_UNDERFLOW", 0, &options.fpu_underflow, init_boolean,
516 "Raise a floating point exception on underflow."},
518 {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision_loss, init_boolean,
520 "Raise a floating point exception on precision loss."},
526 /* init_variables()-- Initialize most runtime variables from
527 * environment variables. */
530 init_variables (void)
534 for (v = variable_table; v->name; v++)
539 /* check_buffered()-- Given an unit number n, determine if an override
540 * for the stream exists. Returns zero for unbuffered, one for
541 * buffered or two for not set. */
544 check_buffered (int n)
550 if (options.all_unbuffered)
553 strcpy (name, "GFORTRAN_UNBUFFERED_");
554 strcat (name, itoa (n));
566 /* pattern_scan()-- Given an environment string, check that the name
567 * has the same name as the pattern followed by an integer. On a
568 * match, a pointer to the value is returned and the integer pointed
569 * to by n is updated. Returns NULL on no match. */
572 pattern_scan (char *env, const char *pattern, int *n)
577 len = strlen (pattern);
578 if (strncasecmp (env, pattern, len) != 0)
592 *n = atoi (env + len);
600 show_variables (void)
606 /* TODO: print version number. */
607 st_printf ("GNU Fortran 95 runtime library version "
610 st_printf ("Environment variables:\n");
611 st_printf ("----------------------\n");
613 for (v = variable_table; v->name; v++)
615 n = st_printf ("%s", v->name);
616 print_spaces (25 - n);
618 if (v->show == show_integer)
619 st_printf ("Integer ");
620 else if (v->show == show_boolean)
621 st_printf ("Boolean ");
623 st_printf ("String ");
626 st_printf ("%s\n\n", v->desc);
629 st_printf ("\nDefault unit names (GFORTRAN_NAME_x):\n");
631 for (e = environ; *e; e++)
633 p = pattern_scan (*e, "GFORTRAN_NAME_", &n);
636 st_printf ("GFORTRAN_NAME_%d %s\n", n, p);
639 st_printf ("\nUnit buffering overrides (GFORTRAN_UNBUFFERED_x):\n");
640 for (e = environ; *e; e++)
642 p = pattern_scan (*e, "GFORTRAN_UNBUFFERED_", &n);
646 st_printf ("GFORTRAN_UNBUFFERED_%d = %s\n", n, p);
649 /* System error codes */
651 st_printf ("\nRuntime error codes:");
652 st_printf ("\n--------------------\n");
654 for (n = ERROR_FIRST + 1; n < ERROR_LAST; n++)
656 st_printf ("%d %s\n", n, translate_error (n));
658 st_printf (" %d %s\n", n, translate_error (n));
660 st_printf ("\nCommand line arguments:\n");
661 st_printf (" --help Print this list\n");
663 /* st_printf(" --resume <dropfile> Resume program execution from dropfile\n"); */