Home | History | Annotate | Line # | Download | only in intrinsics
      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