1 1.1 mrg /* Implementation of the GETARG and IARGC g77, and 2 1.1 mrg corresponding F2003, intrinsics. 3 1.1.1.4 mrg Copyright (C) 2004-2024 Free Software Foundation, Inc. 4 1.1 mrg Contributed by Bud Davis and Janne Blomqvist. 5 1.1 mrg 6 1.1 mrg This file is part of the GNU Fortran 95 runtime library (libgfortran). 7 1.1 mrg 8 1.1 mrg Libgfortran is free software; you can redistribute it and/or 9 1.1 mrg modify it under the terms of the GNU General Public 10 1.1 mrg License as published by the Free Software Foundation; either 11 1.1 mrg version 3 of the License, or (at your option) any later version. 12 1.1 mrg 13 1.1 mrg Libgfortran is distributed in the hope that it will be useful, 14 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 mrg GNU General Public License for more details. 17 1.1 mrg 18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 19 1.1 mrg permissions described in the GCC Runtime Library Exception, version 20 1.1 mrg 3.1, as published by the Free Software Foundation. 21 1.1 mrg 22 1.1 mrg You should have received a copy of the GNU General Public License and 23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 1.1 mrg <http://www.gnu.org/licenses/>. */ 26 1.1 mrg 27 1.1 mrg #include "libgfortran.h" 28 1.1 mrg #include <string.h> 29 1.1 mrg 30 1.1 mrg 31 1.1 mrg /* Get a commandline argument. */ 32 1.1 mrg 33 1.1 mrg extern void getarg_i4 (GFC_INTEGER_4 *, char *, gfc_charlen_type); 34 1.1 mrg iexport_proto(getarg_i4); 35 1.1 mrg 36 1.1 mrg void 37 1.1 mrg getarg_i4 (GFC_INTEGER_4 *pos, char *val, gfc_charlen_type val_len) 38 1.1 mrg { 39 1.1 mrg int argc; 40 1.1 mrg char **argv; 41 1.1 mrg 42 1.1 mrg get_args (&argc, &argv); 43 1.1 mrg 44 1.1 mrg if (val_len < 1 || !val ) 45 1.1 mrg return; /* something is wrong , leave immediately */ 46 1.1 mrg 47 1.1 mrg memset (val, ' ', val_len); 48 1.1 mrg 49 1.1 mrg if ((*pos) + 1 <= argc && *pos >=0 ) 50 1.1 mrg { 51 1.1 mrg gfc_charlen_type arglen = strlen (argv[*pos]); 52 1.1 mrg if (arglen > val_len) 53 1.1 mrg arglen = val_len; 54 1.1 mrg memcpy (val, argv[*pos], arglen); 55 1.1 mrg } 56 1.1 mrg } 57 1.1 mrg iexport(getarg_i4); 58 1.1 mrg 59 1.1 mrg 60 1.1 mrg /* INTEGER*8 wrapper of getarg. */ 61 1.1 mrg 62 1.1 mrg extern void getarg_i8 (GFC_INTEGER_8 *, char *, gfc_charlen_type); 63 1.1 mrg export_proto (getarg_i8); 64 1.1 mrg 65 1.1 mrg void 66 1.1 mrg getarg_i8 (GFC_INTEGER_8 *pos, char *val, gfc_charlen_type val_len) 67 1.1 mrg { 68 1.1 mrg GFC_INTEGER_4 pos4 = (GFC_INTEGER_4) *pos; 69 1.1 mrg getarg_i4 (&pos4, val, val_len); 70 1.1 mrg } 71 1.1 mrg 72 1.1 mrg 73 1.1 mrg /* Return the number of commandline arguments. The g77 info page 74 1.1 mrg states that iargc does not include the specification of the 75 1.1 mrg program name itself. */ 76 1.1 mrg 77 1.1 mrg extern GFC_INTEGER_4 iargc (void); 78 1.1 mrg export_proto(iargc); 79 1.1 mrg 80 1.1 mrg GFC_INTEGER_4 81 1.1 mrg iargc (void) 82 1.1 mrg { 83 1.1 mrg int argc; 84 1.1 mrg char **argv; 85 1.1 mrg 86 1.1 mrg get_args (&argc, &argv); 87 1.1 mrg 88 1.1 mrg return (argc - 1); 89 1.1 mrg } 90 1.1 mrg 91 1.1 mrg 92 1.1 mrg /* F2003 intrinsic functions and subroutines related to command line 93 1.1 mrg arguments. 94 1.1 mrg 95 1.1 mrg - function command_argument_count() is converted to iargc by the compiler. 96 1.1 mrg 97 1.1 mrg - subroutine get_command([command, length, status]). 98 1.1 mrg 99 1.1 mrg - subroutine get_command_argument(number, [value, length, status]). 100 1.1 mrg */ 101 1.1 mrg 102 1.1 mrg /* These two status codes are specified in the standard. */ 103 1.1 mrg #define GFC_GC_SUCCESS 0 104 1.1 mrg #define GFC_GC_VALUE_TOO_SHORT -1 105 1.1 mrg 106 1.1 mrg /* Processor-specific status failure code. */ 107 1.1 mrg #define GFC_GC_FAILURE 42 108 1.1 mrg 109 1.1 mrg 110 1.1 mrg extern void get_command_argument_i4 (GFC_INTEGER_4 *, char *, GFC_INTEGER_4 *, 111 1.1 mrg GFC_INTEGER_4 *, gfc_charlen_type); 112 1.1 mrg iexport_proto(get_command_argument_i4); 113 1.1 mrg 114 1.1 mrg /* Get a single commandline argument. */ 115 1.1 mrg 116 1.1 mrg void 117 1.1 mrg get_command_argument_i4 (GFC_INTEGER_4 *number, char *value, 118 1.1 mrg GFC_INTEGER_4 *length, GFC_INTEGER_4 *status, 119 1.1 mrg gfc_charlen_type value_len) 120 1.1 mrg { 121 1.1 mrg int argc, stat_flag = GFC_GC_SUCCESS; 122 1.1 mrg gfc_charlen_type arglen = 0; 123 1.1 mrg char **argv; 124 1.1 mrg 125 1.1 mrg if (number == NULL ) 126 1.1 mrg /* Should never happen. */ 127 1.1 mrg runtime_error ("Missing argument to get_command_argument"); 128 1.1 mrg 129 1.1 mrg if (value == NULL && length == NULL && status == NULL) 130 1.1 mrg return; /* No need to do anything. */ 131 1.1 mrg 132 1.1 mrg get_args (&argc, &argv); 133 1.1 mrg 134 1.1 mrg if (*number < 0 || *number >= argc) 135 1.1 mrg stat_flag = GFC_GC_FAILURE; 136 1.1 mrg else 137 1.1 mrg arglen = strlen(argv[*number]); 138 1.1 mrg 139 1.1 mrg if (value != NULL) 140 1.1 mrg { 141 1.1 mrg if (value_len < 1) 142 1.1 mrg stat_flag = GFC_GC_FAILURE; 143 1.1 mrg else 144 1.1 mrg memset (value, ' ', value_len); 145 1.1 mrg } 146 1.1 mrg 147 1.1 mrg if (value != NULL && stat_flag != GFC_GC_FAILURE) 148 1.1 mrg { 149 1.1 mrg if (arglen > value_len) 150 1.1 mrg stat_flag = GFC_GC_VALUE_TOO_SHORT; 151 1.1 mrg 152 1.1 mrg memcpy (value, argv[*number], arglen <= value_len ? arglen : value_len); 153 1.1 mrg } 154 1.1 mrg 155 1.1 mrg if (length != NULL) 156 1.1 mrg *length = arglen; 157 1.1 mrg 158 1.1 mrg if (status != NULL) 159 1.1 mrg *status = stat_flag; 160 1.1 mrg } 161 1.1 mrg iexport(get_command_argument_i4); 162 1.1 mrg 163 1.1 mrg 164 1.1 mrg /* INTEGER*8 wrapper for get_command_argument. */ 165 1.1 mrg 166 1.1 mrg extern void get_command_argument_i8 (GFC_INTEGER_8 *, char *, GFC_INTEGER_8 *, 167 1.1 mrg GFC_INTEGER_8 *, gfc_charlen_type); 168 1.1 mrg export_proto(get_command_argument_i8); 169 1.1 mrg 170 1.1 mrg void 171 1.1 mrg get_command_argument_i8 (GFC_INTEGER_8 *number, char *value, 172 1.1 mrg GFC_INTEGER_8 *length, GFC_INTEGER_8 *status, 173 1.1 mrg gfc_charlen_type value_len) 174 1.1 mrg { 175 1.1 mrg GFC_INTEGER_4 number4; 176 1.1 mrg GFC_INTEGER_4 length4; 177 1.1 mrg GFC_INTEGER_4 status4; 178 1.1 mrg 179 1.1 mrg number4 = (GFC_INTEGER_4) *number; 180 1.1 mrg get_command_argument_i4 (&number4, value, &length4, &status4, value_len); 181 1.1 mrg if (length) 182 1.1 mrg *length = length4; 183 1.1 mrg if (status) 184 1.1 mrg *status = status4; 185 1.1 mrg } 186 1.1 mrg 187 1.1 mrg 188 1.1 mrg /* Return the whole commandline. */ 189 1.1 mrg 190 1.1 mrg extern void get_command_i4 (char *, GFC_INTEGER_4 *, GFC_INTEGER_4 *, 191 1.1 mrg gfc_charlen_type); 192 1.1 mrg iexport_proto(get_command_i4); 193 1.1 mrg 194 1.1 mrg void 195 1.1 mrg get_command_i4 (char *command, GFC_INTEGER_4 *length, GFC_INTEGER_4 *status, 196 1.1 mrg gfc_charlen_type command_len) 197 1.1 mrg { 198 1.1 mrg int i, argc, thisarg; 199 1.1 mrg int stat_flag = GFC_GC_SUCCESS; 200 1.1 mrg char **argv; 201 1.1 mrg gfc_charlen_type arglen, tot_len = 0; 202 1.1 mrg 203 1.1 mrg if (command == NULL && length == NULL && status == NULL) 204 1.1 mrg return; /* No need to do anything. */ 205 1.1 mrg 206 1.1 mrg get_args (&argc, &argv); 207 1.1 mrg 208 1.1 mrg if (command != NULL) 209 1.1 mrg { 210 1.1 mrg /* Initialize the string to blanks. */ 211 1.1 mrg if (command_len < 1) 212 1.1 mrg stat_flag = GFC_GC_FAILURE; 213 1.1 mrg else 214 1.1 mrg memset (command, ' ', command_len); 215 1.1 mrg } 216 1.1 mrg 217 1.1 mrg for (i = 0; i < argc ; i++) 218 1.1 mrg { 219 1.1 mrg arglen = strlen(argv[i]); 220 1.1 mrg 221 1.1 mrg if (command != NULL && stat_flag == GFC_GC_SUCCESS) 222 1.1 mrg { 223 1.1 mrg thisarg = arglen; 224 1.1 mrg if (tot_len + thisarg > command_len) 225 1.1 mrg { 226 1.1 mrg thisarg = command_len - tot_len; /* Truncate. */ 227 1.1 mrg stat_flag = GFC_GC_VALUE_TOO_SHORT; 228 1.1 mrg } 229 1.1 mrg /* Also a space before the next arg. */ 230 1.1 mrg else if (i != argc - 1 && tot_len + arglen == command_len) 231 1.1 mrg stat_flag = GFC_GC_VALUE_TOO_SHORT; 232 1.1 mrg 233 1.1 mrg memcpy (&command[tot_len], argv[i], thisarg); 234 1.1 mrg } 235 1.1 mrg 236 1.1 mrg /* Add the legth of the argument. */ 237 1.1 mrg tot_len += arglen; 238 1.1 mrg if (i != argc - 1) 239 1.1 mrg tot_len++; 240 1.1 mrg } 241 1.1 mrg 242 1.1 mrg if (length != NULL) 243 1.1 mrg *length = tot_len; 244 1.1 mrg 245 1.1 mrg if (status != NULL) 246 1.1 mrg *status = stat_flag; 247 1.1 mrg } 248 1.1 mrg iexport(get_command_i4); 249 1.1 mrg 250 1.1 mrg 251 1.1 mrg /* INTEGER*8 wrapper for get_command. */ 252 1.1 mrg 253 1.1 mrg extern void get_command_i8 (char *, GFC_INTEGER_8 *, GFC_INTEGER_8 *, 254 1.1 mrg gfc_charlen_type); 255 1.1 mrg export_proto(get_command_i8); 256 1.1 mrg 257 1.1 mrg void 258 1.1 mrg get_command_i8 (char *command, GFC_INTEGER_8 *length, GFC_INTEGER_8 *status, 259 1.1 mrg gfc_charlen_type command_len) 260 1.1 mrg { 261 1.1 mrg GFC_INTEGER_4 length4; 262 1.1 mrg GFC_INTEGER_4 status4; 263 1.1 mrg 264 1.1 mrg get_command_i4 (command, &length4, &status4, command_len); 265 1.1 mrg if (length) 266 1.1 mrg *length = length4; 267 1.1 mrg if (status) 268 1.1 mrg *status = status4; 269 1.1 mrg } 270