Summary:
See also: Compiling Programs, Preprocessor, Database Schema Files, Flow Control, The Application class, Localized Strings.
You can control the behavior of the runtime system with some FGLPROFILE configuration parameters.
Dialog.fieldOrder = {true|false}
When this parameter is set to true, intermediate triggers are executed. As the user moves to a new field with a mouse click, the runtime system executes the BEFORE FIELD / AFTER FIELD triggers of the input fields between the source field and the destination field. When the parameter is set to false, intermediate triggers are not executed.
For new applications, it is recommended that you set the parameter to false. GUI applications allow users to jump from one field to any other field of the form by using the mouse. Therefore, it makes no sense to execute the BEFORE FIELD / AFTER FIELD triggers of intermediate fields.
Important note: The default setting for the runtime system is false; while the default
setting in FGLPROFILE for Dialog.fieldOrder
is true. As a result, the
overall setting after installation is true. To modify the behavior of
intermediate field trigger execution, change the setting of Dialog.fieldOrder
in FGLPROFILE to false.
Dialog.fieldOrder
configuration parameter is ignored when the dialog uses the FIELD
ORDER FORM option.Dialog.currentRowVisibleAfterSort = {true|false}
When this parameter is set to true, the offset of table page is automatically adapted to show the current row after a sort. By default, the offset is not changed and current row may not be visible after sorting rows of a table. Changing this parameter has no impact on existing code, it is just an indicator to force the dialog to shift to the page of rows having the current row, as if the end-user had scrollbar. You can use this parameter to get the same behavior as well known e-mail readers.
The MAIN block is the starting point of the application. When the runtime system executes a program, after some initialization, it gives control to this program block.
MAIN
[ define-statement | constant-statement ]
{ [defer-statement] | fgl-statement | sql-statement }
[...]
END MAIN
The DEFER instruction allows you to control the behavior of the program when an interruption or quit signal has been received.
DEFER { INTERRUPT | QUIT }
When an interrupt signal is caught by the runtime system and DEFER INTERRUPT is used, the INT_FLAG global variable is set to TRUE by the runtime system.
Interrupt signals are raised on terminal consoles when the user presses a key like CTRL-C, depending on the stty configuration. When a BDL program is displayed through a front end, no terminal console is used; therefore, users cannot send interrupt signals with the CTRL-C key. To send an interruption request from the front end, you must define an 'interrupt' action view. For more details, refer to Interruption Handling in the Dynamic User Interface.
DEFER QUIT indicates that the program must continue when it receives a quit signal. By default, the program stops when it receives a quit signal.
When a quit signal is caught by the runtime system and DEFER QUIT is used, the QUIT_FLAG global variable is set to TRUE by the runtime system.
STATUS is a predefined variable that contains the execution status of the last instruction.
STATUS
DEFINE STATUS INTEGER
01
MAIN02
DEFINE n INTEGER03
WHENEVER ANY ERROR CONTINUE04
LET n = 10/005
DISPLAY STATUS06
END MAIN
INT_FLAG is a predefined variable that is automatically set to TRUE when the user presses the interruption key.
INT_FLAG
DEFINE INT_FLAG INTEGER
01
MAIN02
DEFINE n INTEGER03
DEFER INTERRUPT04
LET INT_FLAG = FALSE05
FOR n = 1 TO 100006
IF INT_FLAG THEN EXIT FOR END IF07
...08
END FOR09
END MAIN
QUIT_FLAG is a predefined variable that is automatically set to TRUE when a 'quit event' arrives.
QUIT_FLAG
DEFINE QUIT_FLAG INTEGER
01
MAIN02
DEFER QUIT03
LET QUIT_FLAG = FALSE04
INPUT BY NAME ...05
IF QUIT_FLAG THEN06
...07
END IF08
END MAIN
The IMPORT instruction declares a C extension to be used by the current module.
IMPORT filename [,...]
The IMPORT instruction must be used to declare a C extension implementing functions or variables used by the current module.
Modules declared with the IMPORT instruction do not have to be linked to create a program. The runtime system automatically loads dependent modules.
The FGLLDPATH environment variable specifies the directories to search for the modules.
By default, the runtime system tries to load a module with the name userextension, if it exists. This simplifies the migration of existing C extensions; you just need to create a shared library named userextension.so (or userextension.dll on Windows), and copy the file to one of the directories defined in FGLLDPATH.
01
IMPORT mylib1, mylib202
DEFINE filename STRING03
MAIN04
CALL func1() -- function defined in mylib105
END MAIN
See also: C Extensions.
The OPTIONS instruction allows you to change default program options.
OPTIONS
{ INPUT [NO] WRAP
| HELP FILE help-filename
| INPUT ATTRIBUTE ( {FORM|WINDOW|input-attributes}
)
| DISPLAY ATTRIBUTE ( {FORM|WINDOW|display-attributes} )
| SQL INTERRUPT {ON|OFF}
| FIELD ORDER {CONSTRAINED|UNCONSTRAINED|FORM}
| ON TERMINATE SIGNAL CALL user-function
| ON CLOSE APPLICATION {CALL user-function|STOP}
| RUN IN {FORM|LINE} MODE
| MESSAGE LINE line-value
TUI Only!
| COMMENT LINE {OFF|line-value}
TUI
Only!
| PROMPT LINE line-value
TUI Only!
| ERROR LINE line-value
TUI Only!
| FORM LINE line-value
TUI Only!
| INSERT KEY key-name
TUI Only!
| DELETE KEY key-name
TUI Only!
| NEXT KEY key-name
TUI Only!
| PREVIOUS KEY key-name
TUI Only!
| ACCEPT KEY key-name
TUI Only!
| HELP KEY key-name
TUI Only!
} [,...]
A program can include several OPTIONS statements. If these statements conflict in their specifications, the OPTIONS statement most recently encountered at runtime prevails. OPTIONS can specify the following features of other statements (such as CONSTRUCT, DISPLAY, DISPLAY ARRAY, DISPLAY FORM, ERROR, INPUT, INPUT ARRAY, MESSAGE, OPEN FORM, OPEN WINDOW, PROMPT and RUN ):
The following options define the positions of reserved lines in TUI mode. Is it not recommended that you use these options in GUI mode, as most have no effect on the display.
You can specify any of the following positions for each reserved line:
Expression | Description |
FIRST | The first line of the screen or window. |
FIRST + integer | A relative line position from the first line. |
integer | An absolute line position in the screen or window. |
LAST - integer | A relative line position from the last line. |
LAST | The last line of the screen or window. |
Any attribute defined by the OPTIONS statement remains in effect until the runtime system encounters a statement that redefines the same attribute. This can be another OPTIONS statement, or an ATTRIBUTE clause in one of the following statements:
The ATTRIBUTE clause in these statements only redefines the attributes temporarily. After the window closes (in the case of an OPEN WINDOW statement) or after the statement terminates (in the case of a CONSTRUCT, INPUT, DISPLAY, DIALOG, INPUT ARRAY, or DISPLAY ARRAY statement), the runtime system restores the attributes from the most recent OPTIONS statement.
The FORM keyword in INPUT ATTRIBUTE or DISPLAY ATTRIBUTE clauses instructs the runtime system to use the input or display attributes of the current form. Similarly, you can use the WINDOW keyword of the same clauses to instruct the program to use the input or display attributes of the current window. You cannot combine the FORM or WINDOW attributes with any other attributes.
The following table shows the valid input-attributes and display-attributes:
Attribute | Description |
BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, WHITE, YELLOW | The color of the displayed text. |
BOLD, DIM, INVISIBLE, NORMAL | The font attribute of the displayed text. |
REVERSE, BLINK, UNDERLINE | The video attribute of the displayed text. |
The tab order in which the screen cursor visits fields of a form is that of the field list of currently executing CONSTRUCT, INPUT, and INPUT ARRAY statements, unless the tab order has been modified by a NEXT FIELD clause. By default, the interactive statement terminates if the user presses RETURN in the last field (or if the entered data fills the last field and that field has the AUTONEXT attribute).
The INPUT WRAP keywords change this behavior, causing the cursor to move from the last field to the first, repeating the sequence of fields until the user presses the Accept key. The INPUT NO WRAP option restores the default input loop behavior.
The OPTIONS ON TERMINATE SIGNAL CALL function defines the function that must be called when the application receives the SIGTERM signal. With this option, you can control program termination - for example, by using ROLLBACK WORK to cancel all pending SQL operations. If this statement is not called, the program is stopped with an exit value of SIGTERM (15).
On Microsoft Windows platforms, the function will be called in the following cases:
The OPTIONS ON CLOSE APPLICATION CALL function can be used to execute specific code when the front-end stops. For example, when the client program is stopped, when the user session is ended, or when the workstation is shut down.
Before stopping, the front-end sends a internal event that is trapped by the runtime system. When a callback function is specified with the above program option command, the application code that was executing is canceled, and the callback function is executed before the program stops.
You typically do a ROLLBACK WORK, close all files, and release all resources in that function.
The default is OPTIONS ON CLOSE APPLICATION STOP. This instructs the runtime system to stop without any error message if the front end program is stopped.
Note that a front-end program crash or network failure is not detected and cannot be handled by this instruction.
The HELP FILE clause specifies an expression that returns the filename of a help file. This filename can also include a pathname. Messages in this file can be referenced by number in form-related statements, and are displayed at runtime when the user presses the Help key.
By default, message files are searched in the current directory, then DBPATH environment variable is scanned to find the file.
See also Message Files.
In an INPUT, INPUT ARRAY or CONSTRUCT, by default, the tabbing order is defined by the list of fields used by the program instruction. This corresponds to FIELD ORDER CONSTRAINED.
When using FIELD ORDER UNCONSTRAINED, the UP ARROW and DOWN ARROW keys will move the cursor to the field above or below, respectively. Use the FIELD ORDER CONSTRAINED option to restore the default behavior of the UP ARROW and DOWN ARROW keys (moving the cursor to the previous or next field, respectively).
Warning: The UNCONSTRAINED option can only be supported in TUI mode, with a simple form layout. It is not recommended to use this option: it is supported for backward compatibility only.
When you specify FIELD ORDER FORM, the tabbing order is defined by the TABINDEX attributes of the current form fields. This allows you to define a tabbing order specific to the layout of the form, independent of the program instruction:
Form file:
01
LAYOUT02
GRID03
{04
First name: [f001 ]05
Last name: [f002 ]06
}07
END08
END09
ATTRIBUTES10
EDIT f001 = FORMONLY.fname, TABINDEX = 1;11
EDIT f002 = FORMONLY.lname, TABINDEX = 2;12
END
Program file:
01
MAIN02
DEFINE fname, lname CHAR(20)03
OPTIONS FIELD ORDER UNCONSTRAINED04
OPEN FORM f1 FROM "f1"05
DISPLAY FORM f106
INPUT BY NAME fname, lname07
END MAIN
The OPTIONS instruction can specify physical keys to support logical key functions in the interactive instructions.
Warning: The physical key definition options
are only
provided for backward compatibility with the character mode. These as not
supported in GUI
mode. Use the Action
Defaults to define accelerator keys for actions.
In TUI mode,
action defaults accelerators are ignored.
Description of the keys:
You can specify the following keywords for the physical key names:
Key Name | Description |
ESC or ESCAPE | The ESC key (not recommended, use ACCEPT instead). |
INTERRUPT | The interruption key (on UNIX, interruption signal). |
TAB | The TAB key (not recommended). |
CONTROL-char | A control key where char can be any character except A, D, H, I, J, K, L, M, R, or X |
F1 through F255 | A function key. |
LEFT | The left arrow key. |
RETURN or ENTER | The return key. |
RIGHT | The right arrow key. |
DOWN | The down arrow key. |
UP | The up arrow key. |
PREVIOUS or PREVPAGE | The previous page key. |
NEXT or NEXTPAGE | The next page key. |
You might not be able to use other keys that have special meaning to your version of the operating system. For example, CONTROL-C, CONTROL-Q, and CONTROL-S specify the Interrupt, XON, and XOFF signals on many UNIX systems.
When using character terminals, BDL recognizes two screen display modes: line mode (IN LINE MODE) and formatted mode (IN FORM MODE). The OPTIONS and RUN statements can explicitly specify a screen mode. The OPTIONS statement can set separate defaults for these statements.
After IN LINE MODE is specified, the terminal is in the same state (in terms of stty options) as when the program began. This usually means that the terminal input is in cooked mode, with interruption enabled, and input not available until after a newline character has been typed.
The IN FORM MODE keywords specify raw mode, in which each character of input becomes available to the program as it is typed or read.
By default, a program operates in line mode, but so many statements take it into formatted mode (including OPTIONS statements that set keys, DISPLAY, OPEN WINDOW, DISPLAY FORM, and other screen interaction statements), that typical programs are actually in formatted mode most of the time.
When the OPTIONS statement specifies RUN IN FORM MODE, the program remains in formatted mode if it currently is in formatted mode, but it does not enter formatted mode if it is currently in line mode.
When the OPTIONS statement specifies RUN IN LINE MODE, the program remains in line mode if it is currently in line mode, and it switches to line mode if it is currently in formatted mode.
The RUN instruction creates a new process and executes the command passed as an argument.
RUN command
[ IN {FORM|LINE} MODE ]
[ RETURNING variable | WITHOUT WAITING ]
The RUN instruction executes an operating system command line; you can even run a second application as a secondary process. When the command terminates, the runtime system resumes execution.
Defining the command execution shell
In order to execute the command line, the RUN instruction uses the OS-specific shell defined in the environment of the current user. On UNIX, this is defined by the SHELL environment variable. On Windows, this is defined by COMSPEC. Note that on Windows, the program defined by the COMSPEC variable must support the /c option as CMD.EXE.
Waiting for the sub-process
By default, the runtime system waits for the end of the execution of the command.
Unless you specify WITHOUT WAITING, the RUN instruction also does the following:
If you specify WITHOUT WAITING, the specified command line is executed as a background process, and generally does not affect the visual display. This clause is useful if you know that the command will take some time to execute, and your program does not need the result to continue. It is also used in GUI mode to start another Genero program. In TUI mode, you must not use this clause because two programs cannot run simultaneously on the same terminal.
Catching the execution status
The RETURNING clause saves the termination status code of the command that RUN executes in a program variable of type SMALLINT. You can then examine this variable in your program to determine the next action to take. A status code of zero usually indicates that the command has terminated normally. Non-zero exit status codes usually indicate that an error or a signal caused execution to terminate.
On Unix systems, the lower byte (x mod 256) of the return status defines the termination status of the RUN command. The higher byte (x / 256) of the return status defines the execution status of the program. On Windows systems, the value of the return status defines the execution status of the program.
IN LINE MODE and IN FORM MODE
By default, programs operate in LINE MODE, but as many statements take it into FORM MODE (including OPTIONS statements that set keys, DISPLAY, OPEN WINDOW, DISPLAY FORM, and other screen interaction statements), typical programs are actually in FORM MODE most of the time.
According to the type of command to be executed, you may need to use the IN {LINE|FORM} MODE clause with the RUN instruction. It defines how the terminal or the graphical front-end behaves when running the child process.
Besides RUN, the OPTIONS, START REPORT, and REPORT statements can explicitly specify a screen mode. If no screen mode is specified in the RUN command, the current value from the OPTIONS statement is used. This is, by default, IN LINE MODE. The default screen mode for PIPE specifications in REPORT is IN FORM MODE.
When the RUN statement specifies IN FORM MODE, the program remains in form mode if it is currently in form mode, but it does not enter form mode if it is currently in line mode. When the prevailing RUN option specifies IN LINE MODE, the program remains in line mode if it is currently in line mode, and it switches to line mode if it is currently in form mode. This also applies to the PIPE option.
Typically, if you need to run another interactive program, you must use the IN LINE MODE clause:
However, if you want to execute a sub-process running silently (batch program without output), you must use the IN FORM MODE clause:
It is recommended that you use functions to encapsulate child program and system command execution:
01
MAIN02
DEFINE result SMALLINT03
CALL runApplication("app2 -p xxx")04
CALL runBatch("ls -l", FALSE) RETURNING result05
CALL runBatch("ls -l > /tmp/files", TRUE) RETURNING result06
END MAIN07
08
FUNCTION runApplication(pname)09
DEFINE pname, cmd STRING10
LET cmd = "fglrun " || pname11
IF fgl_getenv("FGLGUI") == 1 THEN12
RUN cmd WITHOUT WAITING13
ELSE14
RUN cmd15
END IF16
END FUNCTION17
18
FUNCTION runBatch(cmd, silent)19
DEFINE cmd STRING20
DEFINE silent STRING21
DEFINE result SMALLINT22
IF silent THEN23
RUN cmd IN FORM MODE RETURNING result24
ELSE25
RUN cmd IN LINE MODE RETURNING result26
END IF27
IF fgl_getenv("OS") MATCHES "Win*" THEN28
RETURN result29
ELSE30
RETURN ( result / 256 )31
END IF32
END FUNCTION
The EXIT PROGRAM instruction terminates the execution of the program.
EXIT PROGRAM [ exit-code ]
01
MAIN02
DISPLAY "Emergency exit."03
EXIT PROGRAM (-1)04
DISPLAY "This will never be displayed !"05
END MAIN
Database Schema Specification identifies the database schema files to be used for compilation.
SCHEMA dbname
[DESCRIBE] DATABASE dbname
01
SCHEMA dbdevelopment -- Compilation database schema02
DEFINE rec RECORD LIKE customer.*03
MAIN04
DATABASE dbproduction -- Runtime database specification05
SELECT * INTO rec.* FROM customer WHERE custno=106
END MAIN
The NULL constant is provided as "nil" value.
NULL
01
MAIN02
DEFINE s CHAR(5)03
LET s = NULL04
DISPLAY "s IS NULL evaluates to:"05
IF s IS NULL THEN06
DISPLAY "TRUE"07
ELSE08
DISPLAY "FALSE"09
END IF10
END MAIN
The TRUE constant is a predefined boolean value that evaluates to 1.
TRUE
01
MAIN02
IF FALSE = TRUE THEN03
DISPLAY "Something wrong here"04
END IF05
END MAIN
The FALSE constant is a predefined boolean value that evaluates to 0.
FALSE
01
FUNCTION isodd( value )02
DEFINE value INTEGER03
IF value MOD 2 = 1 THEN04
RETURN TRUE05
ELSE06
RETURN FALSE07
END IF08
END FUNCTION
The NOTFOUND constant is a predefined integer value that evaluates to 100.
NOTFOUND
01
MAIN02
DATABASE stores03
SELECT tabid FROM systables WHERE tabid = 104
IF SQLCA.SQLCODE = NOTFOUND THEN05
DISPLAY "No row was found"06
END IF07
END MAIN
The BREAKPOINT instruction sets a program breakpoint when running in debug mode.
BREAKPOINT
When you start fglrun in debug mode, if the program flow encounters a BREAKPOINT instruction, the program execution stops and the debug prompt is displayed, to let you enter a debugger command.
The BREAKPOINT instruction is ignored when not running in debug mode.
01
MAIN02
DEFINE i INTEGER03
LET i=12304
BREAKPOINT05
DISPLAY i06
END MAIN
This feature allows you to define the labels of keys, to show a specific text in the default action button created for the key.
key.key-name.text = "label"
CALL FGL_SETKEYLABEL( "key-name", "label"
)
KEYS
key-name = "label"
[...]
[END]
CALL FGL_DIALOG_SETKEYLABEL( "key-name", "label"
)
KEY key-name = "label"
Traditional 4GL applications use a lot of function keys and/or control keys to manage user actions. For example, in the following interactive dialog, the function key F10 is used to show a detail window:
01
INPUT BY NAME myrecord.*02
ON KEY (F10)03
CALL ShowDetail()04
END INPUT
For backward compatibility, the language allows you to specify a label to be displayed in a default action button created specifically for the key.
By default, if you do not specify a label, no action button is displayed for a function key or control key.
The following table shows the key names recognized by the runtime system:
Key Name | Description |
f1 to f255 | Function keys. |
control-a to control-z | Control keys. |
accept | Validation key. |
interrupt | Cancellation key. |
insert | The insert key when in an INPUT ARRAY. |
delete | The delete key when in an INPUT ARRAY. |
help | The help key. |
You can define key labels at different levels, from the default settings to a specific field, to show a specific label for the key when the focus is in that field. The order of precedence for key label definition is the following:
You can query the label defined at the program level with the FGL_GETKEYLABEL function and, for the current interactive instruction, with the FGL_DIALOG_GETKEYLABEL function.
On Windows platforms, when the user disconnects, the system sends a CTRL_LOGOFF_EVENT event to all console applications. When the DVM receives this event, it stops immediately (a simple exit(0) system call is done).
On a Windows Terminal Server, if an Administrator user closes his session, a CTRL_LOGOFF_EVENT is sent to all console applications started by ANY user connected to the machine (even if these applications were not started by the Administrator).
To prevent the DVM from stopping on a logoff event, you can use the fglrun.ignoreLogoffEvent entry in the FGLPROFILE configuration file. If this entry is set to true, the CTRL_LOGOFF_EVENT event is ignored by the DVM.
fglrun.ignoreLogoffEvent = true
As a result, when the Administrator user disconnects on a Windows Terminal Server, programs started by remote users would not stop.