using ENUM

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

using ENUM

Post by MrSwiss »

This shows the use of ENUM's in order to simplify e.g. command line processing.

Assume: you want to read a simple to use command-line-switches, which in fact,
would require a rather complex evaluation in your code ...

The example chosen is a FBC compiler call (programmatically), which we know
to have a great many options, for exaples sake, somewhat reduced to essentials.
This is not a hindrance, since it can be extended, at any time (see: comments
in code):

Code: Select all

' ENUM_with_Default.bas --
'
' compile: -s console                   ' windows only!
'

' ----- Start-Enumerations -----
' the constants (from enum's) can be used directly in the command line, that
' calls the program ... e.g. C_32 = FBC 32 bit | C_64 = FBC 64 bit, etc.
' x_def can be assigned as desired (by any of the defined constants)
Enum comp_                              ' compiler selection (bitness)
    C_32
    C_64
    ' can be extended here
    C_def   = C_64                      ' default (if not specified by user)
End Enum
Enum b_e_                               ' backend to be used (GAS/GCC)
    B_gas
    B_gcc
    ' can be extended here
    B_def   = B_gcc                     ' default (if not specified by user)
End Enum
Enum opt_                               ' optimizer options (GCC only!)
    O_0                                 ' = 0 (NULL/ZERO), just ignore it
    O_1
    O_2
    O_3
    O_max
    ' can be extended here
    O_def   = O_2                       ' default (if not specified by user)
End Enum
Enum f_out_                             ' compile into: .exe | .lib | .dll/.so
    F_exe                               ' can be ignored (is default anyway)
    F_lib
    F_dylib
    F_def   = F_exe
End Enum

#Ifdef __FB_WIN32__
Enum subs_                              ' windows subsystem (win only!)
    Console = 1
    GUI
    SS_def  = Console                   ' default subsystem
End Enum                                ' NOT in the following type!
#EndIf  ' __FB_WIN32__

' further examples not used in the type currently and, in demo code below
Enum err_
    E_none                              ' just a exaple of how to implement
    E_e                                 ' additional compiler switches ...
    E_ex
    E_exx
    E_def   = E_none                    ' default (if not specified by user)
End Enum
Enum warn_                              ' set warning level
    W_std                               ' standard setting
    W_1                                 ' numeric level
    W_2
    W_3
    W_all
    W_ped                               ' pedantic warnings (debuging)
    W_def   = W_std                     ' default (if not specified by user)
End Enum
' further examples - end
' ----- End-Enumerations -----

' ----- Start-Type -----
Type cmd_opt                            ' stores command line arguments (numeric)
  Private:                              ' size = 4 Bytes
    As UByte    comp, b_e, opt, outF    ' compiler, backend, optimizer, output
  Public:
    Declare Sub init    (ByVal As UByte = C_def, ByVal As UByte = B_def, ByVal As UByte = O_def, ByVal As UByte = F_def)
    Declare Sub get_all (ByRef As UByte = 0, ByRef As UByte = 0, ByRef As UByte = 0, ByRef As UByte = 0)
End Type

Sub cmd_opt.init( _
    ByVal compiler  As UByte = C_def, _
    ByVal backend   As UByte = B_def, _
    ByVal optimizer As UByte = O_def, _
    ByVal out_file  As UByte = F_def _
    )
    This.comp   = compiler
    This.b_e    = backend
    This.opt    = optimizer
    This.outF   = out_file
End Sub

Sub cmd_opt.get_all( _
    ByRef compiler  As UByte = 0, _
    ByRef backend   As UByte = 0, _
    ByRef optimizer As UByte = 0, _
    ByRef out_file  As UByte = 0 _
    )
    compiler    = This.comp
    backend     = This.b_e
    optimizer   = This.opt
    out_file    = This.outF         
End Sub
' ----- End-Type -----

' simplify code with short-cut's
#Define DQ  ( Chr(34) )                 ' double quote
#Define SP  ( Space(1) )                ' single space

' revert selections to string again (however, command line version)
' dyn. arrays (UBound defined by number of initializers, variable)
Dim As String compiler (0 To ...) => { "C:\DEV_TOOLS\FreeBASIC\1060_32\fbc", _
                                       "C:\DEV_TOOLS\FreeBASIC\1060_64\fbc" }
Dim As String backend  (0 To ...) => { SP + "-gen gas", SP + "-gen gcc" }
Dim As String optimizer(0 To ...) => { "", SP + "-O 1", SP + "-O 2", _
                                       SP + "-O 3", SP + "-O max" }
Dim As String out_file (0 To ...) => { "", SP + "-lib", SP + "-dylib" }
Dim As String subsys   (0 To ...) => { "", SP + "-s console", SP + "-s gui" }
' variables
Dim As String   ss_out = "", _          ' win only, otherwise, just empty
                fname = "any_file.bas"  ' a proxy file name only
Dim As cmd_opt  c_opt                   ' one type instance
Dim As UByte    co, be, op, of          ' compiler | backend | optimizer &
                                        ' out_file

' ===== MAIN =====
c_opt.init()                            ' set all to defaults (predefined)
c_opt.get_all(co, be, op, of)           ' get current defaults

Print "Default settings result"
Print "~~~~~~~~~~~~~~~~~~~~~~~"
Print

#Ifdef __FB_WIN32__                     ' windows only
ss_out = subsys(SS_def)
#EndIf  ' __FB_WIN32__

If be = 0 Then op = 0                   ' no optimizing, if: -gen gas

Print "Command Line ="
Print compiler(co); backend(be); _      ' build string from part-strings _
      optimizer(op); out_file(of); _    ' or from string arrays content
      ss_out; SP; DQ; fname; DQ         ' double quotes around 'fname'

Print : Print
Print "done ... ";

Sleep
' ===== END-MAIN =====  ' ----- EOF -----
A huge benefit in this scenario is, that "most used" options, can be "pre-set",
aka: default values are used, if none specified, by user.
Post Reply