CALL, CALL SYSTEM

Syntax

CALL subroutine USING  {src_txt_lit|_var|_col}|{ src_num_lit|_var|_col} {dst_txt_var|_num_var}  [param]

To issue operating system commands from within an SQR program, use the following syntax:

CALL SYSTEM USING command status [ WAIT | NOWAIT ]

Description

Issues an operating system command or calls a subroutine that you have written in another language, such as C or COBOL, and passes the specified parameters.

You can write your own subroutines to perform tasks that are awkward in SQR. Subroutines can be written in any language.

WARNING:

Oracle recommends that the UCALL function not use any database calls because it may cause erroneous results.

Used in an SQR program, CALL has the following format:

   CALL your_sub USING source destination [param_literal]
   CALL SYSTEM USING command status [WAIT|NOWAIT]

The CALL SYSTEM is a special subroutine that is provided as part of SQR to enable the program to issue operating system commands. Its arguments, command, status, and WAIT|NOWAIT are described subsequently.

The values of the source and destination variables and the parameter's literal value are passed to your subroutine. Upon return from the subroutine, a value is placed in the destination variable.

You must write the subroutine and call it in one of the supplied UCALL routines. Optionally, you could rewrite UCALL in another language instead.

The source file UCALL.C contains sample subroutines written in C. The UCALL function takes the following arguments:

Argument Description How Passed

callname

Name of the subroutine.

By reference with a maximum of 31 characters, null terminated.

strsrc

Source string.

By reference with a maximum of 255 characters, null terminated.

strdes

Destination string.

By reference with a maximum of 255 characters.

dblsrc

Source double floating point.

By reference.

dbldes

Destination double floating point.

By reference.

param

Subroutine parameter string. It must be a literal.

By reference with a maximum of 80 characters, null terminated.

When you use the CALL command, your arguments are processed in the following way:

  • Calling arguments are copied into the variables depending on the type of argument. Strings are placed into strsrc and numerics are placed into dblsrc.

  • Return values are placed into strdes or dbldes depending on whether your destination argument for CALL is a string or numeric variable.

The destination arguments can also be used to pass values to your subroutine.

To access your subroutine, add a reference to it in UCALL and pass along the arguments that you need.

You must relink SQR to CALL after compiling a user-defined function that becomes another SQR function.

If you have created a new object file, you must add your subroutine to the link command file: in UNIX/Linux it is called SQRMAKE; in Microsoft Windows it is called SQREXT.MAK. (Alternatively, you could add your routine to the bottom of the UCALL source module that is already included in the link).

Your subroutine and calling SQR program are responsible for passing the correct string or numeric variables and optional parameter string to the subroutine. No checking is performed.

Parameters

Parameter Description

subroutine

Specifies the name of your subroutine.

src_txt_lit|_var|_col

Specifies a text column, variable, or literal that is to be input to the called subroutine.

src_num_lit|_var|_col

Specifies a numeric column, variable (decimal, float, or integer), or literal that is to be input to the called subroutine.

dst_txt_var|_num_var

Specifies a text or numeric variable (decimal, float, or integer) into which the called subroutine is to place the return result.

param

Specifies an optional alphanumeric string of characters to be passed as a parameter to the subroutine.

SYSTEM

Specifies that this CALL command issues an operating system command.

command

Specifies the operating system command to carry out. The command can be a quoted string, string variable, or column.

status

Contains the status returned by the operating system. The status must be a numeric variable. The value returned in status is system-dependent as described here:

UNIX/Linux: Zero (0) indicates success. Any other value is the system error code.

PC/ Microsoft Windows: A value less than 32 indicates an error.

WAIT|NOWAIT

(Microsoft Windows only): WAIT specifies that SQR suspend its execution until the CALL SYSTEM command has finished processing. NOWAIT specifies that SQR start the CALL SYSTEM command but continue its own processing while that command is in progress.

For Microsoft Windows, the default is NOWAIT. On UNIX\Linux operating systems, the behavior is always WAIT.

Example

For example, if your program runs under UNIX and you want to make a copy of a file, you can use the following code in your program:

!Executing a UNIX command from an SQR program
Let $Command_String='cp /usr/tmp/file1.dat /usr/tmp/file2.dat'
Call System Using $Command_String #Status
If #Status<>0
  Show 'Error executing the command in Unix: '$command
End-If

See these sample subroutines included in the UCALL source file:

  • TODASH shows how strings can be manipulated.

  • SQROOT demonstrates how to access numerics.

  • SYSTEM invokes a secondary command processor.

The following code calls these subroutines:

call todash using $addr $newaddr '/.',                   ! Convert these to 
                                                         ! dashes
call sqroot using #n #n2                                 ! Put square root of
                                                         ! #n into #n2
call sqroot using &hnvr #j                               ! Hnvr is numeric
                                                         ! database column
call system using 'dir' #s                               ! Get directory listing

The following example uses the SYSTEM argument to issue an operating system command. Some operating systems enable you to invoke a secondary command processor to enter one or more commands and then return to SQR.

! Unix (Type 'exit' to return to SQR)
!
let $shell = getenv('SHELL')
if isblank($shell)
  let $shell = '/bin/sh'
end-if
call system using $shell #unix_status

!Windows (Type 'exit' to return to SQR)
!
let $comspec = getenv('COMSPEC')
let $cmd = comspec || '/c' ||$comspec || ' /k' 
call system using $cmd #win_status wait

The following step-by-step example shows how to add a user-defined subroutine to SQR so that it can be invoked from SQR with the CALL command. For this example, the C function initcap, which makes the first letter of a string uppercase, is added. The function accepts two parameters. The first parameter is the string to which the initcap function is applied. The second is the resultant string.

To add the initcap function to SQR, you need to make the following modifications to the UCALL.C file that was provided with SQR:

  1. Add the prototype for the initcap function:

    static void initcap CC_ARGS((char *, char *));
  2. Modify the UCALL routine in the UCALL.C file.

    Specifically, add an else if statement at the end of the if statement to check for the initcap function:

       void ucall CC_ARGL((callname, strsrc, strdes, dblsrc, dbldes, params))
       ...   
    
           /* If other subroutines, add "else if..." statement for each */
           else if (strcmp(callname,"initcap") == 0)
               initcap(strsrc, strdes);
           else
               sq999("Unknown CALLed subroutine:  %s\n", callname);
           return;
           }
    
  3. At the end of the UCALL.C file, add the initcap routine listed in the following example.

    The routine name must be lowercase; however, in your SQR program, it can be referenced by using either uppercase or lowercase.

    static void initcap CC_ARGL((strsrc, strdes))
    CC_ARG(char *, strsrc)               /* Pointer to source string      */
    CC_LARG(char *, strdes)              /* Pointer to destination string */
       {
       int nIndex;
       int nToUpCase;
       char cChar;
       nToUpCase = 1;
       for (nIndex = 0; cChar = strsrc[nIndex]; nIndex++)
          {
          if (isalnum(cChar))
             {
             if (nToUpCase)
                strdes[nIndex] = islower(cChar) ? toupper(cChar) : cChar;
             else
                strdes[nIndex] = isupper(cChar) ? tolower(cChar) : cChar;
             nToUpCase = 0;
             }
          else
             {
             nToUpCase = 1;
             strdes[nIndex] = cChar;
             }
          }
       strdes[nIndex] = '\0';
       }

Note:

The CC_ARG macros are defined in the UCALL.C source module. The macros enable the programmer to define a fully prototyped function without concern for whether the C compiler supports the feature.

After these modifications, recompile UCALL.C and relink SQR. See the programming manual for your particular machine for details.

Finally, the following example shows a simple SQR program that uses the initcap function:

begin-program
   input $name 'Enter the first name '! Get the first name from the user 
   lowercase $name                    ! Set the first name to all lowercase 
   call initcap using $name $capname  ! Now set the first character to uppercase
   input $last 'Enter the last name ' ! Get the last name from the user 
   lowercase $last                    ! Set the last name to all lowercase 
   call initcap using $last $caplast  ! Now set the first character to uppercase
   .
   .
   .

See The LET command for information about user-defined functions using UFUNC. C that can be used in the context of an expression and that can either or both pass and return any number of arguments.