Sample Code
Home Up RTI Routines AREV Subs System Subs Printers Sample Code Tips & Tricks Tech Bulls

 


SAMPLE CODE

 

ATTACHTABLE_SUB (parms)

ATTACHTABLE_SUB( volumeName, tableList, options )

/* attaches a list of tables */
volume = "SAMPLE"
tableList = ""
tableList<1> = "SAMPLE_CUSTOMERS" /* data, dict, and index */
tableList<2> = "DATA.CAR_PARTS" /* data and index only */
tableList<3> = "DICT.CAR_ORDERS" /* dict only */

options = "A" /* Announce option */

call ATTACHTABLE_SUB(volume, tablelist, options )

if len( status() ) then
call fsmsg() /* display messages */
end

BUILDINDEX_SUB (parms)

declare subroutine buildindex_sub, fsmsg
declare function index.open

tablename = "PEOPLE_10000"
open tablename to datahandle else
fsmsg()
stop
end

open "DICT", tablename to @dict else
fsmsg()
stop
end
if index.open("!":tablename, indexhandle) else
fsmsg()
stop
end
fieldinfo = ""
fieldinfo<1, 1> = "AGE"
fieldinfo<1, 2> = "Btree"
fieldinfo<1, 3> = ""
fieldinfo<1, 4> = "AGE"
fieldinfo<1, 5> = 1 ;* Btree
fieldinfo<1, 6> = 4 ;* Column position
fieldinfo<1, 7> = 1 ;* Convert to Uppercase
fieldinfo<1, 8> = "RL"
fieldinfo<1, 9> = "AA"
fieldinfo<1, 10> = 0 ;* single value

fieldinfo<2, 1> = "ADDRESS"
fieldinfo<2, 2> = "CrossRef"
fieldinfo<2, 3> = ""
fieldinfo<2, 4> = "ADDRESS_XREF"
fieldinfo<2, 5> = 1 ;* Btree
fieldinfo<2, 6> = 5
fieldinfo<2, 7> = 1 ;* Convert to Uppercase
fieldinfo<2, 8> = "LL"
fieldinfo<2, 9> = "AA"
fieldinfo<2, 10> = 0 ;* single value

fieldinfo<3, 1> = "CITY"
fieldinfo<3, 2> = "Relational"
fieldinfo<3, 3> = "CITIES*PEOPLE_IN_CITY*BOT" ;* Related info
fieldinfo<3, 4> = "CITY"
fieldinfo<3, 5> = 2 ;* Relational
fieldinfo<3, 6> = 6
fieldinfo<3, 7> = 1 ;* Convert to Uppercase
fieldinfo<3, 8> = "LL"
fieldinfo<3, 9> = "AA" ;* Sort for "BOT" index
fieldinfo<3, 10> = 0 ;* single value

buildindex_sub(tablename, datahandle, indexhandle, fieldinfo, 0)
if @file.error then
if @file.error[1, @RM] eq "421" then
text = "The process has been cancelled. You MUST rebuild"
text<-1> = "the indexes before you can use them!"
msg( text )
end else
fsmsg()
end
end

 

Figure 2. An example of a program that builds the index information array from information in the dictionary entry for the indexed column.

declare subroutine msg, fsmsg

msg('Rebuild index in what table?','RC', tableName, "" )
if tableName else stop
open tableName to tableHandle else
fsmsg() ; stop
end

/* open index */
bang_tableName = "!":tableName
open bang_tableName to bangTableHandle else
msg(tableName: " is not an indexed table!" ) ; stop
end

call msg('Rebuild index for what column?','RC', indexName, '')
if indexName else stop

call msg("what index type? [B/C/R]", "RC", indexType, "" )
if indexType else stop
if index( "BCR", indexType, 1 ) else
msg("not a valid index type!" ) ; stop
end

open "DICT." : tableName to @dict else
call fsmsg() ; stop
end

/* read entry from dictionary, then assemble necessary information for
indexInfo array */
read dictEntry from @dict, indexName else
call fsmsg() ; stop
end

indexInfo = ""
relationalInfo = ""

begin case
case indexType = "B"
if dictEntry<6> else
msg("%1% is not a Btree index!", '', '', indexName ) ; stop
end
indexTypeName = "Btree"
indexTypeCode = 1

case indexType = "C"
if dictEntry<22> else
msg("%1% is not a Cross reference index!", '', '', indexName ) ; stop
end
indexTypeName = "Crossreference"
indexTypeCode = 1


case indexType = "R"
if dictEntry<23> else
msg("%1% is not a Relational index", '', '', indexName ) ; stop
end
indexTypeName = "Relational"
indexTypeCode = 2
relational_info = dictEntry<23>
end case

/* fill in the rest of the index_info array using data from the
dictionary entry */

indexInfo< 1 > = indexName /* name of column &*/
indexInfo< 2 > = indexTypeName /* text of index type */
indexInfo< 3 > = relationalInfo /* null for Btree/Xref indexes */
if indexType = "C" then
indexName := "_XREF"
end
indexInfo< 4 > = indexName /* name of column */
indexInfo< 5 > = indexTypeCode /* 1=Btree/Xref, 2=Relational */

if dictEntry<1> = "F" then
indexInfo< 6 > = dictEntry< 2 > /* column position */
end else
indexInfo< 6 > = indexName /* column name */
end

indexInfo< 7 > = Not( dictEntry< 26 > ) /* case-sensitive flag */
gosub GetJustification
indexInfo< 8 > = just : sortOrder

gosub getSortDirection
indexInfo < 9 > = sortDirection

if dictEntry< 4 > = "M" then /* multivalue flag */
indexInfo< 10 > = 1
end else
indexInfo< 10 > = ""
end

convert @fm to @vm in indexInfo
call buildindex_sub( tableName, tableHandle, bangTableHandle, indexInfo, 0 )

status = status()
fe = @file.error
debug

if @file.error then
if @file.error[1,@rm] eq 421 then
msg("Process interrupted! Please rebuild indexes before using!")
end else
fsmsg()
end
end
stop

/* -------------------------------------------------------------------*/
GetJustification:
sortOrder = "L" /* default except for relational */
if indexType = "R" then
sortOrder = field( relationalInfo, "*", 3 )
if sortOrder[2,1] = "R" then
sortOrder = "R"
end else
sortOrder = "L"
end
end
just = dictEntry< 9 >
if just ne "R" then just = "L" /* make "T" and "C" into "L" */
return
/* -------------------------------------------------------------------*/
GetSortDirection:
sortDirection = "AA" /* default except for relational */
if indexType = "R" then
sortOrder = field( relationalInfo, "*", 3 )
if sortOrder = "TOP" or sortOrder[1,1] = "D" then
sortOrder = "D"
end else
sortOrder = "A"
end
sortDirection = "A" : sortOrder
end
return

EXIT_SYSTEM (parms)

text    = "Are you sure you want to quit? [Y/N]"
map     = ""
map<1>  = "RC"
map<133> = "1"     /* literal message */
map<15> = "(B)"    /* validate a Y/N  (boolean) response */
response = 0       /* default = No */

call msg( text, map, response, "" )

if response = 1 then
  displayMessage = ""      /* don't display a message */
  call exit_system( displayMessage )
end

GETCONFIGURE (parms)

declare function getconfigure
error = getconfigure( configureRecord )
if error else
  systemLevel = configureRecord< 1 >
  if systemLevel < 3.0 then
     text = "You must be using version 3.0 or higher for this process!"
     call msg( text )
     stop
  end
end else
  text = "Unable to determine the current system configuration!"
  call msg( text )
  stop
file: end

MAKEACCOUNT_SUB (Parms)

The NewList row is a list of new tables and rows to create in the new application. By default, the NEWAPPLICATIONLIST row in SYSENV is used. Each field in the list contains the name of the table to create. The first value in the field is the table name. Dictionaries must be explicitly given. The second and subsequent values are rows to create in the new table. The wildcard "*" is used to indicate that all rows from the currently attached table of the same name should be copied.

In the first value, if MFSs are to be automatically installed on the table they follow the table name and are separated by @SVM.

Examples:
MYTABLE2*
Copies all rows from the currently attached MYTABLE into the new MYTABLE in the new application.
MYTABLEnMY.MFS
Creates MYTABLE in the new application. Installs MY.MFS on the new table.

MYTABLEnMY.MFS2IMPORTANTROW
Creates MYTABLE in the new application, installing MY.MFS. Only copies in IMPORTANTROW from the currently attached MYTABLE.

INDEX.REBUILD.SUB

SUBROUTINE INDEX.REBUILD.SUB(FILE_NAME,INDEX)
*
* desc: indirectly causes an index to be rebuilt by putting the
* appropriate information into the !INDEXING file for the
* indexing system to pick up. The program is divided into
* 3 parts:
*
* 1) determine what file and field to re-index
* 2) build a "rebuild all" token to put into !INDEXING
* 3) place rebuild token at the end of the 0 record in
* !INDEXING (or, in 2.1, in !DATAFILE)
*
*---------------------------------------------------------------------------
* error return codes in STATUS()
*
* 0 = everything ok
* 1 = !INDEXING not available (Not needed in 2.1)
* 2 = "filename" is not available
* 3 = "index" is not a field or is not an indexed field
*---------------------------------------------------------------------------

DECLARE SUBROUTINE DELAY
DECLARE FUNCTION GETCONFIGURE

$INSERT SYSINCLUDE CONFIGURE.RECORD.EQUS
* init
EQU TRUE$ TO 1
EQU FALSE$ TO 0
EQU NULL$ TO ""
* error return codes for STATUS()
EQU OK$ TO 0
EQU NO_BANG_INDEXING$ TO 1 ;* Not needed in 2.1
EQU BAD_FILE$ TO 2
EQU BAD_INDEX$ TO 3
STATUS() = OK$ ;* assume ok
*-------------------
TWO_ONE = FALSE$
CONFIG = NULL$
IF GETCONFIGURE(CONFIG) THEN
    VERSION = CONFIG<SYSTEM.LEVEL$>
    IF VERSION >= 2.1 THEN
        TWO_ONE = TRUE$
    END
END

IF TWO_ONE THEN
    * 2.1 code
    OPEN "!":FILE_NAME TO BANG_INDEXING_FILE ELSE
        STATUS() = BAD_FILE$
        RETURN
    END
    * end 2.1 code
END ELSE
    * Pre 2.1 code
    OPEN '!INDEXING' TO BANG_INDEXING_FILE ELSE
        STATUS() = NO_BANG_INDEXING$
        RETURN
    END
    * end pre 2.1 code
END

OPEN FILE_NAME TO T$FILE ELSE
STATUS() = BAD_FILE$
RETURN
END

BTREE_FLAG = XLATE("DICT.":FILE_NAME, INDEX, 6, "X")
IF BTREE_FLAG ELSE
   STATUS() = BAD_INDEX$
   RETURN
END
*-------------------
* build token
* build index name/volume string out of information in FILES and VOLUMES

VOLUME_NAME = XLATE("FILES", FILE_NAME, 1, "X")
ACCOUNT_NAME = XLATE("FILES", FILE_NAME, 3, "X")
VOLUME_LABEL = XLATE("VOLUMES", VOLUME_NAME, 1, "X")
FILE_SPEC = FILE_NAME:"*":ACCOUNT_NAME:"*":VOLUME_LABEL

TOKEN = ''
TOKEN<1> = FILE_SPEC
TOKEN<2> = 1 ; * number of 'transactions' to accomplish for this file
TOKEN<3> = INDEX ; * field name
TOKEN<4> = "%%ALL.IDS%%" ; * actual rebuild/clear token
TOKEN<5> = "" ; * trailing @FMs are important
TOKEN<6> = ""
TOKEN<7> = ""
IF TWO_ONE THEN
   * If 2.1 or higher, remove the first two fields of the token.
   TOKEN = DELETE(TOKEN, 1, 0, 0)
   TOKEN = DELETE(TOKEN, 1, 0, 0)
END
*-------------------
* place token as last transaction in 0 record in !INDEXING
LOCKED_FLAG = FALSE$
LOOP
   LOCK BANG_INDEXING_FILE, "0" THEN
      LOCKED_FLAG = TRUE$
   END ELSE NULL
UNTIL LOCKED_FLAG
* try again after 2 seconds
   DELAY(2)
REPEAT

* place rebuild token at the end of the 0 record
READ ZERO_REC FROM BANG_INDEXING_FILE, "0" THEN
   IF ZERO_REC[-1,1] NE @FM THEN ZERO_REC := @FM ELSE NULL
END ELSE
   ZERO_REC = '0' : @FM
END
ZERO_REC := TOKEN
WRITE ZERO_REC ON BANG_INDEXING_FILE, "0"
UNLOCK BANG_INDEXING_FILE, "0"
RETURN


Figure 2
FILE_NAME = 'SAMPLE_CUSTOMERS'
INDEX = 'COMPANY_NAME'
CALL INDEX.REBUILD.SUB(FILE_NAME,INDEX)
IF STATUS() THEN
   TEXT = "Index rebuild subroutine failed with error %1%"
   CALL MSG(TEXT,'','',STATUS())
END ELSE
   CALL INDEX.FLUSH(FILE_NAME,INDEX)
END
STOP

REBUILDINDEX_SUB (parms)

declare subroutine rebuildindex_sub, fsmsg
declare function index.open

tablename = "PEOPLE_10000"
open tablename to datahandle else
fsmsg()
stop
end

open "DICT", tablename to @dict else
fsmsg()
stop
end

if index.open("!":tablename, indexhandle) else
fsmsg()
stop
end

fieldinfo = ""
fieldinfo<1, 1> = "AGE"
fieldinfo<1, 2> = "Btree"
fieldinfo<1, 3> = ""
fieldinfo<1, 4> = "AGE"
fieldinfo<1, 5> = 1 ;* Btree
fieldinfo<1, 6> = 4 ;* Column position
fieldinfo<1, 7> = 1 ;* Convert to Uppercase
fieldinfo<1, 8> = "RL"
fieldinfo<1, 9> = "AA"
fieldinfo<1, 10> = 0 ;* single value

fieldinfo<2, 1> = "ADDRESS"
fieldinfo<2, 2> = "CrossRef"
fieldinfo<2, 3> = ""
fieldinfo<2, 4> = "ADDRESS_XREF"
fieldinfo<2, 5> = 1 ;* Btree
fieldinfo<2, 6> = 5
fieldinfo<2, 7> = 1 ;* Convert to Uppercase
fieldinfo<2, 8> = "LL"
fieldinfo<2, 9> = "AA"
fieldinfo<2, 10> = 0 ;* single value

fieldinfo<3, 1> = "CITY"
fieldinfo<3, 2> = "Relational"
fieldinfo<3, 3> = "CITIES*PEOPLE_IN_CITY*BOT" ;* Related info
fieldinfo<3, 4> = "CITY"
fieldinfo<3, 5> = 2 ;* Relational
fieldinfo<3, 6> = 6
fieldinfo<3, 7> = 1 ;* Convert to Uppercase
fieldinfo<3, 8> = "LL"
fieldinfo<3, 9> = "AA" ;* Sort for "BOT" index
fieldinfo<3, 10> = 0 ;* single value

rebuildindex_sub(tablename, datahandle, indexhandle, fieldinfo, 0)
if @file.error then
fsmsg()
end

 

The Function of WC_RESET% in Window Processing (TB#81) The Function of WC_RESET% in Window Processing
A hurdle for programmers new to the Advanced Revelation window processor is trying to decide which WINDOW_COMMON% variables to use in which circumstances, particularly, the variable WC_RESET%. It can take one of 6 values and which value it takes depends on where it is used. Furthermore, other variables, for example WC_DISPLAY_ACTION%, seem to need WC_RESET% in some places and not others.

This Technical Bulletin explains how the window processor uses WC_RESET% to affect window processing.

To understand WC_RESET% you must first understand that the window processor is basically a loop. The window starts, then the first prompt is processed. The second prompt is processed and then the third and so on until all prompts have been processed. In fact, Window consists of loops within loops.

The Basic LOOP...UNTIL

R/BASIC supports several looping structures. FOR...NEXT is one, LOOP...UNTIL...REPEAT is another. LOOP...UNTIL is the structure used by Window.
The syntax of LOOP...UNTIL is:

LOOP
UNTIL condition is met
REPEAT

This syntax is very flexible. Additional processing statements can be placed anywhere inside the LOOP...REPEAT block. For example:

LOOP
do some processing
do more processing
UNTIL
condition is met keep on working
don't stop
REPEAT

In this example the entire loop keeps on looping until some condition is realized. When that condition is realized control jumps straight to the REPEAT statement, skipping everything between the UNTIL and the REPEAT.

Using this knowledge, a basic window loop might look like:

LOOP
process prompt
UNTIL reset
do between prompt work
REPEAT

Advanced LOOP...UNTIL

LOOP...UNTIL permits multiple exit points. For example:

LOOP
do work
UNTIL condition is met
do more work
UNTIL another condition is met
do still more work
REPEAT

This feature helps the window loop exit more gracefully. Notice that in the basic window loop above that if the between prompt work indicates that the window should quit, one more prompt must be processed before exiting the loop. If you change the loop structure you can avoid the extra processing.

LOOP
process prompt
UNTIL reset
do between prompt work
UNTIL reset
REPEAT

Now there are two ways out of the loop. In fact you are not limited to just two exit points. You can have as many as you want.

Hypothetical Window Loop

The loop for a hypothetical window processor might look like this:

LOOP
process prompt
UNTIL reset
if perpetual process
do perpetual process
end
UNTIL reset
if save flag set then
do save process
end
UNTIL reset
if delete flag set
do delete process
end
UNTIL reset
if display then
do display process
end
REPEAT

The loop quits anytime reset is true. This loop allows multiple processes the opportunity to set reset. Reset is being used as a flag to indicate that a process (the window) should stop. How can the same feature be used to stop another process? Take, for example, the save process.

Resetting a Save Process

The save process (in the hypothetical window loop) should allow for a presave process. If the user wants to avoid the save they should set reset. One way to implement this is like this:

save process:
if presave process then
do presave process
if reset else
do save
end
end else
do save
end

This is cumbersome for two reasons. First, the actual save routine is duplicated. Second, if the save is cancelled so is the window because reset is never set back to false. What you need is a way to indicate that the save process should be cancelled, but not the window. You also need a way to indicate that both the save process and the window should be cancelled.

A simple approach would be to say, "1 means cancel the save, 2 means cancel the save and the window". This approach is too simple and it makes extension of the use of reset difficult. It makes all of the checks in the main loop look for a particular value. It also does not help the save process avoid duplicating code.

If you change the way you use the code it gets easier. For example:

save process:
if presave process then
do presave process
end
if reset then
if reset <= 1 then
reset = ""
end else
reset -= 1
end
end else
do save
end

This approach uses the same value for reset as originally outlined, but makes it easier to write clean code. The presave process is completely encapsulated inside one IF...THEN block and the save code is not duplicated. Walking through the if reset section will show that the reset values produce the required results:

_ If reset is non-null (true) the then branch is taken. Otherwise the else branch is taken. It is only in the else branch that the save code is executed, so setting reset to 1 or 2 will prevent the save, which is what was intended.

_ In the then branch the value of reset is checked. If it is less than or equal to 1 reset is set to null. This means that when control returns to the main loop reset is not true and the window is not cancelled. If, on the other hand, reset is greater than 1, (in this case 2) subtract 1 from reset. When control returns to the main loop reset is true and the window is cancelled.

Prompt Processing

Prompt processing, unlike the save process examined above, is itself a loop. In the hypothetical window it would be desirable to have the same editor used in all conditions and to have some fancy features like popups and softkeys. All of this can be done by using a loop.

The simple solution is to call an editor until the editor is done and then pass control back to the main loop. For example:

LOOP
call editor
UNTIL done
REPEAT

This structure is both too complex and too simple. It assumes that the editor will handle all the desired features (like popups and softkeys). If that is the case then the editor should be called for the prompt and no loop is needed for when it returns control the prompt has been processed and the main loop can continue.

This is not a bad strategy if you don't mind burdening the editor with window specific functions. However, you might want to use the editor outside the window as well. A better strategy would be to define special keystrokes that the editor would recognize mean "give control back to the window processor". The window processor could then examine which key was pressed and act accordingly. With this strategy the prompt loop might look like this:

LOOP
editor(exitkeys, lastkey)
process lastkey
UNTIL reset
REPEAT

In this loop the process lastkey routine is like the save process above it can set reset. But this loop has the same failing as the original save process, if reset is set, the window is cancelled. There is also no preprompt processing. A better prompt processing loop looks like:

process prompt:
if preprompt then
perform preprompt
if reset then
if reset <= reset_edit$ then
reset = ""
end else
reset -= 1
end
end
end
if reset else
loop
editor(exitkeys, lastkey)
process lastkey
until reset
repeat
if reset <= reset_edit$ then
reset = ""
end else
reset -= 1
end
end

Notice how the same strategy is used here to deal with the reset codes as was used in the save process.

Summary

Refer to the original window loop, above. Note that the display action is evaluated at a specific point in the loop (the actual point is somewhat different in the real Window). In order to get the display action evaluated you must get to that point. If a prompt is being processed how do you get there? You must set reset to a value high enough to get control out of the prompt processing loop.

To set reset you need to invoke a special keystroke. Maybe [F2] or a softkey; any keystroke that the editor recognizes as significant so it returns control to the window processor. If your program doesn't set reset high enough the edit loop is not exited. Note that there is no need to set reset if control is passing out of the prompt normally.

Window

How does this hypothetical window processor compare to Window? Figure 1 is pseudo code that shows the flow of the main window loop, emphasizing the role of WC_RESET%. Figure 2 is the pseudo code for I/O processing, while Figure 3 shows prompt processing.

WC_RESET% can take the values in the following table. Use these values as you trace through the pseudo code.

Value Mnemonic

1 CLEAN.UP.LINE$
2 CLEAN.UP.EDIT$
3 RESET.EDIT$
4 RESET.PROMPT$
5 RESET.RECORD$
6 RESET.WINDOW$

Window Flow

As Figure 1 shows, if WC_RESET% is still set after the prompt is processed the perpetual process is not executed. Since most windows do not have a perpetual process there is usually no practical difference between setting WC_RESET% to RESET.PROMPT$ or setting it to RESET.RECORD$ from a prompt process.

Notice that after every possible "hook" the system checks for WC_RESET%. This means that setting WC_RESET% to RESET.WINDOW$ from any process will quickly cancel the window.

The window processor also checks for WC_DISPLAY_ACTION% after all hooks, making it easy for you to affect window display.

I/O Processing

Figure 2 shows the basic flow followed by read, write, and delete processing. Note that all WC_RESET% values less than RESET.RECORD$ have the same effect on window flow. To have an impact on window flow from an I/O process you must use RESET.RECORD$ or, to leave your window, RESET.WINDOW$.

Prompt Flow

Figure 3 shows the flow of control through a prompt. Careful study of the pseudo code will show that from a preprompt process you must set WC_RESET% to at least RESET.PROMPT$ to force the system to leave the prompt.

From the Options key or from Softkeys you must set WC_RESET% to at least RESET.EDIT$ to force the system to leave the prompt. Note that if you set WC_RESET% to CLEAN.UP.LINE$ or CLEAN.UP.EDIT$ you do not leave the prompt.

CLEAN.UP.LINE$ and CLEAN.UP.EDIT$ are used by the window processor to ensure that edit checks are done. Using these values in your programs will have no effect.
Edit Checks As you can see in Figure 3, one of the parameters passed to SCRIBE is the edit patterns used by the prompt (WC_SI%<VINP>). SCRIBE will, in turn, call IN.VALUE to validate your input. This processing is important in two ways.
First, it explains why your custom edit checks will find the input data in @ANS. SCRIBE and IN.VALUE are independent routines. They are not window specific and cannot use the window common variables. In order to pass data to your routine, @ANS, and not WC_IS% must be used.

Second, because SCRIBE can be interrupted before the edit checks have been done, there must be a way to call SCRIBE and tell it to process the data through the edit checks. This is the function of CLEAN.UP.LINE$ and CLEAN.UP.EDIT$.

Depending on when processing was interrupted and whether there are edit checks, the system will use WC_RESET% to set flags in WC_SCRIBE_FLAGS%. These flags will be used by SCRIBE when it is called again to determine what action to take.

Figure 1

LOOP
process prompt
IF WC_RESET% THEN
WC_RESET% -= 1
END ELSE
do perpetual process
END
UNTIL WC_RESET%
IF WC_AMV_ACTION% THEN do amv process
IF WC_JOINED_KEYS% THEN do join process
IF WC_DISPLAY_ACTION% THEN do display process
IF WC_SAVE_REC% THEN
do save process
IF WC_DISPLAY_ACTION% THEN do display process
END
UNTIL WC_RESET%
IF WC_DELETE_REC% THEN
do delete process
IF WC_DISPLAY_ACTION% THEN do display process
END
UNTIL WC_RESET%
IF WC_MV_NEXT% THEN adjust position in amv
IF WC_NEW_DATAFILE% THEN do new datafile process
IF WC_NEW_BROWSE% THEN do new browse list process
IF WC_RING_NEXT% THEN adjust browse list pointer
IF WC_NEW_ID% THEN
do read process
IF WC_DISPLAY_ACTION% THEN do display process
END
UNTIL WC_RESET%
IF WC_WI_NEXT% THEN adjust prompt cursor is on
IF WC_WINDOW_ACTION% THEN pan/resize/move
REPEAT

Figure 2

IF preprocess THEN
do preprocess
IF WC_RESET% <= RESET.PROMPT$ THEN
WC_RESET% = ""
END ELSE
WC_RESET% -= RESET.PROMPT$
END
END

IF WC_RESET% THEN
WC_RESET% -= 1
END ELSE
IF replace process THEN
do replace process
IF WC_RESET% <= RESET.PROMPT$ THEN
WC_RESET% = ""
END ELSE
WC_RESET -= RESET.PROMPT$
END
END ELSE
do i/o
END
IF WC_RESET% THEN
WC_RESET% -= 1
END ELSE
IF postprocess THEN
do postprocess
IF WC_RESET% <= RESET.PROMPT$ THEN
WC_RESET% = ""
END ELSE
WC_RESET% -= RESET.PROMPT$
END
END
IF WC_RESET% THEN
WC_RESET -= 1
END ELSE
do work
END
END
END

Figure 3

prompt:
IF WC_SI%<PRE.CODE> THEN
do preprompt process
IF WC_RESET% <= RESET.EDIT$ THEN
WC_RESET% = ""
END ELSE
WC_RESET% -= 1
END
END

IF WC_RESET% ELSE
LOOP
WC_VALID% = TRUE$
LOOP
LOOP
SCRIBE(WC_IS%, WC_WEXIT_KEYS%, WC_WC%, WC_SI%<VINP>........)
UNTIL WC_RESET% ;* clean.up.line$
WHILE WC_WC%
IF WC_DISPLAY_ACTION% THEN
do display action
END
check wc_wc% ;* process popups, softkeys etc
UNTIL WC_RESET% ;* clean.up.line$
REPEAT
IF WC_WC% THEN
IF WC_RESET% THEN
WC_RESET% -= 1
IF WC_RESET% > 1 THEN
WC_RESET% -= 1
END ELSE
adjust scribe state so edit check gets done
END
END
END ELSE
WC_RESET% = 1
END
UNTIL WC_RESET% ;* clean.up.edit$
REPEAT
WC_RESET% -= 1
UNTIL WC_RESET% ;* reset.prompt$
IF WC_SI%<POST.CODE> THEN
do postprompt process
IF WC_RESET% <= RESET.EDIT$ THEN
WC_RESET% = ""
END ELSE
WC_RESET% -= RESET.EDIT$
END
END
UNTIL WC_VALID%
UNTIL WC_RESET%
REPEAT
END
IF WC_RESET% THEN
WC_RESET% -= 1
WC_IS% = WC_IS_ORIG%
END
RETURN

Revelation , Advanced Revelation , AREV and Open Insight are trademarks of Revelation Technologies, Inc.   All other products mentioned are registered trademarks or trademarks of their respective companies.

Questions or problems regarding this web site should be directed to the WebMaster.
Copyright © 2000 TARDIS Systems . All rights reserved..