re PR middle-end/40026 (ICE during gimplify_init_constructor)
[official-gcc.git] / libgfortran / intrinsics / args.c
blob7187beccb74af89eda34c4c5d2a9f63f50976692
1 /* Implementation of the GETARG and IARGC g77, and
2 corresponding F2003, intrinsics.
3 Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
4 Contributed by Bud Davis and Janne Blomqvist.
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "libgfortran.h"
28 #include <string.h>
31 /* Get a commandline argument. */
33 extern void getarg_i4 (GFC_INTEGER_4 *, char *, gfc_charlen_type);
34 iexport_proto(getarg_i4);
36 void
37 getarg_i4 (GFC_INTEGER_4 *pos, char *val, gfc_charlen_type val_len)
39 int argc;
40 int arglen;
41 char **argv;
43 get_args (&argc, &argv);
45 if (val_len < 1 || !val )
46 return; /* something is wrong , leave immediately */
48 memset (val, ' ', val_len);
50 if ((*pos) + 1 <= argc && *pos >=0 )
52 arglen = strlen (argv[*pos]);
53 if (arglen > val_len)
54 arglen = val_len;
55 memcpy (val, argv[*pos], arglen);
58 iexport(getarg_i4);
61 /* INTEGER*8 wrapper of getarg. */
63 extern void getarg_i8 (GFC_INTEGER_8 *, char *, gfc_charlen_type);
64 export_proto (getarg_i8);
66 void
67 getarg_i8 (GFC_INTEGER_8 *pos, char *val, gfc_charlen_type val_len)
69 GFC_INTEGER_4 pos4 = (GFC_INTEGER_4) *pos;
70 getarg_i4 (&pos4, val, val_len);
74 /* Return the number of commandline arguments. The g77 info page
75 states that iargc does not include the specification of the
76 program name itself. */
78 extern GFC_INTEGER_4 iargc (void);
79 export_proto(iargc);
81 GFC_INTEGER_4
82 iargc (void)
84 int argc;
85 char **argv;
87 get_args (&argc, &argv);
89 return (argc - 1);
93 /* F2003 intrinsic functions and subroutines related to command line
94 arguments.
96 - function command_argument_count() is converted to iargc by the compiler.
98 - subroutine get_command([command, length, status]).
100 - subroutine get_command_argument(number, [value, length, status]).
103 /* These two status codes are specified in the standard. */
104 #define GFC_GC_SUCCESS 0
105 #define GFC_GC_VALUE_TOO_SHORT -1
107 /* Processor-specific status failure code. */
108 #define GFC_GC_FAILURE 42
111 extern void get_command_argument_i4 (GFC_INTEGER_4 *, char *, GFC_INTEGER_4 *,
112 GFC_INTEGER_4 *, gfc_charlen_type);
113 iexport_proto(get_command_argument_i4);
115 /* Get a single commandline argument. */
117 void
118 get_command_argument_i4 (GFC_INTEGER_4 *number, char *value,
119 GFC_INTEGER_4 *length, GFC_INTEGER_4 *status,
120 gfc_charlen_type value_len)
122 int argc, arglen = 0, stat_flag = GFC_GC_SUCCESS;
123 char **argv;
125 if (number == NULL )
126 /* Should never happen. */
127 runtime_error ("Missing argument to get_command_argument");
129 if (value == NULL && length == NULL && status == NULL)
130 return; /* No need to do anything. */
132 get_args (&argc, &argv);
134 if (*number < 0 || *number >= argc)
135 stat_flag = GFC_GC_FAILURE;
136 else
137 arglen = strlen(argv[*number]);
139 if (value != NULL)
141 if (value_len < 1)
142 stat_flag = GFC_GC_FAILURE;
143 else
144 memset (value, ' ', value_len);
147 if (value != NULL && stat_flag != GFC_GC_FAILURE)
149 if (arglen > value_len)
151 arglen = value_len;
152 stat_flag = GFC_GC_VALUE_TOO_SHORT;
154 memcpy (value, argv[*number], arglen);
157 if (length != NULL)
158 *length = arglen;
160 if (status != NULL)
161 *status = stat_flag;
163 iexport(get_command_argument_i4);
166 /* INTEGER*8 wrapper for get_command_argument. */
168 extern void get_command_argument_i8 (GFC_INTEGER_8 *, char *, GFC_INTEGER_8 *,
169 GFC_INTEGER_8 *, gfc_charlen_type);
170 export_proto(get_command_argument_i8);
172 void
173 get_command_argument_i8 (GFC_INTEGER_8 *number, char *value,
174 GFC_INTEGER_8 *length, GFC_INTEGER_8 *status,
175 gfc_charlen_type value_len)
177 GFC_INTEGER_4 number4;
178 GFC_INTEGER_4 length4;
179 GFC_INTEGER_4 status4;
181 number4 = (GFC_INTEGER_4) *number;
182 get_command_argument_i4 (&number4, value, &length4, &status4, value_len);
183 if (length)
184 *length = length4;
185 if (status)
186 *status = status4;
190 /* Return the whole commandline. */
192 extern void get_command_i4 (char *, GFC_INTEGER_4 *, GFC_INTEGER_4 *,
193 gfc_charlen_type);
194 iexport_proto(get_command_i4);
196 void
197 get_command_i4 (char *command, GFC_INTEGER_4 *length, GFC_INTEGER_4 *status,
198 gfc_charlen_type command_len)
200 int i, argc, arglen, thisarg;
201 int stat_flag = GFC_GC_SUCCESS;
202 int tot_len = 0;
203 char **argv;
205 if (command == NULL && length == NULL && status == NULL)
206 return; /* No need to do anything. */
208 get_args (&argc, &argv);
210 if (command != NULL)
212 /* Initialize the string to blanks. */
213 if (command_len < 1)
214 stat_flag = GFC_GC_FAILURE;
215 else
216 memset (command, ' ', command_len);
219 for (i = 0; i < argc ; i++)
221 arglen = strlen(argv[i]);
223 if (command != NULL && stat_flag == GFC_GC_SUCCESS)
225 thisarg = arglen;
226 if (tot_len + thisarg > command_len)
228 thisarg = command_len - tot_len; /* Truncate. */
229 stat_flag = GFC_GC_VALUE_TOO_SHORT;
231 /* Also a space before the next arg. */
232 else if (i != argc - 1 && tot_len + arglen == command_len)
233 stat_flag = GFC_GC_VALUE_TOO_SHORT;
235 memcpy (&command[tot_len], argv[i], thisarg);
238 /* Add the legth of the argument. */
239 tot_len += arglen;
240 if (i != argc - 1)
241 tot_len++;
244 if (length != NULL)
245 *length = tot_len;
247 if (status != NULL)
248 *status = stat_flag;
250 iexport(get_command_i4);
253 /* INTEGER*8 wrapper for get_command. */
255 extern void get_command_i8 (char *, GFC_INTEGER_8 *, GFC_INTEGER_8 *,
256 gfc_charlen_type);
257 export_proto(get_command_i8);
259 void
260 get_command_i8 (char *command, GFC_INTEGER_8 *length, GFC_INTEGER_8 *status,
261 gfc_charlen_type command_len)
263 GFC_INTEGER_4 length4;
264 GFC_INTEGER_4 status4;
266 get_command_i4 (command, &length4, &status4, command_len);
267 if (length)
268 *length = length4;
269 if (status)
270 *status = status4;