@<Var> is the variable to test; it must be passed by reference.
<lVarIsByRef> a logical value indicating if the variable is passed by reference to actual function or procedure.
This function return a logical value indicating if the variable is passed by reference to actual function or procedure.
ATTENTION: The variable to test must be passed by reference. If the variable is not passed by reference, the function return NIL. This function is based on the form that Harbour manages to the variables for reference. When a variable is passed by reference, what receives the function or procedure is, a pointer to the previous variable, be this the container variable of the data or a pointer to another variable. The function observes if the variable passed points to a common variable or to a variable passed by reference.
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:
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
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.
Expression of any type
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).
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 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 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.
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.
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 (...)
The return value of a function is not enclosed in parentheses, although parentheses may be used to clarify a complex expression.
return (nCode * 47) + nAnswer
Preprocessor directives are lowercase and are preceded by the # sign.
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:
Manifest constants are uppercase.
#define ESCAPE 27
if lastkey() == ESCAPE
Pseudo-function names should also be uppercase.
#define AREA(length, width) ((length)*(width))
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.
Variables can be initialized when they are declared, although it is often clearer (and safer) to initialize them immediately before they are used.
The .T. and .F. are typed in uppercase.
The in-line assignment operator (:=) is used for all assignments, and the exact comparison operator (==) is used for all comparisons.
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).
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.
do while .T.
if nTotal < 50
? "Less than 50."
elseif nTotal > 50
? "Greater than 50."
? "Equal to 50."
Case statements in a do…case structure are also indented 3 spaces.
case nChoice == 1
? "Choice is 1"
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.
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."
Use double quotes for text that needs to be translated (will appear on the screen), and single quotes for other strings.
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 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.