I have now converted most of my FoxPro applications into Harbour code.
This is an updated list of the problems I had and how I solved them :
Installing Harbour in FreeBSD.
First 'pkg search harbour' then 'pkg install harbour'. As indicated by the installation
message from bash, edit /etc/fstab, add 'fdesc /dev/fd fdescfs rw 0 0'
Using Harbour
Simple as '$ hbmk2 filename.prg'. You don't even need the '.prg' ending, BUT the
top level file has to have 'proc main()...return' in it or you will get a compile time error.
Compile time errors
1. ; (line continuation chr) in text areas. Move semicolons out of
text areas.
2. Differences in array syntax. Dimension to private, round brackets
to square.
Example:
dime arrayv(3,5) && FoxPro
private arrayv[3,5] && Harbour
3. recno(0) (Fox) vs set softseek on (Harbour). Note 'seek <memvar> softseek' also works.
4. 'Display' doesn't need the 'fields' clause.
5. 'Browse' not supported, use browse().
6. Scroll command not supported. Use scroll()
7. Errors in the form " undefined reference to `HB_FUN_TREATV'" mean
that Harbour cannot find a udf named treatv(). Typically this will be
because a FoxPro array variable hasn't been reformatted.
So, for instance, a line still has
treatv(blah, blah), rather than treatv[blah, blah]. Also the FoxPro
sys() functions will all trigger this (HB_FUN_SYS).
Use grep to identify the file ($ grep -ly 'treatv(' *.prg ), then edit
the file indicated and use the search function to find the missed
array name.
8. Sys(2) = seconds(). Seconds() return numeric, sys(2) returns
character, so val(sys(2)) = seconds().
9. Sys(2002) = set cursor off.
10. Sys(2002,1) = set cursor on.
11. No scatter/gather in Harbour, you have to make your own:
&& udf scatter() &&&&&&&&&&&&&&&&&&&&&&&&&&&
function scatter
&& create a variable that gather() will be able to see
public scatgatav[0]
&& store dbf structure for current work area to array
store dbstruct() to scatgatav
&& loop throught array storing values from current record
store 1 to countv
do while countv < fcount()+1
store fieldget(countv) to scatgatav[countv]
store countv+1 to countv
enddo
return .t.
&& udf gather() &&&&&&&&&&&&&&&&&&&&&&&&&&
function gather
&& replace values into current, locked record
store 1 to countv
do while countv < fcount()+1
fieldput(countv, scatgatav[countv])
store countv+1 to countv
enddo
return .t.
So adding the UDFs above means that 'scatter()' replaces 'scatter to <memvar>' and
'gather()' replaces 'gather from <memvar>'.
12. 'Set printer to lp -dprinter' doesn't work. Harbour assumes it is a print file and adds '.prn.' to the end.
Change to 'set printer to output' then, after closing, send 'output.prn' to the printer with an OS level command:
'! lp output.prn'. Add a short delay to prevent later print commands overwriting output.prn. For example inkey(3).
13. Str(). when using str(numeric_variable) always use the length parameter ie: store str(numvar,5) to thingv,
because the defaults are different in FoxPro.
14. In some places parenthesis () substitutes for macro & . For example 'use (filenamev)'
15. Ascan() doesn't work on two dimensional arrays in Harbour, or at least not the same way FoxPro works. Use two arrays.
Run time errors
1. Permissions problems can cause hard to understand error messages.
'# chmod a+rw *' is the way to go. Also add to a common group for all the users.
2. Memory variable (.mem) files aren't compatible, they have to be
recreated. This doesn't seem to a a problem now (Harbour 3.0).
I hope this may help anyone who follows the same FoxPro to Harbour
If anyone notices something I missed feel free to reply.
I've attached my rough-'n'-ready command line utilities for anyone to use and abuse.
Thanks to all who generously helped, especially to Massimo.