Getting Started with X# -- Converting a VFP Application or DLL

This forum is meant for questions about the Visual FoxPro Language support in X#.

Jeff Stone
Posts: 34
Joined: Fri Jun 07, 2019 4:16 pm

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Jeff Stone »

Hi Wolfgang,

Other than code to work with .DBC files, I previously was able to adjust the .DLL code compile successfully with Harbour. Most of the code seems to compile in X# okay. I only see three issues:
1. The line:
DELETE FILE temp.dbf
is generating "error XS9002: Parser: unexpected input 'file' which makes no sense
2. We use a bunch of ALTER TABLE commands. Each one is generating an error like:
"warning XS1030: #warning: ' This command is not (yet) supported:"alter table (laliasname) ADD COLUMN (lfieldname) B(2)"
3. DEFINE CLASS fpimport AS Relation OLEPUBLIC is generating the message: "warning XS9230: The 'OLEPUBLIC' clause is not supported and ignored."

I know you probably cannot help with #3. #1 is surprising. Perhaps I need to include another GAC reference? Regarding #2, I cannot find any X# command or function to add a field to table. Do you know if one exists?

Thanks in advance again,

Jeff
User avatar
Chris
Posts: 4583
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Chris »

Hi Jeff,

Regarding 1, apparently this command definition is missing from X#, we will add it in the next build. For now, you can add this in the beginning of your .prg and it will work:

Code: Select all

#command DELETE FILE <(filename)> => System.IO.File.Delete(<(filename)>)

For 2 and 3, I will let Robert/Fabrice comment, but please keep in mind that VFP support in X# is still a work in progress, so you must expect some things not being supported yet.

Also regarding XIDE, I (as the author of it) must admit that VFP support in it is not very well done (being a former Visual Objects developer myself, XIDE works best for VO developers), so you may want to try also Visual Studio, where VFP support is much more complete, so it might make things easier for you.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Jeff Stone
Posts: 34
Joined: Fri Jun 07, 2019 4:16 pm

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Jeff Stone »

Hi Chris,

I suspected the command hadn't been defined yet. However, looking now at the DELETE FILE command in the X# Language Reference, I see the note "This command is defined in a header file and will be preprocessed by the X# preprocessor to a function call. If you disable the standard header (-nostddefs) files then this command will not be available. If you tell the compiler to use a different standard header file (-stddef ) then this command may also be not available"

So, it appears that I needed to check the "/nostsddefs: Ignore XSharpDefs.vh" checkbox on the Advanced Tab of the Application Properties when using XIDE.

Now the line:
USE (testfile) Alias tst
is producing the error:
error XS9002: Parser: unexpected input 'ALIAS'

So, help here would be greatly appreciated.

Regarding #2, I'm just going to create my own routine to add a field as enabling embedded SQL statements is a significant task and will take a fair bit of time.

Regarding #3, the OLEPUBLIC keyword defines this class as a custom Automation server (or COM server) that can be instantiated from other applications. Perhaps X# already has a different means of doing this?

Thanks for your help.

Regards,

Jeff

Updated listing of Additional Application Properties Settings for a VFPer starting with XIDE
-General Tab
Compiler Language: XSharp
Dialect (x# only): <FoxPro>
-References Tab
GAC Tab
Included box should include:
XSharp.Core
XSharp.RT
XSharp.Data ??
XSharp.VFP ??
-Compiler Tab
-lb (late bound calls)
-memvar (support for MEMVARs vars, PUBLICs, PRIVATEs etc)
-undeclared (support for undeclared vars, PUBLICs, PRIVATEs etc)
-fox1
-fox2
-vo2
-vo3
-vo7
-vo9
-vo12
-vo14
User avatar
robert
Posts: 4255
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by robert »

Jeff,
I would NOT recommend to disable the standard header files.
All FoxPro commands, such as the USE command require these files

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Jeff Stone
Posts: 34
Joined: Fri Jun 07, 2019 4:16 pm

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Jeff Stone »

Hi Robert,

I unchecked the nostsddefs checkbox and then added the following #command statements:

#command RENAME <(filename1)> TO <(filename2)> => FRENAME(<(filename1)>, <(filename2)>)
#command DELETE FILE <(filename)> => System.IO.File.Delete(<(filename)>)

to the small .prg, which relates to https://www.xsharp.eu/forum/topic/3564,that you see below and am now getting the following error message when compiling in XIDE:
error XS7038: Failed to emit module 'Test1': Unable to determine specific cause of the failure.

As always, thanks for all of the help.

Regards,

Jeff

Code: Select all

#command DELETE FILE <(filename)> => System.IO.File.Delete(<(filename)>)
#command RENAME <(filename1)> TO <(filename2)> => FRENAME(<(filename1)>, <(filename2)>) 
FUNCTION Start( ) AS VOID
	System.Console.WriteLine("Hello x#!")
	
	testfile = "d:\als_mod"
	USE (testfile) ALIAS tst
	x = ADD_TABLE_COLUMN("tst", newfld, "C", 12, 0) 
RETURN
	            
FUNCTION ADD_TABLE_COLUMN
PARAMETERS TableAlias, fldName, fldType, fldLen, fldDec
IF VARTYPE(fldName) <> "C"
	messagebox("Error on call to ADD_TABLE_COLUMN. Field Name must be a Character String")
	RETURN 1
ENDIF
IF Len(fldName) < 1 .or. Len(fldName) > 10
	messagebox("Error on call to ADD_TABLE_COLUMN. Field Name length must be bewteen 1 and 10")
	RETURN 1
ENDIF
CurrWorkArea = Alias()
select (TableAlias)
cDBF = DBF()
cDBFPath = JUSTPATH(cDBF) 
TempFldsFile = cDBFPath+"\temp_flds"
copy STRUCTURE extended TO (TempFldsFile)
Select 0
use (TempFldsFile) alias tempflds
Append Blank
Replace Field_name WITH fldName
Replace Field_type WITH fldType
Replace Field_len WITH fldLen
Replace Field_dec WITH fldDec 
tempdbf = cDBFPath+"\tempdbf"     
Use
Select (TableAlias)
Create (tempdbf) FROM TempFldsFile
Use (tempdbf) Alias (TableAlias)
Append FROM (cDBF)   
*Erase (cDBF) 
DELETE File (cDBF)
Use      
Rename (tempdbf) TO (cDBF)
Select 0
Use (cDBF) Alias (TableAlias)
select (CurrWorkArea)
RETURN 0
User avatar
Chris
Posts: 4583
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Chris »

Hi Jeff,

I could not reproduce the problem, which X# version are you using? Can you please send the app so we can have a look here? Just right-click on the app in the Project window, select Export Application and post the (zipper) .viaef file that will be created.

Regarding the DELETE FILE, it's just a case of the help file lying :)
We just forgot to add the command in the header file, we'll do that for the next release.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Jeff Stone
Posts: 34
Joined: Fri Jun 07, 2019 4:16 pm

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Jeff Stone »

Hi Chris,

Thanks for taking the time to help. I've attached the .viaef file, but I had to zip it first for some reason (probably the security system on our side). I've probably got an incorrect switch setting. I'm using the October 2023 XIDE build.

Please check the header file for the RENAME To command as well on the next release.

Regards,

Jeff
Attachments
TestCode.zip
(1.6 KiB) Downloaded 107 times
User avatar
Chris
Posts: 4583
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Chris »

Hi Jeff,

Thanks, I see the problem now, it's because the reference to XSharp.VFP is missing. Please add that and it will compile ok now. Of course this is a compiler bug though, it should not crash without this reference, but instead report a helpful error message. Will log this for Robert to fix it, thanks for reporting this!
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Jeff Stone
Posts: 34
Joined: Fri Jun 07, 2019 4:16 pm

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by Jeff Stone »

Hi Chris,

Thanks for pointing out about XSharp.VFP as missing. I cleaned up the code an it now compiles and runs successfully through XIDE. (I've pasted it below, if anyone cares.) So, I've added the ADD_TABLE_COLUMN function to the .DLL code to try to get that converted for X# and have noticed a few other issues:

1. When coding a REPLACE ALL command, VFP allows the "ALL", which is the scope, to be place anywhere in the command. X# is more particular. For example:
VFP allows REPLACE ALL x field1 WITH value2
while
X# seems to only accept REPLACE x field1 WITH value2 ALL

2. The INDEX command did not like the use of & in front of a variable while surrounding the variable with parentheses was okay. So,
INDEX ON &lcfieldname TO (ltempname) will generate error XS9002: Parser: unexpected input 'on' while
INDEX ON (lcfieldname) TO (ltempname) will not
I think this makes sense for X# as & probably represents macro expansion while () indicates indirect reference, but it might be worth a more detailed error message for sloppy VFP folks such as myself.

3. A line with the SET ORDER command is generating: error XS9002: Parser: unexpected input 'ORDER'
Is an additional #command needed to address this as this command as seems tied to -nostddefs?

Regards,

Jeff

Code: Select all

#command DELETE FILE <(filename)> => System.IO.File.Delete(<(filename)>)
#command RENAME <(filename1)> TO <(filename2)> => FRENAME(<(filename1)>, <(filename2)>) 
FUNCTION Start( ) AS VOID
	System.Console.WriteLine("Hello x#!")
	
	testfile = "d:\collat"
	USE (testfile) ALIAS tst
	? loan_id,balance
	x = ADD_TABLE_COLUMN("tst", "newfld", "C", 12, 0) 
	wait
	Close all
RETURN
	            
***Much more input validation is needed, but it works
FUNCTION ADD_TABLE_COLUMN
PARAMETERS TableAlias, fldName, fldType, fldLen, fldDec
LOCAL TempFldsFile 
IF VARTYPE(fldName) <> "C"
	messagebox("Error on call to ADD_TABLE_COLUMN. Field Name must be a Character String")
	RETURN 1
ENDIF
IF Len(fldName) < 1 .or. Len(fldName) > 10
	messagebox("Error on call to ADD_TABLE_COLUMN. Field Name length must be bewteen 1 and 10")
	RETURN 1
ENDIF
CurrWorkArea = Alias()
select (TableAlias)
cDBF = DBF()
cDBFPath = JUSTPATH(cDBF) 
TempFldsFile = cDBFPath+"\temp_flds"
copy STRUCTURE extended TO (TempFldsFile)
Select 0
use (TempFldsFile) alias tempflds
Append Blank
Replace Field_name WITH fldName
Replace Field_type WITH fldType
Replace Field_len WITH fldLen
Replace Field_dec WITH fldDec 
tempdbf = cDBFPath+"\tempdbf.dbf"     
Use
Select (TableAlias)
Create (tempdbf) FROM (TempFldsFile)
Use (tempdbf) Alias (TableAlias)
Append FROM (cDBF)   
DELETE File (cDBF)
DELETE File (TempFldsFile) 
Use
Rename (tempdbf) TO (cDBF)
Select 0
Use (cDBF) Alias (TableAlias)
select (CurrWorkArea)
RETURN 0
END FUNC
User avatar
robert
Posts: 4255
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Re: Getting Started with X# -- Converting a VFP Application or DLL

Post by robert »

Jeff,
1) Apparently FoxPro is very forgiving in the order of optional clauses:
This is the declaration of the REPLACE command in the docs:

Code: Select all

REPLACE FieldName1 WITH eExpression1 [ADDITIVE]
   [, FieldName2 WITH eExpression2 [ADDITIVE]] ... [Scope]
   [FOR lExpression1] [WHILE lExpression2] [IN nWorkArea | cTableAlias]
   [NOOPTIMIZE]
ALL is part of the [Scope] clause.

2) This has already been fixed for the next build

3) What did your SET ORDER command look like? Did it also use the &lcfieldname syntax?

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Post Reply