After uncompressing the rar file, I created several directory and I moved the files according to their types: all source code files went to src directory, all the executables files to exe directory. Then lib, obj and other common extensions.
The software is a multi-company multi-year accounting package, the type used by accounting professionals. Each company/year has a dedicated directory, under a root directory. Data files can be in the root directory if they are valid for every company (for example fiscal deadlines, vat codes) or in the subdirectory (invoices, clients, payments…). If the data file is present in both directories, the subdirectory has precedence.
Code has a mix of spaces and tabs (but not always); it uses # instead of !=; SELE instead of SELECT, RETU instead of RETURN (and so on). Remark blocks are delimited by a strange combination of /* that makes my editor choke sometimes on syntax highligting. Single lines of remmed code are introduced by *– and again the editor doesn’t recognize them as remark lines.
Printing is supported natively only on dot-matrix printers and in the source you find something like
SET DEVICE TO PRINTER @ y,x SAY "text"
My hope was that they were using some sort of library for printing so that I could replace it if it was not available for Harbour. Since I don’t want to touch code that makes calculations (and business and presentation code is mixed in the source code) I will accept the idea to print to a temporary file and then use an external program to convert it to PDF, as suggested in harbour-users mailing list.
In the directory I found one batch file that compiles all the source files, one by one, using a long series of
CLIPPER file.prg -l
command. This batch file compiles 178 files. But in the src directory I now have 201 prg files. And some of the 178 files are not present among the 201! More on this later.
There are 17 .lnk files. They are in blinker syntax and they can be easily converted to hbmk2. From these files I understand that the software uses Funcky library. It also uses an internal library. I know the company had several business software and probably they share a common library… unfortunately the source code for this library is not present.
The software is composed by various executables – probably not 17, but I think at least 10. They call each other using a batch file: the program that wants to call another one sets the errorlevel and exits. The batch file then calls the appropriate executable depending on the errorlevel value. In the batch file the first executable shows the menu and has also a lot of forms inside but not the main ones.
To complicate a bit the situation, the first exe called by the batch file, as first step, asks the user to choice a working directory: all the following executables will have their curdir() in that directory. An environment variable will tell the software which is the root (where the exe and the common files are). So we have the current working directory set to a subdirectory, a root directory, and the need to set the working directory in a way that is kept between executable calls. The software uses Funcky chdir() function, in Harbour I could not find an equivalent function that keeps the changed directory after exiting the program.
Browsing the code, I think that the programmer had cobol roots. I never used cobol myself but I could recently have a look at some cobol source code. I found it redundant. The programmer was smart, but not very used to Clipper. There is not a single #include in the 201 source code files! One file, included and run at the beginning of each executable, has a long list of PUBLIC variables named after common #define constants and values assigned to them… there are also copyright lines from Clipper include files! As an example:
PUBLIC K_INS K_INS = 22 && Ins, Ctrl-V
Now K_INS is a public variable and its value can, by error, be modified. And 22 can be changed in a different Clipper release… The same happens for DBedit, aChoiche and other constants.
I decided to try to compile the main program. The batch file told me which one is the first called and a quick look confirmed that it had the menu inside. The menu is implemented… well… let’s just say “implemented”. I have never seen code so strange: as I said, the original programmer was very smart and infact implemented something that really worked but it was not really Clipper.
Located the proper blinker .lnk file, I manually converted it to hbmk2 .hbp format, listing all the files. The compiler failed in a couple of places for some incompatibility with Clipper (more on this later) and I promptly modified the code until it compiled with no errors.
Obviously linking failed with several missing functions, some of them from Funcky library but some also from the library I don’t have sources.
Time to make up a strategy: what to do with the missing functions? What to do with the multiple executables? What about the mix of root/subdirectory? In the next posts, of course :-)