> Earlier in this discussion of a testsuite, the question came up about
> generating an error return in COBOL source code.
>
> In COBOL, "GOBACK ERROR 1." is the equivalent of a C "return 1;".
> When executed in the initial "top-level" program-id, it results in
> the value 1 being passed back to the _start stub.
>
> "STOP RUN ERROR 1." is the equivalent of (and is in fact implemented
> with) "exit(1)".
>
> Bob D.
Let's speak COBOL here and please re-consider if this is the best option
available in GCC [note: I'm also interested for the implementation in
GnuCOBOL, but that's a tangent for this list].
The syntax of the STOP statement and the rules are the following
("noise" words written in parenthesis, optional items in brackets, pipe
gives alternatives within braces):
----------------------------------------------------------------------
STOP RUN
[ (WITH) { ERROR | NORMAL } (STATUS) [ { identifier | literal } ] ]
rules: literal should be non-zero length, if numeric it should be an
integer (no sign, no decimal place);
any constraints on the value of the literal or the contents of the
identifier are defined by the implementor
If the ERROR phrase is specified, the operating system will indicate an
error termination of the run unit if such a capability exists within the
operating system.
If the NORMAL phrase is specified, the operating system will indicate a
normal termination of the run unit if such a capability exists within
the operating system.
During execution of the STOP statement with a literal or an identifier
specified, the literal or the contents of the identifier are passed to
the operating system.
----------------------------------------------------------------------
exit() allows us to "pass to the operating system" directly; but it
doesn't directly say "success" or "fail".
Obviously the statements
STOP RUN WITH NORMAL STATUS 41
and
STOP RUN ERROR 41
Should have a different result for the operating system.
As those numbers must be unsigned, it could be reasonable to translate
that to exit (41) and exit (-41).
While a "STOP RUN ERROR 0" would be possible as well, there could be an
implementor-defined constraint (which can be enforced for literals) that
zero is not valid.
This would mean that STOP RUN == STOP RUN WITH NORMAL STATUS == STOP RUN
WITH NORMAL STATUS 0 == exit (0) and
STOP RUN WITH ERROR STATUS == STOP RUN WITH ERROR STATUS 1 == exit (-1)
Then we have additional the question on how to translate
STOP RUN WITH ERROR "Don't do that, Jon!"
in which case something like
fflush (stderr);
fprintf(stderr, "%s\n", "Don't do that, Jon!");
exit (-1);
or even something along
void cobol_stop_run __attribute__((noreturn))
(int status, char *message) {
const int exit_status = error ? status * -1 : status;
const FILE* stream = error ? stderr : stdout;
const char* prefix = error ?
: _("runtime exited with normal status");
if (error) {
fflush (stderr );
fprintf (stderr , _("runtime exited with error status %d: %s\n",
status, message);
exit (-status);
} else {
fflush (stdout);
fprintf (stderr , _("runtime exited with normal status %d: %s\n",
status, message);
exit (status);
}
}
Side note: I'd highly suggest to keep abort() for runtime-covered error
handling (index out of bounds, program not found, ...)
Simon