[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter (the largest in this manual) describes the programming language of MUIbase, including all available functions. This chapter, however, is not intended as a general guide about programming. You should be familiar with the basics about programming and should already have written some small (and correctly working :-)) programs.
15.1 Program editor Where to enter a MUIbase program. 15.2 External program source Using your favorite editor for programming. 15.3 Preprocessing Includes, conditional compilation, and constants. 15.4 Programming language The syntax of expressions.   Functions     15.5 Defining commands Function and variable definitions. 15.6 Program control functions Loops, conditional expressions, and more. 15.7 Type predicates Examining the type of an expression. 15.8 Type conversion functions Converting types. 15.9 Boolean functions AND, OR, and NOT. 15.10 Comparison functions Comparing values of expressions. 15.11 Mathematical functions Adding, Multiplying, etc. 15.12 String functions Useful stuff for strings. 15.13 Memo functions Useful stuff for memos. 15.14 Date and time functions Useful stuff for date and time values. 15.15 List functions List processing commands. 15.16 Input requesting functions Asking the user for input. 15.17 I/O functions File input and output commands. 15.18 Record functions Useful stuff for records. 15.19 Attribute functions Manipulating attributes. 15.20 Table functions Manipulating tables. 15.21 GUI functions Manipulating the user interface. 15.22 Project functions Getting information about the project. 15.23 System functions Operating system related functions. 15.24 Variables Pre-defined variables. 15.25 Constants Pre-defined constant values.   Useful information     15.26 Functional parameters Using functions as arguments in function calls. 15.27 Type specifiers Types for variables. 15.28 Semantics of expressions The meaning of an expression. 15.29 Function triggering How to use trigger functions. 15.30 List of obsolete functions Functions that disappeared and need replacement.   Function index Index of all functions.
To enter a program for a project, open the program editor by selecting menu item `Program - Edit'. If you are using the setting program source internal (see Program source), this will open the `Edit program' window containing:
The program editor is a non-modal window. You can leave the window open and still work with the rest of the application. You can close the editor at any time by clicking into its window close button. If you have done changes since the last successful compilation then a safety requester pops-up asking for confirmation to close the window.
In case you have set menu item `Program - Source' to `External' the external editor (see External editor) is launched with the filename of the external source file when choosing `Program - Edit'. This allows you to edit the program source using your favorite editor (see External program source).
You can also compile a project's program without opening the program editor by choosing menu item `Program - Compile'. This can be useful if you e.g. do changes to an external include file and want to incorporate these changes in the project's program.
By choosing menu item `Program - Source - External' and entering a filename you can make the program source of a project externally available. This allows you to load the program source into your favorite editor for programming.
If compilation is successful, the compiled program is set as the project's program and used when executing trigger functions. When you save a project, the last successfully compiled program is store with the project inside the project file. Thus, after saving and closing a project, the external source is no longer needed actually. You can specify if unneeded external source files should be deleted automatically by checking menu item `Preferences - Cleanup external program source'.
The status of menu item `Program - source' is stored with the project. If you re-open a project that uses the external source feature, the external source file is created after opening the project. If the external source file already exists and is different from the version stored inside the project, a safety requester asks for confirmation before overwriting the file.
On the Amiga you can send the compile
command to MUIbase' ARexx port
from your editor.
MUIbase then reads the external program source, compiles it, and returns the
compile status with an optional error message containing filename, line
and column, and an error description. This allows you to place the
cursor at the exact location of where a compile error occurred.
See ARexx compile, for details on return values and error format.
MUIbase programs are pre-processed similar to a C compiler preprocessing a C source file. This section describes how to use the preprocessing directives.
All directives start with a hash symbol # which should be the first character on a line. Space or tab characters can appear after the initial #.
15.3.1 #define Defining constants. 15.3.2 #undef Un-defining constants. 15.3.3 #include Including external files. 15.3.4 #if Conditional compilation. 15.3.5 #ifdef Conditional compilation. 15.3.6 #ifndef Conditional compilation. 15.3.7 #elif Conditional compilation. 15.3.8 #else Conditional compilation. 15.3.9 #endif Conditional compilation.
|
Example: `(PRINTF "X is %i" X)' prints `X is 1' (Occurrences of name in strings are not altered.)
The replacement of defined symbols is done syntactically which means that you can replace symbols with any text, e.g. you can define your own syntax like in the following example:
#define BEGIN ( #define END ) BEGIN defun test () ... END |
#define
directive to allow nested definitions.
However there is an upper limit of 16 nested definitions.
See also #undef, #ifdef, #ifndef.
|
See also #define, #ifdef, #ifndef.
|
An external file may include one or more other external files. However
there is an limit of 16 nested #include
directives. To protect files from
including them more than once, you can use conditional compilation.
Be careful when moving source code to external files! Debugging and tracking down errors is much harder for external files. Move only well tested and project independent code to external files.
|
#else
, #elif
, or #endif
is used for compilation,
otherwise (the expression results to NIL) the text up to the matching #else
,
#elif
, or #endif
is discarded for compilation.
Currently you can only use TRUE and NIL as constant expressions.
See also #ifdef, #ifndef, #elif, #else, #endif.
|
#define
directive then the
text up to the matching #else
, #elif
, or #endif
is used for compilation,
otherwise it is discarded.
See also #if, #ifndef, #elif, #else, #endif.
|
#define
directive then the
text up to the matching #else
, #elif
, or #endif
is used for compilation,
otherwise it is discarded.
See also #if, #ifdef, #elif, #else, #endif.
|
#elif
directives may appear between an #if
,
#ifdef
, or #ifndef
directive and a matching #else
or
#endif
directive. The lines following the #elif
directive
are used for compilation only if all of the following
conditions hold:
If the above conditions hold then subsequent #elif
and #else
directives are
ignored up to the matching #endif
.
See also #if, #ifdef, #ifndef, #else, #endif.
|
#else
and the matching #endif
are ignored. If the
preceding conditional indicates that lines would be ignored, subsequent
lines are included for compilation.
Conditional directives and corresponding
#else
directives can be nested. However there is a maximum nesting count
limit of 16 nested conditional directives
See also #if, #ifdef, #ifndef, #elif, #endif.
|
#if
,
#ifdef
, or #ifndef
. Each such directive must have a matching #endif
.
See also #if, #ifdef, #ifndef, #elif, #else.
MUIbase uses a programming language with a lisp-like syntax. Indeed several
constructs and functions have been adopted from standard lisp.
However, MUIbase is not fully compatible to standard lisp.
Many functions are missing (e.g. destructive commands) and the meaning of
some commands is different (e.g. the return
command).
15.4.1 Why lisp? The advantages of lisp. 15.4.2 Lisp syntax Syntax of programming language. 15.4.3 Kinds of programs Different kinds of programs used in MUIbase. 15.4.4 Name conventions Name conventions for program symbols. 15.4.5 Accessing record contents Using attributes and tables in programs. 15.4.6 Data types for programming Available data types for programming. 15.4.7 Constants Constant expressions. 15.4.8 Command syntax Syntax for describing all commands.
The advantage of a lisp-like language is that you can program in both, a functional and an imperative way. Functional languages are getting quite popular in mathematical applications. The basic concept in functional languages is the use of expressions. Functions are defined in a mathematical way and recursion is used heavily.
Imperative programming languages (e.g. C, Pascal, Modula) use an imperative description on how to compute things. Here, the state is the basic concept (e.g. variables) and a program computes its output by going from one state to another (e.g. by assigning values to variables).
Lisp combines both techniques and therefore you can choose in which way you want to implement things. Use the one which is more appropriate for the specific problem or which you like more.
A lisp expression is either a constant, a variable, or
a function application.
For calling functions, lisp uses a prefix notation.
The function and its arguments are surrounded by parenthesis.
For example, to add two values a
and b
, you write
(+ a b) |
a
and b
returned.
Expressions can be nested, that is, you can place an expression
as a sub-expression into another one.
Function evaluation is done by using a call-by-value scheme, this means that the arguments are evaluated first before a function is called.
If not stated otherwise, all functions are strict, that is,
all arguments of a function are evaluated before the function is called.
Some functions, however, are non-strict, e.g. IF
, AND
and
OR
. These functions may not evaluate all arguments.
MUIbase knows three kinds of programs. The first one is the project program kind. In a program of this kind you can define functions and global variables. The functions can be used as trigger functions for attributes. You define a project program in the program editor (see Program editor).
The second kind is the query program kind. For this kind you can enter expressions only. An expression is allowed to contain global variables and calls to functions that are defined in the project program. However, you cannot define new global variables or functions in a query program. Query programs are entered in the query editor (see Query editor).
The third kind of programs are filter expressions. Here you can only enter expressions that contain calls to pre-defined MUIbase functions. Not all pre-defined functions are available, only those that don't have a side effect, e.g. you cannot use a function that writes data to a file. Filter expressions are entered in the change filter requester (see Changing filters).
In a MUIbase program you can define symbols like functions and local or global variables. The names of these symbols must follow the following conventions:
To access tables and attributes in a MUIbase program, you have to specify a path to them. A path is a dot separated list of components where each component is the name of a table or an attribute.
Paths can either be relative or absolute. Absolute paths are specified with a table name as the first component, followed by a list of attributes that lead to the final attribute you want to access. E.g. the absolute path `Person.Name' accesses the `Name' attribute in the current record of table `Person', or the absolute path `Person.Father.Name' accesses the `Name' attribute in the record referenced by the `Father' field (a reference attribute to table `Person').
Relative paths already have a current table to which they are relative. For example in a filter expression the current table is the table for which you write the filter expression. The relative path for an attribute in the current table is simply the attribute name itself. For attributes that are not directly accessible from the current table but indirectly via a reference attribute, the same rules as for absolute paths apply.
It is not always clear if a specified path is a relative or an absolute one, e.g. suppose you are writing a filter expression for a table `Foo' that has an attribute `Bar' and there also exists a table `Bar'. Now entering `Bar' would be ambiguous, what is meant, the table or the attribute? Therefore all paths are first treated as relative ones. If no attribute is found for the specified path than the path is treated as global. In our example the attribute would be preferred.
But now, what if you want to access the table in the above example? Therefore the path must be given absolute. To indicate that a path is global you have to insert two colons in front of the path. In our example you would have to type `::Bar' for accessing the table.
To give you a better understanding of paths and their semantics, consider in our example that the `Bar' attribute in the `Foo' table is a reference to the `Bar' table, and the `Bar' table has an attribute `Name'. Now you can access the `Name' attribute by typing `Bar.Name' or `::Bar.Name'. Both expressions have a different meaning. `::Bar.Name' means to take the current record of table `Bar' and return the value of the `Name' attribute of this record, whereas `Bar.Name' takes the current record of table `Foo', extracts the record reference of the `Bar' field and uses this record for getting the value of the `Name' attribute.
To make a more complete example, consider that table `Bar' has two records. One that contains `Ralph' and one that contains `Steffen' in the `Name' field. The first record should be the current one. Furthermore table `Foo' has one record (the current one) whose `Bar' field refers to the second record of table `Bar'. Now `::Bar.Name' results to `Ralph' and `Bar.Name' to `Steffen'.
The programming language of MUIbase knows of the following data types:
Type Description Boolean all expressions. Non-NIL expressions are treated as TRUE. Integer long integer, 32 bit, choice values are automatically converted to integers Real double, 64 bit String strings of arbitrary length Memo like strings but line oriented format Date date values Time time values Record pointer to a record File file descriptor for reading/writing List list of items, NIL is empty list. |
The programming language of MUIbase can handle constant expressions which can be entered depending on the type of the expression:
Type Description Integer Integer constants in the range of -2147483648 to 2147483647 can be specified as usual. Values starting with 0 are interpreted as octal numbers, values starting with 0x as hexadecimal numbers. Real Floating point constants in the range of -3.59e308 to 3.59e308 can be specified as usual, in scientific or non-scientific format. If you omit the decimal point then the number may not be treated as a real number but as an integer instead. String String constants are any character strings surrounded by double quotes, e.g. "sample string". Within the double quotes you can enter any characters except control characters or new lines. However there are special escape codes for entering such characters: \n new line (nl) \t horizontal tabulator (ht) \v vertical tabulator (vt) \b backspace (bs) \r carriage return (cr) \f form feed (ff) \\ backslash character itself \" double quote \e escape code 033 \nnn character with octal code nnn \xnn character with hex code nn Memo Same as string constants. Date Constant date values can be specified in one of the formats `DD.MM.YYYY', `MM/DD/YYYY', or `YYYY-MM-DD', where `DD', `MM' and `YYYY' are standing for two and four digit values representing the day, month and year of the date respectively. Time Constant time values can be entered in the format `HH:MM:SS', where `HH' represent the hours, `MM' the minutes, and `SS' the seconds. |
In the remainder of this chapter, you will find the description of all commands and functions available for programming MUIbase. The following syntax is used for describing the commands:
This section lists commands for defining functions and global variables. The commands are only available for project programs.
15.5.1 DEFUN Function definition. 15.5.2 DEFUN* Function definition with hidden name. 15.5.3 DEFVAR Global variable definition. 15.5.4 DEFVAR* Global variable that remembers its value.
DEFUN
defines a function with the specified name, a list of arguments
that are passed to the function, and a list of expressions to evaluate.
|
The parameters varlist specifies the arguments of the function:
varlist: var1 ... |
It is also possible to add type specifiers to the arguments (see Type specifiers).
The function executes the expressions expr, ... one by one and returns the value of the last expression. The function may call further functions including itself. A self defined function can be called like calling a pre-defined function.
For example to count the number of elements of a list, you can define the following function:
(DEFUN len (l) (IF (= l NIL) 0 (+ 1 (len (REST l))) ) ) |
DEFUN
are listed in the pop-up list-views
of table and attribute requesters (see Creating tables and Creating attributes).
This command is only available for project programs.
DEFUN*
is the star version of DEFUN
and has the same
effect as DEFUN
(see DEFUN). The only difference is that functions
defined with DEFUN*
are not listed in the pop-up list-views
when creating or changing tables and attributes.
However, it is still possible to enter the function name in the corresponding
string fields.
This command is only available for project programs.
|
You can also add a type specifier to the variable name (see Type specifiers).
DEFVAR
is only available for project programs.
All DEFVAR
commands should be placed on top of all function definitions.
After execution of a trigger function (when MUIbase returns to the user
interface), all global variables loose their contents.
They are re-initialized with their initial value expr on the next
invocation of a trigger function.
If this is not desired, use the DEFVAR*
(see DEFVAR*) command
which allows to store the value of global variables between program calls.
Please use global variables rarely (if at all). All global variables have to be initialized (and expr be evaluated if given) whenever a trigger function is called from outside.
Example: `(DEFVAR x 42)' defines a global variable `x' with value 42.
There are some pre-defined global variables in MUIbase (see Pre-defined variables).
See also DEFVAR*, DEFUN, DEFUN*, LET.
|
DEFVAR*
has the same effect as the DEFVAR
command
(see DEFVAR) except that a variable defined with DEFVAR*
does not loose its value after the program completes.
On the first invocation of the program, var is initialized
with expr or NIL if expr is omitted.
Subsequent calls of the program do not evaluate expr again but use the
value of var from the previous call. This way it is possible to
transfer information from one program call to another without storing data
in an external file or a database table. Note, however, that
all global variables defined with DEFVAR*
loose their contents when
the project program is re-compiled. If you wish to permanently store
information, use a (possibly hidden) attribute in a table.
See also DEFVAR, DEFUN, DEFUN*, LET.
This section lists functions for program control, e.g. functions for defining local variables, loop functions, conditional program execution, loop control functions and more.
15.6.1 PROGN Compound statement, returns last expression. 15.6.2 PROG1 Compound statement, returns first expression. 15.6.3 LET Defining local variables. 15.6.4 SETQ Setting the value of variables, attributes and tables. 15.6.5 SETQ* Setting the value of variables, attributes and tables. 15.6.6 FUNCALL Calling a function with arguments. 15.6.7 APPLY Applying a function to an argument list. 15.6.8 IF If-then-else conditional program execution. 15.6.9 CASE Switch-case conditional program execution. 15.6.10 COND Powerful conditional program execution. 15.6.11 DOTIMES Loop over a range of integer values. 15.6.12 DOLIST Loop over a list. 15.6.13 DO Generic loop. 15.6.14 FOR ALL Loop over sets of records. 15.6.15 NEXT Jumping to next loop run. 15.6.16 EXIT Exiting a loop. 15.6.17 RETURN Returning from a function. 15.6.18 HALT Stopping program execution. 15.6.19 ERROR Aborting program execution with an error message.
To evaluate several expressions one by another the PROGN
construction can be used.
|
(PROGN
[expr ...])
.
Example: `(1 2 3 4)' results to 4.
See also PROG1.
Another way, besides the PROGN
function, to evaluate several expressions
one by another is the PROG1
expression.
|
Example: `(PROG1 1 2 3 4)' results to 1.
See also PROGN.
LET
defines a new block of local variables.
This is useful, e.g., for defining local variables of a function.
The syntax is
|
varlist: varspec ... |
varspec: |
In the case of a (
var expr)
specification,
the new variable is initialized with the given expression.
In the other case the new variable is set to NIL.
It is also possible to add type specifiers to the variables. (see Type specifiers).
After initializing all variables the list of expressions expr ... are evaluated and the value of the last one is returned.
For example, the following LET
expression
(LET ((x 0) y (z (+ x 1))) (+ x z) ) |
See also DOTIMES, DOLIST, DO, DEFVAR.
The SETQ
function sets values to variables, attributes and tables.
|
LET
expression).
Setting the value of a table means setting its program or
GUI record pointer: `(SETQ
Table expr)
'
sets the program record pointer of Table to the
value of expr, `(SETQ
Table* expr)
'
sets the GUI record pointer of it and updates the display.
For more information about program and GUI record pointers, see Tables.
SETQ
returns the value of the last expression.
Example: `(SETQ a 1 b 2)' assigns 1 to the variable `a', 2 to the variable `b' and returns 2.
See also SETQ*, LET, DEFVAR, Tables, Semantics of expressions.
SETQ*
is the star version of SETQ
(see SETQ)
and has similar effects. The difference is that when assigning
a value to an attribute, SETQ*
calls the trigger function of
that attribute (see Attribute trigger)
instead of directly assigning the value.
In case no trigger function has been specified for an attribute,
SETQ*
behaves like SETQ
and simply assigns the value
to the attribute.
Example: `(SETQ* Table.Attr 0)' calls the trigger function of `Table.Attr' with an argument of 0.
Warning: With this function it is possible to write endless loops, e.g.
if you have defined a trigger function for an attribute and this function
calls SETQ*
to set a value to itself.
FUNCALL
is used to call a function with arguments.
|
FUNCALL
returns the return value of the function call
or NIL if fun-expr is NIL.
For more information about functional expressions, see Functional parameters.
See also APPLY.
APPLY
is used to apply a function to a list of arguments.
|
cons
'ing
the arguments expr ... to list-expr.
In other words: calls the function fun-expr with the arguments
expr ... and list-expr expanded to its list elements.
The expression fun-expr can be any expression whose value is a pre-defined or user-defined function, e.g. a variable holding the function to call. The last argument list-expr must be a valid list or NIL, otherwise an error message is generated. If the number of arguments is not correct, an error occurs.
APPLY
returns the return value of the function call
or NIL if fun-expr is NIL.
For more information about functional expressions, see Functional parameters.
Example: `(APPLY + 4 (LIST 1 2 3))' returns 10.
See also FUNCALL.
IF
is a conditional operator.
|
This function is not strict, that is, only one expression of expr2 or expr3 will be evaluated.
CASE
is similar to the switch
statement in the C language.
|
case: |
The CASE
expression first evaluates expr.
Then each case pair is checked whether it (or one of the expressions in the list)
matches the evaluated expression.
If a matching case expression is found then the corresponding expressions
are executed and the value of the last expression is returned.
If no case matches, NIL is returned.
Example: `(CASE 1 ((2 3 4) 1) (1 2))' returns 2.
COND
is, like IF
, a conditional operator.
|
COND
test the first expression of each list one by one.
For the first one that does not result to NIL,
the corresponding expressions expr ... are evaluated
and the value of the last expression is returned.
If all tested expressions result to NIL then NIL is returned.
(COND ((> 1 2) "1 > 2") ((= 1 2) "1 = 2") ((< 1 2) "1 < 2") ) |
For simple loops the DOTIMES
command can be used.
|
The number of times the loop is executed is given in int-expr. In result-expr ... expressions can be specified that are executed after terminating the loop. In loop-expr you specify the body of the loop, that is, the expressions that are evaluated in each loop run.
Before executing the loop, DOTIMES
computes the value of int-expr
to determine the number of times the loop gets executed.
Here int-expr is evaluated only once at the start of the loop
and must result to an integer value.
Then DOTIMES
sets the loop variable to the values of 0 to int-expr-1
one by one for each loop run. First, the variable is initialized with zero
and checked if it is already greater or equal to the value of expr.
If int-expr is negative or NIL or if the variable is greater or equal to the value of
expr then the loop is terminated and the result expressions are evaluated.
Otherwise the loop expressions are evaluated and the variable is incremented
by one. Then the execution returns to the termination test and, possibly,
does further loop runs.
The DOTIMES
expression returns the value of the last result expression
or NIL if no result expression has been given.
(DOTIMES (i 50 i) (PRINT i)) |
See also DOLIST, DO, FOR ALL, LET.
For loops through lists the DOLIST
expression can be used.
|
In list-expr you specify the list over which the loop should be executed, result-expr ... are expressions which are evaluated after terminating the loop, and loop-expr ... build the body of the loop.
Before executing the loop, DOLIST
computes the value of list-expr.
This expression is evaluated only once at the start of the loop and must result
to a list value.
Then DOTIMES
sets the loop variable to the nodes of the list one by one
for each loop run.
First the loop variable is initialized to the first node of the list.
If the list is already empty (NIL) then the loop is terminated and the
result expressions are evaluated.
Otherwise the loop expressions are
evaluated and the variable is set to the next node of the list.
Then the execution returns to the termination test and, possibly, does further
loop runs.
The DOLIST
expression returns the value of the last result expression
or NIL if no result expression has been given.
(DOLIST (i (SELECT * FROM Accounts)) (PRINT i)) |
See also DOTIMES, DO, FOR ALL, LET.
With the DO
expression arbitrary loops can be programmed.
|
(
name init [step])
where name is a name for the new variable, init is the initial
value of the variable, and step is a step expression.
Furthermore, term-expr is the termination test expression, result-expr ... are the result expressions (the default is nil) and loop-expr ... build the body of the loop.
The DO
loop first initializes all local variables with the init
expressions, then tests the termination expression. If it results to TRUE,
the loop is terminated and the result expressions are evaluated. The value
of the last result expression is returned.
Otherwise the body of the loop (
loop-expr ...)
is executed
and each variable is updated by the value of its step expression.
Then the execution returns to test the terminating expression and so on.
(DO ((i 0 (+ i 1))) ((>= i 5) i) (PRINT i)) |
DOTIMES
expression.
See also DOTIMES, DOLIST, FOR ALL, LET.
The FOR ALL expression is used to loop over a list of records.
|
FOR ALL
first generates a list of all record sets for which the loop body should
be executed. This is done like in the SELECT
expression.
Please see SELECT, for more information about how this list is generated.
For each element of this list the loop body expr ... is executed.
For example, summing up an attribute of a table can be done in the following way:
(SETQ sum 0) (FOR ALL Accounts DO (SETQ sum (+ sum Accounts.Amount)) ) |
FOR ALL
expression returns NIL.
See also SELECT, DOTIMES, DOLIST, DO.
NEXT
can be used for controlling DOTIMES
,
DOLIST
, DO
and FOR ALL
loops.
Calling NEXT
in the body of a loop will jump to the next loop iteration.
This can be used for skipping non-interesting loop runs, like e.g. in
the following example:
(FOR ALL Table DO (IF not-interested-in-the-current-record (NEXT)) ... ) |
EXIT
can be used to terminate a loop.
|
EXIT
within a loop body will terminate the loop,
execute the optional expressions expr ..., and return the
value of the last expression (or NIL in case of no expression)
as the return value of the loop.
Possible return expressions of the loop as for example in
(DOTIMES (x 10 ret-expr ...) ...) |
You may use the EXIT
function for example to end a FOR ALL
loop
when you found the record you are interested in:
(FOR ALL Table DO (IF interested-in-the-current-record (EXIT Table)) ... ) |
Within a function definition you can return to
the caller by using the RETURN
command.
|
(DEFUN find-record (name) (FOR ALL Table DO (IF (= Name name) (RETURN Table)) ) ) |
HALT
can be used to terminate program execution.
|
For aborting program execution with an error message
the ERROR
function can be used.
|
SPRINTF
function (see SPRINTF).
For each type a predicate is defined that returns TRUE if the supplied expression is of the specified type and NIL otherwise. The predicates are:
Predicate Description |
This section lists functions for converting values from one type to another one.
15.8.1 STR Conversion to string. 15.8.2 MEMO Conversion to memo. 15.8.3 INT Conversion to integer. 15.8.4 REAL Conversion to real. 15.8.5 DATE Conversion to date. 15.8.6 TIME Conversion to time.
STR
can be used to convert an expression into a string representation.
|
Type Return string String The string itself. Memo The whole memo text in one string. Integer String representation of integer value. Real String representation of real value. If expr is an attribute then the number decimals specified for this attribute are used, otherwise 2 decimals are used. Choice Label string of the choice attribute. Date String representation of date value. Time String representation of time value. Boolean The string "TRUE" NIL User defined nil string if expr is an attribute, the string "NIL" otherwise. Record String representation of record number. Others String representation of internal address pointer. |
MEMO
can be used to convert an expression into a memo.
|
STR
function
(see STR) but returns a memo text instead of a string.
See also STR.
INT
is used to convert an expression into an integer.
|
Type Return value String If the complete string represents a valid integer value, it is converted into an integer. A string starting with 0 is interpreted as an octal number, one starting with 0x as hexadecimal number. Leading and following spaces are ignored. If the string does not represent an integer value, NIL is returned. Memo Same as for string. Integer The value itself. Real If the value lies within the integer range than the real value is rounded and returned, otherwise NIL is returned. Choice The internal number (starting with 0) of the current label. Date Number of days since 01.01.0000. Time Number of seconds since 00:00:00. Record Record number. NIL NIL Others An error message is generated and program execution is aborted. |
REAL
is used to convert an expression into a value of type real.
|
INT
function
(see INT) but returns a value of type real instead of an integer.
See also INT.
DATE
is used to convert an expression into a date (with your favorite friend :-).
|
Type Return value String If the whole string represents a date value then the string is converted into a date value. Leading and following spaces are ignored. If it does not represent a date value, NIL is returned. Memo Same as for string. Integer A date value is generated where the given integer represents the number of days since 01.01.0000. If the integer value is too great (date value would be greater than 31.12.9999) or negative then NIL is returned. Real Same as for integer. Date The value itself. NIL NIL others An error message is generated and program execution is aborted. |
TIME
is used to convert an expression into a time value.
|
Type Return value String If the whole string represents a time value then the string is converted into a time value. Leading and following spaces are ignored. If it does not represent a time value, NIL is returned. Memo Same as for string. Integer A time value is generated where the given integer represents the number of seconds since 00:00:00. Real Same as for integer. Time The value itself. NIL NIL others An error message is generated and program execution is aborted. |
This section lists Boolean operators.
15.9.1 AND Conjunction of Boolean values. 15.9.2 OR Disjunction of Boolean values. 15.9.3 NOT Inverting a Boolean value.
AND
checks if all of its arguments are TRUE.
|
This function is non-strict which means that arguments of AND
may not be evaluated, e.g. in `(AND NIL (+ 1 2))' the expression
`(+ 1 2)' is not evaluated since a NIL value has already been processed,
however in `(AND (+ 1 2) NIL)' the expression `(+ 1 2)' gets evaluated.
OR
checks if all of its arguments are NIL.
|
This function is non-strict which means that arguments of OR
may not be evaluated, e.g. in `(OR TRUE (+ 1 2))' the expression
`(+ 1 2)' is not evaluated since a non-NIL value (here `TRUE')
has already been processed, however in `(OR (+ 1 2) TRUE)'
the expression `(+ 1 2)' gets evaluated.
NOT
is used to invert the value of a Boolean expression.
|
In this section you will find functions for comparing values.
15.10.1 Relational operators =, <>, <, >, <=, >= and their star versions. 15.10.2 CMP Returns an integer representing the order. 15.10.3 CMP* Extended comparison, e.g. case insensitive.
For comparing two values in a MUIbase program, use
|
=
, <>
, <
, >
, >=
,
<=
, =*
, <>*
, <*
, >*
, >=*
, <=*
}.
The star is used for special comparison (strings are compared case
insensitive, records are compared by using the order defined by the user).
The following table shows all rules for comparing two values in a MUIbase program.
Type Order relation Integer NIL < MIN_INT < ... < -1 < 0 < 1 < ... < MAX_INT Real NIL < -HUGE_VAL < ... < -1.0 < 0.0 < 1.0 < ... < HUGE_VAL String: NIL < "" < "Z" < "a" < "aa" < "b" < ... (case sensitive) NIL <* "" <* "a" <* "AA" <* "b" < ... (case insensitive) Memo: same as string Date NIL < 1.1.0000 < ... < 31.12.9999 Time NIL < 00:00:00 < ... < 596523:14:07 Boolean NIL < TRUE Record: NIL < any_record (records itself are not comparable with <) NIL <* rec1 <* rec2 (order specified by user) |
CMP
returns an integer representing the order of
its arguments.
|
Do not assume that the returned value will always be -1, 0, or 1!
Example: `(CMP "Bike" "bIKE")' results to -1.
See also CMP*, Relational operators.
CMP*
is the star version of CMP
.
The difference is that CMP*
uses the extended ordering
as defined for relational operators (see Relational operators)
where strings are compared case insensitive and records are
compared using the user defined record order.
Example: `(CMP* "Bike" "bIKE")' results to 0.
See also CMP, Relational operators.
Here, some mathematical functions are listed.
15.11.1 + Adding values. 15.11.2 - Subtracting values. 15.11.3 1+ Increasing value. 15.11.4 1- Decreasing value. 15.11.5 * Floating point multiplication. 15.11.6 / Floating point division. 15.11.7 DIV Integer division. 15.11.8 MOD Integer modulo. 15.11.9 MAX Maximum expression. 15.11.10 MIN Minimum expression. 15.11.11 ABS Absolute value of an expression. 15.11.12 TRUNC Truncating decimals of a real value. 15.11.13 ROUND Rounding a real value. 15.11.14 RANDOM Random number generator. 15.11.15 POW Power of numbers. 15.11.16 SQRT Square root function. 15.11.17 EXP Exponential function. 15.11.18 LOG Logarithm of a number.
For adding values, use
|
You may also add strings or memos. In this case the result is the concatenation of the strings/memos.
If expr is of type date and the rest of the arguments are integers/reals then the sum of integers/reals are interpreted as a number of days and added to expr. If the resulting date is out of range (smaller than 1.1.0000 or greater than 31.12.9999) then NIL is the result.
If expr is of type time and the rest of the arguments are integers/reals or other time values then the sum of integers/reals (interpreted as a number of seconds) and time values are added to expr. If the resulting time is out of range (smaller than 00:00:00 or greater than 596523:14:07) then NIL is the result.
Expression Value (+ 1 2 3) 6 (+ 5 1.0) 6.0 (+ "Hello" " " "world!") "Hello world!" (+ 28.11.1968 +365 -28 -9) 22.10.1969 (+ 07:30:00 3600) 08:30:00 (+ 03:00:00 23:59:59) 26:59:59 |
For subtracting values, use
|
(-
expr)
has a special meaning, it returns the
negative value of expr (integer or real), e.g.
`(- (+ 1 2))' results to -3.
1+
increases an integer or real expression by one.
|
1-
decreases an integer or real expression by one.
|
For multiplying integer/real values, use
|
For dividing integer/real values, use
|
DIV
is used for integer division.
|
MOD
is used for modulo calculation.
|
See also DIV.
MAX
returns the argument that has the largest value.
|
See also MIN.
MIN
returns the argument that has the smallest value.
|
See also MAX.
ABS
computes the absolute value of an expression.
|
TRUNC
truncates decimals of a real value.
|
Examples: `(TRUNC 26.1)' results to 26, `(TRUNC -1.2)' results to -2.
See also ROUND.
ROUND
rounds a real value.
|
Examples: `(ROUND 70.70859 2)' results to 70.71, `(ROUND 392.36 -1)' results to 390.0.
See also TRUNC.
RANDOM
can be used to generate random numbers.
|
RANDOM
generates a random number in the range of
0 ... expr, excluding the value of expr itself.
The type of expr (integer or real) is the return type.
If expr is NIL then NIL is returned.
Example Meaning (RANDOM 10) returns a value from 0 to 9, (RANDOM 10.0) returns a value from 0.0 to 9.99999... |
POW
computes the power of values.
|
Example: `(POW 2 3)' results to 8.
SQRT
computes the square root of a number.
|
See also POW.
EXP
computes the exponential function.
|
LOG
computes the natural logarithm of a number.
|
See also EXP.
This section deals with functions useful for strings.
15.12.1 LEN String length. 15.12.2 LEFTSTR Left sub string. 15.12.3 RIGHTSTR Right sub string. 15.12.4 MIDSTR Individual sub string. 15.12.5 SETMIDSTR Replacing a sub string. 15.12.6 INSMIDSTR Inserting a string. 15.12.7 INDEXSTR First occurrence of sub string, case-sensitive. 15.12.8 INDEXSTR* First occurrence of sub string, case-insensitive. 15.12.9 INDEXBRK First occurrence of characters, case-sensitive. 15.12.10 INDEXBRK* First occurrence of characters, case-insensitive. 15.12.11 RINDEXSTR Last occurrence of sub string, case-sensitive. 15.12.12 RINDEXSTR* Last occurrence of sub string, case-insensitive. 15.12.13 RINDEXBRK Last occurrence of characters, case-sensitive. 15.12.14 RINDEXBRK* Last occurrence of characters, case-insensitive. 15.12.15 REPLACESTR Replacing sub strings, case-sensitive. 15.12.16 REPLACESTR* Replacing sub strings, case-insensitive. 15.12.17 REMCHARS Removing characters from string. 15.12.18 TRIMSTR Removing leading and trailing characters. 15.12.19 WORD Extracting word in a string. 15.12.20 WORDS Number of words in a string. 15.12.21 STRTOLIST Convert a string into a list of sub-strings. 15.12.22 LISTTOSTR Convert a list of items into a string. 15.12.23 CONCAT Concatenating strings. 15.12.24 CONCAT2 Concatenating strings. 15.12.25 COPYSTR Creates copies of a string. 15.12.26 SHA1SUM SHA1 hash of a string. 15.12.27 UPPER Upper case string. 15.12.28 LOWER Lower case string. 15.12.29 ASC Unicode/8-bit value of character. 15.12.30 CHR Character of Unicode/8-bit value. 15.12.31 LIKE Comparing strings. 15.12.32 SPRINTF String formatting.
LEN
computes the length of a string.
|
See also WORDS, LINES, MAXLEN.
LEFTSTR
extracts a sub string out of a string.
|
Example: `(LEFTSTR "Hello world!" 5)' results to "Hello".
See also RIGHTSTR, MIDSTR, WORD, LINE.
RIGHTSTR
extracts a sub string out of a string.
|
Example: `(RIGHTSTR "Hello world!" 6)' results to "world!".
See also LEFTSTR, MIDSTR, WORD, LINE.
MIDSTR
extracts a sub string out of a string.
|
Example: `(MIDSTR "Hello world!" 3 5)' results to "lo wo".
See also LEFTSTR, RIGHTSTR, WORD, LINE, SETMIDSTR, INSMIDSTR.
SETMIDSTR
replaces a sub string in a string.
|
Example: `(SETMIDSTR "Hello world!" 6 "Melanie!")' results to "Hello Melanie!".
See also INSMIDSTR, REPLACESTR.
INSMIDSTR
is used to insert a sub string into a string.
|
Example: `(INSMIDSTR "Hello world!" 6 "MUIbase-")' results to "Hello MUIbase-world!".
See also SETMIDSTR, REPLACESTR.
INDEXSTR
searches a string for the first occurrence of a sub string.
|
Example: `(INDEXSTR "Hello world!" "world")' returns 6.
See also INDEXSTR*, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.
INDEXSTR*
has the same effect as INDEXSTR
(see INDEXSTR)
except that string comparison is done case-insensitive.
See also INDEXSTR, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.
INDEXBRK
searches for the first occurrence of a character in a string.
|
Example: `(INDEXBRK "Hello world!" "aeiou")' returns 1.
See also INDEXBRK*, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.
INDEXBRK*
has the same effect as INDEXBRK
(see INDEXBRK)
except that string comparison is done case-insensitive.
See also INDEXBRK, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.
RINDEXSTR
searches a string for the last occurrence of a sub string.
|
Example: `(RINDEXSTR "Do itashimashite." "shi")' returns 11.
See also RINDEXSTR*, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.
RINDEXSTR*
has the same effect as RINDEXSTR
(see RINDEXSTR)
except that string comparison is done case-insensitive.
See also RINDEXSTR, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.
RINDEXBRK
searches for the last occurrence of a character in a string.
|
Example: `(RINDEXBRK "Konnichiwa" "chk")' returns 6.
See also RINDEXBRK*, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.
RINDEXBRK*
has the same effect as RINDEXBRK
(see RINDEXBRK)
except that string comparison is done case-insensitive.
See also RINDEXBRK, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.
REPLACESTR
replaces sub strings by other strings.
|
If any of the strings are NIL or any search string is empty then NIL is returned.
Example: `(REPLACESTR "black is white" "black" "white" "white "black")' results to "black is black".
See also REPLACESTR*, SETMIDSTR, INSMIDSTR, REMCHARS.
REPLACESTR*
has the same effect as REPLACESTR
(see REPLACESTR) except that string comparison is done case-insensitive
for searching sub strings.
See also REPLACESTR, SETMIDSTR, INSMIDSTR, REMCHARS.
REMCHARS
removes characters from a string.
|
Example: `(REMCHARS your-string " \t\n")' removes all spaces, tabs and newline characters from your-string.
See also REPLACESTR, TRIMSTR.
TRIMSTR
removes leading and trailing characters from a string.
|
TRIMSTR
cannot be called with two arguments.
If any of str, front, or back is NIL then NIL is returned.
Example: (TRIMSTR " I wrecked Selma's bike. ")
results to
"I wrecked Selma's bike.", (TRIMSTR "007 " "0" " \f\n\r\t\v")
results to
"7".
See also REMCHARS.
WORD
returns a word of a string.
|
If str or num are NIL, or if num is out of range, that is, less than zero or greater or equal to the number of words, then NIL is returned.
Example: `(WORD "Therefore, I lend Selma my bike." 3)' results to "Selma".
See also WORDS, LINE, LEFTSTR, RIGHTSTR, MIDSTR.
WORDS
counts the number of words in a string.
|
Example: `(WORDS "Actually, it wasn't really my bike.")' results to 6.
STRTOLIST
converts a string to a list of sub-strings.
|
"\t"
is used.
If sep is the empty string ""
then a list of all
characters in the string is returned.
If str or sep are NIL then NIL is returned.
`(STRTOLIST "I\tlike\tJapan.")' results to ( "I" "like" "Japan." ).
`(STRTOLIST "Name|Street|City" "|")' results to ( "Name" "Street" "City" ).
`(STRTOLIST "abc" "")' results to ( "a" "b" "c" ).
See also MEMOTOLIST, LISTTOSTR.
LISTTOSTR
converts a list of items into a string.
|
"\t"
is used.
If list or sep are NIL then NIL is returned.
`(LISTTOSTR (LIST "Peter is" 18 "years old"))' results to: "Peter is\t18\tyears old".
`(LISTTOSTR (LIST "Name" "Street" "City") "|")' results to: "Name|Street|City".
See also LISTTOMEMO, CONCAT, CONCAT2, STRTOLIST.
CONCAT
concatenates strings.
|
Example: `(CONCAT "I" "thought" "it" "was" "an "abandoned" "bike.")' results to "I thought it was an abandoned bike.".
See also CONCAT2, +, LISTTOSTR, COPYSTR, SPRINTF.
CONCAT2
concatenates strings.
|
Example: `(CONCAT2 "! " "But" "it" "wasn't!")' results to "But! it! wasn't!".
See also CONCAT, +, LISTTOSTR, COPYSTR, SPRINTF.
COPYSTR
creates copies of a string.
|
Example: `(COPYSTR "+-" 5)' results to "+-+-+-+-+-".
See also CONCAT CONCAT2, +, SPRINTF.
SHA1SUM
computes the SHA1 hash of a string.
|
Example: `(SHA1SUM "flower, sun and beach")' results to "47b6c496493c512b40e042337c128d85ecf15ba4".
See also ADMINPASSWORD, demo `Users.mb'.
UPPER
converts a string to upper case.
|
Example: `(UPPER "Selma found a letter attached to my bike.")' results to "SELMA FOUND A LETTER ATTACHED TO MY BIKE.".
See also LOWER.
LOWER
converts a string to lower case.
|
Example: `(LOWER "The letter was from Silke.")' results to "the letter was from silke.".
See also UPPER.
ASC
converts a character to its internal integer representation.
|
Example: (ASC "A")
results to 65.
CHR
converts an integer code to a character.
|
Example: `(CHR 67)' results to "C".
LIKE
compares strings.
|
Example: `(LIKE "Silke has been in France for one year." "*France*")' results to TRUE.
See also Comparison functions.
SPRINTF
formats a string with various data.
|
SPRINTF
takes a series of arguments, converts them to strings,
and returns the formatted information as one string.
The string fmt determines exactly what gets written to
the return string and may contain two types of items: ordinary characters
which are always copied verbatim and conversion specifiers which direct
SPRINTF
to take arguments from its argument list and format them.
Conversion specifiers always begin with a `%' character.
Conversion specifiers always take the following form:
|
SPRINTF
will be converting, such as string, integer, real, etc.
Note that all of the above fields are optional except for type. The following tables list the valid options for these fields.
SPRINTF
returns the formatted string or NIL in case fmt is NIL.
Call Result (SPRINTF "Hello") "Hello" (SPRINTF "%s" "Hello") "Hello" (SPRINTF "%10s" "Hello") " Hello" (SPRINTF "%-10.10s" "Hello") "Hello " (SPRINTF "%010.3s" "Hello") " Hel" (SPRINTF "%-5.3b" TRUE) "TRU " (SPRINTF "%i" 3) "3" (SPRINTF "%03i" 3) "003" (SPRINTF "%0- 5.3i" 3) " 3 " (SPRINTF "%f" 12) "12.00" (SPRINTF "%10e" 12.0) " 1.20e+01" (SPRINTF "%+-10.4f" 12.0) "+12.0000 " (SPRINTF "%10.5t" 12:30:00) " 12:30" (SPRINTF "%d" 28.11.1968) "28.11.1968" (SPRINTF "He%s %5.5s!" "llo" "world champion ship") "Hello world!" |
This section deals with functions useful for memos.
15.13.1 LINE Extracting a line in a memo. 15.13.2 LINES Number of lines in a memo. 15.13.3 MEMOTOLIST Converting memo into list. 15.13.4 LISTTOMEMO Converting list into memo. 15.13.5 FILLMEMO Filling in a memo. 15.13.6 FORMATMEMO Formatting a memo. 15.13.7 INDENTMEMO Indenting a memo.
LINE
extracts a line in a memo.
|
LINES
returns the number of lines in a memo.
|
MEMOTOLIST
converts a memo into a list of strings.
|
If expandstr is given and is not NIL then resulting list of strings
is further processed by applying STRTOLIST
to each list element.
This results into a list of lists of strings.
`(MEMOTOLIST "My insurance\npays for\nthe wrecked bike.")' results to ( "My insurance" "pays for" "the wrecked bike." ).
`(MEMOTOLIST "Here is\ta multi-columned\nexample." TRUE)' results to ( ( "Here is" "a multi-columned" ) ( "example" ) ).
See also STRTOLIST, LISTTOMEMO.
LISTTOMEMO
converts a list into a memo.
|
LISTTOSTR
(see LISTTOSTR)
is applied on it before integrating the resulting string into the memo.
`(LISTTOMEMO (LIST "Silke" "lends me" "'my' bike" "till" 01.09.1998)' results to: "Silke\nlends me\n'my' bike\ntill\n01.09.1998".
`(LISTTOMEMO (LIST (LIST "Name" "Birthday") (LIST "Steffen" 28.11.1968)' results to: "Name\tBirthday\nSteffen\t28.11.1968".
See also LISTTOSTR, MEMOTOLIST.
FILLMEMO
fills in a memo with the results of expressions.
|
Example: `(FILLMEMO "(+ 1 1) is $(+ 1 1).")' results to "(+ 1 1) is 2."
Please use only small expressions in the memo as debugging and tracking down errors is not easy here.
See also FORMATMEMO, INDENTMEMO.
FORMATMEMO
formats a memo.
|
See also FILLMEMO, INDENTMEMO.
INDENTMEMO
indents a memo by putting spaces to the left.
|
See also FILLMEMO, FORMATMEMO.
This section deals with functions useful for date and time values.
15.14.1 DAY Extracting day field of a date. 15.14.2 MONTH Extracting month field of a date. 15.14.3 YEAR Extracting year field of a date. 15.14.4 DATEDMY Creating date value from day, month and year. 15.14.5 MONTHDAYS Number of days of a month. 15.14.6 YEARDAYS Number of days of a year. 15.14.7 ADDMONTH Adding a number of months to a date value. 15.14.8 ADDYEAR Adding a number of years to a date value. 15.14.9 TODAY Getting current date. 15.14.10 NOW Getting current time.
DAY
extracts the day field of a date.
|
See also MONTH, YEAR, DATEDMY.
MONTH
extracts the month field of a date.
|
See also DAY, YEAR, DATEDMY, MONTHDAYS.
YEAR
extracts the year field of a date.
|
See also DAY, MONTH, DATEDMY, YEARDAYS.
DATEDMY
creates a date value from day, month, and year.
|
Example: `(DATEDMY 28 11 1968)' results to the 28th of November, 1968.
See also DATE, TODAY, DAY, MONTH, YEAR.
MONTHDAYS
gets the number of days of a month.
|
Examples: `(MONTHDAYS 2 2004)' results to 29, `(MONTHDAYS 2 NIL)' results to 28.
YEARDAYS
gets the number of days of a year.
|
Examples: `(YEARDAYS 2004)' results to 366, `(YEARDAYS 2005)' results to 365.
ADDMONTH
adds a number of months to a date.
|
ADDMONTH
handles over- and underflow of the month field by adjusting
the year field accordingly. In case the day field exceeds the maximum number
of days of the resulting month, it is decremented to the maximum allowed day.
Examples: `(ADDMONTH 30.01.2004 1)' results to 29.02.2004, `(ADDMONTH 30.01.2004 -1)' results to 30.12.2003.
ADDYEAR
adds a number of years to a date.
|
ADDYEAR
decrements the day field by 1 in case date represents
February 29th and the resulting year is not a leap year.
Examples: `(ADDYEAR 29.02.2004 1)' results to 28.02.2005, `(ADDMONTH 04.02.2004 -1962)' results to 04.02.0042.
TODAY
returns the current date.
|
NOW
returns the current time.
|
See also TODAY.
This section lists functions for processing lists.
15.15.1 CONS Elementary list constructor. 15.15.2 LIST Generating a list of elements. 15.15.3 LENGTH Getting number of list elements. 15.15.4 FIRST Extracting first element of a list. 15.15.5 REST Getting remainder of a list. 15.15.6 LAST Extracting last element of a list. 15.15.7 NTH Extracting n-th element of a list. 15.15.8 APPEND Concatenating lists. 15.15.9 REVERSE Reversing a list. 15.15.10 MAPFIRST Applying a function to all list elements. 15.15.11 SORTLIST Sorting elements of a list. 15.15.12 SORTLISTGT Sorting elements of a list.
CONS
builds a pair of expressions.
|
Example: `(CONS 1 (CONS 2 NIL))' results to ( 1 2 ).
The elements of a list can be of any type, e.g. it's also possible to have
a list of lists (e.g. see SELECT).
The CONS
constructor can also be used to build pairs of elements, e.g.
`(CONS 1 2)' is the pair with the two integers 1 and 2.
LIST
generates a list out of its arguments.
|
(CONS
elem (CONS
... NIL))
.
Note that NIL alone stands for an empty list.
LENGTH
determines the length of a list.
|
Example: `(LENGTH (LIST "a" 2 42 3))' results to 4.
See also LIST.
FIRST
extracts the first element in a list.
|
See also REST, LAST, NTH, CONS.
REST
returns the sub-list after the first element of a list.
|
Example: `(REST (LIST 1 2 3))' results to ( 2 3 ).
LAST
extracts the last element in a list.
|
NTH
extracts the n-th element of a list.
|
APPEND
concatenates lists.
|
Example: `(APPEND (list 1 2) (list 3 4) (list 5))' results to ( 1 2 3 4 5 ).
See also LIST.
REVERSE
reverses a list.
|
Example: `(REVERSE (list 1 2 3))' results to ( 3 2 1 ).
MAPFIRST
applies a function to all list elements.
|
Expression Value (MAPFIRST 1+ (LIST 1 2 3)) ( 2 3 4 ) (MAPFIRST + (LIST 1 2 3) (LIST 2 3)) ( 3 5 NIL ) |
SORTLIST
sorts the elements of a list.
|
Example for a string comparing function usable for sorting:
(DEFUN cmp_str (x y) (COND ((< x y) -1) ((> x y) 1) (TRUE 0) ) ) |
(SORTLIST cmp_str (LIST "hi" "fine" "great" "ok")) |
See also SORTLISTGT, MAPFIRST.
SORTLIST
sorts the elements of a list.
|
SORTLIST
but here you specify an order function that returns a value
not equal to NIL if the first element is greater then the second one, and NIL
otherwise.
Example: `(SORTLISTGT > (LIST "hi" "fine" "great" "ok"))' result to ( "fine" "great" "hi" "ok" ).
For requesting information from the user, the following functions can be used.
15.16.1 ASKFILE Requesting a filename. 15.16.2 ASKDIR Requesting a directory name. 15.16.3 ASKSTR Requesting a string. 15.16.4 ASKINT Requesting an integer. 15.16.5 ASKCHOICE Requesting one item out of many items. 15.16.6 ASKCHOICESTR Requesting a string, offering predefined ones. 15.16.7 ASKOPTIONS Requesting some items out of many items. 15.16.8 ASKBUTTON Requesting the user to press a button. 15.16.9 ASKMULTI Requesting several informations.
ASKFILE
prompts the user for entering a filename.
|
ASKFILE
returns the entered filename as string or NIL in case the user
canceled the requester.
ASKDIR
prompts the user for entering a directory name.
|
ASKFILE
(see ASKFILE).
ASKDIR
returns the entered directory
name as string or NIL in case the user canceled the requester.
ASKSTR
prompts the user for entering a string.
|
ASKSTR
returns the entered string or NIL in case the user canceled.
See also ASKFILE, ASKDIR, ASKCHOICESTR, ASKINT.
ASKINT
prompts the user for entering an integer value.
|
ASKINT
returns the entered integer or NIL if the user canceled the requester.
See also ASKSTR.
ASKCHOICE
prompts the user to select one item out of many items.
|
Both, choices and titles, can also be given as a memo and a string
(instead of lists).
If so, they are converted to lists automatically by calling
(MEMOTOLIST choices TRUE)
(see MEMOTOLIST) and
(STRTOLIST titles)
(see STRTOLIST) respectively.
ASKCHOICE
returns the index of the chosen item
or NIL if the user canceled the requester.
(LET ((items (LIST "First Entry" 2 3.14 "Last entry")) index) (SETQ index (ASKCHOICE "Choose one item" "Ok" items NIL)) (IF index (PRINTF "User chose item num %i with contents <%s>\n" index (STR (NTH index items)) ) ) ) |
(LET ((query (SELECT Article, Name, Number, Prize from Article WHERE (> Prize 10) ORDER BY Name)) (recs (MAPFIRST FIRST (REST query))) ; record pointers (items (MAPFIRST REST (REST query))) ; choices (titles (REST (FIRST query))) ; titles (index (ASKCHOICE "Choose" "Ok" items NIL titles)) (rec (NTH index recs))) ; now rec holds the selected record (or NIL on cancel) ) |
ASKCHOICESTR
prompts the user for entering a string value offering
several pre-defined ones.
|
Both, strings and titles, can also be given as a memo and a string
(instead of lists).
If so, they are converted to lists automatically by calling
(MEMOTOLIST strings TRUE)
(see MEMOTOLIST) and
(STRTOLIST titles)
(see STRTOLIST) respectively.
ASKCHOICESTR
returns the chosen string or NIL if the user canceled the
requester.
(LET ((strings (LIST "Claudia" "Mats" "Ralphie")) likebest) (SETQ likebest (ASKCHOICESTR "Who do you like the best?" "Ok" strings "My collies!" ) ) (IF likebest (PRINTF "User chose <%s>\n" likebest)) ) |
ASKOPTIONS
prompts the user for selecting several items out of a list of items.
|
Both, options and titles, can also be given as a memo and a string
(instead of lists).
If so, they are converted to lists automatically by calling
(MEMOTOLIST options TRUE)
(see MEMOTOLIST) and
(STRTOLIST titles)
(see STRTOLIST) respectively.
ASKOPTIONS
returns a list of integers each specifying the index of a selected
item, or NIL in case the user canceled or did not choose any item.
(LET ((options (LIST "Salva Mea" "Insomnia" "Don't leave" "7 days & 1 week")) (selected (LIST 0 1 3)) ) (SETQ selected (ASKOPTIONS "Select music titles" "Ok" options selected)) (IF selected ( (PRINTF "User has selected the following items:\n") (DOLIST (i selected) (PRINTF "\tnum: %i contents: <%s>\n" i (STR (NTH i options))) ) ) ) ) |
ASKBUTTON
prompts the user for pressing a button.
|
ASKBUTTON
returns the number of the pressed button (starting with 0 for
the first (leftmost) button) or NIL if the user pressed the `Cancel' button.
(LET ((buttons (LIST "At home" "In bed" "In front of my computer")) index) (SETQ index (ASKBUTTON "Please answer:" "Where do you want to be tomorrow?" buttons "Don't know") ) (IF index (PRINTF "User chose: <%s>\n" (NTH index buttons)) ) ) (ASKBUTTON "Info" "MUIbase is great!" NIL NIL) |
ASKMULTI
prompts the user to enter various kinds of information.
|
ASKMULTI
is a multi-purpose requester. It opens a window with the specified
title, a set of GUI objects for editing data, and two buttons (`Ok' and `Cancel')
for terminating the requester. The text of the `Ok' button can be set in
oktext (string or NIL for default text). The set of GUI objects are
specified in itemlist which is a list of items where each item has one
of the following forms:
|
ASKMULTI
returns a list of result values which the user
has edited and acknowledged by pressing the `Ok' button.
Each result value of a field has the same format as the one for
the initial value, e.g. for a choice list field the result value is
the index of the selected item (or NIL if no item has been
selected), or for an options field the result value is
a list of integers representing the indices of the selected items.
For static text a value of NIL is returned.
E.g. if you have specified a date field, a static text field, a choice field, an options field, and a string field with initial value "world", and the user has entered 11.11.1999, selected the choice entry with index number 2, selected the 3rd and 4th item in the options field, and left the string field untouched then the function returns the list ( 11.11.1999 NIL 2 ( 3 4 ) "world" ).
If the user cancels the requester, NIL is returned.
(ASKMULTI "Please edit:" NIL (LIST (LIST "N_ame" "String" "") (LIST "_Birthday" "Date" NIL) (LIST "_Sex" "Choice" 0 (LIST "male" "female")) (LIST "_Has car?" "Bool" NIL) (LIST "_Likes" "Options" (LIST 0 2) (LIST "Beer" "Wine" "Whisky" "Wodka" "Schnaps") )) ) |
This sections lists functions and variables for input and output (e.g. printing) of data.
15.17.1 FOPEN Opening a file for reading/writing. 15.17.2 FCLOSE Closing a file. 15.17.3 stdout Standard output file handle. 15.17.4 PRINT Printing an expression to stdout. 15.17.5 PRINTF Formatted printing to stdout. 15.17.6 FPRINTF Formatted printing to a file. 15.17.7 FERROR Error checking of a file. 15.17.8 FEOF Detecting end of file. 15.17.9 FSEEK Setting position in a file. 15.17.10 FTELL Getting current position in a file. 15.17.11 FGETCHAR Reading the next input character from a file. 15.17.12 FGETCHARS Reading several input characters from a file. 15.17.13 FGETSTR Reading a string from a file. 15.17.14 FGETMEMO Reading a memo from a file. 15.17.15 FPUTCHAR Writing a character to a file. 15.17.16 FPUTSTR Writing a string to a file. 15.17.17 FPUTMEMO Writing a memo to a file. 15.17.18 FFLUSH Flushing a file.
FOPEN
opens a file for reading/writing.
|
The optional parameter encoding controls the encoding of the file and is one of the following strings:
LANG
and LC_*
environment variables, see man locale
.
On Amiga it is the default 8 bit encoding.
If no encoding parameter is given then `"auto"' is used.
FOPEN
returns a file handle on success.
On failure NIL is returned.
If filename, mode or encoding are NIL then NIL is returned.
`(FOPEN "index.html" "w" "utf-8")' opens and returns a file handle for writing to the file `index.html' and encoding it in UTF-8.
`(FOPEN "output.txt" "a+")' opens file `output.txt' for appending it using the same text encoding as is already present in the file. Note that if you only specify `"a"' as mode then MUIbase might not be able to read the file and decide the existing encoding. In this case the encoding is decided when writing to the file (and might be different from the exising one).
See also FCLOSE, stdout, FFLUSH.
FCLOSE
closes a file.
|
The global variable stdout
holds the file handle
to MUIbase's standard output file.
The output filename can be set in menu item `Program - Output file'
(see Program output file).
The output file is openend on the first access of this variable (e.g. when calling `(FPRINTF stdout ...)', or when calling `(PRINTF ...)'). The file is not pre-opened on program execution. This avoids opening the file when no output is generated, e.g. when you simply want to do some calculations and change some record contents.
When opening the output file the mode parameter is either `"w"' or `"a+"' depending on the `Append' setting in menu item `Program - Output file'. The encoding is set to `"auto"'.
If MUIbase can't open the program output file then execution is aborted and an error message is generated.
PRINT
converts an expression to a string and prints it.
|
stdout
.
This function mainly exists for debug purposes.
PRINTF
prints a formatted string.
|
stdout
.
Formatting is done like in SPRINTF
(see SPRINTF).
PRINTF
returns the number of output characters or NIL on failure.
If format is NIL then NIL is returned.
Example: `(PRINTF "%i days and %i week" 7 1)' prints the string
"7 days and 1 week" to stdout
and returns 17.
See also PRINT, FPRINTF, stdout.
FPRINTF
prints a formatted string to a file.
|
SPRINTF
(see SPRINTF).
FPRINTF
returns the number of output characters or NIL on failure.
If file is NIL then FPRINTF
still returns the number of
potentially written characters but no output is actually written.
If format is NIL then NIL is returned.
FERROR
checks if an file I/O error has occurred.
|
FEOF
checks for an end of file status.
|
See also FERROR, FTELL, FOPEN, FCLOSE.
FSEEK
sets the read/write position in a file.
|
On success, FSEEK
returns 0. Otherwise NIL is returned
and the file position stays unchanged.
If file, offset, or whence is NIL, or if
whence is not one of the constant values SEEK_SET, SEEK_CUR, or SEEK_END
then NIL is returned.
Note that after a read operation calling FSEEK
with whence as SEEK_CUR
is only supported for encoding `"none"'.
See also FTELL, FOPEN, Pre-defined constants.
FTELL
returns the read/write position of a file.
|
Note that after a read operation calling FTELL
is only supported for encoding `"none"'.
FGETCHAR
reads a character from a file.
|
See also FGETCHARS, FGETSTR, FPUTCHAR.
FGETCHARS
reads characters from a file.
|
FGETSTR
reads a string from a file.
|
See also FGETCHAR, FGETCHARS, FGETMEMO, FPUTSTR.
FGETMEMO
reads a memo from a file.
|
FPUTCHAR
writes a character to a file.
|
FPUTSTR
writes a string to a file.
|
See also FPUTCHAR, FPUTMEMO, FGETSTR.
FPUTMEMO
writes a memo to a file.
|
FFLUSH
flushes pending data to a file.
|
This section lists functions that deal with records.
15.18.1 NEW Allocating new record. 15.18.2 NEW* Allocating new record by calling trigger function. 15.18.3 DELETE Deleting a record. 15.18.4 DELETE* Deleting a record by calling trigger function. 15.18.5 DELETEALL Deleting all records of a table. 15.18.6 GETMATCHFILTER Getting the match-filter state of a record. 15.18.7 SETMATCHFILTER Setting the match-filter state of a record. 15.18.8 GETISSORTED Checking if a record is in the right order. 15.18.9 SETISSORTED Telling a record its order state. 15.18.10 RECNUM Getting the record number of a record. 15.18.11 COPYREC Copying the contents of a record.
NEW
allocates a new record for a table.
|
NEW
returns a record pointer to the new record.
The NEW
function has the side effect of setting the
program record pointer of the given table (see Tables)
to the new record.
Example: `(NEW table NIL)' allocates a new record in the given table and initializes it with the initial record.
See also NEW*, DELETE, Tables.
NEW*
is the star version of NEW
(see NEW).
|
NEW*
checks if you have specified a `New' trigger
function for the given table (see New trigger).
If so then this trigger function is called for allocating
the record and its result is returned.
The init parameter can be used to specify a record with
which the new record should be initialized (use NIL for the
initial record).
If no trigger function has been specified, the function behaves like
the NEW
function.
Warning: With this function it is possible to write endless loops, e.g.
if you have defined a `New' trigger function for a table
and this function calls NEW*
to allocate the record.
DELETE
deletes a record in a table.
|
The return code of the DELETE
function
reflects the selected action. If it returns TRUE then
the record has been deleted, otherwise (the user
has canceled the operation) NIL is returned.
On deletion, DELETE
sets the program record pointer
(see Tables) of the specified table to NIL.
Example: `(DELETE table NIL)' deletes the current record in the given table silently.
See also DELETE*, DELETEALL, NEW, Tables.
DELETE*
is the star version of DELETE
(see DELETE).
|
DELETE*
checks if you have specified a `Delete' trigger
function for the given table (see Delete trigger).
If so then this trigger function is called for deleting
the record and its result is returned.
The requester parameter can be used to specify
if the trigger function should pop up a confirmation requester
before deleting the record.
If no trigger function has been specified, the function behaves like
the DELETE
function.
Warning: With this function it is possible to write endless loops, e.g.
if you have defined a `Delete' trigger function for a table
and this function calls DELETE*
to delete the record.
See also DELETE, DELETEALL, NEW*.
DELETEALL
deletes all records of a table.
|
DELETEALL
returns TRUE on successful deletion of all records,
otherwise NIL is returned. If table is NIL then NIL is returned.
Example: `(DELETEALL table*)' deletes all records in the given table that match the filter of the table.
GETMATCHFILTER
returns the match-filter state of a record.
|
See also SETMATCHFILTER, GETISSORTED, GETFILTERSTR, SETFILTERSTR.
SETMATCHFILTER
sets the match-filter state of a record.
|
SETMATCHFILTER
returns the new match-filter state of the given record.
The new state may be different from the expected one because setting the
match-filter state to NIL does only work when the filter of the corresponding
table is currently active, otherwise TRUE is returned.
Calling SETMATCHFILTER
with a value of NIL for rec
(the initial record) will always return NIL.
See also GETMATCHFILTER, SETISSORTED, GETFILTERSTR, SETFILTERSTR.
GETISSORTED
returns the sorted state of a record.
|
See also SETISSORTED, GETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.
SETISSORTED
sets the sorted state of a record.
|
REORDER
function
(see REORDER).
SETISSORTED
returns the new sorted state of the given record.
Calling SETISSORTED
with a value of NIL for rec
(the initial record) will return NIL.
For an example on how to use this function, see Comparison function.
See also GETISSORTED, SETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.
RECNUM
returns the record number of a record.
|
COPYREC
copies records.
|
COPYREC
returns rec.
See also NEW.
This section lists functions that work on attributes of a table.
15.19.1 ATTRNAME Getting the name of an attribute. 15.19.2 MAXLEN Maximum number of characters for a string attribute. 15.19.3 GETLABELS Getting the labels of a choice or string attribute. 15.19.4 SETLABELS Setting the list-view labels of a string attribute.
ATTRNAME
returns the name of an attribute.
|
See also TABLENAME
MAXLEN
returns the maximum size of a string attribute.
|
See also LEN.
GETLABELS
returns all labels of a choice or string attribute.
|
The labels are returned in one single string and are separated by newline characters.
For example, consider you have a choice attribute with the labels
`Car', `House', and `Oil'.
Then calling GETLABELS
on that attribute will result to
the string "Car\nHouse\nOil".
Note: you can easily convert the result string to a list by
calling MEMOTOLIST
(see MEMOTOLIST) on the result string.
See also SETLABELS.
SETLABELS
is used to set the labels of a string attribute.
|
SETLABELS
returns the value of its str argument.
Example: `(SETLABELS Table.String "My house\nis\nyour house")' sets the static list-view labels of the specifies string attribute to `My house', `is', and `your house'.
Note: you can easily convert a list of labels to the required string format by calling LISTTOMEMO on the list.
See also GETLABELS.
15.20.1 TABLENAME Getting the name of a table. 15.20.2 GETORDERSTR Getting record order. 15.20.3 SETORDERSTR Setting record order. 15.20.4 REORDER Reordering unsorted records. 15.20.5 REORDERALL Reorder all records of a table. 15.20.6 GETFILTERACTIVE Getting record filter state. 15.20.7 SETFILTERACTIVE Setting record filter state. 15.20.8 GETFILTERSTR Getting record filter expression. 15.20.9 SETFILTERSTR Setting record filter expression. 15.20.10 RECORDS Number of records. 15.20.11 RECORD Getting pointer to a record. 15.20.12 SELECT Select-from-where queries.
TABLENAME
returns the name of a table.
|
See also ATTRNAME
GETORDERSTR
returns the record order of a table.
|
If the table is ordered by a comparison function then the name of this function is returned.
An empty string means no ordering.
Consider a table `Person' which is ordered by the Attributes `Name' (ascending), `Town' (ascending), and `Birthday' (descending). Then `(ORDERSTR Person)' will result to the string "+Name +Town -Birthday".
See also SETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Order, Comparison function.
SETORDERSTR
sets the record order of a table.
|
For sorting using an attribute list, the order string must contain the attribute names separated by any number of spaces, tabs or newlines. Each attribute name may be prepended by a `+' or a `-' sign indicating ascending or descending order. If you omit this sign then ascending ordering is assumed.
For sorting using a comparison function, the order string must hold the name of the function.
SETORDERSTR
returns TRUE if it has been able to set the new order,
NIL otherwise, e.g. if an unknown attribute has been specified
or the type of the attribute is not allowed for ordering.
If you specify NIL for the order argument then nothing
happens and NIL is returned.
Note: For building the order string you should not directly write the
attribute names into the string because when you change
an attribute name then the order string will not be updated.
Better use the ATTRNAME
function (see ATTRNAME)
to copy the attribute's name into the order string.
Consider a table `Person' with the attributes `Name', `Town', and `Birthday'. Then `(SETORDERSTR Person (SPRINTF "+%s" (ATTRNAME Person.Name)))' will set the order of table `Person' using `Name' as (ascending) order attribute.
See also GETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Order, Comparison function.
REORDER
brings all unsorted records back into the right order.
|
REORDER
the sorted state of all records is TRUE.
REORDER
returns NIL.
Usually you only need to call this function, when you are using a comparison function for defining the order of a table. Orders defined by an attribute list are automatic, that is, a record is reordered automatically when needed.
For an example on how to use this function, see Comparison function.
See also REORDERALL, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Order, Comparison function.
REORDERALL
reorders all records of a table.
|
REORDER
for reordering everything.
REORDERALL
returns NIL.
See also REORDER, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Order, Comparison function.
GETFILTERACTIVE
returns the filter state of a table.
|
See also SETFILTERACTIVE, GETFILTERSTR, GETMATCHFILTER.
SETFILTERACTIVE
sets the filter state of a table.
|
SETFILTERACTIVE
returns the new state of the filter.
The new state may not be the expected one in case you activate
the filter but an error condition occurs and the filter can't be
activated.
However deactivating the filter always succeeds.
See also GETFILTERACTIVE, SETFILTERSTR, SETMATCHFILTER.
GETFILTERSTR
returns the record filter expression of a table.
|
See also SETFILTERSTR, GETFILTERACTIVE, GETMATCHFILTER.
SETFILTERSTR
sets the record filter expression of a table.
|
SETFILTERSTR
returns TRUE if it has been able to compile
the given filter string expression, otherwise NIL is returned.
Note that you only get the result of the compilation.
If the filter of the given table is currently active and
recomputing all match-filter states of the corresponding
records fails then you will not notice that from the result
of this function.
The recommended way to set a new filter expression is
like follows:
(SETFILTERACTIVE Table NIL) ; always succeeds. (IF (NOT (SETFILTERSTR Table filter-string)) (ERROR "Can't set filter string for %s!" (TABLENAME Table)) ) (IF (NOT (SETFILTERACTIVE Table TRUE)) (ERROR "Can't activate filter for %s!" (TABLENAME Table)) ) |
SETFILTERSTR
is called with a value of NIL for
the filter-str argument then nothing happens and NIL is returned.
Example: `(SETFILTERSTR Table "(> Value 0.0)")'.
See also GETFILTERSTR, SETFILTERACTIVE, SETMATCHFILTER.
RECORDS
returns the number of records in a table.
|
RECORD
returns a record pointer for a given record number.
|
Please note that record numbers start with 1 and record number 0 is used for the initial record.
SELECT
extracts and returns various data from records.
|
exprlist: |
tablelist: table[ |
The orderlist has the following syntax:
orderlist: expr [ |
ASC
or DESC
for an
ascending or descending order.
If none of them are present then an ascending order is assumed.
The select-from-where query builds the (mathematical) cross product of all tables in the table list (it examines all sets of records in table, ...) and checks the where-expression (if any). If the where-expression results to TRUE (or there is no where-expression) then a list is build whose elements are calculated by the expression list in the select-part. If you have specified a single star for the expression list then the list contains the values of all attributes belonging to tables in the table list (except virtual attributes and buttons).
The result of the query is a list of lists. The first list entry contains the title strings, the remaining ones contain the values of the from-list in the matching records.
See Query examples, for some examples using the SELECT
function.
See also FOR ALL.
This section describes functions for manipulating GUI elements.
15.21.1 SETCURSOR Placing the cursor on a GUI element. 15.21.2 GETWINDOWOPEN Getting open/close state of a window. 15.21.3 SETWINDOWOPEN Opening/closing of a window. 15.21.4 GETVIRTUALLISTACTIVE Getting the active line of a virtual attribute. 15.21.5 SETVIRTUALLISTACTIVE Setting the active line of a virtual attribute.
SETCURSOR
sets the cursor on a GUI element.
|
SETCURSOR
returns TRUE if everything went ok
(window could be opened) or NIL on failure.
See also SETVIRTUALLISTACTIVE.
GETWINDOWOPEN
returns the open state of a window.
|
See also SETWINDOWOPEN.
SETWINDOWOPEN
opens and closes a window.
|
SETWINDOWOPEN
returns the new open state of the window.
See also GETWINDOWOPEN.
GETVIRTUALLISTACTIVE
returns the index of the active line
of a virtual attribute that uses the `List' kind for display.
|
See also SETVIRTUALLISTACTIVE.
SETVIRTUALLISTACTIVE
sets the active line
of a virtual attribute that uses the `List' kind for display.
|
Returns num, or NIL if the GUI element of virtual-attr is not visible, does not use the `List' kind for display, or if num is out of range (less than 1 or greater than the number of lines).
SETVIRTUALLISTACTIVE
does not set the cursor to the
attribute's GUI element, use SETCURSOR
(see SETCURSOR) for doing so.
See also GETVIRTUALLISTACTIVE, SETCURSOR.
This section lists functions dealing with projects.
15.22.1 PROJECTNAME Getting the project name. 15.22.2 CHANGES Getting number of changes made to current project. 15.22.3 GETADMINMODE Checking for admin or user mode. 15.22.4 SETADMINMODE Setting admin or user mode. 15.22.5 ADMINPASSWORD SHA1 hash of admin password.
PROJECTNAME
returns the project name.
|
PROJECTNAME
returns the name of the current project as a string
or NIL if no name has been defined yet.
The project name is the pathname of the project directory in the file system.
See also CHANGES.
CHANGES
returns the number of changes in the current
project.
|
See also PROJECTNAME.
GETADMINMODE
tells whether the current project is in admin mode
or user mode.
|
See also SETADMINMODE, ADMINPASSWORD, onAdminMode.
SETADMINMODE
changes the current project to admin mode or user mode.
|
Returns TRUE if the project has been set to admin mode, or NIL if set to user mode.
See also GETADMINMODE, ADMINPASSWORD, onAdminMode, demo `Users.mb'.
ADMINPASSWORD
obtains the admin password as SHA1 hash string.
|
See also GETADMINMODE, SETADMINMODE, SHA1SUM, demo `Users.mb'.
This section lists functions accessing the operating system.
15.23.1 EDIT Launching external editor synchronously. 15.23.2 EDIT* Launching external editor asynchronously. 15.23.3 VIEW Launching external viewer synchronously. 15.23.4 VIEW* Launching external viewer asynchronously. 15.23.5 SYSTEM Calling external commands synchronously. 15.23.6 SYSTEM* Calling external commands asynchronously. 15.23.7 STAT Examining a file. 15.23.8 TACKON Creating pathname from components. 15.23.10 DIRNAME Getting directory name from a path. 15.23.9 FILENAME Getting last component of a path. 15.23.11 MESSAGE Showing messages to the user. 15.23.12 COMPLETEMAX Setting max number of progress steps. 15.23.13 COMPLETEADD Increasing current progress state. 15.23.14 COMPLETE Setting absolute progress state. 15.23.15 GC Forcing garbage collection. 15.23.16 PUBSCREEN Name of public screen (Amiga).
EDIT
launches the external editor.
|
EDIT
starts the external editor synchronously, that is,
it waits until the user exits the editor.
EDIT
returns the return code of the external editor as an integer.
EDIT*
is the star version of EDIT
and has the same
effect as EDIT
(see EDIT).
The only difference is that EDIT*
starts the external editor
asynchronously, thus the function returns immediately.
EDIT*
returns 0 if it was successful in starting the editor,
otherwise it returns a non-zero integer value representing a
system specific error code.
See also EDIT, VIEW*, SYSTEM*.
VIEW
launches the external viewer.
|
VIEW
starts the external viewer synchronously, that is,
it waits until the user exits the viewer. Note that on some systems,
the call might return immediately if an instance of the viewer is
already running.
VIEW
returns the return code of the external viewer as an integer.
VIEW*
is the star version of VIEW
and has the same
effect as VIEW
(see VIEW).
The only difference is that VIEW*
starts the external viewer
asynchronously, thus the function returns immediately.
VIEW*
returns 0 if it was successful in starting the viewer,
otherwise it returns a non-zero integer value representing a
system specific error code.
See also VIEW, EDIT*, SYSTEM*.
SYSTEM
calls an external program.
|
SPRINTF
function (see SPRINTF).
For interpreting the command line, a system specific shell is used
(ShellExecute on Windows, /bin/sh on Mac OS and Linux, the user shell on Amiga).
SYSTEM
waits until the called program exits.
SYSTEM
returns the return code of the executed command as an integer.
SYSTEM*
is the star version of SYSTEM
and has the same
effect as SYSTEM
(see SYSTEM).
The only difference is that SYSTEM*
executes the command line
asynchronously, thus the function returns immediately.
SYSTEM*
returns 0 if it was successful in starting execution of
the command line, otherwise it returns a non-zero integer value
representing a system specific error code.
See also SYSTEM, EDIT*, VIEW*.
STAT
examines a filename.
|
STAT
returns NIL if the filename could not be found,
0 if the filename exists and is a directory, and an integer
value greater than 0 if the filename exists and is a regular file.
TACKON
creates a pathname.
|
TACKON
knows how to deal with special characters used as path
separators at the end of each argument.
It returns the pathname as a string or NIL if any of the arguments is NIL.
Note that TACKON
does not perform any check whether the resulting
path actually refers to an existing file or directory in the filesystem.
Example: `(TACKON "Sys:System" "CLI")' results to "Sys:System/CLI".
FILENAME
extracts the filename part of a path name.
|
FILENAME
to
get the name of a sub-directory.
FILENAME
returns its result as a string or NIL if
path is NIL.
Example: `(FILENAME "Sys:System/CLI")' results to "CLI".
DIRNAME
extracts the directory part of a path name.
|
DIRNAME
to
get the name of a parent directory.
DIRNAME
returns its result as a string or NIL if
path is NIL.
Example: `(DIRNAME "Sys:System/CLI")' results to "Sys:System".
MESSAGE
displays a message to the user.
|
SPRINTF
function (see SPRINTF).
MESSAGE
returns the formatted title string.
Example: `(MESSAGE "6 * 7 = %i" (* 6 7))'.
COMPLETEMAX
sets the maximum number of progress steps.
|
COMPLETEMAX
returns its argument steps.
See also COMPLETEADD, COMPLETE.
COMPLETEADD
increases the progress state.
|
COMPLETEADD
returns its argument add.
(SETQ num ...) (COMPLETEMAX num) (DOTIMES (i num) (COMPLETEADD 1) ) |
COMPLETE
sets the progress state.
|
COMPLETE
returns its argument cur.
(COMPLETE 10) ... (COMPLETE 50) ... (COMPLETE 100) |
GC
forces garbage collection.
|
PUBSCREEN
returns name of public screen.
|
PUBSCREEN
returns the name of the public screen MUIbase
is running on, or NIL in case the screen is not public.
On other systems PUBSCREEN
returns NIL.
MUIbase knows some pre-defined global variables.
In the current version there exists only one global variable: stdout
(see stdout).
The following pre-defined constants can be used in any expression for programming.
Name Type Value Comment ------------------------------------------------------------------------- |
#define
preprocessing directive (see #define).
You can pass a function as an argument to another function. This is useful for defining functions of higher order, e.g. for sorting or mapping a list.
To call a function that has been passed in an argument you have
to use the FUNCALL
function (see FUNCALL).
(DEFUN map (l fun) # arguments: list and function (LET (res) # local variable res, initialized with NIL (DOLIST (i l) # for all items one by one (SETQ res (CONS (FUNCALL fun i) res) # calls function and ) # build new list ) (REVERSE res) # we need to reverse the new list ) ) |
`(map (LIST 1 2 3 4) 1+)' results to ( 2 3 4 5 ).
See also FUNCALL, APPLY, MAPFIRST.
It is possible to specify the type of a variable by adding a type specifier behind the name. The following type specifiers exist:
Specifier Description :INT for integers :REAL for reals :STR for strings :MEMO for memos :DATE for dates :TIME for times :LIST for lists :FILE for file handles :FUNC for functions of any type :table for record pointers to table |
(LET (x:INT (y:REAL 0.0) z) ...) |
The advantage of the type specifiers is that the compiler can detect more type errors, e.g. if you have a function:
(DEFUN foo (x:INT) ...) |
For reasons of speed no type checking is currently done at run time. It could be implemented but then would add a little overhead which is not really necessary as the wrong type will result in a type error sooner or later anyway.
Type specifiers for record pointers have another useful feature. If you tag a variable as a record pointer to a table then you can access all attributes of this table by using the variable name instead of the table name in the attribute path. E.g. if you have a table `Foo' with an attribute `Bar', and you define a variable `foo' as:
(LET (foo:Foo) |
(SETQ foo (RECORD Foo 3)) (PRINT foo.Bar) |
The semantics of expressions are very important for understanding what a program does. This section lists the semantics depending on syntactical expressions.
(
func [expr ...])
Evaluates expr ... and then calls the function func
(call by value).
Returns the return value of the called function.
In MUIbase there exists some non-strict functions, e.g.
AND
, OR
and IF
.
These functions may not evaluate all expressions.
For more information about non-strict functions, see Lisp syntax,
AND, OR, and IF.
(
[expr ...])
Evaluates expr ... and returns the value of the
last expression (see PROGN).
An empty expression ()
evaluates to NIL.
Returns the program record pointer of the given table.
Returns the GUI record pointer of the given table.
Returns the contents of the specified attribute. The attribute path specifies which record is used to extract the attribute value. For example `Table.Attribute' uses the program record of `Table' to extract the value of the attribute, `Table.ReferenceAttribute.Attribute' uses the program record of `Table' to extract the value of the reference attribute (which is a record pointer) and then uses this record to extract the value of `Attribute'.
Returns the contents of the global or local variable var.
Global variables can be defined with DEFVAR
(see DEFVAR),
local variables e.g. with LET
(see LET).
For automatic execution of MUIbase programs you can specify trigger functions for projects, tables and attributes which are called in specific cases. This section lists all available trigger possibilities.
15.29.1 onOpen Trigger after opening a project. 15.29.2 onClose Trigger when closing a project. 15.29.3 onAdminMode Trigger when entering/leaving admin mode. 15.29.4 onChange Trigger when changing a project. 15.29.5 New trigger Trigger for allocating a new record. 15.29.6 Delete trigger Trigger for deleting a record. 15.29.7 Comparison function For comparing records of a table. 15.29.8 Attribute trigger Trigger for changing an attribute. 15.29.9 Virtual attributes How to write functions for virtual attributes. 15.29.10 Compute enabled function For computing the enabled state of an object. 15.29.11 Double click trigger Trigger for double clicks in a virtual list. 15.29.12 Compute list-view labels Trigger when pressing list-view pop-up. 15.29.13 Compute reference records Trigger when pressing reference pop-up.
After opening a project, MUIbase searches the project's program
for a function called onOpen
.
If such a function exists then this function is called without
any arguments.
(DEFUN onOpen () (ASKBUTTON NIL "Thank you for opening me!" NIL NIL) ) |
Before closing a project, MUIbase searches the project's program
for a function called onClose
.
If such a function exists then this function is called without
any arguments. In the current version the result of the
trigger function is ignored and the project is closed regardless
of its return value.
If you do changes to the project in the onClose
function
then MUIbase will ask you for saving the project first before
it is actually closed. If you use menu item `Project - Save & Close'
for closing the project, the trigger function is called before
saving the project, thus the changes are saved automatically.
(DEFUN onClose () (ASKBUTTON NIL "Good bye!" NIL NIL) ) |
Whenever a project is set into admin mode or user mode
and a function called onAdminMode
exists in the project's program
then this function is called.
The funnction receives one argument admin
telling whether the project is in admin mode (admin is non-NIL)
or in user mode (admin is NIL).
(DEFUN onAdminMode (admin) (IF admin (ASKBUTTON NIL "Now in admin mode" NIL NIL) (ASKBUTTON NIL "Back to user mode" NIL NIL) ) ) |
Whenever the user makes changes to a project or after saving a project,
MUIbase searches the project's program for a function called
onChange
.
If such a function exists then this function is called without
any arguments. This can be used to count the changes a user
does to a project.
(DEFUN onChange () (SETQ Control.NumChanges (CHANGES)) ) |
See also onOpen, onClose, onAdminMode, demo `Trigger.mb'.
When the user wants to allocate a new record by selecting one of the menu items `New record' or `Duplicate record' and the `New' trigger of that table has been set to a MUIbase program function then this trigger function is executed. The `New' trigger function can be set in the table requester (see Creating tables).
The trigger function receives NIL or a record pointer as the first
and only argument. NIL means that the user wants to allocate a
new record, a record pointer means that the user wants to duplicate
this record. If the trigger function has more than one argument
then these are initialized with NIL. The trigger function should
allocate the new record by calling the NEW
function (see NEW).
The result returned by the trigger function will be examined.
If it returns a record pointer then this record will be displayed.
The `New' trigger is also called when a MUIbase program calls
the NEW*
function (see NEW*).
(DEFUN newRecord (init) (PROG1 ; for returning the result of NEW (NEW Table init) ... ) ) |
When the user wants to delete a record by selecting menu item `Delete record' and the `Delete' trigger of that table has been set to a MUIbase program function then this trigger function is executed. The `Delete' trigger function can be set in the table requester (see Creating tables).
The trigger function receives a Boolean argument as its only argument.
If the argument is non-NIL then the function should ask the user
if he really wants to delete the record. If so, the function should
call DELETE
(see DELETE) for deleting the record.
The `Delete' trigger is also called when a MUIbase program calls
the DELETE*
function (see DELETE*).
(DEFUN deleteRecord (requester) (DELETE Table requester) ) |
For defining an order on the records of a table you can use a comparison function. See Changing orders, for information on how to specify such a function for a table. The function takes two record pointers as arguments and returns an integer value reflecting the order relation of the two records. The comparison function should return a value smaller than 0 if its first argument is smaller than the second, 0 if they are equal and a value larger than 0 it the first argument is greater then the second one.
For example, if you have a table `Persons' with a string attribute `Name' then you could use the following function for comparing two records:
(DEFUN cmpPersons (rec1:Persons rec2:Persons) (CMP rec1.Name rec2.Name) ) |
Using a comparison function you can define very complex order relations. Be careful not to create recursive functions that will call itself. MUIbase will stop program execution and prompt you with an error message if you try to do so. Also you should not use commands that cause side effects, e.g. setting a value to an attribute.
When using a comparison function, MUIbase does not always know when it has to reorder its records. E.g. consider in the above example another table `Toys' with a string attribute `Name' and a reference attribute `Owner' referring to `Persons', and the following function for comparing records:
(DEFUN cmpToys (rec1:Toys rec2:Toys) (CMP* rec1.Owner rec2.Owner) ) |
Now if the user changes one record in the `Persons' table and this record gets a new position then also records in `Toys' that refer to this record have to be reordered. MUIbase, however, does not know of this dependency.
Besides using menu item `Table - Reorder all records' on the `Toys' table for rearranging the order, you can implement an automatic reordering yourself by specifying the following trigger function for the `Name' attribute of `Persons':
(DEFUN setName (newValue) (SETQ Persons.Name newValue) (FOR ALL Toys WHERE (= Toys.Owner Persons) DO (SETISSORTED Toys NIL) ) (REORDER Toys) ) |
See also Order, CMP, GETISSORTED, SETISSORTED, REORDER, REORDERALL, GETORDERSTR, SETORDERSTR, demo `Order.mb'.
In the attribute requester (see Creating attributes) you can define a trigger function that is called whenever the user wants to change the attribute contents.
If you have defined such a trigger function for an attribute and
the user changes the value of that attribute then
the record contents are not automatically updated with the new value.
Instead the value is passed to the trigger function as first argument.
The trigger function can now check the value and may refuse it.
To store the value in the record you have to use the SETQ
function.
The trigger function should return the result of the SETQ
call or the old value of the attribute if it decides to refuse
the new one.
The trigger function is also called when a MUIbase program calls
the SETQ*
function (see SETQ*) for setting a value
to the attribute.
(DEFUN setAmount (amount) (IF some-expression (SETQ Table.Amount amount) (ASKBUTTON NIL "Invalid value!" NIL NIL) ) Table.Amount ; return current value ) |
In MUIbase virtual attributes are special attributes that calculate their value on the fly whenever it is needed. E.g. if you go to another record by clicking on one of the arrow buttons in a table's panel bar then a virtual attribute in that table is automatically recomputed and displayed (given appropriate settings for the virtual attribute, see Attribute object editor). For computing the value the attribute's `Compute' trigger function is called. This trigger function can be specified in the attribute requester (see Type specific settings). The return value of this function defines the value of the virtual attribute. If you don't specify a `Compute' trigger function for a virtual attribute then the attribute's value is NIL.
You can also trigger the calculation of a virtual attribute by simply accessing it in an MUIbase program, so e.g. if you have a button that should compute the value of the virtual attribute, you only need to specify a function for the button like the following one:
(DEFUN buttonHook () virtual-attr ) |
SETQ
function:
(SETQ virtual-attr expr) |
SETQ
call
then the value of the virtual attribute is recomputed.
There is no caching of the value of a virtual attribute because it's not easy to know when the value has to be recomputed and when not. Thus you should access virtual attributes rarely and cache the value in local variables for further use by yourself.
For an example on how to use virtual attributes please check the `Movie.mb' demo.
See also Virtual, demo `Movie.mb'.
For attribute objects and window buttons you can specify a trigger function for computing the enabled state of the object. See Attribute object editor and Window editor, for information on how to specify this trigger function.
The trigger function is called without any arguments. It should return NIL for disabling the object and non-NIL for enabling it.
For example the compute enabled function for an object, that gets enabled when a certain virtual attribute using the `List' kind has an active item, could look like this:
(DEFUN enableObject () (GETVIRTUALLISTACTIVE virtual-list-attr) ) |
For virtual attributes that use the list kind for displaying its contents, a trigger function can be specified which gets called whenever the user double clicks on an item in the list. See Attribute object editor, for information on how to specify this trigger function for a virtual attribute object.
The trigger functions is called with three arguments. The first argument holds the row number of the clicked field, starting with 1 for the first line (row 0 refers to the list header). The second argument holds the column number starting with 0. The third argument is a pointer to the record the list field has been generated from, or NIL if the entry has not been generated directly from one. The return code of the function is ignored.
A typical example of a double click trigger is the following.
(DEFUN doubleClickTrigger (row col rec:Table) ... ) |
In case there is more than one possible table the record argument could belong to, the following construction using type predicates to different tables is useful.
(DEFUN doubleClickTrigger (row col rec) (COND ((RECP Table1 rec) (SETQ Table1 rec) ...) ((RECP Table2 rec) (SETQ Table2 rec) ...) ... ) ) |
(DEFUN doubleClickTrigger (row col) (PRINT (NTH col (NTH row virtual-attr))) ) |
For string attributes, the GUI object can contain a listview pop-up that when pressed opens a list of label strings the user can choose from. The labels in this list can be static labels or they can be computed by a trigger function. See Attribute object editor, for information on how to select between static and computed labels and how to specify the trigger function.
The trigger function for computing the labels does not have any arguments. It should return a memo text with one label per line or NIL for no labels.
For example the compute function could look like this:
(DEFUN computeLabels () "Tokyo\nMunich\nLos Angeles\nRome" ) |
For reference attributes, the GUI object usually contains a pop-up button that when pressed opens a list of records the user can choose from. The list of records in this pop-up can be computed by a trigger function. See Attribute object editor, for information on how to specify the trigger function for reference fields.
The function for computing the list of records does not have any arguments. It should return a list that is searched for the occurrence of records of the referenced table. Any such record found is added to the list shown in the reference pop-up. Items that are not records of the referenced table are ignored silently.
A typical compute function for reference records is the following example. Say a project contains a table `Person' with a Boolean attribute `Female'. Then the following compute function only shows the female persons in the reference popup:
(DEFUN computeFemaleRecords () (SELECT Person FROM Person WHERE Female) ) |
The following functions are obsolete starting with MUIbase version 2.7.
GETDISABLED
SETDISABLED
GETWINDOWDISABLED
SETWINDOWDISABLED
Obsolete functions are not working as expected any longer and calling any of them is either ignored (resulting in a no-operation), opens a warning dialog, or causes an error, depening on the setting of menu item `Program - Obsolete functions' (see Obsolete functions).
It is recommended to remove these functions from a project program and implement the functionality using the enabled/disabled setting of attribute objects and window buttons (see Compute enabled function).
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |