diff options
author | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-04 17:00:12 +0000 |
---|---|---|
committer | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-04 17:00:12 +0000 |
commit | 9b057c29eafcc5bc7bdfd77f387f3c2a9928fed5 (patch) | |
tree | bf14ee897d80e183e56fcc50abe726cd40989776 /libgfortran/intrinsics/args.c | |
parent | 0317cd3ecbaa21b3abce954ada012051d81d46b3 (diff) | |
download | gcc-9b057c29eafcc5bc7bdfd77f387f3c2a9928fed5.tar.gz |
PR fortran/15280
PR fortran/15665
* gfortran.h (enum gfc_generic_isym_id): Add GFC_ISYM_IARGC and
GFC_ISYM_COMMAND_ARGUMENT_COUNT.
* intrinsic.c (add_functions): Identify iargc. Add
command_argument_count.
(add_subroutines): Resolve getarg. Add get_command and
get_command_argument.
* intrinsic.h (gfc_resolve_getarg, gfc_resolve_get_command,
gfc_resolve_get_command_argument): Add prototypes.
* iresolve.c (gfc_resolve_getarg, gfc_resolve_get_command,
gfc_resolve_get_command_argument): New functions.
* trans-decl.c (gfor_fndecl_iargc): New variable.
(gfc_build_intrinsic_function_decls): Set it.
* trans-intrinsic.c (gfc_conv_intrinsic_iargc): New function.
(gfc_conv_intrinsic_function): Use it.
* trans.h (gfor_fndecl_iargc): Declare.
libgfortran/
* libgfortran.h (gfc_strlen_type): Define.
* intrinsics/args.c (getarg): Rename ...
(getarg_i4): ... to this.
(getarg_i8, get_command_argument_i4, get_command_argument_i8,
get_command_i4, get_command_i8): New functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84087 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/intrinsics/args.c')
-rw-r--r-- | libgfortran/intrinsics/args.c | 200 |
1 files changed, 196 insertions, 4 deletions
diff --git a/libgfortran/intrinsics/args.c b/libgfortran/intrinsics/args.c index da684fd99d4..caa55d46d8b 100644 --- a/libgfortran/intrinsics/args.c +++ b/libgfortran/intrinsics/args.c @@ -1,5 +1,7 @@ -/* Implementation of the IARG/ARGC intrinsic(s). +/* Implementation of the GETARG and IARGC g77, and + corresponding F2003, intrinsics. Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by Bud Davis and Janne Blomqvist. This file is part of the GNU Fortran 95 runtime library (libgfortran). @@ -23,8 +25,11 @@ Boston, MA 02111-1307, USA. */ #include <string.h> #include "libgfortran.h" + +/* Get a commandline argument. */ + void -prefix(getarg) (GFC_INTEGER_4 *pos, char *val, GFC_INTEGER_4 val_len) +prefix(getarg_i4) (GFC_INTEGER_4 *pos, char *val, gfc_strlen_type val_len) { int argc; int arglen; @@ -35,7 +40,7 @@ prefix(getarg) (GFC_INTEGER_4 *pos, char *val, GFC_INTEGER_4 val_len) if (val_len < 1 || !val ) return; /* something is wrong , leave immediately */ - memset( val, ' ', val_len); + memset (val, ' ', val_len); if ((*pos) + 1 <= argc && *pos >=0 ) { @@ -46,8 +51,23 @@ prefix(getarg) (GFC_INTEGER_4 *pos, char *val, GFC_INTEGER_4 val_len) } } + +/* INTEGER*8 wrapper of getarg. */ + +void +prefix(getarg_i8) (GFC_INTEGER_8 *pos, char *val, gfc_strlen_type val_len) +{ + GFC_INTEGER_4 pos4; + + pos4 = (GFC_INTEGER_4) *pos; + prefix(getarg_i4) (&pos4, val, val_len); +} + + +/* Return the number of commandline arguments. */ + GFC_INTEGER_4 -prefix(iargc) () +prefix(iargc) (void) { int argc; char **argv; @@ -56,3 +76,175 @@ prefix(iargc) () return argc; } + + +/* F2003 intrinsic functions and subroutines related to command line + arguments. + + - function command_argument_count() is converted to iargc by the compiler. + + - subroutine get_command([command, length, status]). + + - subroutine get_command_argument(number, [value, length, status]). +*/ + +/* These two status codes are specified in the standard. */ +#define GFC_GC_SUCCESS 0 +#define GFC_GC_VALUE_TOO_SHORT -1 + +/* Processor-specific status failure code. */ +#define GFC_GC_FAILURE 42 + + +/* Get a single commandline argument. */ + +void +prefix(get_command_argument_i4) (GFC_INTEGER_4 *number, + char *value, + GFC_INTEGER_4 *length, + GFC_INTEGER_4 *status, + gfc_strlen_type value_len) +{ + int argc, arglen = 0, stat_flag = GFC_GC_SUCCESS; + char **argv; + + if (number == NULL ) + /* Should never happen. */ + runtime_error ("Missing argument to get_command_argument"); + + if (value == NULL && length == NULL && status == NULL) + return; /* No need to do anything. */ + + get_args (&argc, &argv); + + if (*number < 0 || *number >= argc) + stat_flag = GFC_GC_FAILURE; + else + arglen = strlen(argv[*number]); + + if (value != NULL) + { + if (value_len < 1) + stat_flag = GFC_GC_FAILURE; + else + memset (value, ' ', value_len); + } + + if (value != NULL && stat_flag != GFC_GC_FAILURE) + { + if (arglen > value_len) + { + arglen = value_len; + stat_flag = GFC_GC_VALUE_TOO_SHORT; + } + memcpy (value, argv[*number], arglen); + } + + if (length != NULL) + *length = arglen; + + if (status != NULL) + *status = stat_flag; +} + + +/* INTEGER*8 wrapper for get_command_argument. */ + +void +prefix(get_command_argument_i8) (GFC_INTEGER_8 *number, + char *value, + GFC_INTEGER_8 *length, + GFC_INTEGER_8 *status, + gfc_strlen_type value_len) +{ + GFC_INTEGER_4 number4; + GFC_INTEGER_4 length4; + GFC_INTEGER_4 status4; + + number4 = (GFC_INTEGER_4) *number; + prefix (get_command_argument_i4) (&number4, value, &length4, &status4, + value_len); + if (length) + *length = length4; + if (status) + *status = status4; +} + + +/* Return the whole commandline. */ + +void +prefix(get_command_i4) (char *command, + GFC_INTEGER_4 *length, + GFC_INTEGER_4 *status, + gfc_strlen_type command_len) +{ + int i, argc, arglen, thisarg; + int stat_flag = GFC_GC_SUCCESS; + int tot_len = 0; + char **argv; + + if (command == NULL && length == NULL && status == NULL) + return; /* No need to do anything. */ + + get_args (&argc, &argv); + + if (command != NULL) + { + /* Initialize the string to blanks. */ + if (command_len < 1) + stat_flag = GFC_GC_FAILURE; + else + memset (command, ' ', command_len); + } + + for (i = 0; i < argc ; i++) + { + arglen = strlen(argv[i]); + + if (command != NULL && stat_flag == GFC_GC_SUCCESS) + { + thisarg = arglen; + if (tot_len + thisarg > command_len) + { + thisarg = command_len - tot_len; /* Truncate. */ + stat_flag = GFC_GC_VALUE_TOO_SHORT; + } + /* Also a space before the next arg. */ + else if (i != argc - 1 && tot_len + arglen == command_len) + stat_flag = GFC_GC_VALUE_TOO_SHORT; + + memcpy (&command[tot_len], argv[i], thisarg); + } + + /* Add the legth of the argument. */ + tot_len += arglen; + if (i != argc - 1) + tot_len++; + } + + if (length != NULL) + *length = tot_len; + + if (status != NULL) + *status = stat_flag; +} + + +/* INTEGER*8 wrapper for get_command. */ + +void +prefix(get_command_i8) (char *command, + GFC_INTEGER_8 *length, + GFC_INTEGER_8 *status, + gfc_strlen_type command_len) +{ + GFC_INTEGER_4 length4; + GFC_INTEGER_4 status4; + + prefix (get_command_i4) (command, &length4, &status4, command_len); + if (length) + *length = length4; + if (status) + *status = status4; +} |