RExL Version 2.11 A Rule-based Applications Development Environment From The Software Loft, Kiemar House, Shanakiel Road, Cork City, Ireland. Tel: [+353] 21-302511 Fax: [+353] 21-343562 Internet: softloft@iruccvax.ucc.ie Compuserve: 100042,1237 -- Part II -- The Appendices -- _______ ____|__ | (R) --| | |------------------- | ____|__ | Association of | | |_| Shareware |__| o | Professionals -----| | |--------------------- |___|___| MEMBER This program is produced by a member of the Association of Shareware Professionals (ASP). ASP wants to make sure that the shareware principle works for you. If you are unable to resolve a shareware-related problem with an ASP member by contacting the member directly, ASP may be able to help. The ASP Ombudsman can help you resolve a dispute or problem with an ASP member, but does not provide technical support for members' products. Please write to the ASP Ombudsman at 545 Grover Road, Muskegon, MI 49442- 9427 or send a Compuserve message via CompuServe Mail to ASP Ombudsman 70007,3536. o Information in this document is subject to change without notice and does not represent a commitment on the part of The Software Loft. The software described in this manual may be used and copied within the terms of the license agreement. Turbo C, Turbo Pascal and Sidekick are registered trademarks of Borland International. dBase III+ and dBase are registered trademarks of Ashton-Tate. (C) Copyright, The Software Loft, 1992. All rights reserved. If you have any difficulties, please contact us at the address above. Contents Chapter 1 Function Families 3 1.1 Introduction . . . . . . . . . . . . . . 3 1.2 Array handling . . . . . . . . . . . . . 3 1.3 Binary operations . . . . . . . . . . . 4 1.4 Database operations . . . . . . . . . . 4 1.5 Date and time manipulation . . . . . . . 5 1.6 RExL error handling functions . . . . . 6 1.7 Keyboard handling functions . . . . . . 7 1.8 Operating system interface functions . . 7 1.9 Financial functions . . . . . . . . . . 8 1.10 Mathematical functions . . . . . . . . 8 1.11 Screen handling functions . . . . . . . 9 1.12 Miscellaneous functions . . . . . . . . 9 Chapter 2 The Database Module 11 2.1 Introduction to Databases . . . . . . 11 2.2 Indexes . . . . . . . . . . . . . . . 13 2.3 Using Database Files . . . . . . . . . 15 2.3.1 Opening and selecting files . . . 15 2.3.2 Reading and writing to files . . 16 2.3.2.1 Using functions . . . . . . 16 2.3.2.2 Direct field access . . . . 18 2.3.3 Moving around in a file . . . . . 20 2.3.4 Miscellaneous functions . . . . . 20 2.3.4.1 Statistical analysis of data . . . . . . . . . . . . 20 2.3.4.2 Deletion of information . . 20 2.3.4.3 Other functions . . . . . . 21 Chapter 3 Function Reference 23 Chapter 4 Keystroke reference 95 4.1 Editor keystrokes . . . . . . . . . . 95 4.2 Screen designer keystrokes . . . . . . 97 4.3 Debugger keystrokes . . . . . . . . . 99 i Chapter 5 Error Messages 101 5.1 Error messages common to runtime and editor . . . . . . . . . . . . . . . . 101 5.1.1 Bad help file format . . . . . . 101 5.1.2 Cannot locate system . . . . . . 101 5.1.3 Cannot open print file . . . . . 101 5.1.4 Couldn't open file . . . . . . . 101 5.1.5 Macros nested too deep (20=max) . 102 5.1.6 Help file index is not loaded . . 102 5.1.7 Unable to locate help file . . . 102 5.1.8 Macro recursion not allowed . . . 102 5.1.9 Error loading configuration file . . . . . . . . . . . . . . 102 5.1.10 Zero memory allocation request! . . . . . . . . . . . . 102 5.1.11 Not enough memory to perform selected operation . . . . . . . 103 5.1.12 This window is not movable . . . 103 5.1.13 No directories available . . . . 103 5.1.14 No files in directory . . . . . 103 5.1.15 No macros defined . . . . . . . 103 5.1.16 --- Out of memory --- . . . . . 103 5.1.17 No screens defined . . . . . . . 103 5.1.18 Not enough memory to load system . . . . . . . . . . . . . 103 5.1.19 No unused rules available . . . 104 5.1.20 No unused screens available . . 104 5.1.21 No variables defined . . . . . . 104 5.1.22 Rule is not used in current listing . . . . . . . . . . . . 104 5.1.23 Error saving configuration file . . . . . . . . . . . . . . 104 5.1.24 Screen is not used in current listing . . . . . . . . . . . . 104 5.1.25 Screen file is corrupt . . . . . 104 5.1.26 Too many files open . . . . . . 105 5.1.27 Too many keys in macro (500=max) . . . . . . . . . . . 105 5.1.28 Variable is not used in current listing . . . . . . . . . . . . 105 5.1.29 Wrong source file format . . . . 105 5.1.30 Wrong screen file format . . . . 105 5.1.31 Error opening screen file . . . 105 5.2 Error messages unique to editor . . . 106 5.2.1 Incorrect format in listing file . . . . . . . . . . . . . . 106 5.2.2 Cannot nest fields . . . . . . . 106 ii 5.2.3 Can only delete recursed rule from first level of recursion . . . . 106 5.2.4 Unable to locate runtime module . 106 5.2.5 Area crosses fields . . . . . . . 106 5.2.6 Can't have a field of this type in this screen . . . . . . . . . . . 107 5.2.7 Illegal array dimension . . . . . 107 5.2.8 Maximum number of fields reached . . . . . . . . . . . . . 107 5.2.9 Memory low, should save now! . . 107 5.2.10 Not used in listing . . . . . . 107 5.2.11 This is the main rule and is called to start the kbs . . . . . . . . 107 5.2.12 Cannot change rule name to one already existing . . . . . . . . 107 5.2.13 This screen already exists . . . 108 5.2.14 Toggle fields must be more than 5 and less than 75 characters wide . . . . . . . . . . . . . . 108 5.2.15 Unable to create screen file . . 108 5.2.16 Error saving file . . . . . . . 108 5.2.17 Error loading file . . . . . . . 108 5.2.18 Error loading screen file . . . 108 5.2.19 Cannot change name of Main Program . . . . . . . . . . . . 108 5.3 Error messages unique to runtime- debugger . . . . . . . . . . . . . . . 109 5.3.1 Array bounds overflow . . . . . . 109 5.3.2 Can't set a breakpoint here . . . 109 5.3.3 Cannot open printer for output . 109 5.3.4 Cannot find editor . . . . . . . 109 5.3.5 Divide by zero . . . . . . . . . 109 5.3.6 String-numeric collision . . . . 109 5.3.7 Can't have string for radio button parameter . . . . . . . . . . . . 110 5.3.8 Stack underflow . . . . . . . . . 110 5.3.9 Stack overflow . . . . . . . . . 110 5.3.10 Numeric value out of range . . . 110 5.3.11 Rule stack overflow . . . . . . 110 5.3.12 Invalid database file handle . . 110 5.3.13 Unable to allocate rule stack . 111 5.3.14 Math error : Parameter out of range in function XXX . . . . . . . . 111 5.3.15 Math error : Parameter singularity in function XXX . . . . . . . . 111 5.3.16 Math error : numeric overflow . 111 5.3.17 Math error : numeric underflow . 111 5.3.18 Math error : precision loss . . 111 iii 5.4 Critical Errors . . . . . . . . . . . 111 5.4.1 Write protect error . . . . . . . 112 5.4.2 Drive not ready . . . . . . . . . 112 5.4.3 Printer out of paper . . . . . . 112 5.4.4 Write fault . . . . . . . . . . . 112 5.4.5 Read fault . . . . . . . . . . . 112 5.4.6 General Failure . . . . . . . . . 112 5.4.7 Sector not found . . . . . . . . 113 5.4.8 Unknown unit . . . . . . . . . . 113 5.4.9 Unknown command . . . . . . . . . 113 5.4.10 CRC error . . . . . . . . . . . 113 5.4.11 Bad request structure length . . 113 5.4.12 Seek error . . . . . . . . . . . 113 5.4.13 Unknown media type . . . . . . . 113 Chapter 6 Extra Utilities 115 6.1 RExLPC . . . . . . . . . . . . . . . . 115 6.2 RDU . . . . . . . . . . . . . . . . . 117 6.2.1 Introduction . . . . . . . . . . 117 6.2.2 Loading and Running . . . . . . . 117 6.2.3 RDU menu system . . . . . . . . . 117 6.2.3.1 File Menu . . . . . . . . . 117 6.2.4 Edit Menu . . . . . . . . . . . . 119 6.2.5 Search Menu . . . . . . . . . . . 121 6.2.6 Utilities Menu . . . . . . . . . 122 6.2.7 Options Menu . . . . . . . . . . 124 6.3 RExLRD . . . . . . . . . . . . . . . . 125 6.4 RExLRT . . . . . . . . . . . . . . . . 126 6.5 ScrList . . . . . . . . . . . . . . . 127 6.6 ScrFix . . . . . . . . . . . . . . . . 128 6.7 ScrGrab . . . . . . . . . . . . . . . 129 6.8 ScrXtrct . . . . . . . . . . . . . . . 130 6.9 ScrAdd . . . . . . . . . . . . . . . . 131 6.10 MI . . . . . . . . . . . . . . . . . 131 6.11 KbdSpeed . . . . . . . . . . . . . . 134 6.12 KbdScan . . . . . . . . . . . . . . . 134 Chapter 7 Afterword 137 iv Tables Table 1.1: Functions in AR function family . . . 3 Table 1.2: Functions in BT function family . . . 4 Table 1.3: Functions in DB function family . . . 5 Table 1.4: Functions in DT function family . . . 5 Table 1.5: Functions in ER function family . . . 6 Table 1.6: Functions in KB function family . . . 7 Table 1.7: Functions in OS function family . . . 8 Table 1.8: Financial functions . . . . . . . . . 8 Table 1.9: Math functions . . . . . . . . . . . 9 Table 1.10: Screen functions . . . . . . . . . . 9 Table 1.11: Miscellaneous functions . . . . . .10 Table 2.1: Simple Database Record Structure . .12 Table 2.2: dBase Expression Compatibility with RExL . . . . . . . . . . . . . . . .14 Table 2.3: Miscellaneous Database Functions . .21 Table 3.1: ARsize() Input Indexing . . . . . . .26 Table 3.2: BEEP() Frequencies . . . . . . . . .29 Table 3.3: Color Attribute Codes . . . . . . . .30 Table 3.4: DISPLAY() escape sequences . . . . .51 Table 3.5: Valid Format Specifiers for DTformat() . . . . . . . . . . . . .54 Table 3.6: OSdir() File Attribute Coding . . . .74 Table 3.7: OSdriveok() return values . . . . . .76 Table 3.8: OSstat() Return Indexing . . . . . .78 Table 3.9: CPU Type Return Coding . . . . . . .79 Table 3.10: Coprocessor Type Return Coding . . .79 Table 3.11: Video Adapter Type Return Coding . .79 Table 3.12: Color Attribute Codes . . . . . . .81 Table 4.1: Cursor movement keys . . . . . . . .95 Table 4.2: Hilite bar movement keys . . . . . .95 Table 4.3: Modifier keys . . . . . . . . . . . .96 Table 4.4: Editor list keys . . . . . . . . . .96 Table 4.5: Editor miscellaneous keys . . . . . .96 Table 4.6: Screen designer movement keys . . . .97 Table 4.7: Screen designer field definition keys . . . . . . . . . . . . . . . .97 Table 4.8: Screen designer line draw keys . . .97 Table 4.9: Screen designer miscellaneous keys .98 Table 4.10: Screen designer block mark keys . .98 v Table 4.11: Debugger hilite bar movement keys .99 Table 4.12: Debugger list keys . . . . . . . . .99 Table 4.13: Debugger miscellaneous keys . . . .99 Table 4.14: KB function return values . . . . 100 Table 6.1: Keystrokes in structure create . . 122 vi - Appendices. Page: 3 - Chapter 1 Function Families 1.1 Introduction This appendix gives a brief introduction to the use of and the design behind the the seven function families in RExL and the various miscellaneous functions. 1.2 Array handling There are nine functions which are used to manipulate arrays and determine information about them. The functions are as follows: Table 1.1: Functions in AR function family ARavg() ARcount() ARinit() ARmax() ARmin() ARsize() ARstd() ARsum() ARvar() The functions fall into two groups, the smaller first group has two functions in it: ARinit() and ARsize(). The ARinit() function is used to initialise the contents of an array, while the second determines, at runtime, the size of a particular dimension of an array. The other functions in this family are used for statistical analysis of the contents of the arrays. The function names are based upon similar functions found in Lotus 123, and where appropriate, the parameter lists are the same. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 4 - 1.3 Binary operations There are six functions, using the initial letters BT which are used to perform binary operations. The functions are as follows: Table 1.2: Functions in BT function family BTand() BTnot() BTor() BTshl() BTshr() BTxor() The function names are based upon the equivalent 8086 assembly language functions. All the BT functions convert their parameters to sixteen bit words, any parameters greater than 65535 being set to 65535 and any parameters less than 1 being set to 0. Typically, these functions are used in conjunction with the four memory access functions, PEEK(), PEEKW(), POKE() and POKEW() to determine information which cannot be obtained through the other system functions. For example, to determine if the NumLock state is active or not, the following line could be used: [Expr] NumLockOn:=BTand(PEEK(0,1047),32) The use of the memory access functions should be avoided if you intend your application to run on widely different machines. 1.4 Database operations The thirty-nine dBase file and index manipulation functions use the initial letters DB. The functions are as follows: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 5 - Table 1.3: Functions in DB function family DBappend() DBavg() DBbottom() DBcloseall() DBclosedbf() DBclosendx() DBcount() DBcountflds() DBdelete() DBdeleted() DBexact() DBgo() DBlocate() DBmax() DBmin() DBmkdbf() DBmkndx() DBnext() DBpack() DBprev() DBrecall() DBreccount() DBrecno() DBreindex() DBreplace() DBrnum() DBrstr$() DBseek() DBseldbf() DBselndx() DBskip() DBstd() DBstruct() DBsum() DBtop() DBusedbf() DBusendx() DBvar() DBzap() Because of the size and complexity of the database module in RExL, it is treated on its own in the next appendix. 1.5 Date and time manipulation The eighteen date and time manipulation functions use the initial letters DT. The functions are as follows: Table 1.4: Functions in DT function family DTdate() DTdate$() DTdatevalue() DTday$() DTdayno() DTformat() DThourno() DTminuteno() DTmonth$() DTmonthno() DTnow() DTsecondno() DTsetdate() DTsettime() DTtime() DTtime$() DTtimevalue() DTyearno() The date functions are again, based largely upon those in Lotus 123, with a few minor inconsistencies removed. The date module can use dates in any of the three most common date formats, European, American and Japanese. The exact format which is in use initially is determined by the settings in the CONFIG.SYS file in your machine. If there is no specific format set up, then the date format will default to American. The DTformat() command can be used to set the date and time formats and separators explicitly, overriding the defaults. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 6 - Date and time information are stored in RExL as real numbers. The integer portion of a date-time number is the Julian day number while the fractional part is the time, expressed as a fraction of 24 hours. The Julian day number of a particular date is the number of days elapsed since and including the first of January, 4713 BC (the reasons for this exact date being chosen as the origin are historically amusing). The Julian day number system is used widely in date calculations and should not be confused with the Julian Calendar. The algorithms used in RExL to calculate the Julian day number do not take account of the ten day transition from the Julian Calendar to the Gregorian Calendar which occurred from October 5th to October 15th in 1582 in Rome and at various other later dates around the rest of the world. Dates before 0 AD cannot be represented in RExL. Apart from any other considerations, there was no standard calendar then, rendering calculations somewhat useless. Date and time functions which return a date or time number will return zero if the date or time was invalid. 1.6 RExL error handling functions The five error handling functions use the initial letters ER. The functions are as follows: Table 1.5: Functions in ER function family ERclear() ERmsg$() ERnum() ERok() ERwatch() Whenever an error occurs in the runtime portion of RExL, internal variables save the text of the error and the error number. These variables can be interrogated by using the ERmsg$() function (to retrieve the text of the error) and ERnum() (to retrieve the error code). If no errors have occurred, then calls to ERmsg$() will return an empty string and calls to ERnum() will return zero. Once an error has occurred, the text and error number remain fixed until the next error occurs, an application is LOAD()'ed or the ERclear() function is used. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 7 - While the development of an application is in progress, errors should be left on, to detect errors such as divide by zero, which would otherwise not be seen. In the final distribution version, the error display can be disabled with the ERwatch() function. 1.7 Keyboard handling functions The five keyboard handling functions use the initial letters KB. The functions are as follows: Table 1.6: Functions in KB function family KBclear() KBlast() KBread() KBready() KBwait() The IBM PC uses a keyboard buffer to store keystrokes until they can be processed by a program. The normal size of the buffer is 15 keystrokes. The KBclear() function resets and empties the keyboard buffer, while the KBready() reports whether a keystroke is pending in the keyboard buffer. The other two functions in the group are used for retrieving keystrokes from the buffer, optionally waiting a variable time span for one. When a screen has been terminated, the KBlast() function can be used to determine the keystroke which caused its termination. If a keystroke returned by RExL is a character key, then the ASCII code of the character will be returned immediately. Keys that do not have ASCII codes, such as the function keys, return a more complex coding, the details of which are not necessary. The complete list of function return values is listed in appendix D, with the other keystrokes RExL can return. Note that the key is captured by the runtime module and is not returned to the application. 1.8 Operating system interface functions The thirteen operating system interface functions, which use the initial letter code OS, are as follows: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 8 - Table 1.7: Functions in OS function family OScd() OScmd() OScopy() OSdel() OSdir() OSdrive() OSexists() OSmd() OSnumber() OSrd() OSren() OSstat() OSwd$() These functions perform most of the operations commonly needed to interface with the operating system under which RExL is working. The commands are modelled after the corresponding DOS commands and require the same parameters. The OSstat() function is the only function in the group which has no direct DOS counterpart. It returns the status of the machine, including the processor, co-processor and display adapter type as well as the operating system version and information about the currently selected disk. 1.9 Financial functions The financial functions in RExL are used in the calculation of ordinary annuities. There are seven functions in this group which does not use a common initial two-letter group. Table 1.8: Financial functions CTERM() FV() PMT() PV() RATE() SLN() SYD() TERM() The functions in this group are based upon those in Lotus 123. The annuity due for the FV() and PV() functions may be calculated easily by multiplying the result of the ordinary annuity by the expression 1+rate, where rate is the periodic interest rate. 1.10 Mathematical functions As with the financial functions, the math functions do not have a common initial letter pair. The thirty-one math functions are as follows: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 9 - Table 1.9: Math functions ABS() ACOS() AND() ASIN() ATAN() CEIL() COS() DEG() DIV() EQV() EXP() FALSE() FLOOR() IMP() LOG() LOG10() MAX() MIN() MOD() NOT() OR() PI() POW() RAD() RAND() ROUND() SEED() SIN() SQRT() TAN() TRUE() XOR() All math functions requiring an angle parameter must have the angle expressed in radian measure. The RAD() and DEG() functions can be used to convert degrees to radians and vice versa. 1.11 Screen handling functions The functions in this section are used for handling screens: input, output, box drawing and painting areas as well as for loading screens. There are fifteen functions in this group: Table 1.10: Screen functions BEEP() CODE() ATTRXY() BOX() CHAR$() CHARXY$() CLS() DISPLAY() FILL() GOTOXY() INPUT() INPUT$() INVERSE() LOADSCR() PAINT() 1.12 Miscellaneous functions This final group of functions fall into no clearly defined grouping. The functions in the group are as follows: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 10 - Table 1.11: Miscellaneous functions ESCWATCH() EXACT() FIND() IIF() IF$() INIT() LEFT$() LENGTH() LOAD() LOWER$() MID$() OUTPUT() PAUSE() PEEK() PEEKW() POKE() POKEW() QUIT() REPEAT$() REPLACE$() RIGHT$() SOUNDEX$() STRING$() SUFFIX$() TRIM$() UPPER$() VALUE() VERSION() - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 11 - Chapter 2 The Database Module The database function family, the largest single grouping of functions, in RExL is fully compatible with the database and index file format used in dBase III+. Since this feature is central to RExL, it's treated on its own in this appendix which contains a complete introduction to the database facilities in RExL. 2.1 Introduction to Databases There are a few terms relating to databases which need to be understood before we can move on to the next section. Most database formats, including the dBase format used here, store their information in fixed fields. A field is simply storage area of fixed length (known as the field size) which is referenced from RExL through a field name. The field names follow the same conventions as RExL variable names, save that the dollar character `$' is not used to denote strings. The maximum width of a field name in the dBase file format is ten characters. Each field can be one of the following four different types: o Numeric: which are used to store numeric information within a fixed number of digits. The maximum field width of a numeric field is nineteen digits. If there are decimal fractions to be stored, then the field must contain space for a decimal point and the field must also have a fixed decimal fraction width, at most two less than the size of the field. o String: These fields are used to store character or string information with a maximum field width of 255 characters. Because of the limit of 80 character long strings in the current release of RExL, any - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 12 - fields which are wider then 80 characters are truncated. o Date: This field, used to store dates, has a fixed field width of 8 characters. Since there is no intrinsic date type in RExL, date fields are converted to Julian day numbers, compatible with the date system in use elsewhere in RExL. o Logical: This final field type stores yes-no type logical information. As with the date fields, there is no intrinsic logical data type in RExL, so logical information is returned as a numeric type, 0 for False and 1 for True. Traditionally, to avoid having to repeat the field types too often, the types are abbreviated to single letter: `N' for numeric, `C' for character, `D' for date and `L' for logical. The memo type, which is not commonly used in dBase applications, is not supported in RExL. Fields are collected together to form records of information. Whenever an application has a database open for use, RExL maintains a pointer, known as the record pointer, into the database pointing at the record which all operations are based upon. When a database is first opened, the record pointer is placed at the first record in the database. As a complete example of a record structure, a customer database might be designed as follows: Table 2.1: Simple Database Record Structure Field Name Type Width Decimal Places CUSTNAME `C' 30 BALANCE `N' 8 2 MAILSHOT `L' 1 NEXTBILL `D' 8 The above database structure demonstrates the use of the four different field types. When databases are created, the width of the logical and date fields is set automatically and does not have to be specified, the same is true for the decimal places specifier in character field types. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 13 - Databases are stored on disk with a file extension of ".DBF", so the above structure could be stored as "CUSTOMER.DBF". 2.2 Indexes Databases are designed for the storage and retrieval of large amounts of information. If the information is held in an random manner (like a shuffled pack of cards) then searching for a particular item of information can become prohibitively slow if there are large numbers of records in the database. The dBase file format specifies a way in which indexes may be generated through which it is possible to access information rapidly in a large database. An index file, used to store the indexing information, is a separate DOS file (using the extension ".NDX") which is used in tandem with a database file to allow rapid access to specific information. This rapid access is achieved by storing the indexing information in strict order (alphabetic or date or numeric). The function of the index file is analogous to a card index system in a library, where a box contains a sorted list of cards, one for each book in the library. When somebody looks for a book, the card index can be searched quickly (since it is sorted) and upon finding the wanted book name, the card will contain some information on how to locate the book in the library. In the same way, the index file contains sorted information together with pointers to the records in the database which match the information in the index file. The index is generated using an index expression which defines the order in which the records in the database are to be retrieved in. Initially, when the index is first created, the index expression is evaluated for all records in the database. Subsequently, whenever a record is modified, added or removed from the database, the index is updated to reflect the new contents of the database. In the example from the end of the previous section, if the developer decided that the records were to be sorted with respect to the name of the customer, then an index could be generated with the index expression CUSTNAME. Thus, when the user of the end system wanted to view a particular - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 14 - customer's record, the customer name would be entered, the name would then be searched for in the index file and if located, would then be returned to the user of the system. Since the index files used by RExL may also be used with dBase, Clipper and other packages which adhere to the ".NDX" standard, the search expression must be a dBase expression and not a RExL expression. The simplest dBase expressions are simply field names and for most purposes, this is sufficient. The RExL call to generate the customer name index from the previous paragraph would be as follows: [Expr] DBmkndx("CUSTndx","CUSTNAME") This would create an index file called "CUSTndx.NDX", sorting the records with respect to the field named "CUSTNAME". The dBase expression parser built into RExL also copes with more complicated expressions involving dBase function calls and mathematical operators. The following table gives a brief summary of the functions and operators supported: (dBase does not follow the dollar character string convention, so some of the functions in the table may seem slightly at odds with the rest of RExL.) Table 2.2: dBase Expression Compatibility with RExL Function Meaning * + - / ^ Ordinary mathematical operators >= <= > < = <> Ordinary relational operators DATE() Return system date as `D' DELETED() Return delete of current record as `L' DTOC() Convert date field to `C'. (not recommended) DTOS() Convert date field to `C'. (recommended) CTOD() Convert string to date. IIF() Equivalent to RExL IIF() RECNO() Returns the current record number RECCOUNT() Returns the number of records in the database STR() Convert number to string as STRING$() SUBSTR() Equivalent to RExL MID$() TIME() Return system time VAL() Convert string to number UPPER() Equivalent to UPPER$() SOUNDEX() Equivalent to SOUNDEX$() - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 15 - The DTOC() function is supported, although is is not recommended as an index expression function: Since it returns the year as a two digits instead of four, the function can only cope with dates in a single century. The DTOS() function returns the date as a string with the format "yyyymmdd" (y for year, m for month and d for day) and is therefore more suitable for indexing since it can deal with multiple centuries. A full description of the database functions above is beyond the scope of this introduction. Consult your dBase manual for precise details on how these functions and operators operate. 2.3 Using Database Files 2.3.1 Opening and selecting files The handling of database files is based largely around the concept of file handles, which are very similar to the notion of work-spaces used in the dBase documentation. When a data file is opened (using DBusedbf()) or an index file is opened (using DBusendx()), a file handle (a reference number greater than zero) is returned to RExL, through which the application can make references to that file or index. The advantage of the file handle system is that a theoretically arbitrary number of files and indexes may be kept open at any one time and any file or index can be referenced through its file handle. In practice however, the number of DOS files which may be opened simultaneously is limited (by DOS) to twenty, five of which cannot be reassigned, so up to fifteen database and index files may be open simultaneously. (Note that beginning with version 2.10, it is possible to access multiple database files without having to make repeated calls to DBseldbf().) speech For example, assuming that the database file and index file from the previous sections have been created and exist in the work directory. The following code can be used to open and select the two files: [Expr] DBFhandle:=DBusedbf("customer") [Expr] NDXhandle:=DBusendx("custndx") [Expr] DBseldbf(DBFhandle) [Expr] DBselndx(NDXhandle) [Expr] DBtop() - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 16 - The first line opens the customer database and returns the database file handle which RExL has assigned to it. The second line opens the index file and assigns the index file handle to NDXhandle. Next, the database file opened previously is selected or made the current work file, at this point the records are not yet sorted, since the index file has not been selected. The fourth line applies the sort order to the current database. Finally, the current record number is set to the first record in the database (it's good practice always to know what the current record is). In a real-life application, the return values of DBFhandle and NDXhandle would be checked for validity, to make sure that they had been opened correctly. 2.3.2 Reading and writing to files There are two ways in which information can be written to and read from database files. The first method uses specific functions to read and write database files and is compatible with RExL version 2.00, but is cumbersome to use. The second, newer and more efficient method is to use the @ notation introduced in version 2.10, generally known as `direct field access'. The next two subsections deal with both methods. 2.3.2.1 Using functions There are four functions which are used to read and write the currently selected database file. These are DBappend(), used to append a blank record to the end of the file, DBreplace() to write to the file and DBrnum() and DBrstr$() to read from it. a) Writing to a file The DBreplace() command requires two parameters, the first is the field name while the second parameter, which may be either string or numeric in type, specifies the value to place into the field. This function is equivalent to the dBase command REPLACE. The action of DBreplace() is slightly more complicated than it may at first seem. First of all, if the field is numeric and the number being written is too wide for the field, then the field will be set to zero. If the field is string and the string being written is too long, then it will be truncated. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 17 - It is also possible to write string values to numeric fields (although the strings must clearly contain numeric value for this to work) and to write numeric values to string fields, where \rexl\ will attempt to convert the number into a string before writing it to the field. Generally, these cross-breed replacements should be avoided where possible. For logical fields, a value of \true\ will be written to the field if the second parameter is numeric and non zero, or if it is string and equal to "Y" "y" "T" or "t". In all other cases, the value written will be false. If the field is a date field, then the second parameter will be internally converted to a date number and written to the field. The DBappend() command is used to place a new and blank record at the end of the currently selected database file. If this has been performed successfully, then the record pointer will be placed there. b) Reading from a file The two functions DBrnum() and DBrstr$() are used to extract information from the current record. DBrnum() returns the field expressed as a number, where possible, while DBrstr$() returns the field expressed as a string, which is always possible. DBrstr$() is subject to much the same caveats as DBreplace() as regards reading strings: If the field contains a string longer than 80 characters, then it will be truncated. As with DBreplace() it is possible, but not recommended, to perform cross-breed reading, from numeric fields to string variables and string fields to numeric values. When the two field reading functions are applied to date fields, the return value will be the value of the field converted to the appropriate type. Thus DBrstr$() applied to a date field will return a date string in the current date format, while a call to DBrnum() applied to the same field will return the Julian day number of the date specified in the field. The two functions can also be applied to logical fields, where DBrnum() will return 1.0 for a true value in the field and 0.0 for a false value. DBrstr$ will return "Y" for true and "N" for false. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 18 - 2.3.2.2 Direct field access a) Basics The `@' operator is used to access database fields directly and is mapped internally to a call to either DBrstr$() or DBrnum(). There are two forms of the operator, the first which corresponds to DBrstr$(), is `@$' and is used for accessing the value of a field as a string. The second, taking the place of the DBrnum() function, is the `@' symbol on its own and is used to access the value of a field as a string. To use the access operator, it is simply placed at the start of the database field name. For example, to read a field called `CUSTNO', and assign its value to a variable, the following expression could be written: [Expr] customer:=@custno Similarly, the contents of a character field may be returned to a string as follows: [Expr] name$:=@$name where `NAME' is a character field. As with the read functions DBrstr$() and DBrnum(), full cross-type read operations are permitted. This again, is most noticeable when using date fields: using the @$ operator on a date field will return a date string while using the @ operator will return the Julian Day Number of the date specified in the field. Information may also be written to the database file in exactly the same manner as it is read, so that a string may be assigned to a string field using: [Expr] @$name:="Joe Smith" and to a numeric field using: [Expr] @age:=24 b) Accessing multiple database files - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 19 - The syntax of the @ operator can be extended to allow a single token to access multiple database files simultaneously. The general format of the extended @ operator is: Numeric value: @. and String value: @$. where is a simple (ie. non-array) numeric variable whose value is the file handle for a database file, the dot is a full stop character and is the name of the field whose value is being assigned or retrieved. If, for example, two database files had been opened as follows: db_one:=dbusedbf("customer") db_two:=dbusedbf("orders") then a character field, NAME, in the customer file can be accessed using the expression: @$db_one.name while a numeric field `ORDERVAL' in the orders file can be accessed using: @db_two.orderval Note again that only simple numeric variables can appear between the @symbol and the full stop. Direct numeric values, expressions and arrays are not allowed. This extension to the format of the @ operator is a very powerful feature and extends considerably the power of the language in interrogating database files. In particular, it does away with the need to select and reselect different database files in order to use them and also reduces the likelihood of introducing bugs by having the wrong database open at a particular time. Perhaps its greatest benefit is that it allows a single screen to access multiple database files, something which was extremely cumbersome in the previous version. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 20 - 2.3.3 Moving around in a file There are six functions used to move the record pointer within the file from one record to another. With all of these functions, the movement is carried out with respect to the current index file, if one is open. The first two functions, DBtop() and DBbottom(), move the record pointer to the first and last records in the file while DBprev() and DBnext() move the previous and next records. DBskip() will skip, forward or backward through the file by a specified number of records. If an index is open, then index ordering will be used. DBgo() is used to go to an absolute record number, but unlike DBskip(), it does not obey any index. There are two functions used to find information in a file. The first of these, DBlocate() is used to locate a specific string or number in a database field (date and logical fields are not currently supported by DBlocate()). This function is based upon the LOCATE command in dBase. In a large file, locating a record may take some time, since it must read and check every record to see if the search condition is met. It is therefore usually better to generate an index and use it with the DBseek() function to find information. DBseek(), based upon the SEEK command in dBase, is used to find information in a file through its current index. Because the index file is kept in strict order, the seek can be performed very rapidly. 2.3.4 Miscellaneous functions 2.3.4.1 Statistical analysis of data There are seven functions, based largely upon similar functions in Lotus 123, which can be used to perform basic statistical analysis upon the data in a database file. The functions, covered fully in the function reference, are as follows: DBavg(), DBcount(), DBstd(), DBsum(), DBvar(), DBmax() and DBmin(). 2.3.4.2 Deletion of information Four functions are used to control the removal of information from database files. These are DBdelete(), - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 21 - DBdeleted(), DBpack() and DBrecall(). When a call to DBdelete() is made to delete a record, the record is marked for deletion and not physically removed from the file. Thus, a further call to DBrecall() can be made to unmark the record to return it to its normal status. The DBdeleted() function can be used to determine whether a record has been marked for deletion or not, while the DBpack() function will permanently remove all records from the database which have been marked for deletion. 2.3.4.3 Other functions There are nine other functions in the database packed in RExL which are used to perform maintenance on the database file itself. These functions are Table 2.3: Miscellaneous Database Functions Function Use DBcountflds() Returns the number of fields in the database DBexact() Turn database case sensitivity on and off DBmkdbf() Create a database DBmkndx() Create an index file DBreindex() Re-create an index file DBreccount() Return the number of records in a database DBrecno() Return the current record number DBstruct() Return the current database structure DBzap() Remove all records from a database By default, the database module is case sensitive, contrary to the rest of RExL. This is for reasons of compatibility with dBase which is case sensitive. However, if the database files will not be used with dBase, then case sensitivity can be safely set to off. If index files generated with case sensitivity off are used with dBase, then the results are unpredictable, since the index file format is not identical. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 22 - - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 23 - Chapter 3 Function Reference -------------------------------------------------------------------- ABS(number) ABS() returns the absolute value (or modulus) of the parameter. Returns: The parameter expressed as a positive number See also: FLOOR CEIL ROUND Example: val:=ABS(-10) Returns 10 to the variable val Example: val:=ABS(10) Returns 10 to the variable val -------------------------------------------------------------------- ACOS(number) Returns the arc-cosine of the parameter. The return value is expressed in radians. To convert radians to degrees, use the DEG() function. The value returned will be in the range of zero radians to pi radians. Returns: A number See also: ASIN ATAN DEG Example: val:=ACOS(0.5) Returns 1.04719775 radians to val. -------------------------------------------------------------------- AND(log1,log2) AND() performs a logical AND operation upon the two logical parameters passed to the function and returns the result of the test. The function returns True if both logical parameters are True otherwise it returns False. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 24 - Returns: A number See also: NOT EQV XOR OR IMP Example: val:=AND(TRUE(),FALSE()) Returns False to to the variable val. --------------------------------------------------------------------- ARavg(num[#],start,end) ARavg() returns the average of the elements of the one dimensional numeric array parameter between the specified start and end elements. Note that unlike ARcount(), ARavg() takes account of zero values in its calculation. In order to determine if the value for the average is meaningful, you should also calculate the standard deviation of the data, using the ARstd() function. Returns: A number See also: ARcount ARsum DBavg Example: avg:=ARavg(score[#],0,9) Returns, to the variable avg, the average of score[#] over the first to tenth elements inclusive. --------------------------------------------------------------------- ARcount(numstr[#],start,end) ARcount() counts the elements of the one dimensional array parameter which are nonzero, if the array is numeric, or nonempty, if the array is of type string. The count is performed between the specified start and end elements inclusive. Returns: The number of nonempty elements See also: ARavg ARsum DBcount Example: n:=ARcount(name$[#],0,2) Returns, to the variable n, the number of nonempty strings in the string array, name$[#], between the first and third elements. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 25 - --------------------------------------------------------------------- ARinit(numstr[#]) ARinit() clears all elements of an array, setting numeric array values to 0 and string array values to "". The function accepts arrays of any dimension. Returns: True Example: ARinit(name$[#]) Resets all elements of name$[#] to "". --------------------------------------------------------------------- ARmax(num[#],start,end) ARmax() returns the maximum value of the numeric array parameter between the specified start and end elements. Returns: A number See also: ARcount ARmin Example: mmax:=ARmax(score[#],0,9) Returns, to the variable mmax, the maximum value of the numeric array score[#] over the first to tenth elements inclusive. --------------------------------------------------------------------- ARmin(num[#],start,end) ARmin() returns the minimum value of the numeric array parameter between the specified start and end elements. Returns: A number See also: ARcount ARmax Example: mmin:=ARmin(score[#],0,9) Returns, to the variable mmin, the minimum value of the numeric array score[#] over the first to tenth elements inclusive. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 26 - ARsize(numstr[#],dimension) ARsize() returns the size of the specified array, in the specified dimension. The dimensions are defined as follows: Table 3.1: ARsize() Input Indexing Dimension Meaning 1 x dimension (first dimension) 2 y dimension (second dimension) 3 z dimension (third dimension) Returns: The size of the specified dimension Example: ARsize(name$[#],1) Returns the size of the first, or x, dimension of the string array name$[#]. --------------------------------------------------------------------- ARstd(num[#],start,end) ARstd() returns the population standard deviation of the values in num[#] between the specified start and end elements, inclusive. This function uses the n method (biased) to determine the standard deviation of the population data. The standard deviation can be thought of as a measure of the validity of the average of the set of data. If the deviation is small, then the average is good, if the deviation is large, then the value for the average could be meaningless. Returns: A number See also: ARvar ARavg ARcount Example: std:=ARstd(score[#],0,9) Returns, to the variable std, the standard deviation of the value of score[#] over the first to tenth elements inclusive. --------------------------------------------------------------------- ARsum(num[#],start,end) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 27 - ARsum() returns the summation of the elements in the num[#] array between the specified start and end elements, inclusive. Returns: A number See also: ARvar ARstd ARavg ARcount Example: sum:=ARsum(score[#],0,9) Returns, to the variable sum, the sum of the first ten elements of the array score[#] --------------------------------------------------------------------- ARvar(num[#],start,end) ARvar() returns the population variance of the values in num[#] between the specified start and end elements, inclusive. This function uses the n method (biased) to determine the standard deviation of the population data. ARvar() is also equal to the sqaure of the population standard deviation of the array, as returned by the ARstd() function. Returns: A number See also: ARstd ARavg ARcount Example: var:=ARvar(score[#],0,9) Returns, to the variable var, the population variance of the value of the array score[#] over the first to tenth elements inclusive. --------------------------------------------------------------------- ASIN(number) Returns the inverse sine of the parameter. The return value is expressed in radians and can range in value from from - pi/2 to pi/2. Returns: A number See also: ACOS, ATAN - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 28 - Example: val:=ASIN(0.5) Returns 0.52335987756 radians to val --------------------------------------------------------------------- ATAN(number) Returns the inverse tangent of the parameter. The return value is expressed in radians and can range from -pi/2 to pi/2. Returns: A number See also: ASIN, ACOS Example: val:=ATAN(0.5) Returns 0.463647609 radians to val --------------------------------------------------------------------- ATTRXY(xpos, ypos) This function returns the attribute (or color value) of the character displayed at position (xpos,ypos). The entry for BOX() has a table of color values which can be used to work out the actual colors used on the screen. Returns: A number between 0 and 255 See also: PAINT CHARXY Example: col:=ATTRXY(10,10) Returns the attribute value of the character at screen co-ordinates (10,10). --------------------------------------------------------------------- BEEP(frequency,time) Sounds the computer's internal speaker. The frequency is measured in Hertz and time is measured in millseconds (thousandths of a second). If the time parameter is set to 0 then the sound will be generated until another call to BEEP() is made. If time set to -1, the beeper is switched off. The following is a table of natural frequencies and their corresponding musical notes. time can be as long as - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 29 - 65534 milliseconds, or about 65 seconds. A frequence of 440Hz is A below Middle C. Table 3.2: BEEP() Frequencies Note Frequency Note Frequency C 130.810 C 523.250 D 146.830 D 587.330 E 164.810 E 659.260 F 174.610 F 698.460 G 196.000 G 783.990 A 220.000 A 880.000 B 246.940 B 987.770 C 261.630 C 1046.500 D 293.660 D 1174.700 E 329.630 E 1318.500 F 349.230 F 1396.900 G 392.000 G 1568.000 A 440.000 A 1760.000 B 493.880 B 1975.500 Returns: True Example: BEEP(523.250,1000) Sounds the beeper at middle C for one second. --------------------------------------------------------------------- BOX(x, y, w, h, color, type) Draws a character box on screen. The parameters specify the coordinates of the top left corner and the desired width and height of the box. The sixth parameter specifies the type of box: type is zero for a single line box and one for a double line box. The color parameter specifies the attribute with which the box is to be drawn. The interior of the box will be filled with spaces. Attributes are calculated by adding the color number of the background (paper color) to that of the foreground (ink) color. The following are the color numbers: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 30 - Table 3.3: Color Attribute Codes Color Foreground Background Black 0 0 Blue 1 16 Green 2 32 Cyan 3 48 Red 4 64 Magenta 5 80 Brown 6 96 Light Gray 7 112 Dark Gray 8 (128) Light Blue 9 (144) Light Green 10 (160) Light Cyan 11 (176) Light Red 12 (192) Light Mgnta 13 (208) Yellow 14 (224) White 15 (240) Blink 128 - If the last screen displayed during execution had the flash-intensity bit set to `intensity', then a further eight background colors, indicated above by the bracketed numbers, are available, at the expense of blinking. Note that the background colors are derived from the foreground colors by multiplying by sixteen. Returns: True See also: PAINT INVERSE Example: BOX(0,0,79,24,31,1) Draws a double lined white on blue box around the screen. --------------------------------------------------------------------- BTand(bit1,bit2) BTand() performs a bitwise and operation upon the two parameters. As with all the bit manipulation functions, the values are internally converted to sixteen bit words, so numbers greated than 65535 are treated as 65535 and numbers less than 1 are treated as zero. Returns: A number between 0 and 65535 - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 31 - See also: BTnot BTor BTshl BTshr BTxor Example: bt:=BTand(6,4) Returns a value of 4 to the variable bt --------------------------------------------------------------------- BTnot(bits) BTnot() performs a bitwise 16 bit NOT operation on its numeric parameter. Returns: A number between 0 and 65535 See also: BTand BTor BTshl BTshr BTxor Example: bt:=BTnot(65535) Returns a value of 1 to the variable bt --------------------------------------------------------------------- BTor(bit1,bit2) BTor() performs a bitwise or operation upon two sixteen-bit parameters. Returns: A number between 0 and 65535 See also: BTnot BTand BTshl BTshr BTxor Example: bt:=BTor(6,4) Returns a value of 6 to the variable bt --------------------------------------------------------------------- BTshl(bit1,bit2) BTshl() performs a bitwise left shift of the first parameter by the number of bits specified by the second parameter. The return value of BTshl() is equivalent to the product of the first parameter and two raised to the power of the second parameter. Returns: A number between 0 and 65535 See also: BTnot BTor BTand BTshr BTxor - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 32 - Example: bt:=BTshl(2,2) Returns a value of 8 to the variable bt --------------------------------------------------------------------- BTshr(bit1,bit2) BTshr() performs a bitwise right shift of the first paremeter by the number of bits specified by the second parameter. The return value of BTshr() is equivalent to the quotient of the first parameter divided by two raised to the power of the second parameter. Returns: A number between 0 and 65535 See also: BTnot BTor BTshl BTand BTxor Example: bt:=BTshr(8,2) Returns a value of 2 to the variable bt --------------------------------------------------------------------- BTxor(bit1,bit2) BTxor() performs a bitwise exclusive or operation upon the two sixteen bit parameters. Returns: A number between 0 and 65535 See also: BTnot BTor BTshl BTshr BTand Example: bt:=BTxor(32767,16) Returns a value of 32751 to the variable bt --------------------------------------------------------------------- CEIL(number) CEIL() returns the smallest number greater than the parameter. Returns: A number See also: FLOOR - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 33 - Example: a:=CEIL(5.5) Returns the value 6.0 to the variable a. --------------------------------------------------------------------- CHAR$(asciicode) Returns the ASCII character whose ASCII code is asciicode. Returns: A one-character string See also: CODE Example: t$:=CODE(65) Returns the letter "A", whose ASCII code is 65, to the variable t$. --------------------------------------------------------------------- CHARXY$(xpos,ypos) CHARXY$() returns the ASCII code of the character displayed at the screen coordinates (xpos,ypos). The top left hand corner of the screen is position (0,0) and the bottom right corner is position (79,24). Returns: A number See also: CHAR$ ATTRXY Example: asciival:=CHARXY(0,0) Assigns the ascii value of the character displayed at position (0,0), the top left corner. --------------------------------------------------------------------- CLS() CLS() clears the screen. The screen will be set to white on black and the cursor position will be set to the top left hand corner. Returns: True Example: CLS() - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 34 - Clears the screen. --------------------------------------------------------------------- CODE(character$) Returns the ASCII code of the first letter of the string parameter. See appendix F for a table of ASCII codes. Returns: A number See also: CHAR$ Example: asciival:=CODE("A") Returns 65 to asciival, the ASCII code for the letter "A". --------------------------------------------------------------------- COS(angle) Calculates the cosine of the angle, where the angle is measured in radians. The return value will be in the range of -1 to 1. The ACOS() function is used to convert the cosine of an angle to the angle. Returns: A number Example: val:=COS(0.5) Returns 0.8775825619 to the variable val. --------------------------------------------------------------------- CTERM(rate, end, start) CTERM() returns the number of compound periods it would take for the start value, at the specified interest rate to grow to the end value. The rate should be the specified as a decimal fraction rather than a percentage. Returns: A number See also: FV PMT PV RATE TERM Example: yrs:=CTERM(0.1,100,10) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 35 - Returns 24.1588 interest periods to the variable yrs, indicating that it would take 24 years and two months for an amount of $10 to grow to $100 at a rate of 10% per annum. --------------------------------------------------------------------- DBappend(none) Adds a new blank record to the end of the currently selected database file. Returns: True if successful, False otherwise See also: DBreplace Example: DBappend() --------------------------------------------------------------------- DBavg(field$,start,end) DBavg() returns the average of the fields of the currently open database, between the specified start and end fields. (Note that unlike the function DBcount(), DBavg() takes account of zero values). Note that the specified field must be numeric and not string. Returns: A number See also: DBcount DBsum DBavg Example: avg:=DBavg("AMOUNT",1,10) avg is assigned the average of the field "AMOUNT" in the current database between the first and tenth records inclusive. --------------------------------------------------------------------- DBbottom() Places the record pointer at the last record in the currently selected database file in index order. Returns: True if successful, False otherwise See also: DBtop - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 36 - Example: DBbottom() This will go to the last record in the current database using the current index. --------------------------------------------------------------------- DBcloseall() Closes all open database and index files. It is better practice to close each file separately using DBclosedbf(). Returns: True if successful, False otherwise. Example: DBcloseall() --------------------------------------------------------------------- DBclosedbf() Closes the currently open database file. Any active index files will also be closed. It will fail if there are no files open. Returns: True if successful, False otherwise See also: DBcloseall DBclosendx Example: DBclosedbf() --------------------------------------------------------------------- DBclosendx(num) Closes the index file addressed by the index file handle num. Returns: True if successful, False otherwise See also: DBusendx Example: DBclosendx(names) Closes the index file linked to the index handle names. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 37 - DBcount(field$,start,end) DBcount() counts the fields of the currently active database, between the specified start and end records elements, which are nonzero, if the field is numeric, or nonempty, if the field is of type string. Returns: The number of nonempty fields See also: DBavg DBsum DBcount Example: n:=DBcount("DONATION",1,DBreccount()) n is assigned the number of records in the currently open database which have nonempty DONATION fields. --------------------------------------------------------------------- DBcountflds() DBcountflds() returns the number of fields in a record in the currently selected database file. This function is most useful for determining if a call to DBstruct() would result in an error from too many fields in the database. Returns: A number Example: ARsize(name$[#],1) and keys during execution of an application. In the default condition of on (a value for number of 1), an `error' is flagged, prompting the user to see if he wants to terminate the application. If the parameter is zero, then RExL will not scan for the key. During debugging of an application, it's best to leave watching on. Returns: True Example: ESCWATCH(TRUE()) Monitor the and keys for presses during execution of an application. --------------------------------------------------------------------- EXACT(num) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 61 - EXACT() defines whether the string comparisons and tests are carried out respecting the case of the letters being compared (when num = 1) or irrespective of case (num = 0). In its default condition, RExL is not sensitive to the case of letters. Returns: True Example: EXACT(TRUE()) Turns on case sensitivity. --------------------------------------------------------------------- EXP(number) Returns the exponential e (2.71828) to the power of the single numeric parameter. Returns: A number See also: LOG Example: x:=EXP(1) Returns 2.718281828 to the variable x. --------------------------------------------------------------------- FALSE() Returns the value zero. It is used to fail a rule or part of a rule. Returns: False See also: TRUE NOT Example: value:=NOT(FALSE()) Returns 1 to the variable value. --------------------------------------------------------------------- FILL(x, y, w, h, char$) Fills an area of the screen with the specified character. The first four parameters specify the horizontal and - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 62 - vertical coordinates of the top left hand corner (x,y) of the bounding box and its width w and height h respectively. The fifth parameter specifies the ASCII character to fill the area with. The attributes of the box remain unchanged by this command. Returns: True See also: PAINT BOX Example: FILL(0,0,79,24,"A") Fills the screen with the letter A. --------------------------------------------------------------------- FIND(substr$, superstr$) Locates the first occurrence of substr$ within superstr$. If the substring is not in superstr$, then the function will return False. The value returned is zero based, meaning that if the substring starts at the first character, then the return value will be zero. This behaviour is comatible with C language, where all string positions are zero-based. Returns: String index if located, -1 otherwise Example: pos:=FIND("lo","Hello") Returns a value of 3 to the variable pos. --------------------------------------------------------------------- FLOOR(number) FLOOR() returns the largest number less than the numeric parameter. Returns: A number See also: CEIL Example: a:=FLOOR(5.5) Returns the value 5.0 to the variable a. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 63 - FV(pmt,rate,periods) Calculates the future value of equal payments of amount pmt of a simple ordinary annuity, earning at a periodic interest rate for the number of payment periods. The interest rate should be expressed as a decimal rather than a percentage. Returns: A number Example: x:=FV(1000,0.1,10) Returns $15937.43 to the variable x. --------------------------------------------------------------------- GOTOXY(xpos, ypos) Positions the text cursor on the text screen at the specified horizontal co-ordinate xpos and vertical co- ordinate ypos, taking (0,0) to be the top right hand corner of the screen. If the coordinates are out of range, the GOTOXY() will return False. Returns: True if successful, False otherwise See also: DISPLAY Example: GOTOXY(0,0) Sets the cursor to the top left hand corner of the screen. -------------------------------------------------------------------- HELP(log) HELP() is used to turn the online help feature on and off. When `log' is true, will display the currently active help screen when pressed from within a dialog screen. When `log' is false, keystrokes will be returned to the application. Returns: True Example: HELP(1) Turns on monitoring. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 64 - IIF(boolexp, anstrue, ansfalse) Returns one of the parameters anstrue or ansfalse depending on the value of the boolean expression passed as the first parameter, boolexp. If the boolexp is true (non-zero), then anstrue is returned, otherwise ansfalse is returned. This behaviour is compatible with the Clipper IF command. Returns: Either of the second two parameters See also: IIF$ Example: a:=IIF(x,1,2) If the value of x is non-zero, then A is assigned the value 1, otherwise the value 2. --------------------------------------------------------------------- IIF$(boolexp, anstrue$, ansfalse$) IIF$() will return anstrue$ if the boolean expression boolexp is true, or ansfalse$, if boolexp is false. This behaviour is compatible with the Clipper IF command. Returns: A string See also: IIF Example: a$:=IIF$(x,"Y","N") If the value of x is non-zero, then A$ is assigned the value "Y", otherwise the value "N". --------------------------------------------------------------------- IMP(log1,log2) IMP() performs a logical implication test upon the two logical parameters passed to the function. The function returns True if the first parameter is True and the second is False, otherwise it returns False. Returns: A number See also: NOT AND XOR OR EQV Example: val:=IMP(TRUE(),FALSE()) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 65 - Returns True to to the variable val. --------------------------------------------------------------------- INIT() Clears out all variables currently defined, setting numeric variables to 0.0 and setting strings to zero length. Returns: True Example: INIT() --------------------------------------------------------------------- INPUT(x,y,w,p,value) Generates an input field of width w and decimal precision p at the horizontal and vertical coordinates (x,y). The initial value of the input is value The attribute at (x,y) will be extended to the width of the input. If value is too large to display in the assigned area, then overwriting of the surrounding screen may occur. The input area will not be affected by this. The maximum width of input is 19 digits and the maximum precision is 17 digits. Returns: The number input See also: INPUT$ Example: n:=INPUT(5,10,10,2,1.2) Accepts the input of a number a column 5, row 10, with a width of 10 places and including room for 2 decimal places, with an initial value of 1.2. The number will be stored in the variable n. --------------------------------------------------------------------- INPUT$(x,y,width,value$) Generates a string input field of width w at the horizontal and vertical coordinates (x,y) specified, setting the initial value of the input to value$. Returns: The string input See also: INPUT - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 66 - Example: t$:=INPUT$(5,10,10,"Test") Accepts input of a string at column 5 row 10, with a width of 10 places and an initial value of "Test". --------------------------------------------------------------------- INVERSE(x1, y1, x2, y2) Inverts the attributes of an area of screen. The first two parameters define the top left corner. The last two define the bottom right corner. If you invert the same area twice, you will be left with the same area. This can be used to flash an area. The inverse attribute is generated by xor'ing the current attribute with 7Fh. Returns: True Example: INVERSE(0,0,79,24) Inverts the attributes for the whole screen. --------------------------------------------------------------------- KBclear() Clears all keystrokes from the keyboard buffer. Returns: True Example: KBclear() --------------------------------------------------------------------- KBlast() KBlast() returns the last keystroke typed by the user. The function can be used to determine the keystroke which caused the termination of a dialog screen (for example, if the user pressed , , and so on). If no keys have been pressed since the application started running, or since the last call of KBclear(), then KBlast() returns False. See appendix D for a list of return values. Returns: Key code for last key pressed, False if none present See also: KBwait - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 67 - Example: key:=KBlast() --------------------------------------------------------------------- KBread() Waits until a key is pressed and then returns the code associated with it. If the key is a character key, the ASCII code will be returned, otherwise, the internal code for the key will be returned. See appendix D for a list of return values. Returns: Key code for key pressed See also: KBwait Example: key:=KBread() Waits for a key to be pressed and returns keyboard code in the variable key. --------------------------------------------------------------------- KBready() KBready() returns the value of a keystroke, if one is ready and waiting in the keyboard buffer. If there is no pending keystroke, the function returns immediately with a value of zero, otherwise it returns the keystroke code, as listed in appendix D. Returns: Key code for key waiting, zero otherwise Example: KeyWaiting:=KBready() --------------------------------------------------------------------- KBwait(time) Waits for the specified number of seconds time for a key to be pressed. The function then returns the coded value for that key or zero if no key was pressed. See appendix D for a list of keystroke codes. Returns: Key code if key pressed, False if no key pressed Example: key:=KBwait() - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 68 - --------------------------------------------------------------------- LEFT$(str$,num) Returns a string comprising the leftmost num number of characters from the string str$. If the number specified is greater than the length of the string then the entire string will be copied. Returns: A string See also: RIGHT$ MID$ Example: a$:=LEFT$("Hello",2) This sets a$ to be "He" --------------------------------------------------------------------- LENGTH(string$) Returns the length of a character string string$. If the string is empty, then the value 0 will be returned Returns: A number Example: lgth:=LENGTH("System") This will set lgth to be 6. --------------------------------------------------------------------- LOAD(filename$) Loads in and passes control to another listing. LOAD() is not nested so that when the second listing finishes, control is not passed back to the original listing. LOAD() may return False if the second listing is too big, or does not exist. If the specified application image does not exist in the current directory, then the list of paths specified in the RExL environment variable will be searched in sequence. If the application is located, then all databases are closed, the internal error variables are reset and execution begins at the master rule of the new application. The stack of screens stored by PUSHSCR() and POPSCR() are not cleared, so screenfuls of information may be passed between two applications. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 69 - Applications compiled with the postfix compiler must exercise caution when using the LOAD function, which is implemented slightly differently in the executable file library. The section on the postfix compiler RExLPC gives more details on this. Returns: False if listing could not load Example: LOAD("2ndpart") Loads and passes control to the application image with the DOS file name "2ndpart.rxl". --------------------------------------------------------------------- LOADSCR(filename$, x, y) Loads in a small area of the screen from the specified filename. The x and y coordinates specify the top left corner of where the screen is to appear. Any fields that are contained with the screen will then be activated. If you wish to load the screen to its original x or y position then set the relevant parameter to -1. Any parts of the screen being loaded which do not fit will be ignored and not displayed. Returns: True if loaded ok, False otherwise See also: SAVESCR Example: LOADSCR(n$,10,-1) Get the screen named n$ and place it at column 10 with the row being the same as that from where it was saved. --------------------------------------------------------------------- LOG(number) Returns the natural logarithm (log to base e (2.71828)) of the parameter. Returns: A number See also: EXP Example: nl:=LOG(0.51) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 70 - This will set nl to be -0.673344553 --------------------------------------------------------------------- LOG10(number) Returns the base-10 logarithm of the parameter. Returns: A number Example: lg:=LOG10(0.51) This will set lg to be -0.292429824 --------------------------------------------------------------------- LOWER$(string$) LOWER$() returns the parameter string translated in lower case. The European ASCII characters are left as they are and are not translated to lower case. Returns: A string See also: UPPER$ Example: a$:=LOWER$("hELlO") Returns the string "hello" to a$. --------------------------------------------------------------------- MAX(num1, num2) Returns the larger of the two numeric parameters. Returns: A number See also: MIN Example: bigger:=MAX(5,4) This will set bigger to be 5 --------------------------------------------------------------------- MID$(source$, start, count) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 71 - Returns count characters, starting at position start from the string source$. If start is past the end of the string or count is less than or equal to zero, then an empty string is returned. Returns: A string See also: LEFT$ RIGHT$ Example: a$:=MID$("ABCDEF",2,2) This will set a$ to be "CD" --------------------------------------------------------------------- MIN(number1, number2) Returns the smaller of the two parameters. Returns: A number See also: MAX Example: small:=MIN(5,4) This will set small to be 4. --------------------------------------------------------------------- MOD(number1, number2) Returns the remainder of the division of number2 by number1. Mathematically, this operation is known as modulo division. Returns: A number See also: DIV Example: remainder:=MOD(10,3) This will set remainder to be 1. --------------------------------------------------------------------- NOT(boolean) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 72 - Returns the logical inverse of the parameter: If the parameter evaluates to false, the function will return True, otherwise it will return False. Returns: True or False See also: BTnot Example: NOT(TRUE()) Returns False. --------------------------------------------------------------------- OR(log1,log2) OR() performs a logical OR upon the two logical parameters passed to the function. The function returns True if either of the two logical parameters are True otherwise it returns False. Returns: A number See also: NOT EQV XOR AND IMP Example: val:=OR(TRUE(),FALSE()) Returns False to to the variable val. --------------------------------------------------------------------- OScd(path$) Changes directory to the path specified by path$. If the directory cannot be accessed then the function returns false, otherwise true. To change the current drive use OSdrive(). Returns: True if successful, False otherwise See also: OSdrive OSrd OSmd Example: OScd("\rexl\demo") Sets the directory to be \rexl\demo on the default drive. --------------------------------------------------------------------- OScmd(command$) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 73 - Allows external programs to be loaded and run. The parameter contains the program name and any parameters which must be passed to it. OScmd() returns True if the command executed and False if it failed to do so. Note that RExL must be able to access the command interpreter to run the command. The command interpreter is usually the file "COMMAND.COM", located in the root directory of the boot drive and is referenced by the COMSPEC environment variable. Returns: True if successful, False otherwise Example: OScmd("edit c:\autoexec.bat") Executes the program or batch file named "edit" and passes the string "c:\autoexec.bat" to it as a parameter. --------------------------------------------------------------------- OScopy(source$,dest$) Copys a file from the source$ to dest$. The destination parameter, unlike its MS-DOS equivalent, must contain the name of the file to which the file will be copied. The wild card characters ? and are not allowed in either parameter. If you need to perform a wild card copy, use the OScmd() function. Returns: True if successful, False otherwise See also: OScmd Example: OScopy("TEST.DOC","\T.TXT") Copies a file "TEST.DOC" in the current directory to the root directory, naming it "T.TXT". --------------------------------------------------------------------- OSdel(filename$) Deletes the specified file from the disk. If the file does not exist, or could not be deleted then this function will return false, otherwise true. filename$ may specify a full path including drive specifier. Returns: True if successful, False otherwise - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 74 - See also: OSexists Example: OSdel("TEST.RXL") Deletes the file called "TEST.RXL" in the current directory. --------------------------------------------------------------------- OSdir(mask$, attr, n$[#], sz[#], dt[#], at[#]) OSdir() is used to obtain DOS diretory listings from disk. The first parameter specifies the DOS file mask to use for the search and may include drive and path designators as well as wild card characters. The second parameter specifies the file attribute to search for. To search for more than one file type, add the search attributes together. The following table gives the valid search attributes: Table 3.6: OSdir() File Attribute Coding Attribute Code Meaning 1 Read only attribute 2 Hidden file 4 System file 8 Volume label 16 Directory 32 Archive 64 All files If you are unsure about the meanings of any of these attributes, consult your DOS manual. The results of the search are placed in the arrays: file names in n$[#], file sizes in sz[#], file dates and times in dt[#] and file attributes in at[#]. The return value from OSdir() is the number of files returned in the array. If any of the arrays are not large enough to hold the information required, then an array bounds error eill be generated and the function will return without looking for any more files. Returns: The number of files found or zero if no files located See also: OSexists Example: OSdir("*.rxl",64,n$[#],sz[#],dt[#],at[#]) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 75 - Returns lists of all of the RExL application image files in the current directory. The files may have any attribute. Example: OSdir("T?.RXL",64,n$[#],sz[#],dt[#],at[#]) Returns a list of all of the RExL files in the current directory, whose names have two letters, the first of which is "T" --------------------------------------------------------------------- OSdrive(drive$) Selects a new current disk drive. The parameter should be a two character string, the first character of which is a drive letter and the second a colon. The return value of the function is the ASCII character code of the drive selected. If the drive was not successfully selected, then the value returned will be the ASCII code of the current drive letter. Passing an empty string in place of drive$ will return the current drive with no change made. Returns: True if successful, False otherwise See also: OScd OSwd$ Example: OSdrive("C:") Sets the current or default drive to be C: --------------------------------------------------------------------- OSdriveok(dstr$) OSdriveok() tests a disk drive, normally a floppy drive, to determine if it is ready to be written to or read from. `dstr$' specifies the DOS disk drive to test. The function can return one of a range of values, giving explicit information about why the disk drive is not ready. The following table gives the exact return values and their meanings: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 76 - Table 3.7: OSdriveok() return values -1 Wrong parameters 0 Drive loaded and ready to read or write 1 Drive door open or diskette inserted upside down 2 Diskette is unformatted 3 Write protected 4 Undetermined Note that unlike almost all other rexl functions, this function returns zero if the test performed was successful. Returns: A number See also: OSdrive Example: !OSdriveok("A:") Returns true if drive A: is not write protected and is ready for access. --------------------------------------------------------------------- OSexists(filename$) Checks to see if the specified file exists. filename$ can contain a full pathname and drive specification. Returns: True if file exists, False otherwise See also: OSdir Example: OSexists("c:\command.com") Tests to see if the file "COMMAND.COM" exists in the root diretory of the C: drive. --------------------------------------------------------------------- OSmd(dirname$) OSmd() will make a DOS directory. The single string parameter specifies the directory name to make and may contain a drive letter. As in the DOS md command, you may only make one directory level at a time. Returns: True if successful, False otherwise - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 77 - See also: OSrd Example: OSmd("\test") Makes a directory called "test" in the root directory of the current drive. --------------------------------------------------------------------- OSnumber() This function returns a value indicating which operating system RExL is currently running under. Currently, the only value returned is 1, for MS-DOS, but future versions of RExL running under different operating systems will return different values. Use OSstat() to determine the operating system version number. Returns: 1 for MS-DOS See also: OSstat Example: sys:=OSnumber() Sets sys equal to 1 if the operating system is MS-DOS. --------------------------------------------------------------------- OSrd(dirname$) OSrd() will remove a DOS directory. The single string parameter specifies the directory name to be deleted. The string can contain a drive letter and a full path specification. Returns: True if successful, False otherwise See also: OSmd Example: OSrd("c:\test") Removes a directory called "\test" from the root directory of the C: drive. --------------------------------------------------------------------- OSren(source$,dest$) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 78 - This function will rename the file named source$ to dest$. The parameters may specify a directory paths, so that files may be moved from one directory to another using OSren(). Note that, as in DOS, the destination file must not exist, or the function will fail. Returns: True if successful, otherwise False. See also: OScopy OSdel Example: OSren("TEST.TXT","TEST.BAK") Changes the name of the file "TEST.TXT" to "TEST.BAK". --------------------------------------------------------------------- OSstat(ar[#]) OSstat() returns seven items of information, about the current status of the machine, to the specified one dimensional numeric array. The information returned is as follows: Table 3.8: OSstat() Return Indexing Array Index Meaning 0 Disk space free on current drive 1 Total disk space on current drive 2 Total number of disk drives available 3 Largest block of free memory available 4 Current DOS version 5 CPU type 6 Coprocessor type 7 Video adapter type If the current disk is large, then DOS may take a few seconds to determine the its free space and total size. If the current disk is not valid, for example, a floppy drive with an open door, then a critical error will be generated and a value of zero will be returned for the size of the disk. The DOS version is returned as a real number of the form x.yy where x is the major version number and yy is the minor version number. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 79 - Table 3.9: CPU Type Return Coding Return Value Processor Type 0 Intel 8088 1 Intel 8086 2 NEC V20 3 NEC V30 4 Intel 80188 5 Intel 80186 6 Intel 80286 7 Intel 80386 8 Intel 80486 Table 3.10: Coprocessor Type Return Coding Return Value Coprocessor Type 0 None installed 1 Intel 8087 2 Intel 80287 3 Intel 80387 Table 3.11: Video Adapter Type Return Coding Return Value Video Adapter type 0 Monochrome 1 CGA adapter 2 EGA adapter 3 VGA adapter Returns: True if array large enough, False otherwise See also: OSdir OSnumber Example: OSstat(Stat[#]) Returns the above information to the stat[#] array. --------------------------------------------------------------------- OSwd$() Returns a string containing the current directory path. The string will also contain the current drive letter. Returns: A string See also: OSdir OScd - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 80 - Example: d$:=OSwd$() --------------------------------------------------------------------- OUTPUT(device$) Sets the default output device for print requests. Since the string is passed directly to DOS it can be a file on disk. By default the printer output device is the device driver "PRN". If you are using a parallel/centronics type printer then you may wish to use the command: [Expr] OUTPUT("LPT1") or if you are using a serially connected printer: [Expr] OUTPUT("COM1") These two functions explicitly state which type of printer you will be using. Using the generic PRN device you should have less problems when people connect different types of printers. Making it a variable would allow you to modify to set up a option for the user to select the output device. Returns: True Example: OUTPUT("DUMP.DOC") Assigns all printer output to the file "DUMP.DOC" --------------------------------------------------------------------- PAINT(x, y, w, h, att, mask) PAINT() changes the attributes of a box whose top left hand corner is (x,y) and whose width and height are w and h respectively. When changing the attribute byte on the screen, PAINT() performs a boolean AND on the byte with the mask and then adds the attribute which has been ANDed with the inverted mask. The result of this complicated manoeuvering is that any color can be filtered in or out from either background or foreground. If you wish to change foreground only set the mask to be 240, to change the background only, set it to 15. If you want to change everything in the area set the mask to be 0. The following table lists the colors which can be used on color monitors: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 81 - Table 3.12: Color Attribute Codes Color Foreground Background Black 0 0 Blue 1 16 Green 2 32 Cyan 3 48 Red 4 64 Magenta 5 80 Brown 6 96 Light Gray 7 112 Dark Gray 8 (128) Light Blue 9 (144) Light Green 10 (160) Light Cyan 11 (176) Light Red 12 (192) Light Mgnta 13 (208) Yellow 14 (224) White 15 (240) Blink 128 - If the last screen displayed during execution had the flash-intensity bit set to `intensity', then a further eight background colors, indicated above by the bracketed numbers, are available, at the expense of blinking. Note that the background colors are derived from the foreground colors by multiplying by sixteen. Some early CGA systems do not support the flash-intensity toggle, so distribution packages which may be used on these adapters should not use this feature. Returns: True See also: INVERSE FILL Example: PAINT(0,0,79,24,31,0) This will set the entire screen to bright white on a blue background. Example: PAINT(0,0,79,24,15,240) This changes all foreground colors to white, leaving background colors unchanged. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 82 - PAUSE(time) Halts execution of the application for a specified time before execution continues. The time is measured in milliseconds (thousandths of a second). Returns: True Example: PAUSE(1500) Halts the system for a second and a half. --------------------------------------------------------------------- PEEK(seg,ofs) PEEK() returns the value of the byte at the memory location referenced by a segment value of seg and an offset value of ofs. Consult a DOS reference if you are not familiar with the concept of offsets and segmentation. Returns: A number from 0 to 255 See also: PEEKW POKE POKEW Example: DisplayType:=PEEK(0,1097) This expression returns, to the variable DisplayType, the type of display attached to your computer. The value will be 3 for a color display and 7 for a monochrome display. --------------------------------------------------------------------- PEEKW(seg,ofs) PEEKW() returns the value of the sixteen bit word at the memory location referenced by a segment value of seg and an offset value of ofs. Consult a DOS reference if you are not familiar with the concept of offsets and segmentation. Returns: A number from 0 to 65535 See also: PEEK POKE POKEW Example: CharAttr:=PEEKW(47104,0) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 83 - This expression returns, to the variable CharAttr, the first character and attribute pair of a color display. The attribute will be in the upper byte and the character will be in the lower byte. --------------------------------------------------------------------- PI() Returns the value of pi, 3.14159265358979. Returns: True Example: degs:=rads*180/PI() Returns the value of rads radians, expressed in degrees to the variable degs. This expression performs the same action as the DEG() function. --------------------------------------------------------------------- PMT(prin,rate,periods) Calculates the equal periodic payment for an ordinary annuity with an initial principal of prin, at the specified rate, for periods payments. The interest rate must be expressed as a decimal fraction, rather than as a percentage. Returns: A number Example: amt:=PMT(1000,0.1,10) Stores the value $162.75 to the variable amt. --------------------------------------------------------------------- POKE(seg,ofs,value) POKE() will place the byte value at the memory location referenced by a segment value of seg and an offset value of ofs. This function should be used with care, since poking to random areas of the computer's memory may corrupt DOS and cause unpredictable behaviour. Consult your DOS reference if you are not familiar with the concept of offsets and segmentation. Returns: True - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 84 - See also: PEEKW PEEK POKEW Example: POKE(0,1047,0) This expression pokes a value of zero to the keyboard flags byte at 0417h in the BIOS data segment. This will turn off insert status, caps lock and num lock. --------------------------------------------------------------------- POKEW(seg,ofs,value) POKEW() will place the sixteen bit word value at the memory location referenced by a segment value of seg and an offset value of ofs. Use this function with care, since poking to random areas of the computer's memory may corrupt DOS and cause unpredictable behaviour. Consult your DOS reference if you are not familiar with the concept of offsets and segmentation. Returns: True See also: PEEKW PEEK POKE Example: POKEW(47104,0,0) This expression pokes a value of zero to the first character and attribute pair at the start of the color display memory area. This is displayed as a black space. --------------------------------------------------------------------- POPSCR() POPSCR() restores the screen from a temporary work area in memory. The PUSHSCR() function is used to save the screen in memory. Up to ten screens may be saved and restored, on a first-in, last-out or stack based basis. Returns: True if successful, false otherwise. See also: PUSHSCR Example: POPSCR() Restores contents of screen. --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 85 - POW(number, exponent) Returns the value of number raised to the power of exponent. This function is included for reasons of compatibility with the C language. Returns: True Example: v:=POW(10,2) Returns 100 to the variable v. Note that this operation can also be carried out using the `raise to power' operator, the caret, ^, so that the above expression could be rewritten as follows: Example: v:=10^2 --------------------------------------------------------------------- PUSHSCR() PUSHSCR() saves the current screen in a temporary work area in memory. The information saved consists only of a picture of the screen and does not save any fields. The POPSCR() function is used to restore a screen from memory. Up to ten screens may be saved and restored, on a first-in, last-out or stack based basis. Returns: True if successful, false otherwise. See also: POPSCR Example: PUSHSCR() Saves contents of screen. --------------------------------------------------------------------- PV(pmt, rate, periods) Calculates the present value of equal pmt in a simple ordinary annuity at the specified interest rate for a number of periods. As with all financial functions, the interest rate must be expressed as a decimal fraction, rather than as a percentage. Returns: A number - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 86 - Example: amt:=PV(1000,0.1,10) Stores $6144.57 to the variable amt. --------------------------------------------------------------------- QUIT() Halts the execution of the current application. If the runtime debugger was called from within the editor, then the editor wil be restarted, otherwise, the module will return to DOS. Returns: N/A Example: QUIT() Halts the application and then returns to the operating system or editor. --------------------------------------------------------------------- RAD(angle) Converts an angle expressed in degrees into an equivalent angle in radians. All trigonometric functions in RExL use radians as input. Returns: A number See also: DEG Example: r:=RAD(180) This assigns the value of pi, the radian equivalent of 180 degrees, to the variable r. --------------------------------------------------------------------- RAND() Returns a pseudo-random number between 0 and 1. Each time the inference engine starts a seed set to generate the sequence. Since the seed is always the same, the random number generator follows the same sequence. You can set your own seed value by using the SEED() function. Returns: A number - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 87 - See also: SEED Example: num:=FLOOR(RAND()*80)+10 Assigns an random whole number between 10 and 90 to the variable num. --------------------------------------------------------------------- RATE(fv, pv, periods) Calculates the periodic interest rate necessary for pv to grow to fv over a fixed number of compounding periods. Returns: A number Example: val:=RATE(1000,100,10) Assigns the value 0.2589 (or 25.89%) to the variable val. --------------------------------------------------------------------- REPEAT$(str$,times) REPEAT$() returns a string consisting of a source string, str$, repeated times times. If the string would need to grow beyond the maximum string length of 80 characters, it will be truncated. Returns: A string Example: a$:=REPEAT$("-",5) Assigns the string "-----" to a$. --------------------------------------------------------------------- REPLACE$(str$,start,chars,repl$) REPLACE$() takes a source string, str$, removes chars number of characters from it, starting at position start from within the string and inserts the replacement string, repl$ into the source in that position. If repl$ is an empty string, then the nett effect of REPLACE$() is to remove a substring from a parent string. If repl$ is empty, then str$ will be terminated at position start. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 88 - Note that all string indexing numbers (such as the start parameter above) are zero based, meaning that the first character is as position zero, not at position one as is the default in some other computer languages. Returns: A string Example: a$:=REPLACE$("Hello",0,2,"Ha") Assigns the string "Hallo" to the variable a$. It removes two characters from the string "Hello", starting at position 0, giving "llo" and inserts the string "Ha" at position 0 to give the final string "Hallo". --------------------------------------------------------------------- RIGHT$(str$, number) Returns the rightmost number of characters from the string str$. Returns: A string See also: LEFT$ MID$ Example: a$:=RIGHT$("Hello",2) Assigns the string "lo" to the variable a$. --------------------------------------------------------------------- ROUND(number, places) Truncates the first parameter to the number of specified places of decimals, or if places is negative, the output will be to that number of significant digits. Returns: A number See also: FLOOR CEIL Example: num:=ROUND(1.546,2) Assigns num to be 1.55 Example: num:=ROUND(213.2,-1) Assigns num to be 210.0 --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 89 - SEED(Value) Sets the seed for the pseudo-random number generator in RExL. This is set, by default, at the start of an application to a constant value (resulting in a repeatable array of random numbers), but you can make your seed more random by using some function of date and time. Value must be in the range of 0 to 65535. Returns: True See also: RAND Example: SEED((DTminuteno()+DTsecondno())*65535/120) This expression randomly assign the seed value to one of 120 different values. --------------------------------------------------------------------- SIN(angle) Calculates the sine of the angle angle, measured in radians. Returns: A number See also: COS TAN RAD DEG Example: value:=SIN(0.5) Assigns the value 0.4794255386 to the variable value. --------------------------------------------------------------------- SLN(cost, salvage, life) Calculates the straight line, or constant, depreciation allowance of an asset per period. The first parameter specifies the initial cost, the second, the salvage value at the end of the item's life and the third parameter gives the expected life of the item. Returns: A number Example: depr:=SLN(5000,1500,5) Assigns 700 to the variable depr. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 90 - --------------------------------------------------------------------- SOUNDEX$(string) SOUNDEX$() calculates the soundex code of the string parameter. The soundex code of a string is a four character string, having an initial letter (equal to that of the source string) followed by a three digit code, which codes for the phonetic value of that string. SOUNDEX$() is most usually used in conjunction with database applications, where the precise spelling of search keys is not known, or where there is an significant chance of misspelling of a search key. Returns: A four letter string Example: search1$:=SOUNDEX$("smith") Example: search2$:=SOUNDEX$("smythe") Both search1$ and search2$ are assigned the value of "S530", the soundex code of both strings. --------------------------------------------------------------------- SQRT(number) Calculates the square root of a number. The number must be zero or greater as the square root of a negative number is undefined. Returns: A positive number Example: num:=SQRT(9) Assigns the value 3 to the variable num. --------------------------------------------------------------------- STRING$(number, width, places) Returns number converted to a string of the specified width and number of decimal places. The width must also include space for a decimal point and minus sign. If the width is larger than the resulting number then it will be right justified. If width is less than it then the string will be truncated. If the width is zero, the number will be - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 91 - converted to the format most suitable, that is omitting the decimal point and fraction if none exists or inserting an exponent if the number is too large for normal display. Returns: A string Example: num$:=STRING$(-5.2,4,1) This will assign the string "-5.2" to the variable num$. --------------------------------------------------------------------- SUFFIX$(num) SUFFIX$() returns the parameter as a string, with the appropriate numeric suffix added. This function is most useful when applied to dates. Returns: A string Example: a$:=SUFFIX$(12) Returns the string "12th" to the variable a$ --------------------------------------------------------------------- SYD(cost, salvage, life, period) Calculates the sum of the year's depreciation allowance of an asset for a specified of period, given the original cost, the salvage value at the end of its life of life periods. The life is measured in the same units as periods and it typically the number of years of expected life. Returns: A number Example: x:=SYD(1000,100,9,3) Returns the value 140 to the variable x. --------------------------------------------------------------------- TAN(angle) Calculates the trigonometrical tangent of an angle, where the angle is measured in radians. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 92 - Returns: A number Example: value:=TAN(0.5) This will assign the value 0.5463024898 to the variable value. --------------------------------------------------------------------- TERM(pmt, rate, fv) TERM() calculates and returns the number of periods of payment, each payment of amount pmt needed to reach fv at a periodic interest rate, rate. The rate parameter should be expressed as a decimal fraction, the percentage divided by 100. Returns: A number Example: num:=TERM(50,0.15,5000) Assigns the value 19.837 to the variable num. --------------------------------------------------------------------- TRIM$(str$,trimtype) TRIM$() returns the string parameter str$ with spaces removed from it, according to the numeric parameter. Legal values for trimtype are as follows: trimtype Meaning 0 Remove spaces from both ends of the string 1 Remove spaces from the right end only 2 Remove spaces from the left end only Returns: A string Example: a$:=TRIM$(" <-> ",0) Returns the string "<->" to a$. Example: a$:=TRIM$(" <-> ",1) Returns the string " <->" to a$. Example: a$:=TRIM$(" <-> ",2) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 93 - Returns the string "<-> " to a$. --------------------------------------------------------------------- TRUE() Returns the value True. If you place this as the first and only line of a OR condition in a rule, then that rule will always evaluate to True. Returns: True See also: FALSE Example: TRUE() --------------------------------------------------------------------- UPPER$(string$) UPPER$() returns the parameter string in upper case. European accented characters are not translated by this function. Returns: A string See also: LOWER$ Example: a$:=UPPER$("hello") Returns the string "HELLO" to a$. --------------------------------------------------------------------- VALUE(number$) VALUE() converts a string, number$, to a number. It returns the converted number if successful or 0 if there was an error. number$ may contain exponents using the e+99 format. Returns: True if successful, False otherwise Example: num:=VALUE("5.23") Assigns a value of 5.23 to the variable num --------------------------------------------------------------------- - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 94 - VERSION() Returns the version number of RExL under which the application is running. Returns: A number Example: ver:=VERSION() Sets the variable ver to be x.yy where x is the major version number and yy is the minor version number. --------------------------------------------------------------------- XOR(log1,log2) XOR() performs a logical exclusive-or upon the two logical parameters passed to the function. The function returns True if the two parameters are of different logical values, and False otherwise. Returns: A number See also: AND NOT EQV OR IMP Example: val:=XOR(TRUE(),FALSE()) Returns False to to the variable val. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 95 - Chapter 4 Keystroke reference 4.1 Editor keystrokes Table 4.1: Cursor movement keys Context sensitive help Move one character left Move one character right Move to start of input Move to end of input Move to previous word Move to next word Delete character to left Delete character to right Place string in scrap Paste string from scrap Undo changes to string Move window (if applicable) Toggle macro recording Select playback macro Table 4.2: Hilite bar movement keys , Move one line up and down Move up 20 lines Move down 20 lines Move to top of screen Move to end of screen Move to to of rule Expand rule definition Contract rule definition , Delete line Insert blank line - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 96 - Table 4.3: Modifier keys , Start expression Select screen type Make rule one-pass Toggle [Multi] Toggle [Single] Toggle [Not] Toggle [While] Toggle [BackTo] Toggle [Zap] Table 4.4: Editor list keys , Rule list Rule reference list Expand and enter rule , Screen list Screen reference list Locate and position at 1st occurrence , Unused rule list Enter rule definition , , Delete rule Unused screen list , , Delete screen from file , Variable list Variable rule-ref list Alter array dimensions Function list Table 4.5: Editor miscellaneous keys Quit editor Graphic rule display Show user screen Toggle breakpoint Rule reference Save application Load new application Debug application Run application (no debugger) - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 97 - 4.2 Screen designer keystrokes Table 4.6: Screen designer movement keys ten characters right ten characters left / one character left/right / one character up/down to top of screen to top of screen to bottom of screen to end of screen to top left hand corner of screen to top left hand corner of screen to left of screen to right of screen one word right one word left next line, to right of nearest box if possible Delete character to right Delete character to left Table 4.7: Screen designer field definition keys Display expression attached to hilited field Define menu field Define toggle list field Define radio button field Define output field Define input field Define new field $ Field control menu Define check box field Edit field expression Table 4.8: Screen designer line draw keys , One character right One character left One line down One line up , End line draw Toggle delete mode Force horizontal emphasis to one line Force horizontal emphasis to two lines Force vertical emphasis to one line Force vertical emphasis to two lines - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 98 - Table 4.9: Screen designer miscellaneous keys Begin block mark Begin block mark Show screen designer status Delete characters & fields on line Second time, delete entire line Save screen Load new screen Exit from screen designer Exit from screen designer , Variable list , Rule list , Screen list Enter line draw mode Delete hilited field Toggle flash-intensity Remark last block Table 4.10: Screen designer block mark keys Extend block mark to right of screen Extend block mark to left of screen , Extend block mark to bottom of screen , Extend block mark to top of screen Extend block mark to bottom-right of screen Extend block mark to top-left of screen Extend block mark one line up Extend block mark one line down Extend block mark one line right Extend block mark one line left Extend block mark ten characters right Extend block mark ten characters left , , Select marked block Terminate block mark , , Delete marked block Draw box in marked block - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 99 - 4.3 Debugger keystrokes Table 4.11: Debugger hilite bar movement keys Expand rule definition Contract rule definition Move cursor left one character Move cursor right one character Move up 20 lines Move down 20 lines Move up one line Move down one line Move down one line Move to top of screen Move to end of screen Move to top of rule Table 4.12: Debugger list keys , Rule list Expand rule definition , Screen list Unused rule list Unused screen list , Variable list , Function list Table 4.13: Debugger miscellaneous keys Quit debugger Show user screen , Evaluate expression , Add watch Animate debugger Execute to cursor Expand debugger window Toggle windows Trace execution Step execution Run program Remove all breakpoints and run program Toggle breakpoint Trace execution Return cursor to origin Toggle macro recording Select playback macro , Pass control to debugger - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 100 - Table 4.14: KB function return values 8 331 379 9 333 380 13 335 381 27 336 382 271 337 383 272 339 384 273 340 385 274 341 386 275 342 387 276 343 388 277 344 500 278 345 501 279 346 502 280 347 503 281 348 504 286 349 506 287 350 507 288 351 508 289 352 509 290 353 510 291 354 601 292 355 602 293 356 603 294 357 604 300 358 605 301 359 606 302 360 607 303 361 610 304 362 611 305 363 612 306 364 614 315 365 615 316 366 616 317 367 617 318 368 618 319 369 619 320 371 620 321 372 621 322 373 622 323 374 623 324 375 624 327 376 625 328 377 626 329 378 700 - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 101 - Chapter 5 Error Messages 5.1 Error messages common to runtime and editor 5.1.1 Bad help file format The help file has become corrupted somehow. The only way to remove this error is to restore a copy of the help file from the distribution disks, or archive file which you received your copy of RExL in. 5.1.2 Cannot locate system RExL cannot shell to DOS because it cannot locate the system files which are required. This is most likely to be caused by the COMSPEC environment variable set incorrectly. It should contain the name, directory and drive of your main command processor. Try issuing the following DOS command from the normal DOS prompt, if none of the above makes sense. set comspec=c:\command.com 5.1.3 Cannot open print file RExL is unable to open the file which was specified instead of the printer. Generally, this is caused by running out of file handles. This condition can be rectified by placing the following line in your CONFIG.SYS file: files=20 5.1.4 Couldn't open file RExL is unable to open some file. Generally, this is caused by running out of file handles. This condition can be rectified by placing the following line in your CONFIG.SYS file: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 102 - files=20 5.1.5 Macros nested too deep (20=max) You're most unlikely to encounter this error. It indicates that you are trying to execute a macro from within a macro from within a macro etc, to a level of twenty deep, the maximum allowable. 5.1.6 Help file index is not loaded If RExL was unable to locate the help file, this error message will be displayed if any of the help keys are pressed. 5.1.7 Unable to locate help file When the editor starts up, it preloads a portion of the help file to allow more rapid access to the information in it. If the editor is not able to locate the help file in the in the current directory or the or list of directories specified in the REXL environment variable, then it will isue this error message. Automatic preloading can be disabled by setting the Options|Help menu option to slow. 5.1.8 Macro recursion not allowed RExL will not allow a macro being defined to call a macro which in turn executes the keystroke which is being defined. This is to prevent infinite recursion of the macro facility. 5.1.9 Error loading configuration file The RExL configuration file REXL.CFG in the current directory is invalid or could not be loaded for some reason. The configuration file format changes from version to version, so this error may appear if you run a new version of RExL without deleting the old configuration file. If this occursm, just ignore the error and it won't re-appear. 5.1.10 Zero memory allocation request! For some reason, a zero length request has been made to the memory allocator. This should never occur, thus indicating a bug if it does. Note down the exact circumstances in which the error occurred and report it to us. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 103 - 5.1.11 Not enough memory to perform selected operation There is not enough memory available for RExL to do whatever you just asked it to. If you have any TSR programs loaded in memory, then unload them, re-enter RExL and try again. 5.1.12 This window is not movable You have just tried to move a window which is not movable. Generally, the only unmovable windows are the system menus. 5.1.13 No directories available RExL is unable to locate any directories in the current directory for the File|Change directory menu. This warning only occurs if you are in the root directory of a drive which has no subdirectories. 5.1.14 No files in directory This error in a file selection menu if the specified drive and directory do not contain any directories nor files matching the stipulated file specification. 5.1.15 No macros defined The Options|Save macro file menu option has been chosen but there are no macros currently defined in memory to be saved. 5.1.16 --- Out of memory --- RExL has run out of memory in some critical operation where memory must be present. The best course of action it to quit RExL as soon as possible, remove any TSR programs resident and to retry. 5.1.17 No screens defined You have requested the screen list, but there are no screens present to make the list from. 5.1.18 Not enough memory to load system The DOS command processor COMMAND.COM requires a certain amount of memory to run, depending on the version of DOS. If there is not enough memory present then this warning will appear. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 104 - 5.1.19 No unused rules available You have selected the unused rule list, but RExL has determined that all rules are used in the listing. Remember that recursive rules are taken to be used, irrespective of whether they are called by any other rules. When scanning for unused rules, RExL also checks the line buffer to locate rules, marking them as used if any are present. 5.1.20 No unused screens available You have selected the unused screen list, but RExL has determined that all screens defined in the current screen file are used in the listing. When scanning for unused screens, RExL also checks the line buffer to locate screens, marking them as used if any are present. 5.1.21 No variables defined You have selected the variable list, but RExL has been unable to find any variables in its internal list. 5.1.22 Rule is not used in current listing RExL has tried and failed to find any references to the rule for which you have just requested a reference list. This error can occur from the editor window when is pressed, or in the rule list, with the same keystroke. 5.1.23 Error saving configuration file RExL was unable to save the configuration file, REXL.CFG, correctly. If a partial file was saved, then it should be deleted since it will generate an error when RExL next starts from that directory. 5.1.24 Screen is not used in current listing RExL has tried and failed to find any references to the screen for which you have just requested a reference list. This error can occur in the screen list, when is pressed. 5.1.25 Screen file is corrupt The screen file has somehow become corrupted and no longer can be read by REXL. The only action which can be taken is to restore the screen file from your last backup. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 105 - 5.1.26 Too many files open RExL has failed when attempting to enter a DOS shell since it was unable to open the command processor file because of lack of available file handles. Close some files and retry. 5.1.27 Too many keys in macro (500=max) RExL can store up to 500 keystrokes in a single macro. This error appears if you have attempted to go past this limit. If you require that more than 500 keystrokes are to be played back, then you should define one macro which does the first section and then calls a macro which does those remaining. 5.1.28 Variable is not used in current listing You have tried to get RExL to generate a variable reference list for a variable which does not have any references in the listing. Note that RExL does not look in the screen file for variables, so that a variable which is apparently unused may be present in some screen. 5.1.29 Wrong source file format RExL application listing files change format from one version to another. This error is generated if you attempt to load an application file saved from one version of RExL into another version. To transfer listings between versions, use the Import|ASCII load and save options. 5.1.30 Wrong screen file format The editor has attempted to load an incorrectly formatted screen from a screen file. This is usually caused by using different versions of RExL. Use the Import|ASCII load and save menu options to move applications between different versions of RExL. 5.1.31 Error opening screen file RExL was unable to open the screen file associated with the current application. This is probably due to having too many files open. Close some files and try again. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 106 - 5.2 Error messages unique to editor 5.2.1 Incorrect format in listing file RExL has found some incorrectly formatted item in the ASCII listing file, which it is unable to process. ASCII files are not intended for editing with text editors and attempts to do so may produce errors such as this one. 5.2.2 Cannot nest fields All field types, except menu fields, cannot nest or overlay each other. 5.2.3 Can only delete recursed rule from first level of recursion A rule which is in the rule stack cannot have lines deleted from it, since they might corrupt the rule stack and possibly crash RExL. This error is generated when an attempt is made to delete a block from a recursive rule or to delete a line from a recursive rule. If the line or lines must be deleted, then you should return to the root (by pressing repeatedly) and then entering the rule by selecting it in the rule list and pressing . 5.2.4 Unable to locate runtime module RExL has tried to run the runtime and debugger module but was unable to find it. When searching, RExL first searches the current directory, then the directory or directories specified by the REXL environment variable, and finally the entire DOS path. Only when all of these have been searched unsuccessfully, will this error message be displayed. 5.2.5 Area crosses fields An attempt has been made to move or copy a block of text and fields from one place on the screen to another and in the process overlaying some previously defined fields. RExL does not allow this and issues this message when it occurs. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 107 - 5.2.6 Can't have a field of this type in this screen You have tried to define a field of a type not permitted in the current screen. Consult the table in the chapter on using the screen designer to find out the valid combinations of field type and screen type. 5.2.7 Illegal array dimension When entering the size of an array dimension, an invalid number was entered. Re-enter the number and try again. 5.2.8 Maximum number of fields reached Screens can contain a maximum of 127 fields. Any screen which contains more than that amount should be re-designed, since the screen updating process may become noticeable on slow PC's. 5.2.9 Memory low, should save now! The amount of memory available in RExL's memory pool has gone below 2,000 bytes. In order to save a listing successfully, RExL needs about 1,000 bytes, so saving and quitting now would be a good idea. 5.2.10 Not used in listing You have tried to enter a rule which is defined, but not used, in the current listing. 5.2.11 This is the main rule and is called to start the kbs You have attempted to find rule references for the main program rule. This is only a diagnostic message. 5.2.12 Cannot change rule name to one already existing Normally, RExL allows for and automatically compensates for the changing of the name of any rule in an application. It does not, however, allow a rule name to be changed to one which exists already, since a name conflict would arise. Any changes made to the rule name are undone. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 108 - 5.2.13 This screen already exists As with rule names previously, it is not possible to change the name of a screen to one which already exists. Any changes made to the screen name are undone. 5.2.14 Toggle fields must be more than 5 and less than 75 characters wide The width of toggle fields must be between 6 and 74 characters inclusive. 5.2.15 Unable to create screen file RExL was unable to create a screen file to go with the current application. This is probably caused either by having no disk space left, or by having no file handles available. 5.2.16 Error saving file RExL was, for some reason, unable to save the current application to disk successfully. This is probably caused either by having no disk space left, or by having no file handles available. 5.2.17 Error loading file RExL was, for some reason, unable to load an application from disk successfully. This is probably caused by having no file handles available. 5.2.18 Error loading screen file RExL was unable to load the screen file associated with the current application. 5.2.19 Cannot change name of Main Program It is not possible, in the current version of RExL, to change the name of the root rule. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 109 - 5.3 Error messages unique to runtime-debugger 5.3.1 Array bounds overflow The runtime module has detected an attempt to access an array element beyond the defined bounds of the array. Array bounds can be set in the editor from the variable list by selecting the array, pressing and entering the size of the array. 5.3.2 Can't set a breakpoint here A breakpoint can only be set on a line which will actually be executed. These lines include rules, screens and expressions but do not include blank lines. 5.3.3 Cannot open printer for output Cannot write to print device Cannot close print device , The printer device cannot be opened for output, written to or closed. If output is directed to the printer, then make sure that it is connected and online. Alternatively, if the printer destination has been set using the OUTPUT() command, then make sure that the filename is valid. 5.3.4 Cannot find editor You have run the debugger from the editor or you have passed the -e option on the command line, but the debugger is unable to locate the editor. The debugger will terminate when this message is cleared. When searching for the editor, RExL searches the current directory, the directories specified in the REXL environment directory and then the entire DOS path. 5.3.5 Divide by zero Your application has attempted a to divide a numeric expression by zero, which is a computationally invalid operation. 5.3.6 String-numeric collision This error should never occur in normal operation of RExL. It indicated that an internal parsing error has occurred - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 110 - during the assignment of some quantity of to another. If you receive this error, then contact us. 5.3.7 Can't have string for radio button parameter Only numeric variables are valid radio button LValues. This error is kept for reasons of compatibility with earlier versions of RExL. 5.3.8 Stack underflow This error should not occur. It indicated that one of RExL's internal stacks (numeric, string or array) has underflowed. If you receive this error, then contact us. 5.3.9 Stack overflow This error should not occur. It indicated that one of RExL's internal stacks (numeric, string or array) has overflowed. If you receive this error, then contact us. 5.3.10 Numeric value out of range Certain mathematical functions require that their parameters be within certain ranges. For example, the LOG() function is only defined for values greater than zero, and attempts to find logiarithms of numbers less thanor equal to zero will generate this error. 5.3.11 Rule stack overflow You have tried to recurse beyond the maximum limit of recursion. By default, the limit is 100 entries on the stack, but it can be increased from within the editor using the Options|Rule stack menu option or by specifying the -s option on the command line to the debugger. 5.3.12 Invalid database file handle An operation involving database file handles has failed because an invalid file handle was passed. This error generally occurs in expressions using RExL's @variable.field construction, when does not contain a valid database file handle. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 111 - 5.3.13 Unable to allocate rule stack The runtime and debugger module has been unable to allocate enough memory to the runtime stack and consequently will not attempt to run the application. Make sure that you're not passing some over-large value to the module either on the command line, with the -s option, or from within the editor using the Options|Rule stack option. 5.3.14 Math error : Parameter out of range in function XXX The function XXX has been passed a value which is out of the range for which the function is defined. The functions which can generate this error are SIN(), COS(), ACOS(), ASIN(), TAN(), ATAN(), LOG() and LOG10(). 5.3.15 Math error : Parameter singularity in function XXX Certain functions, while defined across certain ranges have values within the range for which the return value generates a singularity. For example, the TAN() function is not defined for PI/2 radians and an attempt to calculate this value would cause this error to be generated. 5.3.16 Math error : numeric overflow You have tried to generate a result greater than the maximum value which RExL can cope with, about 2.7E308, absolute. 5.3.17 Math error : numeric underflow This error indicates that the result of a calculation has underflown and cannot be represented accurately. Generally speaking, a numeric underflow will return a zero value. 5.3.18 Math error : precision loss This error indicates that a calculation has not been carried out to a sufficient degree of accuracy. This generally occurs when evaluating functions close to parameter singularities. 5.4 Critical Errors These errors occur when some item of hardware attached to your PC does not appear to be functioning correctly. These - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 112 - errors are entirely DOS generated and RExL itself can do little to rectify them. Like the other error messages above, these are trappable using the ERok() function. These errors are listed in increasing order of obscurity, with errors at the bottom of the list being the most unlikely to occur. 5.4.1 Write protect error An attempt has been made to write information to a write protected disk. Remove the write protect tab and try again. 5.4.2 Drive not ready The disk drive accessed in the last operation was not ready. Make sure that the disk is inserted correctly, is properly formatted and can be read from the drive. 5.4.3 Printer out of paper The printer device has returned an error code to DOS indicating that something was wrong with the printer. Possible causes include no paper in the printer, the printer being turned off or off line or a paper jam. 5.4.4 Write fault DOS has tried to write to some block or character device driver but the driver returned an error code, indicating that it was unable to perform the operation. When applied to printers, it generally means that the printer has run out of paper or has been turned off during a print run. 5.4.5 Read fault DOS has tried to read from some block or character device driver but the driver returned an error code, indicating that it was unable to perform the operation. 5.4.6 General Failure This is a general purpose catch-all error message, saying that something went wrong, but DOS was unable to figure out exactly what. When applied to disks, it generally means that the disk is not formatted or is not of the correct size for the disk drive. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 113 - 5.4.7 Sector not found This error indicates that a sector on a disk has been found to be invalid, probably caused by a corruption of some type on the disk in question. 5.4.8 Unknown unit A request has been made by DOS to some device which does not exist or has not responded. 5.4.9 Unknown command An IOCTL request has been made to some block or character device driver but the command was not recognised by the driver. 5.4.10 CRC error The cyclic redundancy check on disk reads and writes has failed, indicating a faulty drive or improperly formatted disk. 5.4.11 Bad request structure length An IOCTL request has been made to some block or character device driver but the format of the request structure is incorrect. 5.4.12 Seek error BIOS was unable to locate the disk sector requested in a DOS call. 5.4.13 Unknown media type The disk which has just been accessed does not have a valid media identifier. This is usually caused by using Unix (and other system) formatted floppy disks. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 114 - - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 115 - Chapter 6 Extra Utilities This appendix documents the extra utilities supplied with RExL which are only available in the fully registered version. 6.1 RExLPC RExLPC is a utility which will combine a RExL application image file, its associated screen file and a special stub file into a single standalone executable file, suitable for distribution. It is provided as a neater alternative to RExLRT, described further on in this chapter. Typically, RExLRT is used to distribute applications which can be modified by the end-user, or may require on-site modification by the developer. On the other hand, RExLPC can be used to provide a single, faster DOS executable application which cannot be decompiled. Backups of the original versions of the application must be kept if they may need to be modified at a later date As a rough guide to performance gains, RExL applications converted with RExLPC will run code approximately two to four times as fast as REXLRD and REXLRT will. Corresponding C programs will run about half as fast to twice as fast again. For database operations, the speed gain will be small because most time is spent within the database code, which is common both the stub and the other executables. RExLPC takes two parameters on the command line, the first specifies the RExL application file to be converted, while the second parameter specifies the DOS executable file to be created. The base stub file REXLSTUB.COD must be accessible either through the REXL environment variable or on the DOS PATH. While the postfix compiler is running, it posts progress reports on the screen, to keep you informed of how far it has got. When the compiler finishes, it will - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 116 - generate an executable file as specified by the second command line parameter. If an executable file of this name exists already, then it will be overwritten. Applications should be fully working and debugged when passed through the compiler. The resulting executable file can be copied, distributed and run like any other DOS executable. The process involved in conversion is as follows. Firstly, the screen file and application images are loaded as normal and the stub file is copied to the specified output executable file. Then the postfix compiler module postfix- compiles the application and appends the generated code to the stub file. Finally, the screen file is postfix compiled and then appended to the stub. The resulting executable file can be copied, distributed and run like any other DOS executable and does not require any of the files (which were required to build it) to be present when the program is run. As with all other RExL executable files, you should not attempt to compress the file with compressors such as PKLite, DIET, LZexe and such like because of the nature of the files. Finally, a minor point of incompatibility with RExL: RExLPC does not supports the LOAD() function as it exists in RExL, because of the different .RXL and .EXE internal formats. In the compiled version, the LOAD() function will look for an executable file of the same name as the application image and load and execute that instead. This seems to be the most acceptable solution and will work transparently if multiple applications are converted and distributed together. If this is not satisfactory, then the OScmd() function can be used to run the runtime (or the runtime- debugger module), passing it the name of the application to run. For example, the command LOAD("TEST") which, in normal circumstances would load an application image file "TEST.RXL", would be interpreted by RExLPC as a call to load and run the file "TEST.EXE", overlaying the caller application (unlike a call to OScmd(), where the application regains control when the called program terminates). Alternatively, the command OScmd() could be used to run the application using a call such as: OScmd("rexlrt test"). - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 117 - 6.2 RDU 6.2.1 Introduction RDU, the RExL Database Utility, is a standalone database manager which can be used to manage dBase III+ compatible files. It can create and modify database structures, edit and browse database files and create and maintain dBase III+ index files. RDU is quite simple to operate and is based upon the same interface as other RExL programming tools. 6.2.2 Loading and Running RDU is loaded by typing RDU at the DOS prompt and needs about 180k of DOS memory to run. To start work on a database file immediately, rather than having to use the menu system to load one, you can simply pass the name of the database on the command line. For example, to load and start work on a database named "CUSTOMER.DBF", issue the DOS command `RDU customer'. The default and necessary extension of ".DBF" will be automatically appended for you, so you don't need to specify it. When RDU has loaded, you'll be presented with the main screen which is similar to RExL's editor. There are five pull down menus in RDU which are used to control the program. The next five sections will explain each menu. 6.2.3 RDU menu system 6.2.3.1 File Menu There are seven options in this menu, based upon those in the File Menu of RExL's editor. The options are as follows: o Use File: When selected, this option pops up a dialog box prompting for a database file to open. You can either enter a database name directly or press and select from a list. When a database file has been selected, it can be edited using the Edit menu. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 118 - o Use Index: When a database has been opened and selected, an index file can be opened, to order the contents of the database. When this menu option is selected, a file name dialog box appears, prompting for an index file to open. As with the Use File option, an index name can be entered directly or, upon pressing , an index file can be selcted from a list. If there is no database open, then this option cannot be used. o Remove: This choice allows you to delete a file from disk. You may need to do this is you want to save a file on disk, but are unable to do so through a lack of disk space. o Change Dir: This option will allow you to change the active directory. The format used here is much the same as that used in the file name input routine, the only differences being that no file names are displayed in the list and that the current active path (drive name with full directory) will be displayed on the status line at the bottom of the screen. o Default Drive: When this option is chosen, a menu will pop up displaying the list of available DOS disk drives. As with the directory selection above, the current active path is displayed on the status display line at the bottom of the screen. o OS Shell: If you want to run a DOS command, but do not wish to exit from RDU permanently, choose this option to go into a DOS shell. While you are in the shell, you should not, under any circumstances, run any T$SR programs (such as Sidekick, ScrGrab and so forth), since these programs change critical area of the computer's memory which may cause it to crash unpredictably when you return to RDU. When you are finished in the shell, type `exit' at the DOS prompt to return. o Quit: This option terminates RDU and returns you to DOS permanently. Since any work done is written to the database immediately, there is no `File has been changed' type prompt generated when this option is selected. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 119 - 6.2.4 Edit Menu This six option menu is used to control the editing and deletion of information in the database file currently selceted. If there is no database file open, then the options in this menu may not be used. The first two options, edit and browse, are used for changing and viewing information in the current database and are both `variations on a theme'. In either of these modes, the fields in the database are displayed on the left hand side of the screen and the contents of the fields are displayed to the right of the field names. The and keys are used to move to the next and previous records respectively, while moves the record pointer to the top of the database and moves it to the last record. If there are more fields in the database than can be fitted on the screen, then moves the first field in the database to the top of the screen, while moves the last field to the bottom line of the screen. In browse mode, it is not possible to edit the contents of the database and there is therefore no cursor visible. Pressing and will move increment and decrement the top field on the screen, if there are more fields than can be fitted, otherwise the keys have no effect in browse mode. In edit mode, and move to the previous and next fields in the database, scrolling the field list, if needed. and perform the same action as and . If or is pressed on the final field in the record, when the record pointer is at the final record in the database, then the prompt Append records? will appear. If the Yes option is selected, then a record will be appended to the database and editing will proceed from the new record. If the no option is selected, then no record will be added. When editing date fields, the date entered will be displayed and must be entered in the format appropriate to the country set up on your machine. If a valid date is entered, then it will be silently converted to a dBase date and written to the database file. RDU will not allow you to enter an invalid date. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 120 - Logical fields are one character wide and treat values of Y, y, T and t as true and all other characters as false. True values are stored as Y and false values as N in the database. Character fields may be from 1 to 255 characters wide. If the field width of the field being edited is greater than 67 characters, then a small arrow will be displayed before the start of the edit area. The arrow can be one of three characters, depending on whether the edit area extends to the left of the currently displayed area (uses ASCII character 27), whether it extends on both sides (uses ASCII character 29), or whether it extends to the left (uses ascii character 26). Any changes made to the database file are written to the file immediately. The six options in the Edit menu are as follows: o Edit record: Enters RDU's record editing facility, as described above. o Browse record: Enters RDU's record display facility, as described above. The contents of the database cannot be changed when using this mode. o Delete record: This option will set the delete flag of the current record. Because this option is relatively common, the keystroke can be used to toggle this flag. Note that when a record is marked for deletion, it is not physically removed from the database. o Recall deleted record: This option clears the delete flag for the current record in the current database. can be used to clear the delete flag on a record, if it has been set. o Pack database: All records marked for deletion in a database will be removed when it is packed. After this operation, the records cannot be recalled from deletion using the Recall menu option. o Zap database: This menu option permanently removes all records in a database. As with packing, the records cannot be retrieved afterward. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 121 - 6.2.5 Search Menu The search menu is used for searching for and locating information in database files. There are three options in this menu: o Locate string: This option is used to search for an occurrence of a string within a field in the current database. When the option is chosen, a menu will pop up containing the names of all the fields in the current database. The field selected here will be the one searched in during the searching operation. Once a field has been selected, a dialog box will appear prompting for a string to locate. The dialog input area will be as wide as the field being searched in. When a search string has been entered, the record pointer will be reset to the top of the file and searching will begin from there. If a match is found, then the matching record will be displayed and a prompt box will appear, asking whether the search should continue from that location to try to find another occurrence of the string. The record counter in the bottom right of the screen is constantly updated during the search to keep you informed of its progress. o Seek string: This option is used to seek for a key string in an index file. When selected, a dialog box appears, prompting for a string to seek for. If the seek is successful, then the record pointer wil be placed at the record whose key expression matches that entered. If it is unsuccessful, then an error message will be displayed. Since records are in index order when an index file is open, you will not be prompted to continue the seek when it has successfully found something. o Go to record: This option will prompt for a record number to jump to. If the record number specified is less than 1 or greater than the number of records in the database, then no action will be taken. Otherwise, the record pointer will be set to the - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 122 - specified record number. The record number is not dependant on any index files open. 6.2.6 Utilities Menu This menu has six options as follows: o Create database: This option is used to create database structures. When it is first chosen, a dialog box appears prompting for a file name to call the structure which is about to be created. When one has been entered the creation of the structure begins. o The structure creation box has four columns in it. The first is for field names, the second for field types, the third for field widths and the final column for field decimal places. o For logical and date fields, the field width is fixed at one and eight characters respectively, with no decimal places. The dialog will not allow figures to be entered in the final two columns for these two field types. Similarly, it is not possible to enter decimal field widths for character fields. RDU will not allow duplicate field names to exist in a file, displaying an error if this is attempted. o The keystrokes used are as follows: Table 6.1: Keystrokes in structure create Go to previous input area in field Go to next input area in field Go to next input area, creating field if already on last input area Go to same input area in field above Go to same input area in field below Delete field definition o The field type can be toggled by pressing . Alternatively, pressing the field type letter will set the type: `C' for character fields, `D' for date fields, `N' for numeric fields and `L' for logical fields. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 123 - o When the field definitions have been created, move to the final field in the structure and press to create the strucure on disk. o Once the structure has been created, the File/Use database menu options can be used to open and select the file just created. o Modify structure This choice operates in exactly the same way as the previous option for creating database files. The structure of the current database will be placed in the database creation box where it can be modified using the same keystrokes as before. o If the type of a field is changed, then RDU will do its best to preserve the contents of the field. In particular, date fields converted to numeric fields will have their contents changed to Julian day numbers, used elsewhere in RExL, while numeric fields (changed to date fields) will be assumed to hold Julian day numbers and processed accordingly. o If the width of any field is reduced, then the contents will be truncated to fit. If numbers in numeric fields no longer fit, then they will be replaced with asterisks. o When the desired changes have been made to the file, press on the empty field at the end of the list to make the changes permanent. o Create index: This choice is used to create an index file for the database which is currently open. When this menu option is selected, you will be prompted to enter an index key expression, which may contain any of the dBase III functions supported in RExL and the fields in the current database. As an aid-de- memoire, lists the fields in the database while can be used to list the functions available to you. If the expression entered is not valid, then an error will be generated. o When a syntactically valid index key expression has been entered, you will be prompted for a DOS file name to save the index file under. If one is entered, then index generation will proceed. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 124 - o While the index file is being generated, its progress will be displayed in a progress box in the center of the screen. Because of the method used for generation of index files, sorting may be slow if the file is already in order, however, if the file is not sorted, then the index will be generated very rapidly. o Reindex: This option will reindex an index file. This operation may need to be carried out if a database file has been modified while its associated index file was closed. If there is no database file or index file open, then this option performs no action. o Statistics: This option displays statistics about the database and index files currently open. The first line displays the name of the current database, the second displays the name of the current index file, if one is open. o The third and fourth lines show the number of fields and records, respectively, in the database. The fifth line displays the date of the last update to the database file, while the final line shows the size of the database header record. o Field list: This option lists the fields in the current database. The display format is exactly the same as in the database create option above, with field names in the first column, types in the second, widths in the third and decimal places in the fourth. 6.2.7 Options Menu This menu is fundamentally the same as that in the editor. It has five options as follows: o Load macros: Any macro definitions you define may be saved to disk for later retrieval using this menu option. The macro file format is constant across the RExL product range, so that macros defined in the editor may be used in the debugger or in the database manager and so on. Macros are explained in more detail at the start of the chapter on the editor. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 125 - o Save macros: This option allows you to save macros which can then be reloaded at some future time using the load option above. o Beep off: By default, RExL beeps whenever it encounters an error. This beeping can be toggled on and off by selecting this option. o Exploding windows In its normal state, all windows in RExL open instantaneously upon activation. This option can be used to make windows `grow' to full size on the screen. This is only a visual effect and has no effect upon the application. o Case sensitivity: By default, all database indexes and searches are carried out with case sensitivity on, to follow the dBase convention. However, this is contrary to the case-insensitivity in the rest of RExL. If dBase compatibility is not required, then the case sensitivity may be turned off. Note that the case-sensitivity feature only affects the generation of index files. 6.3 RExLRD RExLRD is the combined runtime and debugger module for the RExL programming environment and is called by the editor whenever the application is run. RExLRD uses the following command line syntax: RExLRD [-d] [-k] [-e] The options are used as follows: o -d: The `d' parameter will cause the debugger to start up in debug mode, as if the user had pressed during loading of the application. This switch is passed invisibly by the editor to the debugger whenever the debugger is called via the Debug application option in the Run menu in the editor. o -e: The `e' option will return control to the editor when the debugger terminates. Whenever the editor calls the debugger, this option is silently passed to the - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 126 - debugger, so that the debugger will return to the editor when it terminates. o -k: This `k' option is used to tell the runtime module not to watch out for the two keystrokes of and , which are normally monitored. ( will interrupt the run module and relinquish control to the debugger while pressing twice will terminate the application.) o -l: This `l' option is used to tell the runtime module that it is running on an LCD display. If you are running the debugger from the editor, then this option will be passed automatically, but if you are running it from the DOS command line, then you need to include it specifically. o -s: This `s' option is used to set the size of the runtime stack to be used when executing the application. Be default the size is 100 stack entries, but if your application uses recursion then this value should be increased. If you need as much memory as posible, then this value may be reduced: Each stack entry requires eight bytes of permanent storage. The required stack size is placed after the `s'. For example, to set a stack size of 30 entries, the command line option `-s30' should be passed. 6.4 RExLRT RExLRT is the runtime module of the RExL programming environment. If it used for running the systems written in RExL. It is about one-third smaller than the combined runtime-debugger module and it runs applications about 10% to 15% faster. The command line syntax for RExLRT is identical to that for the debugger, with the only difference being that does not pass control to the debugger, since there is none. RExLRT is used in preference to the executable file generator, RExLPC described earlier, when it is necessary to have separate application image, screen and executable files. Typically, this program is used to distribute - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 127 - unfinished applications which may require on-site modifications. Note also, that REXLRT supports the LOAD() function call, whereas RExLPC does not, because of the differing internal formats. 6.5 ScrList ScrList lists the contents of screen files and outputs the contents to the standard output device, usually the monitor. The format of the output file listing is as follows: The block number of every block in the screen file is printed first, immediately followed by a colon. If the block is in use as a screen, then the screen name will be printed surrounded by quotes. If the block is not in use, then the message (Block is not used) will be displayed. The next line displays the position and size of the block in the screen file in the format [x,y]->[x+w,y+h] where the screen was originally saved from position (x,y) with a block width and height of w and h respectively. The number of fields defined in the block follows next. The rest of the line is concerned with internal information: bsz is the size of the current block, ofs is the offset of the block within the screen file while fsz is the size of the block used up by the screen, the difference between bsz and fsz being unused. As an integrity check, the sum of the current block's offset and block size should equal the next blocks offset. The remaining lines in a screen's list display the fields defined in the screen. Firstly, the type of the field is listed, followed by a colon and the position and dimensions of the field, in the format of (x,y) [w,h], where the symbols have their usual meanings. If the field is a menu field, then ScrList will move to the next field immediately. Otherwise, the expression associated with the field is displayed, enclosed in square brackets. Note that since the screen file itself contains no variable name information, the names of variables in expressions cannot be determined and they are therefore displayed as variable reference numbers, immediately - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 128 - preceded by a hash # symbol. If you require a listing of the expressions attached to all the fields in your application, then use the `Import/Save ASCII' option in the editor. If the field is a toggle list, then the different options in the list will be displayed on the following lines, again enclosed in square brackets. The following is an extract from a typical example of the output from ScrList showing all the salient features: 6:"Is Data ok?" [28,11]- [51,17] - 3 fields (fsz: 221, ofs: 2395, bsz:221) Menu : (24, 4) [21x 1] : [#1] MArea : (35,14) [ 7x 1] MArea : (35,15) [ 7x 1] 7:"Enter Names and Question 1" [ 0, 0]- [79,24] - 7 fields (fsz: 901, ofs: 2616, bsz: 901) Input : (24, 4) [21x 1] : [#2] Input : (24, 5) [ 9x 1] : [#3] Toggle: (24, 6) [15x 1] : [#4] [Civil Eng] [Science] [Electrical] [Mechanical] [Agriculture] Input : (24, 7) [11x 1] : [#5] Input : (18,13) [ 1x 1] : [#0[1,1]] Check : (18,14) [ 3x 1] : [#6] Radio : (18,15) [ 3x 4] : [#7] 6.6 ScrFix ScrFix is a command line utility which repairs corrupted screen files. A screen file can become corrupted if the disk it resides on generates read errors or if the PC was switched off during a write to a screen file. ScrFix can take either one or two command line paramaters. The first paramater specifies the screen file to fix, while the second parameter specifies an optional output file. If the second parameter is omitted, the original file is renamed with an extension of ".bks" and the corrected version assumes the name of the older file. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 129 - While ScrFix is running, it displays possible screen corruptions on the monitor, thus giving warning of those screens which are most likely to be lost. For example, if a screen file "test.scr" has become corrupted, it could be fixed using the following two commands: scrfix test scrfix test fixed The first command produces a corrected output file called "test.scr", renaming the corrupted file "test.bks". The second line creates a new corrected screen file called "fixed.scr" and does not alter the contents of the corrupted file. The best way to approach fixing corrupted files is to copy the application image file (extension is ".rxl") and the corrupted screen file to some new root name, using a DOS command such as: copy broken.* test.* where "broken" is the root name of the corrupted application image and screen file and "test" is the name of the file which will be modified by ScrFix. 6.7 ScrGrab ScrGrab is a terminate and stay resident utility which is used to grab text screens from the monitor and to place the contents in files compatible with RExL's ".SCR" format. The ScrAdd utility can be used to combine screen files together. Typical applications of ScrGrab and ScrAdd are demonstration programs like that supplied with RExL, bug reports supplied with screen dumps and so on. When loaded in memory, ScrGrab uses about 2,500 bytes of memory. When it is no longer required, it and can be unloaded from memory from the command line. The command line arguments which ScrGrab uses are as follows: - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 130 - -h and -? Show command line help -u Unload from memory. If further T&SR programs have been loaded since ScrGrab, then it cannot be unloaded since doing so would corrupt DOS and most likely crash the machine. -k....: This option is used to set up the keystroke, by default , which will cause ScrGrab to save a screen to disk. Unless you have a keyboard scan code table, you'll need to used the KbdScan utility to determine the exact four character keyboard scan code to supply here. Refer to the section on Scan for more information. -d: Requests ScrGrab to report the current defaults which it is using. The first line gives the activating scan code, in a format compatible with the output from KbdScan while the next line gives the DOS paragraph where the program is loaded. This information is purely technical and is not of much use. You should not run any T&SR programs from within an operating system shell, such as when the `File/OS shell' is selected from the editor, since T&SR's perform surgery upon DOS which will cause it to crash if the shell is subsequently terminated using the DOS exit command. 6.8 ScrXtrct ScrXtrct is a utility which can extract and place a screen from one screen file into another screen file. The general command line format of this command are: ScrXtrct OldScr ScreenNo NewScr where OldScr is the screen file from which screen number ScreenNo will be extracted and placed into the NewScr screen file, erasing NewScr if it already exists. Unlike the rest of RExL, ScreenNo is one-based, meaning that the first screen is number 1, the second number 2 and so on. If OldScr contains a number of screens and you are not sure of the reference number of the screen you want, then you can use the ScrList utility to list them along with their screen numbers. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 131 - 6.9 ScrAdd ScrAdd is a utility which can extract and place a screen from one screen file into another screen file. The general command line format of this command are: ScrAdd OldScr ScreenNo NewScr where OldScr is the screen file from which screen number ScreenNo will be extracted and placed into the NewScr screen file. Note that, as with ScrXtrct, ScreenNo is one-based. If OldScr contains a number of screens, then you can use the ScrList utility to list them along with their screen numbers. If the name of the screen specified clashes with one in the new screen file, then you will be promted to enter a new name for the screen being added. ScrAdd does not perform any of the optimization operations carried out in the editor upon screen files when they are being modified. Instead, it simply appends the screen to NewScr. ScrAdd is generally used in combination with ScrGrab and ScrXtrct to move screens from one screen file to the next. 6.10 MI MI, short for memory information, displays pertinent information about the state of DOS and the programs resident in your PC. The following is a typical display of the output from MI: MI Version 2.1 Copyright (c) 1992, The Software Loft -------- -------- ------------ -------------- PSP addr Size Owner Hooked vectors -------- -------- ------------ -------------- 0008 24,048 [ Dos ] 084E 2,368 [ Shell ] 22 23 24 2E EF 64 [ Free ] 084E 752 [ Shell ] 0AA6 128 [ Dos ] 0921 6,208 edos.com 2F - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 132 - 0AA6 2,592 edos.com 0B54 2,320 scrgrab.com 09 16 21 28 0BE7 606,768 [ Free ] ------------ ---------------------- ---------------------- Memory Total bytes Available bytes ------------ ---------------------- ---------------------- Conventional 655,360 (640k) 606,592 (592k) Expanded EMS not responding Extended 3,145,728 (3,072k) 0 (0k) XMS 2,048,000 (2,000k) 2,048,000 (2,000k) HMA allocated, EBDA not present There are 12,102,400 (out of 120,946,944) bytes free on drive N: The first section of the display gives information about memory control blocks (MCB's) in low DOS memory, between 0 and 640k. It lists the hexadecimal address of the owner of the MCB in `PSP addr' column, the amount of memory owned by the block in the `Size' column, the name of the program which owns the PSP in the `Owner' column. The final column lists, in hexadecimal, the interrupt vectors which are hooked into the memory controlled by the MCB. From the above display, we can see that ScrGrab hooks the high and low priority keyboard interrupts, the main DOS server interrupt and the DOSok interrupt. A DOS technical reference will tell you the meanings and uses of the different interrupt numbers. DOS itself also owns blocks of memory and these are signalled by owners of `[Dos]', for blocks with invalid environments and `[Shell]', for blocks which do not have program names attached to them. The second section of the output from MI lists the amount memory available in each of the different memory schemes used in the PC. The listing is divided into five columns: The first gives the type of memory about to be listed, the second gives the total amount of memory allocatable and the fourth gives the amout of memory remaining unallocated. The third and fifth columns convert the byte counts to measurements in kilobytes (bytes divided by 1024). Conventional memory extends from 0 to 640k, unless VGA graphics memory has been used to backfill DOS to 736k (generally, it isn't). The available conventional figure will always be slightly less than that noted as [Free] in the first section of the listing. This is because the first - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 133 - section lists as free the memory used by the environment of the currently active program, while the second does not. The next line gives the amount of expanded memory (LIM EMS) in your system. It interrogates the status of int 67h which controls the interface to the memory. If this vector is NULL, then the message `None' will be displayed. If the vector exists, but does not respond in the way it should, then the message `EMS not responding' will be displayed. The third line in this section gives the amount of vanilla extended memory available and free. The total is read from the CMOS setup information in your PC, while the amount of free memory is taken from int 15h/fn 88h. The final line in the memory display gives the amount of XMS (Extended Memory System) in your machine. The second last line gives the on/off status of the DOS 5 HMA (High Memory Arena) and that of the EBDA (Extended BIOS Data Area) which is normally only present on PS/2, Compaq, Digital and Olivetti PC's. The final line gives the total disk space and the space on the currently selected disk drive. MI can optionally be followed by a drive letter to specify a drive, whose statistics are displayed instead of the current drive. For example the line MI a: will list the free space and total drive space on the A: drive rather than the current drive. MI takes one of two optional command line parameters, -c and -m. The -c parameter instructs MI to display the CPU type, the floating point coprocessor type, the video adapter type. If the processor is an Intel 80386 or above, then a message will be displayed saying whether or not the CPU is running in protected mode. The -m parameter causes the normal `condensed' memory control block display to be displayed in its low level unprocessed form. When -m is specified, no memory or capacities are determined. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 134 - 6.11 KbdSpeed KbdSpeed is a small utility to set the keyboard repeat rate on AT class computers with extended keyboards. The format of the command is as follows: KbdSpeed where letter is a letter in the range `a' to `z' and controls the repeat rate, with `a' at 30 repeats per second and `z' meaning 5 repeats per second. digit is a digit in the range `1' to `4' specifying the delay before repeating occurs. 1 specifies a delay of 1/4 seconds, up to 4 specifying a delay of 1 second. To set the keyboard to repeat at 30 characters per second, with a delay of 1/4 seconds before auto repeat occurs, the following command would be issued: KbdSpeed a1 If you run KbsSpeed from within MicroSoft Windows, then the program will have no effect, since Windows resets the rates of its own accord, ignoring any preset values. KbdSpeed is most useful in RExL when designing screens where the cursor may need to make large movements around the screen. The normal repeat rate of 10 characters per second then becomes an irritation. 6.12 KbdScan KbdScan is another small utility which reads from keystrokes from the keyboard and displays the keyboard scan code, the BIOS keystroke return value and the TSR hotkey code. The information is displayed on three sucessive lines. The format of the command is as follows: KbdScan [-x] This utility is provided so that the activating keyboard scan code for ScrGrab can be changed. If you want to do this, take the TSR hotkey code displayed on the final line - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 135 - of display and place it as the parameter to the -k command line option to ScrGrab. The following is output from KbdScan, with as the last key pressed: KbdScan Version 2.1 (C) Copyright 1992, The Software Loft Press any key, ESC (twice) aborts : Shift/scan code :088b BIOS return value :8100 TSR hotkey code :0881 To change the activating keystroke in ScrGrab to , the following command would be issued. ScrGrab -k0881 Finally, ScrGrab accepts the command line option `-x'. If this option is included, ScrGrab will read keystrokes from an extended 101-102 key keyboard. This is only supplied as an extra feature, and is not used in RExL. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 136 - - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 137 - Chapter 7 Afterword This appendix gives a few pointers to the directions in which the Software Loft hopes to go when developing future versions of RExL. Any suggestions for features which you would like to see incorporated would be most welcome. Please remember that without your support, we cannot continue to supply you with low cost, quality software. Thank you. o More features in the debugger: Break on expression, pass count breakpoints, break on variable access. VGA 43 and 50 line mode support. o More features in the editor: Search and replace, lines longer than 65 characters, and function references (similar to variable references). Color installation program to set up colors of menus, windows and various other system parameters. VGA 43 and 50 line mode support. o Language: rules attached to variables. Every time a variable is either accessed or changed, its rule is called. User defined RExL functions. Link in with C, assembly language and Pascal. o New features in the screen designer. These will include pictures for input and output (as in dBase compatible languages) as well as undo. o Improve the speed of the runtime-debugger module. Currently, we have a better expression evaluator undergoing tests and we hope to include it in the next major release. o Mouse handling. - RExL Version 2.11 Copyright 1992, The Software Loft - - Appendices. Page: 138 - o Add true relational capability to the database module. Most of the code required is in place for this. o A portable runtime module to allow the programmer to write applications in DOS and to port the finished product to Unix, and other text based operating systems. o A windows version of RExL. The current version of RExL has taken fourteen months for us to write. We hope to be able to port most of the code to Windows easily enough and to have an alpha test version running sometime around December of 1992. - RExL Version 2.11 Copyright 1992, The Software Loft -