# LIST OF ALL SHARK FUNCTIONS:

A function is just like an operation; the addition operation (+) requires two arguments (numbers) and returns their sum; a function requires some arguments (0 to 3) and returns some value.

Every function has a type: numeric, string, or logical, depending on the values it returns.

A function has arguments; the values put into the function between the parentheses, separated by commas. Shark functions have at most three arguments; a few have none. Some arguments may be optional.

The arguments can be variables or expressions of type string: str var or str exp, or of type numeric: num var or <num exp>. (Expressions are discussed in Section 3.5)

# Within the above list are some specific Mathematical Functions. The mathematical functions may be divided into five groups::

#### Logarithmic functions:

EXP( e to the power <num exp>
LOG( natural logarithm of <num exp>
LOG10( base 10 logarithm of <num exp>
POW( <num exp1> to the power <num exp2>
SQRT( square root of <num exp>

#### Trigonometric functions:

SIN( sine of <num exp> in radians
COS( cosine of <num exp> in radians
TAN( tangent of <num exp> in radians
ASIN( arc sine of <num exp>; returns a value in radians between -𝜋/2 and 𝜋/2
ACOS( arc cosine of <num exp>; returns a value in radians between 0 and 𝜋
ATAN( arc tangent of <num exp>; returns a value in radians between -𝜋/2 and 𝜋/2

#### Hyperbolic functions:

SINH( hyperbolic sine of <num exp>
COSH( hyperbolic cosine of <num exp>
TANH( hyperbolic tangent of <num exp>

#### Integer-valued functions:

CEIL( ceiling integer: the integer equal to or just above a given number
FLOOR( floor integer: the integer equal to or just below a given number
INT( the integer part of a given number (the fractional part is discarded); useful for currency "rounding", for example.

Note that for positive numbers, INT( and FLOOR( return the same result, but for negative numbers, INT( and CEIL( produce the same result. This is because discarding the decimal part of a real number reduces its distance from zero.

#### Real-valued functions:

ABS( displays the absolute value of <num exp>
MOD( evaluates remainder of a division of a <num exp> by a different <num exp>

#### Examples:

```
1>:PICTURE='999.999999'
1>? EXP(1)
2.718282    ;this is the value of e
1>? LOG(3)
1.098612
1>? LOG10(3)
0.477121
1>? POW(2,4)
16.000000
1>? POW(2,.5)
1.414214
1>? SQRT(4)
2.000000
1>? SQRT(2)
1.414214
1>? SIN(2)      ;2 is in radians
0.909297
1>? ASIN(1)
1.570796
1>? 2*ASIN(1)
3.141593      ; this is, of course, 𝜋; store this to a variable if you need 𝜋
1>? CEIL(3.14)
4.000000
1>? FLOOR(3.14)
3.000000
1>? INT(23.45)
23.000000
1>? INT(-23.45)
-23.000000
1>x=23.45
1>? INT(10*x)
234.000000
1>x=23.999
1>? INT(x)
23.000000
1>? INT(3.14)
3.000000
1>? FLOOR(-3.14)
-4.000000
1>? INT(-3.14)   ;note that for negative numbers, INT(  and FLOOR( give different values
-3.000000
1>? MOD(5,2)     ;this is the remainder of 5 divided by 2
1.000000
1>? MOD(-3.14, .7)
-0.340000
1>? ABS(-3.14)
3.140000
1>:PICTURE='9999999.99'
1>x=15.689
1>? INT(x*100+.5)/100      Note: this is an example of rounding to the nearest 1 cent
15.69
1>x=15.244
1>? INT(x*100+.5)/100
15.24
```

# Within the above list of all functions are some specific Comparative Functions:

```MASK(:  Manipulates bits in a string based on comparison between 2 strings
MAX(:  Compare two expressions of any type and return the larger.
```

# ALPHABETICAL LIST OF ALL SHARK FUNCTIONS:

## !(

Converts a string to upper case.

```!(<str exp>)
```

<str exp> is the text to be converted to upper case

Type: character

All lower-case letters in the <str exp> are converted into upper case by the !( function. See also the LOWER( function.

Examples:

```1>a='Aa12b'
1>? !(a)
AA12B
1>? !('David!')
DAVID!
```

Note that only the lower-case letters are changed.

## #

Gets the current record number.

`#`

Type: numeric

This function returns the record number of the current record of the selected file. Note that ? # displays the current record number in the form specified by the system variable :PICTURE (see Section 2.7). Shark also has a more general form of this function, RECNO(, which allows the user to specify a file other than the selected file.

When used with the option RECNO(filenum), it gives the record number of the current record in file filenum.

Examples:

```1>USE employee
1>? #
1.00
1>GO BOTTOM
1>? #
6.00
1>GO TOP
1>? #
1.00
1>SKIP 2
1>? #
3.00
1>? recno(2); selects current record in file #2
```

## \$( (substring)

This is shorthand for the SUBSTR( function.

## ASTERISK (*)

Determines whether a record is deleted. Type: logical

In the selected file, the current record pointer points at a record. If this record has been marked for deletion (in BROWSE or EDIT, or with the DELETE command), then * gives the value T; otherwise, it is false.

Example:

```1>USE employee
1>DELETE RECORD 2
1 DELETE(S)
1>GO 2
1>? *
T
```

Do not confuse this function with * command (NOTE), or with the * comment marker.

## @( (at)

Gets the location of a substring.

```@(find str exp, <str exp> [,start)

find str exp    the string searched for
<str exp>         the text to be searched
```

Option:

start byte position at which to start looking for find str exp within the string: <str exp>. If it occurs, the function returns the character position of the first (left-most) substring of <str exp> which is the same as find str exp; if it does not occur, the function returns a 0.

@( and its equivalent, the AT( function, can easily search for successive occurrences of a substring within a string.

Consider the previous paragraph. How many occurences are there of the substring "string"? How many of "s"? This function can determine the answer as follows if the paragraph is stored as a single string in the variable STR:

STR='@( and its equivalent, the AT( function, can easily search for successive occurrences of a substring within a string.

```SUBSTR='s'
COUNT=0
START=0
LEN_STR=LEN(STR)
DO WHILE START<LEN_STR
START=@(SUBSTR,STR,START+1)
IF START>0
COUNT=COUNT+1
ELSE
BREAK
ENDIF
ENDDO
```

Be sure that start always advances; if it stays in the same place, it will perform the same operation indefinitely since it will never get to the end.

Ambitious programmers will have noted that, if substr is longer than one byte, start should begin at 1-LEN(SUBSTR) and advance each time by the length. Furthermore, the condition on the DO WHILE line should then be:

```start<=len_str-len_sub
```

(assuming you've saved the length of the substring in this last variable).

Examples:

```1>greeting='Good morning'
1>? @('oo', greeting)
2.00
1>? @('good',greeting)
0.00
```

In a program:

```IF @(answer,'YNQynq')>0
```

checks whether the user response is correct.

This program segment finds and marks every occurrence of a specified string in a page of text displayed on the screen:

```CLS                                ;start by erasing the screen
DO WHILE t                         ;set up continuous loop -break embedded in segment
IF row()<mLineNumber            ;stop at end of screen
IF .not. read(mPrintLine,1)  ;be sure there's more to display
BREAK                     ;if not, break out of loop
ENDIF
?? mPrintLine                ;display the line, no linefeed
IF mText>' '                 ;if looking for input text
mPrintLine=!(mPrintLine)  ;capitalize line from file
mSearchPos=1              ;start search at 1
DO WHILE t
mSearchPos=@(mText,mPrintLine,mSearchPos)
IF mSearchPos=0        ;no more to find, so...
BREAK               ;   get out
ELSE
* we found something...highlight it and increment search-start position
COLOR colorFind,row(),mSearchPos-1,row(),mSearchPos+mTextLen-2
mSearchPos=mSearchPos+mTextLen
ENDIF
ENDDO
ENDIF
?                            ;emit carriage return/linefeed pair
ELSE
BREAK                        ;stop when screen is full
ENDIF
ENDDO

```

## ABS(

displays the absolute value of a <num exp>

Example:

```1>? abs(
1>? @('oo', greeting)
2.00
1>? @('good',greeting)
0.00
```

## ACOS(

arc cosine of a <num exp> returns a value in radians between 0 and π

## ASC(

Converts a character to its ASCII number.

```ASC(<str exp>)
<str exp> the first character of this string is converted

Type: numeric
```

The characters in the character set used by the computer are numbered from 0 to 255. For the first character of the string <str exp>, ASC( returns the corresponding number. RANK( is a synonym for ASC(. See also the functions CHR(, CTONUM(, and NUMTOC(.

Examples:

```1>? ASC('x')
120.00
1>? ASC('xyz')
120.00
```

Note that only the first character of the string matters.

## ASIN(

arc sine of <num exp> returns a value in radians between -π/2 and π/2

## ATAN(

arc tangent of <num exp> returns a value in radians between -π/2 and π/2

## AT(

Gets the location of a substring . . . a synonym for @(

```AT(find str exp, <str exp>, [start]
```

find str exp the string searched for <str exp> the text to be searched

Option:

```[start]         byte position at which to start looking for
```

Type: numeric

This function finds out whether a string: find str exp occurs in the string: <str exp>. If it occurs, the function returns the character position of the first (left-most) substring of <str exp> which is the same as find str exp; if it does not occur, the function returns a 0.

@( and its equivalent, the AT( function, can easily search for successive occurences of a substring within a string.

Consider the previous paragraph. How many occurrences are there of the suBstring "string"? How many of "s"? This function can determine the answer as follows if the paragraph is stored as a single string in the variable STR:

Example:

```SUBSTR='s'
COUNT=0
START=0
LEN_STR=len(str)
DO WHILE start<len_str
start=@(substr,str,start+1)
IF start>0
count=count+1
ELSE
BREAK
ENDIF
ENDDO
```

Be sure that start always advances; if it stays in the same place, it will perform the same operation indefinitely since it will never get to the end.

Ambitious programmers will have noted that, if SUBSTR is longer than one byte, START should begin at 1-LEN(SUBSTR) and advance each time by the length. Furthermore, the condition on the DO WHILE line should then be

```START<=LEN_STR-LEN_SUB
```

(assuming you've saved the length of the substring in this last variable).

Examples:

```1>greeting='Good morning'
1>? @('oo', greeting)
2.00
1>? @('good',greeting)
0.00
```

In a program:

```IF @(answer,'YNQynq')>0
```

checks whether the user response is correct.

This program segment finds and marks every occurrence of a specified string in a page of text displayed on the screen:

```CLS                                ;start by erasing the screen
DO WHILE t                         ;break embedded in segment
IF row()<mLineNumber            ;stop at end of screen
IF .not. read(mPrintLine,1)  ;be sure there's more to display
BREAK                     ;if not, get out
ENDIF
?? mPrintLine                ;display the line, no linefeed
IF mText>' '                 ;if looking for input text
mPrintLine=!(mPrintLine)  ;capitalize line from file
mSearchPos=1              ;start search at 1
DO WHILE t
mSearchPos=@(mText,mPrintLine,mSearchPos)
IF mSearchPos=0        ;no more to find, so...
BREAK               ;   get out
ELSE
* we found something...highlight it and increment search-start position
COLOR colorFind,row(),mSearchPos-1,row(),
mSearchPos+mTextLen-2
mSearchPos=mSearchPos+mTextLen
ENDIF
ENDDO
ENDIF
?                            ;emit carriage return/linefeed pair
ELSE
BREAK                        ;sop when screen is full
ENDIF
ENDDO
```

## BIT(

Bit-set function determines if a given bit is 0 or 1

```BIT(string,bit position)
```

string a string or string variable to test bit position a numeric expression; position of a given bit within string

Type: logical

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001.

When used with the SET( and RESET( functions, which turn specific bits to 1 or 0 respectively, the BIT( function can be used to access large amounts of logical data much more compactly than in a set of logical variables. BIT( returns T (true) if the specified bit is set (0), F (false) if not set (0).

NOTE: Bit positions are counted differently than in some other schemes. In these functions, all bits are counted from the left of the string starting at 1, so that each character contains bits numbered as follows: 1. Bits 1 to 8. 2. Bits 9 to 16. 3. Bits 17 to 24. . . . and so on

Example in a program:

To print the binary value of each character in an input string:

```SET RAW ON         ;eliminates spaces between listed output
DO WHILE t
ACCEPT 'Enter a short string or binary representation: ' TO string
IF string=' '
BREAK
ENDIF
?
REPEAT LEN(string)*8 TIMES VARYING position
?? IFF(BIT(string,position),'1','0')
IF MOD(position,8)=0
?? ' '
ENDIF
ENDREPEAT
ENDDO
```

Now run the program:

```Enter a short string for binary representation: Bit <--- enter text "Bit"
01000010 01101001 01110100   <--- result displays on screen
Enter a short string for binary representation: <--- prompt reappears
```

## BLANK(

Creates a string of blanks or other specified characters.

`BLANK(<num exp>[,charnum)`

<num exp> a number from 0 to 255

Option:

```charnum    the ASCII number of the character used to fill the
blank string; default is 32, the blank character
```

Type: character

This function creates a string of <num exp> blanks or other specified characters.

When charnum is specified, many interesting effects can be created, particularly by using the special pattern characters in the IBM screen character set, 176-178, and the solid block character, 219.

Examples:

```1>name='DAVID'
1>? name+BLANK(15)+name
DAVID               DAVID
1>num=23
1>? name+BLANK(num+5)+name
DAVID                            DAVID
1>? BLANK(20,65)
AAAAAAAAAAAAAAAAAAAA
1>? BLANK(20,196)
--------------------
```

## BOF

Gives the beginning-of-file flag for the currently selected data file.

`BOF`

Type: logical

If the current record pointer is on the first record of the file in use and a SKIP -1 is issued, BOF returns T (true); otherwise it is F (false). Since SKIP -n is treated as n SKIP -1 commands, BOF returns true if SKIP -n goes past the last record.

To check an open data file other than the currently selected one, use the BOF( function.

Examples:

```1>USE employee
1>GO 3
1>SKIP -2
1>? #
1.00
1>? BOF
F
1>SKIP -1
1>? BOF
T
1>GO 4
1>SKIP -5
1>? #
1.00
1>? BOF
T
```

## BOF(

Gives the beginning-of-file flag for a specified data file.

`BOF(<filenum>)`

Option:

`<filenum> the number of the data file to be checked`

Type: logical

For the data file number specified, if the current record pointer is on the first record and a SKIP -1 is issued, BOF( returns T (true); otherwise it is F (false). Since SKIP -n is treated as n SKIP -1 commands, BOF( returns true if SKIP n goes past the first record.

An extended form of the BOF function which, since it takes no parameter, works only on the currently selected data file. If no <filenum> is specified, the current file is assumed.

Examples:

```1>USE employee
1>GO 3
1>SKIP -2
1>? #
1.00
1>? BOF()
F
1>SELECT 2
2>USE inventry
2>GO TOP
2>? #
1.00
2>? BOF()
F
2>SKIP -1
2>? #
1.00
2>? BOF()
T
2>SELECT 1
1>? BOF(2)
T
```

## CEIL(

ceiling integer: the integer equal to or just above a given number

## CEN(

Centers a line of text.

```CEN(<str exp>,<num exp>)

<str exp>    the text to be centered
<num exp>    the line width```

Type: character

This function centers (from the present position) the text <str exp> in a line (column) with <num exp> characters.

Examples:

```1>compiler='Shark'
1>? CEN(compiler,40)
Shark
1>@ 10,20 SAY CEN('Center this',40)```

Note: the last command centers the text between columns 20 and 60.

## CHR(

Converts an ASCII number to character.

(To convert a numeric value to a string, use STR()

```CHR(<num exp>)

<num exp> a number from 0 to 255```

Type: character

The characters in the character set used by the computer are numbered from 0 to 255; this number for a character is called the ASCII number. For a given <num exp> in this range, CHR(<num exp>) is the corresponding character.

This function is useful to send control codes to the printer. For instance,

`1>? CHR(27)+CHR(120)+CHR(1)`

puts the Epson LQ-1500 printer into letter quality mode.

The functions ASC( and RANK( do the reverse. These functions combine nicely. If the memory variable LETTER contains a letter of the alphabet (other than z or Z), then LETTER=CHR(ASC(LETTER)+1) places in LETTER the next letter of the alphabet.

Examples:

1. To send unprintable or other characters to a printer

`1>? CHR(27)`

sends ESC to the printer

```1>letter='C'
1>? CHR(RANK(letter)+1)```

sends "D" to the printer

2. To set a standard IBM or Epson printer into double-wide mode:

`1>SET PRINT ON`
`1>? CHR(14)+'First line.'`

prints:

`First line. `

NOTE: the character '0' is difficult to send to a printer since it represents the end-of-line instruction. A better method of sending characters is the

`PSTR`

command, which permits sending any character to the printer. Example:

`PSTR 27,W,1Bh,41h,3h`

For more information, see the PSTR command.

## CLOSE(

Closes a file.

`CLOSE([filenum])`

Option:

`<filenum>      the DOS file number (between 1 and 4)`

Type: logical

This function closes the DOS file (in particular, the sequential file) opened with the ROPEN( or WOPEN( function. It returns T if successful, F otherwise. See the functions ROPEN(, WOPEN(, SEEK(, SSEEK(, READ(, WRITE(, GET(, PUT(, IN(, OUT(, and CLOSE).

If filenum is not specified, filenum=1 is the default.

Example:

```1>ok=ROPEN('a:label.prg',3)
1>? ok
T
1>ok=CLOSE(3)
```

## COL(

Gets print column position.

`COL()`

Type: numeric

This function gives the current column position of the cursor; if the printer is on, it returns the column position of the printer head. See the commands SET PRINT ON and SET FORMAT TO PRINT, and the function ROW(.

Example:

`@ ROW(),COL()+3 SAY 'Hello'`

prints 'Hello' starting three characters to the right of the end of the last printing.

## COS(

cosine of <num exp> in radians

## COSH(

hyperbolic cosine of <num exp>

## CTONUM(

Convert a hexadecimal string into a decimal number.

```CTONUM(type,string exp)

type         the length of the numeric value to be returned
string exp   the string to be evaluated as a hexadecimal value```

Type: numeric

A general conversion function for converting hexadecimal values into decimal numbers. Input can be any length string or string variable up to eight characters as follows:

``` Type     String Length  Returns
1      1 byte         integer 0 to 255
2      2 bytes        integer -32768 to 32767
4      4 bytes        integer +/- 2 billion
8      8 bytes        a floating point number```

If string is shorter, conversion still assumes the string is the format of the given width. When type is 1, this function is equivalent to RANK( or ASC(.

The NUMTOC( and CHR( functions convert numbers into strings.

Do not confuse these function with STR( and VAL(, which convert decimal numbers into their string representations, and vice versa.

Examples:

```1>? CTONUM(1,'a')
97.00
1>? CTONUM(2,'ab')
25185.00
1>? CTONUM(4,'abc')
6513249.00
1>? CTONUM(4,'abcd'); number too large for format in :PICTURE
```

## DATE(

Displays a date in a specific format, or update :DATE with the computer's system date.

`DATE([type],<str exp>)`

type being one of nine type basic date-output formats:

`DATE(1)`
`DATE(2)`
`DATE(3), etc`

Option: <str exp> the date to be converted

Type: character

This function has three distinctly different purposes and results:

1. with only type specified in the range 1-9, rewrites the current Shark date in :DATE in the format specified by the type, and returns the result.

2. with two parameters (the format in the range 1-9, and the date) returns the given date in the specified format. :DATE is not effected.

3. with only type specified as zero, updates the Shark date with the computer's current system date, and the computer time with the current system time. The Shark and system dates are always the same when Shark is started, but the Shark does not automatically advance at midnight as the computer's system date should. When Shark can be in use overnight, or even for days at a time, it may be important to ensure that these dates are kept in synchronization. Returns a string of length zero.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```Type            Date-output format
-----------     -------------------------------------
0               a string of length zero
1 or YMD        6-character format without slashes: yymmdd
2 or MDY        8-character format with slashes: mm/dd/yy
3 or Char       Spelled out: Month dd, yyyy
4 or Full       Spelled out: Weekday, Month dd, yyyy; valid only
for years 1980-2079
5 or Lchar      Last day of month spelled out in format 3 (Char)
6 or DMY        11-byte string in format dd-MMM-yyyy
(example 03-NOV-1990)
7 or Variable   formatted without slashes according to SET DATE
TO command (See SET DATE TO)
8 or Long       8-character format without slashes: yyyymmdd
9 or Last       Last day of month in format 1 (YMD) or 8 (Long),
depending on whether SET DATE TO command
set year to YY or YYYY
```

Shortcut: When specifying type by name, only the first character is usually required. The exception is for Lchar, Long, and Last, which require two characters to resolve ambiguity. If only one is given, Lchar is assumed.

Note: No name equivalent is provided for type 0, which updates the Shark date from the computer's calendar setting.

```<str exp> must contain the date in one of the following formats:

mmddyy      ddmmyy       yymmdd   mmddyyyy   ddmmyyyy   yyyymmdd
```

Optionally, a slash, a hyphen, or a space may be used to separate the elements of these formats. For example, YY/MM/DD, YY-MM-DD, DD MM YYYY are all equally valid.

There should be two digits each for month and the day, and two or four digits for the year. 01 3 92 is not acceptable. If <str exp> is not acceptable, then DATE( returns a string of blanks.

In the event of ambiguity, dates will be decoded in accordance with the format set in the SET DATE TO command. For example:

```SET DATE TO    date           is interpreted as   Comment
-------------  -----          ---------------     --------
'ddmyy'        11/03/99       March 11, 1999
'mmddyy'       11/03/99       November 3, 1999
'mmddyy'       11/03/60       November 3, 2060    all dates
converted to range 1980-2079
'yyyymmdd'     20110419       2011 April 19
```

See also the system variable :DATE and the command SET DATE TO.

Examples:

```1>:DATE= '10/05/99'
1>? :DATE
10/05/99
1>? DATE()
19991005
1>? :DATE
19991005
1>? DATE(1)
991005
1>? :DATE
991005
1>? DATE(2)
10/05/99
1>? :DATE
10/05/99
1>? DATE(3)
October 5, 1990
1>? :DATE
October 5, 1990
1>? DATE(4)
Saturday, October 5, 1990
1>? :DATE
Saturday, October 5, 1990
1>? DATE(4,'12/08/90')
Sunday, December 8, 1990
1>? :DATE
Saturday, October 5, 1990
1>? DATE(5,'90-30-27')
March 31, 1990
1>? DATE(6,'03  27 90')
27-Mar-1990
1>? :DATE
Saturday, October 5, 1990
1>? :DATE(8)
20110419
```

The date can be recalled with any of the above date() functions, and styled to suit the user. For example, Put the following in the SHARKNET.CNF file:

```:DATE=DATE(8)
:UNDOC=PIC(DATE(8),"XXXX.XX.XX")```

Then the system variable :UNDOC when recalled will display:

```1>? :UNDOC
1>? 2011.04.19```

Thus, a preferred date format can be stored in Shark's .CNF file as a system variable. It's then visible to all applications in Shark:

`:UNDOC=PIC(DATE(8),"XXXX.XX.XX")`

NOTE: If the time has passed midnight during the current run of Shark, you can update the Shark date with DATE(0):

```1>? DATE(0)
1>? DATE(4)
Sunday, October 6, 1990```

NOTE: Formatting the date display has no effect on date calculations.

## DAYS(

Computes dates and date differences in days.

```DAYS(<str exp1>,<str exp2>) Example: DAYS(2005-03-18,2005-06-27)
DAYS(<str exp>,<num exp>) Example: DAYS(2005-03-18,30)
```

In the first form: str exp1 and str exp2 are dates

In the second form: <str exp> is a date and <num exp> is a number

Type: numeric/character

In the first form, DAYS( returns the number of days between two dates. The result is an integer.

In the second form, DAYS( returns the date (as a string) which is <num exp> days past or before the date <str exp>.

The string expressions containing dates can be of many different formats (see the DATE( function for more examples):

```	yyyy/mm/dd  2005/03/18
yyyy-mm-dd  2005-03-18
yyyy mm dd  2005 03 18
mm/dd/yy  03/18/05
mm-dd-yy  03-18-05
mm dd yy  03 18 05
```

There should be two digits each for yy, mm, and dd, and four digits for yyyy. 01 3 90 is not acceptable (dd contains only 1 digit).

In the second form, the date is returned in the format set with the SET DATE TO command (default: mmddyyyy). If you wish a different format, use the DATE( function. See also MONTHS( and SET DATE TO.

Examples:

```1>? DAYS('04 06 90','04 29 90')
23.00
1>? DAYS('01/01/88','01 23 90')
753.00
1>? DAYS('01/01/90','01 23 88')
-708.00
1>? DAYS('01/01/91','01 02 91')
1.00
1>? DAYS('01/02/91','01 01 91')
-1.00
1>? DAYS('04 03 90',30)
050290
1>? DAYS('02 03 90',30)
030590
1>? DAYS('02 03 90',-3)
010490
1>? DAYS('020390',-30)
010490
1>monthday='0203'
1>offset=30
1>? DAYS(monthday+'90',offset+1)
030690
```

Note that the MONTH( and DATE( functions always count the days in leap years:

```
1>? DAYS('02/28/88','03 01 88')    ;leap year
2.00
1>? DAYS('02/28/90','03 01 90')    ;not a leap year
1.00
```

Thus, DAYS(2005-03-18,-365) may not give the same result as MONTHS(2005-03-18,-12)

DAYS( and DATE( may be combined to form complex expressions. For instance, the end of the month closest to today in the form set in the SET DATE TO command:

`DATE(7,DAYS(DATE(2),-15))`

The end of NEXT month:

`DATE(5,DAYS(DATE(2),30))`

See DATE( and MONTHS( functions, and SET DATE TO command.

## DBF(

Allows access to data-file attributes of a file in use.

``` DBF(type[,<filenum>)

type      the information required from the data file header```

Option:

``` <filenum>   the data file number; default is the currently
selected data file```

Type: character/numeric

Each data file has a file head which contains information about its structure, most of which is displayed with the LIST STRUCTURE command.

Using the DBF(, DBFX( and FLD( functions provides users access to this information in a programmable form suitable for display and use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```TYPE             EXPLANATION                        RESULT
1 or (T)ype      file type ("0", "1", "2" or "3")   string
2 or (N)ame      data file name                     string
3 or (F)ields    number of fields in structure      integer
4 or (R)ecords   number of records in file          integer
5 or (I)ndexes   number of indexes currently open   integer
6 or (M)aster    index number of master index       integer
7 or (Q)ualified fully-qualified file name from
SharkBase FILES structure if
one exists; otherwise from DOS    string
8 or (E)xpanded  fully-qualified file name from DOS string```

Shortcut: When specifying type by name, only the first character is required.

Examples:

```1>? DBF(type),DBF(n),DBF(fields),DBF(recs),DBF(indexes),DBF(master)
0 CUSTOMER.DBF       9.00       4.00       2.00       1.00
1>? DBF(q)
C:\SHARK\DBF\CUSTOMER.DBF

1>SET INDEX TO NAME
1>APPE BLANK
1>GO TOP <--- takes you to blank (NEWLY APPENDED) record of indexed table
1>GO BOTT <--- takes you to last record before new record appended to table
1>GOTO DBF(R) <--- takes you to the last (NEWLY APPENDED) record in table```

Since appended record is blank, it won't show as the last (BOTTOM) record in an indexed table. DBF(R) will take you to the last record in the table.

## DBFX(

Gives additional information about an open data file; an extension to the DBF( function.

``` DBF(type[,<filenum>)

type      one of three types of information as listed below```

Option:

``` <filenum>   the data file number; default is the currently
selected data file```

Type: logical

The DBF( and FLD( functions provide information contained in the data file headers.

Shark provides this extended function to give three additional types of information in a programmable form suitable for display and use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```TYPE           EXPLANATION
1 or Filter    TRUE if a FILTER is in effect
2 or Limit     TRUE if a LIMIT is in effect
3 or Relation  TRUE if file is related to another
4 or Write     TRUE if current record has changes to be written to disk```

Shortcut: When specifying type by name, only the first character is required.

In a program, the programmer has control over whether filters, limits and relations are established, so the first three options are primarily helpful in Conversational SharkBase, in program debugging and in displaying the current environment for the aid of end-users.

The fourth option, however, is extremely helpful in programming, especially on networks, for it allows the programmer not only to check whether the user actually wants to save changes made to the record, but to avoid locking and changing records when the user was only looking.

A second valuable use of this feature is to time-stamp changes and leave a record of who made them.

Examples:

```1>USE customer
1>SET FILTER TO state='CA'
1>? DBFX(Filter) or DBFX(1)
T
1>? DBFX(R) or DBFX(3)
F```

In a program segment, starting with the READ command):

```READ
IF DBFX(w)
@ 22,0 say CEN('Record changed. Save the Changes (Y/N)?',80)
CURSOR 23,39
IF !(CHR(INKEY()))='Y'
REPLACE changedby WITH DATE(1)+user+TIME(1)
FLUSH
ELSE
NOUPDATE      ;all changes are discarded
ELSE
ENDIF```

The same approach is used in programming for SHARE files on a network, but the actual technique is beyond the scope of this section due to the many different ways networking-data-indegrity is implemented by various operating systems. See specific network sections of your SharkBase documentation for more on this topic.

## DELETED(

Determines whether a record is deleted.

` DELETED(<filenum>)`

Option:

` <filenum>    the number of the data file to be checked`

Type: logical

In a specified data file, the current record pointer points at a record. If this record has been marked for deletion (in BROWSE or EDIT, or with the DELETE command), then DELETED( gives the value T; otherwise, it is false.

This is a more general form of the * function, which operates the same way as DELETED( but, because it allows no parameter, works only with the currently selected data file.

Examples:
```1>? DELETED(4)
T
```

## DESCEND(

The main use of DESCEND( in Shark is to create indexes that are in reverse, or descending, order.

Remember that an index arranges its keys in order of the value of the characters making up the keys. "A" comes before "B" because the value 65 is smaller than 66.

In C Language terms, Shark reverses all bits in string; equivalent to NOT of string. Shark uses this function to reverse the order of an indexed file.

`DESCEND(string)`
``` string    the string to be converted; every "1" bit is returned
as "0", and every "0" bit is returned as "1"```

Type: character

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001, while the letter B has a decimal value of 66 and a binary value of 01000010.

The DESCEND( function returns a "mirror image" of the input string . . . i.e., one in which evey bit set to 1 is reset to 0, and every 0 is set to 1.

The result is familiar to programmers who use C and other low-level languages, who would use the NOT operator to obtain the same result.

The main use of DESCEND( in Shark is to create indexes that are in reverse, or descending, order.

But suppose the index expression, instead of being on the key expression itself is on the NOT value of it, as in:

`INDEX ON DESCEND(NAME) TO REVERSE`

Now you have an index called REVERSE.NDX in which B comes before A.

This function is especially useful in creating reports. For example, suppose you want to report transactions for your customers in reverse date order (latest transactions first). Your index command could be:

`INDEX ON CUST+DESCEND(DATE) TO CUSTREPT`

Note: if you create an index using the DESCEND( function, you will have to use the same function to modify any find strings if you need to use the index to FIND, SEEK, etc.

Example in a report form:

```TITLE - Transactions by Customer, with Dates in Descending Order
FILE - trans
INDEX - cust+descend(date) to custrept
FILE - cust index cust1
RELATION - custnum to 2
FIELDS - date(6,date),desc,amount
PICTURE - ,,9999999.99
SUBTOTAL - custn
MESSAGE - 'Customer: '+pic(custnum,'xxx-x-xx  -- ')+name#2```

Note: This report form includes a number of features worth noting, including the fact that it creates its own index, sets up a relation to a second file, includes underlined headings and subtotals, and includes one line split into two. In report forms, the comma (,) is a continuation character when it is the last character on a line. See REPORT.

## DIR(

Get file information from disk directory.

``` DIR(filespec) (referred to as "Form 1")
DIR()         (referred to as "Form 2") ```

Option:

`filespec  refers to a string or string expression containing a file name (or skeleton using ? and/or * wildcards), with optional drive and/or path specification (enclosed in single quotes)`

Type: character

Searches for specific files specified by the drive path, subdirectory and/or filename and provides specific information on files found.

If an argument is given as shown in Form 1, it must be a string or string expression naming a file, with * and ? wildcards optional). Returns the first file name found matching filespec. If no match was found, blank is returned.

If no argument is given as shown in Form 2, the previous filespec is used to find the next matching file. If no more matching file names are found, blank is returned.

DIR( differs from DIRF( in that DIR( requires the user to specify the pathname unless the search is to be confined to the current directory. DIRF( (see below) is usually preferable since it searches the directory as which a current FILES structure points for the file name specified. See DIRF(.

Examples:

`? DIR('c:\path\*.bak')`

locates and displays the name of the first file with extension BAK in the subdirectory \PATH, while

`? DIR('*.bak')`

locates and displays the name of the first file with extension BAK in the current directory.

If a file is found, entering DIR() with no parameters will locate the next file meeting the filespec. This will continue until the response is a blank, indicating there are no more files meeting the filespec.

Once a file is identified with DIR(, the DIRX( function may be used to obtain additional information from the DOS directory in a form suitable for use in a program.

## DIRF(

Get file information from disk directory.

``` DIR(filespec) (referred to as "Form 1")
DIR()         (referred to as "Form 2") ```

Option:

`filespec  a string or string expression containing a file name (or skeleton using ? and/or * wildcards), with optional drive and/or path specification (enclosed in single quotes)`

Type: character

Searches for specific files specified by the filename and the path supplied from the FILES structure (see FILES...ENDFILES), and provides specific information on files found.

If an argument is given (Form 1), it must be a string or string expression naming a file, with * and ? wildcards optional). Returns the first file name found matching filespec. If no match was found, blank is returned. If a disk name is supplied, the path supplied by the FILES structure is ignored.

If no argument is given (Form 2), the previous filespec is used to find the next matching file. If no more matching file names are found, blank is returned.

DIR( differs from DIRF( in that DIR( requires the user to specify the pathname unless the search is to be confined to the current directory. See DIR(.

Examples, assuming the following FILES structure is in effect:

```FILES
*.prg,c:\shark\prg
*.frm,c:\shark\prg
*.bak,c:\shark\prg
*.db*,c:\shark\data
*.ntx,c:\shark\ntx
*.cpl,c:\shark\cpl
ENDFILES
DIRF('*.prg')```

locates the first file with extension PRG in the subdirectory C:\SHARK\PRG. NB: this request only LOCATES the file information and doesn't display any result! Read further for instructions on how to DISPLAY needed information.

`DIRF('*.bak')`

locates the first file with extension BAK in the subdirectory C:\SHARK\PRG.

NOTE that the above instruction only locates the file and doesn't display any result. To display the found file, you must type:

`? DIRF('*.bak')`
`DIRF('*.dbt')`

locates the first file with extension DBT in the subdirectory C:\SHARK\DATA.

`DIRF('*.txt')`

locates the first file with extension TXT in the current directory, since there was no matching filename pattern in the FILES structure.

If a file is found, entering DIRF() with no parameters will locate the next file meeting the filespec. This will continue until the response is a blank, indicating there are no more files meeting the filespec.

Once a file is identified with DIRF(, the DIRX( function may be used to obtain additional information from the DOS directory in a form suitable for use in a program.

## DIRX(

Obtain additional information about file located with the DIR( or DIRF( function.

``` DIRX(type)

type    the name or number of the information required about a file
```

Type: character/numeric

Once a file is identified with DIR( or DIRF( additional information can be obtained from the DOS directory in a form suitable for use in a program.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```Type           Explanation                                    Result
1 or Name      last file name found with DIR(                 string
2 or Size      size in bytes of last name found with DIR(     integer
3 or Attribute DOS file attribute as follows                  integer
1 - directory
2 - system
3 - hidden
4 - read only
5 - normal
4 or Time      time file created or last updated              string
5 or Date      date file created or last updated              string
6              directory
7              sub-directory
```

Shortcut: When specifying type by name, only the first character is required.

These functions have many uses. Use them to write a program that backs up recently modified files, a program that lists files so the user can pick one, etc.

Examples:

```DIRX(n) returns the filename (e.g. "Name")
DIRX(a) returns 4 if the file is read only (e.g. "Attribute")
```

## EOF(

Gives the end-of-file flag for a specified data file.

```
EOF(<filenum>)```

Option:

` <filenum>    the number of the data file to be checked`

Type: logical

For the data file number specified, if the current record pointer is on the last record and a SKIP is issued, EOF( returns T (true); otherwise it is F (false). Since SKIP n is treated as n SKIP commands, EOF( returns true if SKIP n goes past the last record.

Also, if a LOCATE or CONTINUE command is unsuccessful, or if NEAREST does not find an index key equal to or greater than the FIND string, EOF( returns T.

If no <filenum> is specified, the current file is assumed.

An alternate form of the function - EOF - works only on the currently selected data file, since it takes no parameter. See EOF.

Examples:

```1>USE employee
1>GO 4
1>SKIP 2
1>? #
6.00
1>? EOF()
F
1>SELECT 2
2>SKIP
2>? EOF()
T
2>GO BOTTOM
2>SKIP
2>? #
6.00
2>SELECT 1
1>? EOF(2)
T
```

## EOF

Gives the end-of-file flag for the currently selected data file.

`EOF`

Type: logical

If the current record pointer is on the last record of the file in use and a SKIP is issued, EOF returns T (true); otherwise it is F (false). Since SKIP n is treated as n SKIP commands, EOF returns true if SKIP n goes past the last record. Also, if a LOCATE or CONTINUE command is unsuccessful, or if NEAREST does not find an index key equal to or greater than the FIND string, EOF returns T.

Examples:

```1>USE employee
1>GO 4
1>SKIP 2
1>? #
6.00
1>? EOF
F
1>SKIP
1>? EOF
T
1>GO 4
1>SKIP 3
1>? #
6.00
1>? EOF
T
```

## EXP(

e to the power <num exp>

## FIELD(

Get the number of the Get Table entry corresponding to a variable or field name.

```
FIELD(<name>) ```
<name> =the name of field or variable in a Get Table

Type: numeric

While in full-screen editing mode (with READ, BROWSE, EDIT, etc.), each input variable and field is put into a Get Table that can be controlled with an ON FIELD structure.

FIELD( returns the number from 1 to 64 of any editing field on screens created with @ GET and TEXT macros. This function is usually used on an ON FIELD structure to redirect the sequence of data entry.

See READ and ON FIELD in the Command Reference section.

Example in a program:

```ON FIELD
FIELD qty
IF qty<0
@ 22,0 say CEN('Quantity cannot be negative. Press any key',80)
cc=INKEY()
ERASE 22,22
:FIELD=FIELD(qty)
ENDIF
ENDON
```

## FILE(

Verifies whether a file exists.

``` FILE(<str exp>)

<str exp>   = a file name   ```

Type: logical

This function looks up the file whose name is given by <str exp>; if the file is found, the function returns T, otherwise it returns F.

If no extension is given in the file name, DBF is assumed (a data file is looked for).

Examples:

```1>? FILE('employee')
T
T
1>? FILE(mfile)
F
1>? FILE('a:'+mfile)
T
```

## FLD(

Get information about a field in a data file.

```
FLD(type,<fieldnum> [,<filenum>])

type       one of the four attributes of a field
<fieldnum>  = the number of the field to be checked```

Option:

` <filenum>    the number of the data file to be checked`

Type: character/numeric

Each field in a data file has four attributes as shown with the LIST STRUCTURE command: name, type, width and (for numeric variables) number of decimal places. The FLD() function is often used in conjunction with the DBF() function.

These attributes can be retrieved in a form suitable for use in a program with the FLD() function.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```Type           Explanation                              Result
1 or Name      string containing field name             string
2 or Type      string containing field type             string
3 or Width     number containing width of field         integer
4 or Decimals  number of decimal places in field        integer
```

Shortcut: When specifying type by name, only the first character is required.

Example in a program:

```REPEAT DBF(records) TIMES varying fldnum
REPEAT 4 times VARYING type
?? FLD(type,fldnum)
ENDREPEAT
?
ENDREPEAT
```

## FLOOR(

floor integer: the integer equal to or just below a given number

## GET(

Gets a string from a DOS file.

``` GET(str var,<width num exp>[,filenum])

str var     stores the string
<width num exp>   = the width of the string requested (must be in range 1 to 254)```

Option:

` filenum            the DOS file number (between 1 and 4)`

Type: logical

This function imports a string of <width num exp> characters from a DOS file opened with the ROPEN( function; the character number pointer is normally positioned with the SEEK( function.

If successful in getting all the bytes requested, GET( returns T (true) and sets str var to the string imported from the file. If str var does not exist, GET( will create it.

If the function is unsuccessful, it returns F (false). This will be the result if the GET( function tries to get data beyond the end of the file. Note, however, that even if GET( returns F, one of more characters may still have been imported from the file; it is wise to check the value and width of str var to ensure part of a file is not lost.

If filenum is not given, filenum=1 is assumed.

GET( READ(, IN(, and WRAP( are the only functions that change the contents of the memory variable used as an argument.

See also the functions ROPEN(, WOPEN(, CLOSE(, SEEK(, and PUT(.

Example in a program:

```IF ROPEN('test',3)
DO WHILE GET(string,80,3)
? string
ENDDO
ENDIF
ok=CLOSE(3)
```

## IFF(

Allows inline IF...THEN logic in expressions.

``` IFF(cond,<exptrue>,<expfalse>)

cond       a logical expression
<exptrue>    the expression to be returned if cond is TRUE
<expfalse>   the expression to be returned if cond is FALSE```

Type: Type: character/numeric/logical

This function returns <exptrue> if cond is true, <expfalse> otherwise. The type of the value returned is the same as the expression selected by the condition. IFF( is very useful in the FIELDS line of reports or in commands such as SUM, AVERAGE, REPLACE, or LIST.

Examples:

```1>? IFF(married,'Married','Single ')
1>SUM IFF(quant>500, quant*price, 0),IFF(state='NY',1,0)
```

The first command prints "Married" or "Single" according to the value of a logical field named MARRIED. The second command will return the sum of all quantities for transactions where quantity is greater than 500, and a count of all records where STATE='NY', thus combining two separate commands (SUM FOR and COUNT FOR) into one.

Caution: do not use expressions of different types or widths in reports, since this may cause the REPORT command to fail.

## IN(

Inputs a single character from a sequential file.

``` IN(str var[,<filenum>])

str var      stores the character```

Option:

` <filenum>      the DOS file number (between 1 and 4)`

Type: logical

This function reads the next character of the DOS file (opened with the ROPEN() function into the string variable str var; if str var does not exist, it will be created. str var cannot be a matrix variable.

If filenum is not given, filenum=1 is assumed. IN( returns T if successful, F otherwise.

This function is especially useful to communicate over the standard COM1, COM2 devices, for conversion of WordStar or other non-standard files to standard ASCII files, to encrypt/decrypt a file through a translation table.

IN(, GET(, READ(, and WRAP( are the only functions that change the contents of the memory variable used as an argument.

See the functions OUT(, ROPEN(, WOPEN(, SEEK(, SSEEK(, and CLOSE(.

## IFKEY(

Tests if a character is waiting in the keyboard buffer.

` IFKEY()`

Type: logical

It is often useful to test whether a key has been pressed on the keyboard without waiting indefinitely if a key is not pressed.

The IFKEY( function returns T (true) if a keystroke is waiting in the keyboard buffer, F (false) if not. The keyboard buffer is not affected.

Example in a program, to create a timing loop that ends as soon as any key is pressed:

```start=VAL(TIME(seconds))
DO WHILE VAL(TIME(seconds))-start<3
IF IFKEY()
BREAK
ENDIF
ENDDO
```

## INKEY(

Waits and gets numeric value of keyboard entry.

`INKEY()`

Type: numeric

This function suspends program execution until a key is pressed. It returns a number identifying the key. Nothing is displayed on the screen. Any key can be read (except Alt, Ctrl, and shift which merely affect the characters produced by other keys) including all function keys, editing keys, and alternate keys. (Function keys F11 and F12 are not recognized by many computers' BIOS programs, and are ignored by Shark.)

Standard keys are identified with their ASCII number. Other keys return values between 256 and 511.

Examples:

```             Key                     INKEY()
Ctrl-C                    3
A                        65
Alt-A                   285
<F1>                    315
Shift-<F1>              340
Ctrl-<F1>               350
Alt-<F1>                360
```

To find out the number identifying a key, give the command:

```1>? INKEY()
```

and press <ENTER>, then the key; the character's number will be displayed.

Using INKEY() the user can program his own EDIT, set up cursor controlled menus, and so on.

A simple example:

INKEY() makes a more attractive screen than the WAIT command:

```CLS
@ 2,0 SAY "The following items will be included in your TOTAL:"
@ 3,0
LIST PERD,T1,T2,T3,T6,T9,P OFF
?
? "Press <Enter> to continue, or press <Esc> to return to menu"
A=INKEY()
```

## INSERT(

Overwrites a string at a given position with another string.

``` INSERT(str expover,<str exp>,<num exp>)

str expover    the string expression to overwrite
<str exp>          the string expression to overwrite with
<num exp>        the position```

Type: character

This function takes the string in str expover and overwrites the string with <str exp> starting at position <num exp>.

Examples:

```1>line='                              '
1>customer='John Smith'
1>ponumber='32109'
1>amount='910.56'
1>line=INSERT(line,customer,1)
1>? line
John Smith
1>line=INSERT(line,ponumber,15)
1>? line
John Smith    32109
1>line=INSERT(line,amount,25)
1>? line
John Smith    32109     910.56
1>line='            c                 '
1>newline=INSERT(line,customer,@('c',line))
1>? newline
John Smith
```

Note: The last example shows the use of INSERT( with "templates". The line variable is the template. The character "c" in it designates the place where the customer has to be inserted. Such templates are useful in report generators or for creating screen displays.

## INT(

Gives the integer part of a given number (the fractional part is discarded); useful for currency "rounding", for example.

Example:

```1> ? int(3.14159)
1> 3.00
```

## LEFT(

Gets the left part of a string.

``` LEFT(<str exp>, <num exp>)

<str exp>   the string from which the new string is formed
<num exp>   the number of characters to place in the new string
```

Type: character

This function takes the first <num exp> characters from the string <str exp>. It is equivalent to, but more efficient than:

```1>\$(<str exp>, 1,<num exp>).
```

If <num exp> is greater than the width of <str exp>, this function returns all of <str exp>.

Wherever an expression calls for a substring starting at the beginning, use LEFT( instead of \$( or SUBSTR(.

Example:

```1>a='David Bark'
1>? LEFT(a,5)
David
1>? LEFT(a,50)
David Bark
```

## LEN(

Gets the width (length) of a string.

``` LEN(<str exp>)

<str exp>  is the string being measured```

Type: numeric

This function returns the width (including trailing blanks) of the string <str exp>.

Examples:

```1>name='David Barberr'
1>? LEN(name)
13.00
1>? LEN(name+' is a nice boy')
27.00
```

Note that the width of a string is at least 1!

## LOC(

LOC( Gets the current byte position in a file opened with ROPEN( or WOPEN(.

LOC(<filenum>)

Option:

<filenum> is the number of the sequential or random file, 1 to 4 (default 1)

Type: number

Whenever a file is opened with the ROPEN( or WOPEN( function, Shark maintains a pointer at a current position, which is where any PUT( or GET( function would take effect. The position pointer is set with the SEEK( and SSEEK( functions, and reset every time the IN(, OUT, READ(, WRITE(, PUT(, and GET( function is used.

If filenum is not given, filenum=1 is assumed.

A common use of LOC( is to get the current position before a SEEK( so that the pointer can be reset to the original position after some operation.

## LOG(

LOG( <num exp>)

gives the natural logarithm of <num exp>

Type: number

Example:

```1>? log(100)
1> 4.60
```

## LOG10(

gives the base 10 logarithm of <num exp>

Type: number

Example:

```1>? log10(100)
1> 2.00
```

## LOWER(

Converts the string <str exp> to lower case.

` LOWER( <str exp>)`
<str exp> is the text to be converted to lower case

Type: character

All upper-case letters in the <str exp> are converted into lower case by the LOWER( function. See also the !( and UPPER( functions.

Examples:

```1>a='Aa12b'
1>? LOWER(a)
aa12b
1>? LOWER('David!')
david!
```

Note that only the upper-case letters, A-Z, are changed (to a-z). No other characters are affected.

## LTRIM(

Trims blanks from the left-hand side of a string:

LTRIM(<str exp> ) <str exp> the string to be trimmed

Type: character

This function gets rid of the blanks on the left of a string. See also TRIM( which removes the blanks on the right side of a string.

Examples:

1>a=' David ' 1>? a David 1>? LEN(a) 14.00 1>? LTRIM(a)+' is trimmed on the left' David is trimmed on the left 1>? LEN(LTRIM(a)) 9.00 1>blank=' ' 1>? LEN(LTRIM(blank)) 1.00

Note: LTRIM(blank) is a single blank.

```MASK(<operation>,<string>,<mask>)    Manipulates bits in a string based on comparison between 2 strings
<operation>       a number representing one of the three masking operations supported by SharkBase: AND, OR, and XOR
<string>          the string to be modified by the operation
<mask>            the string used to modify the bits in string1   ```

Type: character

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001, while the letter B has a decimal value of 66 and a binary value of 01000010. Although SharkBase has functions to set individual bits to 1 or 0 (SET( and RESET( respectively), MASK( can be used to change any number of bits at once.

The three MASK( operations are used to return a string that is the result of bitwise operations between two strings, comparing each bit in one string with the bit in the same position in the other string. If the two bits are both 1 (on or true), AND and OR both produce a 1 in that position, while XOR (exclusive OR) returns a 0. If one is a 1 and the other a 0, OR and XOR both produce a 1 and AND produces a 0. Finally, if both are 0, all three produce a 0.

There is one other operator of this type, known as the bitwise NOT, but it is not implemented through the MASK( function. Since the primary use of the bitwise NOT is to create indexes in decending order, this operation is implemented through the DESCEND( function. See DESCEND(.

The use of AND, OR and XOR is the same as in C and other low-level languages that permit access to data at the bit level, and will rarely be used by most SharkBase programmers. Those who require these operations already know how to use them and need no additional instructions for SharkBase.

Example in a program:

Given any screen color (See COLOR and SET COLOR), determine the reverse that SharkBase would use in highlighting input windows during READ operations (useful in using the same color to highlight messages and other text on the screen):

```CLS
DO WHILE t
INPUT 'Color.... ' to in
low=mod(in,16)             ;separate the low-order and high-order bits
hi=int(in/16)
out=low*16+hi              ;the rest of these operations are too complex to explain...just be assured it works
new=int(in/16)+16*mod(in,16)
:color=in
? 'Main Color..',in
:color=rev
? 'Reverse.....',rev
ENDDO
```

## MAX(

Given any two expressions of the same type, MAX( returns the higher value. It must be remembered that string comparisons are based on the ASCII value of the characters in the two strings. Comparing two logical expressions has no meaning.

You may find that a comparison between a numeric expression and a numeric field results in an error. This can be avoided by ensuring both arguments are an expression, accomplished most easily by adding 0 to a field.

Examples:

```1>? MAX(123,amount+0)         ;adding 0 ensures handling as an expression
5241.34
1>? MAX('hello','goodbye')
hello```
```MAX(<exp1>,<exp2>)     Compare two expressions of any type and return the larger.
<exp1>    any expression
<exp2>    any expression of the same type as <exp1>      ```

Type: Type: character/numeric/logical

Lightbar menu function; allows point-and-shoot selection from an on-screen menu.

```

choices     the number of choices offered by the menu
hotkeys     one character for each possible option, beginning
with zero (normally the exit option)
width       the width of the menu lightbar
```

Option:

`seconds   exit MENU( after this many seconds; function returns value of 65`

Type: numeric

The MENU( function pauses program execution and superimposes a movable lightbar (reverse-video line) over a menu of selections previously written to the screen, usually with TEXT.

The menu lightbar is moved up and down with the up arrow and dn arrow keys. If you press down arrow while on the bottom, the lightbar cycles automatically to the top. Similarly, pressing up arrow while on the top cycles to the bottom.

The user can select any item by moving the lightbar over it and pressing Enter, or entering its line number as a one-digit number. In either case, the line number selected is returned by the function, and the key pressed stored in the system variable :KEY. Both the function value and :KEY can be tested in a subsequent DO CASE structure to determine the program's next actions. The inkey() function displays the :KEY value:

```CLS
DO WHILE t
@ 10,0 SAY "To display a key code, press any key . . ."
? inkey()
ENDDO
```

If the user presses 0 or <Home> , MENU( returns zero, although the first line covered by the lightbar is 1. Options over 9 can be accessed only by the lightbar.

Alternately, you may choose to use the <hotkeys> option for this function's first argument. Instead of the number of choices, a string may be supplied. The length of the string determines the number of choices and the letters in the string math the numbers of the choice. For example, if if you supplied a string literal or variable with the value "Qmdn" for <hotkeys>, pressing "Q" or "q" would return zero, "M" or "m" would return 1, "D" or "d" would return 2, and "N" or "n" would return 3. <Hotkeys> may be caps or lower case; MENU( is not case-sensitive.

If any cursor key except , and <Home> is pressed, MENU( returns the number of the line highlighted by the lightbar, and :KEY contains the key number that would be returned by the INKEY( function. (If SET FUNCTION OFF, all function keys have the same effect as these cursor keys.)

While the MENU( function is active, all other typewriter keys are ignored.

Note: If an ON KEY structure is in effect, it is ignored while MENU( is waiting for input.

Examples:

1. This is a program which shows specifically the values returned by Menu( when any key is pressed:

```CLS
@ 19,46 say 'Returns'
@ 19,64 say ':KEY'
DO WHILE t
CURSOR 5,20
@ 20,50 say var
@ 20,65 say :KEY
ENDDO
```

2. In a simple real-life program:

```CLS
TEXT

 EXIT TO MAIN MENU
 PREPARE SALES TOTALS
 CALCULATE TAX SUMMARY FOR A TAX PERIOD
 PRINT OUT SALES TRANSACTIONS & MARGINS
 REVIEW DEPOSITS JOURNAL

ENDTEXT
CHOICE=0
CURSOR 8,12 ; positions cursor at row 8, column 12
CHOICE=MENU(4,1); 1-wide lightbar moves over 4 menu rows, saves value to choice
*
DO CASE
*** *** *** *** ***
CASE CHOICE = 0
... etc
CASE CHOICE = 1
... etc
```

3. Another real-life program:

```ERASE
WINDOW 1,2,23,77 double            ;draw frame around screen
@ 1,3 say DATE(full)
@ 3,3 say CEN(:company,74)
@ 5,3 say CEN('Payroll Menu',74)
WINDOW 8,25,22,75 blank            ;use WINDOW to position TEXT
TEXT paymenu                       ;menu text in external file
WINDOW
CURSOR 10,23
IF ans=0 .or. :key=335
ENDIF
@ ans+9,23 say CHR(149)             ;• character as bullet
DO CASE
CASE ans=1
... etc.
```

4. Part of the same program using both hotkeys and timeout:

```WINDOW 8,25,22,75 blank            ;use WINDOW to position TEXT
TEXT paymenu                       ;menu text in external file
WINDOW
CURSOR 10,23
hotkeys='Qeprsmwgf'                ;hotkeys can be a string variable
*                                  ;  this allows 8 options plus zero (quit)
IF ans=0 .or. :key=335 .or. ans=65 ;return of 65 means program timed-out
ENDIF
@ ans+9,23 say CHR(149)             ;• character as bullet
DO CASE
CASE ans=1
... etc.
```

## MIN(

Compare two expressions of any type and return the smaller.

```
MIN(exp1,exp2)

exp1    any character or numeric expression
exp2    any expression of the same type as exp1     ```

Type: character/numeric

Given any two expressions of the same type, MIN( returns the lower value. It must be remembered that string comparisons are based on the ASCII value of the characters in the two strings. (Comparing two logical expressions has no meaning.)

You may find that a comparison between a numeric expression and a numeric field results in an error. This can be avoided by ensuring both arguments are an expression, accomplished most easily by adding 0 to a field.

Examples:

```
1>? MIN(123,amount+0)         ;adding 0 ensures handling as an expression
123.00
1>? MIN('Hello','Goodbye')
Goodbye
```

## MOD(

The MODULO function returns the remainder of one number divided by another.

`MOD(<num exp1>,<num exp2>)`

For example:

```1>? MOD(5,2) gives the remainder of 5 divided by 2, e.g.
1.000000
1>? MOD(-3.14, .7)
-0.340000
```
```    MOD(<num exp1>,<num exp2>)  <num exp1> modulo <num exp1>: returns 0 if  <num exp2> is 0; returns the value num with the same sign
as <num exp1>, less than  <num exp2>, satisfying  <num exp1>=i*<num exp2>+num  for some integer i.

1>? MOD(5,2)                    this is the remainder of 5 divided by 2
1.000000
1>? MOD(-3.14, .7)
-0.340000
```

## MONTHS(

Computes dates and date differences in months.

```
MONTHS(<date1>,<date2>) or
MONTHS(<date1>,<num exp>)

<date1>      a string expression containing a valid date
<date2>      a string expression containing a valid date
<num exp>    a numeric expression such as a number of months
```

When <date2> is specified, MONTHS( returns number of months between the two dates. When <num exp> is specified, MONTHS( returns date that many months away

MONTHS( computes the difference between the two dates in months, or computes a date a given number of months before or after a specified date. Fractional parts of months are discarded.

If a computed date is after the last date of the month, the date will be adjusted to the last day of the month. For example, MONTHS('013190',1) results in 022890.

Examples:

```1>? MONTHS('04 06 90','04 29 90')
0.00
1>? MONTHS('01/01/90','02/01/90')
1.00
1>? MONTHS('02/01/90','01/01/90')
-1.00
1>? MONTHS('01/01/90','01/01/92')
24.00
1>? MONTHS('02/01/90',10)
120190
1>? MONTHS('01/01/90',-6)
070189
```

Note that the MONTH( and DATE( functions always count the days in leap years:

Thus, DAYS(2005-03-18,-365) may not give the same result as MONTHS(2005-03-18,-12)

## NDX(

Get information on index files in use.

``` NDX(type [,indexnum] [,<filenum>])

type       the name or number of the information required```

Options:

```    the number of the index being checked (1 to 7);
default is thge master index
<filenum>    the number of the data file to be checked```

Type: character/logical

NDX( is used to primarily in programs to get the information on the current environment in a form suitable for use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```Type           Explanation                          Result
1 or Name      name of index file                   string
2 or Key       key on which index was created       string
3 or DBF_Name  name of data file on which index
was created                        string
4 or Filter    TRUE if filter or FOR clause was
in effect when index was created    logical```

Shortcut: When specifying type by name, only the first character is required.

Examples:

```1>? NDX(n),NDX(key),NDX(dbf),NDX(filter)
CUST1.NDX CUSTNUM  CUSTOMER.DBF F
```

## NTX(

```This is an obsolete function identical to NDX(, which refers to the
discontinued Clipper .ntx file type.  The older Clipper NTX indexes are
no longer used in Shark.
```

## NUMTOC(

```Convert a decimal number to a hexadecimal string.

NUMTOC(type,number)

type      the length of the string to be created
number    the number to be converted

Type:  character

A general conversion function for converting decimal numbers into
hexadecimal values.  Input can be any number, and the returned string length
can be up to eight characters as follows:

The type can be given in either of two forms, a name or number (numeric
expression) as follows:
Type      Range of Number            String Length Returned
1      integer 0 to 255                  1 byte
2      integer -32768 to 32767           2 bytes
4      integer +/- 2 billion             4 bytes
8      a floating point number           8 bytes
Shortcut: When specifying type by name, only the first character is required.

Types 1, 2 and 4 return hexadecimal integers.  Any fractional parts are ignored.

When type is 1, this function is equivalent to CHR(.  Values outside
the range of 0 to 155 return the modulus of 256 for type 1.

The CTONUM(, RANK( and ASC( functions convert strings into numbers.

Do not confuse these function with STR( and VAL(, which convert decimal
numbers into their string representations, and vice versa.

Examples:
1>? NUMTOC(1,97)
a
1>? NUMTOC(2,25185)
ab
1>? NUMTOC(4,6513249)
abc
```

## OUT(

```
Outputs a single character to a sequential file.

OUT(str var [,<filenum>])

str var      contains the character

Option:

<filenum>  the DOS file number (between 1 and 4)

Type:  logical

This function outputs the character in str var to the sequential file
(opened with the WOPEN( function).

If filenum is not given, filenum=1 is assumed.  OUT( returns T if successful, F otherwise.

This function is especially useful to communicate over the standard COM1,
COM2 devices, for conversion of Word Star or other non-standard files to
standard ASCII files, to encrypt/decrypt a file through a translation table.

See the functions IN(, ROPEN(, WOPEN(, CLOSE(, SEEK(, SSEEK(, READ(, and WRITE(.
```

## PIC(

```
Formats the PICTURE of a number or string.

PIC(exp,format)

exp                  is the number or string to be formatted
format              the format clause

Type:  character

This function returns the exp formatted with the format clause
format.  See the command @ for the description of the format clauses.
PIC( is especially useful in preparing numeric values for printing.

PIC( always returns a string, even when a number or numeric expression
is being formatted.

Examples:
1>number=1123.89
1>format='9,999.99'
1>? PIC(number,'9,999.99')
1,123.89
1>? PIC(number,format)
1,123.89
1>format='9999'
1>? PIC(number,format)
1123
1>format='\$\$\$,\$\$\$.99'
1>? PIC(number,format)
\$1,123.89
1>format='\$\$\$,\$\$\$.999'
1>? PIC(number,format)
\$1,123.890
1>string='abcd'
1>format='xX9!'
1>? PIC(string,'xx9!')
abcD
1>? PIC(string,format)
abcD
1>format='X-X-X-X'
1>? PIC(string,format)
a-b-c-d
1>SET ZERO ON
1> ? 0,"*",str(0,5,2),"*",pic(0,"99.99"),"*","0"
0.00 *  0.00 *  0.00 * 0
1>SET ZERO OFF
1> ? 0,"*",str(0,5,2),"*",pic(0,"99.99"),"*","0"
*  0.00 *       * 0

```

## POW(

<num exp1> to the power <num exp2>

## PRINTER(

```
Test whether a printer is ready to print.

PRINTER(printernum)

Option:

printernum  the number of the LPT port (1 or 2)

Type:  logical

Whenever a program has to print, it needs a printer turned on and
on-line. When it is unsuccessful in printing, Shark intercepts the customary
DOS error (the infamous "Abort, Retry, Ignore?") and ends execution.

The PRINTER( function gives programmers a way to ensure the printer is
correctly set up before sending output to the screen.  This makes it possible
to suspend execution under program control, prompt for correction action, or
even SPOOL the output to a disk file instead of the printer.

Examples in programs:

DO WHILE .NOT. PRINTER()
WINDOW 10,10,15,69 DOUBLE
@ 12,10 SAY CEN('Turn on printer and press any key . . .',60)
RING
CURSOR 13,39
cc=INKEY()
WINDOW
ENDDO
IF .NOT. PRINTER(2)                 ;test LPT2
SPOOL printfil
ENDIF
IF PRINTER()
SET PRINT ON
ENDIF
```

## PUT(

```
Puts a string into a DOS file.

PUT(<str exp>[,filenum])

<str exp>         the string to overwrite with

Option:

<filenum>         the DOS file number (between 1 and 4)

Type:  logical

A DOS file was opened with the WOPEN( function; the character number
pointer was normally positioned with the SEEK( function.  This function
overwrites the file from the character chosen by the character number pointer
with the string <str exp>.

If filenum is not given, filenum=1 is assumed.  PUT( returns T if  successful, F otherwise.

See also the functions ROPEN(, WOPEN(, CLOSE(, SEEK(, and GET(.

Examples:
1>byte=CHR(13)
1>ok=WOPEN('test',3)
1>ok=SEEK(5221)
1>ok=PUT(byte,3)
```

## RAND(

```
Gives a random number in the range 0<=n<1.

RAND()

Option:

seed    a number used to initiate the random series

Type: numeric

A series of successive calls to the RAND( function will return a uniform
distribution of random numbers.

The first time RAND( is called, <seed> (any numeric expression) may be
specified. All subsequent calls should be without the seed.  If no initial
seed is provided, a random seed is chosen by the program.

RAND( always returns a number equal to or greater than 0 and less than 1.
If you need a random series of integers between zero and 5000, use
5000*RAND().

Note: if you provide the initial seed, every execution of RAND( ) will
return the same series of numbers.
```

## RANK(

```
Converts a character to its ASCII number.

RANK(<str exp>)

<str exp>      the first character of this string is converted

Type: numeric

The characters in the character set used by the computer are numbered
from 0 to 255.  For the first character of the string <str exp>, RANK(
returns the corresponding number. See also the functions ASC(, CHR(,
CTONUM(, and NUMTOC(.

Examples:

1>? RANK('x')
120.00
1>? RANK('xyz')
120.00

Note that only the first character of the string matters.
```

```
Reads a line of a sequential file.

str var      stores the line read in

Option:

<filenum>      the DOS file number (between 1 and 4)

Type:  logical

This function reads the next line of the sequential file (opened with the
ROPEN( function) into the string variable str var.  If str var does not
exist, it will be created;  str var cannot be a matrix variable.

A line is terminated by the carriage return character (ASCII 13).  Since
the line is read into a string variable, it cannot be longer than 254
characters.

If filenum is not given, filenum=1 is assumed.  READ( returns T if
successful, F otherwise.

In Shark programs, READ( normally appears in an IF or DO WHILE command.

READ(, IN(, GET(, and WRAP( are the only functions that change the
contents of the memory variable used as an argument.

See the functions WRITE(, ROPEN(, WOPEN(, CLOSE(, IN(, OUT(, and SSEEK(.

Examples:

1. In Conversational Shark:

1>ok=ROPEN('a:label.prg')
1>? line

2. Two programs to print a text file, TEST (in the second version it is
assumed that TEST has no more than 20 lines):
SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test')
? line
ENDDO
ok=CLOSE()
ENDIF
DIM CHAR 80 matrix
SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test',1)
REPEAT 20 times VARYING num
matrix[num]=input,
ELSE
BREAK
ENDIF
ENDREPEAT
IF CLOSE(1)
? matrix
ENDIF
ENDIF
```

## RECNO(

```
Gets the current record number in any open data file.

RECNO(<filenum>)

Option:

<filenum>    the number of any open data file; default is the selected data file

Type: numeric

This function returns the record number of the current record of any
specified data file; if no <filenum> is given as in recno(), returns the record number the
selected file.  Note that ? RECNO() displays the current record number in the
form specified by the system variable :PICTURE (see Section 2.7).

Shark also has a more limited form of this function, #, which applies
only to the selected data file.

Examples:
1>USE employee
1>USE#2 customer
1>? RECNO(1)
1.00
1>GO BOTTOM
1>? RECNO(1)
6.00
1>GO TOP
1>? RECNO()
1.00
1>SKIP#2 2
1>? RECNO(2)
3.00
```

## REMLIB(

Removes a library entry. REMLIB(volume) volume the number of the library entry to be removed.

Type: logical

This function deletes a library entry. The function accepts the library volume number you wish to delete as its argument and returns T (true) if the delete operation was successful, F (false) if not. Once a library entry (volume) is deleted, its space in the library is made available for new text. Libraries are created with the SET LIBRARY TO command. Example: 1>? REMLIB(50) T

## REPLACE(

Replaces, in a string expression, all occurrences of a string with another string.

` REPLACE(<str exp>,<str exp1>,<str exp2>)  `

Replace in the string expression <str exp> all occurrences of the string <str exp1> with the string <str exp2>

Type: character

This function looks up the first occurrence of . This process continues as long as <str exp1> occurs in <str exp>.

Examples:

1. A field contains a number as right justified characters, padded on the left with blanks. The following REPLACE( changes these numbers to right justified numbers padded on the left with zeros.

```1>number='     123'
1>number=REPLACE(number,' ','0')
1>? number
00000123
```

2. In writing checks, dollar amounts may be left padded with dollar signs:

```1>number='     123.11'
1>number=REPLACE(number,' ','\$')
1>? number
\$\$\$\$\$123.11```

3. Renaming a variable in a program line. The variable OLDN is renamed FIRSTNUMB.

```1>line='newn=oldn+oldn+(oldn/3)'
1>line=REPLACE(line,'oldn','firstnumb')
1>? line
newn=firstnumb+firstnumb+(firstnumb/3)
```

## RESET(

Sets a bit in a string to 0.

``` RESET(<str exp>,bit position)

<str exp>       the string or string expression on which the
function is to act
bit position  the number of the bit, numbered from the left
starting at 1, which is to be set to zero   ```

Type: logical

A bit is any of the eight binary digits in a character's ASCII number representation. Each bit can have only one of two possible values, 0 and 1.

The SET( and RESET( functions are used to manipulate the bits within a string or string expression. SET( makes a bit 1, and RESET( makes a bit 0. The BIT( function tests the value of a specific bit.

Among the chief uses for these functions is compression of logical (true/false) data by using just one bit for each data item instead of an entire byte for a logical field or two bytes for a logical variable.

See the BIT( function for programming examples.

Examples:

```1>str='PS'
1>? BIT(str,15)
T
1>str=RESET(str,15)
1>? str,BIT(str,15)
PQ F
```

## RIGHT(

Gets the right-hand part of a string.

` RIGHT(<str exp>, <num exp>)  `

<str exp> the string from which the new string is formed <num exp> the number of characters to place in the new string

Type: character

This function returns the last (that is, the rightmost) <num exp> characters from the string <str exp>.

If <num exp> is greater than the width of <str exp>, this function returns all of <str exp>.

Example:

```1>a='David Bark'
1>? RIGHT(a,5)
Bark
1>? RIGHT(a,50)
David Bark
```

## ROPEN(

Opens a DOS file for reading.

``` ROPEN(<str exp> [, <filenum> ])

<str exp>   the file name```

Option:

`<filenum>   the DOS file number (between 1 and 4) `

Type: logical

This function opens <str exp>, a DOS file (in particular, a sequential file or input device, such as COM1), for reading only. The current position pointer (see the SEEK( function) is set to the beginning of the file.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

ROPEN( returns T if successful, F otherwise.

See the functions WOPEN(, CLOSE(, READ(, WRITE(, IN(, OUT(, GET(, PUT(,SEEK(, and SSEEK(.

Examples:

```1>? ROPEN('a:label.prg')
T```

In an Shark program, ROPEN( normally appears in an IF command:

```IF ROPEN('file',2)
? data
ENDDO
ok=CLOSE(2)
ENDIF
```

## ROW(

Gets print row position.

` ROW() `

Type: numeric

This function gives the current row (line) position of the cursor; if the printer is on, it returns the column position of the printer head. See the commands SET PRINT ON and SET FORMAT TO PRINT, and the function COL(.

Example:

`@ ROW()+1,COL()+3 SAY 'Hello'`

prints 'Hello' starting on the next line three characters to the right of the end of the last printing.

## SEEK(

Goes to a given character number in a DOS file.

` SEEK(<num exp> [,filenum])  `

<num exp> the character number

Option:

` <filenum>  a DOS file number (between 1 and 4)`

Type: logical

This function repositions the character number pointer in the DOS file (opened with the ROPEN( or WOPEN( function) to the value given by <num exp>.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

If SEEK( is successful, it returns T (true); otherwise F (false). In a Shark program, SEEK( normally occurs in an IF or DO WHILE command.

Once the character pointer is properly positioned, use the GET( and PUT( functions to manipulate the characters.

See the functions SSEEK(, ROPEN(, WOPEN(, CLOSE(, GET(, and PUT(.

Example:

```1>ok=ROPEN('a:label.prg',4)
1>ok=SEEK(522,4)
```

## SET(

Sets a bit in a string to 1.

```
SET(<str exp>,bit position)

<str exp>        the string or string expression on which the
function is to act
bit position  the number of the bit, numbered from the left
starting at 1, which is to be set to 1   ```

Type: logical

A bit is any of the eight binary digits in a character's ASCII number representation. Each bit can have only one of two possible values, 0 and 1.

The SET( and RESET( functions are used to manipulate the bits within a string or string expression. SET( makes a bit 1, and RESET( makes a bit 0. The BIT( function tests the value of a specific bit.

Among the chief uses for these functions is compression of logical (true/false) data by using just one bit for each data item instead of an entire byte for a logical field or two bytes for a logical variable.

See the BIT( function for programming examples.

Examples:

```1>str='PQ'
1>? BIT(str,15)
F
1>str=RESET(str,15)
1>? str,BIT(str,15)
PS T
```

## SPACE(

Gets the amount of space left in the data space. SPACE()

Type: numeric

This function returns the available memory in the 64K data space (see Appendix A).

Example:

```1>? SPACE()
27155.00
```

As a general rule, when SPACE is down to less than 500.00, there is not a lot of room left for code & variables!

## SIN(

sine of <num exp> in radians

## SINH(

hyperbolic sine of <num exp>

## SQRT(

square root of <num exp>

## SSEEK(

Goes to a given line number in a sequential file.

```
SSEEK(<num exp> [,<filenum>)

<num exp>      the line number    ```

Option:

```
<filenum>      the DOS file number (between 1 and 4)```

Type: logical

This function repositions the line number pointer in the sequential file (opened with the ROPEN( function) to the value given by <num exp>.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

See the functions SEEK(, ROPEN(, WOPEN(, CLOSE(, READ(, IN(, and OUT(.

Example:

```1>ok=ROPEN('a:label.prg',4)
1>line=''
1>ok=SSEEK(5,4)
1>? ok
T
1>? line
GOTO top
1>ok=SSEEK(900,4)
1>? ok
F
```

## STR(

Type: character

Converts a number to a string.

```
STR(<num expression>,<width num expression>[,<decimals num expression<])

<num expression>        the number to be converted
<width num expression>  the width of the string
```

Example:

```1> ? STR(1234,4)
1>     1234
1> ? STR(1234,12)
1>             1234

```

Option:

```
<decimals num expression> the number of decimals
```

This function gets a number by evaluating the <num expression>, and converts it into a string of given width. Optionally, the number of decimals can be specified (the default is 0). See also PIC(.

Examples:

```1>x=123.456
1>? STR(x,8)
123
1>? LEN(STR(x,8))
8.00
1>? STR(x,10)
123
1>? STR(x,10,1); NOTE 'x' is the num expression; '10' is the width of the num expression; and '1' is the number of decimals
123.4
```

When combined with the VAL( function, STR( is a convenient way of rounding decimal numbers with a given precision.

For example:

```1>:PICTURE='9999.99999'
1>a=29.95748
1>? a
29.95748
1>? VAL(STR(a+.005,10,2))
29.96000
1>? VAL(STR(a+.00005,10,4))
29.95750
```

## SUBSTR(

Type: character

Gets a substring of a string.

```
SUBSTR(<str exp>, <start num exp>, <width num exp>)

<str exp>         the string from which the new string is formed
<start num exp>   the position from which the new string is taken
<width num exp>   the number of characters to place in the new string
```

This function, a synonym for the \$( function, takes the string in <str exp> from position <start num exp> (fractions are thrown away); the number of characters taken is <width num exp>. (In both numeric expressions, the fractions are disregarded).

Examples:

```1>name='David Barberr'
1>? SUBSTR(name, 7,3)
Bar
1>? SUBSTR(name, 7,12)
Barberr
1>? LEN(SUBSTR(name,7,12))
7.00
```

Note that SUBSTR(name,7,12) is of width 7, not 12; there are only 7 letters left in name from position 7.

```1>s=3
1>t=1
1>? SUBSTR(name+name,(s+t)/2,1.9)
a
```

Note that 1.9 was taken as 1.

## TAN(

tangent of <num exp> in radians

## TANH(

hyperbolic tangent of <num exp>

## TEST(

Tests a string whether it is a valid expression.

```TEST(<str exp>)

<str exp> the string to be tested

Type: logical```

This function tests the string in <str exp> as to whether it is a valid expression; in particular, all variables must be defined and must be of the proper type. It returns T if it is, F otherwise. If the test is successful, TYPE( can be used to find the type of the expression.

In a Shark program, use TEST( to find out whether a selection criteria typed in by the user is correct. Or use it to ensure that a variable exists in a subroutine that may be called from several programs.

Examples:

```1>? TEST('check=0')
F                                   false because check is not defined
1>check=0
1>? TEST('check=0')
T
1>? TEST('check=0.or.check=1')
T
1>? TEST('check="A".or.check=1')
F                                   false because "A" is of character
type
1>? TEST('num')
F
1>num=5
1>? TEST('num')
T
1>? TEST('num+')                    false because the second operand
is missing
F
IF .NOT. TEST('check')
check=0
ENDIF
```

## TIME(

Gets the system time.

```
TIME(type)```

Option:

```
type      one of three types of information requested, as listed below    ```

Type: character

This function returns a string containing the current system time, and changes the format of the system variable :TIME to this format. (See the system variable :TIME in Section 2. Recall that :TIME is initialized when Shark starts up, but can be reinitialized with a :TIME= command.)

The type can be given in either of two forms, a name or number (numeric expression) as follows:

```Type                Explanation                                      Example
1 or HMS         Hours,minutes,seconds,hundredths                17:26:36.07
2 or AMPM        Hours,minutes with AM/PM                        5:36 pm
3 or Seconds     Seconds since midnight                          62804.80```

Shortcut: When specifying type by name, only the first character is required. The default parameter is 1, the time in the 24-hour format hh:mm:ss.hh.

Examples:

```1>? :TIME
15:45:59
1>? TIME(2)
3:46 pm
1>:TIME
3:46 pm
start=VAL(TIME(seconds))
program lines
finish=VAL(TIME(seconds))
? 'Program execution took',start-finish,'seconds.'```

This displays how long the running of <program lines> took, in seconds.

## TRIM(

Trims blanks from the right-hand side of a string.

```
TRIM(<str exp>)

<str exp>        the string to be trimmed  ```

Type: character

Shark stores strings in fields padded on the right with blanks. In actual use, these blanks may get in the way. TRIM( gets rid of the blanks on the right of a string. TRIM( can be used in the key of an index. See also LTRIM( .

Examples:

```1>a='Vancouver     '
1>b='BC'
1>? a+','+b
Vancouver     ,BC
1>? LEN(a)
14.00
1>? trim(a)+','+b
Vancouver,BC
1>? LEN(TRIM(a))
9.00
1>blank='     '
1>? LEN(TRIM(blank))
1.00```

Note: TRIM(blank) is a single blank.

## TYPE(

Gets the type of an expression.

` TYPE(exp)`
exp = any expression

Type: character

For an expression, exp, this function returns the type of the expression as a one character string:

```C    for character
L    for logical
N    for numeric
M    for memo
F    for float      ;a type used by other xBase languages; treated as N internally
D    for date       ;a type used by other xBase languages; treated as C internally
U    Undefined      ;created by GLOBAL or VARIABLES command, but not yet given
a value or type```

To test whether a string is a valid expression, use the TEST( function.

Examples:

```1>a='name'
1>? TYPE(a)
C
1>? TYPE(a+a)
C
1>n=12
1>? TYPE(a+n)
1. Invalid variable type found when executing an expression.
1>? TYPE(a<a)
L
1>? TYPE(a<a .OR. n<5)
L
1>? TYPE(note)
M
1>? TYPE(date)
D
1>TYPE(n+5/10)
N
```

## UPPER(

```
Converts a string to upper case.

UPPER(<str exp>)

<str exp>    the text to be converted to upper case

Type:  character

All lower-case letters in the <str exp> are converted into upper case by
the UPPER( function, which is a synonym for the !( function.  See also the
LOWER( function.

Examples:

1>a='Aa12b'
1>? UPPER(a)
AA12B
1>? UPPER('David!')
DAVID!
Note that only the lower-case letters are changed.
```

## VAL(

```
Converts a string to its numeric value.

VAL(<str exp>)

<str exp>      the string to be evaluated

Type: numeric

This function takes the string <str exp> which is a number, and returns
it as a number.  If the whole string cannot be interpreted as a number, it
takes as much of the front part as it can.

Examples:

1>a='123.23'
1>? VAL(a)
123.23
1>? VAL(123.23)
1. Invalid variable type found when executing an expression.
1>? VAL('a12')
0.00
1>? VAL('12a')
12.00
1>? VAL(DATE(2))
yields the current month as a number.
```

## WOPEN(

```
Opens a DOS file for writing.

WOPEN(<str exp>[,<filenum>])

<str exp>      the file name

Option:

<filenum>      the DOS file number (between 1 and 4)

Type: logical

This function opens the DOS file, and in particular, the sequential file
<str exp> (or output device, such as COM1:) for writing; if the file does not
exist, it will be created.  If filenum is not given, filenum=1 is assumed.  If
no file extension is given, the extension TXT is used.  It returns T if
successful, F otherwise.

See the functions ROPEN(, CLOSE(, GET(, PUT(, SEEK(, SSEEK(, WRITE(,

Example:
1>ok=WOPEN('a:label.prg')
1>? ok
T

In an Shark program, WOPEN( normally appears in an IF command:

IF WOPEN('file',2)

2. Two programs to print a text file, TEST (in the second version it is
assumed that TEST has no more than 20 lines):

SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test')
? line
ENDDO
ok=CLOSE()
ENDIF
```

## WRAP(

```
Wraps text for output.

WRAP(str var, <num exp>)

<str exp>        the string to be wrapped
<num exp>        the line width

Type:  character

This function returns one line of text with word wrapping from the string
in str var; str var now contains what is left of the string.  In other
words, the string returned will contain as many words as will fit in a line
(the line width is given by <num exp>).  If the whole contents of str var is
one line, str var becomes the blank string (of length 1)

WRAP(, IN(, GET(, and READ( are the only functions that change the
contents of the memory variable used as an argument.

Examples:
1>text='This text line is going to be wrapped in a printed line of width 30.'
1>? text
This text line is going to be wrapped in a printed line of width 30.
1>temp=text
1>WRAP(temp,30)
This text line is going to be
1>? temp
wrapped in a printed line of width 30.
1>WRAP(temp,30)
wrapped in a printed line of
1>? temp
width 30.
1>WRAP(temp,30)
width 30.
1>? temp
1>? LEN(temp)
1.00
```

## WRITE(

```
Writes a new line into the sequential file.

WRITE(str var[,<filenum>])

str var   the line to be written

Option:

<filenum>      the DOS file number (between 1 and 4)

Type: logical

This function writes (appends) the contents of the string variable
str var to the end of a sequential file opened with the WOPEN( function.
If filenum is not given, filenum=1 is assumed.  WRITE( returns T if
successful, F otherwise.
See the functions ROPEN(, WOPEN(, READ(, IN(, OUT(, GET(, PUT(, and CLOSE(.

Example:

1>ok=WOPEN('customer.frm',2)
1>ok=WRITE('FIELDS - cust,orderno,amount',2)
1>ok=CLOSE(2)
creates the CUSTOMER.FRM report form file:
FIELDS - cust,orderno,amount
Now the command REPORT CUSTOMER will run the report.  This example
illustrates how a program can be written that creates a report form file.
In an Shark program, WRITE( normally appears in an IF command:
IF WRITE('file',2)

```