I was under the impression C-style macro definitions work in gfortran?
#define ERROR_CHECKER(msg,stat) \
IF (stat.NE.0) THEN \
DO i = 1,BIG \
IF(msg(i).NE.C_NULL_CHAR)THEN \
ErrMsg(i:i) = msg(i) \
ELSE \
EXIT \
END IF \
END DO\
IF(stat.EQ.1) THEN \
ErrStat = ID_Warn \
ELSE \
ErrStat = ID_Fatal \
RETURN \
END IF \
END IF
But then this error ruins my day:
IF (stat.NE.0) THEN DO i = 1,BIG IF(message
1
Error: Cannot assign to a named constant at (1)
Any ideas what I am doing wrong here?
Secondary question: does intel fortran recognize c-style macros? If so, are compiler flags necessary?
Instead of using a macro, just convert the macro to a function. That way you don't have a massive dependency on the Fortran compiler having a macro facility
LOGICAL FUNCTION ERROR_CHECKER(msg,stat)
character*(*) msg(*)
integer stat
IF (stat.NE.0) THEN
DO i = 1,BIG
IF(msg(i).NE.C_NULL_CHAR)THEN
ErrMsg(i:i) = msg(i)
ELSE
EXIT
END IF
END DO
IF(stat.EQ.1) THEN
ErrStat = ID_Warn
ELSE
ErrStat = ID_Fatal
RETURN .FALSE.
END IF
END IF
RETURN .TRUE.
END FUNCTION
In your code
IF (ERROR_CHECKER(msg, stat)) RETURN
Edit: Some of the later versions of Fortran have statement separators (;) which can be used. Unfortunately, the line length is limited so your macro cannot be very long, nor can it contain more than one control structure.
Aside from the fact that such a macro approach is not good style, you are missing the necessary line breaks in the generated code. This can be fixed by putting a semicolon before each backslash in the macro definition (except the first line).
Related
I'm new to linux kernel development and wonder how wait_event/wait_event_interruptible interacts with other locking primitives in the kernel. I'm used to C++ std::condition_variable::wait and want to achieve something similar in the kernel.
I have a queue of receive buffers which are filled using DMA transfers. The list is protected using a spin lock. Finished buffers are added by the DMA finished soft IRQ. I created a character device which allows reading of the finished buffers. So far this works as expected but I want to support blocking reads.
I've read about wait_event which seems like what I want, but I'm really confused how wait_event does not take any lock/mutex parameter. How is evaluating the condition without holding a lock safe? I suppose I can add the necessary locking to my condition, but then I need to lock again once wait_event returns to extract the data. Is this already a case for prepare_to_wait/schedule/finish_wait?
Without digging to much into the source first I will say you should be using the wait_event library and you do not need mutex's or other such things the kernel is taking care of them. Personally I only have experience with wait_event_interruptible and wake_up_interruptible but I suspect they all are similar.
Now onto the source which I am pulling from https://elixir.bootlin.com/linux/latest/source/include/linux/wait.h#L302
#define ___wait_event(wq_head, condition, state, exclusive, ret, cmd) \
({ \
__label__ __out; \
struct wait_queue_entry __wq_entry; \
long __ret = ret; /* explicit shadow */ \
\
init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0); \
for (;;) { \
long __int = prepare_to_wait_event(&wq_head, &__wq_entry, state);\
\
if (condition) \
break; \
\
if (___wait_is_interruptible(state) && __int) { \
__ret = __int; \
goto __out; \
} \
\
cmd; \
} \
finish_wait(&wq_head, &__wq_entry); \
__out: __ret; \
})
long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
{
unsigned long flags;
long ret = 0;
spin_lock_irqsave(&wq_head->lock, flags);
....
spin_unlock_irqrestore(&wq_head->lock, flags);
return ret;
}
As can be seen the wait library is using spin_locks already which are similar to mutex's (although slightly different). The nice thing about using the wait library is that a lot of safety checks to keep the kernel happy and going are automatically performed for you but it still performs the necessary block on your data. If you need more of an example on using the wait_event_* and it's assosciated wake_up_* calls let me know and I can fetch one.
I have an issue in one of my functions in my code. I am new to Ruby, so I am unsure of where my syntax error is. My irb is giving me a syntax error related to my end keywords, but I believe the syntax is correct
def function1
print "function 1 \n"
print "Please type 4 lines \n"
i = 0
fptr = (File.new("myFile.txt", "w"))
while i < 4
line = gets
fptr.write(line "\n")
i++
end
fptr.close()
end
This function should print two output lines, open a txt file, take in 4 lines of user input, and write them to the said file.
The problem is that i++ is not valid Ruby. Use i += 1 instead.
While i'm trying to build gcc itself. İ faced with this strange error.
error was on aarch64.h
and also, i edited header code a bit before compilation
original header code:
#define PROFILE_HOOK(LABEL) \
{ \
rtx fun, lr; \
lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \
fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \
emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \
}
İ changed it to:
#define PROFILE_HOOK(LABEL) \
{ \
rtx fun, lr; \
if (!flag_fentry)
{ //error: expected unqualified-id before.. this line**************
lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \
fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \
emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \
} //error: expected unqualified-id before.... this line*************
}
and also i dont know if it makes any difference(color change) but before editing code, whole code looks purple. after editing code, lines below if (!flag_fentry) turned to black
im struggling with it for two days with no success
i really appreciate it if anyone help me.
thanx
regards
How can I expand wildcard commandline arguments in Julia?
The shell doesn't seem to expand them before they get there.
If I call my script as julia script.jl *.dat, my output is just *.dat
for arg in ARGS
println(arg)
end
If I write the equivalent program in Java:
public class rejig {
public static void main(String[] args) throws Exception {
for(int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
and call it as java rejig *.dat, I get a listing of all the DAT files in the current directory.
My searching along the lines of "command line", "wildcards", and the like hasn't got me very far.
How do I get Julia to give the same output as the Java code?
I wrote a pure-Julia implementation of Glob (aka fnmatch or wildcard commandline expansion) at https://github.com/vtjnash/Glob.jl, which also available via Pkg.add("Glob").
This can be used for platform-independent wildcard expansion, such as your *.dat example.
As explained in the comment, the shell is the program which expands the wildcards. This expansion is called glob expansion and there are functions in the standard C library which do it (and the shell probably uses itself).
Practically, here is an example of interfacing with the standard libc to expand wildcards:
type GlobType
pathc::Int64
names::Ptr{Ptr{UInt8}}
slots::Int64
extra1::Int64
extra2::Int64
end
function parseglob(gb::GlobType)
i=1
res = UTF8String[]
while i<=gb.pathc
p = unsafe_load(gb.names,i)
if p==C_NULL return res ; end
push!(res,bytestring(p))
i+=1
end
res
end
function glob(filepattern::AbstractString)
gb = GlobType(0,C_NULL,0,0,0)
retval = ccall((:glob,"libc"),Cint,
(Ptr{UInt8},Cint,Ptr{Void},Ptr{GlobType}),
filepattern,0,C_NULL,&gb)
res = ( retval==0 ? parseglob(gb) : UTF8String[] )
ccall((:globfree,"libc"),Void,(Ptr{GlobType},),&gb)
res
end
# glob("*.jl") # ["glob.jl"] on my machine
the library routine has many flags and options which might be of interest to you.
I work under a fortran program and have faced with a strange behaviour of "if" statement.
I have a module in the same file as the main program:
module platform
character (*) SLASH, NULLDEV, COPY_CMD, MKDIR_CMD
parameter (SLASH="\", COPY_CMD="cp -r ", NULLDEV="nul", MKDIR_CMD="mkdir")
!parameter (SLASH="/", COPY_CMD="cp ", NULLDEV="/dev/null", MKDIR_CMD="mkdir -p")
logical binary
parameter ( binary = .TRUE. )
!parameter ( binary = .FALSE. )
end module platform
And in the main program code below is the conditional statement:
...
use module platform
...
if ( .NOT. binary )
call system(MKDIR_CMD // ' ' // outdir //' 2>' // NULLDEV)
endif
The "binary" parameter is false. I checked it in debugger just in case. But program does not run the call!
But, if I modify the statement with adding an any operator above "call", for example:
if ( .NOT. binary ) then
a = 1
call system(MKDIR_CMD // ' ' // outdir //' 2>' // NULLDEV)
endif
All works!
UPD:
the 'outdir' is defined as:
character*255 ssadir, evname, outdir, evlst
...
call getarg(2, evname)
call getarg(3, outdir)
outdir = trim(outdir) // SLASH // trim(evname)