# Module `useful` - General utilities

General utilities.

This module contains miscellaneous utilities for occam-pi programs. The aim is to provide somewhere to collect code that should obviously be in the standard library (that is: it's been needed by more than one occam-pi program), but where there isn't an existing module that it should obviously go into.

This module includes a large number of `PROC`s for formatted output that aren't individually documented. These take varying numbers of arguments, and have names that end with a "format string" indicating the types of the arguments they support. Several families of `PROC`s are provided for different purposes:

- `print.*` write to a `CHAN BYTE`;
- `prints.*` write to a `SHARED CHAN BYTE`, claiming it first;
- `format.*` return a string as a `RESULT MOBILE []BYTE`;
- `trace.*` write directly to standard error, taking no additional parameters.

The output channel or variable always appears at the end of the argument list.

The formatting characters supported are:

- `s` for a string as a `VAL []BYTE`;
- `i` for a decimal integer as a `VAL INT`;
- `r` for a decimal floating-point value as a `VAL REAL32`;
- `b` for a boolean value as a `VAL BOOL`;
- `n` for a newline (taking no parameter).

For example, if you wanted to print a string and an integer followed by a newline to a channel, you could use `PROC print.sin (VAL []BYTE s, VAL INT i, CHAN BYTE out!)` as follows:

    print.sin ("Number of interrupts: ", count, out!)

`PROC`s are provided for all valid combinations of up to 5 formatting characters, with the restrictions that `n` is only permitted at the end of a format string, and `i`, `r` and `b` cannot occur next to each other. (For example, `trace.sisin` is provided, but `trace.siin` and `trace.sinin` are not.)

## Index

- Record `COMPLEX32` - A 2*32-bit complex number
- Record `COMPLEX64` - A 2*64-bit complex number
- Record `VECTOR2` - A two-dimensional vector
- Record `VECTOR3` - A three-dimensional vector
- Function `abs.int` - Remove the sign from an integer
- Function `abs.real32` - Remove the sign from a real
- Process `append.int` - Append a number to a string
- Process `append.string` - Append a string to a string
- Function `clamp.int` - Limit an integer to a particular range
- Function `cross.product3` - Compute the cross product of two s
- Function `deg.to.rad` - Convert an angle in degrees into radians
- Function `is.whitespace` - Is a character whitespace?
- Function `mag.squared2` - Compute the square of the magnitude of a
- Function `mag.squared3` - Compute the square of the magnitude of a
- Process `matrix.add` - Add two matrices
- Process `matrix.multiply` - Compute the ordinary product of two matrices
- Function `max.int` - Find the greater of two integers
- Function `max.real32` - Find the greater of two reals
- Function `min.int` - Find the lesser of two integers
- Function `min.real32` - Find the lesser of two reals
- Function `normal3` - Compute the normal to the plane defined by the two given vectors
- Function `normalise2` - Normalise a
- Function `normalise3` - Normalise a
- Operator `* (VECTOR2, [2][2]REAL32)` - Multiply a by a transformation matrix
- Operator `* (VECTOR3, [3][3]REAL32)` - Multiply a by a transformation matrix
- Process `out.vector2` - Print a
- Process `out.vector3` - Print a
- Function `rad.to.deg` - Convert an angle in radians into degrees
- Process `resize.string` - Resize a string, keeping its contents intact
- Function `rotate2` - Generate a transformation matrix that rotates a 2D point around the origin
- Function `rotate3.x` - Generate a transformation matrix that rotates a 3D point around the X axis
- Function `rotate3.y` - Generate a transformation matrix that rotates a 3D point around the Y axis
- Function `rotate3.z` - Generate a transformation matrix that rotates a 3D point around the Z axis
- Process `rstrip.string` - Remove trailing whitespace from a string
- Function `same.string` - Compare two strings for equality
- Process `update.max.int` - Update a running maximum value
- Function `wrap.int` - Wrap array indexes around

## Declarations

### `vector.occ`:28Process `out.vector2`

`PROC out.vector2 (VAL VECTOR2 v, CHAN BYTE out!)`

Print a `VECTOR2`.

### `vector.occ`:42Function `normalise2`

`VECTOR2 FUNCTION normalise2 (VAL VECTOR2 v)`

Normalise a `VECTOR2`.

#### Parameters:

`VAL VECTOR2` | `v` | Input vector

#### Returns:

`VECTOR2` |  | Unit vector parallel to `v`

### `vector.occ`:47Process `out.vector3`

`PROC out.vector3 (VAL VECTOR3 v, CHAN BYTE out!)`

Print a `VECTOR3`.

### `vector.occ`:64Function `normalise3`

`VECTOR3 FUNCTION normalise3 (VAL VECTOR3 v)`

Normalise a `VECTOR3`.

#### Parameters:

`VAL VECTOR3` | `v` | Input vector

#### Returns:

`VECTOR3` |  | Unit vector parallel to `v`

### `vector.occ`:68Function `cross.product3`

`VECTOR3 FUNCTION cross.product3 (VAL VECTOR3 a, b)`

Compute the cross product of two `VECTOR3`s.

### `vector.occ`:80Function `normal3`

`VECTOR3 FUNCTION normal3 (VAL VECTOR3 a, b)`

Compute the normal to the plane defined by the two given vectors.

### `math.occ`:29Function `abs.int`

`INT FUNCTION abs.int (VAL INT n)`

Remove the sign from an integer.

#### Parameters:

`VAL INT` | `n` | Input value

#### Returns:

`INT` |  | `-n` if `n` is negative, else `n`

### `math.occ`:44Function `min.int`

`INT FUNCTION min.int (VAL INT a, b)`

Find the lesser of two integers.

#### Parameters:

`VAL INT` | `a`, `b` | Integers to compare

#### Returns:

`INT` |  | The lesser of `a` and `b`

### `math.occ`:59Function `max.int`

`INT FUNCTION max.int (VAL INT a, b)`

Find the greater of two integers.

#### Parameters:

`VAL INT` | `a`, `b` | Integers to compare

#### Returns:

`INT` |  | The greater of `a` and `b`

### `math.occ`:74Function `abs.real32`

`REAL32 FUNCTION abs.real32 (VAL REAL32 n)`

Remove the sign from a real.

#### Parameters:

`VAL REAL32` | `n` | Input value

#### Returns:

`REAL32` |  | `-n` if `n` is negative, else `n`

### `math.occ`:89Function `min.real32`

`REAL32 FUNCTION min.real32 (VAL REAL32 a, b)`

Find the lesser of two reals.

#### Parameters:

`VAL REAL32` | `a`, `b` | Reals to compare

#### Returns:

`REAL32` |  | The lesser of `a` and `b`

### `math.occ`:104Function `max.real32`

`REAL32 FUNCTION max.real32 (VAL REAL32 a, b)`

Find the greater of two reals.

#### Parameters:

`VAL REAL32` | `a`, `b` | Reals to compare

#### Returns:

`REAL32` |  | The greater of `a` and `b`

### `math.occ`:121Process `update.max.int`

`PROC update.max.int (INT max, VAL INT value)`

Update a running maximum value. If `value` is greater than `max`, `max` will be set to `value`.

#### Parameters:

`INT` | `max` | The running maximum
`VAL INT` | `value` | The input value

### `math.occ`:137Function `clamp.int`

`INT FUNCTION clamp.int (VAL INT in, left, width)`

Limit an integer to a particular range. For example, if you call this with `left = 3` and `width = 3`, then the output value will be in the range `3 .. 5`.

#### Parameters:

`VAL INT` | `in` | Input value
`VAL INT` | `left` | The lowest value in the range
`VAL INT` | `width` | The width of the range

#### Returns:

`INT` |  | A value in the range `left .. (left + width - 1)`

### `math.occ`:156Function `wrap.int`

`INT FUNCTION wrap.int (VAL INT i, max)`

Wrap array indexes around. If given `-1`, this will return `max - 1`; if given `max + 1`, this will return `1`. This is not quite the same thing as `\ max`, since that doesn't do the right thing for negative numbers.

### `math.occ`:168Function `deg.to.rad`

`REAL32 FUNCTION deg.to.rad (VAL REAL32 deg)`

Convert an angle in degrees into radians.

### `math.occ`:172Function `rad.to.deg`

`REAL32 FUNCTION rad.to.deg (VAL REAL32 rad)`

Convert an angle in radians into degrees.

### `string.occ`:29Process `resize.string`

`PROC resize.string (MOBILE []BYTE s, VAL INT new.size)`

Resize a string, keeping its contents intact.

#### Parameters:

`MOBILE []BYTE` | `s` | String to resize
`VAL INT` | `new.size` | New length

### `string.occ`:37Process `append.string`

`PROC append.string (MOBILE []BYTE out, VAL []BYTE in)`

Append a string to a string.

#### Parameters:

`MOBILE []BYTE` | `out` | String to append to
`VAL []BYTE` | `in` | String that will be appended to `out`

### `string.occ`:48Process `append.int`

`PROC append.int (MOBILE []BYTE out, VAL INT n)`

Append a number to a string.

#### Parameters:

`MOBILE []BYTE` | `out` | String to which the decimal representation of `n` will be appended
`VAL INT` | `n` | Integer to format

### `string.occ`:82Function `same.string`

`BOOL FUNCTION same.string (VAL []BYTE a, b)`

Compare two strings for equality.

#### Parameters:

`VAL []BYTE` | `a`, `b` | Strings to compare

#### Returns:

`BOOL` |  | `TRUE` if the strings are the same, `FALSE` otherwise

### `string.occ`:100Function `is.whitespace`

`BOOL FUNCTION is.whitespace (VAL BYTE ch)`

Is a character whitespace?

#### Parameters:

`VAL BYTE` | `ch` | Character to examine

#### Returns:

`BOOL` |  | `TRUE` if `ch` is a space, tab, carriage-return or line-feed

### `string.occ`:113Process `rstrip.string`

`PROC rstrip.string (MOBILE []BYTE s)`

Remove trailing whitespace from a string.

### `matrix.occ`:33Process `matrix.multiply`

`PROC matrix.multiply (VAL [][]REAL32 a, b, [][]REAL32 result)`

Compute the ordinary product of two matrices. The number of columns in `a` must be the same as the number of rows in `b`. `result` must have the same number of rows as `a` and the same number of columns as `b`.

#### Parameters:

`VAL [][]REAL32` | `a` | First matrix
`VAL [][]REAL32` | `b` | Second matrix
`[][]REAL32` | `result` | Product

### `matrix.occ`:53Process `matrix.add`

`PROC matrix.add (VAL [][]REAL32 a, b, [][]REAL32 result)`

Add two matrices. `a`, `b` and `result` must all be the same size.

#### Parameters:

`VAL [][]REAL32` | `a` | First matrix
`VAL [][]REAL32` | `b` | Second matrix
`[][]REAL32` | `result` | Product

### `matrix.occ`:67Operator `* (VECTOR2, [2][2]REAL32)`

`VECTOR2 FUNCTION "**" (VAL VECTOR2 v, VAL [2][2]REAL32 m)`

Multiply a `VECTOR2` by a transformation matrix.

### `matrix.occ`:77Operator `* (VECTOR3, [3][3]REAL32)`

`VECTOR3 FUNCTION "**" (VAL VECTOR3 v, VAL [3][3]REAL32 m)`

Multiply a `VECTOR3` by a transformation matrix.

### `matrix.occ`:90Function `rotate2`

`[2][2]REAL32 FUNCTION rotate2 (VAL REAL32 theta)`

Generate a transformation matrix that rotates a 2D point around the origin.

#### Parameters:

`VAL REAL32` | `theta` | Angle (in radians)

#### Returns:

`[2][2]REAL32` |  | Transformation matrix

### `matrix.occ`:98Function `rotate3.x`

`[3][3]REAL32 FUNCTION rotate3.x (VAL REAL32 theta)`

Generate a transformation matrix that rotates a 3D point around the X axis.

#### Parameters:

`VAL REAL32` | `theta` | Angle (in radians)

#### Returns:

`[3][3]REAL32` |  | Transformation matrix

### `matrix.occ`:107Function `rotate3.y`

`[3][3]REAL32 FUNCTION rotate3.y (VAL REAL32 theta)`

Generate a transformation matrix that rotates a 3D point around the Y axis.

#### Parameters:

`VAL REAL32` | `theta` | Angle (in radians)

#### Returns:

`[3][3]REAL32` |  | Transformation matrix

### `matrix.occ`:116Function `rotate3.z`

`[3][3]REAL32 FUNCTION rotate3.z (VAL REAL32 theta)`

Generate a transformation matrix that rotates a 3D point around the Z axis.

#### Parameters:

`VAL REAL32` | `theta` | Angle (in radians)

#### Returns:

`[3][3]REAL32` |  | Transformation matrix

### `useful.inc`:71Record `VECTOR2`

`DATA TYPE VECTOR2`

A two-dimensional vector.

### `useful.inc`:85Function `mag.squared2`

`REAL32 INLINE FUNCTION mag.squared2 (VAL VECTOR2 v)`

Compute the square of the magnitude of a `VECTOR2`.

### `useful.inc`:93Record `VECTOR3`

`DATA TYPE VECTOR3`

A three-dimensional vector.

### `useful.inc`:107Function `mag.squared3`

`REAL32 INLINE FUNCTION mag.squared3 (VAL VECTOR3 v)`

Compute the square of the magnitude of a `VECTOR3`.

### `useful.inc`:116Record `COMPLEX32`

`DATA TYPE COMPLEX32`

A 2*32-bit complex number.

### `useful.inc`:173Record `COMPLEX64`

`DATA TYPE COMPLEX64`

A 2*64-bit complex number.