Coding Guidelines

Coding Guidelines

( by Greg Holmes )

Language Syntax 
The general rule of thumb is: built-in features in lowercase, and custom-written functions in mixed case. 
When specifying the complete syntax of a language element in documentation, the input items, parameters, and so on are referred to using the following symbols:

 Symbol  Description
< >  Indicates user input item
( )  Indicates function argument list
[ ]  Indicates optional item or list
{ }  Indicates code block or literal array
| |  Indicates code block argument list
–>  Indicates function return value
 Repeated elements if followed by a symbol
Intervening code if followed by a keyword
,  Item list separator
|  Indicates two or more mutually exclusive options
@  Indicates that an item must be passed by reference
*  Indicates a compatibility command or function

For example:

    len(<cString>|<aArray>) --> nLength

Metasymbols provide a place holder for syntax elements, and they describe the expected data types. A metasymbol consists of one or more lowercase data type designators followed by a mixed case description. This is known as Hungarian Notation.

 Designator  Description
a  Array
b  Code block
c  Character expression
d  Date expression
exp  Expression of any type
id  Literal identifier
l  Logical expression
m  Memo field
n  Numeric expression
o  Object
x  Extended expression

In this example, dnLower and dnUpper can be either date or numeric:

    @...get...range <dnLower>, <dnUpper>
Filenames and Aliases 
All filenames, in any context, are in upper case. Filenames follow DOS naming conventions (preferably limited to letters, numbers, and the underscore).

    use CUSTOMER
    nHandle := fopen('DATAFILE.DAT')

When referring to specific file types in documentation, include the period.
e.g. “A program is stored in a text file with a .PRG extension.” 
Alias names follow the same conventions as filenames, but are limited to A-Z, 0-9, and the underscore. If a filename begins with a number or contains unusual characters, an alias must be specified when the file is opened or an error will result. 
Note that CA-Clipper does not natively support Windows 95 long filenames, although third-party libraries are available to add the capability.

Fieldnames 
Fieldnames are all uppercase, and always include the alias of the table. Fieldnames may contain underscores, but should not begin with one (because the underscore is generally used to indicate an internal symbol).

    @ 10, 10 say BANKS->BRANCH
    nAge := CUSTOMER->CUST_AGE
Memory Variables 
Memory variables consist of a lowercase type designator followed by a mixed case description (see Hungarian Notation). Although CA-Clipper only recognizes the first 10 characters as unique, variable names may be longer.

    cString := "Hello World"
    nYearlyAverage := CalcYearAvg()

If you use Hungarian Notation for your memory variable names and include the table alias with fieldnames, there will be no conflict between the two.

Commands, Functions, and Keywords 
All built-in commands, functions, and keywords are lowercase. In documentation, the font should be Courier or a similar font. If fonts are not available, then bold or CAPITALIZE the word for emphasis. 
Never use abbreviations — this practice is not necessary with a compiler, although it was common in the early days of dBase (which was an interpreter). 
There should never be a space between the function name and the opening parenthesis. Also, note that the iif() function should never be spelled if().

    replace CUSTOMER->CUSTNAME with cCustName
    nKey := inkey(0)

When specifying commands that have clauses in documentation, separate the keywords with an ellipsis (...) and do not include the to clause, unless it is followed by the file,print, or screen keywords.

    copy...sdf
    set message...center
    @...say...get
Programmer-Defined Functions & Procedures 
These begin with an uppercase letter, followed by mixed case letters as appropriate.

    ? StripBlanks("Hello there, this will have no spaces.")

Function and procedure names may contain underscores, but should not begin with one (they may conflict with internal functions which often start with an underscore). There should be only one return statement per function or procedure, and it should not be indented.

    function SomeFunc (...)
      .
      . <statements>
      .
    return cResult

The return value of a function is not enclosed in parentheses, although parentheses may be used to clarify a complex expression.

    return nValue
    return (nCode * 47) + nAnswer
Preprocessor Directives 
Preprocessor directives are lowercase and are preceded by the # sign.

    #include 'INKEY.CH'

Optionally, you may use single quotes around header files that come with CA-Clipper and double quotes around your own. This convention is purely voluntary, but it helps to distinguish between the two. For example:

    #include 'INKEY.CH'
    #include "MY_APP.CH"

Manifest constants are uppercase.

    #define ESCAPE   27
    if lastkey() == ESCAPE

Pseudo-function names should also be uppercase.

    #define AREA(length, width)   ((length)*(width))
Declarations 
Local variables are grouped according to functionality, and may be declared on one or more lines. The declarations appear as the first code at the beginning of a function or procedure.

    procedure Main ( )
    local nTop, nLeft, nBottom, nRight
    local cOldScreen, cOldColor, nOldCursor

Variables may be declared one per line and accompanied by a description.

    local nCount        // Number of records found.
    local nTotal        // Sum of dollars.

The description can be omitted if better variable names are chosen.

    local nRecordCount
    local nDollarTotal

Variables can be initialized when they are declared, although it is often clearer (and safer) to initialize them immediately before they are used.

    local nRecordCount:=0
    local nDollarTotal:=0
Logicals 
The .T. and .F. are typed in uppercase.
Operators 
The in-line assignment operator (:=) is used for all assignments, and the exact comparison operator (==) is used for all comparisons.

    lContinue := .T.
    nOfficeTotal := nRegionTotal := 0
    lDuplicate := (CUSTFILE->CUSTNAME == cCustName)
    if nLineCount == 4  ...
    if left(PRODUCT->CODE, 3) == left(cProdCode, 3)  ...

Although the compound assignment operators (+=-=*=, etc.) are convenient, they should not be used if readability suffers.

    // The traditional way to accumulate:
    nTotal := nTotal + INVDETAIL->PRICE
    // A good use of a compound assignment operator:
    nTotal += INVDETAIL->PRICE
    // But what does this do?
    nVal **= 2

The increment (++) and decrement (--) operators are convenient, but can lead to obscure code because of the difference between prefix and postfix usage.

    nRecCount++
    nY := nX-- - --nX        // Huh?
Spacing 
Whenever a list of two or more items is separated by commas, the commas are followed by a space.

    MyFunc(nChoice, 10, 20, .T.)

Spaces may be used between successive parentheses.

    DoCalc( (nItem > nTotal), .F. )
    cNewStr := iif( empty(cStr), cNewStr, cStr + chr(13) )

Spaces should surround all operators for readability.

    nValue := 14 + 5 - (6 / 4)

In declarations, often spaces are not used around the assignment operator. This tends to make searching for the declaration of a variable easier.

    local lResult:=.F., nX:=0

Thus, searching for “nX :=” would find the lines where an assignment is made, while searching for “nX:=” would find the declaration line (such as the local above).

Indentation 
Indenting control structures is one of the easiest techniques, yet it improves the readability the most. 
Indent control structures and the code within functions and procedures 3 spaces.

    procedure SaySomething
       do while .T.
          if nTotal < 50
             ? "Less than 50."
          elseif nTotal > 50
             ? "Greater than 50."
          else
             ? "Equal to 50."
          endif
          ...
       enddo
    return

Case statements in a do…case structure are also indented 3 spaces.

    do case
       case nChoice == 1
          ? "Choice is 1"
       case ...
          ...
       otherwise
          ...
    endcase
Tabs 
Do not use tabs in source code — insert spaces instead. Tabs cause problems when printing or when moving from one editor to another, because of the lack of a standard tab width between editors and printers. Typically, printers expand tabs to 8 spaces which easily causes nested control structures to fall off the right-hand side of the page. Commonly, a source code editing program will insert the appropriate number of spaces when the <TAB> key is hit.
Line Continuation 
When a line of code approaches the 80th column, interrupt the code at an appropriate spot with a semicolon and continue on the next line. Indent the line so that it lines up in a readable manner.

    set filter to CUSTFILE->NAME  == 'John Smith  ';
            .and. CUSTFILE->STATE == 'OR'

To continue a character string, end the first line with a quote and a plus sign and place the remainder on the next line. Try to choose a logical place in the string to break it, either at a punctuation mark or after a space.

    @ 10, 10 say "The lazy brown fox tripped over " + ;
                 "the broken branch."
Quotes 
Use double quotes for text that needs to be translated (will appear on the screen), and single quotes for other strings.

    ? "Hello World!"
    cColor := 'W+/B'
    SelectArea('PROP')

This is a simple but extremely effective technique because translation departments often want to see the messages in context (in the source code), so the different quote types indicate which messages are to be translated and which should be left alone.

Comments 
Comments are structured just like English sentences, with a capital letter at the beginning and a period at the end.

    // Just like a sentence.
    /* This comment is longer. As you
       can see, it takes up two lines */

You may encounter old-style comment indicators if you maintain older (Summer’87 and earlier) code.

    && This is an older-style of comment indicator.
    *  The asterisk is also old.

For in-line comments, use the double slashes.

    use CUSTOMER            // Open the data file.
    goto bottom             // The last record.

Note that the ‘//‘ of in-line comments begins at column 40, if possible. This leaves enough room for a useful comment.

Source :  http://www.ghservices.com/gregh/clipper/guide.htm

FT Toolkit Overview

NANFOR.LIB Working Group G. Scott [71620,1521]
Overview UCLA
Version 2.1 October, 1992

THE NANFORUM TOOLKIT (NANFOR.LIB)
PUBLIC DOMAIN USER SUPPORTED CLIPPER FUNCTION LIBRARY

.

1 INTRODUCTION

This is a standard for establishing and maintaining NANFOR.LIB, a public-domain, user-supported library of functions designed to interface with Computer Associates CA-Clipper, version 5.01a, and later. You are encouraged to read it over and forward comments to Glenn Scott, CIS ID [71620,1521].

1.1 History

In October and November of 1990, a discussion on the evolution of third-party products, vendors, and marketing took place on the CompuServe Information Service’s Nantucket Forum (NANFORUM). During this discussion, a forum subscriber named Alexander Santic suggested the idea of a user-supported Clipper function library, available to all on the CompuServe Information Service (CIS). A number of subscribers, including several Clipper third party developers, and some Nantucket employees, expressed their support. This standard was a first step toward organizing such an endeavor.

Release 1.0 of the toolkit was made available in April, 1991 and had nearly 150 functions. By the time version 2.0 was released in August, 1991, the 1.0 library had been downloaded nearly 700 times by CompuServe users. By October of 1992, release 2.0 had been downloaded over 2100 times. The source code had been downloaded nearly 1500 times. In addition, release 2.0 was placed on the massive Internet archive site called SIMTEL20 where it was downloaded by CA- Clipper users worldwide. Over the course of the year that release 2.0 was available, seven patches were issued, each one gathering nearly 1000 downloads.

Computer Associates International, Inc. acquired Nantucket in the summer of 1992 and subsequently renamed NANFORUM to simply CLIPPER. In addition, the Clipper product itself was renamed to CA-CLIPPER. Despite the name changes, forum members decided to keep the toolkit’s name as “The Nanforum Toolkit,” partly for nostalgia. References to NANFORUM in this RFC have been replaced with CLIPPER.

1.2 Trademarks

CA-Clipper is a registered trademark of Computer Associates International, Inc. Computer Associates will be referred to as CA throughout this document.

1.3 Relationship to CA and third party

NANFOR.LIB is a project independent of any third party developer or CA. There is no official “sanction” or “seal of approval” from CA of any kind. In addition, NANFOR.LIB routines will be accepted and included without regard for whether or not routines performing a similar function are included in a commercial third party or CA product.

It is desired that NANFOR.LIB not compete with third party products but rather fill in the holes in CA-Clipper’s standard library. However, there will be some overlap into commercial third-party library functions, so it would be best if this is never taken into consideration when deciding on including a particular function.

Developers submitting NANFOR.LIB routines can and will be corporate developers, third party developers, independent consultant / programmers, hobbyists, and other CA-Clipper people. Perhaps even CA employees will contribute. No one is excluded or included due to any particular affiliation.

CA employees submitting functions are doing so as individuals, and are not making a policy of involving CA in the project, nor are they committing CA to supporting the public domain library.

1.4 CA-Clipper version supported

NANFOR.LIB functions, no matter what language they are written in, will be designed to work with CA-Clipper version 5.01a and later. Many of the functions, particularly those that use the EXTEND system, will be compatible with the Summer 1987 version of CA-Clipper. However, ensuring Summer 87 compatibility will be the responsibility of the user. If a user wants a function to work with Summer 87, she will have to modify the code herself if necessary. In many cases, this is a trivial task.

1.5 Queries from new users

Queries from new users interested in finding NANFOR.LIB should be handled in a uniform and courteous way. A short text file will be created that will briefly explain NANFOR.LIB, who the current people maintaining it are, and how to get a hold of it. This text message can be sent in response to any query. TAPCIS users will find this method very easy to implement.

2 DISTRIBUTION

2.1 Public Domain

NANFOR.LIB, its source code, and documentation will be public-domain software. It is not for “sale”, and shall not be sold. No fee or contribution of any kind will be required for anyone wanting a copy, other than what they would normally pay to download it from CompuServe. Users will be encouraged to submit functions via CompuServe.

2.2 Official repository

It is possible that copies of NANFOR.LIB will be downloaded and distributed elsewhere. This is encouraged, but the only copy of NANFOR.LIB and all associated documentation that will be maintained by volunteers is in an appropriate library on the CIS CLIPPER Forum.

2.2.1 Contents

The deliverables that make up the official posting on CompuServe shall be:

2.2.1.1 NFLIB.ZIP

This will contain the files NANFOR.LIB (library), and NANFOR.NG (Norton Guide).

2.2.1.2 NFSRC.ZIP

This will contain all the library source code, makefile, and other source-code related materials.

2.2.1.3 NFINQ.TXT

This is a short text file used as a response to new user queries (see paragraph 1.5)

2.2.1.4 NFRFC.ZIP

This contains an ASCII format, as well as a WordPerfect 5.1 format copy of NANFOR.RFC named NFRFC.TXT (ASCII) and NFRFC.WP5 (WordPerfect 5.1).

2.2.1.5 NFHDRS.ZIP

This contains templates of the file and documentation header blocks, including a sample, for prospective authors (FTHDR.PRG, FTHDR.ASM, FTHDR.SAM)

2.2.1.6 PATx.ZIP

These are patch files (see paragraph 4.5.1).

3 POLICY ON INCLUDING FUNCTIONS

3.1 “Best Function”

It is possible that more than one developer will submit a function or package of functions that perform substantially the same services. In that event, the referees will choose one to be included based on power, functionality, flexibility, and ease of use. Due to the cooperative, non-commercial nature of the library, no one’s feelings should be hurt by excluding duplicate functions.

In addition, it is possible that two substantially similar functions or packages will benefit from merging them together to provide new functionality. This will be the prerogative of the referees (see paragraph 6.3), in close consultation with the authors.

3.2 Public Domain

Each author submitting source code must include as part of that code a statement that this is an original work and that he or she is placing the code into the public domain. The librarian (see paragraph 6.1) and referees should make a reasonable effort to be sure no copyrighted source code, such as that supplied with some third party libraries, makes it into NANFOR.LIB. However, under no circumstances will the librarian, referees, or any other party other than the submitter be responsible for copyrighted code making it into the library accidentally.

3.3 Source code

Full source code must be provided by the author for every routine to be included in NANFOR.LIB. No routine, no matter what language, will be put into the library on the basis of submitted object code.

3.4 Proper submission

Due to the volume of submissions expected, librarians and referees may not have the time to fix inconsistencies in documentation format, function naming, and other requirements. Therefore, the librarian shall expect source code to arrive in proper format before proceeding further with it.

3.5 Quality and perceived usefulness

In a cooperative effort like this, it is very difficult to enforce some standard of quality and/or usefulness. For example, a package of functions to handle the military’s “Zulu time” may be very useful to some, and unnecessary to others.

The Nanforum Toolkit will by its very nature be a hodgepodge of routines, some of very high quality, some not so high. It is up to the users to improve it. It will be complete in some areas and vastly inadequate in others. It is up to the users to fill in the holes.

We shall err on the side of including “questionable” functions, provided they seem to work. Debates on the quality of the library’s source code shall be encouraged and will take place in the proper message section of the CompuServe CLIPPER forum.

4 LIBRARY MAINTENANCE PROCEDURE

4.1 Selection procedure

Source code will be submitted to the librarian, the documenter (see paragraph 6.2), or one of the referees. Code will be added if it has been reviewed, and approved by at least one, but preferably two, referees.

Code not meeting the documentation or source code formatting standards will generally be returned to the author with instructions.

Referees will test the submitted code. When the referees have finished evaluating a submission, they will report their approval or disapproval to the librarian, with comments.

Every effort should be made to make sure that the C and ASM functions are reviewed by referees with suitable C and ASM experience.

4.2 Update interval

As new functions are submitted, they will added to the library, and the documentation updated. Because this is a volunteer project, and because of the complexity involved in coordinating testing, documentation, and delivery, there will be no fixed interval for updates.

4.3 Version control

NANFOR.LIB will use a numeric version number as follows:

The major version will be numeric, starting from 1. This will change with each quarterly update. The minor version will change with each bug fix. This will start with zero and continue until the next major update, at which point it will revert to zero again.

Typical version numbers might be 1.1, 2.12, 15.2, etc.

The .LIB file, and all associated files, will carry a date stamp corresponding to the day it is released on the CLIPPER forum. The file time stamps shall correspond to the version number (i.e., 1:03am is version 1.3).

4.4 Announcing updates

As the library and its associated documentation are updated, simple announcements will be posted on the CLIPPER forum. This is the only place where an update shall be announced. An update will be announced after it has been successfully uploaded to the appropriate library on CompuServe.

4.5 Bug reports and fixes

The librarian will correlate and verify all bug reports, with the help of the referees. If the referees believe a bug to be serious, they will fix it and the librarian will release a maintenance upgrade immediately. If they consider it a minor bug, they will fix it but wait for the next scheduled upgrade to release it. In this case, a bug fix may be released as a “Patch.”

4.5.1 Patches

A “patch” is simply an ASCII text file containing instructions for editing the source code to a misbehaving function or group of functions. Patches may appear in the CIS library before a maintenance release or quarterly upgrade. A patch file will have a name of the form

PATn.ZIP

where <n> is a number starting from 1. Patches will be numbered sequentially. Patches will be deleted every time a new version of NANFOR.LIB goes on-line.

A patch zipfile may optionally contain .OBJ files to be replaced in user libraries via a LIB utility.

4.6 Technical Support

Technical support will work just as any technical subject on the CompuServe CLIPPER forum works. Users will post questions and suggestions to a particular message area or thread, and anyone who knows the answer should respond. No one is obliged to answer, but it is considered good form to respond with something, even if one doesn’t know the answer.

Support will include help on recompiling the routines or modifying the source.

4.7 Linker Compatibility

In order to assist users of CA-Clipper third party linkers (such as WarpLink or Blinker), NANFOR.LIB may need to broken up into root and overlay sections. How this will be done will be determined when splitting becomes necessary.

The librarian is not responsible for testing every possible linker for NANFOR.LIB compatibility. It is hoped that linker users will submit appropriate link scripts or other documentation for posting in the appropriate section on the CLIPPER forum.

4.8 Splitting NANFOR.LIB by functional category

It is possible that at some future date, it will make sense to split NANFOR.LIB into separate functional areas (e.g., video routines vs. date routines, etc). This RFC will be modified accordingly should that need arise.

5 FUNCTION CODING STANDARDS

The goal of this standard is not to force anyone to rewrite his code for this library, but to create some consistency among the functions so that they may more easily maintained and understood by all CA-Clipper developers, both novice and advanced.

However, it is extremely important that anyone submitting code attach the proper headers and documentation and fill them out correctly. This will make it much easier for code to be added to the library.

5.1 Required sections for each function
5.1.1 Header (author name/etc, version ctrl info)

Figure 1 shows a header that must be included at the top of every piece of source code submitted to the library. This header will work with both CA-Clipper and C code. For ASM code, substitute each asterisk (“*”) with a semicolon (“;”) and delete the slashes (“/”).

/*
 * File......:
 * Author....:
 * CIS ID....: x, x
 * Date......: $Date$
 * Revision..: $Revision$
 * Log file..: $Logfile$
 *
 *
 * Modification history:
 * ---------------------
 *
 * $Log$
 *
 */
Figure 1 - Standard function header.

Note that the date, revision, logfile, and modification history fields will be maintained by the librarian and should not be edited or adjusted by code authors.

The “File” field shall contain the source file name. This is often independent of the individual function name. For example, a function named ft_screen() would be included in SCREEN.PRG. As a rule, source files (.PRG, .C, .ASM) should not have the “FT” prefix.

The “Author” field should have the author’s full name, and CIS number. A CIS number is important, as this will make bug fixing and other correspondence easier.

5.1.2 Public domain disclaimer

Authors shall simply state “This is an original work by [Author’s name] and is hereby placed in the public domain.”

5.1.3 Documentation block
/* $DOC$
 * $FUNCNAME$
 *
 * $ONELINER$
 *
 * $SYNTAX$
 *
 * $ARGUMENTS$
 *
 * $RETURNS$
 *
 * $DESCRIPTION$
 *
 * $EXAMPLES$
 *
 * $SEEALSO$
 *
 * $INCLUDE$
 *
 * $END$
 */

Figure 2 – Standard Documentation Header

The documentation block must be carefully formatted as it is used by the documenter to produce the Norton Guide documentation for the library.

The keywords enclosed in dollar-signs delimit sections of the documentation header analogous to those in the CA-Clipper 5.0 documentation. Documentation should be written in the same style and flavor as the CA material, if possible. Refer to the CA-Clipper documentation for more detail and numerous examples.

The documentation will appear on comment lines between the keywords. Examples are optional. Do not put documentation on the same line as the comment keyword.

Note that the $DOC$ and $END$ keywords serve as delimiters. Do not place any text between $DOC$ and $FUNCNAME$, or any documentation after the $END$ keyword, unless that documentation belongs in the source code file and not in the resultant Norton Guide file.

The $FUNCNAME$ keyword should be followed by the function name, with parentheses, and no arguments or syntax, such as:

$FUNCNAME$            
   ft_screen()

Note the indent for readability. Parentheses shall be added after the function name as shown above.

The $ONELINER$ keyword should be followed by a simple statement expressing what the function does, phrased in the form of a command, e.g.:

$ONELINER$
          Sum the values in an array

The length of the entire $ONELINER$ shall not exceed 60 characters (this is a Norton Guide limitation).

The $SYNTAX$ keyword should be followed by a CA- standard syntax specifier, such as:

$SYNTAX$
         ft_screen( <nTop> [,<nBottom>] ) -> NIL

All parameters have proper prefixes (see paragraph 5.4), and are enclosed in <angle brackets>. Optional parameters are enclosed in [square brackets] as well. An arrow should follow, pointing to the return value. If there is no return value, it should be NIL. Any others should be preceded with the proper prefix (see the CA- Clipper documentation).

The $SEEALSO$ field provides a way to generate cross-references in the Norton Guide help documentation. Use it to point the user to other related functions in the forum toolkit. For example, if ft_func1() is also related to ft_func2() and ft_func3(), the field would look like this:

$SEEALSO$
ft_func2() ft_func3()

Note that fields are separated by spaces and the parentheses are included.

The $INCLUDE$ area allows you to specify what files are included by this function (this will be used to organize the on-line help file, and possibly the master makefile). An example would be

$INCLUDE$
int86.ch int86.inc

Other documentation fields should be self- explanatory. Review the appendix for a sample. All fields are required and must be filled in. Examples should not be considered optional.

5.1.4 Sample header and documentation block

Refer to the Appendix for a sample header and documentation block.

5.1.5 Test driver

A test driver is an optional section of C or CA- Clipper code that will only be compiled under certain circumstances. Developers are encouraged to include a short “test section” in front of their code.

The test driver shall be surrounded by the following pre-processor directives, and placed at the top of the source file:

#ifdef FT_TEST
     [test code]
 #endif

The test driver is currently optional, but authors submitting Clipper code should seriously consider adding it. It is a good way to include short demos within a piece of source code, yet pay no penalty because it is only compiled if needed. It will be invoked when a #define is created that says “#define FT_TEST.” This is a way for submitters to include short test routines with their functions and yet keep it all in one source file. This will be useful to end users.

This test driver may become required in a future version of the RFC.

5.1.6 Code

The source code shall be formatted as described in paragraph 5.4.

5.2 Function names

All NANFOR.LIB functions start with one of two prefixes. If the function is to be called by user programs, then it will begin with the prefix

FT_       ("F", "T", underscore)

Note that “FT” is a mnemonic for “Forum Toolkit.” If the function is “internal” to a module, then it will be prefixed by an underscore:

_FT ( Underscore, "F", "T" )

with no trailing underscore. Examples:

FT_CURDIR() "external"
_ftAlloc() "internal"
5.3 Librarian’s authority to change function names

Some functions will be submitted that either (1) bear a similar name to another function in the library, or (2) bear an inappropriate name. For example, a function called FT_PRINT that writes a character to the screen could be said to be named inappropriately, as a name like FT_PRINT implies some relationship to a printer. The librarian shall have the responsibility to rename submitted functions for clarity and uniqueness.

5.3.1 Changing a function name after it has been released

Once the library is released with a particular function included, then a function name should generally be frozen and not renamed. To do so would probably cause difficulties with users who had used the previous name and are not tracking the changes to the library.

5.4 Source code formatting
5.4.1 Clipper

Clipper code shall be formatted in accordance with CA’s currently defined publishing standard. Although there will surely be some debate over whether this is a good idea, in general, the goal is to provide something consistent that all CA- Clipper developers will recognize.

Minor deviations will be permitted.

The CA standard usually means uppercase keywords, and manifest constants, and lower case everything else.

In addition, identifiers shall be preceded with the proper metasymbol:

 n Numeric
 c Character or string
 a Array
 l Logical, or boolean
 d Date
 m Memo
 o Object
 b Code block
 h Handle
 x Ambiguous type

Refer to the CA-Clipper documentation for samples of CA’s code publishing format.

5.4.2 C

C source code shall be formatted in a generally accepted way, such as Kernighan and Ritchie’s style used in the book _The C Programming Language_.” The use of CA’s EXTEND.H is encouraged.

5.4.3 ASM

No particular formatting conventions are required for assembly language source code, since assembly code formatting is fairly standard. Lowercase code is preferred. Be sure to include the proper documentation header information, as described above.

Do not place ASM code in DGROUP. See paragraph 5.11.

5.5 Organization into .PRGs

Since many different people will be submitting routines, it is probably best if all routines that belong together are housed in the same .PRG. If there is some reason to split the .PRG, the referees and the librarian will handle that as part of library organization.

5.6 Header files

Including a “.ch” or “.h” or “.inc” file with each function would get unwieldy. For the purpose of NANFOR.LIB, all #defines, #ifdefs, #commands, #translates, etc that belong to a particular source file shall be included at the top of that source file. Since few submissions will split over multiple source files, there will usually be no need to #include a header in more than one place.

If a “ch” file will make the end user’s job of supplying parameters and other information to NANFOR.LIB functions easier, then it shall be submitted as a separate entity. The referees will decide on whether to include these directives in a master NANFOR.CH file.

5.7 Clipper 5.0 Lexical Scoping

NANFOR.LIB routines that are written in CA-Clipper will make use of CA-Clipper 5.0’s lexical scoping features to insulate themselves from the rest of the user’s application.

For example, all “privates” shall generally be declared “local.”

If a package of Clipper functions is added to the library, then the lower-level, support functions will be declared STATIC as necessary.

5.8 Use of Publics

Authors shall not use PUBLIC variables in NANFOR.LIB functions, due to the potential interference with an end-user’s application or vice versa.

If a global is required for a particular function or package of functions, that global shall be accessed through a function call interface defined by the author (.e.g, “ft_setglobal()”, “ft_getglobal()”, and so on). Globals such as these shall be declared static in the .PRG that needs them.

5.9 Use of Macros (“&” operator)

The use of macros in NANFOR.LIB functions will be, for the most part, unnecessary. Since this is a CA-Clipper 5.0 library, the new 5.0 codeblock construct should be used instead. Anyone having trouble figuring out how to convert a macro to a codeblock should post suitable questions on the CLIPPER forum on CompuServe.

5.10 Use of Static Functions

Any CA-Clipper 5.0 function that is only needed within the scope of one source file shall be declared STATIC. This applies mostly to NANFOR.LIB “internals” (names with an “_ft” prefix) that user programs need not access.

5.11 Use of DGROUP in ASM Functions

Use of DGROUP in assembly language functions shall be avoided, in accordance with CA’s recommendations. Assembly functions written for NANFOR.LIB shall use a segment named _NanFor, as in the following example:

Public FT_ChDir
Extrn _ftDir:Far
Segment _NanFor Word Public "CODE"
 Assume CS:_NanFor
Proc FT_ChDir Far
 .
 .
 .
 Ret
 Endp FT_ChDir
 Ends _NanFor
End
5.12 Use of "Internals"

Use of CA-Clipper “internals” by code authors is allowed. However, should any code make use of an internal, i.e., a function or variable that is not part of the published CA-Clipper API, then that internal shall be clearly marked in the documentation (under “DESCRIPTION”) and in the actual code, everywhere the internal is used.

5.13 Procedures for compiling functions
5.13.1 Clipper

Clipper functions will be compiled under the current release of CA-Clipper 5.0, with the following compiler options:

/n /w /l /r

Note that neither line numbers nor debugging information will find its way into NANFOR.LIB, to keep the code size down. End users may recompile NANFOR.LIB with these options enabled if they want to view NANFOR.LIB source in the debugger.

5.13.2 ASM

Assembly functions must compile successfully under any MSDOS assembler capable of producing the proper .OBJ file. However, care should be taken not to use any macros or special syntax particular to one vendor’s assembler, because that would make it difficult for end users to recompile the source. The preferred assembler is MASM, followed by TASM.

5.13.3 C

C functions must compile successfully under any C compiler capable of interfacing to CA-Clipper. Obviously, Microsoft C, version 5.1, is the preferred development environment. Care should be taken, when writing C code, not to use any special compiler features particular to one vendor’s C compiler, because that would make it difficult for end users to recompile the source.

5.14 Functions requiring other libraries

It is very easy to write functions in C that call the compiler’s standard C library functions. However, NANFOR.LIB can make no assumptions about the end user’s ability to link in the standard library or any other library. Therefore, no function will be added to NANFOR.LIB that requires any other third party or compiler manufacturer’s library.

6 ADMINISTRATIVE DETAILS

6.1 Librarian

The librarian will be the person who rebuilds the library from the sources and uploads the resulting deliverables to the proper CLIPPER forum library on CompuServe. The librarian generally does *not* test code or edit source code to repair formatting errors.

6.2 Documenter

The documenter is responsible for maintaining the Norton and guides and keeping it in sync with each new release.

6.3 Referees

Referees are volunteers who read source code, clean it up, compile it, look for problems like potentially problematic C code, decide on which function is best, consolidate common functions, etc. They make sure the header and documentation blocks are present. There is no election or term for refereedom. One simply performs the task as long as one can and bows out when necessary.

6.4 Transitions

Not everyone will be able to stay around forever to keep working on this project. Therefore, it is the responsibility of each referee, documenter, or librarian to announce as far in advance as possible his or her intention to leave, in order to give everyone a chance to come up with a suitable replacement. Don’t let it die!

7 CONTRIBUTORS

Current contributors, directly and indirectly, to this document include:

Don Caton [71067,1350]
Bill Christison [72247,3642]
Robert DiFalco [71610,1705]
Paul Ferrara [76702,556]
David Husnian [76064,1535]
Ted Means [73067,3332]
Alexander Santic [71327,2436]
Glenn Scott [71620,1521]
Keith Wire [73760,2427]
Craig Yellick [76247,541]
James Zack [75410,1567]

NOTES :

  • In Harbour library file name of NanForum Toolkit is hbnf.a
  • Maybe some functions :
    • obsoleted,
    • used some low-level hardware access or some OS specific features,
    • so not included in hbnf library.

Harbour New Data types

Data type & Syntax extensions in Harbour

In addition to Clipper’s scalar ( Character, Number, Date, Logical, MEMO, Nil ) and complex ( array, CodeBlock )  data types; Harbour has extended data types: pointer as scalar and object and hach as complex type.

For standard data types please refer here and/or here.

In database files (tables) data types of fields are predefined in structure of table.

For extended field types please refer here.

For data items other than fields (such as variables and manifest constants); in general, type of data  determined automatically by system, when assigning a value. The first basic way of this, is assigning a “literal” value.

For a working sample about constants please refer here.

cString := "This is a string" // A character string enclosed by a string delimiter
nNumber := 123.45 // A numeric value combined digits, decimal point and a sign ( + / - )
lTrue   := .T. // A T (tYy) or F (fNn) letter enclosed by two periods (.)
aArray  := {} // Arrays can be assigned literally by enclosed with curly brace

In addition to this basic literal value notations, Harbour has also extended notations:

– Data Types determined by special prefixs

— 0x… : Hexadecimal constant

  nNumber := 0x0A  // 0x prefix implies the string as Hexadecimal String  
                   // and type of resulting value become as Numeric (N) 
  ? nNumber, VALTYPE( nNumber ) // 10 N

— 0d… date constant

    dDate_1 := 0d20121225  // 0d prefix implies the string a date string 
                           // ( instead of using CTOD() )
                           // and type of resulting value become as Date (D) 
    ? dDate_1, VALTYPE( dDate_1 ) // 25.12.2012 D

– Special literal string formats

— d”…” : Date constant

dDate_2 := d"2012-12-26" ? dDate_2, VALTYPE( dDate_2 ) // 26.12.2012 D

— t”…” : Time constant

tTime_1 := dDate_2 + t”01:31:06″

? tTime_1, VALTYPE( tTime_1 ) // 26.12.2012 01:31:06.000 T

— e”…” : Escape sequences

Escape sequences are used to define certain special characters within string literals.

( Prefix by “\” escape sequence codes within that string )

The following escape sequences are available in C and C++ language :

Escape
sequence Description            Representation

   '     single quote          byte 0x27
   "     double quote          byte 0x22
   ?     question mark         byte 0x3f
         backslash             byte 0x5c

         null character        byte 0x00
   a     audible bell          byte 0x07
   b     backspace             byte 0x08
   f     form feed - new page  byte 0x0c
   n     line feed - new line  byte 0x0a
   r     carriage return       byte 0x0d
   t     horizontal tab        byte 0x09
   v     vertical tab          byte 0x0b

   nnn   arbitrary octal value byte nnn
   xnn   arbitrary hexadecimal value byte nn

   unnnn arbitrary Unicode value.
          May result in several characters. code point U+nnnn
   Unnnnnnnn arbitrary Unicode value.
           May result in several characters. code point U+nnnnnnnn

Note that all sequences not available in Harbour.

For the new complex data type Hash, there is a literally assigning way :

hHash := { => }    // => sign indicates the hash

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

PROCEDURE Main()
SET CENT ON
SET DATE GERM
CLS

* Data Types determined by special prefixs

** 0x... : Hexadecimal constant

nNumber := 0x0A // 0x prefix implies the string as Hexadecimal String 
// and type of resulting value become as Numeric(D)
? nNumber, VALTYPE( nNumber ) // 10 N
** 0d... date constant 

 dDate_1 := 0d20121225 // 0d prefix implies the string a date string 
                       // ( instead of using CTOD() )
                       // and type of resulting value become as Date (D) 

? dDate_1, VALTYPE( dDate_1 ) // 25.12.2012 D
* Special literal string formats
** d"..." : Date constant
dDate_2 := d"2012-12-26"
? dDate_2, VALTYPE( dDate_2 ) // 26.12.2012 D 

** t"..." : Time constant
tTime_1 := dDate_2 + t"01:31:06"
? tTime_1, VALTYPE( tTime_1 ) // 26.12.2012 01:31:06.000 T

** e"..." : Escape sequences 

? e"This is\na string\nformatted by\nEscape sequences \x21

/* The result : 
This is
a string
formatted by
Escape sequences !
*/
@ MAXROW(), 0 WAIT "EOF DTS_Exts.prg" 
RETURN // DTS_Exts.Main() 

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DTS_Exts

Using code blocks, again

Using code blocks again (.pdf)

Language Terms

Branching :

Changing the sequence of execution in a program. Execution normally proceeds in sequence from the top of a function or procedure to the bottom. When control is transferred to a statement that is not in sequence, execution is said to have branched.

Comment :

Text in a source program that is ignored by the compiler. Usually used to make descriptive comments about the surrounding source code.

Control Structure :

Any program structure that alters the flow of program control. In Clipper language, these include:

. BEGIN SEQUENCE...END
. DO WHILE...ENDDO
. DO CASE...ENDCASE
. FOR...NEXT
. IF...ENDIF

Keyword :

A word that has a special meaning to a compiler or other utility program. Commands, directives, or options are often recognized by examining supplied text to see if it contains keywords.

Metasymbol :

Descriptive symbols used in syntax to represent information that must be supplied as part of a source code statement. A metasymbol is constructed using two information components: a data type prefix and a logical descriptor.

Sequence :

In Clipper language, a series of statements enclosed in a BEGIN SEQUENCE control structure.

See Also: Algorithm, Iteration, Selection

Statement :

In Clipper language, the basic unit of source code. A statement is normally a single line of text. Multiple statements can be placed on the same line by separating them with semicolons. A statement may be continued to another line by placing a semicolon at the end of the line to be continued. If the text of a statement matches a command definition (defined with a preprocessor directive), it is translated into the form specified by the command definition.

See Also : Command

Syntax :

The rules that dictate the form of statements or commands as defined by the implementors of the language. Also, a complete description of the forms that a statement or command can take.

What is Harbour ?

Harbour is a modern computer programming language. It is a Clipper-compatible compiler which is cross-platform, running on many operating systems (DOSMicrosoft WindowsLinuxUnix variants, several BSD descendants, Mac OS XMINIX 3Windows CEPocket PCSymbianiPhoneQNXVxWorksOS/2/eComStationBeOS/HaikuAIX) using the same source code and databases.

Although it is a powerful general-purpose programming language, it was primarily used to create database/business programs. Harbour have been actively maintained looking for diversity keeping backward-compatible with Clipper style. It has undergone many changes and revisions and regain widely popularity amongst programmers in 1980s and 1990s

The open source Harbour license is similar to the GNU General Public License, with an exception supporting proprietary applications, so proprietary applications can be produced with Harbour and distributed..

Paradigm(s) multi-paradigmimperativefunctional,object-orientedreflective
Appeared in 1999
Designed by Antonio Linares
Developer Viktor Szakáts and community
Stable release 3.0.0 (17 July 2011)
Preview release 3.1.x available from SVN
Typing discipline optionally duckdynamicsafe, partially strong
Dialects Clipper, Xbase ++, Flagship, FoxPro, xHarbour
Influenced by dBase, Clipper
Influenced xHarbour
OS Cross-platform
License Open source GPL Compatible
Usual filename extensions .prg, .ch, .hbs, .dbf
Website http://www.harbour-project.org/

History

The idea of a free software Clipper compiler has been floating around for a long time and the subject has often cropped up in discussion on comp.lang.clipper. Antonio Linares founded the Harbour project and the implementation was started.

Sailing the Clipper ship to a Harbour port. Clipper is a type of ship. Harbour is a synonym to port (where ship docks) Harbour is out port to the Clipper language.

On 2009 Harbour had a huge make over on its design promoted mainly by Viktor Szakáts and Przemyslaw Czerpak

 Database support

Harbour extends the Clipper Replaceable Database Drivers (RDD) approach. It offers multiple RDDs such as DBF, DBFNTX, DBFCDX, DBFDBT and DBFFPT. In Harbour multiple RDDs can be used in a single application, and new logical RDDs can be defined from combination of other RDDs. The RDD architecture allows for inheritance, so that a given RDD may extend the functionality of other existing RDD(s). Third-party RDDs, like RDDSQL, RDDSIX, RMDBFCDX, Advantage Database Server, and Mediator exemplify some of the RDD architecture features. DBFNTX implementation has almost same functionality of DBFCDX and RDDSIX. NETIO and LetoDB provide remote access over TCP protocol Harbour also offers ODBC support by means of an OOP syntax, and ADO support by means of OLEMySQLPostgreSQLSQLiteFirebirdOracle are examples of databases which Harbour can connect.

xBase technologies often is confused with a RDBMS software. Although this is true, xBase is more than a simple database system as the same time xBase languages using purely DBF can not provide full concept of a real RDBMS

Programming philosophy

Unlike Java which is intended to be write once, run anywhere, Harbour aims to be write once, compile anywhere. As the same compiler is available for all of the above operating systems, there is no need for recoding to produce identical products for different platforms, except when operating system dependent features are used. Cross-compiling is supported with MinGW32. Under Microsoft Windows, Harbour is more stable but less well-documented than Clipper, but has multi-platform capability and is more transparent, customizable and can run from a USB flash drive.

Under Linux and Windows Mobile, Clipper source code can be compiled with Harbour with very little adaptation. Most software originally written to run on Xbase ++, Flagship, FoxPro, xHarbour and others dialects can be compiled with Harbor with some adaptation. As 2010 many efforts have been made to turn the transition from other xBase dialects easier.

Harbour can use the following C compilers, amongothers: GCCMinGWClangICCMicrosoft Visual C++ (6.0+), Borland C++Watcom CPelles C and Sun Studio.

Harbour can make use of multiple Graphic Terminal emulations, including console drivers, and Hybrid Console/GUIs, such as GTWvt, and GTWvg.

Harbour supports external GUIs, free (e.g. HWGui, MiniGUI and Qt) and commercial (e.g. FiveWin, Xailer). HBQt is a library provinding bindings to Qt. HBIDE application included in official distribution and SVN repository is a sample of HBQt potencial.

Harbour is 100% Clipper-compatible and supports many language syntax extensions including greatly extended run-time libraries such as OLE, BlatOpenSSLFreeImage,GD, TIP, Tpathy, PCRE, HbZip (zlib and bzip2), cURLCairo, its own implementation of CA-Tools and NanFor libraries and many others. Harbour has an active development community and extensive third party support.

Any xBase language provides a very productive way to build business and data intensive applications. Harbour is not an exception.

Macro Operator (runtime compiler)

One of the most powerful features of xBase languages is the Macro Operator ‘&’. Harbour’s implementation of the Macro Operator allows for runtime compilation of any valid Harbour expression. Such a compiled expression may be used as a VALUE, i.e. the right side of an assignment (rvalue), but more interestingly, such a compiled expression may be used to resolve the left side (lvalue) of an assignment, i.e. PRIVATE, or PUBLIC variables, or a database FIELD.

Additionally, the Macro Operator may compile and execute function calls, complete assignments, or even list of arguments, and the result of the macro may be used to resolve any of the above contexts in the compiled application. In other words, any Harbour application may be extended and modified at runtime to compile and execute additional code on-demand.

Latest Macro compiler can compile any valid Harbour code including code to pre-process before compile.

Syntax:

 &( ... )

The text value of the expression ‘…’ will be compiled, and the value resulting from the execution of the compiled code is the result.

 &SomeId

is the short form for &( SomeId ).

 &SomeId.postfix

is the short form of &( SomeId + “postfix” ).

Object Oriented Programming

Programming in an OOP style is a broader issue than a specific library or a specific interface, but OOP programming is something many Clipper programmers have come to expect. CA-Clipper 5.2 and especially 5.3 added a number of base classes, and a matching OOP syntax. Libraries such as Class(y), Fivewin, Clip4Win, and TopClass provide additional OOP functionality.

Harbour has OOP extensions with full support for classes including inheritance, based on Class(y) syntax. OOP syntax in Harbour is very similar to that of earlier Clipper class libraries so it should be possible to maintain legacy Clipper code with minimal changes.

Syntax and semantics

Harbour as every xBase language is case insensitive and can optionally accept keywords written just by first four characters

Built-in data types

Harbour has 6 scalar types : NilStringDateLogical, NumberPointer, and 4 complex types: ArrayObjectCodeBlock, and Hash. A scalar holds a single value, such as a string, number, or reference to any other type. Arrays are ordered lists of scalars or complex types, indexed by number, starting at 1. Hashes, or associative arrays, are unordered collections of any type values indexed by their associated key, which may be of any scalar or complex type.

Literal (static) representation of scalar types:

  • Nil: NIL
  • String: “hello”, ‘hello’, [hello]
  • Date: 0d20100405
  • Logical: .T., .F.
  • Number: 1, 1.1, −1, 0xFF

Complex Types may also be represent as literal values:

  • Array: { “String””, 1, { “Nested Array” }, .T., FunctionCall(), @FunctionPointer() }
  • CodeBlock: { |Arg1, ArgN| Arg1 := ArgN + OuterVar + FunctionCall() }
  • Hash: { “Name” => “John”, 1 => “Numeric key”, { “Nested” => “Hash” } }

Hashes may use any type including other Hashes as the Key for any element. Hashes and Arrays may contain any type as the Value of any member, including nesting arrays, and Hashes.

Codeblocks may have references to Variables of the Procedure/Function>method in which it was defined. Such Codeblocks may be returned as a value, or by means of an argument passed BY REFERENCE, in such case the Codeblock will “outlive” the routine in which it was defined, and any variables it references, will be a DETACHED variable.

Detached variables will maintain their value for as long as a Codeblock referencing them still exists. Such values will be shared with any other Codeblock which may have access to those same variables. If the Codeblock did not outlive its containing routine, and will be evaluated within the lifetime of the routine in which it is defined, changes to its Detached Variables(s) by means of its evaluation, will be reflected back at its parent routine.

Codeblocks can be evaluated any number of times, by means of the Eval( BlockExp ) function.

Variables

All types can be assigned to named variables. Named variable identifiers are 1 to 63 characters long, start with [A-Z|_] and further consist of the characters [A-Z|0–9|_] up to a maximum of 63 characters. Named variables are not case sensitive.

Variables have one of the following scopes:

  • LOCAL: Visible only within the routine which declared it. Value is lost upon exit of the routine.
  • STATIC: Visible only within the routine which declared it. Value is preserved for subsequent invocations of the routine. If a STATIC variable is declared before any Procedure/Function/Method is defined, it has a MODULE scope, and is visible within any routine defined within that same source file, it will maintain its life for the duration of the application lifetime.
  • PRIVATE: Visible within the routine which declared it, and all routines called by that routine.
  • PUBLIC: Visible by all routines in the same application.

LOCAL and STATIC are resolved at compile time, and thus are much faster than PRIVATE and PUBLIC variables which are dynamic entities accessed by means of a runtime Symbol table. For this same reason, LOCAL and STATIC variables are not exposed to the Macro compiler, and any macro code which attempts to reference them will generate a runtime error.

Due to the dynamic nature of PRIVATE and PUBLIC variables, they can be created and destroyed at runtime, can be accessed and modified by means of runtime macros, and can be accessed and modified by Codeblocks created on the fly.

Control structures

The basic control structures include all of the standard dBase, and Clipper control structures as well as additional ones inspired by the C or Java programming languages:

Loops

[DO] WHILE ConditionExp
   ...
   [LOOP]
   [EXIT]
END[DO]

FOR Var := InitExp TO EndExp [STEP StepExp]
   ...
   [LOOP]
   [EXIT]
NEXT
FOR EACH Var IN CollectionExp
   ...
   [HB_EnumIndex()]
   [LOOP]
   [EXIT]
NEXT
  • The  is a sequence of one of more Harbour statements, and square bracketes [] denote optional syntax.
  • The HB_EnumIndex() may be optionally used to retrieve the current iteration index (1 based).
  • The LOOP statement restarts the current iteration of the enclosing loop structure, and if the enclosing loop is a FOR or FOR EACH loop, it increases the iterator, moving to the next iteration of the loop.
  • The EXIT statement immediately terminates execution of the enclosing loop structure.
  • The NEXT statement closes the control structure and moves to the next iteration of loop structure.

In the FOR statement, the assignment expression is evaluated prior to the first loop iteration. The TO expression is evaluated and compared against the value of the control variable, prior to each iteration, and the loop is terminated if it evaluates to a numeric value greater than the numeric value of the control variable. The optional STEP expression is evaluated after each iteration, prior to deciding whether to perform the next iteration.

In FOR EACH, the Var variable will have the value (scalar, or complex) of the respective element in the collection value. The collection expression, may be an Array (of any type or combinations of types), an Hash Table, or an Object type.

IF statements

IF CondExp
   ...
[ELSEIF] CondExp
   ...
[ELSE]
   ...
END[IF]

 represents 0 or more statement(s). The condition expression(s) has to evaluate to a LOGICAL value.

SWITCH statements

Harbour supports a SWITCH construct inspired by the C implementation of switch().

SWITCH SwitchExp
   CASE LiteralExp
      ...
      [EXIT]
   [CASE LiteralExp]
      ...
      [EXIT]

   [DEFAULT]
      ...
END
  • The LiteralExp must be a compiled time resolvable numeric expression, and may involve operators, as long as such operators involve compile time static value.
  • The EXIT optional statement is the equivalent of the C statement break, and if present, execution of the SWITCH structure will end when the EXIT statement is reached, otherwise it will continue with the first statement below the next CASE statement (fall through).

BEGIN SEQUENCE statements

BEGIN SEQUENCE
   ...
   [BREAK]
   [Break([Exp])]
RECOVER [USING Var]
   ...
END[SEQUENCE]

or:

BEGIN SEQUENCE
   ...
   [BREAK]
   [Break()]
END[SEQUENCE]

The BEGIN SEQUENCE structure allows for a well behaved abortion of any sequence, even when crossing nested procedures/functions. This means that a called procedure/function, may issue a BREAK statement, or a Break() expression, to force unfolding of any nested procedure/functions, all the way back to the first outer BEGIN SEQUENCE structure, either after its respective END statement, or a RECOVER clause if present. The Break statement may optionally pass any type of expression, which may be accepted by the RECOVER statement to allow further recovery handing.

Additionally the Harbour Error Object supports canDefaultcanRetry and canSubstitute properties, which allows error handlers to perform some preparations, and then request a Retry Operation, a Resume, or return a Value to replace the expression triggering the error condition.

Alternatively TRY [CATCH] [FINALLY] statements are available on xHB library working like the SEQUENCE construct.

Procedures/Functions

[STATIC] PROCEDURE SomeProcedureName
[STATIC] PROCEDURE SomeProcedureName()
[STATIC] PROCEDURE SomeProcedureName( Param1' [, ParamsN] )
INIT PROCEDURE SomeProcedureName
EXIT PROCEDURE SomeProcedureName
[STATIC] FUNCTION SomeProcedureName
[STATIC] FUNCTION SomeProcedureName()
[STATIC] FUNCTION SomeProcedureName( Param1' [, ParamsN] )

Procedures/Functions in Harbour can be specified with the keywords PROCEDURE, or FUNCTION. Naming rules are same as those for Variables (up to 63 characters non case sensitive). Both Procedures and Functions may be qualified by the scope qualifier STATIC to restrict their usage to the scope of the module where defined.

The INIT or EXIT optional qualifiers, will flag the procedure to be automatically invoked just before calling the application startup procedure, or just after quitting the application, respectively. Parameters passed to a procedure/function appear in the subroutine as local variables, and may accept any type, including references.

Changes to argument variables are not reflected in respective variables passed by the calling procedure/function/method unless explicitly passed BY REFERENCE using the@ prefix.

PROCEDURE have no return value, and if used in an Expression context will produce a NIL value.

FUNCTION may return any type by means of the RETURN statement, anywhere in the body of its definition.

An example procedure definition and a function call follows:

 x := Cube( 2 )

 FUNCTION Cube( n )
 RETURN n ** 3

 Sample code The typical “hello world” program would be:

 
  ? "Hello, world!"

Or:

  QOut( "Hello, world!" )

Or:

  Alert( "Hello, world!" )

Or, enclosed in an explicit procedure:

 PROCEDURE Main()

    ? "Hello, world!"

 RETURN

 

OOP examples

 #include "hbclass.ch"

 PROCEDURE Main()

    LOCAL oPerson := Person( "Dave" )

    oPerson:Eyes := "Invalid"

    oPerson:Eyes := "Blue"

    Alert( oPerson:Describe() )
 RETURN

 CLASS Person
    DATA Name INIT ""

    METHOD New() CONSTRUCTOR

    ACCESS Eyes INLINE ::pvtEyes
    ASSIGN Eyes( x ) INLINE IIF( ValType( x ) == 'C' .AND. ;
                 x IN "Blue,Brown,Green", ::pvtEyes := x,; 
                 Alert( "Invalid value" ) )

    // Sample of IN-LINE Method definition
    INLINE METHOD Describe()
       LOCAL cDescription

       IF Empty( ::Name )
          cDescription := "I have no name yet."
       ELSE
          cDescription := "My name is: " + ::Name + ";"
       ENDIF

       IF ! Empty( ::Eyes )
          cDescription += "my eyes' color is: " + ::Eyes
       ENDIF
    ENDMETHOD

    PRIVATE:
       DATA pvtEyes
 ENDCLASS

 // Sample of normal Method definition.
 METHOD New( cName ) CLASS Person

   ::Name := cName

 RETURN Self

 

Tools

  • HBMK2 – Powerful build tool like make
  • HBDoc2 and  HBExtern – Creates documentation for Harbour
  • HPPP – Pre-processor, a powerful tool which avoids typical problems found on C language pre-processor
  • HBFormat – Formats source code written on Harbour or another dialect according defined rules
  • HBi18n – Tools to localizing text on applications
  • HBRun – Shell interpreter for Harbour. Macro compiling allows to run any valid Harbour code as it’s being compiled
  • HBIDE – Integrated Development Environment to help Harbour development and various xBase dialects

All tools are multiplatform.

Development

Today Habour development is leading by Viktor Szakáts with huge collaborations and leading many components of core and contribs by Przemysław Czerpak. HBIDE and some components, specially HBQt, are developed by Pritpal Bedi. Others members send minor changes to the Sourceforge SVN repository.  As 2010 Harbour development is keeping vibrant activity

Popularity

Although there is no way to measure popularity of Harbour or xBase, the TIOBE Programming Community Index As of June 2006 ranked Microsoft Visual FoxPro, a high profile dialect of xBase, on 12th position on programming languages popularity ranking. FoxPro/xBase ranked on 25th position As of August 2010. As of September 2010, the Clipper Usenet newsgroupscomp.lang.clipper is still active. As of August 2010 Harbour figured on 16th position on weekly downloads in compiler category and 132th position on global rank.

xHarbour comparison

xHarbour is a fork of the earlier Harbour project. xHarbour takes a more aggressive approach to implementing new features in the language, while Harbour is more conservative in its approach, aiming first of all for an exact replication of Clipper behaviour and then implementing new features and extensions as a secondary consideration. It should also be noted that Harbour is supported on a wide variety of operating systems while xHarbour only really supports MS Windows and Linux 32-bit.

The Harbour developers have attempted to document all hidden behaviour in the Clipper language and test Harbour-compiled code alongside the same code compiled with Clipper to maintain compatibility.

The Harbour developers explicitly reject extensions to the language where those extensions would break Clipper compatibility. These rejections were soften recently since the new Harbour architecture allow extensions out of the core compiler.

A detailed comparison between extensions implemented in Harbour and xHarbour can be found in SVN repository of the project on SourceForge.

As of 2009–2010, Harbour has seen a huge increase in its adoption while xHarbour decline as can be seen on his mailing list

See also

References

  1. ^ Harbour license
  2. ^ LetoDB
  3. ^ Official Harbour page
  4. ^ http://sourceforge.net/projects/harbour-project/
  5. ^ TIOBE Programming Community Index
  6. ^ SourceForge
  7. ^ About xHarbour
  8. ^ xhb-diff.txt
  9. ^ Harbour developers’ mailing list statistics
  10. ^ xHarbour developers’ mailing list statistics
  11. ^ ohloh.net Activity comparison

External links

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Note : This post borrowed by curtesy of Vikipedia from here : http://en.wikipedia.org/wiki/Harbour_(software)