EXTERNAL Command [ HP ALLBASE/4GL Developer Reference Manual Vol. 2 ] MPE/iX 5.0 Documentation
HP ALLBASE/4GL Developer Reference Manual Vol. 2
EXTERNAL Command
The EXTERNAL command transfers program execution to an external program
written in a language other than HP ALLBASE/4GL.
Parameters can be passed to and from the external program.
Formats
{[*REFRESH]{program_name}[parm_1...parm_n]}
EXTERNAL { {data_ref } }
{{program_name} *COMMS }
{{data_ref } }
Parameters
program_name
The name of the program to be executed.
data_ref
Can be one of the following containing the name of the external program.
* Constant.
* Variable or calculated item.
* Screen field name.
* Scratch-pad field name.
parameter_1,...parameter_n
The names of values to be passed to the program. They can be any of the
following:
* Literal.
* Master title name.
* Numeric or alphanumeric constant.
* Variable or calculated item.
* Screen field reference.
* Scratch-pad field reference.
* File record field reference.
* Work area field reference.
* Communication area field.
* File record buffer.
* Work area buffer.
Description
The EXTERNAL command executes an external program which is written in a
language other than HP ALLBASE/4GL. The language must be one supported by
the MPE/iX system.
HP ALLBASE/4GL searches for the external program in the current group,
and then in the groups specified by the MPE/iX system variable HPPATH.
After the EXTERNAL command calls the external program, HP ALLBASE/4GL
waits until the program has finished. HP ALLBASE/4GL then resumes
processing at the command following the EXTERNAL command.
The EXTERNAL command with parameters passes the values of the named
parameters to the program. Parameters are passed to the external program
as an information string. The external program is called as:
PROGRAM_NAME; INFO="parm_1 ... parm_n"
The program must be written to expect the exact number and type of
parameters specified. The total length of the information string cannot
exceed 256 bytes.
If the parameters for the external command contain any of the following
key words, they are passed directly to the external program with the same
meaning as in the MPE/iX RUN command:
* ;PARM=
* ;STDLIST=
* ;STDIN=
These key words are passed to the external program after the parameters
that make up the INFO string. A parameter can contain the complete
statement for the key word expression in the form ";key_word=value", or
can contain only the key word itself in the form ";key_word=". If a
parameter only contains a key word, the next parameter in the list is
taken as the argument. For example, an EXTERNAL command could contain
the following parameters:
EXTERNAL myprog parm_1 ";PARM=3" ... parm_n ";STDLIST=" V-list_file
If the current value of V-list_file is "logfile", this command is passed
to MPE/iX as:
RUN myprog; INFO="parm_1 ... parm_n";PARM=3;STDLIST=logfile
The program can return modified values to the parameters by writing them
to a message file HP4EXTP. The file is a variable length record binary
message file.
The external program must return parameters in the following format.
EXTERNAL_parm_no_value_length_value_ [parm_no_value_length_value]...
The external program must insert a single space character (indicated by
the symbol _) between each term in this expression. Values can be
returned to any of the following HP ALLBASE/4GL items:
* Variables.
* Screen field references.
* Scratch-pad field references.
* File record field references.
* Work area field references.
* File record buffers.
* Work area buffers.
* Communication area fields.
The returned values cannot contain null characters.
You must use parameters if you want the external program to return
values.
Values cannot be returned for constants, calculated items, literals or
read-only communication area fields.
The optional *REFRESH argument controls the terminal behavior when the
external program is called, and on return to HP ALLBASE/4GL. If you
specify the *REFRESH argument, HP ALLBASE/4GL returns the terminal
configuration to the state that existed when HP ALLBASE/4GL was first
started. When control returns to HP ALLBASE/4GL, the system restores the
terminal to its HP ALLBASE/4GL configuration, and redraws the screen.
If you specify the *REFRESH argument, the system displays a message when
the EXTERNAL command is executed.
If you use the EXTERNAL command without the *REFRESH argument, the
terminal remains in HP ALLBASE/4GL mode.
The EXTERNAL command with the *COMMS argument passes the contents of the
communication area field *PASS to the external program as parameter
number 3 (that is, the fourth parameter in the list). If you use the
*COMMS format of the command, HP ALLBASE/4GL does not change the terminal
configurations when the external program is called. However, the system
does restore the terminal to HP ALLBASE/4GL mode and also redraws the
screen on return to HP ALLBASE/4GL. With this format of the EXTERNAL
command, the external program cannot return values to HP ALLBASE/4GL.
Example 1
EXTERNAL factorial "5" V-result
This example shows the use of a Pascal program called by the HP
ALLBASE/4GL EXTERNAL command. The EXTERNAL command calls the external
program factorial. The external program receives a value (in this case
5) from HP ALLBASE/4GL and returns the factorial of the value to the
variable result. The external program factorial could be as follows:
program factorial(info, output);
const WR_ACC = 1;
CONTROLCODE = 1;
type name_type = packed array[1..30] of char;
error_type = packed array[1..10] of char;
status_type = record
info : integer;
subsys : integer;
end;
var fname : name_type;
filenum: integer;
num, i : integer;
status : status_type;
domain : integer;
access : integer;
ew : integer;
t : 1..128;
info : string[255];
str : string[32];
buf1, buf : string[128];
{* These are the intrinsic declarations *}
procedure HPFOPEN; intrinsic;
procedure FCONTROL; intrinsic;
procedure FWRITE; intrinsic;
procedure TERMINATE; intrinsic;
{* This function calculates the factorial of the number passed to it. *}
function fact(n: integer): integer;
begin
if n <= 0 then
fact := 1
else
fact := n*fact(n-1);
end; {* fact *}
{* Error routine to exit out of program *}
procedure error(err_str : error_type);
begin
writeln(err_str, ' failed!');
TERMINATE;
end; {* error *}
begin {* main *}
domain := 2;
access := 1;
ew := 1;
num := 0;
i := 1;
buf1 := 'EXTERNAL!';
fname := '&HP4EXTP&';
{* Convert the 1st parameter to an integer *}
while (info[i] <> ' ') do { first space denotes end of field }
begin
num := num*10 + ord(info[i]) - ord('0');
i := i + 1
end;
{* Convert the factorial to a string *}
strwrite(str,1,t,fact(num):1);
{* Send parameters back to HP ALLBASE/4GL by writing them on
the message file 'HP4EXTP'. *}
HPFOPEN(filenum, status, 2, fname, 3, domain, 11, access);
if status.info <> 0 then
error('HPFOPEN');
FCONTROL(filenum, 45, ew); {** extended wait **}
if ccode <> 2 then
error('FCONTROL');
FWRITE(filenum, buf1, -9, CONTROLCODE);
if ccode <> 2 then
error('FWRITE');
strwrite(buf,1,t,'2 ',strlen(str):1,' ',str,chr(13));
FWRITE(filenum, buf, -(strlen(buf)), CONTROLCODE);
if ccode <> 2 then
error('FWRITE');
end. {* main *}
Example 2
EXTERNAL factorial "5" V-result
This example shows a similar program written in COBOL. The external
command calls the external program factorial. The external program
receives a value (in this case 5) from HP ALLBASE/4GL and returns the
factorial of the value to the variable result. The external program
factorial could be as follows:
Identification Division.
Program-id. Factorial.
Author. HP ASO
Date-written. 08/09/88.
Environment Division.
Configuration Section.
Source-computer. HP3000 series 930.
Object-computer. HP3000 series 930.
Special-names.
condition-code is ccode.
Data Division.
Working-storage section.
77 str pic x(32) value spaces.
77 cntstr pic x(9) value spaces.
77 tmpstr pic x(32).
77 num pic 9(9).
77 factorial pic 9(9) value 1.
77 numz pic z(8)9.
77 cr pic x value %15.
77 counter pic s9(9) comp value 0.
01 intrinsic-parms.
05 infostring pic x(128) usage display.
05 infolength pic s9(4) comp value 128.
05 filenum pic s9(9) comp.
05 status-val pic s9(9) comp.
05 status-valr redefines status-val.
08 sw1 pic s9(4) comp.
08 sw2 pic s9(4) comp.
05 it2 pic s9(9) comp value 2.
05 pname pic x(9) value "&HP4EXTP&".
05 it3 pic s9(9) comp value 3.
05 domain pic s9(9) comp value 2.
05 it11 pic s9(9) comp value 11.
05 accesstype pic s9(9) comp value 1.
05 fconcode pic s9(4) comp value 45.
05 ew pic 9(4) value 1.
05 ename pic x(9) value "EXTERNAL!".
05 len pic s9(4) comp value 9.
05 controlcode pic s9(4) comp value 0.
05 buf pic x(128) value spaces.
05 strlen pic s9(9) comp.
Procedure Division.
S0100-main section.
perform P0110-init.
perform P0120-calculate-factorial.
perform P0130-pack-string.
perform P0150-open-pipe.
perform P0170-write-parms.
perform P0999-end.
P0110-init.
*
* Get parameters from HP ALLBASE/4GL
*
call intrinsic "getinfo" using infostring, infolength.
*
* Split up information recieved
*
unstring infostring delimited by all spaces into num,
tmpstr.
P0120-calculate-factorial.
*
* Calculate the factorial
*
if num <= 1 then
move 1 to factorial
else
perform P0125-factorial until num = 1.
P0125-factorial.
multiply num by factorial giving factorial.
subtract 1 from num.
P0130-pack-string.
*
* Pack factorial value into string to be passed back to
* ALLBASE/4GL.
*
move factorial to numz.
unstring numz delimited by all spaces into tmpstr str.
inspect str tallying counter for characters before initial
space.
move counter to numz.
unstring numz delimited by all spaces into tmpstr cntstr.
string "2", ";", cntstr, ";", str, cr delimited by
spaces into buf.
inspect buf tallying strlen for characters before initial
space.
inspect buf replacing all ";" by space.
P0150-open-pipe.
*
* Send parameters back to HP ALLBASE/4GL by writing them on
* message file
*
call intrinsic "hpfopen" using filenum, status-val,
it2, pname, it3, domain,
it11, accesstype.
if status-val is not = zero then
display "HPFOPEN failed! (" sw1 "," sw2 ")"
perform P0999-end.
call intrinsic "fcontrol" using filenum, fconcode, ew.
if ccode not = 0 then
display "FCONTROL failed!"
perform P0999-end.
P0170-write-parms.
multiply len by -1 giving len.
call intrinsic "fwrite" using filenum, ename, len,
controlcode.
if ccode not = 0 then
display "FWRITE failed!"
perform P0999-end.
multiply strlen by -1 giving strlen.
call intrinsic "fwrite" using filenum, buf, strlen,
controlcode.
if ccode not = 0 then
display "FWRITE failed!".
perform P0999-end.
P0999-end.
stop run.
Example 3
EXTERNAL factorial "5" V-result
This example shows a similar program written in C. The external command
calls the external program factorial. The external program receives a
value (in this case 5) from HP ALLBASE/4GL and returns the factorial of
the value to the variable result. The external program factorial could
be as follows:
#include <stdio.h>
#include "mpe.h"
extern void HPFOPEN();
extern void FCONTROL();
extern void FWRITE();
extern int ccode();
#define CONTROLCODE 0
#define fpr(x) (fprintf(stderr, "%s failed!\n", x))
main (argc, argv)
int argc;
char *argv[];
{
int num,
factorial,
filenum,
domain = 2,
access = 1,
status;
char str[20],
buf[128],
fname[128];
short ew = 1;
/*
* Convert the 1st parameter to an integer
*/
num = atoi(argv[1]);
/*
* Calculate the factorial
*/
for (factorial = 1; num > 1; num--)
factorial *= num;
/*
* Convert the factorial to a string
*/
sprintf(str, "%d", factorial);
/*
* Pack string to be passed back to ALLBASE/4GL
*/
sprintf(buf, "2 %d %s\n", strlen(str), str);
/*
* Send parameters back to ALLBASE/4GL by writing them on
* the message file
*/
sprintf(fname, "&HP4EXTP&");
HPFOPEN(8, &filenum, &status, 2, fname, 3, &domain, 11, &access);
if (status != 0) {
fpr("HPFOPEN");
exit(1);
}
FCONTROL(filenum, 45, (unsigned short ^) &ew);
err_check("FCONTROL");
sprintf(fname, "EXTERNAL!");
FWRITE((short)filenum, (char ^)fname, (short)-9, CONTROLCODE);
err_check("FWRITE");
FWRITE((short)filenum, (char ^)buf, (short)-strlen(buf), CONTROLCODE);
err_check("FWRITE");
}
err_check(name)
char *name;
{
if (ccode() != CCE) {
fpr(name);
exit(1);
}
}
MPE/iX 5.0 Documentation