Merge from the pain train
[official-gcc.git] / libgfortran / intrinsics / args.c
blob72f1b987c87b81d529a1cb8955c5a84e4fae676a
1 /* Implementation of the GETARG and IARGC g77, and
2 corresponding F2003, intrinsics.
3 Copyright (C) 2004, 2005 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 2 of the License, or (at your option) any later version.
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
22 Libgfortran is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public
28 License along with libgfortran; see the file COPYING. If not,
29 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA. */
32 #include "config.h"
33 #include <sys/types.h>
34 #include <string.h>
35 #include "libgfortran.h"
38 /* Get a commandline argument. */
40 extern void getarg_i4 (GFC_INTEGER_4 *, char *, gfc_charlen_type);
41 iexport_proto(getarg_i4);
43 void
44 getarg_i4 (GFC_INTEGER_4 *pos, char *val, gfc_charlen_type val_len)
46 int argc;
47 int arglen;
48 char **argv;
50 get_args (&argc, &argv);
52 if (val_len < 1 || !val )
53 return; /* something is wrong , leave immediately */
55 memset (val, ' ', val_len);
57 if ((*pos) + 1 <= argc && *pos >=0 )
59 arglen = strlen (argv[*pos]);
60 if (arglen > val_len)
61 arglen = val_len;
62 memcpy (val, argv[*pos], arglen);
65 iexport(getarg_i4);
68 /* INTEGER*8 wrapper of getarg. */
70 extern void getarg_i8 (GFC_INTEGER_8 *, char *, gfc_charlen_type);
71 export_proto (getarg_i8);
73 void
74 getarg_i8 (GFC_INTEGER_8 *pos, char *val, gfc_charlen_type val_len)
76 GFC_INTEGER_4 pos4 = (GFC_INTEGER_4) *pos;
77 getarg_i4 (&pos4, val, val_len);
81 /* Return the number of commandline arguments. The g77 info page
82 states that iargc does not include the specification of the
83 program name itself. */
85 extern GFC_INTEGER_4 iargc (void);
86 export_proto(iargc);
88 GFC_INTEGER_4
89 iargc (void)
91 int argc;
92 char **argv;
94 get_args (&argc, &argv);
96 return (argc - 1);
100 /* F2003 intrinsic functions and subroutines related to command line
101 arguments.
103 - function command_argument_count() is converted to iargc by the compiler.
105 - subroutine get_command([command, length, status]).
107 - subroutine get_command_argument(number, [value, length, status]).
110 /* These two status codes are specified in the standard. */
111 #define GFC_GC_SUCCESS 0
112 #define GFC_GC_VALUE_TOO_SHORT -1
114 /* Processor-specific status failure code. */
115 #define GFC_GC_FAILURE 42
118 extern void get_command_argument_i4 (GFC_INTEGER_4 *, char *, GFC_INTEGER_4 *,
119 GFC_INTEGER_4 *, gfc_charlen_type);
120 iexport_proto(get_command_argument_i4);
122 /* Get a single commandline argument. */
124 void
125 get_command_argument_i4 (GFC_INTEGER_4 *number, char *value,
126 GFC_INTEGER_4 *length, GFC_INTEGER_4 *status,
127 gfc_charlen_type value_len)
129 int argc, arglen = 0, stat_flag = GFC_GC_SUCCESS;
130 char **argv;
132 if (number == NULL )
133 /* Should never happen. */
134 runtime_error ("Missing argument to get_command_argument");
136 if (value == NULL && length == NULL && status == NULL)
137 return; /* No need to do anything. */
139 get_args (&argc, &argv);
141 if (*number < 0 || *number >= argc)
142 stat_flag = GFC_GC_FAILURE;
143 else
144 arglen = strlen(argv[*number]);
146 if (value != NULL)
148 if (value_len < 1)
149 stat_flag = GFC_GC_FAILURE;
150 else
151 memset (value, ' ', value_len);
154 if (value != NULL && stat_flag != GFC_GC_FAILURE)
156 if (arglen > value_len)
158 arglen = value_len;
159 stat_flag = GFC_GC_VALUE_TOO_SHORT;
161 memcpy (value, argv[*number], arglen);
164 if (length != NULL)
165 *length = arglen;
167 if (status != NULL)
168 *status = stat_flag;
170 iexport(get_command_argument_i4);
173 /* INTEGER*8 wrapper for get_command_argument. */
175 extern void get_command_argument_i8 (GFC_INTEGER_8 *, char *, GFC_INTEGER_8 *,
176 GFC_INTEGER_8 *, gfc_charlen_type);
177 export_proto(get_command_argument_i8);
179 void
180 get_command_argument_i8 (GFC_INTEGER_8 *number, char *value,
181 GFC_INTEGER_8 *length, GFC_INTEGER_8 *status,
182 gfc_charlen_type value_len)
184 GFC_INTEGER_4 number4;
185 GFC_INTEGER_4 length4;
186 GFC_INTEGER_4 status4;
188 number4 = (GFC_INTEGER_4) *number;
189 get_command_argument_i4 (&number4, value, &length4, &status4, value_len);
190 if (length)
191 *length = length4;
192 if (status)
193 *status = status4;
197 /* Return the whole commandline. */
199 extern void get_command_i4 (char *, GFC_INTEGER_4 *, GFC_INTEGER_4 *,
200 gfc_charlen_type);
201 iexport_proto(get_command_i4);
203 void
204 get_command_i4 (char *command, GFC_INTEGER_4 *length, GFC_INTEGER_4 *status,
205 gfc_charlen_type command_len)
207 int i, argc, arglen, thisarg;
208 int stat_flag = GFC_GC_SUCCESS;
209 int tot_len = 0;
210 char **argv;
212 if (command == NULL && length == NULL && status == NULL)
213 return; /* No need to do anything. */
215 get_args (&argc, &argv);
217 if (command != NULL)
219 /* Initialize the string to blanks. */
220 if (command_len < 1)
221 stat_flag = GFC_GC_FAILURE;
222 else
223 memset (command, ' ', command_len);
226 for (i = 0; i < argc ; i++)
228 arglen = strlen(argv[i]);
230 if (command != NULL && stat_flag == GFC_GC_SUCCESS)
232 thisarg = arglen;
233 if (tot_len + thisarg > command_len)
235 thisarg = command_len - tot_len; /* Truncate. */
236 stat_flag = GFC_GC_VALUE_TOO_SHORT;
238 /* Also a space before the next arg. */
239 else if (i != argc - 1 && tot_len + arglen == command_len)
240 stat_flag = GFC_GC_VALUE_TOO_SHORT;
242 memcpy (&command[tot_len], argv[i], thisarg);
245 /* Add the legth of the argument. */
246 tot_len += arglen;
247 if (i != argc - 1)
248 tot_len++;
251 if (length != NULL)
252 *length = tot_len;
254 if (status != NULL)
255 *status = stat_flag;
257 iexport(get_command_i4);
260 /* INTEGER*8 wrapper for get_command. */
262 extern void get_command_i8 (char *, GFC_INTEGER_8 *, GFC_INTEGER_8 *,
263 gfc_charlen_type);
264 export_proto(get_command_i8);
266 void
267 get_command_i8 (char *command, GFC_INTEGER_8 *length, GFC_INTEGER_8 *status,
268 gfc_charlen_type command_len)
270 GFC_INTEGER_4 length4;
271 GFC_INTEGER_4 status4;
273 get_command_i4 (command, &length4, &status4, command_len);
274 if (length)
275 *length = length4;
276 if (status)
277 *status = status4;