basic.cfunc Definition/BASIC Program

basic.cfunc

Command basic.cfunc Definition/BASIC Program
Applicable release versions: AP/Unix, AP/DOS
Category BASIC Program (486)
Description can be called from a Pick/BASIC program or subroutine in AP/DOS and AP/Unix implementations using a syntax similar to that of normal C.

Commonly used functions are included in the run time package and require no special linking. These functions are referred to as built-in functions. A 'user-defined' function may also be included in a Pick/BASIC application by linking it with the Monitor, thus making a 'user-defined built-in' function.

C function calls can be embedded in Pick/BASIC expressions, Pick/BASIC statements or can be used as arguments to other C function calls. Combined size of all parameters passed may NOT exceed 32 KB. This size can be changed, however, by the "set-cmem" TCL command.

If a "type" specifier is omitted before an argument name, the argument is assumed to be of type integer when "arg" is a number, or to be of type pointer when "arg" is a dynamic array (string). If type is omitted before the function name, the function is assumed to be of type integer.

"arg0" ... "argn" are the optional arguments to the function; up to 15 arguments are supported.

The return type of a function is "void" if the function is not part of an assignment statement or used as an argument to another C function or Pick/BASIC statement. Whenever the return value of a function can be neglected, the type can be overridden by (void).

When a call to a function is made:

- All arithmetic arguments are passed by value.

- All dimensioned arrays are passed by reference.

- All dynamic arrays (strings) are passed by reference.

- String constants (strings between quotes) and sub-strings (string[m,n]) cannot be modified. If a C function tries to modify a string beyond the end of the string, the string will be truncated to its original size but no error will be reported. As is usual in C, no data translation will occur implicitly.

- Pointers are all treated as pointers to characters. When assigned to a Pick/BASIC variable, a pointer can only be passed to another C function or be tested for the value 0 (NULL pointer), anything other than this makes no sense. The following statement has unpredictable results:

ptr=(char*)%malloc(1024)
if ptr > 0 then print 'ok'

The only valid form is to test for ptr = 0 or ptr # 0.

Argument Types

The following argument types are supported:

<nothing>

Default. If "arg" is a number, an (int) is passed to the function. If "arg" is a dynamic array (string), a pointer to the first character of the string is passed to the function. If "arg" is a dimensioned array, a pointer to an image of the dimensioned array is passed to the function. See 'Passing Dimensioned Arrays' below.

(int) (AP/Unix)

Integer. The "arg" is divided by the PRECISION factor and passed to the C function. Integers are 32 bit signed elements.

(int) (AP/DOS)

Integer. The "arg" is divided by the PRECISION factor and passed to the C function. Integers are signed and can be in the range -32767 to 32767. Integers larger than 16 bits ( '+' or '-' 32767) are currently not supported and if they are used, they will cause unpredictable results.

(char)

Character. If "arg" is a dynamic array (string), the first character is passed to the C function. If "arg" is a number it is divided by the PRECISION factor and the result is truncated to 8 bits and passed to the C function.

(char*)

Pointer. The "arg" is a number which is passed to the C function without being divided by the PRECISION factor. The only legal use of this type is to pass a null pointer or a pointer returned by a previous call to a C function to another C function.
All types, except pointers can be prefixed by the keyword "unsigned", (unsigned char) for example.

NOTE: The PRECISION factor is a number between 0 and 9, with 4 being the default value. When a number is divided by the PRECISION factor, the number is actually being divided by 10 raised to the power of PRECISION.

Passing Dimensioned Arrays

Dimensioned arrays of integers can be passed to an external C function. When the array is passed, the C function receives a pointer to the array and all the integers in the array are divided by the PRECISION factor. If the array is multidimensional, the integers are organized column by column. For example, if we have an array that is dimensioned to (2, 5) in Pick/BASIC, the values in the C "array" would be in this order: (1, 1), (2, 1), (1, 2), (2, 2), (1, 3), (2, 3), etc.

Function Types

The following function types are supported:

<nothing>

Default. The return value is assumed to be an integer. It is multiplied by the PRECISION factor.

(void)

The return value is discarded. When prefixed with this type, the function cannot be part of an assignment or be used as an argument to another C function or Pick/BASIC statement or function.

(int) (AP/Unix)

Integer. The return value is a signed integer. It is multiplied by the PRECISION factor.

(int) (AP/DOS)

Integer. The return value is a signed integer. It is multiplied by the PRECISION factor. Integers larger than 16 bit are currently not supported and if they are used, they will cause unpredictable results.

(char)

Character. The return value is stored as a dynamic array containing only one character.

(char*)

Pointer. The return value is stored without being multiplied by the PRECISION factor. The only legal use of this type is to store a pointer that will be used as an argument to another C function.

'Address of' Unary Operator

The C unary operator, & (ampersand), is used to pass the address of an integer to an external C function. This is the only valid form. Note that Pick/BASIC converts numbers which are too large into strings. In this case, the C function would receive a pointer to a character instead of a pointer to an integer.

Space Reserve Statement

When a Pick/BASIC variable (a dynamic array or an element of a one or two-dimensional array) is used to store data returned by a call to a C function (by means of a pointer passed as an argument), the Pick/BASIC variable must have been assigned a size before the call to the function. This needs to be done because C has no notion of dynamic arrays. If a size is not assigned before the result of a C function call is stored in the variable, the data is truncated. Space can be reserved using the following statement:

char variable[size] {,variable[size], ...}

This reserves at least "size" bytes for "variable". "size" can be a constant or an expression. "variable" can be a dynamic array or an element of a one or two-dimensional array. After reserving space for "variable", the content of the variable is undefined.

If a string longer than "size" is assigned to a variable, it is truncated and the characters beyond the given size are ignored. If a string shorter than "size" is assigned to variable, its content after the defined size remains undefined.

Static Data

When using 'user-defined built-in' functions, static data defined as part of a user-defined function remains valid as long as the Pick process is not disconnected from the virtual machine. This is true even if the Pick/BASIC program is finished executing and has returned to TCL. The scope of static data lasts longer than in conventional Unix or DOS programs.

Since static data takes up space in the data section of each Pick process (therefore main memory), it is not advisable to have large amounts of static space. This is especially true for AP/DOS which does not benefit from the underlying Unix virtual memory.

AP/Unix Includes

The following 'header files' are provided in the file bp,unix.h, in the dm account.

errno.h 'errno' values.
fcntl.h Codes for %open(), %creat
ipc.h Semaphores, shared memory, messages.
mode.h File access codes.
sem.h Semaphore operations.
signal.h Unix signal signal numbers.

AP/DOS Includes

The following 'header files' are provided in the file bp,dos, in the dm account.

errno.h MS-DOS/Unix 'errno' codes.
fcntl.h MS-DOS/Unix file access flags.
file.h File system constants.
screen.h Screen constants.
stddefs.h Standard constants.
usrexits.h User exits.

Use "see.also" for information on all system-defined built-in C functions. In most cases, no description is given unless there is something special to mention. Please refer to the Unix or the appropriate system documentation if more details are necessary.

The following rules apply when making a call to a C function:

- The parameters for each funtion must be enclosed in parentheses.
- There must be no spaces between the percent sign (%), the function name and the left parenthesis.
- The function is assumed to return an integer unless explicit casting is performed.
Syntax {variable=}{(type)}%function( {{(type)} arg0 {, ... {(type)} argn}} )
Options
Example
Purpose
Related basic.statements
basic.cfunc.user
tcl.set-cmem
basic.%chdir
basic.%chmod
basic.%chown
basic.%close
basic.%close.apdos
basic.%creat
basic.%dup
basic.%fclose
basic.%fdopen
basic.%fgetc
basic.%fgets
basic.%fprintf
basic.%fsize
basic.%getenv
basic.%getpgrp
basic.%getppid
basic.%ioctl
basic.%kill
basic.%memccpy
basic.%memcpy
basic.%pause
basic.%read
basic.%read.apdos
basic.%semctl
basic.%shmat
basic.%shmdt
basic.%shmget
basic.%write
basic.%write.apdos
basic.%alarm
basic.execute.unix
basic.%pgetpid
basic.cfunction
tcl.rmbi
basic.%lseek.apdos
basic.execute.apdos
basic.%whex
basic.%rdhex
basic.%memxcpy
basic.%free
basic.%popen
basic.%open.apdos
basic.%fputc
basic.%wait
basic.%freopen
basic.%fopen
basic.%pclose
basic.%fputs
basic.%getpid
basic.%lseek
tcl.addbi.apdos
tcl.listbi
basic.%ttyname
basic.%unlink
basic.%open
flash.basic.differences
basic.%
tcl.addbi.unix