Skip to content

Conversation

awvwgk
Copy link
Member

@awvwgk awvwgk commented Dec 19, 2021

  • cleanup of stdlib_system module + documentation
  • new procedure get_argument to retrieve command line arguments in deferred length characters and string_type variables
  • new procedure get_variable to retrieve environment variables in deferred length characters and string_type variables
  • new procedure set_variable to write environment variables

@awvwgk awvwgk added topic: utilities containers, strings, files, OS/environment integration, unit testing, assertions, logging, ... reviewers needed This patch requires extra eyes labels Dec 19, 2021
@awvwgk
Copy link
Member Author

awvwgk commented Dec 19, 2021

Implementing this in Fortran seems not possible due to a long-standing bug (= feature) in GCC (see gcc#42954, gcc#55007). This also means the macro for sleep never worked. Only way forward seems to implement it in C directly.

@urbanjost
Copy link

I found I almost always wanted a default for an environment variable and that I often had an alternate variable to look at so I think having a default would be nice; and because a functional approach is so easily nestable maybe consider a function instead of a subroutine, which also eliminates some issues with whether the result is allocatable or fixed length. If it is a function with a default things like in system_getenv
are easier:

   program demo_system_getenv
   use M_system, only : ge=>system_getenv
   implicit none 
   character(len=:),allocatable :: TMPDIR,USER
   
      ! look first for USER then LOGNAME then USERNAME
      USER=ge('USER', ge('LOGNAME', ge('USERNAME', 'UNKNOWN')))

      TMPDIR= ge('TMPDIR', ge('TMP', ge('TEMPDIR', ge('TEMP', '/tmp'))))
      write(*,*)'favorite scratch area is ',TMPDIR 

   end program demo_system_getenv

@awvwgk
Copy link
Member Author

awvwgk commented Dec 21, 2021

Using a function sounds like a better idea, how do you handle the return status in this case? Also, do you have a good idea how to set variables?

@awvwgk awvwgk marked this pull request as draft December 21, 2021 22:54
@awvwgk awvwgk removed the reviewers needed This patch requires extra eyes label Dec 21, 2021
@urbanjost
Copy link

I actually just return a null string on error. I like functions to be pure, but you could return an optional parameter, but that is something I prefer to use a subroutine for; so the alternative would be a separate function that just returned an error code; sort of like having to check the allocation of a variable before allocating it, or testing for association. In practice I have found I rarely care about any error status; and if I did there is always the intrinsic itself for that case. In the M_system module there are procedures for setting environment variables but they only work on a POSIX platform; but it includes the routines for reading the environment table as well, which is handy for things like "show me all environment variable names starting with "FPM_" and for dumping the environment so you can restore it in a different process. I know there are equivalents on MS_WIndows but I very rarely use MSWindows except with WSL or CygWin so I have never made the routines work with MSWindows. I wonder if instead of always coming up against that if we should start a POSIX library for MSWIndows? It would not be trivial, but is obviously possible, as CygWin does it.

@urbanjost
Copy link

urbanjost commented Dec 21, 2021

Just about (maybe all) Fortran compilers seem to have common posix-like routines but I got tired of all the conditionals needed to use them when writing for multiple compilers; which resulted in M_system once the C interface was standardized; but I used to have wrappers for each compiler that normalized their versions of getenv, fstat, getcwd, ...; which was workable for the platforms I used. A horrible shame that got dropped from the standard; the PXF interface would have been a huge boon to Fortran but the only one I remember fully implementing it was Cray, which only had to do it for their own platform. Since we had a cray as a primary platform we converted a lot of codes to the PXF interface expecting it to become standard and were severely disappointed when everyone did not support it.

Just as an example, gfortran has quite a few related extensions that could be wrapped as a seed, as I think just about everyone has a (different) simiilar extension; sometimes requiring a USE statement; almost always a different syntax

• ABORT: Abort the program
• ACCESS: Checks file access modes
• ALARM: Set an alarm clock
• BACKTRACE: Show a backtrace
• CHDIR: Change working directory
• CHMOD: Change access permissions of files
• EXIT: Exit the program with status.
• FGET: Read a single character in stream mode from stdin
• FGETC: Read a single character in stream mode
• FREE: Memory de-allocation subroutine
• FSEEK: Low level file positioning subroutine
• FSTAT: Get file status
• FTELL: Current stream position
• GERROR: Get last system error message
• GETCWD: Get current working directory
• GETENV: Get an environmental variable
• GETGID: Group ID function
• GETLOG: Get login name
• GETPID: Process ID function
• GETUID: User ID function
• HOSTNM: Get system host name
• ISATTY: Whether a unit is a terminal device
• KILL: Send a signal to a process
• LINK: Create a hard link
• LSTAT: Get file status
• MALLOC: Dynamic memory allocation function
• PERROR: Print system error message
• RENAME: Rename a file
• SIGNAL: Signal handling subroutine (or function)
• SLEEP: Sleep for the specified number of seconds
• STAT: Get file status
• SYMLNK: Create a symbolic link
• TTYNAM: Get the name of a terminal device.
• UNLINK: Remove a file from the file system

Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. This sounds good to me.
Question: how to add tests for such procedures?

Comment on lines +39 to +43
program demo
use stdlib_system, only: sleep
implicit none
call sleep(150)
end program demo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
program demo
use stdlib_system, only: sleep
implicit none
call sleep(150)
end program demo
program demo_sleep
use stdlib_system, only: sleep
implicit none
call sleep(150)
end program demo_sleep

Comment on lines +78 to +84
program demo
use stdlib_system, only: get_argument
implicit none
character(len=:), allocatable :: prog
call get_argument(0, prog)
print '(a)', prog
end program demo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
program demo
use stdlib_system, only: get_argument
implicit none
character(len=:), allocatable :: prog
call get_argument(0, prog)
print '(a)', prog
end program demo
program demo_get_argument
use stdlib_system, only: get_argument
implicit none
character(len=:), allocatable :: prog
call get_argument(0, prog)
print '(a)', prog
end program demo_get_argument

This argument is `intent(out)`.


#### Examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#### Examples
#### Example

Comment on lines +121 to +127
program demo
use stdlib_system, only: get_variable
implicit none
character(len=:), allocatable :: home
call get_variable("HOME", home)
print '(a)', home
end program demo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
program demo
use stdlib_system, only: get_variable
implicit none
character(len=:), allocatable :: home
call get_variable("HOME", home)
print '(a)', home
end program demo
program demo_get_variable
use stdlib_system, only: get_variable
implicit none
character(len=:), allocatable :: home
call get_variable("HOME", home)
print '(a)', home
end program demo_get_variable

This argument is `intent(out)`.


#### Examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#### Examples
#### Example

Comment on lines +163 to +168
```fortran
program demo
use stdlib_system, only: set_variable
implicit none
call set_variable("OMP_NUM_THREADS", "1")
end program demo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```fortran
program demo
use stdlib_system, only: set_variable
implicit none
call set_variable("OMP_NUM_THREADS", "1")
end program demo
```fortran
program demo_set_variable
use stdlib_system, only: set_variable
implicit none
call set_variable("OMP_NUM_THREADS", "1")
end program demo_set_variable

@awvwgk
Copy link
Member Author

awvwgk commented Aug 4, 2022

Since the implementation of set_variable is still broken and I don't find a good way to fix it, I'll drop this patch for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: utilities containers, strings, files, OS/environment integration, unit testing, assertions, logging, ...
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants