]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/runtime/environ.c
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
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
)
83 if (getenv (v
->name
) == NULL
)
93 /* init_integer()-- Initialize an integer environment variable */
96 init_integer (variable
* v
)
100 p
= getenv (v
->name
);
120 /* show_integer()-- Show an integer environment variable */
123 show_integer (variable
* v
)
126 st_printf ("%s %d\n", var_source (v
), *v
->var
);
130 /* init_boolean()-- Initialize a boolean environment variable. We
131 * only look at the first letter of the variable. */
134 init_boolean (variable
* v
)
138 p
= getenv (v
->name
);
142 if (*p
== '1' || *p
== 'Y' || *p
== 'y')
148 if (*p
== '0' || *p
== 'N' || *p
== 'n')
162 /* show_boolean()-- Show a boolean environment variable */
165 show_boolean (variable
* v
)
168 st_printf ("%s %s\n", var_source (v
), *v
->var
? "Yes" : "No");
172 /* init_mem()-- Initialize environment variables that have to do with
173 * how memory from an ALLOCATE statement is filled. A single flag
174 * enables filling and a second variable gives the value that is used
175 * to initialize the memory. */
178 init_mem (variable
* v
)
183 p
= getenv (v
->name
);
185 options
.allocate_init_flag
= 0; /* The default */
190 if (strcasecmp (p
, "NONE") == 0)
193 /* IEEE-754 Quiet Not-a-Number that will work for single and double
194 * precision. Look for the 'f95' mantissa in debug dumps. */
196 if (strcasecmp (p
, "NaN") == 0)
198 options
.allocate_init_flag
= 1;
199 options
.allocate_init_value
= 0xfff80f95;
203 /* Interpret the string as a hexadecimal constant */
220 n
= (n
<< 4) | (*p
++ - offset
);
223 options
.allocate_init_flag
= 1;
224 options
.allocate_init_value
= n
;
229 show_mem (variable
* v
)
233 p
= getenv (v
->name
);
235 st_printf ("%s ", var_source (v
));
237 if (options
.allocate_init_flag
)
238 st_printf ("0x%x", options
.allocate_init_value
);
245 init_sep (variable
* v
)
250 p
= getenv (v
->name
);
255 options
.separator
= p
;
256 options
.separator_len
= strlen (p
);
258 /* Make sure the separator is valid */
260 if (options
.separator_len
== 0)
283 options
.separator
= " ";
284 options
.separator_len
= 1;
289 show_sep (variable
* v
)
292 st_printf ("%s \"%s\"\n", var_source (v
), options
.separator
);
297 init_string (variable
* v
)
302 show_string (variable
* v
)
306 p
= getenv (v
->name
);
310 st_printf ("%s \"%s\"\n", var_source (v
), p
);
314 /* Structure for associating names and values. */
325 { FP_ROUND_NEAREST
, FP_ROUND_UP
, FP_ROUND_DOWN
, FP_ROUND_ZERO
};
327 static choice rounding
[] = {
328 {"NEAREST", FP_ROUND_NEAREST
},
330 {"DOWN", FP_ROUND_DOWN
},
331 {"ZERO", FP_ROUND_ZERO
},
362 init_choice (variable
* v
, choice
* c
)
366 p
= getenv (v
->name
);
371 if (strcasecmp (c
->name
, p
) == 0)
389 show_choice (variable
* v
, choice
* c
)
392 st_printf ("%s ", var_source (v
));
395 if (c
->value
== *v
->var
)
399 st_printf ("%s\n", c
->name
);
401 st_printf ("(Unknown)\n");
407 init_round (variable
* v
)
409 init_choice (v
, rounding
);
412 show_round (variable
* v
)
414 show_choice (v
, rounding
);
418 init_precision (variable
* v
)
420 init_choice (v
, precision
);
423 show_precision (variable
* v
)
425 show_choice (v
, precision
);
429 init_signal (variable
* v
)
431 init_choice (v
, signal_choices
);
434 show_signal (variable
* v
)
436 show_choice (v
, signal_choices
);
440 static variable variable_table
[] = {
441 {"GFORTRAN_STDIN_UNIT", 5, &options
.stdin_unit
, init_integer
, show_integer
,
442 "Unit number that will be preconnected to standard input\n"
443 "(No preconnection if negative)"},
445 {"GFORTRAN_STDOUT_UNIT", 6, &options
.stdout_unit
, init_integer
,
447 "Unit number that will be preconnected to standard output\n"
448 "(No preconnection if negative)"},
450 {"GFORTRAN_USE_STDERR", 1, &options
.use_stderr
, init_boolean
,
452 "Sends library output to standard error instead of standard output."},
454 {"GFORTRAN_TMPDIR", 0, NULL
, init_string
, show_string
,
455 "Directory for scratch files. Overrides the TMP environment variable\n"
456 "If TMP is not set " DEFAULT_TEMPDIR
" is used."},
458 {"GFORTRAN_UNBUFFERED_ALL", 0, &options
.all_unbuffered
, init_boolean
,
460 "If TRUE, all output is unbuffered. This will slow down large writes "
461 "but can be\nuseful for forcing data to be displayed immediately."},
463 {"GFORTRAN_SHOW_LOCUS", 1, &options
.locus
, init_boolean
, show_boolean
,
464 "If TRUE, print filename and line number where runtime errors happen."},
466 /* GFORTRAN_NAME_xx (where xx is a unit number) gives the names of files
467 * preconnected to those units. */
469 /* GFORTRAN_UNBUFFERED_xx (where xx is a unit number) gives a boolean that is used
470 * to turn off buffering for that unit. */
472 {"GFORTRAN_OPTIONAL_PLUS", 0, &options
.optional_plus
, init_boolean
, show_boolean
,
473 "Print optional plus signs in numbers where permitted. Default FALSE."},
475 {"GFORTRAN_DEFAULT_RECL", DEFAULT_RECL
, &options
.default_recl
,
476 init_integer
, show_integer
,
477 "Default maximum record length for sequential files. Most useful for\n"
478 "adjusting line length of preconnected units. Default "
479 stringize (DEFAULT_RECL
)},
481 {"GFORTRAN_LIST_SEPARATOR", 0, NULL
, init_sep
, show_sep
,
482 "Separatator to use when writing list output. May contain any number of "
483 "spaces\nand at most one comma. Default is a single space."},
485 /* Memory related controls */
487 {"GFORTRAN_MEM_INIT", 0, NULL
, init_mem
, show_mem
,
488 "How to initialize allocated memory. Default value is NONE for no "
489 "initialization\n(faster), NAN for a Not-a-Number with the mantissa "
490 "0x40f95 or a custom\nhexadecimal value"},
492 {"GFORTRAN_MEM_CHECK", 0, &options
.mem_check
, init_boolean
, show_boolean
,
493 "Whether memory still allocated will be reported when the program ends."},
495 /* Signal handling (Unix). */
497 {"GFORTRAN_SIGHUP", 0, &options
.sighup
, init_signal
, show_signal
,
498 "Whether the program will IGNORE or ABORT on SIGHUP."},
500 {"GFORTRAN_SIGINT", 0, &options
.sigint
, init_signal
, show_signal
,
501 "Whether the program will IGNORE or ABORT on SIGINT."},
503 /* Floating point control */
505 {"GFORTRAN_FPU_ROUND", 0, &options
.fpu_round
, init_round
, show_round
,
506 "Set floating point rounding. Values are NEAREST, UP, DOWN, ZERO."},
508 {"GFORTRAN_FPU_PRECISION", 0, &options
.fpu_precision
, init_precision
,
510 "Precision of intermediate results. Values are 24, 53 and 64."},
512 {"GFORTRAN_FPU_INVALID", 1, &options
.fpu_invalid
, init_boolean
,
514 "Raise a floating point exception on invalid FP operation."},
516 {"GFORTRAN_FPU_DENORMAL", 1, &options
.fpu_denormal
, init_boolean
,
518 "Raise a floating point exception when denormal numbers are encountered."},
520 {"GFORTRAN_FPU_ZERO", 0, &options
.fpu_zerodiv
, init_boolean
, show_boolean
,
521 "Raise a floating point exception when dividing by zero."},
523 {"GFORTRAN_FPU_OVERFLOW", 0, &options
.fpu_overflow
, init_boolean
,
525 "Raise a floating point exception on overflow."},
527 {"GFORTRAN_FPU_UNDERFLOW", 0, &options
.fpu_underflow
, init_boolean
,
529 "Raise a floating point exception on underflow."},
531 {"GFORTRAN_FPU_PRECISION", 0, &options
.fpu_precision_loss
, init_boolean
,
533 "Raise a floating point exception on precision loss."},
539 /* init_variables()-- Initialize most runtime variables from
540 * environment variables. */
543 init_variables (void)
547 for (v
= variable_table
; v
->name
; v
++)
552 /* check_buffered()-- Given an unit number n, determine if an override
553 * for the stream exists. Returns zero for unbuffered, one for
554 * buffered or two for not set. */
557 check_buffered (int n
)
563 if (options
.all_unbuffered
)
566 strcpy (name
, "GFORTRAN_UNBUFFERED_");
567 strcat (name
, itoa (n
));
579 /* pattern_scan()-- Given an environment string, check that the name
580 * has the same name as the pattern followed by an integer. On a
581 * match, a pointer to the value is returned and the integer pointed
582 * to by n is updated. Returns NULL on no match. */
585 pattern_scan (char *env
, const char *pattern
, int *n
)
590 len
= strlen (pattern
);
591 if (strncasecmp (env
, pattern
, len
) != 0)
605 *n
= atoi (env
+ len
);
613 show_variables (void)
618 /* TODO: print version number. */
619 st_printf ("GNU Fortran 95 runtime library version "
622 st_printf ("Environment variables:\n");
623 st_printf ("----------------------\n");
625 for (v
= variable_table
; v
->name
; v
++)
627 n
= st_printf ("%s", v
->name
);
628 print_spaces (25 - n
);
630 if (v
->show
== show_integer
)
631 st_printf ("Integer ");
632 else if (v
->show
== show_boolean
)
633 st_printf ("Boolean ");
635 st_printf ("String ");
638 st_printf ("%s\n\n", v
->desc
);
641 st_printf ("\nDefault unit names (GFORTRAN_NAME_x):\n");
643 for (e
= environ
; *e
; e
++)
645 p
= pattern_scan (*e
, "GFORTRAN_NAME_", &n
);
648 st_printf ("GFORTRAN_NAME_%d %s\n", n
, p
);
651 st_printf ("\nUnit buffering overrides (GFORTRAN_UNBUFFERED_x):\n");
652 for (e
= environ
; *e
; e
++)
654 p
= pattern_scan (*e
, "GFORTRAN_UNBUFFERED_", &n
);
658 st_printf ("GFORTRAN_UNBUFFERED_%d = %s\n", n
, p
);
661 /* System error codes */
663 st_printf ("\nRuntime error codes:");
664 st_printf ("\n--------------------\n");
666 for (n
= ERROR_FIRST
+ 1; n
< ERROR_LAST
; n
++)
668 st_printf ("%d %s\n", n
, translate_error (n
));
670 st_printf (" %d %s\n", n
, translate_error (n
));
672 st_printf ("\nCommand line arguments:\n");
673 st_printf (" --help Print this list\n");
675 /* st_printf(" --resume <dropfile> Resume program execution from dropfile\n"); */