The MAIN block / function

The MAIN block is the starting point of the program.

Syntax 1 (MAIN / END MAIN)

MAIN
    [ local-declaration
        [...]
    ]
    instruction
    [...]
END MAIN
  1. local-declaration is a DEFINE, CONSTANT or TYPE instruction.
  2. instruction is a language statement.

Syntax 2 (FUNCTION main())

FUNCTION main()
    [ local-declaration
        [...]
    ]
    instruction
    [...]
END FUNCTION
  1. local-declaration is a DEFINE, CONSTANT or TYPE instruction.
  2. instruction is a language statement.

Usage

A Genero program starts in the MAIN block, to perform the instructions defined in this block.

Important: If a DATABASE instruction was specified (for the compilation DB schema) before the MAIN / END MAIN block, an implicit connection will occur in MAIN. For more details see the SCHEMA instruction.
The MAIN block typically consists of:
  1. The signal handling instructions DEFER INTERRUPT and DEFER QUIT,
  2. The exception handling instruction WHENEVER ERROR CALL,
  3. Global runtime configuration settings with the OPTIONS instruction,
  4. A database connection with the CONNECT TO or DATABASE instruction,
  5. In an interactive program, a call to a function implementing the main dialog instruction controlling the main form.
The MAIN / END MAIN block must appear before any other FUNCTION / END FUNCTION block:
IMPORT FGL cust_module
MAIN
    DEFINE uname, upswd STRING
    DEFER INTERRUPT
    DEFER QUIT
    OPTIONS FIELD ORDER FORM, INPUT WRAP,
            SQL INTERRUPT ON, HELP FILE "myhelp"
    CALL get_login() RETURNING uname, upswd
    TRY
        CONNECT TO "stores" USER uname USING upswd
    CATCH
        IF SQLCA.SQLCODE < 0 THEN
           DISPLAY "Error: Could not connect to database."
           EXIT PROGRAM 1
        END IF
    END TRY
    CALL cust_module.customer_input()
END MAIN

FUNCTION show_help()
    DISPLAY "Usage: ..."
END FUNCTION

FUNCTION main()

The MAIN block can also be defined as a regular function with FUNCTION main() / END FUNCTION.

In fact a MAIN / END MAIN block is equivalent to FUNCTION main() / END FUNCTION (returning no values), except that with a MAIN block, an implicit database connection is performed, if the DATABASE instruction is used before MAIN / END MAIN, to define the compilation database schema (the implicit database connection does not occur, when using the SCHEMA instruction).

The FUNCTION main() is very useful, when the main block must be defined after other functions, for example when using function references where functions must be declared before they are referenced:

TYPE t_func FUNCTION (p1 INT, p2 INT) RETURNS INT

FUNCTION add(p1 INT, p2 INT) RETURNS INT
    RETURN p1 + p2
END FUNCTION

FUNCTION sub(p1 INT, p2 INT) RETURNS INT
    RETURN p1 - p2
END FUNCTION

FUNCTION main()
    DEFINE op t_func
    LET op = FUNCTION add
    DISPLAY op( 5, 10 )
    LET op = FUNCTION sub
    DISPLAY op( 5, 10 )
END FUNCTION

Defining MAIN in imported modules

When using IMPORT FGL (that is, when not linking programs), a MAIN block or main() function can be defined in the imported modules.

This allows for example to write unit tests in the same source module.

File math.4gl:

MAIN
    DEFINE
        p1 INT = 6,
        p2 INT = 9,
        res INT

    DISPLAY "Unit testing add (", p1, " , ", p2, ")"
    LET res = add(p1, p2)
    IF res = 15 THEN
        DISPLAY " PASSED"
    ELSE
        DISPLAY " FAILED"
    END IF
END MAIN

PUBLIC FUNCTION add(p1 INT, p2 INT) RETURNS INT
    RETURN p1 + p2
END FUNCTION
File main.4gl:
IMPORT FGL math
MAIN
    DISPLAY math.add(5, 4)
END MAIN
Compiling and running both modules:
$ fglcomp math.4gl
$ fglrun math.42m
Unit testing add (          6 ,           9)
 PASSED
$ fglcomp main.4gl
$ fglrun main.42m
          9