Code beautifier tool usage

This topic describes how to use the code beautifier tool.

Using the code beautifier of fglcomp

The code beautifier is a feature of the fglcomp compiler which is enabled with the --format option:

$ fglcomp --format module.4gl

Several formatting --fo-* options are available and explained below.

Note: The code beautifier supports uppercase or lowercase keyword coding conventions. See the --fo-lowercase-keywords option usage for more details.

Using a configuration file

All --fo-* formatting options except --fo-inplace can be specified in a configuration file named .fgl-format.

This configuration file is typically placed in the top directory of your project, to apply the same formatting rules to all sources located under this root directory:
$ tree -a .
.
`-- top
    |-- .fgl-format
    |-- app1
    |   `-- main.4gl
    `-- lib
        `-- myutils.4gl
3 directories, 3 files

$ cd top

$ cat .fgl-format 
--fo-indent-width=5
--fo-pack=1

$ cd lib

$ fglcomp --format myutils.4gl 
PRIVATE DEFINE debug_level SMALLINT
FUNCTION set_debug_level(l SMALLINT)
     LET debug_level = l
END FUNCTION

Controlling the beautifier result output

By default, the reformatted source is written to the standard output stream (stdout).

To overwrite the original source file, use the --fo-inplace option:
$ fglcomp --format --fo-inplace module.4gl

Before reformatting the source file with the --fo-inplace option, fglcomp creates a copy of the original source file, by adding a tilde character after the .4gl file extension: filename.4gl~.

Note: The --fo-inplace option cannot be used in the .fgl-format configuration file.

Defining the maximum width for a source code line

Use the --fo-column-limit=cols option to specify the width limit for a source code line:

$ cat module.4gl
PUBLIC FUNCTION update_customer( id INTEGER, name VARCHAR(50) )
    UPDATE customer SET cust_name = name WHERE cust_id = id AND cust_valid = 'Y'
END FUNCTION

$ fglcomp --format --fo-column-limit=40 module.4gl
PUBLIC FUNCTION update_customer(
    id INTEGER, name VARCHAR(50))
    UPDATE customer
        SET cust_name = name
        WHERE cust_id = id
            AND cust_valid = 'Y'
END FUNCTION

The default is 80.

Defining the base indentation width

The --fo-indent-width=cols option can be used to set width for base indentations:

$ cat module.4gl
PUBLIC FUNCTION cleanup( mode INTEGER )
CASE
 WHEN mode==1 DISPLAY "Mode 1"
 WHEN mode==2 DISPLAY "Mode 2"
 END CASE
END FUNCTION

$ fglcomp --format --fo-indent-width=6 module.4gl
PUBLIC FUNCTION cleanup(mode INTEGER)
      CASE
^^^^^^ -- 6 spaces from --fo-indent-width
            WHEN mode == 1
      ^^^^^^ -- 6 spaces from --fo-indent-width
                  DISPLAY "Mode 1"
            WHEN mode == 2
                  DISPLAY "Mode 2"
      END CASE
END FUNCTION

The default is 4.

Defining the continuation indentation width

The --fo-continuation-indent-width=cols option defines the indentation width for line-breaks. When breaking long lines, this number of spaces inserted for each extra level:
$ cat module.4gl
PUBLIC FUNCTION update_customer( id INTEGER, name VARCHAR(50) )
    UPDATE customer SET cust_name = name WHERE cust_id = id AND cust_valid = 'Y'
END FUNCTION

$ fglcomp --format --fo-column-limit=40 --fo-continuation-indent-width=2 module.4gl
PUBLIC FUNCTION update_customer(
  id INTEGER, name VARCHAR(50))
^^ -- 2 spaces from --fo-continuation-indent-width
    UPDATE customer
^^^^ -- 4 spaces from --fo-indent-width default
      SET cust_name = name
    ^^ -- 2 spaces from --fo-continuation-indent-width
      WHERE cust_id = id
    ^^ -- 2 spaces from --fo-continuation-indent-width
        AND cust_valid = 'Y'
      ^^ -- 2 spaces from --fo-continuation-indent-width
END FUNCTION

Default is 4.

Controlling instruction clause indentation

The --fo-label-indent=1 option indicates that indentation should apply to instruction sub-clauses, such as the WHEN clause of a CASE / END CASE block. When zero, no sub-clause indentation is done:
$ cat module.4gl
PUBLIC FUNCTION cleanup( mode INTEGER )
CASE
 WHEN mode==1 DISPLAY "Mode 1"
 WHEN mode==2 DISPLAY "Mode 2"
 END CASE
END FUNCTION

$ fglcomp --format --fo-label-indent=0 module.4gl
PUBLIC FUNCTION cleanup(mode INTEGER)
    CASE
    WHEN mode == 1
        DISPLAY "Mode 1"
    WHEN mode == 2
        DISPLAY "Mode 2"
    END CASE
END FUNCTION

When 0, the instruction clauses are aligned with the head of the statement (CASE, INPUT etc). If 1, those "labels" are indented. This results in indenting the statements following those labels 2 levels relatively to the head of the statement.

The default is 1 (clause indentation is enabled).

Controlling how source lines are packed

The --fo-pack=1 option can be used to pack items as much as possible together on the same line:
$ cat module.4gl
PUBLIC FUNCTION func1( )
CALL func2( "aaa", "bbb", "ccc", "ddd", "eee" )
END FUNCTION

$ fglcomp --format --fo-column-limit=30 module.4gl
PUBLIC FUNCTION func1()
    CALL func2(
        "aaa",
        "bbb",
        "ccc",
        "ddd",
        "eee")
END FUNCTION

$ fglcomp --format --fo-column-limit=30 --fo-pack=1 module.4gl
PUBLIC FUNCTION func1()
    CALL func2(
        "aaa", "bbb", "ccc",
        "ddd", "eee")
END FUNCTION 

Using uppercase or lowercase keywords

Genero BDL uses traditionally uppercase keywords and therefore the code formatter produces uppercase keywords by default.

When the coding conventions require lowercase keywords, use the --fo-lowercase-keywords=1 option of the formatter, to produce lower case keywords:
$ cat module.4gl
function myfunc(x INT) retuRNS int
  return x + 1
end funcTION

$ fglcomp --format --fo-lowercase-keywords=1 module.4gl 
function myfunc(x int) returns int
    return x + 1
end function

$ fglcomp --format --fo-lowercase-keywords=0 module.4gl 
FUNCTION myfunc(x INT) RETURNS INT
    RETURN x + 1
END FUNCTION