C5_#define

#define
 Define a manifest constant or pseudofunction
------------------------------------------------------------------------------
 Syntax

     #define <idConstant> [<resultText>]
     #define <idFunction>([<arg list>]) [<exp>]

 Arguments

     <idConstant> is the name of an identifier to define.

     <resultText> is the optional replacement text to substitute whenever
     a valid <idConstant> is encountered.

     <idFunction> is a pseudofunction definition with an optional
     argument list (<arg list>).  If you include <arg list>, it is delimited
     by parentheses (()) immediately following <idFunction>.

     <exp> is the replacement expression to substitute when the
     pseudofunction is encountered.  Enclose this expression in parentheses
     to guarantee precedence of evaluation when the pseudofunction is
     expanded.

     Note:  #define identifiers are case-sensitive, where #command and
     #translate identifiers are not.

 Description

     The #define directive defines an identifier and, optionally, associates
     a text replacement string.  If specified, replacement text operates much
     like the search and replace operation of a text editor.  As each source
     line from a program file is processed by the preprocessor, the line is
     scanned for identifiers.  If a currently defined identifier is
     encountered, the replacement text is substituted in its place.

     Identifiers specified with #define follow most of the identifier naming
     rules in Clipper .  Defined identifiers can contain any combination
     of alphabetic and numeric characters, including underscores.  Defined
     identifiers, however, differ from other identifiers by being case-
     sensitive.  As a convention, defined identifiers are specified in
     uppercase to distinguish them from other identifiers used within a
     program.  Additionally, identifiers are specified with a one or two
     letter prefix to group similar identifiers together and guarantee
     uniqueness.  Refer to one of the supplied header files in the
     \CLIP53\INCLUDE directory for examples.

     When specified, each definition must occur on a line by itself.  Unlike
     statements, more than one directive cannot be specified on the same
     source line.  You may continue a definition on a subsequent line by
     employing a semicolon (;).  Each #define directive is specified followed
     by one or more white space characters (spaces or tabs), a unique
     identifier, and optional replacement text.  Definitions can be nested,
     allowing one identifier to define another.

     A defined identifier has lexical scope like a filewide static variable.  It
     is only valid in the program (.prg) file in which it is defined unless
     defined in Std.ch or the header file specified on the compiler command
     line with the /U option.  Unlike a filewide static variable, a defined
     identifier is visible from the point where it is defined in the program
     file until it is either undefined, redefined, or the end of the program
     file is reached.

     You can redefine or undefine existing identifiers.  To redefine an
     identifier, specify a new #define directive with the identifier and the
     new replacement text as its arguments.  The current definition is then
     overwritten with the new definition, and a compiler warning is issued in
     case the redefinition is inadvertent.  To undefine an identifier,
     specify an #undef directive with the identifier as its argument.
     #define directives have three basic purposes:

     .  To define a control identifier for #ifdef and #ifndef

     .  To define a manifest constant--an identifier defined to
        represent a constant value

     .  To define a compiler pseudofunction

     The following discussion expands these three purposes of the #define
     directive in your program.

 Preprocessor Identifiers

     The most basic #define directive defines an identifier with no
     replacement text.  You can use this type of identifier when you need to
     test for the existence of an identifier with either the #ifdef or
     #ifndef directives.  This is useful to either exclude or include code
     for conditional compilation.  This type of identifier can also be
     defined using the /D compiler option from the compiler command line.
     See the examples below.

 Manifest Constants

     The second form of the #define directive assigns a name to a constant
     value.  This form of identifier is referred to as a manifest constant.
     For example, you can define a manifest constant for the INKEY() code
     associated with a key press:

     #define K_ESC   27
     IF LASTKEY() = K_ESC
        .
        . <statements>
        .
     ENDIF

     Whenever the preprocessor encounters a manifest constant while scanning
     a source line, it replaces it with the specified replacement text.

     Although you can accomplish this by defining a variable, there are
     several advantages to using a manifest constant: the compiler generates
     faster and more compact code for constants than for variables; and
     variables have memory overhead where manifest constants have no runtime
     overhead, thus saving memory and increasing execution speed.
     Furthermore, using a variable to represent a constant value is
     conceptually inconsistent.  A variable by nature changes and a constant
     does not.

     Use a manifest constant instead of a constant for several reasons.
     First, it increases readability.  In the example above, the manifest
     constant indicates more clearly the key being represented than does the
     INKEY() code itself.  Second, manifest constants localize the definition
     of constant values, thereby making changes easier to make, and
     increasing reliability.  Third, and a side effect of the second reason,
     is that manifest constants isolate implementation or environment
     specifics when they are represented by constant values.

     To further isolate the effects of change, manifest constants and other
     identifiers can be grouped together into header files allowing you to
     share identifiers between program (.prg) files, applications, and groups
     of programmers.  Using this methodology, definitions can be standardized
     for use throughout a development organization.  Merge header files into
     the current program file by using the #include directive.

     For examples of header files, refer to the supplied header files in the
     \CLIP53\INCLUDE directory.

 Compiler Pseudo-functions

     In addition to defining constants as values, the #define directive can
     also define pseudofunctions that are resolved at compile time.  A
     pseudofunction definition is an identifier immediately followed by an
     argument list, delimited by parentheses, and the replacement expression.
     For example:

     #define AREA(nLength, nWidth)      (nLength * nWidth)
     #define SETVAR(x, y)               (x := y)
     #define MAX(x, y)                  (IF(x > y, x, y))

     Pseudofunctions differ from manifest constants by supporting arguments.
     Whenever the preprocessor scans a source line and encounters a function
     call that matches the pseudofunction definition, it substitutes the
     function call with the replacement expression.  The arguments of the
     function call are transported into the replacement expression by the
     names specified in the argument list of the identifier definition.  When
     the replacement expression is substituted for the pseudofunction, names
     in the replacement expression are replaced with argument text.  For
     example, the following invocations,

     ? AREA(10, 12)
     SETVAR(nValue, 10)
     ? MAX(10, 9)

     are replaced by :

     ? (10 * 12)
     nValue := 10
     ? (IF(10 > 9, 10, 9)

     It is important when defining pseudofunctions, that you enclose the
     result expression in parentheses to enforce the proper order of
     evaluation.  This is particularly important for numeric expressions.  In
     pseudofunctions, you must specify all arguments.  If the arguments are
     not specified, the function call is not expanded as a pseudofunction and
     exits the preprocessor to the compiler as encountered.

     Pseudofunctions do not entail the overhead of a function call and are,
     therefore, generally faster.  They also use less memory.
     Pseudofunctions, however, are more difficult to debug within the
     debugger, have a scope different from declared functions and procedures,
     do not allow skipped arguments, and are case-sensitive.

     You can avoid some of these deficiencies by defining a pseudofunction
     using the #translate directive.  #translate pseudofunctions are not case-
     sensitive, allow optional arguments, and obey the dBASE four-letter
     rule.  See the #translate directive reference in this chapter for more
     information.

 Examples

     .  In this example a manifest constant conditionally controls the
        compilation of debugging code:

        #define DEBUG
        .
        . <statements>
        .
        #ifdef DEBUG
           Assert(FILE("System.dbf"))
        #endif

     .  This example defines a manifest constant and substitutes it
        for an INKEY() value:

        #define K_ESC      27
        .
        . <statements>
        .
        IF INKEY() != K_ESC
           DoIt()
        ELSE
           StopIt()
        ENDIF

     .  This example defines pseudofunctions for the standard
        Clipper functions, MAX() and ALLTRIM():

        #define MAX(arg1, arg2)      (IF(arg1 > arg2, ;
           arg1, arg2))
        #define ALLTRIM(cString)   (RTRIM(LTRIM(cString)))
        .
        . <statements>
        .
        ? MAX(1, 2)
        ? ALLTRIM("  Hello  ")

See Also: #command #ifdef #ifndef #undef #xcommand

C5_#command | #translate

#command | #translate 
 Specify a user-defined command or translation directive

 Syntax

     #command   <matchPattern> => <resultPattern>
     #translate   <matchPattern> => <resultPattern>

 Arguments

     <matchPattern> is the pattern the input text should match.

     <resultPattern> is the text produced if a portion of input text
     matches the <matchPattern>.

     The => symbol between <matchPattern> and <resultPattern> is, along with
     #command or #translate, a literal part of the syntax that must be
     specified in a #command or #translate directive.  The symbol consists of
     an equal sign followed by a greater than symbol with no intervening
     spaces.  Do not confuse the symbol with the >= or the <= comparison
     operators in the Clipper language.

 Description

     #command and #translate are translation directives that define commands
     and pseudofunctions.  Each directive specifies a translation rule.  The
     rule consists of two portions:  a match pattern and a result pattern.
     The match pattern matches a command specified in the program (.prg) file
     and saves portions of the command text (usually command arguments) for
     the result pattern to use.  The result pattern then defines what will be
     written to the result text and how it will be written using the saved
     portions of the matching input text.

     #command and #translate are similar, but differ in the circumstance
     under which their match patterns match input text.  A #command directive
     matches only if the input text is a complete statement, while #translate
     matches input text that is not a complete statement.  #command defines a
     complete command and #translate defines clauses and pseudofunctions that
     may not form a complete statement.  In general, use #command for most
     definitions and #translate for special cases.

     #command and #translate are similar to but more powerful than the
     #define directive.  #define, generally, defines identifiers that control
     conditional compilation and manifest constants for commonly used
     constant values such as INKEY() codes.  Refer to any of the header files
     in the \CLIP53\INCLUDE directory for examples of manifest constants
     defined using #define.

     #command and #translate directives have the same scope as the #define
     directive.  The definition is valid only for the current program (.prg)
     file unless defined in Std.ch or the header specified with the /U option
     on the compiler command line.  If defined elsewhere, the definition is
     valid from the line where it is specified to the end of the program
     file.  Unlike #define, a #translate or #command definition cannot be
     explicitly undefined.  The #undef directive has no effect on a #command
     or #translate definition.

     As the preprocessor encounters each source line preprocessor, it scans
     for definitions in the following order of precedence: #define,
     #translate, and #command.  When there is a match, the substitution is
     made to the result text and the entire line is reprocessed until there
     are no matches for any of the three types of definitions.  #command and
     #translate rules are processed in stack-order (i.e., last in-first out,
     with the most recently specified rule processed first).

     In general, a command definition provides a way to specify an English
     language statement that is, in fact, a complicated expression or
     function call, thereby improving the readability of source code.  You
     can use a command in place of an expression or function call to impose
     order of keywords, required arguments, combinations of arguments that
     must be specified together, and mutually exclusive arguments at compile
     time rather than at runtime.  This can be important since procedures and
     user-defined functions can now be called with any number of arguments,
     forcing any argument checking to occur at runtime.  With command
     definitions, the preprocessor handles some of this.

     All commands in Clipper are defined using the #command directive and
     supplied in the standard header file, Std.ch, located in the
     \CLIP53\INCLUDE directory.  The syntax rules of #command and #translate
     facilitate the processing of all Clipper and dBASE-style commands
     into expressions and function calls.  This provides Clipper
     compatibility, as well as avenues of compatibility with other dialects.

     When defining a command, there are several prerequisites to properly
     specifying the command definition.  Many preprocessor commands require
     more than one #command directive because mutually exclusive clauses
     contain a keyword or argument.  For example, the @...GET command has
     mutually exclusive VALID and RANGE clauses and is defined with a
     different #command rule to implement each clause.

     This also occurs when a result pattern contains different expressions,
     functions, or parameter structures for different clauses specified for
     the same command (e.g., the @...SAY command).  In Std.ch, there is a
     #command rule for @...SAY specified with the PICTURE clause and another
     for @...SAY specified without the PICTURE clause.  Each formulation of
     the command is translated into a different expression.  Because
     directives are processed in stack order, when defining more than one
     rule for a command, place the most general case first, followed by the
     more specific ones.  This ensures that the proper rule will match the
     command specified in the program (.prg) file.

     For more information and a general discussion of commands, refer to the
     "Basic Concepts" chapter in the Programming and Utilities Guide.

 Match Pattern

     The <matchPattern> portion of a translation directive is the pattern the
     input text must match.  A match pattern is made from one or more of the
     following components, which the preprocessor tries to match against
     input text in a specific way:

     .  Literal values are actual characters that appear in the match
        pattern.  These characters must appear in the input text, exactly as
        specified to activate the translation directive.

     .  Words are keywords and valid identifiers that are compared
        according to the dBASE convention (case-insensitive, first four
        letters mandatory, etc.).  The match pattern must start with a Word.

        #xcommand and #xtranslate can recognize keywords of more than four
        significant letters.

     .  Match markers are label and optional symbols delimited by
        angle brackets (<>) that provide a substitute (idMarker) to be used
        in the <resultPattern> and identify the clause for which it is a
        substitute.  Marker names are identifiers and must, therefore, follow
        the Clipper identifier naming conventions.  In short, the name
        must start with an alphabetic or underscore character, which may be
        followed by alphanumeric or underscore characters.

        This table describes all match marker forms:

        Match Markers
        ---------------------------------------------------------------------
        Match Marker             Name
        ---------------------------------------------------------------------
        <idMarker>               Regular match marker
        <idMarker,...>           List match marker
        <idMarker:word list>     Restricted match marker
        <*idMarker*>             Wild match marker
        <(idMarker)>             Extended Expression match marker
        ---------------------------------------------------------------------

        -  Regular match marker: Matches the next legal expression in the
           input text.  The regular match marker, a simple label, is the most
           general and, therefore, the most likely match marker to use for a
           command argument.  Because of its generality, it is used with the
           regular result marker, all of the stringify result markers, and
           the blockify result marker.

        -  List match marker: Matches a comma-separated list of legal
           expressions.  If no input text matches the match marker, the
           specified marker name contains nothing.  You must take care in
           making list specifications because extra commas will cause
           unpredictable and unexpected results.

           The list match marker defines command clauses that have lists as
           arguments.  Typically these are FIELDS clauses or expression lists
           used by database commands.  When there is a match for a list match
           marker, the list is usually written to the result text using either the
           normal or smart stringify result marker.  Often, lists are written
           as literal arrays by enclosing the result marker in curly ({ })
           braces.

        -  Restricted match marker: Matches input text to one of the
           words in a comma-separated list.  If the input text does not match
           at least one of the words, the match fails and the marker name
           contains nothing.

           A restricted match marker is generally used with the logify result
           marker to write a logical value into the result text.  If there is
           a match for the restricted match marker, the corresponding logify
           result marker writes true (.T.) to the result text; otherwise, it
           writes false (.F.).  This is particularly useful when defining
           optional clauses that consist of a command keyword with no
           accompanying argument.  Std.ch implements the REST clause of
           database commands using this form.

        -  Wild match marker: Matches any input text from the current
           position to the end of a statement.  Wild match markers generally
           match input that may not be a legal expression, such as #command
           NOTE <*x*> in Std.ch, gather the input text to the end of the
           statement, and write it to the result text using one of the
           stringify result markers.

        -  Extended expression match marker: Matches a regular or
           extended expression, including a file name or path specification.
           It is used with the smart stringify result marker to ensure that
           extended expressions will not get stringified, while normal,
           unquoted string file specifications will.

     .  Optional match clauses are portions of the match pattern
        enclosed in square brackets ([ ]).  They specify a portion of the
        match pattern that may be absent from the input text.  An optional
        clause may contain any of the components allowed within a
        <matchPattern>, including other optional clauses.

        Optional match clauses may appear anywhere and in any order in the
        match pattern and still match input text.  Each match clause may
        appear only once in the input text.  There are two types of optional
        match clauses: one is a keyword followed by match marker, and the
        other is a keyword by itself.  These two types of optional match
        clauses can match all of the traditional command clauses typical of
        the Clipper command set.

        Optional match clauses are defined with a regular or list match
        marker to match input text if the clause consists of an argument or a
        keyword followed by an argument (see the INDEX clause of the USE
        command in Std.ch).  If the optional match clause consists of a
        keyword by itself, it is matched with a restricted match marker (see
        the EXCLUSIVE or SHARED clause of the USE command in Std.ch).

        In any match pattern, you may not specify adjacent optional match
        clauses consisting solely of match markers, without generating a
        compiler error.  You may repeat an optional clause any number of
        times in the input text, as long as it is not adjacent to any other
        optional clause.  To write a repeated match clause to the result
        text, use repeating result clauses in the <resultPattern> definition.

 Result Pattern

     The <resultPattern> portion of a translation directive is the text the
     preprocessor will produce if a piece of input text matches the
     <matchPattern>.  <resultPattern> is made from one or more of the
     following components:

     .  Literal tokens are actual characters that are written directly
        to the result text.

     .  Words are Clipper keywords and identifiers that are written
        directly to the result text.

     .  Result markers:  refer directly to a match marker name.  Input
        text matched by the match marker is written to the result text via
        the result marker.

        This table lists the Result marker forms:

        Result Markers
        ---------------------------------------------------------------------
        Result Marker     Name
        ---------------------------------------------------------------------
        <idMarker>        Regular result marker
        #<idMarker>       Dumb stringify result marker
        <"idMarker">      Normal stringify result marker
        <(idMarker)>      Smart stringify result marker
        <{idMarker}>      Blockify result marker
        <.idMarker.>      Logify result marker
        ---------------------------------------------------------------------

        -  Regular result marker:  Writes the matched input text to the
           result text, or nothing if no input text is matched.  Use this,
           the most general result marker, unless you have special
           requirements.  You can use it with any of the match markers, but
           it almost always is used with the regular match marker.

        -  Dumb stringify result marker:  Stringifies the matched input
           text and writes it to the result text.  If no input text is
           matched, it writes a null string ("").  If the matched input text
           is a list matched by a list match marker, this result marker
           stringifies the entire list and writes it to the result text.

           This result marker writes output to result text where a string is
           always required.  This is generally the case for commands where a
           command or clause argument is specified as a literal value but the
           result text must always be written as a string even if the
           argument is not specified.

        -  Normal stringify result marker:  Stringifies the matched input
           text and writes it to the result text.  If no input text is
           matched, it writes nothing to the result text.  If the matched
           input text is a list matched by a list match marker, this result
           marker stringifies each element in the list and writes it to the
           result text.

           The normal stringify result marker is most often used with the
           blockify result marker to compile an expression while saving a
           text image of the expression (See the SET FILTER condition and the
           INDEX key expression in Std.ch).

        -  Smart stringify result marker:  Stringifies matched input text
           only if source text is enclosed in parentheses.  If no input text
           matched, it writes nothing to the result text.  If the matched
           input text is a list matched by a list match marker, this result
           marker stringifies each element in the list (using the same
           stringify rule) and writes it to the result text.

           The smart stringify result marker is designed specifically to
           support extended expressions for commands other than SETs with
           <xlToggle> arguments.  Extended expressions are command syntax
           elements that can be specified as literal text or as an expression
           if enclosed in parentheses.  The <xcDatabase> argument of the USE
           command is a typical example.  For instance, if the matched input
           for the <xcDatabase> argument is the word Customer, it is written
           to the result text as the string "Customer," but the expression
           (cPath + cDatafile) would be written to the result text unchanged
           (i.e., without quotes).

        -  Blockify result marker: Writes matched input text as a code
           block without any arguments to the result text.  For example, the
           input text x + 3 would be written to the result text as {|| x +
           3}.  If no input text is matched, it writes nothing to the result
           text.  If the matched input text is a list matched by a list match
           marker, this result marker blockifies each element in the list.

           The blockify result marker used with the regular and list match
           markers matches various kinds of expressions and writes them as
           code blocks to the result text.  Remember that a code block is a
           piece of compiled code to execute sometime later.  This is
           important when defining commands that evaluate expressions more
           than once per invocation.  When defining a command, you can use
           code blocks to pass an expression to a function and procedure as
           data rather than as the result of an evaluation.  This allows the
           target routine to evaluate the expression whenever necessary.

           In Std.ch, the blockify result marker defines database commands
           where an expression is evaluated for each record.  Commonly, these
           are field or expression lists, FOR and WHILE conditions, or key
           expressions for commands that perform actions based on key values.

        -  Logify result marker: Writes true (.T.) to the result text if
           any input text is matched; otherwise, it writes false (.F.) to the
           result text.  This result marker does not write the input text
           itself to the result text.

           The logify result marker is generally used with the restricted match
           marker to write true (.T.) to the result text if an optional
           clause is specified with no argument; otherwise, it writes false
           (.F.).  In Std.ch, this formulation defines the EXCLUSIVE and
           SHARED clauses of the USE command.

     .  Repeating result clauses are portions of the <resultPattern>
        enclosed by square brackets ([ ]).  The text within a repeating
        clause is written to the result text as many times as it has input
        text for any or all result markers within the clause.  If there is no
        matching input text, the repeating clause is not written to the
        result text.  Repeating clauses, however, cannot be nested.  If you
        need to nest repeating clauses, you probably need an additional
        #command rule for the current command.

        Repeating clauses are the result pattern part of the #command
        facility that create optional clauses which have arguments.  You can
        match input text with any match marker other than the restricted
        match marker and write to the result text with any of the
        corresponding result markers.  Typical examples of this facility are
        the definitions for the STORE and REPLACE commands in Std.ch.

 Notes

     .  Less than operator: If you specify the less than operator (<)
        in the <resultPattern> expression, you must precede it with the
        escape character (\).

     .  Multistatement lines: You can specify more than one statement
        as a part of the result pattern by separating each statement with a
        semicolon.  If you specify adjacent statements on two separate lines,
        the first statement must be followed by two semicolons.

 Examples

     These examples encompass many of the basic techniques you can use when
     defining commands with the #command and #translate directives.  In
     general, these examples are based on standard commands defined in
     Std.ch.  Note, however, the functions specified in the example result
     patterns are not the actual functions found in Std.ch, but fictitious
     functions specified for illustration only.

     .  This example defines the @...BOX command using regular match
        markers with regular result markers:

        #command  @ <top>, <left>, <bottom>, <right> BOX ;
              <boxstring>;
        =>;
              CmdBox( <top>, <left>, <bottom>, ;
              <right>,<boxstring> )

     .  This example uses a list match marker with a regular result
        marker to define the ? command:

        #command ? [<list,...>] => QOUT(<list>)

     .  This example uses a restricted match marker with a logify
        result marker to implement an optional clause for a command
        definition.  In this example, if the ADDITIVE clause is specified,
        the logify result marker writes true (.T.) to the result text;
        otherwise, it writes false (.F.):

        #command RESTORE FROM <file> [<add: ADDITIVE>];
        =>;
              CmdRestore( <(file)>, <.add.> )

     .  This example uses a list match marker with a smart stringify
        result marker to write to the result text the list of fields
        specified as the argument of a FIELDS clause.  In this example, the
        field list is written as an array with each field name as an element
        of the array:

        #command COPY TO <file> [FIELDS <fields,...>];
        =>;
              CmdCopyAll( <(file)>, { <(fields)> } )

     .  These examples use the wild match marker to define a command
        that writes nothing to the result text.  Do this when attempting to
        compile unmodified code developed in another dialect:

        #command SET ECHO <*text*>    =>
        #command SET TALK <*text*>    =>

     .  These examples use wild match markers with dumb stringify
        result markers to match command arguments specified as literals, then
        write them to the result text as strings in all cases:

        #command SET PATH TO <*path*>  =>  ;
           SET( _SET_PATH, #<path> )
        #command SET COLOR TO <*spec*> =>  SETCOLOR( #<spec> )

     .  These examples use a normal result marker with the blockify
        result marker to both compile an expression and save the text version
        of it for later use:

        #command SET FILTER TO <xpr>;
        =>;
              CmdSetFilter( <{xpr}>, <"xpr"> )

        #command INDEX ON <key> TO <file>;
        =>;
              CmdCreateIndex( <(file)>, <"key">, <{key}> )

     .  This example demonstrates how the smart stringify result
        marker implements a portion of the USE command for those arguments
        that can be specified as extended expressions:

        #command USE <db> [ALIAS <a>];
        =>;
              CmdOpenDbf( <(db)>, <(a)> )

     .  This example illustrates the importance of the blockify result
        marker for defining a database command.  Here, the FOR and WHILE
        conditions matched in the input text are written to the result text
        as code blocks:

        #command COUNT [TO <var>];
              [FOR <for>] [WHILE <while>];
              [NEXT <next>] [RECORD <rec>] [<rest:REST>] [ALL];
        =>;
              <var> := 0,;
              DBEVAL( {|| <var>++}, <{for}>, <{while}>,;
                 <next>, <rec>, <.rest.> )

     .  In this example the USE command again demonstrates the types
        of optional clauses with keywords in the match pattern.  one clause
        is a keyword followed by a command argument, and the second is solely
        a keyword:

        #command USE <db> [<new: NEW>] [ALIAS <a>] ;
              [INDEX <index,...>][<ex: EXCLUSIVE>] ;
              [<sh: SHARED>] [<ro: READONLY>];
        =>;
              CmdOpenDbf(<(db)>, <(a)>, <.new.>,;
                 IF(<.sh.> .OR. <.ex.>, !<.ex.>, NIL),;
                    <.ro.>, {<(index)>})

     .  This example uses the STORE command definition to illustrate
        the relationship between an optional match clause and a repeating
        result clause:

        #command STORE <value> TO <var1> [, <varN> ];
        =>;
              <var1> := [ <varN> := ] <value>

     .  This example uses #translate to define a pseudofunction:

        #translate AllTrim(<cString>) => LTRIM(RTRIM(<cString>))

See Also: #define #xcommand


C5 Directives

#command        Specify a user-defined command or translation directive
#define         Define a manifest constant or pseudofunction
#error          Generate a compiler error and display a message
#ifdef          Compile a section of code if an identifier is defined
#ifndef         Compile a section of code if an identifier is undefined
#include        Include a file into the current source file
#stdout         Send literal text to the standard output device
#translate      Specify a user-defined command or translation directive
#undef          Remove a #define macro definition 
#xcommand       Specify a user-defined command or translation directive
#xtranslate     Specify a user-defined command or translation directive

C5 Statements

ANNOUNCE        Declare a module identifier
BEGIN SEQUENCE  Define a sequence of statements for a BREAK
DECLARE*        Create and initialize private memory variables and arrays
DO*             Call a procedure
DO CASE         Execute one of several alternative blocks of statements
DO WHILE        Execute a loop while a condition is true (.T.)
EXIT PROCEDURE  Declare an exit procedure
EXTERNAL*       Declare a list of procedure or function names to the linker
FIELD           Declare database field names
FOR             Execute a block of statements a specified number of times
FUNCTION        Declare a user-defined function name and formal parameters
IF              Execute one of several alternative blocks of statements
INIT PROCEDURE  Declare an initialization procedure
LOCAL           Declare and initialize local variables and arrays
MEMVAR          Declare private and public variable names
PARAMETERS      Create private parameter variables
PRIVATE         Create and initialize private memory variables and arrays
PROCEDURE       Declare a procedure name and formal parameters
PUBLIC          Create and initialize public memory variables and arrays
REQUEST         Declare a module request list
RETURN          Terminate a procedure, user-defined function, or program
STATIC          Declare and initialize static variables and arrays

C5_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 Clipper 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

See Also: FUNCTION LOCAL PARAMETERS PRIVATE PROCEDURE PUBLIC



C5_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: Clipper 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

See Also: BEGIN SEQUENCE FUNCTION LOCAL PRIVATE PROCEDURE



C5_REQUEST

REQUEST
 Declare a module request list
------------------------------------------------------------------------------
 Syntax

     REQUEST <idModule list>

 Arguments

     <idModule list> is the list of modules that will be linked into the
     current executable (.EXE) file.

 Description

     REQUEST is a declaration statement that defines a list of module
     identifiers to the linker.  Like all other declaration statements, a
     REQUEST statement must be specified before any executable statements in
     either the program file, or a procedure or user-defined function
     definition.

     During the compilation of Clipper source code, all explicit
     references to procedures and user-defined functions are made to the
     linker.  In some instances, within a source file, there may be no
     references made to procedure or user-defined function names until
     runtime.  REQUEST resolves this situation by forcing the named
     procedures or user-defined functions to be linked even if they are not
     explicitly referenced in the source file.  This is important in several
     instances:

     .  Procedures, user-defined functions, or formats referenced with
        macro expressions or variables

     .  Procedures and user-defined functions used in REPORT and LABEL
        FORMs and not referenced in the source code

     .  User-defined functions used in index keys and not referenced
        in the source code

     .  ACHOICE(), DBEDIT(), or MEMOEDIT() user functions

     .  Initialization procedures declared with the INIT PROCEDURE
        statement

     .  Exit procedures declared with the EXIT PROCEDURE statement

     To group common REQUESTs together, place them in a header file and then
     include (#include) the header file into each program file (.prg) that
     might indirectly use them.

 Examples

     .  This example shows a typical header file consisting of common
        REQUESTs for REPORT FORMs:

        // Request.ch

        REQUEST HARDCR
        REQUEST TONE
        REQUEST MEMOTRAN
        REQUEST STRTRAN

See Also: ACHOICE() ANNOUNCE DBEDIT() EXIT PROCEDURE EXTERNAL*