Merge from mainline
[official-gcc.git] / libgfortran / runtime / environ.c
blobc519f0845737f3260fb28edd8b4d635ff107ad14
1 /* Copyright (C) 2002,2003,2005 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6 Libgfortran 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)
9 any later version.
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
18 executable.)
20 Libgfortran is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with libgfortran; see the file COPYING. If not, write to
27 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28 Boston, MA 02110-1301, USA. */
30 #include "config.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <ctype.h>
36 #include "libgfortran.h"
37 #include "../io/io.h"
40 /* Environment scanner. Examine the environment for controlling minor
41 * aspects of the program's execution. Our philosophy here that the
42 * environment should not prevent the program from running, so an
43 * environment variable with a messed-up value will be interpreted in
44 * the default way.
46 * Most of the environment is checked early in the startup sequence,
47 * but other variables are checked during execution of the user's
48 * program. */
50 options_t options;
53 typedef struct variable
55 const char *name;
56 int value, *var;
57 void (*init) (struct variable *);
58 void (*show) (struct variable *);
59 const char *desc;
60 int bad;
62 variable;
64 static void init_unformatted (variable *);
66 /* print_spaces()-- Print a particular number of spaces. */
68 static void
69 print_spaces (int n)
71 char buffer[80];
72 int i;
74 if (n <= 0)
75 return;
77 for (i = 0; i < n; i++)
78 buffer[i] = ' ';
80 buffer[i] = '\0';
82 st_printf (buffer);
86 /* var_source()-- Return a string that describes where the value of a
87 * variable comes from */
89 static const char *
90 var_source (variable * v)
92 if (getenv (v->name) == NULL)
93 return "Default";
95 if (v->bad)
96 return "Bad ";
98 return "Set ";
102 /* init_integer()-- Initialize an integer environment variable. */
104 static void
105 init_integer (variable * v)
107 char *p, *q;
109 p = getenv (v->name);
110 if (p == NULL)
111 goto set_default;
113 for (q = p; *q; q++)
114 if (!isdigit (*q) && (p != q || *q != '-'))
116 v->bad = 1;
117 goto set_default;
120 *v->var = atoi (p);
121 return;
123 set_default:
124 *v->var = v->value;
125 return;
129 /* init_unsigned_integer()-- Initialize an integer environment variable
130 which has to be positive. */
132 static void
133 init_unsigned_integer (variable * v)
135 char *p, *q;
137 p = getenv (v->name);
138 if (p == NULL)
139 goto set_default;
141 for (q = p; *q; q++)
142 if (!isdigit (*q))
144 v->bad = 1;
145 goto set_default;
148 *v->var = atoi (p);
149 return;
151 set_default:
152 *v->var = v->value;
153 return;
157 /* show_integer()-- Show an integer environment variable */
159 static void
160 show_integer (variable * v)
162 st_printf ("%s %d\n", var_source (v), *v->var);
166 /* init_boolean()-- Initialize a boolean environment variable. We
167 * only look at the first letter of the variable. */
169 static void
170 init_boolean (variable * v)
172 char *p;
174 p = getenv (v->name);
175 if (p == NULL)
176 goto set_default;
178 if (*p == '1' || *p == 'Y' || *p == 'y')
180 *v->var = 1;
181 return;
184 if (*p == '0' || *p == 'N' || *p == 'n')
186 *v->var = 0;
187 return;
190 v->bad = 1;
192 set_default:
193 *v->var = v->value;
194 return;
198 /* show_boolean()-- Show a boolean environment variable */
200 static void
201 show_boolean (variable * v)
203 st_printf ("%s %s\n", var_source (v), *v->var ? "Yes" : "No");
207 /* init_mem()-- Initialize environment variables that have to do with
208 * how memory from an ALLOCATE statement is filled. A single flag
209 * enables filling and a second variable gives the value that is used
210 * to initialize the memory. */
212 static void
213 init_mem (variable * v)
215 int offset, n;
216 char *p;
218 p = getenv (v->name);
220 options.allocate_init_flag = 0; /* The default */
222 if (p == NULL)
223 return;
225 if (strcasecmp (p, "NONE") == 0)
226 return;
228 /* IEEE-754 Quiet Not-a-Number that will work for single and double
229 * precision. Look for the 'f95' mantissa in debug dumps. */
231 if (strcasecmp (p, "NaN") == 0)
233 options.allocate_init_flag = 1;
234 options.allocate_init_value = 0xfff80f95;
235 return;
238 /* Interpret the string as a hexadecimal constant */
240 n = 0;
241 while (*p)
243 if (!isxdigit (*p))
245 v->bad = 1;
246 return;
249 offset = '0';
250 if (islower (*p))
251 offset = 'a';
252 if (isupper (*p))
253 offset = 'A';
255 n = (n << 4) | (*p++ - offset);
258 options.allocate_init_flag = 1;
259 options.allocate_init_value = n;
263 static void
264 show_mem (variable * v)
266 char *p;
268 p = getenv (v->name);
270 st_printf ("%s ", var_source (v));
272 if (options.allocate_init_flag)
273 st_printf ("0x%x", options.allocate_init_value);
275 st_printf ("\n");
279 static void
280 init_sep (variable * v)
282 int seen_comma;
283 char *p;
285 p = getenv (v->name);
286 if (p == NULL)
287 goto set_default;
289 v->bad = 1;
290 options.separator = p;
291 options.separator_len = strlen (p);
293 /* Make sure the separator is valid */
295 if (options.separator_len == 0)
296 goto set_default;
297 seen_comma = 0;
299 while (*p)
301 if (*p == ',')
303 if (seen_comma)
304 goto set_default;
305 seen_comma = 1;
306 p++;
307 continue;
310 if (*p++ != ' ')
311 goto set_default;
314 v->bad = 0;
315 return;
317 set_default:
318 options.separator = " ";
319 options.separator_len = 1;
323 static void
324 show_sep (variable * v)
326 st_printf ("%s \"%s\"\n", var_source (v), options.separator);
330 static void
331 init_string (variable * v __attribute__ ((unused)))
335 static void
336 show_string (variable * v)
338 const char *p;
340 p = getenv (v->name);
341 if (p == NULL)
342 p = "";
344 st_printf ("%s \"%s\"\n", var_source (v), p);
348 /* Structure for associating names and values. */
350 typedef struct
352 const char *name;
353 int value;
355 choice;
358 enum
359 { FP_ROUND_NEAREST, FP_ROUND_UP, FP_ROUND_DOWN, FP_ROUND_ZERO };
361 static const choice rounding[] = {
362 {"NEAREST", FP_ROUND_NEAREST},
363 {"UP", FP_ROUND_UP},
364 {"DOWN", FP_ROUND_DOWN},
365 {"ZERO", FP_ROUND_ZERO},
366 {NULL, 0}
369 static const choice precision[] =
371 { "24", 1},
372 { "53", 2},
373 { "64", 0},
374 { NULL, 0}
377 static const choice signal_choices[] =
379 { "IGNORE", 1},
380 { "ABORT", 0},
381 { NULL, 0}
385 static void
386 init_choice (variable * v, const choice * c)
388 char *p;
390 p = getenv (v->name);
391 if (p == NULL)
392 goto set_default;
394 for (; c->name; c++)
395 if (strcasecmp (c->name, p) == 0)
396 break;
398 if (c->name == NULL)
400 v->bad = 1;
401 goto set_default;
404 *v->var = c->value;
405 return;
407 set_default:
408 *v->var = v->value;
412 static void
413 show_choice (variable * v, const choice * c)
415 st_printf ("%s ", var_source (v));
417 for (; c->name; c++)
418 if (c->value == *v->var)
419 break;
421 if (c->name)
422 st_printf ("%s\n", c->name);
423 else
424 st_printf ("(Unknown)\n");
428 static void
429 init_round (variable * v)
431 init_choice (v, rounding);
434 static void
435 show_round (variable * v)
437 show_choice (v, rounding);
440 static void
441 init_precision (variable * v)
443 init_choice (v, precision);
446 static void
447 show_precision (variable * v)
449 show_choice (v, precision);
452 static void
453 init_signal (variable * v)
455 init_choice (v, signal_choices);
458 static void
459 show_signal (variable * v)
461 show_choice (v, signal_choices);
465 static variable variable_table[] = {
466 {"GFORTRAN_STDIN_UNIT", 5, &options.stdin_unit, init_integer, show_integer,
467 "Unit number that will be preconnected to standard input\n"
468 "(No preconnection if negative)", 0},
470 {"GFORTRAN_STDOUT_UNIT", 6, &options.stdout_unit, init_integer,
471 show_integer,
472 "Unit number that will be preconnected to standard output\n"
473 "(No preconnection if negative)", 0},
475 {"GFORTRAN_STDERR_UNIT", 0, &options.stderr_unit, init_integer,
476 show_integer,
477 "Unit number that will be preconnected to standard error\n"
478 "(No preconnection if negative)", 0},
480 {"GFORTRAN_USE_STDERR", 1, &options.use_stderr, init_boolean,
481 show_boolean,
482 "Sends library output to standard error instead of standard output.", 0},
484 {"GFORTRAN_TMPDIR", 0, NULL, init_string, show_string,
485 "Directory for scratch files. Overrides the TMP environment variable\n"
486 "If TMP is not set " DEFAULT_TEMPDIR " is used.", 0},
488 {"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean,
489 show_boolean,
490 "If TRUE, all output is unbuffered. This will slow down large writes "
491 "but can be\nuseful for forcing data to be displayed immediately.", 0},
493 {"GFORTRAN_SHOW_LOCUS", 1, &options.locus, init_boolean, show_boolean,
494 "If TRUE, print filename and line number where runtime errors happen.", 0},
496 {"GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean, show_boolean,
497 "Print optional plus signs in numbers where permitted. Default FALSE.", 0},
499 {"GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl,
500 init_unsigned_integer, show_integer,
501 "Default maximum record length for sequential files. Most useful for\n"
502 "adjusting line length of preconnected units. Default "
503 stringize (DEFAULT_RECL), 0},
505 {"GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep, show_sep,
506 "Separatator to use when writing list output. May contain any number of "
507 "spaces\nand at most one comma. Default is a single space.", 0},
509 /* Memory related controls */
511 {"GFORTRAN_MEM_INIT", 0, NULL, init_mem, show_mem,
512 "How to initialize allocated memory. Default value is NONE for no "
513 "initialization\n(faster), NAN for a Not-a-Number with the mantissa "
514 "0x40f95 or a custom\nhexadecimal value", 0},
516 {"GFORTRAN_MEM_CHECK", 0, &options.mem_check, init_boolean, show_boolean,
517 "Whether memory still allocated will be reported when the program ends.",
520 /* Signal handling (Unix). */
522 {"GFORTRAN_SIGHUP", 0, &options.sighup, init_signal, show_signal,
523 "Whether the program will IGNORE or ABORT on SIGHUP.", 0},
525 {"GFORTRAN_SIGINT", 0, &options.sigint, init_signal, show_signal,
526 "Whether the program will IGNORE or ABORT on SIGINT.", 0},
528 /* Floating point control */
530 {"GFORTRAN_FPU_ROUND", 0, &options.fpu_round, init_round, show_round,
531 "Set floating point rounding. Values are NEAREST, UP, DOWN, ZERO.", 0},
533 {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision, init_precision,
534 show_precision,
535 "Precision of intermediate results. Values are 24, 53 and 64.", 0},
537 /* GFORTRAN_CONVERT_UNIT - Set the default data conversion for
538 unformatted I/O. */
539 {"GFORTRAN_CONVERT_UNIT", 0, 0, init_unformatted, show_string,
540 "Set format for unformatted files", 0},
542 {NULL, 0, NULL, NULL, NULL, NULL, 0}
546 /* init_variables()-- Initialize most runtime variables from
547 * environment variables. */
549 void
550 init_variables (void)
552 variable *v;
554 for (v = variable_table; v->name; v++)
555 v->init (v);
559 /* check_buffered()-- Given an unit number n, determine if an override
560 * for the stream exists. Returns zero for unbuffered, one for
561 * buffered or two for not set. */
564 check_buffered (int n)
566 char name[22 + sizeof (n) * 3];
567 variable v;
568 int rv;
570 if (options.all_unbuffered)
571 return 0;
573 sprintf (name, "GFORTRAN_UNBUFFERED_%d", n);
575 v.name = name;
576 v.value = 2;
577 v.var = &rv;
579 init_boolean (&v);
581 return rv;
585 void
586 show_variables (void)
588 variable *v;
589 int n;
591 /* TODO: print version number. */
592 st_printf ("GNU Fortran 95 runtime library version "
593 "UNKNOWN" "\n\n");
595 st_printf ("Environment variables:\n");
596 st_printf ("----------------------\n");
598 for (v = variable_table; v->name; v++)
600 n = st_printf ("%s", v->name);
601 print_spaces (25 - n);
603 if (v->show == show_integer)
604 st_printf ("Integer ");
605 else if (v->show == show_boolean)
606 st_printf ("Boolean ");
607 else
608 st_printf ("String ");
610 v->show (v);
611 st_printf ("%s\n\n", v->desc);
614 /* System error codes */
616 st_printf ("\nRuntime error codes:");
617 st_printf ("\n--------------------\n");
619 for (n = ERROR_FIRST + 1; n < ERROR_LAST; n++)
620 if (n < 0 || n > 9)
621 st_printf ("%d %s\n", n, translate_error (n));
622 else
623 st_printf (" %d %s\n", n, translate_error (n));
625 st_printf ("\nCommand line arguments:\n");
626 st_printf (" --help Print this list\n");
628 /* st_printf(" --resume <dropfile> Resume program execution from dropfile\n"); */
630 sys_exit (0);
633 /* This is the handling of the GFORTRAN_CONVERT_UNITS environment variable.
634 It is called from environ.c to parse this variable, and from
635 open.c to determine if the user specified a default for an
636 unformatted file.
637 The syntax of the environment variable is, in bison grammar:
639 GFORTRAN_CONVERT_UNITS: mode | mode ';' exception ;
640 mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ;
641 exception: mode ':' unit_list | unit_list ;
642 unit_list: unit_spec | unit_list unit_spec ;
643 unit_spec: INTEGER | INTEGER '-' INTEGER ;
646 /* Defines for the tokens. Other valid tokens are ',', ':', '-'. */
649 #define NATIVE 257
650 #define SWAP 258
651 #define BIG 259
652 #define LITTLE 260
653 /* Some space for additional tokens later. */
654 #define INTEGER 273
655 #define END (-1)
656 #define ILLEGAL (-2)
658 typedef struct
660 int unit;
661 unit_convert conv;
662 } exception_t;
665 static char *p; /* Main character pointer for parsing. */
666 static char *lastpos; /* Auxiliary pointer, for backing up. */
667 static int unit_num; /* The last unit number read. */
668 static int unit_count; /* The number of units found. */
669 static int do_count; /* Parsing is done twice - first to count the number
670 of units, then to fill in the table. This
671 variable controls what to do. */
672 static exception_t *elist; /* The list of exceptions to the default. This is
673 sorted according to unit number. */
674 static int n_elist; /* Number of exceptions to the default. */
676 static unit_convert endian; /* Current endianness. */
678 static unit_convert def; /* Default as specified (if any). */
680 /* Search for a unit number, using a binary search. The
681 first argument is the unit number to search for. The second argument
682 is a pointer to an index.
683 If the unit number is found, the function returns 1, and the index
684 is that of the element.
685 If the unit number is not found, the function returns 0, and the
686 index is the one where the element would be inserted. */
688 static int
689 search_unit (int unit, int *ip)
691 int low, high, mid;
693 low = -1;
694 high = n_elist;
695 while (high - low > 1)
697 mid = (low + high) / 2;
698 if (unit <= elist[mid].unit)
699 high = mid;
700 else
701 low = mid;
703 *ip = high;
704 if (elist[high].unit == unit)
705 return 1;
706 else
707 return 0;
710 /* This matches a keyword. If it is found, return the token supplied,
711 otherwise return ILLEGAL. */
713 static int
714 match_word (const char *word, int tok)
716 int res;
718 if (strncasecmp (p, word, strlen (word)) == 0)
720 p += strlen (word);
721 res = tok;
723 else
724 res = ILLEGAL;
725 return res;
729 /* Match an integer and store its value in unit_num. This only works
730 if p actually points to the start of an integer. The caller has
731 to ensure this. */
733 static int
734 match_integer (void)
736 unit_num = 0;
737 while (isdigit (*p))
738 unit_num = unit_num * 10 + (*p++ - '0');
739 return INTEGER;
743 /* This reads the next token from the GFORTRAN_CONVERT_UNITS variable.
744 Returned values are the different tokens. */
746 static int
747 next_token (void)
749 int result;
751 lastpos = p;
752 switch (*p)
754 case '\0':
755 result = END;
756 break;
758 case ':':
759 case ',':
760 case '-':
761 case ';':
762 result = *p;
763 p++;
764 break;
766 case 'b':
767 case 'B':
768 result = match_word ("big_endian", BIG);
769 break;
771 case 'l':
772 case 'L':
773 result = match_word ("little_endian", LITTLE);
774 break;
776 case 'n':
777 case 'N':
778 result = match_word ("native", NATIVE);
779 break;
781 case 's':
782 case 'S':
783 result = match_word ("swap", SWAP);
784 break;
786 case '1': case '2': case '3': case '4': case '5':
787 case '6': case '7': case '8': case '9':
788 result = match_integer ();
789 break;
791 default:
792 result = ILLEGAL;
793 break;
795 return result;
798 /* Back up the last token by setting back the character pointer. */
800 static void
801 push_token (void)
803 p = lastpos;
806 /* This is called when a unit is identified. If do_count is nonzero,
807 increment the number of units by one. If do_count is zero,
808 put the unit into the table. */
810 static void
811 mark_single (int unit)
813 int i,j;
815 if (do_count)
817 unit_count++;
818 return;
820 if (search_unit (unit, &i))
822 elist[unit].conv = endian;
824 else
826 for (j=n_elist; j>=i; j--)
827 elist[j+1] = elist[j];
829 n_elist += 1;
830 elist[i].unit = unit;
831 elist[i].conv = endian;
835 /* This is called when a unit range is identified. If do_count is
836 nonzero, increase the number of units. If do_count is zero,
837 put the unit into the table. */
839 static void
840 mark_range (int unit1, int unit2)
842 int i;
843 if (do_count)
844 unit_count += abs (unit2 - unit1) + 1;
845 else
847 if (unit2 < unit1)
848 for (i=unit2; i<=unit1; i++)
849 mark_single (i);
850 else
851 for (i=unit1; i<=unit2; i++)
852 mark_single (i);
856 /* Parse the GFORTRAN_CONVERT_UNITS variable. This is called
857 twice, once to count the units and once to actually mark them in
858 the table. When counting, we don't check for double occurences
859 of units. */
861 static int
862 do_parse (void)
864 int tok, def;
865 int unit1;
866 int continue_ulist;
867 char *start;
869 unit_count = 0;
871 def = 0;
872 start = p;
874 /* Parse the string. First, let's look for a default. */
875 tok = next_token ();
876 switch (tok)
878 case NATIVE:
879 endian = CONVERT_NATIVE;
880 break;
882 case SWAP:
883 endian = CONVERT_SWAP;
884 break;
886 case BIG:
887 endian = CONVERT_BIG;
888 break;
890 case LITTLE:
891 endian = CONVERT_LITTLE;
892 break;
894 case INTEGER:
895 /* A leading digit means that we are looking at an exception.
896 Reset the position to the beginning, and continue processing
897 at the exception list. */
898 p = start;
899 goto exceptions;
900 break;
902 case END:
903 goto end;
904 break;
906 default:
907 goto error;
908 break;
911 tok = next_token ();
912 switch (tok)
914 case ';':
915 def = endian;
916 break;
918 case ':':
919 /* This isn't a default after all. Reset the position to the
920 beginning, and continue processing at the exception list. */
921 p = start;
922 goto exceptions;
923 break;
925 case END:
926 goto end;
927 break;
929 default:
930 goto error;
931 break;
934 exceptions:
936 /* Loop over all exceptions. */
937 while(1)
939 tok = next_token ();
940 switch (tok)
942 case LITTLE:
943 if (next_token () != ':')
944 goto error;
945 endian = CONVERT_LITTLE;
946 break;
948 case BIG:
949 if (next_token () != ':')
950 goto error;
951 endian = CONVERT_BIG;
952 break;
954 case INTEGER:
955 push_token ();
956 break;
958 case END:
959 goto end;
960 break;
962 default:
963 goto error;
964 break;
966 /* We arrive here when we want to parse a list of
967 numbers. */
968 continue_ulist = 1;
971 tok = next_token ();
972 if (tok != INTEGER)
973 goto error;
975 unit1 = unit_num;
976 tok = next_token ();
977 /* The number can be followed by a - and another number,
978 which means that this is a unit range, a comma
979 or a semicolon. */
980 if (tok == '-')
982 if (next_token () != INTEGER)
983 goto error;
985 mark_range (unit1, unit_num);
986 tok = next_token ();
987 if (tok == END)
988 goto end;
989 else if (tok == ';')
990 continue_ulist = 0;
991 else if (tok != ',')
992 goto error;
994 else
996 mark_single (unit1);
997 switch (tok)
999 case ';':
1000 continue_ulist = 0;
1001 break;
1003 case ',':
1004 break;
1006 case END:
1007 goto end;
1008 break;
1010 default:
1011 goto error;
1014 } while (continue_ulist);
1016 end:
1017 return 0;
1018 error:
1019 def = CONVERT_NONE;
1020 return -1;
1023 void init_unformatted (variable * v)
1025 char *val;
1026 val = getenv (v->name);
1027 def = CONVERT_NONE;
1028 n_elist = 0;
1030 if (val == NULL)
1031 return;
1032 do_count = 1;
1033 p = val;
1034 do_parse ();
1035 if (do_count <= 0)
1037 n_elist = 0;
1038 elist = NULL;
1040 else
1042 elist = get_mem (unit_count * sizeof (exception_t));
1043 do_count = 0;
1044 p = val;
1045 do_parse ();
1049 /* Get the default conversion for for an unformatted unit. */
1051 unit_convert
1052 get_unformatted_convert (int unit)
1054 int i;
1056 if (elist == NULL)
1057 return def;
1058 else if (search_unit (unit, &i))
1059 return elist[i].conv;
1060 else
1061 return def;