For reasons that I won't mention, I had to learn clipper to acomplish a job. I developed a program in python that managed DBF database files. But the dbf binding support for any of the dynamic (and static) languages that I knew haven't CDX writing support, so I started to research for solutions.
The only free (as in free speech) and powerful enough clipper compiler that I have found is xHarbour, xHarbour is a project derived from Harbour , a project wich aims to create a full compatible ca-clipper compiler, xHarbour (wich means eXtended Harbour) has the compatibility stack plus some candy.
So, after realizing how to compile and execute the program, I did my first program, which was a FoxPro's compound index (.CDX) reindexer, which I need to rebuild the index of a dBase file that I handle with python.
Since it was really hard to figure out how to install and compile my first "hello world!" like program, I'll document my experience:
First, you have to download the lastest sources from the xHarbour download page
, then in order to make a sane installation, you have to unpack it, and execute the make_tgz.sh bash script inside the xharbour-$VERSION directory, that will build a .tgz package that you should unpack from / so the binaries get extracted on your system.
Now you have the software enough to compile any harbour source, so let's make our hello world:
function main() ?"Hello world!" return ( nil )
And that's all, so now let's compile and execute it:
arc@dopamine ~ $ xhbmk hello.prg
xHarbour Compiler build 0.99.60 (SimpLex)
Copyright 1999-2006, http://www.xharbour.org http://www.harbour-project.org/
Lines 5, Functions/Procedures 2
Generating C source output to 'hello.c'...
arc@dopamine ~ $ ./hello
arc@dopamine ~ $
Woops, nothing was shown, maybe something went wrong? Well, not really, the output of the program is done via ncurses so, the point is that output is shown and then the screen is cleared, let's make a little modification:
function main() ?"Hello world!" WAIT return ( nil )
And not, let's see how it goes:
Press any key to continue...
Ta da! It works!
So, now,how to rebuild an index from a FoxPro database (the one used by the grupo sp software such as contaplus, facturaplus and so...). To make this we need to load the DBFCDX RDD (Relational Database Driver). DBF is the format of the database, and CDX is de compound index format, both formats are documented.
A little program to rebuild the index file would look like this:
function main() REQUEST DBFCDX
/* Load the table.dbf and table.cdx, on unix, you should ensure that file extensions are on lowercase.*/ USE table INDEX table VIA "DBFCDX" REINDEX return ( nil )
If no table.dbf or table.cdx exist on the current working directory, then the program raises an exception and a prompt is shown waiting for the user interaction. That is kinde annoying if you want to use the program for automatization purposes.
If you want the program to be parametric, using CLI arguments you can use the HB_ARGV() function, you pass the argument number as argument and it returns an string with that argument, you cannot use a string or a string variable as database name so you need to use colons, the code would look like this:
function main() REQUEST DBFCDX
cTable := HB_ARGV(1) USE (cTable) INDEX (cTable) VIA "DBFCDX" REINDEX return ( nil )
This doesn't work if the index header is corrupted, since the index expressions are lost so you can't rebuild it, the only really safe way to do it is doing a program that removes the index and create it from scratch with its definitions. If you want more information on this, ask on the harbour users mailing list, or ping me on aruiz at synaptia dot net.
Another interesting feature is the xml handling capabilities, which surprised me, since clipper had been allways kinda 80's for me. A dumb example of xm handling:
function main() xTag := TXMLNODE(0, "parentNode") xTag:SetAttribute("attr", "value") xAnotherTag := TXMLNODE(0, "childNode") xTag:AddBelow(xAnotherTag) ?xTag:ToString(1) WAIT return ( nil )
I have even found GTK bindings for xHarbour! BTW is made by a spanish guy, yay! :)
I haven't found any documentation like this on the web when I started to work on this, so I hope that this would help someone to not spend so many time learning as me. If you want to go further, you should take a look at the xHarbour Developer Network, Also I should be really grateful to people from the harbour users mailing list, and my special thanks to Luc Saffre (harbour users mailing list subscriber), who answered my dumb questions from my very early steps.