Syntax error in INQUIRE(inpunit,flen=iflen) in gfortran but not in Lahey - file-io

I try to compile my code using gfortran. I got this error:
**INQUIRE(inpunit,flen=iflen)
1
Error: Syntax error in INQUIRE statement at (1)**
This code was compiled before with lahey. With a quick research I find that parameters of INQUIRE have different meaning in gfortran compared to lahey.
inpunit is a scalar INTEGER expression that evaluates to the
input/output unit number of an external file.
flen is a scalar default INTEGER variable having the length of the file in bytes.
My question is when using gfortran is this statement correct to get the same functionality as in Lahey:
**INQUIRE(inpunit,RECL=iflen) **
Are these two statements similar?
Thanks

No, these two are completely different.
flen= is a nonstandard extension specific to the Leahy compiler and returns the length of the file.
recl= is the maximum record length in the file (if the file is connected - opened, otherwise it is 0) https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-inquire-recl-specifier
To be standard conforming you should use size=. Be aware that the result will be in file storage units. Gfortran uses bytes, but other compilers may use 4-byte words.
See What is a good way to get file size in bytes using Fortran (ifort)? Find input file size in fortran90

Related

Raku-native disk space usage

Purpose:
Save a program that writes data to disk from vain attempts of writing to a full filesystem;
Save bandwidth (don't download if nowhere to store);
Save user's and programmer's time and nerves (notify them of the problem instead of having them tearing out their hair with reading misleading error messages and "why the heck this software is not working!").
The question comes in 2 parts:
Reporting storage space statistics (available, used, total etc.), either of all filesystems or of the filesystem that path in question belongs to.
Reporting a filesystem error on running out of space.
Part 1
Share please NATIVE Raku alternative(s) (TIMTOWTDIBSCINABTE "Tim Toady Bicarbonate") to:
raku -e 'qqx{ df -P $*CWD }.print'
Here, raku -executes df (disk free) external program via shell quoting with interpolation qqx{}, feeding -Portable-format argument and $*CWD Current Working Directory, then .prints the df's output.
The snippet initially had been written as raku -e 'qqx{ df -hP $*CWD }.print' — with both -human-readable and -Portable — but it turned out that it is not a ubiquitously valid command. In OpenBSD 7.0, it exits with an error: df: -h and -i are incompatible with -P.
For adding human-readability, you may consider Number::Bytes::Human module
raku -e 'run <<df -hP $*CWD>>'
If you're just outputting what df gives you on STDOUT, you don't need to do anything.
The << >> are double quoting words, so that the $*CWD will be interpolated.
Part 1 — Reporting storage space statistics
There's no built in function for reporting storage space statistics. Options include:
Write Raku code (a few lines) that uses NativeCall to invoke a platform / filesystem specific system call (such as statvfs()) and uses the information returned by that call.
Use a suitable Raku library. FileSystem::Capacity picks and runs an external program for you, and then makes its resulting data available in a portable form.
Use run (or similar1) to invoke a specific external program such as df.
Use an Inline::* foreign language adaptor to enable invoking of a foreign PL's solution for reporting storage space statistics, and use the info it provides.2
Part 2 — Reporting running out of space
Raku seems to neatly report No space left on device:
> spurt '/tmp/failwrite', 'filesystem is full!'
Failed to write bytes to filehandle: No space left on device
in block <unit> at <unknown file> line 1
> mkdir '/tmp/failmkdir'
Failed to create directory '/tmp/failmkdir' with mode '0o777': Failed to mkdir: No space left on device
in block <unit> at <unknown file> line 1
(Programmers will need to avoid throwing away these exceptions.)
Footnotes
1 run runs an external command without involving a shell. This guarantees that the risks attendant with involving a shell are eliminated. That said, Raku also supports use of a shell (because that can be convenient and appropriate in some scenarios). See the exchange of comments under the question (eg this one) for some brief discussion of this, and the shell doc for a summary of the risk:
All shell metacharacters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on. Shell escapes are a severe security concern and can cause confusion with unusual file names. Use run if you want to be safe.
2 Foreign language adaptors for Raku (Raku modules in the Inline:: namespace) allow Raku code to use code written in other languages. These adaptors are not part of the Raku language standard, and most are barely experimental status, if that, but, conversely, the best are in great shape and allow Raku code to use foreign libraries as if they were written for Raku. (As of 2021 Inline::Perl5 is the most polished.)

TypeError: 'str' does not support the buffer interface in python

I'm having this error in a python script:
TypeError: 'str' does not support the buffer interface
The line that is generating the error is
username = cred_file.readlines()[0].split(';')[0]
I'm a python beginner, any help is appreciated.
You're running a python 2 script with python 3. Python 3 now returns bytes no longer str when reading from a binary stream.
3 choices:
run it with python 2. That if you don't have the rights/time to adapt the script, not recommended as python 3 is becoming more and more the norm.
change your code to insert a decode function (it will continue to work in python 2):
username = cred_file.readlines()[0].decode().split(';')[0]
If file is opened in read/binary mode, readlines returns a list of bytes not str. You have do decode the bytes into a str to apply str methods.
open the file in "r" instead of "rb". readlines then returns a list of str and your code will work. Sometimes it can be problematic on windows because of need to preserve the carriage return (\r) chars, so look out for side effects in your code.
Note: cred_file.readlines()[0] is a questionable construction: you're reading the whole file lines, and drop all the lines but the first. Not very efficient I/O and CPU wise.
Prefer that: cred_file.readline() which is equivalent to read the first line.
If you need to read all the lines for further processing, then store the result of readlines in a list.

Determining symbol addresses using binutils/readelf

I am working on a project where our verification test scripts need to locate symbol addresses within the build of software being tested. This might be used for setting breakpoints or reading static data from memory. What I am after is to create a map file containing symbol names, base address in memory, and size. Our build outputs an ELF file which has the information I want. I've been trying to use the readelf, nm, and objdump tools to try and to gain the symbol addresses I need.
I originally tried readelf -s file.elf and that seemed to access some symbols, particularly those which were written in assembler. However, many of the symbols that I wanted were not in there - specifically those that originated within our Ada code.
I used readelf --debug-dump file.elf to dump all debug information. From that I do see all symbols, including those that were in the Ada code. However, the format seems to be in the DWARF format. Does anyone know why these symbols would not be output by readelf when I ask it to list the symbolic information? Perhaps there is simply an option I am missing.
Now I could go to the trouble of writing a custom DWARF parser to get the information but if I can get it using one of the Binutils (nm, readelf, objdump) then I'd really like prefer a standard solution.
DWARF is the debug information and tries to reflect the relation of the original source code. Taking following code as an example
static int one() {
// something
return 1;
}
int main(int ac, char **av) {
return one();
}
After you compile it using gcc -O3 -g, the static function one will be inlined into main. So when you use readelf -s, you will never see the symbol one. However, when you use readelf --debug-dump, you can see one is a function which is inlined.
So, in this example, compiler does not prohibit you use optimization with -g, so you can still debug the executable. In that example, even the function is optimized and inlined, gdb still can use DWARF information to know the function and source/line from current code block inside inlined function.
Above is just a case of compiler optimization. There might be plenty of reasons that could lead to mismatch symbols address between readelf -s and DWARF.

Trying to read in a .gda file to IDL

I am trying to read in a .gda file into IDL for plotting purposes. I am not familiar with the format and my research indicates it is an unformatted binary data file type. Anyways, here is what I am doing:
pro omidi_contour
openr, 1, 'data.gda'
a = fltarr(128,128,128)
readu, 1, a
close, 1
end
However when I look at the variable definition at the left panel of IDL, it indicates that a is 'undefined'. When I try to print:
print, a[0,0,0]
I get:
Variable is undefined: A
How can I solve this?
I found out that there was nothing wrong with my program. It was reading the right values from the file. However, the IDL "forgot" the value of the variables once the program was done. Solution: DO not run this as a program i.e. remove the following lines:
pro omidi_contour
end
This makes the code to run as if each line were typed into the IDL prompt and IDL does remember the values this time round.

program to reproduce itself and be useful -- not a quine

I have a program which performs a useful task. Now I want to produce the plain-text source code when the compiled executable runs, in addition to performing the original task. This is not a quine, but is probably related.
This capability would be useful in general, but my specific program is written in Fortran 90 and uses Mako Templates. When compiled it has access to the original source code files, but I want to be able to ensure that the source exists when a user runs the executable.
Is this possible to accomplish?
Here is an example of a simple Fortran 90 which does a simple task.
program exampl
implicit none
write(*,*) 'this is my useful output'
end program exampl
Can this program be modified such that it performs the same task (outputs a string when compiled) and outputs a Fortran 90 text file containing the source?
Thanks in advance
It's been so long since I have touched Fortran (and I've never dealt with Fortran 90) that I'm not certain but I see a basic approach that should work so long as the language supports string literals in the code.
Include your entire program inside itself in a block of literals. Obviously you can't include the literals within this, instead you need some sort of token that tells your program to include the block of literals.
Obviously this means you have two copies of the source, one inside the other. As this is ugly I wouldn't do it that way, but rather store your source with the include_me token in it and run it through a program that builds the nested files before you compile it. Note that this program will share a decent amount of code with the routine that recreates the code from the block of literals. If you're going to go this route I would also make the program spit out the source for this program so whoever is trying to modify the files doesn't need to deal with the two copies.
My original program (see question) is edited: add an include statement
Call this file "exampl.f90"
program exampl
implicit none
write(*,*) "this is my useful output"
open(unit=2,file="exampl_out.f90")
include "exampl_source.f90"
close(2)
end program exampl
Then another program (written in Python in this case) reads that source
import os
f=open('exampl.f90') # read in exampl.f90
g=open('exampl_source.f90','w') # and replace each line with write(*,*) 'line'
for line in f:
#print 'write(2,*) \''+line.rstrip()+'\'\n',
g.write('write(2,*) \''+line.rstrip()+'\'\n')
f.close
g.close
# then complie exampl.f90 (which includes exampl_source.f90)
os.system('gfortran exampl.f90')
os.system('/bin/rm exampl_source.f90')
Running this python script produces an executable. When the executable is run, it performs the original task AND prints the source code.