home *** CD-ROM | disk | FTP | other *** search
Text File | 1985-11-28 | 70.6 KB | 1,683 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
- THE C2DBASE FUNCTIONS
- version 1.0
- 11/28/85
-
- by
-
-
- COMPUSCAN SOFTWARE
-
- INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . 1
- OVERVIEW . . . . . . . . . . . . . . . . . . . . . . . . . . 2
- FILES IN PACKAGE . . . . . . . . . . . . . . . . . . . . 2
- MODIFICATIONS & REVISIONS . . . . . . . . . . . . . . . . 2
- THE DBASE FILE STRUCTURE . . . . . . . . . . . . . . . . 2
- THE DBINFO STRUCTURE . . . . . . . . . . . . . . . . . . 3
- IMMEDIATE ERROR EXIT POINTS . . . . . . . . . . . . . . . 4
- CDBUTIL - THE DBASE UTILITY PROGRAM . . . . . . . . . . . 4
- KNOWN BUGS . . . . . . . . . . . . . . . . . . . . . . . 5
- REGISTRATION . . . . . . . . . . . . . . . . . . . . . . . . 5
- WHY REGISTER . . . . . . . . . . . . . . . . . . . . . . 5
- HOW TO REGISTER . . . . . . . . . . . . . . . . . . . . . 6
- FUNCTION DESCRIPTIONS . . . . . . . . . . . . . . . . . . . 6
- INTRO . . . . . . . . . . . . . . . . . . . . . . . . . . 6
- DBHEADER . . . . . . . . . . . . . . . . . . . . . . . . 7
- DBSTAT . . . . . . . . . . . . . . . . . . . . . . . . . 7
- RECREAD . . . . . . . . . . . . . . . . . . . . . . . . 8
- RECLIST . . . . . . . . . . . . . . . . . . . . . . . . 8
- RECWRITE . . . . . . . . . . . . . . . . . . . . . . . . 9
- NDXREAD . . . . . . . . . . . . . . . . . . . . . . . . 10
- NDXSTAT . . . . . . . . . . . . . . . . . . . . . . . . 10
- MEMOREAD . . . . . . . . . . . . . . . . . . . . . . . . 11
- TEXTFIND . . . . . . . . . . . . . . . . . . . . . . . . 11
- MEMOADD . . . . . . . . . . . . . . . . . . . . . . . . 12
- ONOFFDBT . . . . . . . . . . . . . . . . . . . . . . . . 13
- DBTPACK . . . . . . . . . . . . . . . . . . . . . . . . . 14
- PASS . . . . . . . . . . . . . . . . . . . . . . . . . . 15
- DBCLOSE . . . . . . . . . . . . . . . . . . . . . . . . 15
- CDBUTIL . . . . . . . . . . . . . . . . . . . . . . . . . . 16
- CDBUTIL MODES . . . . . . . . . . . . . . . . . . . . . . 16
- GENERAL . . . . . . . . . . . . . . . . . . . . . . . 16
- FUNCTION CALLING PROCEDURE . . . . . . . . . . . . . . 16
- DISPLAY FILE INFORMATION . . . . . . . . . . . . . . . 17
- UNFILTERED RECORD COUNT . . . . . . . . . . . . . . . 17
- UNFILTERED COUNT TO MEMORY VARIABLE . . . . . . . . . 17
- RECORD LISTING . . . . . . . . . . . . . . . . . . . . 18
- MEMO FIELD DISPLAY . . . . . . . . . . . . . . . . . . 19
- KEY PHRASE SEARCH THROUGH MEMO FIELD . . . . . . . . . 20
- PROGRAMM-CONTROLLED MEMO WRITING . . . . . . . . . . . 21
- SEPARATE .DBT FROM .DBF . . . . . . . . . . . . . . . 21
- PACK MEMO FILE . . . . . . . . . . . . . . . . . . . . 22
- SOURCE . . . . . . . . . . . . . . . . . . . . . . . . . 22
- MAIN . . . . . . . . . . . . . . . . . . . . . . . . . 22
- FUNCTION 1 . . . . . . . . . . . . . . . . . . . . . . 24
- FUNCTION 2 . . . . . . . . . . . . . . . . . . . . . . 25
- FUNCTION 3 . . . . . . . . . . . . . . . . . . . . . . 25
- FUNCTION 4 . . . . . . . . . . . . . . . . . . . . . . 25
- FUNCTION 5 . . . . . . . . . . . . . . . . . . . . . . 26
- FUNCTION 6 . . . . . . . . . . . . . . . . . . . . . . 27
- FUNCTION 7 . . . . . . . . . . . . . . . . . . . . . . 29
- FUNCTION 8 . . . . . . . . . . . . . . . . . . . . . . 29
- FUNCTION 9 . . . . . . . . . . . . . . . . . . . . . . 30
- CDBUTIL.PRC FOR DBASE III . . . . . . . . . . . . . . . . 30
- EXPLANATION . . . . . . . . . . . . . . . . . . . . . 30
- PROGRAM . . . . . . . . . . . . . . . . . . . . . . . 31
- INTRODUCTION
-
- ASHTON-TATE's DBASE III has brought some of the power of
- large-scale dbms to the PC. The C2DBASE functions add a little more
- power and flexibility to this modern micro-dbms. C2dDBASE is meant for
- those who are familiar with the C language, and can write auxillary
- programs for specific purposes. With the C2DBASE functions, a C
- programmer can:
-
- -Use the files created by DBASE III outside of the DBASE
- environment.
-
- -Extract file statistics without DBASE (i.e. record cound,
- field names, index fields, etc.).
-
- -Write C programs that bring information into the DBASE
- environment (i.e. mathematical functions, peripheral
- status,etc.).
-
- -Display memo fields as you meant them to be displayed, without
- being limited by DBASE's limited formatting.
-
- -Perform very fast keyphrase searching through memo fields in a
- database. This capability brings to life the power of the memo
- field.
-
- -Separate a .DBT file from its associated .DBF file. This is
- very useful where the .DBT file has been corrupted. DBASE will
- not use a .DBF when it cannot find or read the .DBT.
-
- -Squeeze out the wasted disk space inside a .DBT file. For those
- who edit memo fields frequently, the amount of wasted space
- inside the .DBT file would surprise you.
-
- These are a few of the more obvious advantages to the C2DBASE
- functions. Once you understand what these functions are, your own
- creatively will provide you will many more advanatages and uses.
-
- C2DBASE may be used inside or outside of DBASE. When used
- inside, the DBASE command RUN is used to evoke the C program containing
- the C2DBASE functions required to perform the task.
- Used outside of DBASE, these functions can productively access
- all of the files created and used by DBASE. With this version, the
- information that can be extracted from an .NDX file is limited, but all
- other file type are supported completely.
-
- The C2DBASE functions are distributed under the Shareware
- concept. The author assumes no responsibility for the damage a reckless
- programmer can do to his client's database. Indeed, such a programmer
- does not need these function to perform such damage.
-
-
- OVERVIEW
-
- FILES IN PACKAGE
-
- The files distributed with this package are listed below. If you
- are missing any of these files, the package you received is incomplete.
- Upon registration, you will be sent a complete up-to-date program disk,
- and printed documentation.
-
- DBASE.LIB - This is the compiled library of C2DBASE functions.
- It has been compiled using Lattice version 2.14 with the S-memory model.
- Obtaining the source code for these functions will allow you to
- re-compile using another memory model.
-
- DBASE.H - This C header file must appear in any C program which
- uses the C2DBASE functions. (i.e #include dbase.h). It contains the
- definitions these functions require, including the important DBINFO
- structure definition (see below for more information about this
- structure).
-
- CDBUTIL.C - The source code for the demonstration/utility
- program.
-
- CDBUTIL.EXE - The executible program using the C2DBASE
- functions.
-
- CDBUTIL.PRC - An illustrative DBASE procedure file showing how
- the C2DBASE functions may be used inside of DBASE III.
-
- C2DBASE.DOC - This documentation file
-
- In addition to the above files, users of the registered package
- will find the following files on the program diskette:
-
- C2DBSORC.DOC - Source code for all C2DBASE functions
-
- USER.HLP - Miscellaneous information, helpful tips and support
- telephone numbers.
-
-
- MODIFICATIONS & REVISIONS
-
- NONE
-
-
- THE DBASE FILE STRUCTURE
-
- Although you do not need to know about the file structure of
- DBASE, a few words may be in order. DBASE reserves several file
- extensions for its specific use. The ones that are relevant to this
- package are:
-
- .DBF - a DBASE database file containing records of fixed length,
- and predefined fields. A file header contains information about the
- database.
-
- .DBT - a file containing the text held in memo fields for a
- given .DBF file. The .DBF and .DBT files will always have the same
- filename. (i.e. DATA.DBF & DATA.DBT)
-
- .NDX - an index file sorted on a key relevant to the .DBF file
- to which it is associated. Each record in this file points to a record
- in the .DBF file. The .DBF file will appear to be in the order of the
- .NDX file.
-
- .MEM - These files contain names and values of DBASE memory
- variables. They may contain information for up to 256 memory variable.
- The C2DBASE function "pass" writes a .MEM file to pass information to
- DBASE. However, this version writes .MEM files holding a single
- character variable. Later versions will have increased flexibility in
- this area.
-
- .PRG - these are program command files DBASE uses for
- instruction.
-
-
- THE DBINFO STRUCTURE
-
- In order to efficiently use the C2DBASE functions, it is
- necessary to become familiar with the structure used to hold all DBASE
- information. This structure is more completely defined in the dbase.h
- header file. (This header must be included in any program using the
- C2DBASE functions.) Most of the ingredients of this structure are
- automatically handled within the functions themselves, and should not be
- touched by the programmer. The following is a list of those elements of
- the structure that are relevant to the C programmer.
-
- (Note:
- static struct dbinfo dbase;
- /*DBASE information structure-must be static*/ )
-
- dbase.error - This variable will usually be zero if a called
- C2DBASE function was successfully executed. If an error occurs, a
- non-zero code will help to clarify what the error was. Each function has
- its own set of error codes. Refer to the documentation of each function
- for the list of error codes relevant to a particular function. The
- dbase.error variable should be checked after each function call if there
- is a posibility of an error. In all function documentation, this
- variable is denoted as dbase->error.
-
- dbase.ndxnum - This integer is equal to the number of index
- files in use with the .DBF. C2DBASE assigns each index file a number
- from one to ten. The first index specified receives a '1' assignment,
- the second a '2', and so on. To refer to an index file inside of a
- C2DBASE function it is only necessary to refer to its number. Of course
- other ways to refer to index files are supported, but this particular
- method proved convenient for me.
-
- dbase.ndxfile[n] - This is an array of structures containing
- information pertinent to index (.NDX) files that may have been
- specified. Up to 10 index files may be specied for each .DBF file.
- However, this version of the C2DBASE functions does not completely
- support all aspects of the index files. The ndxfile structure includes
- the following element -
- dbase.ndxfile[n].name - 35 characters
- dbase.ndxfile[n].fldnum - number of fields index in this .NDX
- dbase.ndxfile[n].fields[10]-up to 10 field names, 11 bytes each
-
- dbase.info - This is an array of miscellaneous information about
- the .DBF file. Some of the relevant element of this structure are -
- dbase.info.year - character\
- dbase.info.month- character >last date of update
- dbase.info.day - character/
- dbase.info.quan -number of record in .DBF (long integer)
- dbase.info.reclgth- bytes per record
-
- dbase.fieldnum - An integer value equal to the number of fields
- per record in the .DBF. The maximum number of fields is set by MAXFIELD
- in the header file. (Presently 30)
-
- dbase.field[n] - This is an array of structures containing .DBF
- field information. The maximum legal value of n is the number of fields
- per record for the .DBF file - dbase.fieldnum. Each structure contains
- the following elements -
- dbase.field[n].name - 11 characters
- dbase.field[n].type - field type (C, D, N, or M)
- dbase.field[n].length - field length (up to 255 bytes)
- dbase.field[n].decimal- decimanl places if numeric
-
-
- IMMEDIATE ERROR EXIT POINTS
-
- N O T E:
- The C2DBASE functions generally pass control back to the callin
- function when they have completed, even in the case of an error. the
- function reclist, onoffdbt, and pass have have error detection code that
- result in an immediate program exit if particular types of errors occur.
- Refer to the documentation for these functions for further information.
-
-
- CDBUTIL - THE DBASE UTILITY PROGRAM
-
- This package includes the C program CDBUTIL, which will
- hopefully serve as example of how to program with the C2DBASE functions.
- It uses many of the functions, and provides enough useful functionality
- to whet the appetite of the non-programmer familiar with DBASE. It has
- a somewhat cumbersome command line invocation structure, but the
- documentation should be clear enough for most people familiar with
- command line arguments. The program source is included and should be
- examined by those wanting to use the functions.
- Each mode of this utility program performs a specific task and
- requires a specific argument list. This information is provided in a
- help screen which is called up when CDBUTIL is executed without any
- arguments. Examine this screen whenever you need to be refreshed on the
- modes of the CDBUTIL program.
-
-
- KNOWN BUGS
-
- This version of C2DBASE (another is on the way) has a few
- limitations, which may be considered bugs by some. If you are aware of
- these limitations, you should have no trouble using these functions
- reliably.
-
- MEMO FIELDS:
- The first limitation has to do with memo fields. Unless you
- increase the value of MEMOMAX in the dbase.h header file, and re-compile
- the code, the maximum length of any memo field should be less than 2048
- bytes. Beyond this, trucation occurs, or searching is not performed
- depending on the function.
- More importantly perhap is the limitation of only one memo field
- per record. If there are more than one memo field in a record, the
- C2DBASE functions only process the first one. This oversight on my part
- will be corrected in a later version.
-
- INDEX FILE USAGE:
- At present, .DBF files cannot be presented in indexed order.
- For example, the reclist function cannot list records in indexed order.
- In fact, the only thing you can do with index files, at this point, is
- display information contained in their header (i.e. indexed fields,
- index record length, etc.).
-
- MULTI-TASKING ENVIRONMENTS:
- I have had a few difficulties running these functions in some
- MS-DOS multi-tasking environements. When I have enough time to sit down
- and understand the problem, or if the problem causes enough of an
- outcry, I will correct. I may be wrong, but not many of you are running
- under such environments.
-
-
- REGISTRATION
-
- WHY REGISTER
-
- My expectation is that this package will appeal to a unique few.
- Those who know and delight in both the C language and DBASE III, are
- rare enough. Of thoses people, this package will not interest all of
- them. If you find yourself even marginally interested in the
- capabilities that this package provides, consider yourself unique. One
- of the responsibilities of this uniqueness is that you register this
- package.
- Registration gives you several tangible and intangible benefits.
- Some of the intangibles include giving support to others like yourself,
- and encouraging the Freeware concept of software development. By now
- you are familiar with what that is, and why it is the only alternative
- to high-priced software.
- Some of the more tangible benefits of registration are:
-
- -All the source code for the C2DBASE functions are sent to
- registered users. Aside from giving you the power to modify
- these functions, there is a lot to learn about DBASE III from
- the examination of this source code.
-
- -The unregistered documentation file is incomplete and not
- paginated. Although the amount left out is not a lot, it could
- prove helpful if you are attempting to modify the functions, or
- recompile for any reason. The pages refered to in the table of
- contents are not coordinated with the text of the file. This was
- done for convenience. Registered users will receive the complete
- documentation in printed form.
-
- -During the evolution of the C2DBASE functions, registered users
- will continue to receive free updates of newer versions. The
- following improvements are planned for the not-too-distant
- future:
- -better support for .NDX files and indexing functions
- -multiple variables returned with the 'pass' function
- -support for multiple memo fields
- -database recovery provisions
- -improved CDBUTIL modes
-
- -Only registered users may contact me for support of any kind.
- I will be very happy to hear from those who are interested in
- this package. I know you are interested if you register. If you
- are having any trouble incorporating these functions in your
- programs, or have any suggestions on improving them, please
- write, or call the number listed in your registration package.
- ( I may even be convinced to provide customized functions for
- registered users.)
-
-
- HOW TO REGISTER
-
- To register this package, send your name and mailing address,
- along with $15 to:
-
- COMPSCAN
- 60 East Water Street
- North Andover, Mass 01845
-
- You will receive the newest version of the C2DBASE package,
- printed documentation, including source code for all the library
- functions, additional tips helpful if you wish to modify the functions
- in any way,and hotline telephone numbers for support.
- If you intend to use this package, register it at your earliest
- convenience so that support is available to you, if and when you should
- need it.
-
-
- FUNCTION DESCRIPTIONS
-
- INTRO
-
- What follows is a function description for each of the functions
- found in DBASE.LIB. As you read them, let your creative juices flow,
- and see how you may use each of them to solve some problem or other, or
- otherwise make things more convenient for you.
-
-
- DBHEADER
-
- SYNOPSIS:
- dbheader(dbfile,dbase)
-
- char *dbfile; /*file to be examined*/
- struct dbinfo *dbase; /*structure to be filled*/
- ----------------------------------------------------------------
- This routine reads a dbase file header and determines the
- database file information, which includes memo flag,date,number of
- records,record length, file name, field names and type.
- -filename (dbfile) may include directory paths.
- -.DBF extension MUST be included in filename.
- -Maximum record length is 512 bytes (dbase.h).
- -Maximum fields per record is 30 (dbase.h).
- The routine initializes a structure (dbase) containing the dbase
- file information (see dbase.h - structure dbinfo) and returns the level
- 1 file number for further use. This routine should be the first routine
- used to interface with a .DBF file, and it should be used only once
- since it resets a number of variables in the structure. The dbinfo
- structure error variable should be checked for a non-zero value
- indicating an error was detected. The error code meanings are:
- 1 = no .DBF extension in filename
- 2 = cannot open dbfile
- 3=not recognized as a DBASE file, despite the .DBF
- extension
- 4 = cannot open associated .DBT file
- 5 = not assigned yet
- NOTE: .DBT file must be in same directory as the .DBF file
- */
-
-
- DBSTAT
-
- SYNOPSIS:
- dbstat(info)
- struct dbinfo *info;
- ----------------------------------------------------------------
- This routine displays ( on stdout) the status information of the
- .DBF file whose characteristics are passed in the struct info. The
- information includes any index files that have been previously linked to
- the .DBF file with the function NDXREAD.
-
-
-
- RECREAD
-
- SYNOPSIS:
- char *recread(dbase,recnum)
- struct dbinfo *dbase; /*file information structure*/
- long recnum; /*record number to return*/
- ----------------------------------------------------------------
- This routine reads the records of the file whose information
- parameters are in the dbase structure. A pointer to the contents of
- record number "recnum" (which must be a LONG integer) is returned. The
- record contents are contained in a character buffer which must be parsed
- for the record fields by the calling routine. If recnum specifies a
- record that is not in the database, the returned pointer will be NULL,
- and dbase->error will be non-zero. The meaning of the error codes are
- as follows;
- 1 = record not in database
- 2 = code not yet assigned
- Please note that this function returns a character
- pointer and must be declared as such in the calling program.
-
-
- RECLIST
-
- SYNOPSIS:
- reclist(dbase,start,end)
- struct dbinfo *dbase;
- long start,end; /*starting & ending records to list
- ---------------------------------------------------------------
- This routine prints (on stdout) the unindexed records of a dbase
- .DBF file described in the structure info. It takes three parameters,
- the first being the ubiquitous DBINFO structure pointer, the second is
- the record number (LONG) where the listing is to start, and the third is
- the record number (also LONG) where the listing is to end. Ending
- numbers larger than the number of records in the database are
- interpreted as the largest record number. A starting record number of
- zero will be interpreted as a 1.
- This function does a complete program exit (with ERRORLEVEL set
- to 1) if it is requested to list a record number that is not in the
- database.
-
-
- RECWRITE
-
- SYNOPSIS:
- recwrite(dbase,record,string)
- struct dbinfo *dbase;
- long record; /*record number to write*/
- char *string; /*record string to write*/
- ----------------------------------------------------------------
- This function writes a record to the .DBF file specified by the
- DBASE structure pointer. If the record specified by the passed parameter
- 'record' (which is a LONG integer) is less than the total number of
- records in the .DBF file, then record number 'record' is replaced by the
- character string 'string'. If 'record' is larger than the number of
- records in the database, then a new record is appended, and the record
- number is incremented. Please note that this version does not support
- index files, so this function should only be used on databases that are
- not indexed, or where the indexed fields will not be changed and the
- number of records will remain the same. It is the responsibility of the
- programmer to make cetrtain that this is so. The programmer is also
- responsible to make certain that 'record' is correct for the database
- being used. Please be careful. You could screw up the .DBF file with
- this one if these cautions are not observed.
- Upon successful completion, the function returns a zero if the
- record was replaced, and a one if the record was appended. In both
- cases, the dbase->error variable will be zero. If an error has been
- detected, a -1 will be returned and the error variable will be non-zero,
- with the following error codes;
- 1 = Cannot reopen .DBF file.
- 2 =Premature end-of-file or file positioning error
- 3 =.DBF write error
-
-
- NDXREAD
-
- SYNOPSIS:
- ndxread(dbase,ndxfile)
- struct dbinfo *dbase;
- char *ndxfile; /*.NDX filename*/
- ----------------------------------------------------------------
- This routine opens a .NDX file, checks it for various errors,
- and fills the "dbase" structure with the pertinent information
- concerning the named .NDX file - "ndxfile",which must contain the full
- path (default directory assumed if path is missing) of the file to be
- read (including extension). The maximum number of indexed fields
- allowed is presently 10 (MAXFIELD/3). The structure for the .NDX file
- information will be found in the dbase.h header file. If successful,
- the variable dbase.error will be equal to zero, the "dbase" structure
- will be updated with the index file information and the order number
- (from 1 to 10) of the index file will be returned. (NOTE: the subscript
- number of the .NDX file in the 'dbase' structure will be the order
- number minus 1.) If an error condition is detected the "dbase" structure
- will not be updated and dbase.error will be non-zero. The meaning of
- the various codes are;
- 1 = named file does not have .NDX extension
- 2 = cannot open named .NDX file
- 3 = .NDX file is indexed on fields that are not in the .DBF file
- 4 =
- NOTE: The 'dbase' structure can contain up to 10 index files.
-
- DBASE NOTE: DBASE allows indexing on complex keys -i.e. INDEX ON
- LEN(TRIM(SUBSTR(character field))). This C2DBASE function
- can only handle one DBASE modifier on the field - i.e. LEN(field) not
- LEN(TRIM(field)). Fields with multiple function modifiers will be seen
- as a mismatching field, and cause an error 3.
-
-
- NDXSTAT
-
- SYNOPSIS:
- ndxstat(dbase,ndxorder)
- struct dbinfo *dbase;
- int ndxorder;
- ----------------------------------------------------------------
- This function displays (on stdout) information about the index
- file associated with the index order number "ndxorder". This function
- is called by "DBSTAT". If the function executes succesfully, the return
- value will be zero, dbase->error will be zero, and the information will
- be displayed. If it is not succesful, no information will be displayed,
- the return value will be non-zero, and an error code will be placed in
- dbase->error. The error codes are:
- 1=ndxorder exceeds the number of index files with the .DBF
- 2=error code not yet assigned
-
-
- MEMOREAD
-
- SYNOPSIS:
- char *memoread(dbase,rec)
- struct dbinfo *dbase;
- long rec; /*record number to read*/
- ----------------------------------------------------------------
- This routine returns a pointer to the .DBT memo text of the
- record specified in the passed parameter "rec" (which must be a LONG).
- The function must be declared as a character pointer in the calling
- function. The record is assumed to have only one memo field. The
- "dbase" parameter is the dbinfo structure of the .DBF file, which must
- have been previously filled using the "dbheader" function. The largest
- memo field which can be read is 2048 bytes, which should be good enough
- for most applications. If a larger field is needed change the MEMOMAX
- variable in "dbase.h". The routine returns a char pointer to the memo
- field string, unless an error is detected. An error detection returns a
- NULL pointer and sets "dbase->error" to one of several error codes.
- These are;
- 1 = .DBF file does not have associated .DBT file
- 2 = record has no memo field (no .DBT)
- 3 = record has an empty memo field pointer
- 4 = error reading .DBT file
- 5 = memo text too long (valid pointer returned anyway)
- 6 = not assigned yet
-
- NOTE: This function can only handle .DBT files which contain no
- more than 65535 memos.
-
- NOTE: This function also contains another function called
- memptr, which returns the unsigned value of the memo field pointer.
-
-
- TEXTFIND
-
- SYNOPSIS:
- textfind(dbase, record, string)
- struct dbinfo *dbase;
- long record; /*record number to search*/
- char *string; /*string to search for*/
- ----------------------------------------------------------------
- This function looks at the record content and memo text (if
- applicable) for the specified record, given as a LONG integer, and
- searches for 'string'. If found, the function returns a one (1). If
- the search is unsucessful, a zero (0) is returned. Capitalization is
- ignored ("abc" = "ABC"). If the function detects an error, a -1 is
- returned, and dbase->error will be non-zero, with the following error
- codes presently specified;
- 2 = search string is NULL
- 3 = error reading .DBT file
-
- As is presently the case in all the C2DBASE functions that deal
- with memo fields, only one such field per record is assumed. If more
- than one exist, only the first memo field will be processed.
-
-
- MEMOADD
-
- SYNOPSIS:
- memoadd(dbase,rec,text)
- struct dbinfo *dbase;
- long rec; /*record number*/
- char *text; /*pointer to memo text*/
- ---------------------------------------------------------------
- This function replaces the memo field of the record "rec", which
- must be a LONG integer, with an ASCII text file, specified in "text".
- The original memo field pointer is returned by this function (as an
- unsigned integer) upon successful completion. If an error is detected,
- a -1 is returned and the error variable - dbase->error- will be set to
- one of the following error codes:
- 1=record does not have a memo field
- 2=cannot open specified text file
- 3=cannot re-open .DBT file
- 4=code not yet assigned
-
- As is presently the case in all the C2DBASE functions that deal
- with memo fields, only one such field per record is assumed. If more
- than one exist, only the first memo field will be processed.
-
- NOTE: The maximum file length that can be read into the .DBT
- file is 2048 bytes for each record. Any text beyond this length will be
- truncated and a warning message will be displayed on stdout. This
- should be sufficient for most applications. If more than this is
- required, increase MEMOMAX in the dbase.h header file.
-
- NOTE: This function may be used to input memo field data under
- program control (something DBASE presently has no provisions for). Using
- the run command, your favorite editor can be evoked to create the text
- file, then this function is used to bring that text file into the .DBT
- file and set the memo pointer of the record. (see CDBUTIL)
-
- NOTE: a -1 is the same as 65535, so a check should be made on
- the error variable to see if it is non-zero (unless, of course, you are
- sure their isn't 65535 memos in the .DBT).
-
-
- ONOFFDBT
-
- SYNOPSIS:
- onoffdbt(dbase,mode)
- struct dbinfo *dbase;
- int mode; /* 0 removes .DBT, 1 attaches .DBT*/
- ----------------------------------------------------------------
- This function is useful if a .DBT file becomes corrupted or
- otherwise unuseable. DBASEIII will not allow a .DBF file that has an
- associated .DBT file to be used if the .DBT file is not available or
- otherwise unreadable. There may be occaisions where the .DBF file may
- have to be used without the .DBT file as may be the case when the .DBT
- file has become corrupted or damaged. This function will turn the
- DBASE.DBT search function on and off. If the .DBF file is to be used
- without its associated .DBT, the mode parameter should be zero. This
- can be reversed ( if the .DBT latter becomes available, or something),
- by running this function with a mode of one.
- .DBF files that originally had no memo fields, cannot be
- associated with a .DBT file, and running this function in mode one, will
- leave these files unaffected.
- In mode one, this function verifies the existence of the .DBT
- file in the same directory as the .DBF file. If it is not found, and
- error results and the .DBF is not changed.
- A zero is returned upon successful completion, otherwise a -1 is
- return with one of the following error codes in dbase->error;
- 1 = could not find .DBT file (mode one)
- 2 = database has no .DBT file (mode one)
- 3 = invalid mode number passed
-
- NOTE: A write error on the .DBF file will cause an immediate
- exit from the program with an dos ERRORLEVEL of 4.
-
-
- DBTPACK
-
- SYNOPSIS:
- dbtpack(dbase)
- struct dbinfo *dbase;
- ---------------------------------------------------------------
- DBASEIII deal with memo files (.DBT) fairly inefficiently. Each
- record in the .DBF file, if it has a memo field, points to a particular
- offset into the .DBT file. When you change, delete, or otherwise modify
- a memo field, the old one is still left intact, but a new one (your
- modified memo) is appended to the bottom of the file, and the record
- pointer updated. If you are in the habit of making a lot of changes to
- your memo fields (which becomes a more reasonable thing to do since you
- now have these functions), the .DBT file may contain a lot of wasted
- disk space. This function writes a new .DBT file, copying only the
- relevant text to it. The old .DBT file is left intact with a .BAK
- extension. The only way you can accomplish with DBASE III is to copy
- your database over entirely, which consumes more disk space since both
- the .DBF and the .DBT gets duplicated. Try this function on a few of
- your .DBT files and see the difference in disk size.
-
- The only required parameter to this function is a pointer to the
- dbinfo structure. If successful it returns a zero, otherwise a -1 is
- returned, and 'dbase->error' will be one of the following error codes;
- 1 = database has no .DBT file
- 2 = Cannot open original .DBT file
- 3 = Cannot create new .DBT file
- 4 = Error writing to new .DBT file
- 5 = Error updating .DBF file
- 6 = TBDL
-
- As is presently the case in all the C2DBASE functions that deal
- with memo fields, only one such field per record is assumed. If more
- than one exist, only the first memo field will be processed.
-
- NOTE: Memo text fields longer than MEMOMAX (presently 2048)
- bytes, with be truncated to that length. MEMOMAX, the #define in the
- header file may be increased, if this poses a problem.
-
- NOTE: Make sure there is enough disk space before performing
- this function. The most free space that will be needed will be equal to
- the size of the original .DBT file.
-
- NOTE: If you feel a bit queasy about using this function on your
- valuable database files, make a copy of them first, test out the new
- files, then you can dispose of the originals. Always wise to be safe.
-
-
- PASS
-
- SYNOPSIS:
- pass(param,dir)
- char *param; /*string variable to pass to DBASE */
- char *dir; /*directory to write RETURN.MEM file*/
- ----------------------------------------------------------------
- This function, along with a few DBASE program statments, passes
- one parameter to DBASE's memory variable area. This is done by writing
- the variable 'param', which must be a character string pointer (numbers
- must be converted to character strings), to a file in the directory
- specified by the string pointer 'dir' (dir=NULL will default to the
- current directory). This file will be called RETURN.MEM. The parameter
- is recovered from DBASE by the program statement:
- RESTORE FROM RETURN ADDITIVE
- The parameter will be named RETPARAM, and will then be
- accessible (privately) to the DBASE program that called the function.
- To make the passed parameter generally available (global), the following
- program statement should appear before the C function is called;
- PUBLIC RETPARAM
- If the creation of RETURN.MEM is successful, a zero is
- returned by this function. Otherwise an error message is displayed and
- the program exits immediately.
-
- NOTE: Since the "\" character always gets interpreted as "ESC"
- in 'C',the forward slash - "/" - must be substituted in its place when
- specifying the directory for the 'dir' parameter.
-
- NOTE: if this function is used repeatedly in a DBASE program,
- either delete RETURN.MEM before each use, or SET SAFETY OFF to avoid the
- overwrite message and prompt.
-
- PROGRAMMER'S NOTE: This function uses the global structure cmem,
- which is of type cmemvar. (see dbase.h for details)
-
-
-
- DBCLOSE
-
- SYNOPSIS:
- dbclose(dbase)
- struct dbinfo *dbase;
- ----------------------------------------------------------------
- This function closes all the files associated with the C2DBASE
- functions and the .DBF file that are currently open. It should always
- be the last C2DBASE function called, so as to prevent accidents
- happening (which open files are prone to have).The only passed parameter
- to this function is the pointer to the dbinfo structure.
-
-
- CDBUTIL
-
- CDBUTIL MODES
-
- GENERAL
-
- The CDBUTIL program has been provided for two reasons. First and
- foremost, as an example of how to use the C2DBASE functions - hence the
- inclusion of the source code. No special programmig techniques were
- used, nothing especially witty or stupendous. But it is a good place to
- start learning how to use these functions. If you are serious about
- DBASE III, but don't like it's limitations, and if you are familiar with
- the 'C' language, then you can turn DBASE III into DBASE IV (enough
- superlatives). The CDBUTIL program will also be very useful to those
- who haven't the knowledge and/or the inclination (there are those, God
- luv'em) to get into programming. The program, with its modes, extends
- the capabilities of DBASE III enough to be appreciated, but to get the
- full power of C2DBASE, you need to be able to write C programs. For
- those of you who aren't already familiar with the language, this may be
- some small incentive to learn.
- The CDBUTIL program may be used inside or outside of DBASEIII.
- If it is being used inside of DBASEIII, it is best to incorporate it
- into .PRG and .PRC command files to extend the capabilities of DBASEIII.
- An example of such a .PRC file is also included with this package.
- Certain modes (such as packing a memo file) should only be used,
- when not in DBASE. Other modes (such as listing record) make no sense
- to use inside of DBASE. They are provided to give you access to your
- databases without DBASE. Still other modes (such as keyword searchs,
- programmed-controlled memo writing, count to memory variable, etc.) only
- make sense when using them inside of DBASE. I have experienced some
- small difficulty in running CDBUTIL in a multitasking environment. My
- present guess is that the 20 file limit set for MS-DOS was exceeded.
- These difficulties disappeared when I re-instated regular DOS.
- The CDBUTIL program should reside in the directory you are
- using, unless it is in your PATH, or you have a utility which allows you
- to run programs from other directories.
- Any time CDBUTIL performs an error exit, the DOS ERRORLEVEL will
- be set to 1.
- The CDBUTIL modes only scratch the surface of the possibilities
- of C2DBASE. Creativity will extend the flexibility and power with which
- you can manipulate your databases.
-
-
- FUNCTION CALLING PROCEDURE
-
- CDBUTIL is a collection of useful functions gathered into one
- program. The modes are numbered, and each mode expects a specified
- argument list. "CDBUTIL ?", "CDBUTIL HELP", or just plain "CDBUTIL"
- will display a list of the modes available and the argument list
- required. The included modes are discussed in more detail below.
- Parameters indicated with < > are required, while parameters indicated
- with [ ] are optional.The source code for the CDBUTIL program is also
- included as an example of how to program with the C2DBASE functions.
-
-
- DISPLAY FILE INFORMATION
-
- MODE 1 - DISPLAY FILE INFORMATION
- =====================================
- CALLING STATEMENT- CDBUTIL 1 <DBFfile> [NDXfile NDXfile...]
-
- This mode displays the database information of the specified
- file. The display is self-explanatory. NDXfiles (optional) may be
- specified in the calling statement. The complete pathname may be used
- to examine files in foreign directories. If NDXfiles are also
- specified, their extensions are assumed to be .NDX if they are not
- present. They are also assumed to be in the same directory as the .DBF
- file, and their PATH should not be specified. If one of the index files
- cannot be found, the mode aborts and no display is given.
- This mode should be used outside of DBASE III.
-
-
- UNFILTERED RECORD COUNT
-
- MODE 2 - UNFILTERED RECORD COUNT
- ================================
- CALLING STATEMENT - CDBUTIL 2 <DBfile>
-
- If there are large databases in your work, and periodically you
- need to know how many records are contained therein, you can use DBASE's
- COUNT command, which could take awhile (minutes with databases in excess
- of 1000 records). Or you could use mode 2 or 3 of CDBUTIL. mode 2
- displays the unfiltered record count on the terminal screen. This count
- will include all records, including thosed marked for deletion, or
- filtered out-of-sight. Pathnames are allowed, and the .DBF extension is
- assumed.
- This mode may be used inside or outside of DBASE III.
-
-
- UNFILTERED COUNT TO MEMORY VARIABLE
-
- MODE 3 - UNFILTERED COUNT TO MEMORY VARIABLE
- ============================================
- CALLING STATEMENT - CDBUTIL 3 <DBFfile>
-
- This mode is the same as mode 2 except that the count result is
- placed in a .MEM file, in the same directory as the .DBF file, so that
- it may be RESTORED (ADDITIVE), and made available to DBASE III. For
- further details please examine the CDBUTIL.PRC program, the
- documentation on the C2DBASE "pass" function, and the DBASE manual on
- .MEM files.Although the "pass" function is a bit limited in this version
- of C2DBASE, this CDBUTIL mode is an example of how external programs may
- brings results and answers into DBASE III for processing. If you would
- like to extend the mathematical capability of DBASE, and can code up
- what you want in 'C', then DBASE is mathmatically limited only by your
- creativety and knowledge.
-
- NOTE: The maximum number of records that can be processed with
- this CDBUTIL mode is 65535. This is a limitation of CDBUTIL, not
- C2DBASE.
-
-
- RECORD LISTING
-
- MODE 4 - RECORD LISTING
- ========================
- CALLING STATEMENT - CDBUTIL 4 <DBfile> [rec. range]
-
- This mode lists the records of a database file. All the records
- contained in the file will be listed unless the optional [rec. range]
- is given, in which case only those records (inclusively) will be listed.
- The records are listed in numerical order.
- The .DBF extension is assumed if not present, and a pathname may
- be given for the .DBF file.
- As presently programmed, records longer than 80 bytes will wrap
- around the screen, similar to DBASE III. I find this annoying, and will
- probably program some formatting options, or specific field request
- capabilities into CDBUTIL in the next version. Since the source for
- CDBUTIL is given, you may do the same if you don't feel like waiting for
- me.
- DBASE gives a better listing of .DBF records, so this mode need
- only be used when outside of DBASE to view database records.
-
-
- MEMO FIELD DISPLAY
-
- MODE 5 - MEMO FIELD DISPLAY
- ===============================
- CALLING STATEMENT - CDBUTIL 5 <DBFfile> <rec#> [[+],[-],[-rec#]]
-
- This mode simply illustrates the use of the 'memoread' C2DBASE
- function. With this, and a few other C2DBASE functions, the memo fields
- in DBASE III can really be put to use. This memo field display CDBUTIL
- mode only begins to tap the power, and is provided as much for example
- as for usefulness.
- CDBUTIL mode 5 displays the memo field for the record specified.
- If the .DBF specified does not have a memo field, an exit with
- ERRORLEVEL 1 is performed. If the record specified has no memo text in
- its field, a message is displayed saying so.
- If a '+' appears after the record number (i.e. 1745+), then all
- records starting with the one specified will have their memo field
- displayed. If a '-' appears after the record number (i.e. 135-), then
- all records starting with the first and ending with the one specified
- will have their memo field displayed.If a starting and ending record
- number is given (i.e. 657-700), then the memo fields for those records,
- inclusive, will be displayed. Of course, starting number must be lower
- than ending number, or else...
- DBASE III gives very little control over how the memo text is
- displayed. Unless the report generator is used, you are limited to a
- display of 50 columns with an unjustified right edge. This is so no
- matter how the text is actually formatted. If you use another word
- processor to write the text, and format it as you desire, you are still
- limited to DBASE's format. The report generator gives a bit more
- flexibility, but not much. With this mode of CDBUTIL, the display will
- appear formatted as you typed it.
- Please read the documentation for 'memoread' for other
- restrictions and limitations on using this mode. Refer to CDBUTIL.PRC
- on how to use this mode inside of DBASE III.
-
- NOTE: DBASE III version 1.2 allows much greater flexibility over
- the formatting of displayed memo fields. If you have this version,
- check out this capability before you use this mode. you may like it
- better.
-
-
- KEY PHRASE SEARCH THROUGH MEMO FIELD
-
- MODE 6 - KEY PHRASE SEARCH THROUGH MEMO FIELDS
- ==============================================
- CALLING STATEMENT - CDBUTIL 6 <DBFfile> <phrase> [rec. range]
-
- Here's where we begin to see what we can do with some of the
- C2DBASE functions. DBASE III provides no capability to use the memo
- field beyond simple text holders. With DBASE III, you cannot search the
- memo field for keywords, and you cannot do a listing based on the
- contents of the memo field.
- This mode of CDBUTIL searches the memo fields of a database, and
- lists (on stdout) all records whose memo field contains the keyword
- <phrase>. If a record range is provided (optional), it is given in the
- form xxx-xxx (i.e 546-601). In this case only those records specified
- in the range will be searched for the keyword. For each record examied
- that does not contain the keyword or keyphrase, a dot is printed to give
- the user some feedback that the program is proceeding.
- The keyword search is not case specific. It will find a match
- on both upper and lower case.
- Since a space between words on the command line will be
- interpreted as a different argument, spaces are designated by the
- underscore character '_'. In other words, in order to find "the phrase"
- it must be written as "the_phrase". To find "one two three" it is
- necessary to specify it as "one_two_three". This inconvenience comes
- about from DOS's commandline parsing. In a latter version, I expect the
- calling statement for this mode to be made more convenient.
- With a little imagination and creativity, the memo field can be
- made to perform some very useful work.
-
-
- PROGRAMM-CONTROLLED MEMO WRITING
-
- MODE 7 - PROGRAMM-CONTROLLED MEMO WRITING
- =========================================
- CALLING STATMENT - CDBUTIL 7 <DBFfile> <rec#> <textfile> [del]
-
- Presently DBASEIII provides no way to write in the memo field
- under program control. To edit the memo field, you must be in record
- edit mode (possible under program control), manaully place the cursor on
- the field, then press ctrl-pgdn. When writing applications for
- end-users, this may be cumbersome, or inconvenient. This CDBUTIL mode,
- along with the appropriate statements in a .PRG or .PRC file (see
- CDBUTIL.PRC), and an external word-processor, provides the capability of
- writing memo fields under program control.
- This capability is a two-step process. First a textfile must be
- created on disk keeping in mind any size restrictions coming from the
- 'memoadd' C2DBASE function. This may be done by using the RUN command
- to invoke your wordprocessor (i.e. RUN ED file.txt). Once the file is
- on disk, CDBUTIL mode 7 will bring it neatly into the .DBT file, and
- update the specified record. Refer to the CDBUTIL.PRC documentation for
- further clarification.
- To use mode 7, the required parameters are as shown above.
- Pathnames for both the DBFfile and the textfile is permitted. The
- DBFfile extension may be ommitted, but the textfile must have an
- extension. The record number must exist in the database. If "del" is
- specified (optional), the textfile is deleted after successful
- incorporation into the .DBT file.
- You now have a choice in how you create your memo fields. DBASE
- III's ^Kr, when you are in its word processor, will also read in a text
- file from disk, but first you have to be in the word processor. This may
- not be much of an inconvenience at all. It is probably better to use
- DBASE's own facilities when it does not interferre with what you want to
- do or the convenience with which you do it.
-
-
- SEPARATE .DBT FROM .DBF
-
- MODE 8 - DISCONNECT/CONNECT .DBT FILE
- =====================================
- CALLING STATEMENT - <DBFfile> <submode>
-
- This mode implements the C2DBASE 'onoffdbt' function. Please
- read the documentation for this function in order to understand how to
- use this DBUTIL mode. The submode is zero when you want to divorce the
- .DBT file from the .DBF file. The submode is one when you want to
- establish that connection again. If this sound fuzzy, refer to the text
- on the 'onoffdbt' function.
- This mode should only be used outside of DBASE III.
-
-
- PACK MEMO FILE
-
- MODE 9 - PACKING .DBT FILE
- ==========================
- CALLING STATEMENT - <DBFfile>
-
- This mode implements the C2DBASE 'dbtpack' function. Please
- refer to the documentation on this function to understand what this mode
- is doing, when to use it, and the limitations which must be observed.
- This mode should only be used outside of DBASE III.
-
-
- #include "\lattice\h\glfstdio.h" /*greenleaf header*/
- #include "\lattice\h\dbase.h"
- #include "\lattice\h\fcntl.h" /*Lattice Header*/
- #include "\lattice\h\ctype.h" /*Lattice header*/
- #include "\lattice\h\disk.h" /*Greenleaf header file*/
- /*modify the above PATHs for your own system*/
-
- static char *help[]={
- "DBASE UTILITIES PROGRAM version 1.0 Lee Mowatt - 10/85",
- " To perform a particular function, the command line or the RUN string",
- "takes the following generalized form;",
- " CDBUTIL <func#> <.DBF file> [argument list]",
- " (from DOS)",
- " or",
- " RUN CDBUTIL <func#> <.DBF file> [argument list]",
- " (from inside DBASE III)",
- "\n",
- "FUNC. # FUNCTION ARGUMENT LIST",
- "======================================================================",
- " 1 Database information <DBFfile> [NDXfile NDXfile...]",
- " 2 Unfiltered record count <DBFfile>",
- " 3 Count to memory variable <DBFfile>",
- " 4 Record listing <DBFfile> [rec.range]",
- " 5 Memo field display <DBFfile> <rec#> [[+],[-],[-rec#]]",
- " 6 memo field searching <DBFfile> <phrase> [rec. range]",
- " 7 memo field from textfile <DBFfile> <rec#> <textfile> [del]",
- " 8 disconnect/connect .DBT <DBFfile> <0 or 1> ",
- " (0=disconnect, 1=connect)",
- " 9 Pack a .DBT file <DBFfile>",
- " NOTE: [rec. range] is given in the form start#-end# (i.e. 12-234)",
- NULL
- };
-
- struct commlist
- {
- int argnum; /*# of args on commandline excluding CDBUTIL*/
- char *args[20]; /*in-program argument string pointers*/
- };
-
- /*the following defines help in reading the function source code*/
- #define FUNC files->args[0]
- #define DBFILE files->args[1]
- #define NDXFILE(x) files->args[x+1]
- #define RECNUM files->args[2]
- #define PHRASE files->args[2]
- #define RANGE files->args[3]
- #define SUBMODE files->args[2]
- #define TXT files->args[3]
-
- main(argc,argv)
-
- int argc; /*number of arguments*/
- char *argv[]; /*argument string pointers*/
-
- {
- struct commlist arglist; /*argument structure*/
- int loop,count; /*general purpose integer variables*/
- int function; /*C2DBASE function number*/
- int fnum; /*DBF file number*/
- static struct dbinfo db; /*DBASE information structure-must be static*/
- char *ext=".dbf"; /*DBF file extension*/
- char *path; /*file path name*/
- char *stpchr(); /*Lattice function*/
-
- if ((argc==1) || (isdigit(argv[1][0]) == 0))
- {
- for (loop=0;help[loop] != NULL;loop++)
- printf("%s\n",help[loop]);
- exit(0);
- }
- for (loop=0;loop<argc-1;loop++)
- arglist.args[loop]=argv[loop+1];
- arglist.argnum=argc-1; /*program name not included in argument list*/
-
- path[0]=NULL;
- strcat(path,argv[2]);
- if (stpchr(argv[2],'.') == NULL) /*add DBF extension if not present*/
- strcat(path,ext);
- fnum=dbheader(path, &db); /*fill information structure*/
- if (db.error != 0) /*check for error*/
- {
- switch (db.error)
- {
- case 1:
- printf("\7Filename MUST have .DBF extension\n");
- exit(1); break;
- case 2:
- printf("\7Cannot open %s\n",path);
- exit(1); break;
- case 3:
- printf("\7Not a DBASE .DBF file\n");
- exit(1); break;
- case 4:
- printf("\7Cannot open associated .DBT file.\n");
- exit(1);break;
- default:
- printf("Unknown error code - %d\n",db.error);
- exit(1); break;
- }
- }
-
- stcd_i(argv[1],&function); /*convert decimal string to integer*/
- switch (function)
- {
- case 1:
- func1(&db,&arglist);break;
- case 2:
- func2(&db,&arglist);break;
- case 3:
- func3(&db,&arglist);break;
- case 4:
- func4(&db,&arglist);break;
- case 5:
- func5(&db,&arglist);break;
- case 6:
- func6(&db,&arglist);break;
- case 7:
- func7(&db,&arglist);break;
- case 8:
- func8(&db,&arglist);break;
- case 9:
- func9(&db,&arglist);break;
- default:
- printf("\7Unknown CDBUTIL function number\n");break;
- }
- dbclose(&db);
- }
-
-
- /**********************************************************************/
- func1(dbase,files) /*display file information*/
-
- struct dbinfo *dbase;
- struct commlist *files;
-
- {
- int loop;
- char *stpchr(); /*Lattice function*/
- char *string,*temp; /*general purpose caharacter pointer*/
- char *path; /*pathname*/
- char c=0x5c; /*ascii number for '\'*/
- char *ext=".ndx"; /*index extensionto be appended if not present*/
-
- for (loop=3;loop<=files->argnum;loop++) /*process index files*/
- {
- if ((string=stpchr(DBFILE,c)) != NULL) /*PATH processing*/
- {
- while ((temp=stpchr(string,c)) != NULL)
- string=temp+1; /*find last '\'*/
- stccpy(path,DBFILE,(string-DBFILE+1));
- }
- strcat(path,NDXFILE(loop-2));
- if (stpchr(path,'.') == NULL)
- strcat(path,ext);
- ndxread(dbase,path);
- /*test for errors*/
- if (dbase->error !=0)
- {
- switch (dbase->error)
- {
- case 1:
- printf("\7Index file must have .NDX extension\n");
- exit(1);break;
- case 2:
- printf("\7Cannot open %s\n",path);
- exit(1);break;
- case 3:
- printf("\7Wrong index file for database being used\n");
- exit(1);break;
- default:
- printf("\7Unknown ndxread error code-%d\n",dbase->error);
- exit(1);break;
- }
- }
- }
- dbstat(dbase); /*display files information*/
- }
-
-
- /**********************************************************************/
- func2(dbase,files) /*unfiltered record count to screen*/
-
- struct dbinfo *dbase;
- struct commlist *files;
-
- {
- printf("%ld records in %s\n",dbase->info.quan,dbase->filname);
- }
-
-
- /**********************************************************************/
- func3(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
-
- {
- char count[10]; /*string of record count*/
- char c=0x5c; /*ascii number for '\'*/
- char *string,*temp; /*general purpose string variables*/
- char path[35]; /*directory to write .MEM file*/
- char *stpchr(); /*Lattice function*/
-
- stci_d(count,(int)(dbase->info.quan),10); /*convert record number to string*/
-
- if ((string=stpchr(DBFILE,c)) != NULL) /*PATH processing*/
- {
- while ((temp=stpchr(string,c)) != NULL)
- string=temp+1; /*find last '\'*/
- stccpy(path,DBFILE,(string-DBFILE));
- }
-
- pass(count,path);
- }
-
-
- /**********************************************************************/
- func4(dbase,files) /* record listing*/
-
- struct dbinfo *dbase;
- struct commlist *files;
-
- {
- char *range;
- long start,end,strtol();
- char *string,*record,*stpchr();
- char *temp;
-
- if ((files->argnum < 3) || (isdigit(files->args[2][0]) == 0))
- {start=1L; end=dbase->info.quan;} /*no range specified,do all records*/
- else
- {
- range=files->args[2];
- string=stpchr(range,'-');
- strxlf(record,range,(string-range));
- start=strtol(record,&temp,10);
- strxrt(record,range,strlen(range)-(string-range+1));
- end=strtol(record,&temp,10);
- }
-
- reclist(dbase,start,end);
- }
-
-
- /**********************************************************************/
- func5(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
- {
- char *memoread(); /*C2DBASE function*/
- char *memotext; /*text pointer*/
- char *memoname; /*name of memo field*/
- char *stpchr(); /*Lattice function*/
- long rec,start,end; /*record numbers*/
- int fieldspace; /*length of memo text*/
- int count; /*general purpose integer variable*/
- long strtol(); /*Lattice function*/
- char *temp,*record;
-
- for (count=0; count<dbase->fieldnum; count++) /*check that there is a memo field*/
- {
- if (dbase->field[count].type == 'M')
- memoname=dbase->field[count].name;
- }
- memoread(dbase,1L); /*see if this function returns an error*/
- if ( (dbase->error == 1) || (dbase->error == 2) ) /*no memo fields to be read*/
- {
- printf("No memo field in this database\n");
- exit(1);
- }
- if (stpchr(RECNUM,'+') !=NULL)
- {
- start=strtol(RECNUM,&memotext,10); /*record specified*/
- end=dbase->info.quan;
- }
- else
- {
- if ((temp=stpchr(RECNUM,'-')) != NULL)
- {
- if (strlen(RECNUM) > (temp-RECNUM+1)) /*range specified*/
- {
- strxlf(record,RECNUM,(RECNUM - temp));
- start=strtol(record,&memotext,10);
- strxrt(record,RECNUM,strlen(RECNUM)-(temp-RECNUM+1));
- end=strtol(record,&memotext,10);
- }
- else
- {
- start=0L;
- end=strtol(RECNUM,&memotext,10);
- }
- }
- else
- {
- start=strtol(RECNUM,&memotext,10);
- end=start;
- }
- }
- for (rec=start;rec<=end;rec++)
- {
- memotext=memoread(dbase,rec);
- if ((dbase->error == 0) || (dbase->error == 5))
- {
- printf("\n***%s for record %ld***\n",memoname,rec);
- fieldspace=strlen(memotext);
- for (count=0;count<fieldspace;count++)
- bdos(6,memotext[count]);
- printf("\n");
- if (dbase->error == 5)
- printf("Display truncated.Memo text longer than 2048 characters\n");
- }
- else
- {
- switch (dbase->error)
- {
- case 3:
- printf("no memo text for record %ld\n",rec);break;
- case 4:
- printf("error reading .DBT file\n");break;
- default:
- printf("Unknown memoread error -#%d\n",dbase->error);
- break;
- }
- }
- }
- }
-
-
- /**********************************************************************/
- func6(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
- {
- char *memoread();
- long rec,start,end; /*record numbers*/
- char *temp,*string,*record; /*general purpose string variable*/
- char *stpchr();
- long strtol(); /*Lattice function*/
- int find,found=FALSE; /*find status of textfind function*/
- int loop,count;
-
- memoread(dbase,1L); /*see if this function returns an error*/
- if ( (dbase->error == 1) || (dbase->error == 2) ) /*no memo fields to be read*/
- {
- printf("No memo field in this database\n");
- exit(1);
- }
-
- count=strlen(PHRASE);
- for (loop=0;loop<count;loop++)
- {
- if (PHRASE[loop] == '_')
- PHRASE[loop] = 0x20;
- }
-
- if ((files->argnum < 4) || (isdigit(RANGE[0]) == 0)) /*no range specified*/
- {start=1L; end=dbase->info.quan;}
- else
- { /*range given*/
- string=stpchr(RANGE,'-');
- strxlf(record,RANGE,(string-RANGE));
- start=strtol(record,&temp,10);
- strxrt(record,RANGE,strlen(RANGE)-(string-RANGE+1));
- end=strtol(record,&temp,10);
- }
-
- printf("search for %s\n",PHRASE);
- for (rec=start;rec<=end;rec++)
- {
- find=textfind(dbase,rec,PHRASE);
- switch (find)
- {
- case 1:
- found=TRUE;
- printf("\nRecord %ld ",rec);
- break;
- case 0:
- printf(".");break;
- case -1:
- if (dbase->error == 2)
- {
- printf("Error- search string is NULL\n");
- exit(1);
- }
- else
- {
- if (dbase->error == 3)
- printf("Error reading .DBT file.\n");
- }
- break;
- default:
- printf("Unknown error\n"); break;
- }
- }
- printf("\n");
- }
-
-
- /**********************************************************************/
- func7(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
- {
- unsigned memoadd(); /*C2DBASE function*/
- static long rec; /*record number*/
- long strtol(); /*Lattice function*/
- char *stpchr(); /*Lattice function*/
- struct DISKTABLE text; /*structure for Greenleaf function 'dos2delete*/
- /*found in disk.h header*/
-
- rec=strtol(RECNUM);
- if (stpchr(TXT,'.') ==NULL) /* test for proper arguments*/
- {printf("\7Command line error\n"); exit(1);}
-
- if (memoadd(dbase,rec,TXT) == -1)
- {
- switch (dbase->error)
- {
- case 0:
- break;
- case 1:
- printf("\7Record does not have a memo field.\n"); break;
- case 2:
- printf("\7Cannot open %s\n",TXT); break;
- case 3:
- printf("\7Cannot re-open .DBT file\n"); break;
- default:
- printf("\7Unknown error\n"); break;
- }
- }
- else
- {
- if ((files->args[4] == "del") || (files->args[4]=="DEL"))
- {
- text.string=TXT;
- dos2delete(&text); /*delete text file*/
- }
- }
- }
-
-
- /**********************************************************************/
- func8(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
- {
- onoffdbt(dbase,SUBMODE);
- }
-
-
- /**********************************************************************/
- func9(dbase,files)
-
- struct dbinfo *dbase;
- struct commlist *files;
- {
- if (dbtpack(dbase) != 0)
- {
- switch (dbase->error)
- {
- case 1:
- printf("\7Database has no .DBT file\n"); break;
- case 2:
- printf("\7Cannot open original .DBT file\n"); break;
- case 3:
- printf("\7Cannot create new .DBT file\n"); break;
- case 4:
- Printf("\7Error writing to new .DBT file\n"); break;
- case 5:
- printf("\7Error updating .DBF file\n"); break;
- default:
- printf("\7Unknown DBTPACK error code\n"); break;
- }
- }
- }
-
-
-
- CDBUTIL.PRC FOR DBASE III
-
- EXPLANATION
-
- This .PRC illustrates how to make DBASE III sub-programs that
- make the C2DBASE functions available to DBASE. To use this file you
- must use the SET PROCEDURE TO command to tell DBASE to search it for
- called procedures, and the CDBUTIL.EXE program must be in the current
- directory or in one of the directories specified by the PATH. Once this
- is done, the procedures in this file may be called just as if the were
- .PRG files on disk.
- This set of sub-programs are only meant for illustration
- purposes only, although you may find them superficially useful. They
- demonstrate one way the C programs you create using the C2DBASE
- functions may interface to DBASE III.
- Examine the file listings of both CDBUTIL.PRC and CDBUTIL.C to
- get a better idea as to how to interface to the C2DBASE functions from
- both inside and outside of DBASE III. (The .PRC may only be used inside
- DBASE and is only used to evok the real proogram, CDBUTIL.EXE, which may
- also be used outside of DBASE.) Please note that if you are going to
- recompile the source code for CDBUTIL.C, the directory references in the
- .PRC and .C files are specific to the COMPUSCAN hard disk. They should
- be changed to reflect your system. Also, since the source for both the
- CDBUTIL.C and CDBUTIL.PRC are available to you, you may modify the
- programs to suit your specific needs. One thing you must not change is
- the credits. All references to Lee Mowatt and COMPUSCAN must remain
- untouched.
-
- The best way to use CDBUTIL.PRC is to reserve a few memory
- variables devoted to the arguments required by the procedures. Each
- procedure requires certain arguments, which may be easily specified
- using memory variables. The arguments required mimick the CDBUTIL.C
- modes, so if you reserve memory variables called DBFFILE, RECRANGE,
- PHRASE, etc, it becomes very easy to say DO RECCOUNT WITH DBFFILE, or DO
- STRFIND WITH DBFFILE,PHRASE,RECRANGE. Of course, you must assign these
- variables to the proper text before you use them in this way. It will be
- necessary to read the DBASE III manual if what is being said here is a
- little confusing to you. Also being familiar with the CDBUTIL.EXE modes
- with help a lot in using this functions inside of DBASE III. Further
- insight into the arguments passed will be had by understanding the
- calling statements for that program.
-
- From inside of DBASE the following procedures are available
- after the SET PROCEDURE TO statement is executed;
-
- RECCOUNT - This procedure simply displays the unfiltered record
- count of the specified database. It must be passed a parameter
- containing a valid .DBF filename. (i.e. DO RECCOUNT WITH "\direct\file"
- or DO RECCOUNT WITH DBFFILE).
- MEMCOUNT - This procedure puts the unfiltered record count in a
- memory variable called MEMCOUNT. Its arguments are the .DBF filename
- (see RECCOUNT) and the memory variable that will be used to store the
- count. (i.e. DO MEMCOUNT WITH DBFFILE, <MEMVAR>, where <MEMVAR> is a
- memory variable of the user's choice.)
- MEMDISP - Displays the memo field for the specified records.
- Its first argument is DBFFILE, while its second argument must be a
- string representing a valid record number, record range,or starting or
- ending record number. This procedure is particularly useful if you wish
- to view the memo field in a format that is not supported by DBASE
- III.See the documentation on CDBUTIL.C mode 5 for a more complete
- description of these arguments.
- STRFIND - This procedure duplicates CDBUTIL.C mode 6. It
- requires 3 parameters, DBFFILE, PHRASE, and RECRANGE.
-
- WARNING: When CDBUTIL performs an operation on a file, the file
- it is operating on the is file that is presently stored on disk, NOT THE
- FILE STORED IN MEMORY. If you have made changes or additions to the
- file in memory, write it out to disk using the USE or COPY commands
- before using a CDBUTIL function.
-
-
- PROGRAM
-
- *****************
- PROCEDURE RECOUNT
- *****************
- *THIS PROCEDURE PROVIDES A FAST ALTERNATIVE TO DBASE'S COUNT COMMAND. iT GIVES
- *AN UNFILTERED COUNT OF THE NUMBER OF RECORD IN A .DBF FILE. (NORMALLY, YOU CAN
- *HIDE CERTAIN RECORDS FROM DBASE BY USING THE 'SET FILTER TO' COMMAND. THIS
- *WOULD CHANGE THE RECORD COUNT. THIS PROCEDURE INCLUDES THOSE HIDDEN RECORDS.)
- PARAMETERS FILE
- RUN CDBUTIL.EXE 2 &FILE
- RETURN
-
- ******************
- PROCEDURE MEMCOUNT
- ******************
- *THIS PROCEDURE IS THE SAME AS RECOUNT, EXCEPT THAT THE RECORD COUNT IS PASSED
- *TO A USER SPECIFIED MEMORY VARIABLE.
- PARAMETERS FILE,RCOUNT
- RUN CDBUTIL.EXE 3 &FILE
- *ESTABLISH FULL PATHNAME OF .MEM FILE
- TEMP=SUBSTR(FILE,1)
- SLASH=AT("\",TEMP)
- POSITION=0
- DO WHILE SLASH > 0
- POSITION=POSITION+SLASH
- TEMP=SUBSTR(FILE,1+POSITION)
- SLASH=AT("\",TEMP)
- ENDDO
- MEMFILE=SUBSTR(FILE,1,POSITION)+'RETURN'
- RESTORE FROM &MEMFILE ADDITIVE
- RCOUNT=VAL(RETPARAM)
- *RETPARAM IS ALWAYS RESTORED AS A STRING
- RETURN
-
- *****************
- PROCEDURE MEMDISP
- *****************
- *THIS PROCEDURE DISPLAYS THE MEMO FIELD(S) SPECIFIED IN THE VARIABLE RECRANGE
- *RECRANGE MUST BE A STRING REPRESENTING A RECORD NUMBER, RECORD RANGE, OR
- *STARTING OR ENDING RECORD NUMBER.
- PARAMETERS FILE,RECRANGE
- RUN CDBUTIL.EXE 5 &FILE &RECRANGE
- RETURN
-
- ******************
- PROCEDURE STRFIND
- ******************
- *THIS PROCEDURE SEARCHES THROUGH RECORDS TO FIND A KEYPHRASE. THE RECORDS
- *SEARCHED ARE SPECIFIED IN THE THIRD VARIABLE RECRANGE AND MUST BE A STRING
- *OR STRING VARIABLE REPRESENTING THE RECORD OR RECORD RANGE. THE KEYPHRASE
- *IS GIVEN IN THE SECOND VARIABLE, AND THE FILE TO BE SEARCHED IS GIVEN IN
- *THE FIRST VARIABLE.
- PARAMETERS FILE, PHRASE, RECRANGE
- RUN CDBUTIL.EXE 6 &FILE &PHRASE &RECRANGE
- RETURN