(********************************************************************)
(*                                                                  *)
(*  cc_conf.s7i   Configuration values for C compiler and runtime.  *)
(*  Copyright (C) 2013  Thomas Mertes                               *)
(*                                                                  *)
(*  This file is part of the Seed7 Runtime Library.                 *)
(*                                                                  *)
(*  The Seed7 Runtime Library is free software; you can             *)
(*  redistribute it and/or modify it under the terms of the GNU     *)
(*  Lesser General Public License as published by the Free Software *)
(*  Foundation; either version 2.1 of the License, or (at your      *)
(*  option) any later version.                                      *)
(*                                                                  *)
(*  The Seed7 Runtime Library is distributed in the hope that it    *)
(*  will be useful, but WITHOUT ANY WARRANTY; without even the      *)
(*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *)
(*  PURPOSE.  See the GNU Lesser General Public License for more    *)
(*  details.                                                        *)
(*                                                                  *)
(*  You should have received a copy of the GNU Lesser General       *)
(*  Public License along with this program; if not, write to the    *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


include "shell.s7i";
include "osfiles.s7i";


(**
 *  Structure to describe C compiler and runtime library.
 *)
const type: ccConfigType is new struct

    (**
     *  TRUE, when the Seed7 runtime library uses strings with capacity.
     *  The capacity of a string can be larger than its size.
     *  Strings with capacity can be enlarged without calling realloc().
     *)
    var boolean: WITH_STRI_CAPACITY         is FALSE;

    (**
     *  TRUE, when the actual characters of a string can be stored elsewhere.
     *  This allows string slices without the need to copy characters.
     *)
    var boolean: ALLOW_STRITYPE_SLICES      is FALSE;

    (**
     *  TRUE, when the actual characters of a bstring can be stored elsewhere.
     *  This allows bstring slices without the need to copy characters.
     *)
    var boolean: ALLOW_BSTRITYPE_SLICES     is FALSE;

    (**
     *  TRUE, when right shifts preserve the sign of negative signed integers.
     *  The C standard specifies that the right shift of signed integers is
     *  implementation defined, when the shifted values are negative.
     *)
    var boolean: RSHIFT_DOES_SIGN_EXTEND    is FALSE;

    (**
     *  TRUE, when signed integers are represented as twos complement numbers.
     *  This allows some simplified range checks in compiled programs.
     *)
    var boolean: TWOS_COMPLEMENT_INTTYPE    is FALSE;

    (**
     *  TRUE, when the byte ordering of integers is little endian.
     *  With little endian byte ordering it is possible to get the elements
     *  of a union by casting the union to the desired element type.
     *)
    var boolean: LITTLE_ENDIAN_INTTYPE      is FALSE;

    (**
     *  TRUE, when a comparison between two NaN values returns FALSE.
     *  Comparison refers to comparisons with  ==  <  >  <=  or  >= .
     *  If it is FALSE fltEq(), fltGe(), fltGt(), fltLe() and fltLt()
     *  should be used to do comparisons of float values.
     *)
    var boolean: NAN_COMPARISON_OKAY        is FALSE;

    (**
     *  TRUE, when pow() works okay for a base of zero, one or NaN.
     *  If it is FALSE fltPow() should be used instead of pow().
     *)
    var boolean: POW_FUNCTION_OKAY          is FALSE;

    (**
     *  TRUE, when frexp(Infinity, &exponent), frexp(-Infinity, &exponent)
     *  and frexp(NaN, &exponent) return the first argument and set the
     *  exponent to 0.
     *  If it is FALSE checks for this special cases must be done.
     *)
    var boolean: FREXP_INFINITY_NAN_OKAY    is FALSE;

    (**
     *  TRUE, when the functions sigsetjmp() and siglongjmp() are available.
     *  When it is FALSE the functions setjmp() and longjmp() must
     *  be used instead.
     *)
    var boolean: HAS_SIGSETJMP              is FALSE;

    (**
     *  TRUE, when the C function sigaction() is present.
     *  When it is FALSE the function signal() must be used instead.
     *)
    var boolean: HAS_SIGACTION              is FALSE;

    (**
     *  TRUE, when a signal resets the signal handling to SIG_DFL.
     *  When it is FALSE the signal handler stays unchanged, when a
     *  signal is raised. When a signal handler is set with signal() an
     *  incoming signal might trigger a reset of the signal handling.
     *  This depends on the C run-time. SIGNAL_RESETS_HANDLER is TRUE,
     *  when the C run-time resets the signal handling. When a signal
     *  handler is set with sigaction() an incoming signal always leaves
     *  the signal handling unchanged (SIGNAL_RESETS_HANDLER is FALSE).
     *)
    var boolean: SIGNAL_RESETS_HANDLER      is FALSE;

    (**
     *  TRUE, when floating point divisions by zero cause compilation errors.
     *  Some C compilers check if the dividend is 0.0 and classify a
     *  floating point division by zero as fatal error. The generated
     *  C code should avoid this situation and generate code to
     *  raise the exception NUMERIC_ERROR instead.
     *)
    var boolean: FLOAT_ZERO_DIV_ERROR       is FALSE;

    (**
     *  TRUE, when SIGFPE should be raised with an integer division by zero.
     *  An integer division by zero should be done instead of just calling
     *  raise(SIGFPE). Under Windows it is necessary to trigger SIGFPE
     *  this way to assure that the debugger can catch it. The Seed7 to
     *  C compiler produces code to raise SIGFPE when an uncaught EXCEPTION
     *  occurs (when the compiler was called with the option -e).
     *)
    var boolean: DO_SIGFPE_WITH_DIV_BY_ZERO is FALSE;

    (**
     *  TRUE, when integer divisions must be checked for a division by zero.
     *  This applies to the division operations div, rem, mdiv and mod.
     *  The generated C code should, when a division by zero occurs,
     *  raise the exception NUMERIC_ERROR instead of doing the
     *  illegal divide operation.
     *)
    var boolean: CHECK_INT_DIV_BY_ZERO      is FALSE;

    (**
     *  TRUE, when integer remainder must be checked for a division by zero.
     *  This applies to the division operations rem and mod.
     *  The generated C code should, when a remainder by zero occurs,
     *  raise the exception NUMERIC_ERROR instead of doing the
     *  illegal divide operation.
     *)
    var boolean: CHECK_INT_REM_BY_ZERO      is FALSE;

    (**
     *  TRUE, when the integer expression 0%0 might not trigger SIGFPE.
     *  This can happen with a constant or a variable dividend.
     *  This applies to the division operations rem and mod.
     *  The generated C code should, when a remainder by zero occurs,
     *  raise the exception NUMERIC_ERROR instead of doing the
     *  illegal divide operation.
     *)
    var boolean: CHECK_INT_REM_ZERO_BY_ZERO is FALSE;

    (**
     *  TRUE, when the C function exp2() is present.
     *)
    var boolean: HAS_EXP2                   is FALSE;

    (**
     *  TRUE, when the C function exp10() is present.
     *)
    var boolean: HAS_EXP10                  is FALSE;

    (**
     *  TRUE, when the C function log2() is present.
     *)
    var boolean: HAS_LOG2                   is FALSE;

    (**
     *  TRUE, when the C function cbrt() is present.
     *)
    var boolean: HAS_CBRT                   is FALSE;

    (**
     *  TRUE, when floating point divisions by zero don't conform to IEEE 754.
     *  According to IEEE 754 a floating point division by zero should
     *  return Infinity, -Infinity or NaN. In this case the compiler
     *  generates C code, which checks all float divisions ( / and /:= )
     *  for division by zero. The generated C code should, when executed,
     *  return Infinity, -Infinity or NaN instead of doing the divide
     *  operation.
     *)
    var boolean: CHECK_FLOAT_DIV_BY_ZERO    is FALSE;

    (**
     *  TRUE, when the C compiler limits the length of string literals.
     *  Some C compilers limit the maximum string literal length.
     *  There are limits of 2,048 bytes and 16,384 (16K) bytes.
     *  The actual limit is not interesting, but the fact that a
     *  limit exists or does not exist.
     *)
    var boolean: LIMITED_CSTRI_LITERAL_LEN  is FALSE;

    (**
     *  TRUE, when #line directives can use UTF-8 encoded file names.
     *  The file names from #line directives are used by the debugger to
     *  allow source code debugging.
     *)
    var boolean: CC_SOURCE_UTF8             is FALSE;

    (**
     *  TRUE, when the main function is named wmain.
     *  This is a way to support Unicode command line arguments under Windows.
     *  An alternate way to support Unicode command line arguments under
     *  Windows uses the functions getUtf16Argv() and freeUtf16Argv() (both
     *  defined in "cmd_win.c").
     *)
    var boolean: USE_WMAIN                  is FALSE;

    (**
     *  TRUE, when the main function is named WinMain.
     *)
    var boolean: USE_WINMAIN                is FALSE;

    (**
     *  TRUE, when the type ''floatType'' is ''double''.
     *  When it is FALSE ''floatType'' is ''float''.
     *)
    var boolean: FLOATTYPE_DOUBLE           is FALSE;

    (**
     *  Size of the type ''intType'' in bits (either 32 or 64).
     *  A typedef can define ''intType'' as ''int32Type'' respectively
     *  ''int64Type''.
     *)
    var integer: INTTYPE_SIZE               is 0;

    (**
     *  Size of the type ''floatType'' in bits.
     *)
    var integer: FLOATTYPE_SIZE             is 0;

    (**
     *  Size of a pointer in bits.
     *)
    var integer: POINTER_SIZE               is 0;

    (**
     *  The maximum of INTTYPE_SIZE, FLOATTYPE_SIZE and POINTER_SIZE.
     *  This is also the size in bits of the types ''rtlValueUnion'',
     *  ''rtlObjectType'' and ''genericType'' (defined in data_rtl.h).
     *)
    var integer: GENERIC_SIZE               is 0;

    (**
     *  Size of the type ''int'' in bits.
     *)
    var integer: INT_SIZE                   is 0;

    (**
     *  Minimum value of the type ''int''.
     *)
    var integer: INT_MIN                    is 0;

    (**
     *  Maximum value of the type ''int''.
     *)
    var integer: INT_MAX                    is 0;

    (**
     *  Size of the type ''long'' in bits.
     *)
    var integer: LONG_SIZE                  is 0;

    (**
     *  Maximum from the continuous range of integers that map to floats.
     *  All integers from -INT_RANGE_IN_FLOATTYPE_MAX to
     *  INT_RANGE_IN_FLOATTYPE_MAX can be converted to ''floatType''
     *  and back to ''intType'' without loss.
     *)
    var integer: INT_RANGE_IN_FLOATTYPE_MAX is 0;

    (**
     *  Name of a type for the boolean values 0 and 1.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''boolType'' with BOOLTYPE.
     *)
    var string: BOOLTYPE                    is "";

    (**
     *  Name of a signed integer type that is 32 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''int32Type'' with INT32TYPE.
     *)
    var string: INT32TYPE                   is "";

    (**
     *  Name of an unsigned integer type that is 32 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''uint32Type'' with UINT32TYPE.
     *)
    var string: UINT32TYPE                  is "";

    (**
     *  Name of a signed integer type that is 64 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''int64Type'' with INT64TYPE.
     *)
    var string: INT64TYPE                   is "";

    (**
     *  Name of an unsigned integer type that is 64 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''uint64Type'' with UINT64TYPE.
     *)
    var string: UINT64TYPE                  is "";

    (**
     *  Name of a signed integer type that is 128 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''int128Type'' with INT128TYPE. Empty string when
     *  there is no 128-bit signed integer type.
     *)
    var string: INT128TYPE                  is "";

    (**
     *  Name of an unsigned integer type that is 128 bits wide.
     *  The runtime library and the compiler use a typedef to define
     *  the type ''uint128Type'' with UINT128TYPE. Empty string when
     *  there is no 128-bit unsigned integer type.
     *)
    var string: UINT128TYPE                 is "";

    (**
     *  The suffix used by the literals of the 32 bits wide integer type.
     *)
    var string: INT32TYPE_LITERAL_SUFFIX    is "";

    (**
     *  The suffix used by the literals of the 64 bits wide integer type.
     *)
    var string: INT64TYPE_LITERAL_SUFFIX    is "";

    (**
     *  Definition of several macros (likely, unlikely, noreturn).
     *)
    var string: MACRO_DEFS                  is "";

    (**
     *  Name of the signal that is raised when an integer overflow
     *  occurs. Empty string when integer overflow does not raise
     *  a signal.
     *)
    var string: OVERFLOW_SIGNAL             is "";

    (**
     *  The extension used by the C compiler for object files.
     *  Several object files and libraries are linked together to
     *  an executable. Under Linux/Unix/BSD this is usually ".o".
     *  Under Windows this is ".o" for MinGW and Cygwin,
     *  but ".obj" for other compilers.
     *)
    var string: OBJECT_FILE_EXTENSION       is "";

    (**
     *  The extension used by the linker for static libraries.
     *  Several object files can be grouped to a library. Under
     *  Linux/Unix/BSD this is usually ".a". Under Windows this is
     *  ".a" for MinGW and Cygwin, but ".lib" for other linkers.
     *)
    var string: LIBRARY_FILE_EXTENSION      is "";

    (**
     *  The extension used by the operating system for executables.
     *  Since executable extensions are not used under
     *  Linux/Unix/BSD it is "" for them. Under Windows
     *  the value ".exe" is used.
     *)
    var string: EXECUTABLE_FILE_EXTENSION   is "";

    (**
     *  Command to call the stand-alone C compiler and linker.
     *  Most IDEs provide also a stand-alone compiler/linker.
     *)
    var string: C_COMPILER                  is "";

    var string: CPLUSPLUS_COMPILER          is "";
    var boolean: CALL_C_COMPILER_FROM_SHELL is FALSE;
    var string: C_COMPILER_VERSION          is "";
    var string: GET_CC_VERSION_INFO         is "";

    (**
     *  C compiler option to add source level debugging information.
     *  With this option source level debugging information is
     *  added to the object file.
     *)
    var array string: CC_OPT_DEBUG_INFO     is 0 times "";

    (**
     *  C compiler option to suppress all warnings.
     *)
    var string: CC_OPT_NO_WARNINGS          is "";

    (**
     *  C compiler flags to be used when C programs are compiled.
     *)
    var array string: CC_FLAGS              is 0 times "";

    (**
     *  File descriptor to which the C compiler writes errors.
     *  The MSVC stand-alone C compiler (CL) writes the error
     *  messages to standard output (file descriptor 1).
     *  The C compliers of Linux/Unix/BSD and the compilers from
     *  MinGW and Cygwin write the error messages to the error
     *  output (file descriptor 2).
     *)
    var integer: CC_ERROR_FILDES            is 0;

    (**
     *  Linker option to add source level debugging information.
     *  With this option source level debugging information is
     *  added to the executable file. (e.g.: "-Z7" or "-v").
     *  Many compiler/linker combinations don't need this option
     *  to do source level debugging (use "").
     *)
    var string: LINKER_OPT_DEBUG_INFO       is "";

    (**
     *  Linker option to be used without source level debugging.
     *  This option can strip debug information (e.g.: "-Wl,--strip-debug").
     *)
    var string: LINKER_OPT_NO_DEBUG_INFO    is "";

    (**
     *  Linker option to provide the output filename (e.g.: "-o ").
     *  When no such option exists the value of LINKER_OPT_OUTPUT_FILE
     *  should be "". In this case it is assumed that the linker
     *  replaces the OBJECT_FILE_EXTENSION of the file with the
     *  EXECUTABLE_FILE_EXTENSION.
     *)
    var string: LINKER_OPT_OUTPUT_FILE      is "";

    (**
     *  Standard linker options to link a compiled program.
     *  This is intended for options that specify the stack size or
     *  similar things (e.g.: "-Wl,--gc-sections,--stack,4194304").
     *)
    var array string: LINKER_FLAGS          is 0 times "";

    (**
     *  Options to link system libraries to a compiled program.
     *  This is intended for options to link libraries required by the
     *  Seed7 runtime library. E.g. libraries for math, socket or
     *  multiple precision (gmp).
     *)
    var array string: SYSTEM_LIBS           is 0 times "";

    (**
     *  Options to link system console libraries to a compiled program.
     *  This is intended for options to link libraries required by the
     *  Seed7 console runtime library (e.g.: "-lncurses").
     *)
    var array string: SYSTEM_CONSOLE_LIBS   is 0 times "";

    (**
     *  Options to link system graphic libraries to a compiled program.
     *  This is intended for options to link libraries required by the
     *  Seed7 graphic runtime library (e.g.: "-lX11").
     *)
    var array string: SYSTEM_DRAW_LIBS      is 0 times "";

    (**
     *  Options to link database libraries to a compiled program.
     *  This is intended for options to link libraries required by the
     *  Seed7 database runtime libraries (e.g.: "-lmysqlclient").
     *)
    var array string: SYSTEM_DB_LIBS        is 0 times "";

    (**
     *  Name of the Seed7 runtime library (e.g.: "seed7_05.a").
     *)
    var string: SEED7_LIB                   is "";

    (**
     *  Name of the Seed7 text console runtime library (e.g.: "s7_con.a").
     *)
    var string: CONSOLE_LIB                 is "";

    (**
     *  Name of the Seed7 graphic runtime library (e.g.: "s7_draw.a").
     *)
    var string: DRAW_LIB                    is "";

    (**
     *  Name of the Seed7 compiler data runtime library (e.g.: "s7_data.a").
     *)
    var string: COMP_DATA_LIB               is "";

    (**
     *  Name of the Seed7 compiler runtime library (e.g.: "s7_comp.a").
     *)
    var string: COMPILER_LIB                is "";

    (**
     *  Directory containing the Seed7 runtime libraries.
     *  This path uses the standard path representation (a slash is used
     *  as path separator and instead of a drive letter like "C:" the
     *  path "/c" is used).
     *)
    var string: S7_LIB_DIR                  is "";

    (**
     *  Shell parameter to redirect to the file descriptor 1.
     *  Under Linux/Unix/BSD and Windows this is ">".
     *  The file to which the standard output should be
     *  redirected must be appended. E.g.: >myFile.
     *)
    var string: REDIRECT_FILDES_1           is "";

    (**
     *  Shell parameter to redirect to the file descriptor 2.
     *  Under Linux/Unix/BSD and Windows this is "2>".
     *  The file to which the error output should be
     *  redirected must be appended. E.g.: 2>myFile.
     *)
    var string: REDIRECT_FILDES_2           is "";

    (**
     *  Name of the NULL device.
     *  Under Linux/Unix/BSD this is "/dev/null".
     *  Under Windows this is "NUL:".
     *)
    var string: NULL_DEVICE                 is "";

    (**
     *  The suffix used by the literals of the type ''intType''.
     *)
    var string: INTTYPE_LITERAL_SUFFIX      is "";
  end struct;


const func string: configValue (in string: name)             is action "CMD_CONFIG_VALUE";


(**
 *  Determine the built-in (hard-coded) C compiler configuration values.
 *  @return a structure with the built-in configuration values.
 *)
const func ccConfigType: getBuiltInConfig is func
  result
    var ccConfigType: conf is ccConfigType.value;
  local
    var string: configValue is "";
  begin
    conf.WITH_STRI_CAPACITY         := boolean parse configValue("WITH_STRI_CAPACITY");
    conf.ALLOW_STRITYPE_SLICES      := boolean parse configValue("ALLOW_STRITYPE_SLICES");
    conf.ALLOW_BSTRITYPE_SLICES     := boolean parse configValue("ALLOW_BSTRITYPE_SLICES");
    conf.RSHIFT_DOES_SIGN_EXTEND    := boolean parse configValue("RSHIFT_DOES_SIGN_EXTEND");
    conf.TWOS_COMPLEMENT_INTTYPE    := boolean parse configValue("TWOS_COMPLEMENT_INTTYPE");
    conf.LITTLE_ENDIAN_INTTYPE      := boolean parse configValue("LITTLE_ENDIAN_INTTYPE");
    conf.NAN_COMPARISON_OKAY        := boolean parse configValue("NAN_COMPARISON_OKAY");
    conf.POW_FUNCTION_OKAY          := boolean parse configValue("POW_FUNCTION_OKAY");
    conf.FREXP_INFINITY_NAN_OKAY    := boolean parse configValue("FREXP_INFINITY_NAN_OKAY");
    conf.HAS_SIGSETJMP              := boolean parse configValue("HAS_SIGSETJMP");
    conf.HAS_SIGACTION              := boolean parse configValue("HAS_SIGACTION");
    conf.SIGNAL_RESETS_HANDLER      := boolean parse configValue("SIGNAL_RESETS_HANDLER");
    conf.FLOAT_ZERO_DIV_ERROR       := boolean parse configValue("FLOAT_ZERO_DIV_ERROR");
    conf.DO_SIGFPE_WITH_DIV_BY_ZERO := boolean parse configValue("DO_SIGFPE_WITH_DIV_BY_ZERO");
    conf.CHECK_INT_DIV_BY_ZERO      := boolean parse configValue("CHECK_INT_DIV_BY_ZERO");
    conf.CHECK_INT_REM_BY_ZERO      := boolean parse configValue("CHECK_INT_REM_BY_ZERO");
    conf.CHECK_INT_REM_ZERO_BY_ZERO := boolean parse configValue("CHECK_INT_REM_ZERO_BY_ZERO");
    conf.HAS_EXP2                   := boolean parse configValue("HAS_EXP2");
    conf.HAS_EXP10                  := boolean parse configValue("HAS_EXP10");
    conf.HAS_LOG2                   := boolean parse configValue("HAS_LOG2");
    conf.HAS_CBRT                   := boolean parse configValue("HAS_CBRT");
    conf.CHECK_FLOAT_DIV_BY_ZERO    := boolean parse configValue("CHECK_FLOAT_DIV_BY_ZERO");
    conf.LIMITED_CSTRI_LITERAL_LEN  := boolean parse configValue("LIMITED_CSTRI_LITERAL_LEN");
    conf.CC_SOURCE_UTF8             := boolean parse configValue("CC_SOURCE_UTF8");
    conf.USE_WMAIN                  := boolean parse configValue("USE_WMAIN");
    conf.USE_WINMAIN                := boolean parse configValue("USE_WINMAIN");
    conf.FLOATTYPE_DOUBLE           := boolean parse configValue("FLOATTYPE_DOUBLE");
    conf.INTTYPE_SIZE               := integer parse configValue("INTTYPE_SIZE");
    conf.FLOATTYPE_SIZE             := integer parse configValue("FLOATTYPE_SIZE");
    conf.POINTER_SIZE               := integer parse configValue("POINTER_SIZE");
    conf.GENERIC_SIZE               := max({conf.INTTYPE_SIZE, conf.FLOATTYPE_SIZE, conf.POINTER_SIZE});
    conf.INT_SIZE                   := integer parse configValue("INT_SIZE");
    conf.LONG_SIZE                  := integer parse configValue("LONG_SIZE");
    conf.INT_RANGE_IN_FLOATTYPE_MAX := integer parse configValue("INT_RANGE_IN_FLOATTYPE_MAX");
    conf.BOOLTYPE                   := configValue("BOOLTYPE");
    conf.INT32TYPE                  := configValue("INT32TYPE");
    conf.UINT32TYPE                 := configValue("UINT32TYPE");
    conf.INT64TYPE                  := configValue("INT64TYPE");
    conf.UINT64TYPE                 := configValue("UINT64TYPE");
    conf.INT128TYPE                 := configValue("INT128TYPE");
    conf.UINT128TYPE                := configValue("UINT128TYPE");
    conf.INT32TYPE_LITERAL_SUFFIX   := configValue("INT32TYPE_LITERAL_SUFFIX");
    conf.INT64TYPE_LITERAL_SUFFIX   := configValue("INT64TYPE_LITERAL_SUFFIX");
    conf.MACRO_DEFS                 := configValue("MACRO_DEFS");
    conf.OVERFLOW_SIGNAL            := configValue("OVERFLOW_SIGNAL");
    conf.OBJECT_FILE_EXTENSION      := configValue("OBJECT_FILE_EXTENSION");
    conf.LIBRARY_FILE_EXTENSION     := configValue("LIBRARY_FILE_EXTENSION");
    conf.EXECUTABLE_FILE_EXTENSION  := configValue("EXECUTABLE_FILE_EXTENSION");
    conf.C_COMPILER                 := configValue("C_COMPILER");
    conf.CPLUSPLUS_COMPILER         := configValue("CPLUSPLUS_COMPILER");
    conf.CALL_C_COMPILER_FROM_SHELL := boolean parse configValue("CALL_C_COMPILER_FROM_SHELL");
    conf.C_COMPILER_VERSION         := configValue("C_COMPILER_VERSION");
    conf.GET_CC_VERSION_INFO        := configValue("GET_CC_VERSION_INFO");
    conf.CC_OPT_DEBUG_INFO          := noEmptyStrings(split(configValue("CC_OPT_DEBUG_INFO"), ' '));
    conf.CC_OPT_NO_WARNINGS         := configValue("CC_OPT_NO_WARNINGS");
    conf.CC_FLAGS                   := noEmptyStrings(split(configValue("CC_FLAGS"), ' '));
    conf.CC_ERROR_FILDES            := integer parse configValue("CC_ERROR_FILDES");
    conf.LINKER_OPT_DEBUG_INFO      := configValue("LINKER_OPT_DEBUG_INFO");
    conf.LINKER_OPT_NO_DEBUG_INFO   := configValue("LINKER_OPT_NO_DEBUG_INFO");
    conf.LINKER_OPT_OUTPUT_FILE     := configValue("LINKER_OPT_OUTPUT_FILE");
    conf.LINKER_FLAGS               := noEmptyStrings(split(configValue("LINKER_FLAGS"), ' '));
    conf.SYSTEM_LIBS                := noEmptyStrings(split(configValue("SYSTEM_LIBS"), ' '));
    conf.SYSTEM_CONSOLE_LIBS        := noEmptyStrings(split(configValue("SYSTEM_CONSOLE_LIBS"), ' '));
    conf.SYSTEM_DRAW_LIBS           := noEmptyStrings(split(configValue("SYSTEM_DRAW_LIBS"), ' '));
    conf.SYSTEM_DB_LIBS             := noEmptyStrings(split(configValue("SYSTEM_DB_LIBS"), '\n'));
    conf.SEED7_LIB                  := configValue("SEED7_LIB");
    conf.CONSOLE_LIB                := configValue("CONSOLE_LIB");
    conf.DRAW_LIB                   := configValue("DRAW_LIB");
    conf.COMP_DATA_LIB              := configValue("COMP_DATA_LIB");
    conf.COMPILER_LIB               := configValue("COMPILER_LIB");
    conf.S7_LIB_DIR                 := configValue("S7_LIB_DIR");
    conf.REDIRECT_FILDES_1          := configValue("REDIRECT_FILDES_1");
    conf.REDIRECT_FILDES_2          := configValue("REDIRECT_FILDES_2");
    conf.NULL_DEVICE                := configValue("NULL_DEVICE");
    if conf.INTTYPE_SIZE = 32 then
      conf.INTTYPE_LITERAL_SUFFIX := conf.INT32TYPE_LITERAL_SUFFIX;
    else
      conf.INTTYPE_LITERAL_SUFFIX := conf.INT64TYPE_LITERAL_SUFFIX;
    end if;
    if conf.INT_SIZE = 16 then
      if conf.TWOS_COMPLEMENT_INTTYPE then
        conf.INT_MIN := -32768;
      else
        conf.INT_MIN := -32767;
      end if;
      conf.INT_MAX :=  32767;
    elsif conf.INT_SIZE = 32 then
      if conf.TWOS_COMPLEMENT_INTTYPE then
        conf.INT_MIN := -2147483648;
      else
        conf.INT_MIN := -2147483647;
      end if;
      conf.INT_MAX :=  2147483647;
    elsif conf.INT_SIZE = 64 then
      if conf.TWOS_COMPLEMENT_INTTYPE then
        conf.INT_MIN := -9223372036854775807 - 1;
      else
        conf.INT_MIN := -9223372036854775807;
      end if;
      conf.INT_MAX :=  9223372036854775807;
    end if;
  end func;


(**
 *  Structure with configuration values for C compiler and runtime.
 *)
const ccConfigType: ccConf is getBuiltInConfig;


const func string: determineCCVersion (in string: get_cc_version_info) is func
  result
    var string: c_compiler_version is "";
  local
    var string: ccVersionFile is "cc_version";
    var file: aFile is STD_NULL;
  begin
    ccVersionFile &:= "_" <& rand(0, 999999990) lpad0 9;
    cmd_sh(get_cc_version_info & ccVersionFile);
    aFile := open(ccVersionFile, "r");
    if aFile <> STD_NULL then
      c_compiler_version := getln(aFile);
      close(aFile);
    end if;
    if fileType(ccVersionFile) = FILE_REGULAR then
      removeFile(ccVersionFile);
    end if;
  end func;


const func boolean: ccVersionIsOkay is
  return determineCCVersion(ccConf.GET_CC_VERSION_INFO) = ccConf.C_COMPILER_VERSION;