Superlib Read Me

This is the final released version of SuperLib.

It includes a library for Clipper 5.2d, complete source code,  Norton Guides, examples and an .RMK file.

The author no longer does any Clipper work of any kind, and hopes to stop recieving calls and e-mail from people wanting to purchase  Superlib.

This file may be redistributed to FTPs or other archives as long as this README.TXT file is included. Files included:

README.TXT : This file
LIB52.ZIP : Clipper 5.2 compiled .LIB file
SOURCE.ZIP : All the source code
SAMPLES.ZIP : Source and data files for all of the example programs
NG.ZIP : Norton Guides help file
SUP52.RMK : Rmake file for 5.2. You will almost certainly need to modify it

This product is now free, but still copyrighted by Garry A Prefontaine.

You may not charge for any part of this software.

You may use it without charge as long as you:

1. DOWNLOAD IT ON YOUR OWN DIME

2. DO NOT EXPECT ANY TECHNICAL SUPPORT OF ANY KIND

3. DO NOT EXPECT ANY UPGRADES OF ANY KIND (i.e. to 5.3 or VO)

4. AGREE TO THE FOLLOWING TERMS:

SuperLib is provided on an “AS IS” basis, with no implied warranty regarding merchantability or fitness for any particular purpose. Functional Software Inc. and the author Garry A Prefontaine, make no representations or warranties with respect to the contents hereof, and specifically disclaim any implied warranties. By using this software you agree that Functional Software Inc. and the author Garry A Prefontaine, will not be liable to you or any third party for any use of (or inability to use) this software, or for any damages (direct or indirect) whatsoever, even Functional Software Inc or the author Garry A Prefontaine, are apprised of the possibility of such damages occurring. In no event shall Functional Software Inc or the author Garry A Prefontaine be liable for any loss of profit or any other commercial damage, including but not limited to special,
incidental, consequential or other damages. The entire risk related to the quality and performance of the program is on you.
 

HbRun

HbRun is a console interpreter and program ( command file / script file / .prg / .hrb ) runner for the Harbour Language.

Addendum: a clarification by Przemek:

HBRUN is a simple wrapper to Harbour compiler so the same syntax as in
Cl*pper is supported:

DO <filename>[.prg]

only .prg is accepted as extension and it’s default so you do not
have to set it explicitly.

( In Harbour Users Google group, under “hbmk2 and the Dot Prompt” topic:

It can work as interpreter when invoked without parameters or can execute xBase / Harbour source code in .prg file or compiled Harbour Portable Objects (.hrb) file given as parameter.

Type of file is recognized by extension used with <file> parameter. If not given then .hrb is used.

In other words, HbRun can be use in both interpret  and batch mode.

Regarding parameter given or not, when calling HbRun this ‘mode’ determined by program itself. If a parameter ( usually a .prg or .hrb file name ) given, program run in ‘batch’ mode, runs (executes) given script file and end. If no parameter given, program enter interpreter mode.

Using HbRun as an interpreter, may be very useful, productive, and educative for xBase programmers. Too many xBase programmers was learned everything, including   DBF file system and xBase programming language by famous “dot prompt”. Today many xBase programmers uses HbRun daily basis.

When HbRun begin, open a console screen with two basic area: status bars at top and dot prompt line at bottom.

Status bars :

 hbrunStatLines

Dot prompt is quite simple visually: a dot and a  line in inverse color beginning with a blinking cursor :

 hbRunDotPrompt

You may enter here a command to see the result.

For example “DIR” command will give a list of database (.dbf) files in current directory:

hbRun_Dir

SET COLO TO “GR+/N” command will remember you old days :

hbRun_Dir2

The DIR command can be used with DOS style “filter / skeleton” parameter :

DIR *.PRG
DIR *.*

etc.

Inspecting any table ( .dbf file ) is very simple:

USE CLIENTS
BROWSE ()

 hbrunBrowse

 Expand a little:

SET COLO TO “GB+/N”
USE CLIENTS
BROWSE( 3, 10, 24, 60 )

hbrunBrowse2

If you plan to use this snap frequently, make a .prg file (say brwclien.prg) with this three line and run it with DO command:

DO BRWCLIEN

Sometime LIST command may be better:

LIST CL_ID, CLI_SNAM, CLI_NAME, CLI_TLF

hbrun_list

 You can add FOR clause to the LIST command:

LIST CL_ID, CLI_SNAM, CLI_NAME, CLI_TLF FOR RECN() < 10

or

LIST CL_ID, CLI_SNAM, CLI_NAME, CLI_TLF FOR EMPTY( CLI_TLF )

The structure info of a table frequently requires while daily work to xBase Programmers.

Here three small programs for obtain structure info of a table. Usage is quite simple: open ( USE ) your table and enter DO <prgFileName>; for example:

USE CLIENT
DO LISTSTRU
or
DO DISPSTRU
or
DO SAVESTRU

 Notes :

–      To avoid some possible screen metric conflicts caused by default console (DOS box) settings of OS, may be useful some adjusting before invoke HbRun; such as:

MODE CON LINES=48 COLS=128

–       “?” command may be useful as a built-in calculator :

? 2*2           // 4
? 2**8          // 256
? SQRT( 81 )    // 9

–      HbRun keep a “history” for commands entered (for a limited count of commands of course). You can access (and re-enter when required) by using up and down keys. Moreover this history may be usable after re-invoke HbRun.

–      Though Harbour Language is essential, some legal Harbour commands / functions may be un-recognizable by HbRun.

–      Though some legal statements works in interpret mode, may not works in batch mode (such as Browse() ).

Last Note : No further explanation required for experienced xBase programmers; try, see and learn.

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

Examples :

 
/*
 DispStru.prg 

 Display structure of current table ( .dbf file ) on screen.

*/
MEMVAR ASTRUCT, NTOTLEN
IF EMPTY( ALIAS() )
   SETCOLOR( "R/N" )
   ? "No active table in the current work area !", LTRIM( STR( SELECT() ) )
ELSE 
   @ 3, 0 CLEA TO MAXROW() - 1, MAXCOL()
   aStruct := DBSTRUCT()
   nTotLen := 1
   AEVAL( aStruct, { | a1Field | nTotLen += a1Field[ 3 ] } )
   AEVAL( aStruct, { | a1Field, n1FieldNo | ;
   aStruct[ n1FieldNo ] := STR( n1FieldNo, 3 ) + " " +;
                           PADR( a1Field[ 1 ], 12 ) +;
                           PADC( a1Field[ 2 ], 4 ) +;
                           PADL( a1Field[ 3 ], 5 ) +;
                           PADL( a1Field[ 4 ], 3 ) } )
   ? "Structure of database :", DBINFO( 10 )
   ? "Number of data records :", LTRIM( STR( LASTREC() ) )
   ? "Date of last update :", LUPDATE()
   ? "Fld Name Type Width Dec"
   ? "--- ---------- ---- ----- ---"
   @ 21,0 SAY "** Total ** " + PADL( nTotLen, 6 )
   ACHOICE( 8, 0, 20, 30, aStruct ) 
ENDIF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
 ListStru.prg 

 List structure of current table ( .dbf file ) on screen.

*/
MEMVAR ASTRUCT, NTOTLEN
IF EMPTY( ALIAS() )
   SETCOLOR( "R/N" )
   ? "No active table in the current work area !", LTRIM( STR( SELECT() ) )
ELSE 
   @ 3, 0 CLEA TO MAXROW() - 1, MAXCOL()
   aStruct := DBSTRUCT()
   nTotLen := 1
   AEVAL( aStruct, { | a1Field | nTotLen += a1Field[ 3 ] } ) 
   AEVAL( aStruct, { | a1Field, n1FieldNo | ;
   aStruct[ n1FieldNo ] := STR( n1FieldNo, 3 ) + " " +;
                           PADR( a1Field[ 1 ], 12 ) +;
                           PADC( a1Field[ 2 ], 4 ) +;
                           PADL( a1Field[ 3 ], 5 ) +;
                           PADL( a1Field[ 4 ], 3 ) } )
   ? "Structure of database :", DBINFO( 10 )
   ? "Number of data records :", LTRIM( STR( LASTREC() ) )
   ? "Date of last update :", LUPDATE()
   ? "Fld Name Type Width Dec"
   ? "--- ---------- ---- ----- ---"
   AEVAL( aStruct, { | c1Field | QOUT( c1Field ) } ) 
   ? "** Total ** ", PADL( nTotLen, 5 )
ENDIF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
SaveStru.prg

 Save structure of current table ( .dbf file ) to a file.

 Notes :

 - This program uses ListStru.prg
 - Name of target file constructed at line 18; 
   if required you may use alternate ways or
   simply using a constant.
*/
MEMVAR AlteFName
IF EMPTY( ALIAS() )
   SETCOLOR( "R/N" )
   ? "No active table in the current work area !", LTRIM( STR( SELECT() ) )
ELSE 
   AlteFName := LEFT( ALIAS(), 4 ) + "STRU" 
   SET ALTE TO &AlteFName
   SET ALTE ON
   DO LISTSTRU
   SET ALTE OFF
   SET ALTE TO
ENDIF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Procedure and Function Terms

Activation :

The commencement of execution of a procedure. Each call to a procedure is referred to as an activation of that procedure. If the procedure in turn calls another procedure (or calls itself recursively), a new activation is said to have occurred. The earlier activation is then referred to as a pending activation.

Pending activations are often referred to as higher-level activations or higher-level procedures. When one procedure calls another (i.e., creates a new activation), the latter is often referred to as a lower-level activation or a lower-level procedure.

See Also : Activation Record, Activation Stack, Function, Procedure

Activation Record :

An internal data structure that contains information pertaining to an activation.

See Also : Activation, Activation Stack

Activation Stack :

An internal data structure that contains an activation record for the current activation and all pending activations.

See Also : Activation, Activation Record, Stack

Calling Program :

The procedure, or user-defined function that transferred control to the currently executing procedure or function. When the current procedure or user-defined function terminates with a RETURN statement, this is where control will return.

Function :

An executable block of code with an assigned name. Alternately, the collection of source code statements that define a function. Certain functions are supplied as part of Clipper; others are defined by the programmer using the FUNCTION or PROCEDURE declaration statements. The latter are referred to as user-defined functions.

The terms procedure and function are generally interchangeable. By convention, a function returns a value, while a procedure does not.

See Also: Activation, Parameter, Procedure

Identifier :

A name that identifies a function, procedure, variable, constant or other named entity in a source program. In Clipper language, identifiers must begin with an alphabetic character and may contain alphabetic characters, numeric characters, and the underscore character.

Information Hiding :

A fundamental programming principle that states that functions and programs should conceal their inner workings from other functions and programs. Stated simply: a function should possess only the knowledge necessary for it to accomplish its task. When one function calls another, the calling function should possess only the knowledge explicitly required to call the other function.

See Also: Encapsulation, Lexical Scoping, Modularity, Side Effect

Primitive :

A simple, low-level function used by other high-level functions or programs to perform a more complex task.

Procedure :

An executable block of code with an assigned name. Alternately, the collection of source code statements that define a procedure. In Clipper language, this can be a source file (.prg), a format file (.fmt), an explicitly declared procedure (PROCEDURE), or an explicitly declared function (FUNCTION).

The terms procedure and function are generally interchangeable. By convention, a function returns a value, while a procedure does not.

See Also: Activation, Function, Parameter

Return Value :

The value or reference returned by a function or method from a function call or message send.

Source Code :

The textual representation of a program or procedure.

See Also: Object File, Program File

User-defined Function :

See : Function

Word :

A series of characters in a match pattern or result pattern. Source text matches a word in a match pattern if the text is identical to the word or is an acceptable abbreviation of it. A word that appears in a result pattern is copied unmodified into the result text.

Conditional compilation

What are conditional compilation directives ?

They are : #ifdef#ifndef#else and #endif.

#ifdef

Compile a section of code if an identifier is defined.

Syntax :

  #ifdef <identifier>
    <statements>...
  [#else]
    <statements>...
  #endif

Arguments :

<identifier> is the name of a definition whose existence is being verified.

Description :

#ifdef…#endif lets you perform a conditional compilation. It does this by identifying a section of source code to be compiled if the specified <identifier> is defined. The <identifier> can be defined using either the #define directive or the /D compiler option which lets you define an identifier or manifest constant from the compiler command line.

The #else directive specifies the code to compile if <identifier> is undefined. The #endif terminates the conditional compilation block.

Conditional compilation is particularly useful when maintaining many different versions of the same program. For example, the demo code and full system code could be included in the same program file and controlled by a single #define statement.

Examples :

. This code fragment is a general skeleton for conditional compilation with #ifdef:

   #define DEMO
    .
    . <statements>
    .
  #ifdef DEMO
   <demo specific statements>
  #endif

. This example controls conditional compilation with an identifier defined on the compiler command line with the /D option.

In the program (.prg) file:

 #ifdef DEBUG
    Assert(<some condition>)
 #endif

. This example defines a manifest constant to one value if it does not exist and redefines it to another if it exists:

 #ifdef M_MARGIN
    #undef M_MARGIN
    #define M_MARGIN 15
 #else
    #define M_MARGIN 10
 #endif

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

#ifndef

Compile a section of code if an identifier is undefined

Syntax :

  #ifndef <identifier>
    <statements>...
  [#else]
    <statements>...
  #endif

Arguments :

<identifier> is the name of a definition whose absence is being verified.

Description :

#ifndef…#endif lets you perform conditional compilation by identifying a section of source code to compile if the specified <identifier> is undefined.

The #else directive specifies the code to compile if <identifier> is defined. The #endif terminates the conditional compilation block.

Examples :

. This code fragment is a general skeleton for conditional compilation with #ifndef:

 #define DEBUG
   .
   . <statements>
   .
 #ifndef DEBUG
   <optimized version of code>
 #else
   <debugging version of code>
 #endif

. This example compiles a section of code if a specific identifier is undefined.

In the program (.prg) file:

  #ifndef NODEBUG
     Assert(<some condition>)
  #endif

. This example overrides a default definition in the program (.prg) file using a manifest constant defined on the compiler command line with the /D option

In the program (.prg) file:

 #ifndef M_MARGIN
   #define M_MARGIN 15
 #endif