*** Commands with version 1.5.1 *** ------------------------------------------------------------------------------- alias <from> <to> Alias 'from' to 'to'. This is a very simple substition system (expressions are not supported). One thing to note is that if an alias is used inside a procedure then substitutions are done _only_ inside that procedure. eg: alias 1 TRUE alias 0 FALSE ------------------------------------------------------------------------------- var <variable list> svar <variable list> These 2 commands are identical except that svar will cause the variables to be static within a procecure (ie their values are not lost when the procedure exits) whereas var will not. Variables can be declared as an array using '@'. eg: var tom @dick ------------------------------------------------------------------------------- share <variable list> unshare <variable list> Seperate processes can access each others variables providing they have been set to a sharing status using the share command. Only global variables belonging to the process using the share command can be shared. The unshare command removes sharing status from variables. eg: Process 'tom' sets variable 'a' to shared status like so: var a share a set a 1 Process 'dick' then accesses and sets the variable using the <process id>.<variable name> notation. set pid pcs?"tom" printnl "a is " pid.a set pid.a 2 ------------------------------------------------------------------------------- set <variable> <expression/value> This assigns a value to a variable or array element. If an array element does not exist when it is assigned to it is created as long as a specific index number is not used. eg: set tom [addstr "hello " "world] set dick:"one" "test string" ------------------------------------------------------------------------------- tset <variable> [<operator>] <old value> <new value> This is the test and set command which allows the testing and setting of shared variables atomically. Ie the process cannot be swapped out while it is doing the combined test and set and so this allows shared variables to be used as semaphores in interprocess communications. If you were to do the same operation using an "if" statement then the process may get swapped out between the test and set which could cause problems. The command tests the variables value against the old value depending on the operator (If no operator is given it defaults to = to preserve syntax compatability with previous versions of Avios). If the result is true then the command will set the variable to the new value and return 1. If not it will not change the variable and will return 0. This command can also be used on ordinary variables as shorthand for an if var=....; set var..; endif; statement for example. eg: set pid pcs?"testprog" while [not [tset pid.testvar>10 1]]; wend # Spin on semaphore ------------------------------------------------------------------------------- inc <variable> [amount] dec <variable> [amount] These increment or decrement a variable. The default is 1 if the optional amount is not specified. eg: inc fred dec fred 3 ------------------------------------------------------------------------------- addstr <string list> This adds a list of strings together to produce 1 long string. eg: printnl [addstr "hello " "cruel" " world"] ------------------------------------------------------------------------------- substr <string> <from> [<to>] Substracts the characters from 'from' to 'to' from the string. If 'to' is ommited then it defaults to the same as 'from'. This command does the exact opposite of midstr. eg: printnl [substr "12345" 2 4] ------------------------------------------------------------------------------- mulstr <string> <amount> This multiplies the string by the amount to give a result string. eg: printnl [mulstr "'ello " 3] "whats going on 'ere then?" ------------------------------------------------------------------------------- math <maths equation/expression> This works out normal maths equations and is a replacement for the add, sub, mul, div, mod, bwa, bwo, bwx, bsl & bsr commands that appeared in previous versions and have now been removed. Equations can use variables and embedded commands and full nested bracketing is supported. Operands it understands are as follows: +, -, *, /: standard maths operands %: modulus ^: power &: bitwise AND |: bitwise OR ~: bitwise XOR <<: bit shift left >>: bit shift right <: less than >: greater than <=: less than equals >=: greater than equals !=: not equals Priorites are as follows: &, |, ~, <<, >>: priority 4 (highest) ^, %: 3 *, /: 2 +, -: 1 >, <, <=, >=, !=: 0 (lowest) All the comparison operands ( eg <= ) either produce a 1 or 0 if the test is true or false respectively. eg: do set limit [rand 10] until limit!=0 printnl [math ([rand limit]-limit/2)*10] ------------------------------------------------------------------------------- cpl <number> This returns the ones complement of the number (~number in C) which is simply the reversal of all the bits in the integer ie: 0's become 1 and 1's become 0. To get the twos complement simply add 1 to the result. eg: printnl [cpl 0] ------------------------------------------------------------------------------- max <numeric list> min <numeric list> Return the maximum or the minimum of the numeric list. eg: printnl [max 2 15 8] ------------------------------------------------------------------------------- maxstr <string list> minstr <string list> Return the maximum or mininum of the string list eg: printnl [maxstr "hello" "cruel" "world"] printnl [maxstr "A" "B" "C"] ------------------------------------------------------------------------------- print <string or numeric list> printnl <string or numeric list> printlog <string or numeric list> These are the 3 output commands the language uses. The first two will output to wherever the current outstream is pointing too whereas printlog prints to the system log. Printnl automatically places a newline on the end of its output, the others do not. The first two commands can cause the process to go to an OUTPUT_WAIT state if they try to write to locked stream or full message queue stream unless the stream is non-blocking in which case they'll just fall through having done nothing (but the $print_ok system variable will have been set to 0 so you can check for this occurance). eg: printnl "hello" [addstr "cru" "el"] "world " 2 " day" ------------------------------------------------------------------------------- locate <x> <y> This will locate the cursor at the given position on the screen. Avios does not find out the size of any given screen a process is writing to so it will allow any values for x and y that are greater than zero. ie co-ordinates go from 1-n. eg: This draws a box in the centre of the screen proc main var y locate 30 5; print [mulstr "#" 20] locate 30 15; print [mulstr "#" 20] for y 5 to 15 locate 30 y; print "#" locate 50 y; print "#" next endproc ------------------------------------------------------------------------------- cls This command takes no arguments and simply clears the screen. It has exactly the same effect as doing print "~CL" but is a convenient shorthand for it. ------------------------------------------------------------------------------- label "<label>" goto <label> The label command can only have its label in the form of a quoted string but the goto command can use a variable or command output aswell. eg: label "start"; goto [addstr "st" "art"] ------------------------------------------------------------------------------- if <expression> <statements> [else] <statements> endif/fi The if statement works in the expected way and _must_ be terminated with an endif or fi. The else statement is optional. The fi command was new in 1.4 and I added it because on reflection I felt that endif was a bit long winded (you can tell I'm a C coder at heart :) but the endif remains for backwards compatability. eg: if fred=1; printnl "YES" else; printnl "NO" endif if fred=2; printnl "YES 2"; else; printnl "NO 2" fi ------------------------------------------------------------------------------- while <expression> <statements> wend A while loop loops while the expression is true. eg: while cnt<=10 printnl "Count: " cnt; inc cnt wend ------------------------------------------------------------------------------- do <statements> until <expression> A do loop loops until the expression is true. eg: do printnl "Count: " cnt; inc cnt until cnt>10 ------------------------------------------------------------------------------- for <variable> <start> to <end> [step <increment/decrement>] <statements> next Loop from the until the variable has reached the value <end> first setting it to the value <start>. The step is optional and if used will cause the variable to be incremented by the given amount. If no step option is given the interpreter will default to 1 if start < end or -1 if start > end. eg: for cnt 1 to 10; printnl "Count: " cnt; next ------------------------------------------------------------------------------- foreach <subscript variable> <value variable> in <array variable> <statements> nexteach This will go through the array variables elements setting the subscript variable to a subscript and the value variable to its matching value until no more array elements are found. eg: var @a s v set a:"tom" "first" set a:"dick" "second" set a:"harry" "third" foreach s v in a; printnl s "," v; nexteach ------------------------------------------------------------------------------- choose <value> value <value>; [<statements>]; break/continue default; [<statements>]; break/continue chosen This is an analog of the C switch statement but it has one crucial difference which is that the continue command plays a part and it will cause the interpreter to jump back to the beginning of the choose as in a loop. However you can use the acontinue (alternative continue) command which behaves in the "normal" way inside a choose (ie it will continue from the start of the loop body surrounding the choose structure). eg: choose cnt value 1; printnl "Its 1, 3 or 4"; break value 2; printnl "Its 2"; break value 3 value 4; set cnt 1; continue default; printnl "It isn't 1 , 2 or 3" chosen ------------------------------------------------------------------------------- break [<argument>] continue [<argument>] acontinue [<argument>] These work as per the commands in C except for continue within the choose structure (see above). The optional arguments set the $break and $cont variables. If no argument is given the variables remain at their current setting. eg: set j 0 while $break!="END" inc j for i 1 to 10 if [math i+j]=5; break "END"; endif next wend printnl i "," j ------------------------------------------------------------------------------- call <procedure> [<parameters>] vcall <procedure derived from operation> [<parameters>] Unsurprisingly this calls a procedure with optional parameters. These commands cannot be nested because of a rather intractable coding reason (we'd need to unwrap recursive calls within the interpeter itself) so the procedure return value is stored in the system $proc array. The vcall command takes strings, variables or command outputs as the name of the procedure to call. The 'v' stands for variable incidently as the procedure name argument can vary since it isn't fixed in the code (ie: its the equivalent of using function pointers in C). If I was writing Avios from scratch I'd probably leave out "call" altogether as vcall is more flexible and does the same but call is left in for compatability reasons with AviosPL old code (and I suppose it looks a bit neater too). eg: call fred a b printnl $proc:"fred" set procs "tom dick harry" for i 1 to 3 vcall [elements procs i] a b printnl $result next ------------------------------------------------------------------------------- proc <procedure> [<formal parameters>] endproc These commands define the start and end of a procedure as you'd expect. Parameters can either be declared as pass by value or by reference (the latter being defined by placing a star '*' in front of the variable) and can also be declare as an array or read only. eg proc fred c *d set d [math c*2] endproc ------------------------------------------------------------------------------- return [<return value>] exit <numeric exit code> The return command returns from a procedure , the return value being stored in the $proc array element for the precedure. Exit exits from the program and currently returns the exit code to the unix shell and the exit code can only be a number. eg: if a=b; return "fred" else; exit [math a-b] endif ------------------------------------------------------------------------------- input <variable list> This is the input command and it will take its input from the current input stream whatever that may be. Input is read up until the first newline encountered (or until the internal input string size is exceeded) and the date is placed in the first or next variable in the list. This command cannot be nested. The command will not return until all variables have been filled. eg: var name address print "Enter name and address> " input name address printnl "NAME: " name ", ADDRESS: " address ------------------------------------------------------------------------------- atoc <ascii code list> ctoa <string> Atoc converts a list of ascii codes into a character string and ctoa converts a string into a list of ascii codes. eg: printnl [ctoa "abc"] "=" [atoc 97 98 99] ------------------------------------------------------------------------------- not <value> This will return a 1 for any value that is zero or an empty string and will return 0 for anything that is <> 0 or is not an empty string. eg: printnl [not "hello"] [not 0] ------------------------------------------------------------------------------- strlen <string> This gives the length of a string. eg: printnl [strlen "hello"] ------------------------------------------------------------------------------- abs <number> Give the absolute value of the number which basically means that if its a negative value convert it to positive. ------------------------------------------------------------------------------- sgn <number> Give the sign of the number. A negative number returns -1 , positive 1 and 0 returns 0. ------------------------------------------------------------------------------- rand <seed> Returns a random number from 0 up to and *including* the seed. Note that the max value that can be returned is limited by the unix RAND_MAX macro which can be as low as 32767. ------------------------------------------------------------------------------- isnum <value> Returns 1 if the value is a number otherwise 0. eg: printnl [isnum "fred"] [isnum 123] [isnum "123"] ------------------------------------------------------------------------------- upperstr <string> lowerstr <string> These convert a string to upper and lower case respectively. eg: printnl [upperstr "hello"] ------------------------------------------------------------------------------- instr <searched string> <searched for string> <start point> This returns the position the searched for string is found in the search string with searching starting at the start point. If the string is not found then zero is returned. REMEMBER that the first character in the string is at position 1 in this language, not 0 as in C!! eg: printnl [instr "hello" "el" 1] ------------------------------------------------------------------------------- matchstr <string> <wildcard pattern> This returns 1 if the string matches the widlcard pattern else it returns 0. The pattern cannot use full regular expressions but is limited to '?' and '*'. eg: printnl [matchstr "hello world" "h?ll*"] ------------------------------------------------------------------------------- midstr <string> <from> [<to>] This will print the part of the string between and including the 'from' and 'to' positions. If 'to' is ommited it defaults to the same as 'from'. eg: printnl [midstr "12345" 2 4] ------------------------------------------------------------------------------- insertstr <string> <string to insert> <position> overstr <string> <string to insert> <position> Both these put one string inside another starting from position, the difference being that the top one will keep the strings original contents and shift them up accordingly whereas the bottom will overwrite as many characters as necessary. eg: printnl [insertstr "1256" "34" 3] printnl [overwrstr "1256" "34" 3] ------------------------------------------------------------------------------- replstr <string> <old string> <new string> [<start position>] This replaces any occurance of the old string found in string with the new string with the option to provide a search start position. eg: printnl [replstr "xyzdefg xyzdefg" "xyz" "abc"] ------------------------------------------------------------------------------- rpadstr <string> <pad string> <length> lpadstr <string> <pad string> <length> Both the above pad the given string using pad string until it is exactly length characters long. Lpadstr pads to the left whilst rpadstr pads to the right. eg: printnl [rpadstr "start" "-=" 20] printnl [lpadstr "end" "-=" 20] ------------------------------------------------------------------------------- insertelem <list> <element> <position> overelem <list> <element> <position> These work in the same way as the associated string commands. Insertelem will put the element at the given position but keeping the previous element by shitfing the remainder of the list up. Overelem simply overwrites the current element at that position with the new one. eg: printnl [insertelem "one two four" "three" 3] printnl [overelem "one two four four" "three" 3] ------------------------------------------------------------------------------- replelem <list> <old element> <new element> [<start position>] This will replace all occurances of the old element in the list with the new element optionally starting at the start position. eg: printnl [replelem "one two wibble four wibble two one" "wibble" "three"] ------------------------------------------------------------------------------- elements <list> <from> [<to>] This will list the elements from element number 'from' to 'to'. If 'to' is ommited then it defaults to the same as 'from'. eg: printnl [listelem "hello cruel world out there" 2 3] ------------------------------------------------------------------------------- count <list> This counts the number of elements in the given list. Elements are basically words seperated by whitespace. eg: printnl [count "there are seven elements in this list"] ------------------------------------------------------------------------------- match <list1> <list2> unmatch <list1> <list2> Match will return a string with all the elements in list1 that are also in list2. Unmatch does the opposite and returns the elements in list1 that are unmatched in list2. Things to note are that the do not check for repeated elements in list1 (tedious to code) so these will get returned twice if they exist and are part of the result. Duplicate elements in list2 will only be returned once for a match. eg: printnl [match "a a b c d e" "a h k q d p"] gives "a a d". but printnl [match "a b c d e" "a a h k q d p"] will only give "a d". printnl [unmatch "a a b c d e" "a h k q d p"] gives "b c e" ------------------------------------------------------------------------------ unique <list> This removes duplicate elements from a list. eg: printnl [unique "hello there hello cruel cruel world there"] ------------------------------------------------------------------------------ subelem <list> <from> [<to>] This returns the list minus the elements between and including the from and to positions. If 'to' is ommited it defaults to the same as 'from'. eg: printnl [sublem "hello there cruel world" 3] ------------------------------------------------------------------------------- head <list> tail <list> rhead <list> rtail <list> Head gives the first element in a list, rhead gives the last element. Tail gives everything except the first element , rtail everything except the last. eg: set list "head and tail" printnl [head list] "," [tail list] ------------------------------------------------------------------------------- arrsize <array> This returns the number of elements (not string elements) in an array. eg: var @a set a:"one" "first" set a:"two" "second" printnl [arrsize a] ------------------------------------------------------------------------------- trap <statement(s)> This traps any errors returned by the commands within the statements it encloses preventing the interpreter printing the error and halting. The trap command itself returns the error number as its output and also sets $error:"last" to the error number. eg: var fred err set err [trap [cleararray fred]] if err; printnl "Error is: " $error#err; endif or: var fred trap [cleararray fred] if $error:"last"; printnl "Error is: " $error#$error:"last"; endif Fred above is not an array variable and this will cause an error.O ------------------------------------------------------------------------------- in <stream> out <stream> These set the current input and output streams (ie where input and output is got from and sent to). Streams are internally linked with actual file descriptors but at the language level are just name strings. Built in streams are STDIN, STDOUT and STDERR but other streams are obtained from the output of the "open" command. eg: out "STDERR"; printnl "Error"; out "STDOUT" ------------------------------------------------------------------------------- block <input stream> nonblock <input stream> These commands switch blocking on and off for a stream that is either an input or bidirectional one. Normally a stream is blocked on a read which means that if there is no data on a stream or the data is incomplete any "input" command using that stream will hang until normally a newline is seen along with preceding data (other times it will return include an EOF or a closed socket). If noblocking is set the input will get whatever data is there if any and return immediately. Please note that this does NOT force the telnet or console session into non-blocking mode (CBREAK mode in curses.h). eg: nonblock "STDIN" printnl "Enter data> " do input a until a!="" block "STDIN" # return to normal The above will loop until a contains data, just pressing return will not stop the loop since a newline by itself is considered an empty string by the interpreter. ------------------------------------------------------------------------------- lock <internal stream> unlock <internal stream> This locks and unlocks an internal stream that belongs to the process executing the command (currently the only internal streams are message queues). A locked stream means that another process trying to write to it will go to an OUTPUT_WAIT state (or will just fall through the print command if stream is also non-blocking) until the stream becomes unlocked whereupon it can then write its data. eg: lock "MESG_Q" printnl "Current message count as of " [gettime time] " is: " $mesg_cnt unlock "MESG_Q" ------------------------------------------------------------------------------- open to read/write/readwrite/append <filename> This opens a file to carry out normal file operations. It returns a stream identifier as a result which can be used with the in and out commands. If a file is opened to write it will be deleted if it already exists unless it is opened using "readwrite". Append behaves in the usual way. eg: set stream [open to read "datafile"] in stream input line ------------------------------------------------------------------------------- close <stream> Closes a stream and free all memory structures associated with it. ------------------------------------------------------------------------------- cseek start/current <chars offset> lseek start/current <lines offset> These commands both seek through the current input stream, the difference is that cseek does it by number of characters and lseek by number of lines. lseek will count a line as soon as it hits '\n' in the character stream. The "start" option starts the seek from the beginning of the file whereas "current" starts it from the current file position. If the seek can be done a '1' is returned else '0'. eg: set fd [open to read "abcd"] in fd input line if [lseek current 2]=0 printnl "File too small."; close fd; exit 0 endif ------------------------------------------------------------------------------- delete <filename> Delete the named file. An error will be returned if this is not possible eg: If the files doesn't exist or it is in use by another process. ------------------------------------------------------------------------------- rename <old filename> <new filename> Rename the given file from the old to the new name. An error is returned if this can't be done because of the sames reasons as delete. ------------------------------------------------------------------------------- copy <old filename> <new filename> Copy the given file from the old to the new name (keeping the old one naturally). An error is returned if this can't be done. ------------------------------------------------------------------------------- stat <filesytem entry> This returns the following information: file type, size, permissions, last modified, last accessed, owner, group File type will be one of the following: dir - directory file - regular file link - soft link (hard links will be seen as regular files) cdev - character device (eg: tty) bdev - block device (eg: disk driver) fifo - FIFO special file (eg: a pipe) socket - AF_UNIX socket unknown - unknown type The last modified and accessed fields are given as the number of seconds since 1970 which can be converted into times using the gettime command. The owner and group fields were added in release 1.5.1. eg: printnl [gettime time [elements [stat "myfile" ] 4]] ------------------------------------------------------------------------------- chmod <filename> <octal permissions> This changes the permissions of a file. The permissions given are in numeric octal form, eg: 664, 700 etc. The command does not support the "ug+rw" etc format supported by the unix chmod command. eg: chmod "myfile" 600 printnl [elements [stat "myfile"] 3] ------------------------------------------------------------------------------- mkdir <directory> <octal permissions> This will create a directory with the given permissions if supplied. If they are not given then the permissions default to 0755. eg: mkdir "tmpdir" 700 ------------------------------------------------------------------------------- rmdir <directory list> This will remove directories. eg: rmdir "tmpdir" "neilsdir" ------------------------------------------------------------------------------- dir all/files/dirs/links/cdevs/bdevs/usocks <directory> [<wildcard patterns>] This command will return a list of the specified file types in the given directory. The types are the following: all - everything (files , directories , links etc) files - ordinary files dirs - directories cdevs - character devices bdevs - block devices usocks - unix sockets The wildcard pattern allows you to selectively list entries using the '?' and '*' wildcard substitution operators. Please note that full regular expressions are not supported. eg: printnl [dir cdevs "/dev"] printnl [dir all "."] printnl [dir files "." "a*" "???"] ------------------------------------------------------------------------------- format <format string> <argument string1> <string2> ... This will act like C's printf and sprintf statements by formatting a string using \ escape codes and % format definers. There are limitations though in that \000 octal codes are not supported nor is the %* format but for the majority of applications this should not be a problem. Supported escape codes are: \n \r \b \f \t \v and \a. Also \" will allow quotes to be printed in strings. eg: print [format "\aName: \"%-20s\", Total: %03d\n" name [math tot1+tot2]] ------------------------------------------------------------------------------- crypt <string> <salt> This calls the unix crypt function (or avios_crypt() if unix function not available) with the string to be encrypted and the salt. eg: set encrypted_passwd [crypt passwd "NU"] ------------------------------------------------------------------------------- spawn [term/back/dev <device>] [child/orphan] <pid var> [<new process name>] This will spawn a new process. The term, back and dev options allow you to run the new process on the system console in the background or on a given device (normally a tty) instead of them using the port of the current process. If a device is to be used the device name must given after the dev option. The child/orphan option will decide whether the new processes parent pid will be set to that of the spawning process or will be set to zero. If this option is ommited it defaults to a child process. The pid variable will be set to the pid of the process created in the enviroment of the parent process but will be set to zero in the enviroment of the child/orphan process (which will commence its execution from the command immediately following "spawn" in the code). The optional new process name will rename the new process otherwise the process is given the same name as its parent. eg: var pid spawn child pid "tom" if pid; printnl "PARENT"; else; printnl "CHILD"; endif spawn dev "/dev/tty" orphan pid ------------------------------------------------------------------------------- exec [term/back/dev <device>] [child/orphan] <pid var> \ <filename> <process name> [<arguments>] iexec [term/back/dev <device>] [child/orphan] <pid var> \ <program code> <process name> [<arguments>] These will create an entirely new process, either loading up and running the program file given or running the inline code passed with iexec giving it the process name and passing it the command line arguments if any. The exec'ing process will be returned the pid of the new process. The new process (unlike in the spawn command) will start running from the beginning of its main procedure and if the child option is specified its parent id will be set to that of the exec'ing process else it'll be set to zero. The term and back options allow you to run the new process on the system console or in the background instead of them using the port of the current process, the dev option allows you to run it on a tty device (the device name must follow) and the child and orphan options allow you to decide whether the new process will be a child of the exec'ing one or not. If ommited it defaults to being a child. eg: var pid exec child pid "progfile" "tom" "hello" "world" printnl "New pid: " pid iexec child pid [format "proc main argc argv\n \ printnl $name \",\" argc \",\" argv\nendproc"] \ "tom" "hello world" In the above you could also do the following: exec child pid "progfile tom hello world" eg: var pid exec dev "/dev/ttyS1" child pid "login" "login" ie you can have the filename , process name and arguments all in one string. ------------------------------------------------------------------------------- wait <pid var> waitpid <pid> These two commands both wait for termination of processes but the difference is that "wait" will wait for any child process to exit and when it does it returns the pid of the process in the pid variable, whereas "waitpid" will wait for the specific process given as the argument to die and will then return. eg: var pid wait pid : waitpid 3 ------------------------------------------------------------------------------- exists <pid> Returns 1 if the given process exists , otherwise 0. ------------------------------------------------------------------------------- pcsinfo <pid> Returns a list of information about the given process which consists of the following: <process name> <process main filename> <parent pid> <time created> \ <site connected (if any)> <status> <interrupts enabled> <interrupted> \ <message count or queue> <colour on> <swapout after> \ <run count 1> <run count 2> <run count 3> <run count 4> The fields are all self explanitory except for the last line: The run count fields are system statistics on how many times the process has been in scope in certain parts of the scheduler code. I put them in for performance optimisation purposes but I doubt you'll ever need them. ------------------------------------------------------------------------------- relation <pid1> <pid2> This prints a number giving the relation of process 1 to process 2. If the number is negative then this shows that process 1 process is a decendent of 2 but if positive then its an ancestor. The number shows how far removed the processes are. A -1 or 1 indicates a parent or child respectively , -2 or 2 indicates grandparent/grandchild etc. If the result is 0 then either there is no line of descent or the pid equals that of the current process. eg: var pid spawn child pid if pid printnl "PID: " $pid "," pid ": " [relation pid $pid] endif sleep 1 # So the child process doesn't vanish before we test relation ------------------------------------------------------------------------------- kill <pid> halt [<pid>] restart <pid> These command will kill, halt or restart the given process providing the following conditions are met: A) It is not the system_dummy process. B) The process is not a process image. C) The process is not already exiting. D) It is a descendent process of the killing process or kill_any is set to YES in the init file. E) For restart command only: The process is currently halted. The commands return the status of the process just before we did the action to it or if it is not possible to affect the other process an empty string is returned. bear in mind that if the pid does not exist an error will be returned so you may wish to trap the command in case the other process dies just before the command is executed. If the pid is ommited with the halt command the process will halt itself (but it cannot restart itself after this so some other process will have to do it). eg: spawn child pid if [not pid] printnl "Child sleeping"; sleep 10 endif sleep 1 if [trap [set status [kill pid]]] printnl "Error during kill." endif if status="" printnl "Unable to kill process" else printnl "Child status was: " status endif ------------------------------------------------------------------------------- onint from child/nonchild/timer <procedure> onint ignore child/nonchild/timer This command sets up the processes action upon receiving an interrupt. There are 3 different types of interrupt it can receive: child - an interrupt sent by a child process nonchild - an interrupt sent by a non-child process timer - an interrupt sent by an expired timer The procedure given is the procedure called when one of these is received. The ignore option will reset any action previously setup. Please note that there are no default options for interrupts , if a process receives one but onint has not been used the interrupt is ignored and the process does nothing. eg: proc main onint from timer timer_proc timer 1 while 1; wend # loop forever endproc proc timer_proc svar tt if tt="" or tt="tock"; set tt "tick" else; set tt "tock" endif printnl tt timer 1 endproc ------------------------------------------------------------------------------- interrupt <pid> with <string> [on death] This command will interrupt the given process if possible setting its $int_mesg variable to the given string. If interruption is possible it does so and returns a 1 else it returns a 0. The on death clause will cause the process to interrupt the given process if it dies. If interruption is not possible at this point the wait_on_dint init option will decide whether the process hangs until it can interrupt or exits anyway. eg: proc main var pid onint from child intproc spawn child pid if pid=0 # Child interrupts parent interrupt $ppid with "HELLO!" exit 0 endif while 1; wend # Loop until child gets swapped in and sends interrupt endproc proc intproc # Pid of interrupting process is first element in message printnl "Parent got interrupt from: " [head $int_mesg"] printnl "Message: " [tail $int_mesg] exit 0 endproc ------------------------------------------------------------------------------- timer <seconds> This sets up the timer. When the timer expires its sends a timer interrupt to the process. If the process cannot be interrupted the timer interrupt is blocked until interruption is possible. eg: proc main onint from timer timeprint timer 1 while 1; wend endproc proc timeprint printnl [gettime time] timer 1 # Reset timer endproc ------------------------------------------------------------------------------- ei [on/ignore <procedure>] di [on/ignore <procedure>] These commands enable and disable interrupts respecitively. If used without the options then they do this immediately. Using the 'on' option will cause Avios to enable/diable interrupts upon entering the given procedure. When exiting said procedure the interrupt state will be set back to what it was before the procedure was called. The 'ignore' option will unset anything set up the 'on' option. eg: proc main di on sleepproc onint from timer timerproc timer 1 sleep 5; call sleepproc; sleep 5 endproc proc timerproc printnl [gettime time] timer 1 endproc proc sleepproc printnl "Interrupts disabled" sleep 5 printnl "Interrupts enabled" endproc ------------------------------------------------------------------------------- sleep <seconds> usleep <microseconds> These will pause the program for the given time period. The accuracy of the usleep command however is up for debate for low values of microseconds. Also bear in mind that any tuning_delay set in the init file will also have an effect on the actual delay experienced as any delay can *never* be less than the tuning_delay even if it is set as such. eg: while 1 printnl [gettime secs] sleep 1 wend ------------------------------------------------------------------------------- gettime boottime/created/rawtime/date/usdate/rvdate/time/... hours/mins/secs/usecs/wday/mday/month/year/dayname/monthname... [<rawtime in seconds>] This commands returns various times in various formats which mean the following: boottime : Raw time in seconds when Avios was booted (unaffected by optional arg). created : Raw time when process making this call was created (as above). rawtime : Current raw time in seconds from unix time(0) function (as above). date : Date in day/month/year format as used in most of the world. usdate : Date in month/day/year format as used in the USA. revdate : Date in year/month/day (reverse) format. time : Time in hours:mins:secs format. hour : Hour of the day (0 - 23). mins : Minute of the hour. secs : Seconds of the minute. usecs : Microseconds in the second (same value for rawtime time and any user given fromtime) wday : Numeric day of the week (1-7). mday : Numeric day of the month. month : Numeric month of the year (1-12) year : Four digit year (eg 1997) dayname : Name of the day. monthname: Name of the month. The unix time() function normall returns the number of seconds since 1/1/1970. The optional rawtime argument to this command supplies an alternative number of seconds since this date for the commands to use. A simple clock: proc main while 1 print [format "%s\r" [gettime time]] sleep 1 wend endproc ------------------------------------------------------------------------------- colour on/off This switches the conversion of Avios colour codes to ansi codes on and off in print statements. Even when switched on conversion will only take place if the print is writing to STDIN or OUT. Conversion will not take place if we are writing to a file, a process created connect socket or an internal stream such as a message queue. In those cases the Avios colour codes will simply get passed as text. If colour is off and we are writing to STDIN etc then the Avios codes will be removed from the string before it is passed on. The default process colour setting is controlled by the colour_def init file option. eg: colour on printnl "~BR~FGRed background , green foreground." colour off printnl "~BR~FGRed background , green foreground? Not any more." ------------------------------------------------------------------------------- connect <ip address> <port> This attempts to open a socket to the given address and returns a new stream identifier if successful else an error is generated (which can be trapped). Be warned that this command will hang the whole Avios system until it connects or gets an error. eg: if [trap [set sock [connect "localhost" 4000]]] printnl "Unable to connect"; exit 0 endif in sock out sock : ------------------------------------------------------------------------------- echo on/off This switches echoing on and off for the STDIN of the process so passwords can be entered and not be seen. eg: print "Enter name> "; input name echo off print "Enter password> "; input pass echo on -------------------------------------------------------------------------------