テスト出力する内容を変更した

テスト出力する内容を変更した

' PROJECT SMILE++
' Smile++ Transpiler 2017.1

option strict

acls
prgEdit 1

' 文字列に含まれる小文字アルファベットを大文字に変換する

def upcase$(string$)
	var i
	var charCode
	for i = 0 to len(string$) - 1
		charCode = asc(mid$(string$, i, 1))
		if charCode >= asc("a") && charCode <= asc("z") then
			string$ = substr$(string$, i, 1, chr$(charCode - 32))
		endif
	next
	return string$
end

' 配列の要素を検索する

def indexOf$(array$[], string$)
	var i
	for i = 0 to len(array$) - 1
		if array$[i] == string$ then return i
	next
	return -1
end

' 配列を生成する

def array(list$)
	dim arr[0]
	var tmp = ""
	var i
	var c$ = ""
	for i = 0 to len(list$) - 1
		c$ = mid$(list$, i, 1)
		if c$ == " " && tmp$ != "" then
			push arr, val(tmp$)
			tmp$ = ""
		endif
		tmp$ = tmp$ + c$
	next
	if tmp$ != "" && tmp$ != " " then push arr, val(tmp$)
	return arr
end

def array$(list$)
	dim arr$[0]
	var tmp$ = ""
	var i
	var c$ = ""
	for i = 0 to len(list$) - 1
		c$ = mid$(list$, i, 1)
		if c$ == " " && tmp$ != "" then
			push arr$, tmp$
			tmp$ = ""
		else
			tmp$ = tmp$ + c$
		endif
	next
	if tmp$ != "" && tmp$ != " " then push arr$, tmp$
	return arr$
end

' 配列の内容を出力する

def arrayDump arr[]
	var i
	for i = 0 to len(arr) - 1
		? str$(arr[i]) + " ";
	next
	? ""
end

def arrayDump arr$[]
	var i
	for i = 0 to len(arr$) - 1
		? arr$[i] + " ";
	next
	? ""
end

' 定数

var NONE = -1, UNKNOWN = 1, DIRECTION = 2, RESERVED = 3
var OPERATOR = 4, CONSTANT = 5, STRING = 6

' 演算子

dim operators$[0]
operators$ = array$("+ - * / DIV MOD << >> NOT ( ) == != < <= > >= && || AND OR XOR !")

' 予約語

dim reservedWords$[0]
reservedWords$ = array$("IF THEN ELSE ELSEIF ENDIF GOTO GOSUB RETURN ON FOR NEXT WHILE WEND REPEAT UNTIL BREAK CONTINUE DEF END VAR DIM DATA READ RESTORE PRINT INPUT LINPUT CALL SWAP OUT COMMON USE EXEC FILES SAVE RENAME DELETE CHKFILE PRGEDIT PRGGET$ PRGSET PRGINS PRGDEL PRGSIZE PRGNAME$ XSCREEN DISPLAY VISIBLE BACKCOLOR ACLS FADE CLS COLOR LOCATE PRINT ? ATTR SCROLL FONTDEF WIDTH SPPAGE SPCLIP SPDEF SPSET SPCLR SPSHOW SPHIDE SPHOME SPOFS SPROT SPSCALE SPCOLOR SPCHR SPLINK SPUNLINK SPANIM SPSTOP SPSTART SPCHK SPVAR SPCOL SPCOLVEC SPHITINFO SPFUNC BGPAGE BGSCREEN BGCLR BGSHOW BGHIDE BGCLIP BGHOME BGOFS BGROT BGSCALE BGPUT BGFILL BGSET BGANIM BGSTOP BGSTART BGCHK BGVAR BGLOAD BGSAVE BGCOORD BGCOLOR BGFUNC GPAGE GCOLOR RGBREAD GCLIP GPRIO GCLS GPSET GLINE GCIRCLE GBOX GFILL GPAINT GCOPY GSAVE GLOAD GTRI GPUTCHR GOFS GPUTCHR16 XON XOFF BUTTON BREPEAT STICK STICKX ACCEL GYROA GYROV GYROSYNC TOUCH MICSTART MICSTOP MICDATA MICSAVE CONTROLLER VIBLATE BEEP BGMCHK BGMCLEAR BGMPLAY BGMSET BGMSETD BGMVAR BGMSTOP BGMVOL WAVSET WAVSETA EFCOFF EFCON EFCSET EFCWET TALK TALKCHK TALKSTOP BGMPAUSE BGMCONT SNDSTOP BIQUAD BQPARAM FFT IFFT FFTWFN PCMCONT PCMSTOP PCMSTREAM PCMVOL RINGCOPY ARYOP MPSTART MPSEND MPRECV MPSTAT MPNAME$ MPGET MPSET INC DEC COPY SORT RSORT PUSH UNSHIFT FILL RANDOMIZE STOP OPTION WAIT VSYNC REM KEY DTREAD TMREAD DIALOG CLIPBOARD DLCOPEN")

' 組み込み定数

dim constants$[0]
constants$ = array$("ON OFF YES NO TRUE FALSE BLACK NAVY BLUE GREEN TEAL LIME AQUA CYAN MAROON PURPLE OLIVE GRAY SILVER RED FUCHSIA MAGENTA YELLOW WHITE TBLACK TMAROON TRED TGREEN TLIME TOLIVE TYELLOW TNAVY TBLUE TPURPLE TMAGENTA TTREAL TCYAN TGRAY TWHITE UP DOWN LEFT RIGHT A B X Y L R ZR ZL TROT0 TROT90 TROT180 TROT270 TREVH TREVV SPSHOW SPROT0 SPROT90 SPROT180 SPROT180 SPROT270 SPREVH SPREVV SPADD BGROT0 BGROT90 BGROT180 BGROT270 BGREVH BGREVV CHKXY CHKZ CHKUV CHKI CHKR CHKS CHKC CHKV BQAPF BQLPF BQHPF BQBPF BQBSF BQLSF BQHSF BQPEQ WFRECT WFHAMM WFHANN WFBLKM AOPADD AOPSUB AOPMUL AOPDIV AOPMAD AOPLIP AOPCLP")

' 字句解析

def lex string$, tk$[], type[]
	var record$ = ""
	var phase = NONE
	var index = 0
	var isRecorded = false

	while true
		var c$ = mid$(string$, index, 1)

		if c$ == chr$(34) && phase != NONE then
			phase = STRING
			isRecorded = true
			inc index
		elseif c$ == chr$(34) && phase == STRING then
			push type, phase : phase = NONE
			push tk$, record$ + chr$(34)
			record$ = ""
			isRecorded = false
			inc index
		elseif phase == STRING && index != len(string$) - 1 then
			inc index
		elseif c$ == chr$(34) && phase != STRING then
			if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
			if indexOf$(operators$, upcase(record$)) != -1 then phase = OPERATOR
			if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
			push type, phase : phase = NONE
			push tk$, record$
			record$ = ""
			phase = STRING
			inc index
		elseif c$ == "#" then
			phase = DIRECTION
			isRecorded = true
			inc index
		elseif c$ == " " || index == len(string$) - 1 then
			if phase == UNKNOWN then
				if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
				if indexOf$(operators$, upcase$(record$)) != -1 then phase = OPERATOR
			endif
			if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
			if phase == STRING then ? "Error: 文字列定数がダブルクォートによって正しく閉じられていません" : break
			if phase != NONE then
				push type, phase : phase = NONE
				push tk$, record$
				record$ = ""
				isRecorded = false
			endif
			inc index
		elseif c$ != " " && !isRecorded then
			phase = UNKNOWN
			isRecorded = true
			inc index
		else
			inc index
		endif

		if isRecorded then record$ = record$ + c$
		if index >= len(string$) then break
	wend
end

var i, n
for n = 0 to prgSize(1) - 1
	dim tk$[0]
	dim type[0]
	lex prgGet$(), tk$, type
	for i = 0 to len(tk$)
		? tk$[i] + " -> ";
		if type[i] == UNKNOWN then
			? "Unknown"
		elseif type[i] == DIRECTION then
			? "Direction"
		elseif type[i] == RESERVED then
			? "Reserved"
		elseif type[i] == OPERATOR then
			? "Operator"
		elseif type[i] == CONSTANT then
			? "Constant"
		elseif type[i] == STRING then
			? "String"
		endif
	next
next

' PROJECT SMILE++
' Smile++ Transpiler 2017.1

option strict

acls
prgEdit 1

' 文字列に含まれる小文字アルファベットを大文字に変換する

def upcase$(string$)
	var i
	var charCode
	for i = 0 to len(string$) - 1
		charCode = asc(mid$(string$, i, 1))
		if charCode >= asc("a") && charCode <= asc("z") then
			string$ = substr$(string$, i, 1, chr$(charCode - 32))
		endif
	next
	return string$
end

' 配列の要素を検索する

def indexOf$(array$[], string$)
	var i
	for i = 0 to len(array$) - 1
		if array$[i] == string$ then return i
	next
	return -1
end

' 配列を生成する

def array(list$)
	dim arr[0]
	var tmp = ""
	var i
	var c$ = ""
	for i = 0 to len(list$) - 1
		c$ = mid$(list$, i, 1)
		if c$ == " " && tmp$ != "" then
			push arr, val(tmp$)
			tmp$ = ""
		endif
		tmp$ = tmp$ + c$
	next
	if tmp$ != "" && tmp$ != " " then push arr, val(tmp$)
	return arr
end

def array$(list$)
	dim arr$[0]
	var tmp$ = ""
	var i
	var c$ = ""
	for i = 0 to len(list$) - 1
		c$ = mid$(list$, i, 1)
		if c$ == " " && tmp$ != "" then
			push arr$, tmp$
			tmp$ = ""
		else
			tmp$ = tmp$ + c$
		endif
	next
	if tmp$ != "" && tmp$ != " " then push arr$, tmp$
	return arr$
end

' 配列の内容を出力する

def arrayDump arr[]
	var i
	for i = 0 to len(arr) - 1
		? str$(arr[i]) + " ";
	next
	? ""
end

def arrayDump arr$[]
	var i
	for i = 0 to len(arr$) - 1
		? arr$[i] + " ";
	next
	? ""
end

' 定数

var NONE = -1, UNKNOWN = 1, DIRECTION = 2, RESERVED = 3
var OPERATOR = 4, CONSTANT = 5, STRING = 6

' 演算子

dim operators$[0]
operators$ = array$("+ - * / DIV MOD << >> NOT ( ) == != < <= > >= && || AND OR XOR !")

' 予約語

dim reservedWords$[0]
reservedWords$ = array$("IF THEN ELSE ELSEIF ENDIF GOTO GOSUB RETURN ON FOR NEXT WHILE WEND REPEAT UNTIL BREAK CONTINUE DEF END VAR DIM DATA READ RESTORE PRINT INPUT LINPUT CALL SWAP OUT COMMON USE EXEC FILES SAVE RENAME DELETE CHKFILE PRGEDIT PRGGET$ PRGSET PRGINS PRGDEL PRGSIZE PRGNAME$ XSCREEN DISPLAY VISIBLE BACKCOLOR ACLS FADE CLS COLOR LOCATE PRINT ? ATTR SCROLL FONTDEF WIDTH SPPAGE SPCLIP SPDEF SPSET SPCLR SPSHOW SPHIDE SPHOME SPOFS SPROT SPSCALE SPCOLOR SPCHR SPLINK SPUNLINK SPANIM SPSTOP SPSTART SPCHK SPVAR SPCOL SPCOLVEC SPHITINFO SPFUNC BGPAGE BGSCREEN BGCLR BGSHOW BGHIDE BGCLIP BGHOME BGOFS BGROT BGSCALE BGPUT BGFILL BGSET BGANIM BGSTOP BGSTART BGCHK BGVAR BGLOAD BGSAVE BGCOORD BGCOLOR BGFUNC GPAGE GCOLOR RGBREAD GCLIP GPRIO GCLS GPSET GLINE GCIRCLE GBOX GFILL GPAINT GCOPY GSAVE GLOAD GTRI GPUTCHR GOFS GPUTCHR16 XON XOFF BUTTON BREPEAT STICK STICKX ACCEL GYROA GYROV GYROSYNC TOUCH MICSTART MICSTOP MICDATA MICSAVE CONTROLLER VIBLATE BEEP BGMCHK BGMCLEAR BGMPLAY BGMSET BGMSETD BGMVAR BGMSTOP BGMVOL WAVSET WAVSETA EFCOFF EFCON EFCSET EFCWET TALK TALKCHK TALKSTOP BGMPAUSE BGMCONT SNDSTOP BIQUAD BQPARAM FFT IFFT FFTWFN PCMCONT PCMSTOP PCMSTREAM PCMVOL RINGCOPY ARYOP MPSTART MPSEND MPRECV MPSTAT MPNAME$ MPGET MPSET INC DEC COPY SORT RSORT PUSH UNSHIFT FILL RANDOMIZE STOP OPTION WAIT VSYNC REM KEY DTREAD TMREAD DIALOG CLIPBOARD DLCOPEN")

' 組み込み定数

dim constants$[0]
constants$ = array$("ON OFF YES NO TRUE FALSE BLACK NAVY BLUE GREEN TEAL LIME AQUA CYAN MAROON PURPLE OLIVE GRAY SILVER RED FUCHSIA MAGENTA YELLOW WHITE TBLACK TMAROON TRED TGREEN TLIME TOLIVE TYELLOW TNAVY TBLUE TPURPLE TMAGENTA TTREAL TCYAN TGRAY TWHITE UP DOWN LEFT RIGHT A B X Y L R ZR ZL TROT0 TROT90 TROT180 TROT270 TREVH TREVV SPSHOW SPROT0 SPROT90 SPROT180 SPROT180 SPROT270 SPREVH SPREVV SPADD BGROT0 BGROT90 BGROT180 BGROT270 BGREVH BGREVV CHKXY CHKZ CHKUV CHKI CHKR CHKS CHKC CHKV BQAPF BQLPF BQHPF BQBPF BQBSF BQLSF BQHSF BQPEQ WFRECT WFHAMM WFHANN WFBLKM AOPADD AOPSUB AOPMUL AOPDIV AOPMAD AOPLIP AOPCLP")

' 字句解析

def lex string$, tk$[], type[]
	var record$ = ""
	var phase = NONE
	var index = 0
	var isRecorded = false

	while true
		var c$ = mid$(string$, index, 1)

		if c$ == chr$(34) && phase != NONE then
			phase = STRING
			isRecorded = true
			inc index
		elseif c$ == chr$(34) && phase == STRING then
			push type, phase : phase = NONE
			push tk$, record$ + chr$(34)
			record$ = ""
			isRecorded = false
			inc index
		elseif phase == STRING && index != len(string$) - 1 then
			inc index
		elseif c$ == chr$(34) && phase != STRING then
			if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
			if indexOf$(operators$, upcase(record$)) != -1 then phase = OPERATOR
			if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
			push type, phase : phase = NONE
			push tk$, record$
			record$ = ""
			phase = STRING
			inc index
		elseif c$ == "#" then
			phase = DIRECTION
			isRecorded = true
			inc index
		elseif c$ == " " || index == len(string$) - 1 then
			if phase == UNKNOWN then
				if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
				if indexOf$(operators$, upcase$(record$)) != -1 then phase = OPERATOR
			endif
			if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
			if phase == STRING then ? "Error: 文字列定数がダブルクォートによって正しく閉じられていません" : break
			if phase != NONE then
				push type, phase : phase = NONE
				push tk$, record$
				record$ = ""
				isRecorded = false
			endif
			inc index
		elseif c$ != " " && !isRecorded then
			phase = UNKNOWN
			isRecorded = true
			inc index
		else
			inc index
		endif

		if isRecorded then record$ = record$ + c$
		if index >= len(string$) then break
	wend
end

var i, n
for n = 0 to prgSize(1) - 1
	dim tk$[0]
	dim type[0]
	lex prgGet$(), tk$, type
	for i = 0 to len(tk$)
		? tk$[i] + " " + str$(type[i])
	next
next


codegen/QtGamepad: updated

codegen/QtGamepad: updated

Modified:
codegen/QtGamepad/QGamepadManager.prg

%%
%% Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

$addRequests

$beginClassFrom=QObject

$addMethods

$addSignals

$endClass

$destructor

#pragma BEGINDUMP

$includes=5,9,0

$prototype=QGamepadManager() [private]

$prototype=~QGamepadManager() [private]
%% $deleteMethod

%%
%% Q_PROPERTY(QList<int> connectedGamepads READ connectedGamepads NOTIFY connectedGamepadsChanged)
%%

$prototype=const QList<int> connectedGamepads() const
%% TODO: const QList<int>
%% $method=5,9,0|const QList<int>|connectedGamepads|

%%
%%
%%

$prototype=static QGamepadManager* instance()
$staticMethod=5,9,0|QGamepadManager *|instance|

$prototype=bool isGamepadConnected(int deviceId) const
$method=5,9,0|bool|isGamepadConnected|int

$prototype=bool isConfigurationNeeded(int deviceId) const (slot)
$slotMethod=5,9,0|bool|isConfigurationNeeded|int

$prototype=bool configureButton(int deviceId, GamepadButton button) (slot)
$slotMethod=5,9,0|bool|configureButton|int,QGamepadManager::GamepadButton

$prototype=bool configureAxis(int deviceId, GamepadAxis axis) (slot)
$slotMethod=5,9,0|bool|configureAxis|int,QGamepadManager::GamepadAxis

$prototype=bool setCancelConfigureButton(int deviceId, GamepadButton button) (slot)
$slotMethod=5,9,0|bool|setCancelConfigureButton|int,QGamepadManager::GamepadButton

$prototype=void resetConfiguration(int deviceId) (slot)
$slotMethod=5,9,0|void|resetConfiguration|int

$prototype=void setSettingsFile(const QString &file) (slot)
$slotMethod=5,9,0|void|setSettingsFile|const QString &

$beginSignals
$signal=5,9,0|axisConfigured(int,QGamepadManager::GamepadAxis)
$signal=5,9,0|buttonConfigured(int,QGamepadManager::GamepadButton)
$signal=5,9,0|configurationCanceled(int)
$signal=5,9,0|connectedGamepadsChanged()
$signal=5,9,0|gamepadAxisEvent(int,QGamepadManager::GamepadAxis,double)
$signal=5,9,0|gamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)
$signal=5,9,0|gamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)
$signal=5,9,0|gamepadConnected(int)
$signal=5,9,0|gamepadDisconnected(int)
$endSignals

#pragma ENDDUMP

%%
%% Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

$addRequests

$beginClassFrom=QObject

$addMethods

$addSignals

$endClass

$destructor

#pragma BEGINDUMP

$includes=5,9,0

$prototype=QGamepadManager() (private)

$prototype=~QGamepadManager() (private)
%% $deleteMethod

%%
%% Q_PROPERTY(QList<int> connectedGamepads READ connectedGamepads NOTIFY connectedGamepadsChanged)
%%

$prototype=const QList<int> connectedGamepads() const
%% TODO: const QList<int>
%% $method=5,9,0|const QList<int>|connectedGamepads|

%%
%%
%%

$prototype=static QGamepadManager* instance()
$staticMethod=5,9,0|QGamepadManager *|instance|

$prototype=bool isGamepadConnected(int deviceId) const
$method=5,9,0|bool|isGamepadConnected|int

$prototype=bool isConfigurationNeeded(int deviceId) const (slot)
$slotMethod=5,9,0|bool|isConfigurationNeeded|int

$prototype=bool configureButton(int deviceId, GamepadButton button) (slot)
$slotMethod=5,9,0|bool|configureButton|int,QGamepadManager::GamepadButton

$prototype=bool configureAxis(int deviceId, GamepadAxis axis) (slot)
$slotMethod=5,9,0|bool|configureAxis|int,QGamepadManager::GamepadAxis

$prototype=bool setCancelConfigureButton(int deviceId, GamepadButton button) (slot)
$slotMethod=5,9,0|bool|setCancelConfigureButton|int,QGamepadManager::GamepadButton

$prototype=void resetConfiguration(int deviceId) (slot)
$slotMethod=5,9,0|void|resetConfiguration|int

$prototype=void setSettingsFile(const QString &file) (slot)
$slotMethod=5,9,0|void|setSettingsFile|const QString &

$beginSignals
$signal=5,9,0|axisConfigured(int,QGamepadManager::GamepadAxis)
$signal=5,9,0|buttonConfigured(int,QGamepadManager::GamepadButton)
$signal=5,9,0|configurationCanceled(int)
$signal=5,9,0|connectedGamepadsChanged()
$signal=5,9,0|gamepadAxisEvent(int,QGamepadManager::GamepadAxis,double)
$signal=5,9,0|gamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)
$signal=5,9,0|gamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)
$signal=5,9,0|gamepadConnected(int)
$signal=5,9,0|gamepadDisconnected(int)
$endSignals

#pragma ENDDUMP


[RDD] VFP no longer removes the fieldname when the alias is added.

//
// Copyright (c) B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING XSharp.RDD.Enums
USING XSharp.RDD.Support
USING System.IO
USING System.Collections.Generic
USING System.Diagnostics

BEGIN NAMESPACE XSharp.RDD
/// <summary>DBFVFP RDD. DBFCDX with support for the FoxPro field types.</summary>
[DebuggerDisplay("DBFVFP ({Alias,nq})")];
CLASS DBFVFP INHERIT DBFCDX
    PRIVATE CONST VFP_BACKLINKSIZE := 262 AS LONG
	CONSTRUCTOR()
		SUPER()
		SELF:_AllowedFieldTypes := "BCDFGILMNPQTVWY0"
		RETURN

	PUBLIC   PROPERTY Driver                  AS STRING GET "DBFVFP"
    INTERNAL PROPERTY DbcName        AS STRING AUTO
    INTERNAL PROPERTY DbcPosition    AS INT GET DbfHeader.SIZE + SELF:_Fields:Length  * DbfField.SIZE +1

    PUBLIC OVERRIDE METHOD Create( openInfo AS DbOpenInfo ) AS LOGIC
	LOCAL isOk AS LOGIC
    isOk := SUPER:Create(openInfo)
    IF isOk
        SELF:_SetFoxHeader()
    ENDIF
    SELF:_ReadDbcInfo()
    RETURN isOk

    PROTECTED VIRTUAL METHOD _checkField( dbffld REF DbfField) AS LOGIC
        IF dbffld:Type:IsVfp()
            IF dbffld:Flags:HasFlag(DBFFieldFlags.AutoIncrement)
                IF dbffld:Counter == 0
                    dbffld:Counter := 1
                ENDIF
                IF dbffld:IncStep == 0
                    dbffld:IncStep := 1
                ENDIF
            ENDIF
            RETURN TRUE
        ENDIF
        RETURN FALSE

     PROTECTED METHOD _SetFoxHeader() AS VOID
        LOCAL lVar AS LOGIC
        LOCAL lAutoIncr AS LOGIC
        // check for foxpro field types and adjust the header
        lVar        := FALSE
        lAutoIncr   := FALSE
        FOREACH VAR fld IN _Fields
            SWITCH fld:FieldType
            CASE DbFieldType.VarChar
            CASE DbFieldType.VarBinary
            CASE DbFieldType.Blob
                lVar := TRUE
            END SWITCH
            IF fld:Flags:HasFlag(DBFFieldFlags.AutoIncrement)
                lAutoIncr := TRUE
            ENDIF
        NEXT
        IF lAutoIncr
            IF lVar
                SELF:_Header:Version := DBFVersion.VisualFoxProVarChar
            ELSE
                SELF:_Header:Version := DBFVersion.VisualFoxProAutoIncrement
            ENDIF
        ELSEIF lVar
            SELF:_Header:Version := DBFVersion.VisualFoxProVarChar
        ELSE
            SELF:_Header:Version := DBFVersion.VisualFoxPro
        ENDIF
        // Set Flags
        SELF:_Header:TableFlags := DBFTableFlags.None
        IF SELF:_HasMemo
            SELF:_Header:TableFlags |= DBFTableFlags.HasMemoField
        ENDIF
        IF SELF:_indexList != NULL .AND. SELF:_indexList:Count > 0
            VAR orderBag := SELF:_indexList:First
            IF orderBag != NULL .AND. orderBag:Structural
                SELF:_Header:TableFlags |= DBFTableFlags.HasStructuralCDX
            ENDIF
        ENDIF

        SELF:_Header:HeaderLen += VFP_BACKLINKSIZE
        SELF:_HeaderLength   += VFP_BACKLINKSIZE
        SELF:_writeHeader()
        // Adjust the file size to accomodate the backlink data
        _oStream:SafeSetLength(SELF:_HeaderLength)
        RETURN

    /// <inheritdoc />
    METHOD CreateFields(aFields AS RddFieldInfo[]) AS LOGIC
        LOCAL NullCount := 0 AS LONG
        LOCAL nullFld  := NULL AS RddFieldInfo
        LOCAL lOk := FALSE as LOGIC
        FOREACH VAR fld IN aFields
            IF fld:IsNullable
                NullCount += 1
            ENDIF
            IF fld:IsVarLength
                NullCount += 1
            ENDIF
            IF String.Compare(fld:Name, _NULLFLAGS, TRUE) == 0
                nullFld := fld
                fld:Name := _NULLFLAGS
            ENDIF
        NEXT
        IF nullFld != NULL
            LOCAL nLen AS LONG
            nLen := NullCount / 8
            IF NullCount %8 != 0
                nLen += 1
            ENDIF
            nullFld:Length := (BYTE) nLen
        ENDIF
        lOk := SUPER:CreateFields(aFields)
        RETURN lOk

        PROPERTY FieldCount AS LONG
        GET
            // Exclude the _NullColumn
            LOCAL ret := 0 AS LONG
            IF SELF:_Fields != NULL
                ret := SELF:_Fields:Length
                IF SELF:_NullColumn != NULL
                    ret -= 1
                ENDIF
            ENDIF
            RETURN ret
        END GET
        END PROPERTY

    METHOD Open ( info AS DbOpenInfo) AS LOGIC
        LOCAL lOk AS LOGIC
        LOCAL lOld AS LOGIC
        // Delay auto open until after we have read the DBC name and we have read the long fieldnames
        lOld := XSharp.RuntimeState.AutoOpen
        XSharp.RuntimeState.AutoOpen := FALSE
        lOk := SUPER:Open(info)
        XSharp.RuntimeState.AutoOpen := lOld
        IF lOk
            IF SELF:_Header:Version:IsVfp()
                SELF:_ReadDbcInfo()
            ENDIF
            IF XSharp.RuntimeState.AutoOpen
                SELF:OpenProductionIndex(info)
            ENDIF
            SELF:GoTop()
        ENDIF

        RETURN lOk

    METHOD FieldInfo(nFldPos AS LONG, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
        IF nOrdinal == DbFieldInfo.DBS_PROPERTIES
           RETURN DbFieldInfo.DBS_FLAGS
        ENDIF
        RETURN SUPER:FieldInfo(nFldPos, nOrdinal, oNewValue)

    PROTECTED METHOD _ReadDbcInfo() AS VOID
        LOCAL nPos := SELF:DbcPosition AS LONG
        LOCAL buffer AS BYTE[]
        buffer := BYTE[]{VFP_BACKLINKSIZE}
        SELF:DbcName := ""
        IF _oStream:SafeSetPos(nPos) .AND. _oStream:SafeRead(buffer)
            VAR cName := System.Text.Encoding.Default:GetString(buffer):Replace(e"\0","")
            IF ! String.IsNullOrEmpty(cName)
                SELF:DbcName := Path.Combine(Path.GetDirectoryName(SELF:_FileName), cName)
                SELF:_ReadDbcFieldNames()
            ENDIF
        ENDIF
        RETURN

    PROTECTED METHOD _ReadDbcFieldNames() AS VOID
        LOCAL oDbc AS DBFVFP
        LOCAL oi   AS DbOpenInfo
        LOCAL nTable := 0 AS LONG
        LOCAL nType AS LONG
        LOCAL nName AS LONG
        LOCAL nParent AS LONG
        LOCAL nProp AS LONG
        LOCAL fields AS List<STRING>
        LOCAL props  AS List<byte[]>
        LOCAL cFile AS STRING
        LOCAL lOk AS LOGIC
        LOCAL lOld AS LOGIC
        oDbc := DBFVFP{}
        oi := DbOpenInfo{}
        oi:FileName  := SELF:DbcName
        oi:Extension := System.IO.Path.GetExtension(SELF:DbcName)
        oi:Shared   := TRUE
        oi:ReadOnly := TRUE
        cFile := System.IO.Path.GetFileNameWithoutExtension(SELF:_FileName)
        lOld := XSharp.RuntimeState.AutoOpen
        XSharp.RuntimeState.AutoOpen := FALSE
        TRY
            lOk := oDbc:Open(oi)
        CATCH as Exception
            lOk := FALSE
        END TRY
        XSharp.RuntimeState.AutoOpen := lOld
        IF lOk
            nType   := oDbc:FieldIndex("OBJECTTYPE")
            nName   := oDbc:FieldIndex("OBJECTNAME")
            nParent := oDbc:FieldIndex("PARENTID")
            nProp   := oDbc:FieldIndex("PROPERTY")
            oDbc:GoTop()
            DO WHILE ! oDbc:EoF
                IF ((STRING)oDbc:GetValue(nType)):StartsWith("Table")
                    LOCAL cName := (STRING) oDbc:GetValue(nName)  AS STRING
                    cName := cName:Trim()
                    IF String.Compare(cName, cFile, TRUE) == 0
                        nTable := (INT) oDbc:GetValue(oDbc:FieldIndex("OBJECTID"))
                        EXIT
                    ENDIF
                ENDIF
                oDbc:Skip(1)
            ENDDO
            fields := List<STRING>{}
            props  := List<byte[]>{}

            IF nTable != 0
                oDbc:GoTop()
                DO WHILE ! oDbc:EoF
                    VAR n1 := (LONG) oDbc:GetValue(nParent)
                    VAR c1 := (STRING) oDbc:GetValue(nType)
                    IF n1== nTable .AND.  c1:StartsWith("Field")
                        VAR cAlias := (STRING) oDbc:GetValue(nName)
                        VAR b1 := (BYTE[]) oDbc:Memo:GetValue(nProp)
                        fields:Add(cAlias:Trim())
                        props:Add(b1)
                    ENDIF
                    oDbc:Skip(1)
                ENDDO
            ENDIF
            oDbc:Close()
            IF SELF:FieldCount == fields:Count
                // assign aliases
                LOCAL nPos AS LONG
                FOR nPos := 1 TO SELF:FieldCount
                    LOCAL oColumn AS DbfColumn
                    oColumn := SELF:_GetColumn(nPos) ASTYPE DbfColumn
                    SetColumnProperties(oColumn, props[nPos-1])
                    oColumn:Alias := fields[nPos-1]
                    oColumn:ColumnName := fields[nPos-1]
                    IF String.Compare(oColumn:Name, oColumn:Alias, TRUE) != 0
                        // We add the alias as alternative to the fieldname.
                        // As a result we can call FieldIndex with the alias AND the fieldName
                        SELF:_fieldNames:Add(oColumn:Alias:ToUpper(), nPos-1)
                    ENDIF
                NEXT
            ENDIF
        ENDIF

    PRIVATE METHOD SetColumnProperties(oColumn as RddFieldInfo, bProps AS BYTE[]) AS VOID
        VAR token  := FtpMemoToken{bProps}
        VAR length := token:Length
        Debug.Assert(token.DataType == FlexFieldType.String )
        Debug.Assert(length == bProps.Length-8)
        VAR pos := 8
        DO WHILE pos < bProps:Length
            VAR len  := (LONG) bProps[pos]
            VAR type := FoxToLong(bProps, pos+1)
            Debug.Assert(type == FlexFieldType.String )
            VAR prop := (LONG) FoxToShort(bProps, pos+5)
            VAR strValue := SELF:_Encoding:GetString(bProps, pos+7, len-8)
            pos += len
            oColumn:Properties:Add((DatabasePropertyType) prop, strValue)
        ENDDO
        RETURN

    /// <inheritdoc />
    METHOD AddField(info AS RddFieldInfo) AS LOGIC
        LOCAL isOk AS LOGIC
        isOk := SUPER:AddField( info )
        IF String.Compare(info:Name, _NULLFLAGS,TRUE) == 0 .AND. info IS DbfNullColumn VAR dbfnc
            SELF:_NullColumn := dbfnc
        ENDIF
        IF info IS DbfColumn VAR column
            IF column:IsVarLength
                column:LengthBit := SELF:_NullCount++
            ENDIF
            IF column:IsNullable
                column:NullBit := SELF:_NullCount++
            ENDIF
        ENDIF
        RETURN isOk

    OVERRIDE PROTECTED METHOD _readRecord() AS LOGIC
        LOCAL lOk AS LOGIC
        LOCAL lMustReadNull AS LOGIC
        lMustReadNull := ! SELF:_BufferValid
        lOk := SUPER:_readRecord()
        IF lOk .AND. SELF:_NullColumn != NULL .AND. lMustReadNull
            SELF:_NullColumn:GetValue(SELF:_RecordBuffer)
        ENDIF
        RETURN lOk

    OVERRIDE PROTECTED METHOD _writeRecord() AS LOGIC
        // Write VFP Null flags, if any
        IF SELF:_NullColumn != NULL .AND. ! SELF:_ReadOnly
            SELF:_NullColumn:PutValue(0, SELF:_RecordBuffer)
        ENDIF
        RETURN SUPER:_writeRecord()
END CLASS

END NAMESPACE

//
// Copyright (c) B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING XSharp.RDD.Enums
USING XSharp.RDD.Support
USING System.IO
USING System.Collections.Generic
USING System.Diagnostics

BEGIN NAMESPACE XSharp.RDD
/// <summary>DBFVFP RDD. DBFCDX with support for the FoxPro field types.</summary>
[DebuggerDisplay("DBFVFP ({Alias,nq})")];
CLASS DBFVFP INHERIT DBFCDX
    PRIVATE CONST VFP_BACKLINKSIZE := 262 AS LONG
	CONSTRUCTOR()
		SUPER()
		SELF:_AllowedFieldTypes := "BCDFGILMNPQTVWY0"
		RETURN

	PUBLIC   PROPERTY Driver                  AS STRING GET "DBFVFP"
    INTERNAL PROPERTY DbcName        AS STRING AUTO
    INTERNAL PROPERTY DbcPosition    AS INT GET DbfHeader.SIZE + SELF:_Fields:Length  * DbfField.SIZE +1

    PUBLIC OVERRIDE METHOD Create( openInfo AS DbOpenInfo ) AS LOGIC
	LOCAL isOk AS LOGIC
    isOk := SUPER:Create(openInfo)
    IF isOk
        SELF:_SetFoxHeader()
    ENDIF
    SELF:_ReadDbcInfo()
    RETURN isOk

    PROTECTED VIRTUAL METHOD _checkField( dbffld REF DbfField) AS LOGIC
        IF dbffld:Type:IsVfp()
            IF dbffld:Flags:HasFlag(DBFFieldFlags.AutoIncrement)
                IF dbffld:Counter == 0
                    dbffld:Counter := 1
                ENDIF
                IF dbffld:IncStep == 0
                    dbffld:IncStep := 1
                ENDIF
            ENDIF
            RETURN TRUE
        ENDIF
        RETURN FALSE

     PROTECTED METHOD _SetFoxHeader() AS VOID
        LOCAL lVar AS LOGIC
        LOCAL lAutoIncr AS LOGIC
        // check for foxpro field types and adjust the header
        lVar        := FALSE
        lAutoIncr   := FALSE
        FOREACH VAR fld IN _Fields
            SWITCH fld:FieldType
            CASE DbFieldType.VarChar
            CASE DbFieldType.VarBinary
            CASE DbFieldType.Blob
                lVar := TRUE
            END SWITCH
            IF fld:Flags:HasFlag(DBFFieldFlags.AutoIncrement)
                lAutoIncr := TRUE
            ENDIF
        NEXT
        IF lAutoIncr
            IF lVar
                SELF:_Header:Version := DBFVersion.VisualFoxProVarChar
            ELSE
                SELF:_Header:Version := DBFVersion.VisualFoxProAutoIncrement
            ENDIF
        ELSEIF lVar
            SELF:_Header:Version := DBFVersion.VisualFoxProVarChar
        ELSE
            SELF:_Header:Version := DBFVersion.VisualFoxPro
        ENDIF
        // Set Flags
        SELF:_Header:TableFlags := DBFTableFlags.None
        IF SELF:_HasMemo
            SELF:_Header:TableFlags |= DBFTableFlags.HasMemoField
        ENDIF
        IF SELF:_indexList != NULL .AND. SELF:_indexList:Count > 0
            VAR orderBag := SELF:_indexList:First
            IF orderBag != NULL .AND. orderBag:Structural
                SELF:_Header:TableFlags |= DBFTableFlags.HasStructuralCDX
            ENDIF
        ENDIF

        SELF:_Header:HeaderLen += VFP_BACKLINKSIZE
        SELF:_HeaderLength   += VFP_BACKLINKSIZE
        SELF:_writeHeader()
        // Adjust the file size to accomodate the backlink data
        _oStream:SafeSetLength(SELF:_HeaderLength)
        RETURN

    /// <inheritdoc />
    METHOD CreateFields(aFields AS RddFieldInfo[]) AS LOGIC
        LOCAL NullCount := 0 AS LONG
        LOCAL nullFld  := NULL AS RddFieldInfo
        LOCAL lOk := FALSE as LOGIC
        FOREACH VAR fld IN aFields
            IF fld:IsNullable
                NullCount += 1
            ENDIF
            IF fld:IsVarLength
                NullCount += 1
            ENDIF
            IF String.Compare(fld:Name, _NULLFLAGS, TRUE) == 0
                nullFld := fld
                fld:Name := _NULLFLAGS
            ENDIF
        NEXT
        IF nullFld != NULL
            LOCAL nLen AS LONG
            nLen := NullCount / 8
            IF NullCount %8 != 0
                nLen += 1
            ENDIF
            nullFld:Length := (BYTE) nLen
        ENDIF
        lOk := SUPER:CreateFields(aFields)
        RETURN lOk

        PROPERTY FieldCount AS LONG
        GET
            // Exclude the _NullColumn
            LOCAL ret := 0 AS LONG
            IF SELF:_Fields != NULL
                ret := SELF:_Fields:Length
                IF SELF:_NullColumn != NULL
                    ret -= 1
                ENDIF
            ENDIF
            RETURN ret
        END GET
        END PROPERTY

    METHOD Open ( info AS DbOpenInfo) AS LOGIC
        LOCAL lOk AS LOGIC
        LOCAL lOld AS LOGIC
        // Delay auto open until after we have read the DBC name and we have read the long fieldnames
        lOld := XSharp.RuntimeState.AutoOpen
        XSharp.RuntimeState.AutoOpen := FALSE
        lOk := SUPER:Open(info)
        XSharp.RuntimeState.AutoOpen := lOld
        IF lOk
            IF SELF:_Header:Version:IsVfp()
                SELF:_ReadDbcInfo()
            ENDIF
            IF XSharp.RuntimeState.AutoOpen
                SELF:OpenProductionIndex(info)
            ENDIF
            SELF:GoTop()
        ENDIF

        RETURN lOk

    METHOD FieldInfo(nFldPos AS LONG, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
        IF nOrdinal == DbFieldInfo.DBS_PROPERTIES
           RETURN DbFieldInfo.DBS_FLAGS
        ENDIF
        RETURN SUPER:FieldInfo(nFldPos, nOrdinal, oNewValue)

    PROTECTED METHOD _ReadDbcInfo() AS VOID
        LOCAL nPos := SELF:DbcPosition AS LONG
        LOCAL buffer AS BYTE[]
        buffer := BYTE[]{VFP_BACKLINKSIZE}
        SELF:DbcName := ""
        IF _oStream:SafeSetPos(nPos) .AND. _oStream:SafeRead(buffer)
            VAR cName := System.Text.Encoding.Default:GetString(buffer):Replace(e"\0","")
            IF ! String.IsNullOrEmpty(cName)
                SELF:DbcName := Path.Combine(Path.GetDirectoryName(SELF:_FileName), cName)
                SELF:_ReadDbcFieldNames()
            ENDIF
        ENDIF
        RETURN

    PROTECTED METHOD _ReadDbcFieldNames() AS VOID
        LOCAL oDbc AS DBFVFP
        LOCAL oi   AS DbOpenInfo
        LOCAL nTable := 0 AS LONG
        LOCAL nType AS LONG
        LOCAL nName AS LONG
        LOCAL nParent AS LONG
        LOCAL nProp AS LONG
        LOCAL fields AS List<STRING>
        LOCAL props  AS List<byte[]>
        LOCAL cFile AS STRING
        LOCAL lOk AS LOGIC
        LOCAL lOld AS LOGIC
        oDbc := DBFVFP{}
        oi := DbOpenInfo{}
        oi:FileName  := SELF:DbcName
        oi:Extension := System.IO.Path.GetExtension(SELF:DbcName)
        oi:Shared   := TRUE
        oi:ReadOnly := TRUE
        cFile := System.IO.Path.GetFileNameWithoutExtension(SELF:_FileName)
        lOld := XSharp.RuntimeState.AutoOpen
        XSharp.RuntimeState.AutoOpen := FALSE
        TRY
            lOk := oDbc:Open(oi)
        CATCH as Exception
            lOk := FALSE
        END TRY
        XSharp.RuntimeState.AutoOpen := lOld
        IF lOk
            nType   := oDbc:FieldIndex("OBJECTTYPE")
            nName   := oDbc:FieldIndex("OBJECTNAME")
            nParent := oDbc:FieldIndex("PARENTID")
            nProp   := oDbc:FieldIndex("PROPERTY")
            oDbc:GoTop()
            DO WHILE ! oDbc:EoF
                IF ((STRING)oDbc:GetValue(nType)):StartsWith("Table")
                    LOCAL cName := (STRING) oDbc:GetValue(nName)  AS STRING
                    cName := cName:Trim()
                    IF String.Compare(cName, cFile, TRUE) == 0
                        nTable := (INT) oDbc:GetValue(oDbc:FieldIndex("OBJECTID"))
                        EXIT
                    ENDIF
                ENDIF
                oDbc:Skip(1)
            ENDDO
            fields := List<STRING>{}
            props  := List<byte[]>{}

            IF nTable != 0
                oDbc:GoTop()
                DO WHILE ! oDbc:EoF
                    VAR n1 := (LONG) oDbc:GetValue(nParent)
                    VAR c1 := (STRING) oDbc:GetValue(nType)
                    IF n1== nTable .AND.  c1:StartsWith("Field")
                        VAR cAlias := (STRING) oDbc:GetValue(nName)
                        VAR b1 := (BYTE[]) oDbc:Memo:GetValue(nProp)
                        fields:Add(cAlias:Trim())
                        props:Add(b1)
                    ENDIF
                    oDbc:Skip(1)
                ENDDO
            ENDIF
            oDbc:Close()
            IF SELF:FieldCount == fields:Count
                // assign aliases
                LOCAL nPos AS LONG
                FOR nPos := 1 TO SELF:FieldCount
                    LOCAL oColumn AS DbfColumn
                    oColumn := SELF:_GetColumn(nPos) ASTYPE DbfColumn
                    SetColumnProperties(oColumn, props[nPos-1])
                    oColumn:Alias := fields[nPos-1]
                    oColumn:ColumnName := fields[nPos-1]
                    IF String.Compare(oColumn:Name, oColumn:Alias, TRUE) != 0
                        SELF:_fieldNames:Remove(oColumn:Name)
                        SELF:_fieldNames:Add(oColumn:Alias, nPos-1)
                    ENDIF
                NEXT
            ENDIF
        ENDIF

    PRIVATE METHOD SetColumnProperties(oColumn as RddFieldInfo, bProps AS BYTE[]) AS VOID
        VAR token  := FtpMemoToken{bProps}
        VAR length := token:Length
        Debug.Assert(token.DataType == FlexFieldType.String )
        Debug.Assert(length == bProps.Length-8)
        VAR pos := 8
        DO WHILE pos < bProps:Length
            VAR len  := (LONG) bProps[pos]
            VAR type := FoxToLong(bProps, pos+1)
            Debug.Assert(type == FlexFieldType.String )
            VAR prop := (LONG) FoxToShort(bProps, pos+5)
            VAR strValue := SELF:_Encoding:GetString(bProps, pos+7, len-8)
            pos += len
            oColumn:Properties:Add((DatabasePropertyType) prop, strValue)
        ENDDO
        RETURN

    /// <inheritdoc />
    METHOD AddField(info AS RddFieldInfo) AS LOGIC
        LOCAL isOk AS LOGIC
        isOk := SUPER:AddField( info )
        IF String.Compare(info:Name, _NULLFLAGS,TRUE) == 0 .AND. info IS DbfNullColumn VAR dbfnc
            SELF:_NullColumn := dbfnc
        ENDIF
        IF info IS DbfColumn VAR column
            IF column:IsVarLength
                column:LengthBit := SELF:_NullCount++
            ENDIF
            IF column:IsNullable
                column:NullBit := SELF:_NullCount++
            ENDIF
        ENDIF
        RETURN isOk

    OVERRIDE PROTECTED METHOD _readRecord() AS LOGIC
        LOCAL lOk AS LOGIC
        LOCAL lMustReadNull AS LOGIC
        lMustReadNull := ! SELF:_BufferValid
        lOk := SUPER:_readRecord()
        IF lOk .AND. SELF:_NullColumn != NULL .AND. lMustReadNull
            SELF:_NullColumn:GetValue(SELF:_RecordBuffer)
        ENDIF
        RETURN lOk

    OVERRIDE PROTECTED METHOD _writeRecord() AS LOGIC
        // Write VFP Null flags, if any
        IF SELF:_NullColumn != NULL .AND. ! SELF:_ReadOnly
            SELF:_NullColumn:PutValue(0, SELF:_RecordBuffer)
        ENDIF
        RETURN SUPER:_writeRecord()
END CLASS

END NAMESPACE


[Tests] Added Function Overload test

[Tests] Added Function Overload test

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit

// WinBool test
BEGIN NAMESPACE XSharp.VO.Tests

	CLASS MacroTests

		[Fact, Trait("Category", "Macro")];
		METHOD Tests AS VOID
			LOCAL cMacro AS STRING
			LOCAL bMacro AS USUAL
			LOCAL uValue AS USUAL
			cMacro := "1+1"
			uValue := &(cMacro)
			Assert.Equal (2, (INT) uValue)
			cMacro := "{||1+2}"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro)
			Assert.Equal (3, (INT) uValue)
			cMacro := "{||SQrt(25)}"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro)
			Assert.Equal (5, (INT) uValue)
			cMacro := e"{|aaa,bbb| \"aaa\" + \"bbb\" }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal ("aaabbb", (STRING) uValue)
			cMacro := "{|aaa,bbb| aaa + bbb }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal (42, (INT) uValue)

            cMacro := "{| a, b, c |  'a' $ 'a|b|c|d' }"
            //cMacro := "{| a,b,c| c == a + b}"
            bMacro := MCompile(cMacro,TRUE)
			uValue := Eval(bMacro,1,2,3)
            Assert.Equal (TRUE, (LOGIC) uValue)
			cMacro := "{|aaa , bbb| aaa + bbb }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal (42, (INT) uValue)
		    cMacro := "{|aaa , bbb| aaa + bbb + ccc }" // not existing field
			bMacro := MCompile(cMacro)
	        Assert.ThrowsAny<Exception>( { => Eval(bMacro,20,22) })
            RETURN

		[Fact, Trait("Category", "Macro")];
		METHOD FunctionOverloadTest AS VOID
			LOCAL cMacro AS STRING
			LOCAL bMacro AS USUAL
		    cMacro := "Left('abcdefg',2)" // not existing field
			bMacro := MCompile(cMacro)

            Assert.Equal("MyLeft", eval(bMacro))

            RETURN

	END CLASS
END NAMESPACE // XSharp.Runtime.Tests

FUNCTION Left(cValue as STRING, nLen as DWORD) AS STRING
    RETURN "MyLeft"

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit

// WinBool test
BEGIN NAMESPACE XSharp.VO.Tests

	CLASS MacroTests

		[Fact, Trait("Category", "Macro")];
		METHOD Tests AS VOID
			LOCAL cMacro AS STRING
			LOCAL bMacro AS USUAL
			LOCAL uValue AS USUAL
			cMacro := "1+1"
			uValue := &(cMacro)
			Assert.Equal (2, (INT) uValue)
			cMacro := "{||1+2}"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro)
			Assert.Equal (3, (INT) uValue)
			cMacro := "{||SQrt(25)}"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro)
			Assert.Equal (5, (INT) uValue)
			cMacro := e"{|aaa,bbb| \"aaa\" + \"bbb\" }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal ("aaabbb", (STRING) uValue)
			cMacro := "{|aaa,bbb| aaa + bbb }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal (42, (INT) uValue)

            cMacro := "{| a, b, c |  'a' $ 'a|b|c|d' }"
            //cMacro := "{| a,b,c| c == a + b}"
            bMacro := MCompile(cMacro,TRUE)
			uValue := Eval(bMacro,1,2,3)
            Assert.Equal (TRUE, (LOGIC) uValue)
			cMacro := "{|aaa , bbb| aaa + bbb }"
			bMacro := MCompile(cMacro)
			uValue := Eval(bMacro,20,22)
			Assert.Equal (42, (INT) uValue)
		    cMacro := "{|aaa , bbb| aaa + bbb + ccc }" // not existing field
			bMacro := MCompile(cMacro)
	        Assert.ThrowsAny<Exception>( { => Eval(bMacro,20,22) })

            RETURN

	END CLASS
END NAMESPACE // XSharp.Runtime.Tests


codegen/QtXml/QDomComment.prg: fixed

codegen/QtXml/QDomComment.prg: fixed

%%
%% Qt4xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 4
%%
%% Copyright (C) 2020 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$project=Qt4xHb
$module=QtXml

$header

#include "hbclass.ch"

$addRequests

$beginClassFrom=QDomCharacterData

$addMethods

$endClass

$destructor

#pragma BEGINDUMP

$includes

$prototype=QDomComment ()
$internalConstructor=|new1|

$prototype=QDomComment ( const QDomComment & x )
$internalConstructor=|new2|const QDomComment &

/*
[1]QDomComment ()
[2]QDomComment ( const QDomComment & x )
*/

HB_FUNC_STATIC( QDOMCOMMENT_NEW )
{
  if( ISNUMPAR(0) )
  {
    QDomComment_new1();
  }
  else if( ISNUMPAR(1) && ISQDOMCOMMENT(1) )
  {
    QDomComment_new2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}
$addMethod=new

$prototypeV2=QDomNode::NodeType nodeType() const

#pragma ENDDUMP

%%
%% Qt4xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 4
%%
%% Copyright (C) 2020 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$project=Qt4xHb
$module=QtXml

$header

#include "hbclass.ch"

$addRequests

$beginClassFrom=QDomCharacterData

$addMethods

$endClass

$destructor

#pragma BEGINDUMP

$includes

$prototype=QDomComment ()
$internalConstructor=|new1|

$prototype=QDomComment ( const QDomComment & x )
$internalConstructor=|new2|const QDomComment &

/*
[1]QDomComment ()
[2]QDomComment ( const QDomComment & x )
*/

HB_FUNC_STATIC( QDOMCOMMENT_NEW )
{
  if( ISNUMPAR(0) )
  {
    QDomComment_new1();
  }
  else if( ISNUMPAR(1) && ISQDOMCOMMENT(1) )
  {
    QDomComment_new2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}
$addMethod=new

$prototypeV2=QDomNode::NodeType nodeType() cons

#pragma ENDDUMP