Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » And again about the return value of a program

Credits go to bamccaig and Mokkan for helping out!
This thread is locked; no one can reply to it. rss feed Print
And again about the return value of a program
Martin Kalbfuß
Member #9,131
October 2007
avatar

Because I didn't get an answer to last question about the return value of a program, I will try it again with this post. Maybe, the last one wasn't clear enough because I asked about the interaction with CMAKE. But that isn't realy important. Much more interesting is, if and how it's possible to process a returned value with the bash(linux) or the equivalents on other systems. Is there a standard way for all systems, or it different for everyone.

The bash script "allegro-config --static" for example, returns the needed headers to compile a static version of the program. This is done with echo. So I thought ist would work with printf. But it didn't. Maybe simply did it wrong. ???

The command to read the return value of a program in CMAKE is:
exec_program(Executeable ARGS arg1 VARIABLE)

Thanks

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

Mokkan
Member #4,355
February 2004
avatar

I think Linux (or just Bash?) sets the environmental variable $? to the return value of the last executed program, so you can mess with that.

Martin Kalbfuß
Member #9,131
October 2007
avatar

And what about windows, mac and dos? Do you know it, too?

Thanks

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

bamccaig
Member #7,536
July 2006
avatar

Martin Kalbfuß said:

The bash script "allegro-config --static" for example, returns the needed headers to compile a static version of the program. This is done with echo. So I thought ist would work with printf. But it didn't. Maybe simply did it wrong. ???

AFAIK, all major desktop platforms (Windows, Linux, Mac) only support integer (int) return types. :-/ I assume most, if not all, other Unix flavors do as well. So the return type is actually a number. allegro-config doesn't return the needed headers - it prints them. The back-quotes (``) are special characters to the bash shell and tell bash to execute the string between them as a separate command and replace the back-quoted string with the output. It's not a return value - it's output. If my recent readings are correct, it would also work to use $() on newer versions of bash, but using back-quotes gives your makefile better compatibility with older versions of bash... I don't know what other shells support this syntax. :-/

g++ files -o output ... `allegro-config ...`
g++ files -o output ... $(allegro-config ...)

For example, if you had the following scripts...

#!/bin/bash
# Name: foo.sh

@echo foo

#!/bin/bash
# Name: bar.sh

@echo $1

...and executed either of the following commands...

./bar.sh `./foo.sh`
./bar.sh $(./foo.sh)

...then the output should be...

foo

* These scripts are untested at the time of writing. They're based on my understanding of bash and I haven't done enough scripting to be confident yet. :P

Martin Kalbfuß
Member #9,131
October 2007
avatar

if I'm workin with the bash, both methods work. But with CMAKE, I can't get the value.

On the bash echo $? returns the return value of the main function. But $ENV(?) doesn't work,
exec_program returns an empty Variable and SET im combination with `./test` (That's the program) returns `./test`

The CMakeList.txt file:

exec_program(./test ARGS anything TESTVARIABLE)
MESSAGE( "${TESTVARIABLE}" )

SET(TESTVARIABLE `./test.c`)
MESSAGE( "${TESTVARIABLE}" )

MESSAGE( "$ENV{?}")

The output on executing "cmake ." :

running ./test anything TESTVARIABLE 2>&1

`./test.c`
Syntax error in cmake code at
/home/martin/Desktop/Test/CMakeLists.txt:7:
syntax error, unexpected cal_SYMBOL, expecting } (7), when parsing string "$ENV{?}"
$ENV{?}
-- Configuring done
-- Generating done
-- Build files have been written to: /home/martin/Desktop/Test

and thr test.c file:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{

printf("Hallo");

return EXIT_SUCCESS;

}

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

Audric
Member #907
January 2001

(unix) When passed to the shell, it's a signed character actually. You can only retrieve -128 to 127.

Martin Kalbfuß
Member #9,131
October 2007
avatar

Interresting. But why are you posting this? ??? I can't see any connections.

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

bamccaig
Member #7,536
July 2006
avatar

According to what I read briefly before leaving work, CMAKE uses its own language. It's completely separate from bash so bash syntax doesn't work with CMAKE.

CMake Cross Platform Make said:

  1. EXEC_PROGRAM: Run and executable program during the processing of the CMakeList.txt file.

  EXEC_PROGRAM(Executable [directory in which to run]
               [ARGS <arguments to executable>]
               [OUTPUT_VARIABLE <var>]
               [RETURN_VALUE <var>])

The executable is run in the optionally specified directory. The executable can include arguments if it is double quoted, but it is better to use the optional ARGS argument to specify arguments to the program. This is because cmake will then be able to escape spaces in the executable path. An optional argument OUTPUT_VARIABLE specifies a variable in which to store the output. To capture the return value of the execution, provide a RETURN_VALUE. If OUTPUT_VARIABLE is specified, then no output will go to the stdout/stderr of the console running cmake.

The EXECUTE_PROCESS command is a newer more powerful version of EXEC_PROGRAM, but the old command has been kept for compatibility.

- Source

My interpretation of that syntax map for your purposes is...
EXEC_PROGRAM("./test" OUTPUT_VARIABLE TESTVARIABLE)
In other words, OUTPUT_VARIABLE looks like a keyword that tells the interpreter that the next token is the output variable. To me, that makes better sense then having useless values for parameters you don't use, which appears to be what you did with ARGS. I apologize if I misinterpreted what you were trying to do.

Martin Kalbfuß said:

exec_program(./test ARGS anything TESTVARIABLE)

I'm completely new to CMAKE and I'm not familiar with the syntax though so I could be wrong.

CMake Cross Platform Make said:

  1. EXECUTE_PROCESS: Execute one or more child processes.

  EXECUTE_PROCESS(COMMAND <cmd1> [args1...]]
                  [COMMAND <cmd2> [args2...] [...]]
                  [WORKING_DIRECTORY <directory>]
                  [TIMEOUT <seconds>]
                  [RESULT_VARIABLE <variable>]
                  [OUTPUT_VARIABLE <variable>]
                  [ERROR_VARIABLE <variable>]
                  [INPUT_FILE <file>]
                  [OUTPUT_FILE <file>]
                  [ERROR_FILE <file>]
                  [OUTPUT_QUIET]
                  [ERROR_QUIET]
                  [OUTPUT_STRIP_TRAILING_WHITESPACE]
                  [ERROR_STRIP_TRAILING_WHITESPACE])

Runs the given sequence of one or more commands with the standard output of each process piped to the standard input of the next. A single standard error pipe is used for all processes. If WORKING_DIRECTORY is given the named directory will be set as the current working directory of the child processes. If TIMEOUT is given the child processes will be terminated if they do not finish in the specified number of seconds (fractions are allowed). If RESULT_VARIABLE is given the variable will be set to contain the result of running the processes. This will be an integer return code from the last child or a string describing an error condition. If OUTPUT_VARIABLE or ERROR_VARIABLE are given the variable named will be set with the contents of the standard output and standard error pipes respectively. If the same variable is named for both pipes their output will be merged in the order produced. If INPUT_FILE, OUTPUT_FILE, or ERROR_FILE is given the file named will be attached to the standard input of the first process, standard output of the last process, or standard error of all processes respectively. If OUTPUT_QUIET or ERROR_QUIET is given then the standard output or standard error results will be quietly ignored. If more than one OUTPUT_* or ERROR_* option is given for the same pipe the precedence is not specified. If no OUTPUT_* or ERROR_* options are given the output will be shared with the corresponding pipes of the CMake process itself.

The EXECUTE_PROCESS command is a newer more powerful version of EXEC_PROGRAM, but the old command has been kept for compatibility.

- Source

Apparently "EXECUTE_PROCESS is a newer more powerful version of EXEC_PROGRAM". :P My interpretation of the syntax map for your purposes is...
EXECUTE_PROCESS(COMMAND ./test OUTPUT_VARIABLE TESTVARIABLE)

Martin Kalbfuß
Member #9,131
October 2007
avatar

:D I did it.
And the mistake was ........ a missing \n in the printf. :o
I don't understand why this is needed! Strange.

My Syntax of EXEC_PROGRAM was wrong, too. :-X
Thank you for the correction,

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

Evert
Member #794
November 2000
avatar

Quote:

And the mistake was ........ a missing \n in the printf. :o
I don't understand why this is needed! Strange.

You need to flush stdout. An fflush(stdout) would probably have worked too.

Audric
Member #907
January 2001

Audric said:

(unix) When passed to the shell, it's a signed character actually. You can only retrieve -128 to 127.

Martin Kalbfuß said:

Interesting. But why are you posting this? ??? I can't see any connections.

It's only to warn you about that pitfall. If an executable ends by exit(1000), the return code caught by the OS/shell/cmake will actually be -104.

Go to: