SET FORMAT

SET FORMAT*

Activate a format when READ is executed

Syntax

      SET FORMAT TO [<idProcedure>[.<ext>]]

Arguments

TO <idProcedure> is a format (.fmt) file, a program (.prg) file, or a procedure.

<ext> is the extension of the format file. If not specified, the default extension is (.fmt).

SET FORMAT TO with no argument deactivates the current format.

Description

SET FORMAT defines a procedure to execute when a READ is invoked. Unlike the interpreted environment, formats are not opened and executed at runtime. Instead, the Harbour compiler treats SET FORMAT the same as a DO command. The compiler first looks to see whether it has already compiled a procedure with the same name as <idProcedure>. If it has, it uses that procedure for the reference. If <idProcedure> is not found, the compiler looks to disk for a file with the same name. If this file is not found, an external reference is generated that must be resolved at link time.

SET FORMAT is a compatibility command and not recommended.

Notes

. Active format procedures: Unlike other dialects where each work area can have an active format, Harbour supports only one active format procedure for all work areas.

. Screen CLEARing: Harbour does not clear the screen when a format procedure is executed.

. Legal statements: Format procedures allow statements and commands in addition to @…SAY and @…GET.

. Multiple pages: Harbour does not support multiple-page format procedures.

Examples

      .  This example uses a format procedure to add records to a
         database file until the user presses Esc:

      USE Sales NEW
      SET FORMAT TO SalesScr
      DO WHILE LASTKEY() != 27
         APPEND BLANK
         READ
      ENDDO
      RETURN

      PROCEDURE SalesScr
         @ 12, 12 SAY "Branch     : " GET  Branch
         @ 13, 12 SAY "Salesman   : " GET  Salesman
         RETURN

Seealso

@…GET, @…SAY, PROCEDURE, READ

SET PROCEDURE

SET PROCEDURE*

Compile procedures and functions into the current object (.OBJ) file

Syntax

      SET PROCEDURE TO [<idProgramFile>[.<ext>]]

Arguments

TO <idProgramFile> is the name of the procedure file to compile into the current object file. It can optionally include a path and/or drive designator.

<ext> is the optional extension of the procedure. If not specified, .prg is assumed.

SET PROCEDURE TO with no argument is ignored.

Description

SET PROCEDURE directs the compiler to compile all procedures and user- defined functions declared within the specified procedure file into the current object (.OBJ) file.

SET PROCEDURE is a compatibility command and not recommended. It has been superseded by other facilities more appropriate to the compiled environment (e.g., the compiler script (.clp)) file.

See the Clipper “Compiler” chapter in the Programming and Utilities Guide for a full discussion of program architecture and configuration.

Seealso

#include, DO*, FUNCTION, PROCEDURE, RETURN

STATIC

STATIC

Declare and initialize static variables and arrays

Syntax

       STATIC <identifier> [[:= <initializer>], ... ]

Arguments

<identifier> is the name of the variable or array to declare static. If the <identifier> is followed by square brackets ([ ]), it is created as an array. If the <identifier> is an array, the syntax for specifying the number of elements for each dimension can be array[<nElements>, <nElements2>, …] or array[<nElements>]

[<nElements2>]… The maximum number of elements is 4096. The maximum number of dimensions is limited only by available memory.

<initializer> is the optional assignment of a value to a new static variable. An <initializer> for a static variable consists of the inline assignment operator (:=) followed by a compile-time constant expression consisting entirely of constants and operators or a literal array. If no explicit <initializer> is specified, the variable is given an initial value of NIL. In the case of an array, each element is NIL. Array identifiers cannot be given values with an <initializer>.

Note: The macro operator (&) cannot be used in a STATIC declaration statement.

Description

The STATIC statement declares variables and arrays that have a lifetime of the entire program but are only visible within the entity that creates them. Static variables are visible only within a procedure or user-defined function if declared after a PROCEDURE or FUNCTION statement. Static variables are visible to all procedures and functions in a program (.prg) file (i.e., have filewide scope) if they are declared before the first procedure or user-defined function definition in the file. Use the /N compiler option to compile a program with filewide variable scoping.

All static variables in a program are created when the program is first invoked, and all values specified in a static <initializer> are assigned to the variable before the beginning of program execution.

Declarations of static variables within a procedure or user-defined function must occur before any executable statement including PRIVATE, PUBLIC, and PARAMETERS. If a variable of the same name is declared FIELD, LOCAL, or MEMVAR within the body of a procedure or user-defined function, a compiler error occurs and no object (.OBJ) file is generated.

The maximum number of static variables in a program is limited only by available memory.

Notes

. Inspecting static variables within the Debugger: To access static variable names within the Harbour debugger, you must compile program (.prg) files using the /B option so that static variable information is included in the object (.OBJ) file.

. Macro expressions: You may not refer to static variables within macro expressions or variables. If a static variable is referred to within a macro expression or variable, a private or public variable of the same name will be accessed instead. If no such variable exists, a runtime error will be generated.

. Memory files: Static variables cannot be SAVED to or RESTOREd from memory (.mem) files.

. Type of a static local variable: Since TYPE() uses the macro operator (&) to evaluate its argument, you cannot use TYPE() to determine the type of a local or static variable or an expression containing a local or static variable reference. The VALTYPE() function provides this facility by evaluating the function argument and returning the data type of its return value.

Examples

       .  This example declares static variables both with and without
          initializers:
          STATIC aArray1[20, 10], aArray2[20][10]
          STATIC cVar, cVar2
          STATIC cString := "my string", var
          STATIC aArray := {1, 2, 3}
       .  This example manipulates a static variable within a user-
          defined function.  In this example, a count variable increments
          itself each time the function is called:
          FUNCTION MyCounter( nNewValue )
             STATIC nCounter := 0         // Initial value assigned once
             IF nNewValue != NIL
                nCounter:= nNewValue      // New value for nCounter
             ELSE
                nCounter++                // Increment nCounter
             ENDIF
             RETURN nCounter
       .  This example demonstrates a static variable declaration that
          has filewide scope.  In this code fragment, aArray is visible to both
          procedures that follow the declaration:
          STATIC aArray := {1, 2, 3, 4}
          FUNCTION One
             ? aArray[1]                  // Result: 1
             RETURN NIL
          FUNCTION Two
             ? aArray[3]                  // Result: 3
             RETURN NIL

Seealso

FUNCTION, LOCAL, PARAMETERS, PRIVATE, PROCEDURE, PUBLIC

RETURN

RETURN

Terminate a procedure, user-defined function, or program

Syntax

       RETURN [<exp>]

Arguments

<exp> is an expression of any type that evaluates to the return value for user-defined functions. If a user-defined function terminates without executing a RETURN statement, the return value is NIL.

Description

RETURN terminates a procedure, user-defined function, or program by returning control to either the calling procedure or user-defined function. When RETURN executes in the highest level procedure, control passes to the operating system. All private variables created and local variables declared in the current procedure or user-defined function are released when control returns to the calling procedure.

There can be more than one RETURN in a procedure or user-defined function. A procedure or user-defined function need not, however, end with a RETURN. Since user-defined functions must return values, each must contain at least one RETURN statement with an argument.

Note: A procedure or user-defined function definition is terminated by a PROCEDURE statement, a FUNCTION statement, or end of file but not by a RETURN statement.

Notes

. Arrays: Since array is a data type like any other data type, instances of array type are really values like character strings and, therefore, can be RETURNed from a user-defined function.

. RETURN TO MASTER: Harbour does not support RETURN TO MASTER or any other form of RETURN specifying the level to which the call is to return. You can, however, simulate these operations with BEGIN SEQUENCE…END.

Examples

       .  These examples illustrate the general form of the RETURN
          statement in a procedure and in a user-defined function:
          PROCEDURE <idProcedure>
             //
             <statements>...
             //
             RETURN
          FUNCTION <idFunction>
             //
             <statements>...
             //
             RETURN <expReturn>
       .  This example returns an array, created in a user-defined
          function, to a calling procedure or user-defined function:
          FUNCTION PassArrayBack
             PRIVATE aArray[10][10]
             aArray[1][1] = "myString"
             RETURN aArray

Seealso

BEGIN SEQUENCE, FUNCTION, LOCAL, PRIVATE, PROCEDURE

FUNCTION

FUNCTION

Declare a user-defined function name and formal parameters

Syntax

       [STATIC] FUNCTION <idFunction>[(<idParam list>)]
              [LOCAL <identifier> [[:= <initializer>], ... ]]
              [STATIC <identifier> [[:= <initializer>], ... ]]
              [FIELD <identifier list> [IN <idAlias>]]
              [MEMVAR <identifier list>]
              .
              . <executable statements>
              .
              RETURN <exp>

Arguments

<idFunction> is the name of the user-defined function to be declared. User-defined function names can be any length, but only the first 10 characters are significant. Names can contain any combination of characters, numbers, or underscores, but must begin with a character or an underscore. Leading underscores are not recommended since they are reserved for internal functions.

<idParam list> is the declaration of one or more parameter variables. Variables specified in this list are declared local.

STATIC FUNCTION declares a user-defined function that can be invoked only by procedures and user-defined functions declared in the same program (.prg) file.

LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current function.

STATIC declares and optionally initializes a list of variables or arrays whose visibility is the current user-defined function and lifetime is the duration of the program.

FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.

MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.

<identifier> and <identifier list> are labels to be used as variable or array names.

<initializer> is a value to which an array or variable is originally set in an inline expression. RETURN <exp> passes control back to the calling procedure or user-defined function, returning the result of <exp> as the value of the function. Each function must have at least one

RETURN statement that returns a value. RETURN statements can occur anywhere in the body of a function.

Description

The FUNCTION statement declares a user-defined function and an optional list of local variables to receive parameters often referred to as formal parameters. A user-defined function is a subprogram comprised of a set of declarations and statements executed whenever you refer to <idFunction> followed by an open and closed parentheses pair. A function definition begins with a FUNCTION statement which is the FUNCTION declaration and ends with the next FUNCTION statement, PROCEDURE statement, or end of file.

Functions encapsulate a computational block of code and then later create expressions using the value returned. Functions and procedures increase both readability and modularity, isolate change, and help manage complexity.

A function in Harbour is the same as a procedure, except that it must return a value. The returned value can be any data type including an array, a code block, or NIL. Each function must begin with a FUNCTION statement and contain at least one RETURN statement with an argument. Function declarations cannot be nested within other function definitions. A user-defined function can be used wherever standard functions are supported, including expressions.

The visibility of function names falls into two classes. Functions that are visible anywhere in a program are referred to as public functions and declared with a FUNCTION statement. Functions that are visible only within the current program (.prg) file are referred to as static functions and declared with a STATIC FUNCTION statement.

Static functions have filewide scope. Static functions limit visibility of a function name, thereby restricting access to the function. Because of this, subsystems defined within a single program (.prg) file can provide an access protocol with a series of public functions and conceal the implementation details of the subsystem within static functions and procedures. Since the static function references are resolved at compile time, they preempt references to public functions which are resolved at link time. This ensures that within a program file, a reference to a static function executes that function if there is a name conflict with a public function.

For more information on user-defined functions, variable declarations, and parameter passing, refer to the “Basic Concepts” chapter.

Notes

. Calling a user-defined function: Use the same notation to call a user-defined function as when calling a standard Harbour function: <idFunction>([<argument list>])

You can call a user-defined function within an expression or on a line by itself. If called on a line by itself, the return value is ignored.

You can also call a user-defined function as an aliased expression by prefacing it with an alias and enclosing it in parentheses: <idAlias>->(<idFunction>(<argument list>))

When you call a user-defined function as an aliased expression, the work area associated with <idAlias> is selected, the expression is executed, and the original work area is then reselected. You can specify an aliased expression on a line by itself, as you would any other expression.

A user-defined function in Harbour may call itself recursively. This means you can make a reference to a user-defined function in statements or expressions of the same user-defined function definition.

. Parameters: User-defined functions, like procedures, can receive parameters passed from a calling procedure, user-defined function, or DOS command line. A parameter is a place holder for a value or reference. In Harbour, there are two ways to express parameters: you can declare a list of local variable names as a part of the FUNCTION declaration (referred to as formal parameters), or you can specify a list of private variables in a separate PARAMETERS statement. Note that you cannot mix a declaration of formal parameters with a PARAMETERS statement. Attempting this will result in a fatal compiler error.

Functions receive parameters in the order passed. In Harbour, the number of parameters does not have to match the number of arguments passed. You can skip arguments or omit them from the end of the argument list. A parameter not receiving a value or reference is initialized to NIL. You can skip a parameter by passing NIL. If arguments are specified, PCOUNT() returns the position of the last argument passed. (If more arguments are passed than are parameters, they are ignored.)

Parameters specified in a user-defined function can receive arguments passed by value or reference. The default method for expressions and variables is by value. This includes variables that contain references to arrays and objects. All variables except field variables, when prefaced with the pass-by-reference operator (@), are passed by reference. Field variables cannot be passed by reference and are always passed by value.

Examples

       .  This example demonstrates a user-defined function that formats
          numeric values as currency:
       ? Currency( 1000 )               // Result: Þ1,000.00
       FUNCTION Currency( nNumber )
          LOCAL cNumber
          IF nNumber < 0
             cNumber := TRANSFORM(-1 * nNumber, ;
                   "999,999,999,999.99")
             cNumber := PADL("(Þ" + LTRIM(cNumber) + ")", ;
                   LEN(cNumber))
          ELSE
             cNumber := TRANSFORM(nNumber, ;
                   "999,999,999,999.99")
             cNumber := PADL("Þ" + LTRIM(cNumber), ;
                   LEN(cNumber))
          ENDIF
          RETURN cNumber
       . This example demonstrates a user-defined function that takes a
          character string formatted as a comma-separated list and returns 
          an array with one element per item:
       aList := ListAsArray("One, Two")
       // Result: {"One", "Two"}
       FUNCTION ListAsArray( cList )
          LOCAL nPos
          // Define an empty array
          LOCAL aList := {}
          //
          DO WHILE (nPos := AT(",", cList)) != 0
             // Add a new element
             AADD(aList, SUBSTR(cList, 1, nPos - 1))
             cList := SUBSTR(cList, nPos + 1)
          ENDDO
          AADD(aList, cList)
          //
          // Return the array
          RETURN aList
       .  This example checks for a skipped argument by comparing
          the parameter to NIL:
       FUNCTION MyFunc( param1, param2, param3 )
          IF param2 == NIL
             param2 := "default value"
          ENDIF
          .
          . <statements>
          .
          RETURN NIL
       .  This example uses the user-defined function, Currency()
          (defined above), as an aliased expression:
       USE Invoices NEW
       USE Customer NEW
       ? Invoices->(Currency(Amount))

Seealso

LOCAL, PARAMETERS, PCOUNT(), PRIVATE, PROCEDURE, RETURN

DO

DO*

Call a procedure

Syntax

      DO <idProcedure> [WITH <argument list>]

Arguments

<idProcedure> is the name of the procedure or user-defined function to be executed.

WITH <argument list> specifies up to 128 arguments, separated by commas, to pass to <idProcedure>. Each argument may be a single variable, field, array, array element, expression, or object. Arguments can be skipped or left off the end of the list.

Description

The DO statement calls a procedure or user-defined function, optionally passing arguments to the called routine. It performs the same action as a user-defined function or procedure specified on a line by itself with the exception that variables other than field variables are passed by reference as the default. In order to pass a field variable as an argument, enclose it in parentheses, unless you declare it with the FIELD statement or with an alias.

The number of specified arguments need not match the number of specified parameters in the called procedure. If the number of arguments is less than the number of parameters, the parameter variables with no corresponding arguments are initialized with a NIL value when the procedure is called. If the number of arguments is greater than the number of parameters, they are ignored.

Also, skipping an argument within the <argument list> by leaving an empty spot next to the comma initializes the corresponding argument to NIL. To detect the position of the last argument passed in the <argument list>, use PCOUNT(). To detect a skipped argument, compare the receiving parameter to NIL.

In addition to calling a procedure or user-defined function, DO also has an effect on compilation if you compile the current program file without the /M option. If the compiler encounters a DO statement and the specified procedure has not already been compiled, the compiler searches the current directory for a .prg file with the same name and compiles it. If the file with the same name as the procedure is not found, the called procedure is assumed to be external, and a reference is added to the object (.OBJ) file. At link time, the linker will search other object files and libraries for this external reference.

DO is a compatibility statement and therefore not recommended. Calling a procedure or function on a line by itself is the preferred method. Since this preferred calling convention normally passes parameters by value, you must preface an argument with the pass- by-reference operator (@) in order to pass by reference. If you are using DO to make a procedure call more readable, a user-defined command, specified with the #command directive, can provide greater readability without sacrificing the safety of variables passed as parameters. For more information on passing parameters refer to the Functions and Procedures section of the “Basic Concepts”.

Examples

       .  This example executes a procedure with no parameters:
          DO AcctsRpt
          AcctsRpt()                           // Preferred method
       .  This example executes a procedure passing two constants:
          DO QtrRpt WITH "2nd", "Sales Division"
          QtrRpt("2nd", "Sales Division")      // Preferred method
       .  In this example, a procedure is executed with the first
          argument passed by value and the second passed by reference:
          nNumber := 12
          DO YearRpt WITH nNumber + 12, nNumber
          YearRpt(nNumber + 12, @nNumber)      // Preferred method
       .  Here, a procedure is invoked with skipped arguments embedded
          in the list of arguments:
          DO DisplayWindow WITH ,,,,"My Window"
          DisplayWindow(,,,,"My Window")       // Preferred method

Seealso

FUNCTION, LOCAL, PARAMETERS, PRIVATE, PROCEDURE, PUBLIC

PARAMETERS

PARAMETERS

Declares private parameter variables

Syntax

PARAMETERS <idPrivate list>

Arguments

<idPrivate list> is one or more parameter variables separated by commas.

The number of receiving variables does not have to match the number of arguments passed by the calling procedure or user-defined function.

Description

The PARAMETERS statement declares private variables to receive passed values or references. Receiving variables are referred to as parameters. The values or references actually passed by a procedure or user-defined function invocation are referred to as arguments.

When a PARAMETERS statement executes, all variables in the parameter list are created as private variables and all public or private variables with the same names are hidden until the current procedure or user-defined function terminates. A PARAMETERS statement is an executable statement and, therefore, can occur anywhere in a procedure or user-defined function, but must follow all compile-time variable declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

Parameters can also be declared as local variables if specified as a part of the PROCEDURE or FUNCTION declaration statement (see the example). Parameters specified in this way are referred to as formal parameters. Note that you cannot specify both formal parameters and a PARAMETERS statement with a procedure or user-defined function definition. Attempting to do this results in a fatal compiler error and an object file is not generated.

In Harbour the number of arguments and parameters do not have to match. If you specify more arguments than parameters, the extra arguments are ignored. If you specify fewer arguments than parameters, the extra parameters are created with a NIL value. If you skip an argument, the corresponding parameter is initialized to NIL. The PCOUNT() function returns the position of the last argument passed in the list of arguments. This is different from the number of parameters passed since it includes skipped parameters.

Examples

     .  This user-defined function receives values passed into private
        parameters with a PARAMETERS statement:

        FUNCTION MyFunc
           PARAMETERS cOne, cTwo, cThree
           ? cOne, cTwo, cThree
           RETURN NIL

     .  This example is similar, but receives values passed into local
        variables by declaring the parameter variables within the FUNCTION
        declaration:

        FUNCTION MyFunc( cOne, cTwo, cThree )
           ? cOne, cTwo, cThree
           RETURN NIL

See Also

 FUNCTION, LOCAL, PCOUNT(), PRIVATE, PROCEDURE, STATIC