03 - Open Source (EN)03g - IBM i Open Source miscellanea (EN)

Harbor – The return of a legend

Hello to all IBM i passionate friends!
Today with this article I want to talk to you about a programming language that everyone has in mind as a distant memory. Let’s go back to the last century to be precise between the 80s and 90s when PCs began to enter our life and work offices. People who have gone through this period can immediately remember the clipper programming language!

Whenever I happen to talk to someone, the classic question I am asked is “What programming languages do you know?” . When I answer RPG and VB.NET (mostly used for work). I get as a response the classic sentence:

“Why do you use these programming languages! they are now dead, use your energies to study more modern languages like c # “.

While if I answer that I know the Clipper language, the reaction is totally different and most people tell about their adventure with this language. Today with this article on the Faq400 Blog, I want to openly announce that the Clipper has never faded and has evolved to become Open source.

  • Harbor the new Clipper
    The project is now called Harbor, this project was officially born in 2000, Captained by Antonio Linares, it differs from other projects due to its free nature and the philosophy of team play that is put into play by all fans. Behind Harbor there is no type of company that finances the project but the strength of groups or individual developers who support the language. At the moment around 10,000 people in the world use this language and integrate it with new solutions or existing projects, making it evolve and modernize it as best as possible (for example, like other languages, we find the OOP paradigm we will talk about in future articles and the FOR EACH cycle).
    Among some existing projects, there is to mention:
  • HMG (main graphics library to create winform applications).
    HBQT (project created from the base of the QT 5 libraries, to create GUI applications such as C, ruby, python …) .mod_harbour (of this library more on that later, and one of the more recent projects extending the use of harbor on apache) .
  • TWEB (BOOTSTRAP-based library, is an extension for mod_harbour and offers the ability to create web interfaces with the classic clipper syntax).

other projects such as database connectors, zebra printer report management library, pdf etc … they are part of the harbor core (located in the contrib folder) and can be considered native elements of the language.

  • HARBOR similar to RPG

But when you get here, many may wonder … “What can Harbor be used for in the IBM i world?”
The first thing that unites the two languages is the programming logic. Both make use of macros (e.g. EVAL) and cycles to manage data by a single record.

Small and classic example of a search in a table:

RPG ------------------------------------------------- -------------------
 Chain klst1 FILE01;
 If% found (FILE01);

     C # PDES = PDES;
 
 Endif;
-------------------------------------------------- ---------------------

HARBOR ------------------------------------------------- ---------------
 USE Customer NEW
 INDEX ON Customer-> ID TO ID
 SEEK "Doe"
 IF FOUND ()
 
      ? "Record found"
 
 ENDIF
-------------------------------------------------- ---------------------

as you can see, the logic is almost identical, the only difference is in the name of the command (CHAIN for RPG – SEEK for HARBOR) but both work the same way.

The second similarity concerns the compilation. Harbor as an RPG, is compiled at a low level. This means that we do not need virtual machines (such as .NET framework or JVM for JAVA), but the entire code is stored in the executable making it portable ready to run on any system without installing anything additional.

The third similarity (probably the most important one) concerns data management. Harbor like Clipper, relies on files with the DBF extension and without using external libraries, you can create autonomous applications quickly.


The fourth similarity to RPG concerns the backward compatibility of the code. Harbor as an RPG, looks a lot to code preservation. In fact, if we have clipper code written more than thirty years ago, we can recompile it without problems in 32 or 64 bit and use it without making any changes in the code.

  • ILE concept also on HARBOR T
    he fifth and final similarity with RPG that must be observed more specifically, lies in the flexibility of Harbor to integrate C code within the project and compile it together. This means that any project or library written in C or C ++ can be adapted to the language with minimal effort.

Let’s see some specific examples:

integration of c functions from external file

harbor code ------------------------------------------------ ---
// test.prg
PROCEDURES Main ()
      CLEAR SCREEN
      ? "The result is:", multiply (58, 37)
RETURN
-------------------------------------------------- ---------------
code C ------------------------------------------------ ---------
/ * func.c * /
#include "hbapi.h"
HB_FUNC (MULTIPLY) {
   unsigned int a, b, c;
   a = hb_parni (1);
   b = hb_parni (2);
   c = a * b;
   hb_retni (c);
}
-------------------------------------------------- ---------------

As you can see from this example, just create a C file and using the macro HB_FUNC (), the function becomes native to Harbor.

Then taking advantage of the harbor preprocessor we can concatenate C functions with harbor and use them directly in the prg file using the #PRAGMA command.

#define MAXLOOP 5
Function Main ()
    local l_loop
    MyOutputDebugString ([Harbour]"Starting Hello World")
    FOR l_loop: = 1 to MAXLOOP
        ? "Hello Harbor "+ alltrim (str (l_loop))
        IF l_loop == 3
           AltD () // Same as “SET STEP ON” of VFP
           ? "Paused Debugger "
        ENDIF
    END
    MyOutputDebugString[Harbour] ("Completed Hello World")
RETURN nil
// CODE C =======================================
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
HB_FUNC (MYOUTPUTDEBUGSTRING)
{
   OutputDebugString (hb_parc (1))
;}
#pragma ENDDUMP
// CODE C =======================================
  • Strengths of the language
    I wanted to introduce Harbor to the faq400 community because it can become a valid tool to simplify development. In recent times, due to increasingly fragmented systems, we have to resort to quite difficult methods to manage data from different sources (DB2, MYSQL, POSTGRES …) , but using the internal queries of the harbor we can load the data on virtual dbf and manage them as if th
    ey were from the same database.

Example of interaction between two DB2 – MYSQL tables:

REQUEST SDDODBC, SDDMY, SQLMIX
ANNOUNCE RDDSYS
PROCEDURES Main ()
   concrete
#if defined (_HBSCRIPT_HBSHELL)
   rddRegister ("SQLBASE")
   rddRegister ("SQLMIX")
   hb_SDDMY_Register ()
#endif
   rddSetDefault ("SQLMIX")
   // connect mysql
   IF rddInfo (RDDI_CONNECT, {"MYSQL", "mysql-rfam-public.ebi.ac.uk", "rfamro",, "Rfam", 4497}) == 0
       ? "Unable connect to the server"
       RETURN
   ENDIF
   // take charge of the result
   use ("SELECT * FROM family") Family alias new
   index on family-> rfam_acc to rfam_acc
   // I show the table on the screen
   Browse ()
   // connect with as400
   IF rddInfo (RDDI_CONNECT, {"ODBC", "Driver = {IBM i Access ODBC Driver}; System = pub400.com; Uid = unetcorp; Pwd = QSYSNLS4 $;"}) == 0
      ? "Unable connect to the server"
      RETURN
   ENDIF
   // take charge of the result
   dbUseArea (.T., , "SELECT codart as rfam_acc FROM unetcorp1.art_mag", "art_mag")
   index on art_mag-> rfam_acc to fam_acc
   // I show the table on the screen
   Browse ()
   
   // I connect the two tables and in this case I show the output on the screen
   set RELATION to rfam_acc INTO family
   DO WHILE! family -> (EOF ())
       list art_mag-> rfam_acc, family-> description for art_mag-> rfam_acc = family-> rfam_acc
       skip aka family
   END DO
   dbCloseAll ()
RETURN

As seen in this simple example, we can invoke two queries with the USE command. The table subsequently (as a kind of logical view) is stored in ram. Independently and separately from the database we can create local indexes on Harbor and then we can relate the two tables, making a join as in this case to obtain a list of rows that have the same ID code.

  • Unique Syntax for Creating Interfaces and Reports
    Another point that goes in favor of Harbor like its predecessor is the ability to create interfaces of all kinds. Taking advantage of the libraries that are made available to us, we take advantage of the same native and simple syntax of the language, be it console application or web.
Harbor console interface example:
PROCEDURES Main ()
   CLS
   nChoice = 1
   @ 09.08 TO 15.35 DOUBLE COLOR "rg + / n"
   @ 10,10 PROMPT "1) Insertion .........."
   @ 11,10 PROMPT "2) Edit ............."
   @ 12,10 PROMPT "3) Display ......"
   @ 13,10 PROMPT "4) Print ..............."
   @ 14,10 PROMPT "5) Cancellation ........"
   MENU TO n Choice
RETURN
example of classic winform interface (Created with HMG):
#include "hmg.ch"
FUNCTION Main ()
   DEFINE WINDOW Form_1;
    AT 90.90;
    WIDTH 400;
    HEIGHT 250;
    TITLE "Window of John";
    MAIN
    END WINDOW
  @ 20,20 LABEL text1;
    PARENT Form_1;
    VALUE "First Name"
  @ 40.20 TEXTBOX name;
    PARENT Form_1
  @ 20,150 LABEL text2;
    PARENT Form_1;
    VALUE "Last Name"
  @ 40,150 TEXTBOX surname; PARENT Form_1
  @ 90,150 TEXTBOX sum;
    PARENT Form_1;
    WIDTH 200
  @ 85.20 BUTTON button;
    PARENT Form_1;
    CAPTION "Merge the fields";
    WIDTH 120;
    ONCLICK merge ()
    ACTIVATE WINDOW Form_1
RETURN NIL
FUNCTION merge ()
    Form_1.sum.value: = Form_1.name.value + Form_1.surname.value
RETURN NIL
Web interface example (created with TWEB)
Function main ()
   INIT FORM oForm
     ROWGROUP oForm
     BUTTON;
      LABEL 'Scan C:';
      ICON '<i class = "far fa-save"> </i>';
      ACTION 'Load ()';
      CLASS 'btn-secondary mybtnbar';
      GRID 12 OF oForm
   
      DEFINE BROWSE oBrw ID 'disksize' HEIGHT 500 DBLCLICK 'editRow' OF oFormADD oCol TO oBrw ID 'folder' HEADER 'Folder' ALIGN 'center'
         ADD oCol TO oBrw ID 'size' HEADER 'Size' SORT
      INIT BROWSE oBrw
   end oForm
RETURN 
  • Compiled language? Not only!

Harbor, in addition to being a compiled language, with the updates that have been received from the community and its ability to adapt, is able to create programs that are fully interpreted as python or semi-compiled like java.

Reduced harbor usage process scheme

In conclusion, the Clipper is not dead but continues to live thanks to Harbor. This is certainly an advantage for end users who can still benefit from a language that, even if since the late 90s has seen it give way to new generation languages, still remains current due to its ability to adapt to the needs of the end user. that very few languages have. This article was just a small taste of the potential of this language and will follow on the blog webinar with in-depth articles to better discover Harbor.

  • external links recommended by the community

Harbor’s advanced build process diagram (courtesy of the harbor.wiki site):

HarbourLanguageCompilationProcess_Rev_2020_01_22.png (3044 × 1477)

The examples were taken from the site of my dear friend Giovanni Di Maria (http://www.elektrosoft.it)

external links:

GitHub – harbor / core: Portable, xBase compatible programming language and environment – link to the official project

Harbor manual for beginners – part III (kresin.ru) – harbor manual with insights

Harbor Language Wiki Home – basic wiki with instructions on how to install and configure harbor

Harbor Users – Google Groups – official harbor support group.

FiveTech Software tech support forums • View forum – FiveWin for Harbor / xHarbour (fivetechsupport.com) – official support forum created by Antonio Linares.

Long live Clipper! | Notes of a Clipper Language Student (wordpress.com)

2 Comments

Leave a Reply

%d bloggers like this: