TB#88

Verb and RTP

Programs in  Advanced Revelation use a number of programs to accomplish its tasks. It is sometimes possible for your programs to cause a system program to break. Unfortunately the debugger reports the internal name of the system program, not the name with which you may be familiar.

The figures below list the Verb (V) processors and Run Time Programs (RTPs) used by Advanced Revelation. Figure 1 is a listing of the V processors arranged by V number. Figure 2 is the same list, arranged by VOC name.

Figure 3 shows the RTPs and their associated functions.

SAVELIST  V1 System Loader RTP1
SAVE-LIST  V1 System Level 1 RTP2
GETLIST  V2 R/BASIC Compiler RTP5
GET-LIST V2 READV RTP7
SELECT  V5 WRITEV RTP8
SSELECT V5 OPEN RTP9
SET-OPTIONS  V6 READNEXT RTP11
SUM V8 Index Based READNEXT RTP11.INDEX
COUNT  V9 SELECT RTP12
TIME  V11 HEADING/FOOTING/PAGE RTP15
WHO  V12 XLATE RTP16
COMPILE  V15 EXECUTE RTP17
BASIC  V15 PERFORM (TCL) RTP18
RECORDCOPY  V17 TCL Parser RTP18.ENGLISH
COPY  V17 FMT/OCONV RTP19
ATTACH  V18 WITH processor RTP20
CREATE-FILE  V19 Multi-Valued Math RTP21
MAKEFILE V19 Debugger RTP25
DEFINEFILE V19 ICONV RTP26
NAMEVOL  V20 Program Loader RTP27
NAMEMEDIA V20 Program Loader RTP27A
NAMEVOLUME V20 TCL Options Parser RTP29
LH_VERIFY V21 SUM RTP31
RUN V23 FIELDSTORE RTP32
LISTVOLUMES V24 LOCATE BY RTP33
MLIST V25 CLEARFILE RTP34
LISTFILES V25 LOCK RTP36
MAKEVOC V26 UNLOCK RTP37
CATALOG V26 Network Flush RTP38
DICTCOMPILE V27 TIMEDATE RTP39
DELETE-FILE V28 Labelled Common Loader RTP42
DELETEFILE  V28 Multi-Value READNEXT RTP43
BLIST  V29 Volume Info Reader RTP49
CLEAR-FILE V30 Memory Resident BFS RTP50
CLEARFILE V30 ROS Filing System RTP51
LOGTO V32 Subroutines for ROS RTP51.SUBS
MAKEACCOUNT V33 LINK Filing System RTP52A
CREATE-ACCOUNT V33 DOS BFS RTP53A
DETACH V34 DOS BFS RTP53B
DELETE-LIST  V35 Linear Hash Filing System RTP57
DELLIST V35 Linear Hash Subroutines RTP57.SUBS
PC V36 Revelation G Filing System RTP59
SET-CRT V37 Evaluation System Routine RTP60
SET-LPTR V38 Evaluation System Routine RTP61
MAKEUSER V40 Evaluation System Routine RTP62
DELETEUSER V41
LISTDICT V45
LOOKDICT V45
RENAMEFILE V60
RENAME-FILE V60
LISTVOL V61
LISTMEDIA V61
DELETE-ACCOUNT V63
DELETEACCOUNT V63
PASSWORD V64
CHANGE-PASSWORD V64
ENCRYPT V65
SET-FILE V76
SETFILE V76
DELETEREC V77
DELETE V77
FORM-LIST V82
MAKELIST V82
UNMAKEVOC V83
DELETE-CATALOG V83
FILECOPY V114
REDEFINEFILE V116
RECREATE-FILE V116
REMAKEFILE V116
DUMP V117
TERM V122
TERMINAL V122
PORT V123
DATA V126

TB#95

The %FIELDS% Record


The dictionary of each file contains, as part of its control information, a record called %FIELDS%. The %FIELDS% record contains a summary of the most important characteristics of field definitions in that dictionary. This technical bulletin provides information on the layout and use of this control record.

%FIELDS% Layout

The layout of the %FIELDS% record is:

Pos Description

1 Reserved
2 Sequential counter for next position default in Dictionary window.
3 Field names in ascending left-justified order.
4 Type (F or S).
5 Position.
6 Btree flags. True if this field is Btree indexed.
7 Cross-reference flags. True if this field is Cross-reference indexed.
8 Key part.
9 Single or Multivalued.
10 Justification.
11 Display length.
12 Output format.
13 Default value.
14 Master flag. True if this is the "master" definition of a field (not a synonym).

Fields 3 through 14 are associated multivalued fields, with field 3 (field names) as the controlling field.

Maintaining %FIELDS%

The %FIELDS% control record is maintained automatically by DICT.MFS. Each time you write a record to the dictionary, DICT.MFS examines the record and determines whether it is a valid field. A field valid for inclusion in %FIELDS% must have these characteristics:

1) It is an F-, G-, or S-type field.
2) The field name does not begin with the characters "%" or "@".
3) The field has compiled successfully (F- or S-type).
4) The field could be written successfully to the dictionary.
5) If F-type, it has a numeric Position.
6) If S-type, there is a formula.
7) If G-type, there is display information in attribute 3 of the field.

The fact that DICT.MFS enforces certain naming conventions (no "%" or "@" beginning the field name) means that these characters can only be used as prefixes in the names of dictionary control records (for example, "%SK%"). Other field name prefixes are also restricted (no "$" as a prefix, for example); although DICT.MFS does not prohibit these, other higher-level processes will fail on these types of field names.

If the %FIELDS% record does not exist, DICT.MFS builds it when first opening the dictionary. If this is happening, you will see the message "Rebuilding control records ...".

If the record exists at all, DICT.MFS does not synchronize it with the existing dictionary. This leads to the possibility that %FIELDS% can be logically corrupt. For instance, this could happen if %FIELDS% were deleted, but then new dictionary records were added before DICT.MFS had an opportunity to re-open the file.

If you suspect that %FIELDS% is not up-to-date, delete the record, then re-attach the file and list the dictionary. This will cause DICT.MFS to rebuild the record. If you should ever delete the %FIELDS% record you should immediately re-attach the file.

You cannot update the %FIELDS% record yourself because it is write-protected by DICT.MFS. You will see an error to this effect if you attempt to write the record in any way.

The fact that all valid field names are maintained in %FIELDS% creates an implied limit to the size of a dictionary. All summary information about a dictionary, including all the details listed above, must fit within 64K. However, this limit is comfortably high. Assuming for a moment an average of about 35 bytes per dictionary entry, the maximum allowed would be around 1,875 fields per dictionary. Unusually long field names, formatting specifications, or default specifications would, of course, bring this number down.

Using %FIELDS%

The fact that a summary of the dictionary is maintained in a single record can come in handy during application development, mostly in the aid of speed. Examples of uses for %FIELDS% include:

_ Creating quick pre-sorted listings of field names.
_ Deriving field positions quickly.
_ Deriving formatting specifications for reports.
_ Checking index flags quickly.

Examples of different uses appear in the Figures.

Figure 1

* sorted field names in a popup
DECLARE FUNCTION POP.UP
FILENAME = 'SAMPLE_CUSTOMERS'
AT_FIELDS = XLATE('DICT.':FILENAME,'%FIELDS%','','X')
FIELD_NAMES = AT_FIELDS<3>
CONVERT @VM TO @FM IN FIELD_NAMES

X = 0
Y = 0
FILE = "@":FILENAME
LIST = FIELD_NAMES
FORMAT = "1:25:L::Field Name" ; * 1 fm-delim element per column
MODE = "R"
SELECT = 1 ; * single selection popup
TITLE = FILENAME: " fields"
ATTRIB = ""
HELP = ""
COORD = "1" ; * return col 1 if TYPE is null
TYPE = "" ; * if null, return column in COORD

@ANS=POP.UP(X,Y,FILE,LIST,FORMAT,MODE,SELECT,TITLE,ATTRIB,HELP,C OORD,TYPE)

Figure 2

* use %FIELDS% to validate field names and get formatting information for a report
FILENAME = 'SAMPLE_CUSTOMERS'
OPEN FILENAME TO FILE ELSE CALL FSMSG() ; STOP
OPEN 'DICT.':FILENAME TO @DICT ELSE CALL FSMSG() ; STOP

READ AT_FIELDS FROM @DICT,'%FIELDS%' ELSE CALL FSMSG() ; STOP
FIELD_NAMES = AT_FIELDS<3>
JUSTS = AT_FIELDS<10>
LENGTHS = AT_FIELDS<11>

* build table of fields to be displayed and their corresponding output formats
DISPLAY_FIELDS = ''
DISPLAY_FORMATS = ''
FIELD_CNT = 0
LOOP
NEXT_FIELD = ''
    CALL MSG( 'Next field to display?','RC',NEXT_FIELD,'')
WHILE NEXT_FIELD
        * validate entry
    LOCATE NEXT_FIELD IN FIELD_NAMES USING @VM SETTING POS THEN
        DISPLAY_FIELDS<-1> = NEXT_FIELD
        DISPLAY_FORMATS<-1> = JUSTS<1,POS> : '#' : LENGTHS<1,POS>
        FIELD_CNT += 1
    END ELSE
        TEXT = NEXT_FIELD: " is not a valid field name!"
        CALL MSG(TEXT,'','','')
    END
REPEAT

HEADING "Report of the file: ":FILENAME: "'L'"
SELECT FILE
DONE = 0
LOOP
    READNEXT @ID ELSE DONE = 1
UNTIL DONE
    READ @RECORD FROM FILE, @ID THEN
    FOR CTR = 1 TO FIELD_CNT
        PRINT CALCULATE( DISPLAY_FIELDS<CTR> ) DISPLAY_FORMATS< CTR > :
    NEXT CTR
    PRINT
    END
REPEAT

Figure 3

* simple listindex (does not include relationals)
FILENAME = 'SAMPLE_CUSTOMERS'
AT_FIELDS = XLATE('DICT.':FILENAME,'%FIELDS%','','X')

INDEXED_FIELDS = ''
COL = 0 ; CTR = 1
LOOP
    REMOVE NEXT_FIELD FROM AT_FIELDS<3> AT COL SETTING FLAG
    IF AT_FIELDS<6,CTR> OR AT_FIELDS<7,CTR> THEN
        INDEXED_FIELDS := NEXT_FIELD : @FM
    END
    CTR += 1
WHILE FLAG REPEAT
IF INDEXED_FIELDS THEN
    INDEXED_FIELDS[-1,1] = '' ; * strip trailing field mark
    TEXT = 'Btree/Crossref indexes in ':FILENAME
    TEXT<-1> = INDEXED_FIELDS
    CALL MSG( TEXT,'','','')
END ELSE
    TEXT = 'No fields are indexed in ':FILENAME
END