home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
dblib201.zip
/
FILES.PRG
< prev
next >
Wrap
Text File
|
1993-04-27
|
135KB
|
3,677 lines
*-------------------------------------------------------------------------------
*-- Program...: FILES.PRG
*-- Programmer: Ken Mayer (CIS: 71333,1030)
*-- Date......: 03/24/1993
*-- Notes.....: These are file processing routines. To see how to use this
*-- library file, see: README.TXT.
*-------------------------------------------------------------------------------
PROCEDURE AllTags
*-------------------------------------------------------------------------------
*-- Programmer..: Susan Perschke (SPECDATA) and Michael Liczbanski (LMIKE)
*-- Date........: 01/03/1992
*-- Notes.......: Used to bring up a list of MDX tags on screen for the user,
*-- so they can change the current tag ... This was gotten to me
*-- by Steve (LTI), from "Data Based Advisor", December, 1991.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 12/15/1991 - original procedure.
*-- 01/03/1992 - Ken Mayer -- added shadow ...
*-- Calls.......: SHADOW Procedure in PROC.PRG
*-- Called by...: Any
*-- Usage.......: DO AllTags WITH nULRow, nULCol
*-- Example.....: ON KEY LABEL F8 DO ALLTAGS WITH 02,60
*-- Returns.....: None
*-- Parameters..: nULRow -- Starting Row for Popup
*-- nULCol -- Starting Column for Popup
*-------------------------------------------------------------------------------
parameters nULRow, nULCol
private nBar, cPrompt, nBRRow, nBRCol
*-- Disable left/right arrow keys to prevent an accidental exit
on key label leftarrow ?? chr(7)
on key label rightarrow ?? chr(7)
*-- Save current screen
save screen to sTag
activate screen
*-- define the popup
define popup pTag from nULRow, nULCol;
message " Press ENTER to select new index order...ESC to exit..."
nBar = 1 && first bar
cPrompt = "-No Index-" && will always be this
*-- loop to get the rest of 'em ...
do while "" <> cPrompt && loop until no more tags
define bar nBar of pTag prompt (cPrompt)
cPrompt = tag(nBar)
nBar = nBar + 1
enddo
on selection popup pTag deactivate popup
*-- process shadow
nBRRow = nULRow+(nBar-1)+1 && bottom right for shadow (1 for t/b of pop)
nBRCol = nULCol+11 && bottom right for shadow (2 for sides,
&& +9 for tagnames)
do shadow with nULRow,nULCol,nBRRow,nBRCol
*-- do it
activate popup pTag
*-- Assign a null string to cPrompt if "No Index" selected
cPrompt = iif(bar() = 1, "",prompt())
*-- Don't change index order if ESC pressed
if bar() <> 0
set order to (cPrompt)
endif
*-- cleanup
release popup pTag
restore screen from sTag
release screen sTag
*-- Enable left/right arrow keys
on key label leftarrow
on key label rightarrow
RETURN
*-- EoP: AllTags
PROCEDURE MakeTagFl
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 04/15/1992
*-- Notes.......: Build a .dbf file from scratch, without using CREATE FROM.
*-- The file built has three fields, TAGS1, TAGS2 and TAGS3,
*-- each character-type and 254 bytes wide.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: Broken out of other code and date-writing added
*-- by Jay Parsons, 4/15/1992
*-- : Originally from the program PRGCREAT.ZIP
*-- Called by...: Any
*-- Usage.......: do MakeTagFl WITH "<cFname>"
*-- Example.....: do MakeTagFl WITH "Tags"
*-- Returns.....: None
*-- Parameters..: cFname, name of the .dbf to create
*-- Side effects: Creates a .dbf and overwrites any existing one of same name
*-- : Disables external setting of PRINTER
*-------------------------------------------------------------------------------
parameters cFname
private cName
cName = cFname
if .not. "." $ cName
cName = cName + ".DBF"
endif
set printer to file ( cName )
set printer on
??? "{3}"
??? chr( year( date() - 1900 ) )
??? chr( month( date() ) )
??? chr( day( date() ) )
??? "{0}{0}{0}{0}{129}{0}{251}{2}{0}{0}{0}{0}"
??? "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{201}{0}"
??? "{84}{65}{71}{83}{49}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}" && Tags1
??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
??? "{84}{65}{71}{83}{50}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}" && Tags2
??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
??? "{84}{65}{71}{83}{51}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}" && Tags3
??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
??? "{13}{26}"
set printer off
set printer to
RETURN
*-- EoP: MakeTagFl
PROCEDURE RedoTags
*-------------------------------------------------------------------------------
*-- Programmer..: David Love (CIS: 70153,2433)
*-- Date........: 04/18/1992
*-- Notes.......: This routine is a "generic" MDX cleanup routine. It is useful
*-- for handling "bloated" MDX files -- ones that have been around
*-- awhile (they tend to be larger than necessary). This routine
*-- will store the tag keys in an array, delete the tags, and then
*-- rebuild the MDX file from scratch, keeping all tag names and
*-- keys, and the MDX SHOULD be smaller.
*-- : Will act on the dbf's production mdx (ie. same name as dbf)
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/20/1992 - original function for dBASE IV Ver. 1.1.
*-- 04/18/1992 - David Love - adapted for use with beta version
*-- of dBASE IV, version 1.5.
*-- (TAGCOUNT(), FOR(), DESCENDING(), UNIQUE() are 1.5 functions)
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: do RedoTags with "<cDBF>"
*-- Example.....: do RedoTags with "Referral"
*-- Returns.....: None
*-- Parameters..: cDBF = Name of DATABASE file, no extension necessary.
*-------------------------------------------------------------------------------
parameter cDBF
use (cDBF) excl
*-- First, figure out how many tags exist
private nMaxTags
nMaxTags = tagcount( cDBF,1 )
*-- only perform routine if an index tag exists
if nMaxTags > 0
private nTags, mkey, mtag
*-- store the keys and tags to an array
declare aTags[nMaxTags,5]
nTags = 1
do while nTags <= nMaxTags
store key( (cDBF),nTags) to aTags[nTags,1] && grab the key
store tag( (cDBF),nTags) to aTags[nTags,2] && grab the tagname
store for( (cDBF),nTags) to aTags[nTags,3] && grab the for clause
store descending( (cDBF),nTags) to aTags[nTags,4] && .t. if descending
store unique( (cDBF),nTags) to aTags[nTags,5] && .t. if unique
nTags = nTags + 1
enddo
*-- now, delete the tags
do while "" # tag( (cDBF),1)
delete tag tag( (cDBF),1)
enddo
*-- rebuild the MDX, tag by tag ...
nTags = 1
do while nTags <= nMaxTags
mkey = aTags[nTags,1]+iif(""#aTags[nTags,3]," for "+aTags[nTags,3],"") ;
+ iif(aTags[nTags,4]," DESCENDING","") ;
+ iif(aTags[nTags,5]," UNIQUE","")
mtag = aTags[nTags,2]
index on &mkey. tag &mtag.
nTags = nTags + 1
enddo
*-- release the array ...
release aTags
endif && check for tags ...
use && close database
RETURN
*-- EoP: RedoTags
PROCEDURE AutoRedo
*------------------------------------------------------------------------------
*-- Programmer..: Douglas P. Saine (CIS: 74660,3574)
*-- Date........: 03/06/1992
*-- Notes.......: Displays a popup to choose a DBF from the current directory
*-- to re-build its MDX file
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 03/04/1992 - original procedure.
*-- 03/06/1992 -- Ken Mayer added color parameter,
*-- shadow to popup, and erase DBFS.DBF datafile at end.
*-- Calls.......: LISTDBFS Procedure in FILES.PRG
*-- REDOTAGS Procedure in FILES.PRG
*-- CENTER Procedure in PROC.PRG
*-- YESNO2() Function in PROC.PRG
*-- SHADOW Procedure in PROC.PRG
*-- EXTRCLR() Function in PROC.PRG
*-- Called by...: Any
*-- Usage.......: do AutoRedo with nXTL,nYTL,nXBR,nYBR,cColor
*-- Example.....: do AutoRedo with 5,34,15,47,"rg+/gb,w+/n,rg+/gb"
*-- Returns.....: None
*-- Parameters..: None
*------------------------------------------------------------------------------
parameters nXTL, nYTL, nXBR, nYBR, cColor
*-- Save Environment
cTalk = set("talk")
cStat = set("status")
cCloc = set("clock")
cScor = set("scoreboard")
cSafe = set("safety")
*-- Set Environment
set stat off
set talk off
set cloc off
set scor off
set safe off
*-- Full Screen Window for screen restoration when finished
define window wCoverScr from 0,0 to 23,79 none
activate window wCoverScr
clear
*-- Make a Data File of the Current Directory
do center with 10,80,extrclr('&cColor'),;
'... Making Data File from Current Directory ...'
do ListDBFs
use DBFS
index on DBFS->DBF tag IORDER
*-- Define and access the popup of DataFiles
activate screen
define popup uDbfList from nXTL,nYTL to nXBR,nYBR prompt field DBFS->DBF
on selection popup uDbfList deactivate popup
*-- Execute loop for multiple re-indexes
clear
lLoop = .t.
do while lLoop
do shadow with nXTL,nYTL,nXBR,nYBR
activate popup uDbfList
clear && get rid of shadow
*-- Record the prompt() and remove '.dbf' so it works with Redotag
cDataFile = substr(prompt(),1,len(trim(prompt()))-4)
*-- Verify the MDX exists
if file(cDataFile+'.mdx')
do redotags with cDataFile
else
do center with 10,80,extrclr("&cColor"),;
'... Production MDX file not found for file '+cDataFile
n = inkey(0)
clear
endif
*-- Determine if the user wants to re-build another
if YesNo2(.t.,"CC","",;
"Do you wish to reindex another file?","","&cColor")
use DBFS order IORDER
else
lLoop = .f.
endif
enddo
*-- Restore environment
use DBFS
delete tag IORDER
use
erase DBFS.DBF
release popup uDbfList
deactivate window wCoverScr
release window wCoverScr
set stat &cStat
set talk &cTalk
set cloc &cCloc
set scor &cScor
set safe &cSafe
RETURN
*-- EoP: AutoRedo
PROCEDURE PrntTags
*-------------------------------------------------------------------------------
*-- Programmer..: David Love (CIS: 70153,2433)
*-- Date........: 03/24/1993
*-- Notes.......: This routine is a "quick and not-so-dirty" method of printing
*-- the tag and key expressions for a dbf's production mdx file.
*-- It obviates the need for DISP/LIST STAT TO PRINT (or DISP STAT
*-- followed by SHIFT+PrtScr).
*-- This code is modified from the procedure RedoTags.prg,
*-- previously posted on the BORBBS.
*-- : The proc will print the full key expression, including
*-- FOR/DESCENDING/UNIQUE options, if present.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 01/31/1992 - original procedure written for dBASE IV, Ver. 1.1
*-- 04/18/1992 - David Love - revised for version 1.5
*-- 03/24/1993 - Lee Hite - modified so that wild card specs
*-- may now be used to list multiple .DBF's.
*-- also, added optional parameter to include file
*-- structure in output.
*-- Calls.......: ADIR() Function in FILES.PRG
*-- PARSPATH() Function in FILES.PRG
*-- SHELLSORT() Function in ARRAY.PRG
*-- NOTE: These routines are called only when using wildcards.
*-- Called by...: Any
*-- Usage.......: do PrntTags with "<cDBF>",[lDispStru]
*-- Example.....: do PrntTags with "Referral"
*-- do PrntTags with "*.dbf",.t.
*-- Returns.....: None
*-- Parameters..: cDBF = Name of DATABASE file, may include wildcard specs
*-- (i.e., "REF*"). No extension is necessary, but
*-- if it's there, it better be ".DBF" <g>
*-- lDispStru = [optional] set to .T. to include the file
*-- structure in the output
*-------------------------------------------------------------------------------
parameter cDBFParm,lDispStru
private cTalk
cTalk = set("TALK")
set talk off
set printer on
*-- handle whether or not we got a wild card
private cDBFPath,cDBFMask,nDBFs,aMyArray,lDummy,nKntr
if "*" $ cDBFParm .or. "?" $ cDBFParm
*-- wildcards, so build an array of the file names
cDBFMask = iif(at(".DBF",upper(cDBFParm))>0,cDBFParm,cDBFParm+".DBF")
nDBFs = aDir(cDBFMask,"","")
if nDBFs > 0
declare aMyArray[nDBFs,1]
nKntr = 1
do while nKntr <= nDBFs
aMyArray[nKntr,1] = gaDir[nKntr,1]
nKntr = nKntr + 1
enddo
lDummy = ShellSort(nDBFs)
endif
cDBFPath = ParsPath(cDBFMask)
else
*-- no wild cards, so we just have one entry in the array
private aMyArray
declare aMyArray[1,1]
aMyArray[1,1] = upper(cDBFParm)
nDBFs = 1
cDBFPath = ""
endif
*-- loop for each .DBF
private cDBF,nKntr
nKntr = 1
do while nKntr <= nDBFs
cDBF = aMyArray[nKntr,1]
*-- pull extension out of file name so TAGCOUNT(), etc. work...
cDBF = iif(at(".DBF",cDBF)=0,cDBF,left(cDBF,at(".DBF",cDBF)-1))
use (cDBFPath+cDBF)
?? "DATABASE: "+cDBF at 0
?
?
*-- display file structure if optioned
if lDispStru
?? "STRUCTURE:" at 0
disp stru
?
endif
*-- now, figure out how many tags exist
private nMaxTags
nMaxTags = tagcount( cDBF )
?? "INDEX TAGS:" at 0
?
*-- only perform routine if an index tag exists
if nMaxTags > 0
private nTags, mkey, mtag
*-- store the keys and tags to an array
declare aTags[nMaxTags,5]
nTags = 1
do while nTags <= nMaxTags
store key( (cDBF),nTags) to aTags[nTags,1] && grab the key
store tag( (cDBF),nTags) to aTags[nTags,2] && grab the tagname
store for( (cDBF),nTags) to aTags[nTags,3] && grab the for clause
store descending( (cDBF),nTags) to aTags[nTags,4] && .t. if descending
store unique( (cDBF),nTags) to aTags[nTags,5] && .t. if unique
nTags = nTags + 1
enddo
*-- print each tag with it's key expression
?? "Tag" at 0
?? "Key Expression" AT 12
?
nTags = 1
do while nTags <= nMaxTags
?? aTags[nTags,2] AT 0
?? aTags[nTags,1] + ;
iif(""#aTags[nTags,3]," FOR "+aTags[nTags,3],"") + ;
iif(aTags[nTags,4]," DESCENDING","") + ;
iif(aTags[nTags,5]," UNIQUE","") AT 12
?
nTags = nTags + 1
enddo
*-- release the array ...
release aTags
else
*-- no tags found
?? "none" at 0
?
endif && check for tags ...
use && close database
?? replicate("=",60) at 0
?
nKntr = nKntr + 1
enddo && loop for each .dbf
*-- restore the environment
release gaDir
set printer off
set talk &cTalk
RETURN
*-- EoP: PrntTags
PROCEDURE ListDBFs
*-------------------------------------------------------------------------------
*-- Programmer..: David Love (70153,2433)
*-- Date........: 01/31/1992
*-- Notes.......: This procedure will create a list of the database (.dbf) files
*-- in the current directory. It will create a database file
*-- named Dbfs.dbf which exists of one 12-character field--Dbf.
*-- It will also create a text file, Dbfs.txt, through the
*-- LIST FILES to FILE command. Then it will append records
*-- to the Dbfs.dbf file and erase the Dbfs.txt file.
*-- : This Dbfs.dbf file can be SCANned, or used in a POPUP PROMPT
*-- FIELD command, or in any way that you can imagine.
*-- : The file 'Dbfs.dbf' will not be included in the Dbfs.dbf file.
*-- WARNING===> : If your application includes a file with the name of
*-- 'Dbfs.dbf', it will be overwritten with the file created
*-- by this procedure.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 01/31/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: do ListDBFs
*-- Example.....: do ListDBFs
*-- Returns.....: None
*-- Parameters..: None
*-------------------------------------------------------------------------------
private cConsole
*-- Write the directory of dbf files to a text file (Dbfs.txt)
*-- First, erase the file if it exists
if file("Dbfs.txt")
erase dbfs.txt
endif
*-- And, erase the dbfs.dbf file if it exists (so won't be included
*-- in the list)
if file("Dbfs.dbf")
erase Dbfs.dbf
endif
*-- Now, write the dbfs.txt file
cConsole = set("CONSOLE")
set console off
list files to file dbfs.txt
set console &cConsole.
*-- Then, create the file DBFS.DBF
*-- Acknowledgement..: Bowen Moursund for the code that creates Dbfs.dbf
*-- (Download PRGCREAT.ZIP from BORBBS for more info.)
set printer to file DBFS.DBF
set printer on
??? "{3}{92}{2}{1}{0}{0}{0}{0}{65}{0}{13}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"+;
"{0}{0}{0}{0}{0}{0}{0}{0}{89}{0}{68}{66}{70}{0}{0}{0}{0}{0}{0}{0}{0}{67}{3}"+;
"{0}{44}{85}{12}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{13}{26}"
set printer to
set printer off
*-- Now, append dbfs.txt to dbfs.dbf if the record is a dbf listing.
use Dbfs
append from Dbfs.txt for ".DBF" $ Dbf type sdf
use && can remove this command if you want
erase Dbfs.txt && don't need it anymore
RETURN
*--EOP: ListDBFs
FUNCTION Recompile
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 71600,340)
*-- : Adapted from Compall.prg and Compall2.prg, by James Thomas.
*-- Date........: 06/10/1992
*-- Notes.......: Recompiles all dBASE source-code files. Takes three
*-- : optional parameters:
*-- : Directory to recompile. Default is current directory.
*-- : Skeleton to recompile. Default is all of .PRG, .LBG,
*-- : .FRG, .PRS, .FMT, .QBE and .UPD files. If a skeleton
*-- : is provided that matches files that are not dBASE
*-- : source-code files, compiler errors will occur and,
*-- : in the absence of external error handling, see below,
*-- : suspend processing.
*-- : "Runtime" or any characters starting with "R" or "r" to
*-- : direct the compilation be with the "RUNTIME" option.
*-- : Does not recompile a file if a file of the same root name,
*-- : an .??O extension and a later timestamp resides in the
*-- : directory.
*-- : Renames compilations of FMT, FRG, LBG and QBO files to ??O.
*-- : Returns .T. if successful, or .F.
*-- :
*-- : Listing of compilation errors requires SET ALTERNATE TO,
*-- : and trapping such errors as passing the name of a file
*-- : that does not contain dBASE source code to the COMPILE
*-- : command requires an ON ERROR trap. These are omitted here
*-- : due to lack of ways to prevent the function from changing
*-- : these settings externally. Lines needed to have any
*-- : compilation errors print to the alternate file are included
*-- : as comments.
*-- :
*-- Written for.: dBASE IV Version 1.5.
*-- : Adaptation to a prior release may require changing the
*-- : way parameters are handled, and also rewriting the lines
*-- : that use fdate() and ftime() to read timestamps.
*-- Rev. History: 04/07/1992 - original function.
*-- : 04/13/1992 - additional environment settings.
*-- : 04/16/1992 - aliases added thanks to BOWEN.
*-- : 06/10/1992 - a few minor bug fixes
*-- Calls : Makestru() FUNCTION in FILES.PRG
*-- Called by...: Any
*-- Usage.......: Recompile ( [<cDir>] [,<cSkel> [,"R"]] )
*-- Example.....: ? Recompile ( "\dBASE\Myprogs", "*.??G" )
*-- Parameters..: cDir, a DOS directory name ( and path if needed )
*-- : cSkel, skeleton using wildcards for files to compile
*-- : cRun, "R" or "r" if compilation is for Runtime
*-- Side effects: Creates compiled .??O files, overwriting any of the same
*-- : root names that may exist.
*-------------------------------------------------------------------------------
parameters cDirectry, cSkeleton, cRun
private cCons, cAlias, cAlt, cDir, cSafety, cTempfile,;
cSrcfile, cObjfile, cString1, cString2, cRunopt
* preserve environment
cCons = set( "CONSOLE" )
SET CONSOLE OFF
cAlias = alias()
cAlt = set( "ALTERNATE" )
SET ALTERNATE OFF
cDir = set( "DIRECTORY" )
IF type( "cDirectry" ) = "C" .AND. "" # cDirectry
SET DIRECTORY TO &cDirectry
ENDIF
cSafety = set( "SAFETY" )
SET SAFETY OFF
SELECT select()
* make temporary structure file and fill in the DOS DIR listing structure
cTempfile = Makestru()
USE ( cTempfile ) ALIAS cTempfile
APPEND BLANK
REPLACE FIELD_NAME WITH "FILENAME", FIELD_TYPE WITH "C", FIELD_LEN WITH 9, ;
FIELD_DEC WITH 0, FIELD_IDX WITH "N"
APPEND BLANK
REPLACE FIELD_NAME WITH "EXT", FIELD_TYPE WITH "C", FIELD_LEN WITH 4, ;
FIELD_DEC WITH 0, FIELD_IDX WITH "N"
APPEND BLANK
REPLACE FIELD_NAME WITH "FLENGTH", FIELD_TYPE WITH "C", FIELD_LEN WITH 10, ;
FIELD_DEC WITH 0, FIELD_IDX WITH "N"
APPEND BLANK
REPLACE FIELD_NAME WITH "TIMESTAMP", FIELD_TYPE WITH "C", FIELD_LEN WITH 16, ;
FIELD_DEC WITH 0, FIELD_IDX WITH "N"
* make .dbf for source file names, reset and return if error occurs
cSrcfile = cTempfile
DO WHILE file ( cSrcfile + ".DBF" )
cSrcfile = "TMP" + ltrim( str( rand() * 100000, 5 ) )
ENDDO
CREATE ( cSrcfile ) FROM ( cTempfile )
USE ( cSrcfile ) alias cSrcfile
IF "" = alias()
ERASE ( cTempfile +".DBF" )
SET DIRECTORY TO &cDir
SET ALTERNATE &cAlt
IF "" # cAlias
SELECT ( cAlias )
ENDIF
SET CONSOLE &cCons
RETURN .F.
ENDIF
* and for object file names
SELECT select()
USE ( cTempfile ) ALIAS cTempfile
GO 1
REPLACE FIELD_IDX WITH "Y"
cObjfile = cSrcfile
DO WHILE file ( cObjfile + ".DBF" )
cObjfile = "TMP" + ltrim( str( rand() * 100000, 5 ) )
ENDDO
CREATE ( cObjfile ) FROM (cTempfile)
use ( cObjfile ) alias cObjfile order filename
IF "" = alias()
ERASE ( cTempfile + ".DBF" )
SELECT cSrcfile
USE
ERASE ( cSrcfile + ".DBF" )
SET DIRECTORY TO &cDir
SET ALTERNATE &cAlt
IF "" # cAlias
SELECT ( cAlias )
ENDIF
SET CONSOLE &cCons
RETURN .F.
ENDIF
* reuse name of cTempfile as SDF; DIR names of source files to it and append
cString1 = cTempfile + ".DBF"
RUN dir *.* > &cString1
SELECT cSrcfile
APPEND FROM ( cString1 ) TYPE SDF
* delete directory entries not for source files of desired name or type
IF type("cSkeleton") = "C" .AND. "" # cSkeleton
DELETE ALL FOR .NOT. like( upper( cSkeleton ), trim( Filename ) +"." ;
+ trim( Ext ) )
ELSE
DELETE ALL FOR .NOT. Ext $ "PRG LBG FRG PRS FMT QBE UPD "
ENDIF
PACK
* reuse again for .??O files
RUN dir *.??o > &cString1
SELECT cObjfile
APPEND FROM ( cString1 ) TYPE SDF
DELETE ALL FOR left( Filename, 1 ) = " " .OR. right( Ext, 2 ) # "O "
PACK
ERASE ( cString1 )
* assemble Runtime option
cRunopt = iif( type( "cRun" ) = "C" .AND. "" # cRun ;
.AND. left( cRun, 1 ) $ "Rr", " RUNTIME", "" )
* now compile all the files that need it
SELECT cSrcfile
SCAN
cString1 = trim( Filename ) + "." + trim( Ext )
* Is there an object file of this name?
IF Seek( Filename, "cObjfile" )
cString2 = trim( cObjfile->Filename ) + "." + trim( cObjfile->Ext )
cString2 = dtos( fdate( cString2 ) ) + ftime( cString2 )
* then check timestamps and skip it if already compiled
IF dtos( fdate( cString1 ) ) + ftime( cString1 ) < cString2
LOOP
ENDIF
ENDIF
* compile it otherwise, listing errors if enabled
cString2 = cString1 + cRunopt
* SET ALTERNATE ON
* ? "Compiling " + cString2
COMPILE &cString2
* ?
* SET ALTERNATE OFF
* and rename object files that should not be .DBOs
IF Ext $ "FMT FRG LBG QBE "
cString2 = stuff( cString1, len( cString1 ), 1, "O" )
IF file( cString2 )
ERASE ( cString2 )
ENDIF
cString1 = trim( Filename ) + ".DBO"
RENAME ( cString1 ) TO ( cString2 )
ENDIF
ENDSCAN
* Clean up
USE
ERASE ( cSrcfile + ".DBF" )
SELECT cObjfile
USE
ERASE ( cObjfile + ".DBF" )
ERASE ( cObjfile + ".MDX" )
SET SAFETY &cSafety
SET DIRECTORY TO &cDir
SET ALTERNATE &cAlt
IF "" # cAlias
SELECT ( cAlias )
ENDIF
SET CONSOLE &cCons
RETURN .T.
*-- Eof() Recompile
PROCEDURE Makedbf
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 71600,340).
*-- Date........: 04/26/1992
*-- Notes.......: Makes an empty dBASE .dbf file
*-- Written for.: dBASE IV, 1.1, 1.5
*-- Rev. History: 04/26/1992 -- Original
*-- Calls.......: Tempname() function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: DO MakeDbf WITH <cFilename>, <cStrufile>, <cArray>
*-- Example.....: DO MakeDbf WITH Customers, cCustfields
*-- Parameters..: cFilename - filename ( without extension ) of the .dbf to be
*-- created.
*-- cStrufile - name ( without extension ) of a STRUC EXTE .dbf
*-- cArray - name of the array holding field information for the
*-- .dbf. The array must be dimensioned [ F, 5 ] where F is the
*-- number of fields. Each row must hold data for one field:
*-- [ F, 1 ] field name, character
*-- [ F, 2 ] field type, character from set "CDFLMN"
*-- [ F, 3 ] field length, numeric. If field type is
*-- D, L, or M, will be ignored
*-- [ F, 4 ] field decimals, numeric. optional if 0.
*-- [ F, 5 ] field is mdx tag, char $ "YN", optional if N
*-------------------------------------------------------------------------------
parameters cFname, cSname, aAname
private nX,cF1,cF2,cF3,cF4,cF5,cStrufile,cFtype
cF1 = aAname + "[nX,1]"
cF2 = aAname + "[nX,2]"
cF3 = aAname + "[nX,3]"
cF4 = aAname + "[nX,4]"
cF5 = aAname + "[nX,5]"
select select()
use ( cSname ) ALIAS cSname
zap
nX = 1
do while type( cF1 ) # "U"
cFtype = &cF2
append blank
replace Field_name with &cF1, Field_type with cFtype
do case
case cFtype = "D"
replace Field_len with 8
case cFtype = "M"
replace Field_len with 10
case cFtype = "L"
replace Field_len with 1
otherwise
replace Field_len with &cF3
endcase
if type( cF4 ) = "N" .and. cFtype $ "FN"
replace Field_dec with &cF4
else
replace Field_dec with 0
endif
if type( cF5 ) # "U" .and. cFtype $ "CDFN" .and. &cF5 = "Y"
replace Field_idx with "Y"
else
replace Field_idx with "N"
endif
nX = nX + 1
enddo
use
create ( cFname ) FROM ( cSname )
RETURN
*-- EoP: Makedbf
PROCEDURE MakeDBF2
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 02/22/1993
*-- Notes.......: Creates an empty DBF file of the structure specified in
*-- the array aMakeDBF[], which must be declared and initialized
*-- with the proper values before calling this procedure.
*-- The array must be declared as aMakeDBF[n,5], where n is
*-- the number of fields in the DBF to be created. The columns
*-- of the array correspond to the fields of a structure extended
*-- file, and must be initialized to the appropriate values,
*-- before calling this procedure, one row for each field.
*--
*-- Structure of a structure extended file:
*-- Field Type Len Dec
*-- -----------------------
*-- FIELD_NAME C 10 0
*-- FIELD_TYPE C 1 0
*-- FIELD_LEN N 3 0
*-- FIELD_DEC N 3 0
*-- FIELD_IDX C 1 0
*--
*-- aMakeDBF[n,1] = Field name: 10 or less characters
*-- aMakeDBF[n,2] = Field type: 1 character
*-- "C" = character
*-- "N" = numeric
*-- "F" = float
*-- "D" = date
*-- "L" = logical
*-- "M" = memo
*-- aMakeDBF[n,3] = Field length: numeric
*-- "C" = 1 - 254
*-- "N","F" = use dBASE guidelines
*-- "D" = 8
*-- "L" = 1
*-- "M" = 10
*-- aMakeDBF[n,4] = Decimal places: numeric
*-- 0 for non numeric fields
*-- aMakeDBF[n,5] = MDX flag: 1 char, "Y" or "N"
*--
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 05/27/1992 -- Original Release
*-- 02/22/1993 -- Minor changes to PRIVATE calls.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: do MakeDBF with <cDBFpath>,<cStruPath>
*-- Example.....: cStruPath = MakeStru2(.f.)
*-- declare aMakeDBF[1,5]
*-- aMakeDBF[1,1] = "FIELD1"
*-- aMakeDBF[1,2] = "C"
*-- aMakeDBF[1,3] = 20
*-- aMakeDBF[1,4] = 0
*-- aMakeDBF[1,5] = "N"
*-- do MakeDBF2 with "foo", cStruPath
*-- erase (cStruPath+".dbf")
*-- release aMakeDBF
*-- Returns.....: none
*-- Parameters..: cDBFpath = the [path]filename of the DBF to be created.
*-- cStruPath = the [path]filename of an empty structure extended
*-- file.
*-------------------------------------------------------------------------------
parameters cDBFpath,cStruPath
if pcount() = 2 && we need 2 parms
private cAlias
if type("aMakeDBF[1,1]") = "C" && check array validity
cAlias = alias()
select select()
use (cStruPath)
append from array aMakeDBF
use
create (cDBFpath) from (cStruPath)
use
if "" # cAlias
select (cAlias)
endif
endif
endif
RETURN
*-- EoP: MakeDBF2
FUNCTION Makestru
*-------------------------------------------------------------------------------
*-- Programmer..: Martin Leon (Hman), formerly sysop of A-T BBS
*-- : Revised by Jay Parsons, (CIS: 71600,340).
*-- Date........: 04/24/1992
*-- Notes.......: Makes an empty dBASE STRUCTURE EXTENDED file and returns
*-- : its root name
*-- Written for.: dBASE IV v1.5
*-- Rev. History: 06/12/1991 - original function.
*-- : Changed to take no parameter, return filename, 4-7-1992.
*-- : Code added to preserve catalog status and name, 4-10-1992.
*-- : Use of Tempname() added 4-24-92.
*-- : set("safety") check, minor mods, 05-28-1992, Bowen Moursund
*-- Calls : Tempname() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: Makestru()
*-- Example.....: Tempfile = Makestru()
*-- Returns.....: Name of file created
*-- Parameters..: None
*-------------------------------------------------------------------------------
private all
lTitleOn = ( set("TITLE") = "ON" )
lSafeOn = ( set("SAFETY") = "ON" )
lCatOff = ( set("CATALOG") = "OFF" )
cAlias = alias()
cTmpCat = TempName("cat") + ".CAT"
set title off
set safety off
cCatalog = catalog()
set catalog to (cTmpCat)
set catalog to &cCatalog.
cStruName = TempName("dbf")
select select()
use (cTmpCat) nosave
copy to (cStruName) structure extended
use (cStruName) exclusive
zap
use
if lTitleOn
set title on
endif
if lSafeOn
set safety on
endif
if lCatOff
set catalog off
endif
if "" # cAlias
select (cAlias)
endif
RETURN cStruname
*-- Eof: Makestru()
FUNCTION MakeStru2
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 05/27/1992
*-- Notes.......: Create an empty STRUCTURE EXTENDED file, using DBASE print
*-- redirection. If specified, the file will be created in the
*-- subdirectory pointed to by the DOS environment variable
*-- DBTMP, if it is set, otherwise in the current subdirectory.
*--
*-- Structure of a STRUCTURE EXTENDED file:
*-- Field Type Len Dec
*-- -----------------------
*-- FIELD_NAME C 10 0
*-- FIELD_TYPE C 1 0
*-- FIELD_LEN N 3 0
*-- FIELD_DEC N 3 0
*-- FIELD_IDX C 1 0
*--
*-- Written for.: dBASE IV v1.1
*-- Rev. History: 05/27/1992 -- Original
*-- Calls.......: TEMPNAME() Function in FILES.PRG
*-- Called by...: Any, except when printing
*-- Usage.......: MakeStru(<lDBTMP>)
*-- Example.....: cStruPath = MakeStru2(.T.)
*-- Returns.....: The name, no extension, of the file created.
*-- Parameters..: lDBTMP = create the file in the DBTMP subdirectory, or not.
*-- Side Effects: WARNING: Do not call when printing.
*-------------------------------------------------------------------------------
parameter lDBTMP
private all
cDBTMP = "" && TempName() will assign this, if lDBTMP
if lDBTMP
cFname = TempName( "dbf", .t. )
else
cFname = TempName( "dbf", .f. )
endif
cPath = iif( "" # cDBTMP, cDBTMP, set("DIRECTORY") ) + "\" + cFname + ".DBF"
dDate = date()
set printer to file (cPath)
set printer on
* Thanks to JPARSONS for the suggestion to document the header structure
??? "{3}" && various bit flags
??? chr(year(dDate)-1900) + chr(month(dDate)) + ;
chr(day(dDate)) && date bytes in YYMMDD format
??? "{0}{0}{0}{0}" && no. of records
??? "{193}{0}" && no. of bytes in header
??? "{19}{0}" && no. of bytes per record
??? "{0}{0}" && reserved
??? "{0}" && incomplete transaction flag
??? "{0}" && encryption flag
??? "{0}{0}{0}{0}{0}{0}{0}{0}{0}" + ;
"{0}{0}{0}" && multi-user reserved
??? "{0}" && MDX flag
??? "{0}{0}{0}" && reserved
* field descriptors
??? "{70}{73}{69}{76}{68}{95}{78}{65}{77}{69}{0}{67}{3}{0}{208}" + ;
"{72}{10}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Field_Name
??? "{70}{73}{69}{76}{68}{95}{84}{89}{80}{69}{0}{67}{13}{0}{208}" + ;
"{72}{1}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Field_Type
??? "{70}{73}{69}{76}{68}{95}{76}{69}{78}{0}{0}{78}{14}{0}{208}" + ;
"{72}{3}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Field_Len
??? "{70}{73}{69}{76}{68}{95}{68}{69}{67}{0}{0}{78}{17}{0}{208}" + ;
"{72}{3}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Field_Dec
??? "{70}{73}{69}{76}{68}{95}{73}{68}{88}{0}{0}{67}{20}{0}{208}" + ;
"{72}{1}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Field_Idx
??? "{13}{26}"
set printer to
set printer off
RETURN cFname
*-- Eof() MakeStru2
FUNCTION TempName
*-------------------------------------------------------------------------------
*-- Programmer..: Martin Leon (HMAN) Former Sysop, ATBBS
*-- Date........: 02/22/1993
*-- Notes.......: Obtain a name for a temporary file of a given extension
*-- that does not conflict with existing files.
*-- Written for.: dBASE IV, v1.5
*-- Rev. History: Originally part of Makestru(), 6-12-1991
*-- 04/26/92, made a separate function - Jay Parsons
*-- 05/27/92, added lDBTMP option - Bowen Moursund
*-- 02/22/93, Minor update to PRIVATE command.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: TempName( cExt , lDBTMP )
*-- Example.....: Sortfile = TempName( "DBF" , .t. )
*-- Returns.....: Name not already in use. Additionally, if the memvar
*-- cDBTMP is declared before calling the function with
*-- the lDBTMP option, it will be assigned the result
*-- of getenv("DBTMP").
*-- Parameters..: cExt = Extension to be given file ( without the "." )
*-- lDBTMP = Optional. If .t., function returns unique file
*-- name in the DBTMP subdirectory.
*-- Side Effects: The function will return a unique filename for the DEFAULT
*-- subdirectory if the lDBTMP option is used and the DOS
*-- environment variable DBTMP does not point to a valid
*-- subdirectory.
*-------------------------------------------------------------------------------
parameters cExt, lDBTMP
private cDefDir
cDefDir = set("DIRECTORY")
if lDBTMP
cDBTMP = getenv("DBTMP")
if "" # cDBTMP
set directory to &cDBTMP.
endif
endif
do while .t.
Fname = "TMP" + ltrim( str( rand() * 100000, 5 ) )
if .not. file( Fname + "." + cExt ) .and. ( upper( cExt ) # "DBF" .or.;
.not. ( file( Fname + ".MDX" ) .or. file ( Fname + ".DBT" ) ) )
exit
endif
enddo
set directory to &cDefDir.
RETURN Fname
*-- Eof() TempName
PROCEDURE FileMove
*-------------------------------------------------------------------------------
*-- Programmer..: David Frankenbach (FRNKNBCH)
*-- DF Software Development, Inc.
*-- PO Box 87
*-- Forest, VA, 24551
*-- (804) 237-2342
*-- Date........: 02/11/1992
*-- Notes.......: This procedure gives the record movement allowed with EDIT
*-- when you use a simple @SAY/GET..READ. It allows you to
*-- pre/post process each record during editing, something you
*-- can't do with EDIT. This works best with a single file,
*-- although it would work with a parent->child relation. You
*-- should: SELECT child and SET SKIP to child. This will
*-- allow the user to change the parent record pointer though!
*-- If you want to limit the child record movement to a single
*-- parent record, you can use a conditional index, or add logic
*-- to the routine to limit the record pointer movement. For these
*-- cases I have a seperate FileMove procedure, but they are not
*-- generic enough for public consumption.
*--
*-- These keys are trapped:
*-- UpArw, Shift-Tab, LeftArw, Ctrl-LeftArw, PgUp =
*-- backward one record
*-- DnArw, Tab, RightArw, Ctrl-RightArw, PgDn, Enter, Ctrl-End =
*-- forward one record
*-- Ctrl-PgUp = top of database or active index
*-- Ctrl-PgDn = bottom of database or active index
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 06/17/1991 - original routine.
*-- 02/07/1992 -- Ken Mayer, brought into one PROCEDURE,
*-- rather than a function and a procedure ...
*-- 02/11/1992 -- Author, additional documentation
*-- Released into Public Domain
*-- Calls.......: None
*-- Called by...: None
*-- Usage.......: do FileMove with <nKey>
*-- where: <nKey> is the return value of readkey()
*-- Example.....: lMove = .t. && if you want the user to be able to move the
*-- && record pointer in my applications if the user
*-- && is adding a new record I usually lMove = .f.,
*-- && for editing I allow them to move through the
*-- && records.
*-- lOk = .t.
*-- do while ( lOk )
*-- do Mem_Load && load memvars from record
*-- @say/gets && display/get the memvars
*-- read
*-- i = readkey() && grab last key ...
*-- lOk = ( i <> 27 ) && if Esc was pressed lOK is false
*-- if ( lOk )
*-- if ( i > 256 ) && if record is changed
*-- do Mem_Unload && replace dbf fields from memvars
*-- endif && ( i > 256 )
*-- if ( lMove ) && if ok to move record pointer
*-- do FileMove with i && <----- Move it
*-- else
*-- lOk = .f. && terminate loop if .not. lMove
*-- endif && ( lMove )
*-- endif && (lOK)
*-- enddo && while (lOK)
*-- Parameters..: nKey = last keystroke from a READKEY() call ...
*-- Returns.....: None
*-- Side Effects: Moves record pointer in current file if lMove = .t.
*-------------------------------------------------------------------------------
parameter nKey
private n
m->n = m->nKey
if ( m->n > 255 ) && if value is > 256, record has changed, but we want
m->n = m->n - 256 && values < 256 to figure out which direction to move
endif && from the readkey() table
do case
*-- keys to move backward through database 1 record at a time ...
*-- LeftArw, Ctrl-LeftArw, UpArw, Shift-Tab, PgUp
case ( m->n = 0 ) .or. ( m->n = 2 ) .or. ( m->n = 4 ) .or. ( m->n = 6 )
if ( .not. bof() ) && if not at beginning of file
skip -1 && move backward one record
endif
*-- keys to move forward through database 1 record at a time ...
*-- RightArw, Ctrl-RightArw, DownArw, Tab, PgDn, Ctrl-End, Enter
case ( m->n = 1 ) .or. ( m->n = 3 ) .or. ( m->n = 5 ) .or. ( m->n = 7 );
.or. ( m->n = 14) .or. ( m->n = 15)
if ( .not. eof() ) && if not end of file
skip 1 && move forward one record
endif
if ( eof() ) && if we're now at the EOF,
goto bottom && go back to last record ...
endif
*-- go to toP of database, Ctrl-PgUp
case ( m->n = 34 )
goto top
*-- go to BOTtoM of database, Ctrl-PgDn
case ( m->n = 35 )
goto bottom
endcase
RETURN
*-- EoP: FileMove
FUNCTION Used
*-------------------------------------------------------------------------------
*-- Programmer..: Ken Mayer (CIS: 71333,1030)
*-- Date........: 02/28/1992
*-- Notes.......: Created because the picklist routine by Malcolm Rubel
*-- from DBA Magazine (11/91) calls a function that checks
*-- to see if a DBF file is open ...
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 05/15/1992 -- Original
*-- 02/08/1993 -- Discovered (thanks to Jay, and then Malcolm)
*-- a much simpler way to do this ...
*-- Called by...: Any
*-- Calls.......: None
*-- Usage.......: Used("<cFile>")
*-- Example.....: if used("Library")
*-- select library
*-- else
*-- select select()
*-- use library
*-- endif
*-- Returns.....: Logical (.t. if file is in use, .f. if not)
*-- Parameters..: cFile = file to check for
*-------------------------------------------------------------------------------
parameters cFile
RETURN (select(cFile) # 0)
*-- EoF: Used()
FUNCTION MDXbyte
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 05/21/1992
*-- Notes.......: Sets the MDX byte in a DBF header ON or OFF.
*-- The DBF must not be open when the function is called.
*-- Written for.: dBASE IV v1.5
*-- Rev. History: 05/21/1992 -- Original
*-- Calls.......: dBASE low level file functions
*-- Called by...: Any
*-- Usage.......: MDXbyte(<cDBFpath>,<cOnOff>)
*-- Example.....: lByteSet = MDXbyte("mydbf.dbf","OFF")
*-- Returns.....: .T. if successful
*-- Parameters..: cDBFpath = the [path]filename.ext of the DBF
*-- cOnOff = "ON" or "OFF"
*-------------------------------------------------------------------------------
parameters cDBFpath,cOnOff
private all
cOnOff = upper(cOnOff)
* check the validity of the parameters
lSuccess = ( pcount() = 2 .AND. cOnOff $ "ON|OFF" .AND. file(cDBFpath) )
if lSuccess
nHandle = fopen(cDBFpath,"RW")
if nHandle > 0
if fseek(nHandle, 28) = 28
lSuccess = ( fwrite(nHandle, iif(cOnOff="OFF",chr(0),chr(1))) = 1 )
else
lSuccess = .F.
endif
lClosed = fclose(nHandle)
else
lSuccess = .F.
endif
endif
RETURN lSuccess
*-- Eof() MDXbyte
FUNCTION aDir
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 02/22/1993
*-- Notes.......: aDir() creates a public array gaDir[ n, 5 ] containing
*-- directory information. gaDir[ n, 5 ] is limited to 234
*-- rows (files) or less, depending on the memory available.
*--
*-- Structure of 2D array gaDir[ n, 5 ]:
*--
*-- Col Contents Type Width
*-- ------------------------------------------
*-- 1 File Name Character 12
*-- 2 Date (mm/dd/yy) Date 8
*-- 3 Time (hh:mm:ss) Character 8
*-- 4 Size (bytes) Numeric 10
*-- 5 Attributes Character 6
*--
*-- aDir() makes use of SEARCH.BIN, and credit is due its
*-- author (Roland Boucherau, Borland Technical Support).
*-- See SEARCH.ASM or SEARCH.TXT source for details.
*-- *****************************
*-- **** REQUIRES SEARCH.BIN ****
*-- *****************************
*-- Written for.: dBASE IV, v1.5
*-- Rev. History: 07/24/1992 -- Original Release
*-- 02/22/1993 -- Minor Update to PRIVATE call.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: adir( <cFMask>, <cBINpath>, <cAttr> )
*-- Examples....: nFiles = adir( "d:\app\fu*.db?", "d:\dbase4\library\", "" )
*-- nFiles = adir( cPathSkel )
*-- nFiles = adir( "c:\*.*", "", "RHSD" )
*-- Returns.....: Number of matching files found: rows in gaDir[]
*-- Parameters..: cPathSkel = the directory path and file skeleton that you
*-- want, like the DOS DIR command. Wildcards OK.
*-- cBINpath = Optional path to Search.Bin. If omitted,
*-- Search.Bin must be in current subdirectory.
*-- Include the trailing backslash.
*-- cAttr = Optional file attribute mask string.
*--
*-- Mask Codes
*-- ------------
*-- R - Read Only
*-- H - Hidden
*-- S - System
*-- D - Directory
*-- V - Volume
*-- A - Archive
*--
*-- If cAttr is omitted, null, or blank, gaDir[] will
*-- contain only 'ordinary' files, i.e. files without
*-- HSDV attributes. If V is specified in the mask,
*-- ONLY volume labels are matched. Any other attribute
*-- or combination of attributes results in those files
*-- AND ordinary files being matched.
*-------------------------------------------------------------------------------
parameters cPathSkel, cBINpath, cAttr
private cModule,cAttr,cFSkel,cFName,cFDate,cFTime,cFSize,cFAttr,;
nMaxRows,nFCount,nResult,n
cModule = iif( pcount() >= 2, cBINpath + "search.bin", "search.bin" )
store upper( iif( pcount() >= 3, left( cAttr + " ", 6 ), " " ) ) ;
to cAttr, cFAttr
cFSkel = left( cPathSkel + space(12), max( len( cPathSkel ), 12 ) )
cFName = cFSkel
* ( memory() * 3.4 ) is a guess on max rows before 'Insufficient Memory'
nMaxRows = min( memory() * 3.4, 234 ) && 234 is the absolute maximum
nFCount = 0
load ( cModule )
nResult = call( "Search", 1, cFName, cAttr )
if nResult = 0
do while nResult = 0 .and. nFCount <= nMaxRows
nFCount = nFCount + 1
nResult = call( "Search" , 2, cFName )
enddo
nFCount = min( nMaxRows, nFCount )
release gaDir
public array gaDir[ nFCount, 5 ]
cFName = cFSkel
cFDate = " / / "
cFTime = " : : "
nFSize = 0
n = 1
nResult = ;
call( "Search", 1, cFName, cFAttr, cFDate, cFTime, nFSize )
do while nResult = 0 .AND. n <= nFCount
store cFName to gaDir[ n, 1 ]
store ctod( cFDate ) to gaDir[ n, 2 ]
store cFTime to gaDir[ n, 3 ]
store nFSize to gaDir[ n, 4 ]
store cFAttr to gaDir[ n, 5 ]
nResult = ;
call( "Search", 2, cFName, cFAttr, cFDate, cFTime, nFSize )
n = n + 1
enddo
else
release gaDir
endif
release module Search
RETURN nFCount
*-- EoF: aDir()
FUNCTION DbfDir
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 07/03/1992
*-- Notes.......: DbfDir() creates or OVERWRITES DdbDir.Dbf, and populates
*-- it with directory information. The function uses the DOS
*-- 5.0 DIR command and requires DOS 5.0.
*--
*-- Structure of DBFDIR.DBF
*-- -----------------------
*-- Field Type Len Dec
*-- F_NAME C 12 0
*-- F_DATE D 8 0
*-- F_TIME C 8 0
*-- F_SIZE N 10 0
*-- *********************************************************
*-- * DO NOT CALL THIS ROUTINE WHILE PRINTING (the function *
*-- * uses Print Redirection ...) *
*-- *********************************************************
*-- Written for.: dBASE IV v1.5, DOS 5.0
*-- Rev. History: 07/03/1992 -- Original
*-- Calls.......: TempName() Function in FILES.PRG
*-- Called by...: None
*-- Usage.......: DbfDir( "<cPathSkel>", <lHidSys> )
*-- Examples....: nFiles = DbfDir( "*.dbf" )
*-- nFiles = DbfDir( "*.dbf", .t. )
*-- Returns.....: Number of matching files found: reccount() of DbfDir.dbf
*-- Parameters..: cPathSkel = the directory path and file skeleton that you
*-- want, like the DOS DIR command. Wildcards OK.
*-- lHidSys = Optional. If .t., hidden & system files
*-- are included.
*-------------------------------------------------------------------------------
parameters cPathSkel, lHidSys
private all
cDBTMP = ""
cTmpFile = tempname( "txt", .t. ) + ".txt"
cTmpFile = iif( "" = cDBTMP, cTmpFile, cDBTMP + "\" + cTmpFile )
cDirParms = iif( lHidSys, "/B/A-D/ON", "/B/A-D-H-S/ON" )
run dir &cPathSkel. &cDirParms. > &cTmpFile.
nFiles = 0
if fsize( cTmpFile ) > 0
lSafeOn = ( set( "safety" ) = "ON" )
set safety off
set printer to file DbfDir.dbf && create DbfDir.dbf
set printer on
* first byte of header - various bit flags
??? "{3}"
* next 3 bytes - file date in binary YYMMDD
??? chr(year(date())-1900) + chr(month(date())) + chr(day(date()))
* the rest of the header, field descriptors, and records if any
??? "{0}{0}{0}{0}{161}{0}{39}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"+;
"{0}{0}{0}{0}{0}{0}{0}{1}{1}{70}{95}{78}{65}{77}{69}{0}{0}{0}{0}{0}"+;
"{67}{0}{0}{0}{0}{12}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"+;
"{70}{95}{68}{65}{84}{69}{0}{0}{0}{0}{0}{68}{0}{0}{0}{0}"
??? "{8}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{70}{95}{84}"+;
"{73}{77}{69}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}{8}{0}{0}{0}{0}{0}{0}"+;
"{0}{0}{0}{0}{0}{0}{0}{0}{0}{70}{95}{83}{73}{90}{69}{0}{0}{0}{0}{0}"+;
"{78}{0}{0}{0}{0}{10}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
??? "{0}{0}{0}{13}{26}"
set printer to
set printer off
cAlias = alias()
select select()
use DbfDir
append from ( cTmpFile ) sdf
goto top
cPath = parspath( cPathSkel )
scan
replace f_size with fsize( cPath + f_name ),;
f_date with fdate( cPath + f_name ),;
f_time with ftime( cPath + f_name )
endscan
nFiles = reccount()
use
if lSafeOn
set safety on
endif
if "" # cAlias
select ( cAlias )
endif
endif
erase ( cTmpFile )
RETURN nFiles
*-- EoF: DBFDir()
FUNCTION ParsPath
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 07/16/1992
*-- Notes.......: ParsPath() extracts and returns the path from a
*-- full path file specification.
*-- Written for.: dBASE IV v1.1
*-- Rev. History: 07/16/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: ParsePath( "<cFullPath>" )
*-- Example.....: set fullpath on
*-- cDBF = dbf()
*-- cPath = ParsPath( cDBF )
*-- Returns.....: The path only, including the trailing backslash,
*-- of the full path file specification
*-- Parameters..: cFullPath = a full path file spec, e.g. "c:\dbase\dbase.exe"
*-------------------------------------------------------------------------------
parameter cFullPath
private all
cPath = ""
if "\" $ cFullPath
nPos = 1
do while left( right ( cFullPath, nPos ), 1 ) # "\"
nPos = nPos + 1
enddo
cPath = substr( cFullPath, 1, len( cFullPath ) - nPos + 1)
endif
RETURN cPath
*-- EoF: ParsPath()
PROCEDURE TagPop
*-------------------------------------------------------------------------------
*-- Programmer..: Ken Mayer (CIS: 71333,1030)
*-- Date........: 09/08/1992
*-- Notes.......: Used to bring up a list of MDX tags on screen for the user,
*-- so they can change the current tag ... This is based on an
*-- article by Susan Perschke and Mike Liczbanski in "Data Based
*-- Advisor", December, 1991, and another by Malcom C. Rubel,
*-- Data Based Advisor, September, 1992.
*-- The idea is to bring up a picklist of all MDX tags for
*-- the current database file, showing the tag name, and
*-- expression, as well as whether or not it's unique, has a
*-- FOR clause, and whether it's ascending or descending ...
*-- However, as an additional bonus, if the user selects one
*-- of the MDX tags, the current tag is changed to the one the
*-- user selects. The tag with a "*" by it is the current tag.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 09/08/1992 -- Version 1
*-- 09/21/1992 -- Version 1.1 -- added more docs and removed
*-- reference to parameters of which there are
*-- none ... (changed my mind)
*-- Calls.......: SHADOW Procedure in PROC.PRG
*-- CENTER Procedure in PROC.PRG
*-- Called by...: Any
*-- Usage.......: DO TagPop
*-- Example.....: ON KEY LABEL F8 DO TagPop
*-- Returns.....: None (well, ok -- it resets the MDX tag if you select one)
*-- Parameters..: None
*-------------------------------------------------------------------------------
private nBar, cPrompt, cBorder, cTag, nTag, nTagTotal, cFor, cUnique,;
cDir, cKey
*-- Disable left/right arrow keys to prevent an accidental exit
on key label leftarrow ?? chr(7)
on key label rightarrow ?? chr(7)
*-- Save current screen
save screen to sTag
cBorder = set("BORDER")
activate screen
*-- define the screen/window
define window wTagPop from 5,2 to 20,77 double
activate screen
do shadow with 5,2,20,77
activate window wTagPop
*-- check to see if there are any tags ... or an active database ...
if isblank(alias()) .or. isblank(tag(1))
*-- if not, display appropriate error message
if isblank(alias())
do center with 1,75,"","** No active Database ... **"
else
do center with 1,75,"","** No active .MDX file for this .DBF **"
endif
x=inkey(0) && wait for user to press a key ...
else && we DO have an active database AND active MDX file
*-- headings
do center with 0,75,"","Select new MDX Tag"
@2,1 say "Name"
@2,10 say "For"
@2,14 say "Unq"
@2,18 say "Seq"
@2,22 say "Expression"
@3,1 say replicate(chr(196),72) && ─
*-- popup will display here
*-- footings (as it were)
@10,1 say replicate(chr(196),72) && ─
@11,3 say chr(251)+" in 'For' column means there is a 'For' clause"
@12,3 say chr(251)+" in 'Unq' column means the tag is set to 'Unique'"
@13,3 say chr(24)+" in 'Seq' means tag is 'Ascending', "+;
chr(25)+" means tag is descending"
*-- define the popup
set border to none && no border for popup
define popup pTag from 3,0 to 10,73;
message " Press ENTER to select new index order ... ESC to exit ..."
nBar = 1 && first bar
*-- place a * if no tag is currently active
cPrompt = iif(TagNo()=0,"*"," ")+" No Index" && bar 1 will always be this
cPrompt = cPrompt + space(11)+"(Natural Order)"
nTag = 0
*-- loop to get the rest of 'em ...
nTagTotal = tagcount() && get total number of tags
do while nTag <= nTagTotal && loop until no more tags
define bar nBar of pTag prompt (cPrompt)
nTag = nTag + 1
cDefault = iif(TagNo() = nTag,"*"," ") && if current tag ...
*-- the fun part of all this is getting the spacing "just right"
*-- that's what all the IIF( ....,space(...)) stuff is about
cTag = tag(nTag)+iif(len(tag(nTag))<9,space(9-len(tag(nTag))),"")
cFor = iif(isblank(for(nTag))," ",chr(251))
cUnique = iif(unique(nTag),chr(251)," ")
cDir = iif(descending(nTag),chr(25),chr(24)) && up/down arrows ...
cKey = iif(len(key(nTag))>57,left(key(nTag),52)+" ...",key(nTag))
cKey = iif(len(cKey)<57,cKey+space(57-len(cKey)),cKey)
*-- here's the actual definition of the bars ...
cPrompt = cDefault+cTag+" "+cFor+" "+cUnique+" "+cDir+" "+cKey
nBar = nBar + 1
enddo
*-- turn it off when an item's been selected (or <Esc> was pressed)
on selection popup pTag deactivate popup
*-- do it
activate popup pTag
*-- Don't change index order if ESC pressed
if bar() <> 0
*-- Assign a null string to cPrompt if "No Index" selected
cPrompt = iif(bar() = 1, "",tag(bar()-1))
set order to (cPrompt)
endif
*-- cleanup
release popup pTag
set border to &cBorder
endif
deactivate window wTagPop
release window wTagPop
restore screen from sTag
release screen sTag
*-- re-enable left/right arrow keys
on key label leftarrow
on key label rightarrow
RETURN
*-- EoP: TagPop
FUNCTION AAppend
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Appends a text file into an array. This routine is limited to
*-- text files of 1,170 lines, and 254 characters per line.
*-- The text file must be an ASCII Txt formatted file. Taken from
*-- Technotes, April, 1992.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TextLine() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: AAppend(<cFileName>,<aArrayName>)
*-- Example.....: ?AAppend("CONFIG.DB","aConfig")
*-- Returns.....: .T.
*-- Parameters..: cFileName = Name of DOS Text file to read into array
*-- aArrayName = Name of array to create. If it already exists,
*-- this array will be destroyed and overwritten.
*-------------------------------------------------------------------------------
parameters cFileName, aArrayName
private aTArray, nLines, nX, nHandle
*-- assign array name to a temp variable name ...
aTArray = aArrayName
*-- if it exists, get rid of it, and then re-define it
release &aTArray
public &aTArray
nLines = TextLine(cFileName) && get number of lines
declare &aTArray[min(nLines,1170)]
*-- get file handle
nHandle = fopen(cFileName)
*-- store the file into the array
nX = 1
do while nX <= nLines
store fgets(nHandle,254) to &aTArray[nX]
nX = nX + 1
enddo
*-- close the file
nHandle = fClose(nHandle)
RETURN .T.
*-- EoF: AAppend()
FUNCTION FDel
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Deletes a given portion of a file. Taken from TechNotes,
*-- April, 1992
*-- Used to delete a portion of a file (text or binary) from
*-- the beginning of the file, the end of file or current pointer
*-- position. This routine accomplishes it's task by writing the
*-- data you want to keep to a temp file, then overwriting
*-- the data you no longer want with the temp file. If you are on
*-- a network, make sure that you set TMP (or DBTMP) to either
*-- a local drive, or one where you have full rights.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TempFile() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: FDel(<nHandle>,<nBytes>,<nStart>)
*-- Example.....: nOpen = fopen("TEXT.TXT","RW")
*-- ?FDel(nOpen,1000,1)
*-- Returns.....: Logical
*-- Parameters..: nHandle = file handle number, as returned by FOPEN
*-- nBytes = number of characters (bytes) to delete in file
*-- nStart = starting position, where:
*-- 0 is the beginning of the file
*-- 1 is the current file pointer position
*-- 2 is the end of the file
*-------------------------------------------------------------------------------
parameters nHandle, nBytes, nStart
private nTemp,cTemp,nSave,nSeek,nRead,nWrite,lFlush,nClose
*-- create a temporary file
cTemp = tempfile("ADM")
*-- save current position in file
nSave = fseek(nHandle,0,1)
do case
case nStart = 0 && beginning of file
nSeek = fseek(nHandle,nBytes,0)
nTemp = fcreate(cTemp)
do while .not. feof(nHandle)
nRead = fread(nHandle,254)
nWrite = fwrite(nTemp,nRead)
lFlush = fflush(nTemp)
enddo
nSeek = fseek(nTemp,0,0)
nSeek = fseek(nHandle,0,0)
do while .not. feof(nTemp)
nRead = fread(nTemp,254)
nWrite = fwrite(nHandle,nRead)
lFlush = fflush(nHandle)
enddo
nWrite = fwrite(nHandle,chr(0),0)
nClose = fclose(nTemp)
nSeek = fseek(nHandle,nSave,0)
case nStart = 1 && Current Location
*-- skip these bytes
nSeek = fseek(nHandle,nDelete,1)
*-- write the rest to a temp file
nTemp=fCreate(cTemp)
do while .not. feof(nHandle)
nRead = fread(nHandle,254)
nWrite = fwrite(nTemp,nRead)
lFlush = fflush(nTemp)
enddo
nSeek = fseek(nTemp,0,0)
nSeek = fseek(nHandle,nSave,0)
nWrite = fwrite(nHandle,chr(0),0)
do while .not. feof(nTemp)
nRead = fread(nTemp,254)
nWrite = fwrite(nHandle,nRead)
lFlush = fflush(nHandle)
enddo
nSeek = fseek(nHandle,nSave,0)
nClose = fclose(nTemp)
case nStart = 2 && End of File
nSeek = fseek(nHandle,-1*abs(nDelete),2)
nWrite = fwrite(nHandle,chr(0),0)
endcase
erase (cTemp)
RETURN (ferror() = 0)
*-- EoF: FDel()
FUNCTION FGetLine
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Used to extract a line of text from a text file.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TLine() Function in FILES.PRG
*-- TLineNo() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: FGetLine(<cFileName>,<cLookup>,[<lCase>],[<lEntire>])
*-- Example.....: ?FGetLine("config.db","command",.f.,.f.)
*-- Returns.....: A character expression
*-- Parameters..: cFileName = Name of file to extract text from
*-- cLookup = Text to look for
*-- lCase = Case sensitive? (Logical = .t. or .f.)
*-- If empty, default is .F.
*-- lEntire = Return entire line, or the rest of the line
*-- .t. = return the entire line
*-- .f. = return everything following cLookup
*-- If empty, default is .t.
*-------------------------------------------------------------------------------
parameters cFileName, cLookup, lCase, lEntire
private nLine, cText
*-- defaults
lCase = iif(pcount() <= 2,.f.,lCase)
lEntire = iif(pcount() <=3,.t.,lEntire)
*-- get the line ...
nLine = TLineNo(cFile,cLookup,lCase)
cText = iif(nLine<=0,"",TLine(cFile,nLine,lCase))
cResult = upper(cText)
RETURN iif(lEntire,cText,substr(cText,at(upper(cLookup),cResult)+len(cLookup)))
*-- EoF: FGetLine()
FUNCTION FIns
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Inserts specified number of NULLS into a low-level file.
*-- Taken from Technotes, April, 1992. FIns() works the way
*-- FDel() works, but in reverse. See comments in FDel about
*-- temp directory ...
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TempFile() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: FIns(<nHandle>,<nBytes>,<nStart>)
*-- Example.....: nOpen = fopen("TEST.TXT","RW")
*-- ?FIns(nOpen,10,1)
*-- Returns.....: Logical
*-- Parameters..: nHandle = File Handle from FOPEN() function
*-- nBytes = Number of nulls to insert into file
*-- nStart = Location in file to start at, where:
*-- 0 = Beginning of file
*-- 1 = Current file pointer
*-- 2 = End of file
*-------------------------------------------------------------------------------
parameters nHandle, nBytes, nStart
private nTemp, cTemp, nSave, nRead, nWrite, nSeek, lFlush, nX, nClose
cTemp = TempFile("ADM") && create temp file
nSave = fseek(nHandle,0,1) && save current position
do case
case nStart = 0 && beginning of file
nTemp = fcreate(cTemp)
nX = 1
do while nX <= nBytes
nWrite = fwrite(nTemp,chr(0),1)
nX = nX + 1
enddo
nSeek = fseek(nHandle,0,0)
do while .not. feof(nHandle)
nRead = fread(nHandle,254)
nWrite = fwrite(nTemp,nRead)
lFlush = fflush(nTemp)
enddo
nSeek = fseek(nTemp,0,0)
nSeek = fseek(nHandle,0,0)
do while .not. feof(nTemp)
nRead = fread(nTemp,254)
nWrite = fwrite(nHandle,nRead)
lFlush = fflush(nHandle)
enddo
nWrite = fwrite(nHandle,chr(0),0)
nclose = fclose(ntemp)
nSeek = fseek(nHandle,0,0)
case nStart = 1 && current location
*-- write the rest to a temp file
nTemp = fcreate(cTemp)
do while .not. feof(nHandle)
nRead = fread(nHandle,254)
nWrite = fwrite(nTemp,nRead)
lFlush = fflush(nTemp)
enddo
nSeek = fseek(nHandle,nSave,0)
nX = 1
do while nX <= nBytes
nWrite = fWrite(nHandle,chr(0),1)
nX = nX + 1
enddo
nSeek = fseek(nTemp,0,0)
do while .not. feof(nTemp)
nRead = fread(nTemp,254)
nWrite = fwrite(nHandle,nRead)
lFlush = fflush(nHandle)
enddo
nSeek = fseek(nHandle,nSave,0)
nClose = fclose(nTemp)
case nStart = 2 && End of File
nSeek = fseek(nHandle,0,2)
nX = 1
do while nX <= nBytes
nWrite = fwrite(nHandle,chr(0),1)
nX = nX + 1
enddo
endcase
erase (cTemp)
RETURN (ferror() = 0)
*-- EoF: FIns()
FUNCTION GetInfo
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: This retrieves information from STATUS that you cannot get
*-- with the dBASE IV function SET(). See 'parameters' below for
*-- list of keywords.
*-- CAUTION: If you have ALTERNATE set, you need to reset it after
*-- the function executes. SET ALTERNATE TO must be used instead
*-- of LIST STATUS TO filename, since the print destination
*-- would always show as a file. All results that are returned
*-- are returned as character types, including ones that
*-- return numbers (use VAL() to look at/use returned value as
*-- a number).
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TempFile() Function in FILES.PRG
*-- TextLine() Function in FILES.PRG
*-- AAppend() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: GetInfo(<cKeyWord>,[<cKeyWord2>])
*-- Example.....: ? GetInfo("F5")
*-- Returns.....: Character expression
*-- Parameters..: cKeyWord = Item you are looking for status of, options
*-- listed return the following:
*-- WORK Number of work area you are currently
*-- in - whether or not a database is in use.
*-- PRINT Current printer destination where output
*-- is directed (PRN, NUL, LPT1, COM1) as
*-- set by SET PRINTER TO.
*-- ERROR The error condition set by ON ERROR
*-- ESCAPE The escape condition set by ON ESCAPE
*-- F2 to F10, Ctrl-F1 to Ctrl-F10, Shift-F1 to
*-- Shift-F10
*-- The current setting of each key as set
*-- by SET FUNCTION <label> TO
*-- **** The following require a second paramter
*-- (cKeyWord2 ...)
*-- PAGE,LINE Line number specified by
*-- ON PAGE AT LINE
*-- in the page handling routine
*-- HANDLE,<filename> The handle number of the low-
*-- level file specified by <filename>
*-- NAME,<filehandle> The file name of the low-level
*-- file specified by <filehandle>
*-- MODE,<filehandle> The privilege of the low-level
*-- file specified by <filehandle>
*-- cKeyWord2 = see list above ...
*-------------------------------------------------------------------------------
parameters cKeyWord, cKeyWord2
private cKey, l2Parms, cStart, cSafety, cTempTxt, nLines, cTmpArray
cKey = upper(cKeyWord)
l2Parms = (pcount() = 2)
do case
case cKey = "CTRL-" .or. cKey = "SHIFT" .or. ;
(","+cKey+"," $ ",F2,F3,F4,F5,F6,F7,F8,F9,F10,")
cStart = cKey + space(9 - len(cKey))+"-"
case cKey = "PRINT"
cStart = "Print Destination:"
case cKey = "WORK"
cStart = "Current work area ="
if "" <> dbf()
RETURN select(alias())
endif
case cKey = "ERROR"
cStart = "On Error:"
case cKey = "ESCAPE"
cStart = "On Escape:"
case cKey = "PAGE"
cStart = "On Page At Line"
case cKey = "HANDLE" .or. cKey = "NAME" .or. cKey = "MODE"
cStart = "Low level files opened"
otherwise && none of the above
RETURN ""
endcase
cSafety = set("SAFETY")
cTempTxt = TempFile()
*-- get status info (into a temp file), which will then be parsed to extract
*-- information requested ...
set console off
set alternate to &cTempTxt. && create file without extension
set alternate on
list status
close alternate
set console on
nLines = TextLine(cTempTxt)
aTmpArray = right(cTempTxt,8)
cTmp = AAppend(cTempTxt,aTmpArray)
nHandle = fopen(cTempTxt,"R")
cResult = ""
nX = 1
do while nX <= nLines
if left(&aTmpArray[nX],len(cStart)) = cStart
cResult = ltrim(substr(&aTmpArray[nX],len(cStart)+1))
exit
endif
nX = nX + 1
enddo
*-- 2 parameters?
if l2Parms .and. "" # cResult
do case
case cKey = "PAGE"
if upper(cKeyWord2) = "LINE"
cResult = left(cResult,at(" ",cResult) - 1)
else
cResult = substr(cResult,at(" ",cResult) + 1)
endif
case cKey = "HANDLE" .or. cKey = "NAME" .or. cKey = "MODE"
cResult = ""
nX = nX + 2
do while val(&aTmpArray[nX]) <> 0
do case
case cKey = "HANDLE" .and. upper(cKeyWord2) $ &aTmpArray[nX]
cResult = str(val(&aTmpArray[nX]))
case cKey = "NAME" .and. cKeyWord2 = val(&aTmpArray[nX])
cResult = substr(&aTmpArray[nX],10,40)
case cKey = "MODE" .and. cKeyWord2 = val(&aTmpArray[nX])
cResult = substr(&aTmpArray[nX],50,5)
endcase
if "" <> cResult
exit
endif
nX = nX + 1
enddo
endcase
endif
relase &aTmpArray
nClose = fclose(nHandle)
set safety off
erase (cTempTxt)
set safety &cSafety
cResult = ltrim(rtrim(cResult))
RETURN iif(right(cResult,1) = ":",;
left(cResult,len(cResult-1)),cResult)
*-- EoF: GetInfo()
FUNCTION TextLine
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Returns the number of lines of text in an ASCII Text File
*-- Taken from TechNotes, April, 1992
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: TextLine(<cTextFile>)
*-- Example.....: ?TextLine("CONFIG.DB")
*-- Returns.....: Number of lines
*-- Parameters..: cTextFile = name of file
*-------------------------------------------------------------------------------
parameter cTextFile
private nLines, nHandle, cTemp, nClose
nLines = 0
if file(cTextFile) && if it exists ...
nHandle = fopen(cTextFile,"R")
do while .not. feof(nHandle)
cTemp = fgets(nHandle,254)
nLines = nLines + 1
enddo
nClose = fclose(nHandle)
endif
RETURN nLines
*-- EoF: TextLine()
FUNCTION TLine
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Returns a specific line in an ASCII Text File. This is similar
*-- to the way MLINE() works on a memo field. Taken from TechNotes
*-- April, 1992.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: TLine(<cTextFile>,<nLine>)
*-- Example.....: ?TLine("CONFIG.DB",20)
*-- Returns.....: Character expression - specified line of text file.
*-- Parameters..: cTextFile = name of text file
*-- nLine = line to return from text file
*-------------------------------------------------------------------------------
parameters cTextFile, nLine
private cText, nX, nHandle, nClose
cText = ""
nX = 1
if file(cTextFile) && if file exists ...
nHandle = fopen(cTextFile,"R")
do while .not. feof(nHandle)
cText = fgets(nHandle,254)
if nX = nLine
exit
endif
nX = nX + 1
enddo
nClose = fclose(nHandle)
endif
RETURN cText
*-- EoF: TLine()
FUNCTION TLineNo
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Returns the line number of the phrase you are searching for
*-- in an ASCII Text File. This is similar to dBASE's AT()
*-- function, but works on LINES rather than CHARACTERS.
*-- Taken from TechNotes, April, 1992
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: TLineNo(<cTextFile>,<cLookup>,[<lCase>])
*-- Example.....: ?TLineNo("CONFIG.DB","command",.f.)
*-- Returns.....: numeric value (the line number containing the line needed)
*-- returns -1 if not found
*-- Parameters..: cTextFile = Name of ASCII Text File
*-- cLookup = Text to search for ...
*-- lCase = Case Sensitive? (Default is .F.)
*-------------------------------------------------------------------------------
parameters cTextFile, cLookup, lCase
private cPhrase, nHandle, cText, nX, nClose
if pCount() = 3 .and. lCase
lCase = .t.
cPhrase = cLookup
else
lCase = .f.
cPhrase = upper(cLookup)
endif
cText = ""
nX = 1
if file(cTextFile)
nHandle = fopen(cTextFile,"R")
do while .not. feof(nHandle)
cText = fgets(nHandle,254)
if at(cPhrase,iif(lCase,cText,upper(cText))) > 0
nClose = fclose(nHandle)
RETURN nX
endif
nX = nX + 1
enddo
nClose = fclose(nHandle)
endif
RETURN -1
*-- EoF: TLineNo()
FUNCTION TempFile
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Returns a random filename.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: TempDir() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: TempFile([cFileExt])
*-- Example.....: cVarFile = TempFile("$XY")
*-- Returns.....: Filename
*-- Parameters..: cFileExt = optional parameter - allows you to assign a
*-- file extension to the end of the filename.
*-------------------------------------------------------------------------------
parameters cFileExt
RETURN TempDir()+"TMP"+right(ltrim(str(rand(-1)*10000000)),5);
+iif(pcount() = 0 .or. "" = cFileExt,"","."+cFileExt)
*-- EoF: TempFile()
FUNCTION TempDir
*-------------------------------------------------------------------------------
*-- Programmer..: Adam L. Menkes (Borland Technical Support)
*-- Date........: 04/01/1992
*-- Notes.......: Returns path of temporary directory as set from DOS
*-- (i.e., SET DBTMP= ...) Taken from TechNotes, April, 1992
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/01/1992 -- Original
*-- Calls.......: GetEnv() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: TempDir()
*-- Example.....: ?TempDir()
*-- Returns.....: Path of temporary directory
*-- Parameters..: None
*-------------------------------------------------------------------------------
cTempDir = iif("" <> GetEnv("DBTMP"),GetEnv("DBTMP"),GetEnv("TMP"))
RETURN cTempDir+iif(right(cTempDir,1)<> "\" .and.;
left(os(),3) = "DOS" .and. .not. "" = cTempDir,"\","")
*-- EoF: TempDir()
FUNCTION DirList
*-------------------------------------------------------------------------------
*-- Programmer..: Oktay Amiry (Borland Technical Support)
*-- Date........: 02/01/1993
*-- Notes.......: Used to display a popup of the hierarchical structure
*-- of directories. With this you can select a directory from
*-- the popup.
*-- DirList() returns a DOS Error Number if it encounters one,
*-- or a -1 if it fails to perform its task. It
*-- Originally Printed in TechNotes, February 1993
*-- ************************************************
*-- *** REQUIRES DOS TREE COMMAND BE IN DOS PATH ***
*-- ************************************************
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 02/01/1993 -- Original Release
*-- Calls.......: WhatDir Procedure in FILES.PRG
*-- Called by...: Any
*-- Usage.......: DirList([<cDrive>])
*-- Example.....: ?DirList() or
*-- ?DirList("A:")
*-- Returns.....: See above
*-- Parameters..: cDrive = Optional Parameter to list a specific drive instead
*-- of the default.
*-------------------------------------------------------------------------------
parameters cDrive
*-- deal with possible errors
do case
case .not. "DOS" $ UPPER(OS()) && gotta be DOS, not UNIX
RETURN "Incompatible operating system"
case pcount() # 0 .and. type("cDRIVE") # "C"
RETURN "Invalid Parameter"
case type("cDrive") = "C" .and. .not. isalpha(left(cDrive,1))
RETURN "Invalid Parameter"
endcase
*-- deal with file already being there
if file("DIRECT.XXX")
erase direct.xxx
endif
*-- save screen and then clear whatever's on it
save screen to sDirList
clear
*-- get the "message" color from the attributes ....
cMsgColor = substr(set("ATTRIBUTE"),at(chr(38),set("ATTRIBUTE"))+3)
cMsgColor = substr(cMsgColor,at(",",cMsgColor)+1)
cMsgColor = substr(cMsgColor,at(",",cMsgColor)+1)
cMsgColor = left(cMsgColor,at(",",cMsgColor)-1)
*-- display message (slightly modified by KJM)
@ 9,22 fill to 13,60 color n+/n && shadow
@ 8,20 fill to 12,58 color &cMsgColor.
@ 8,20 to 12,58 double color &cMsgColor.
@10,22 say "The directory tree is being created" color &cMsgColor.
*-- execute DOS RUN command, putting output into a text file
if type("CDRIVE") = "L"
* tree must be run in DOS directory or in DOS path
nRun = run(.f.,"TREE \ > direct.XXX",.t.)
else
cDrive = left(cDrive,1)+":\"
nRun = run(.f.,"TREE &cDrive > direct.xxx",.t.)
endif
*-- error has occured of some sort -- return error number OR -1
if nRun # 0 .or. .not. file("DIRECT.XXX")
RETURN iif(nRun # 0,nRun, -1)
endif
*-- use low-level routines to go in and deal with the file ...
nHandle = fopen("DIRECT.XXX","R") && open text file
cMove = fGets(nHandle,":")
if feof(nHandle)
lClose = fClose(nHandle)
erase direct.xxx
restore screen from sDirList
release screen sDirList
RETURN - 1
endif
cMove = fSeek(nHandle,len(cMove)-1)
*-- define the popup
define popup pTree from 1,20
nBar = 1
do while .not. feof(nHandle)
define bar nBar of pTree prompt space(2)+fGets(nHandle)+space(5)
nBar = nBar + 1
enddo
*-- store path (bar) and location of ascii 195 (├) or 192 (└) to array
declare aTemp[nBar,2] && temp array
nBar = 1
cMove = fSeek(nHandle,0,0)
cMove = fGets(nHandle,":")
cMove = fSeek(nHandle,len(cMove) - 1)
do while .not. feof(nHandle)
cBar = trim(fGets(nHandle))
store cBar to aTemp[nBar,1]
store iif(at(chr(195),cBar) # 0, at(chr(195),cBar),;
at(chr(192),cBar)) to aTemp[nBar,2]
nBar = nBar + 1
enddo
*-- hokay ...
clear
cUser = ""
*-- when user selects something, execute routine WhatDir ...
on selection popup pTree do whatdir with bar(),cUser
activate popup pTree
release popup pTree
lClose = fClose(nHandle)
erase direct.xxx
restore screen from sDirList
release screen sDirList
RETURN cUser
*-- EoF: DirList()
PROCEDURE WhatDir
*-------------------------------------------------------------------------------
*-- Programmer..: Oktay Amiry (Borland Technical Support)
*-- Date........: 02/01/1993
*-- Notes.......: Part of DIRLIST() above -- this is used to extract out of
*-- the prompt from a popup, the directory a user selected ...
*-- This routine should not be used on its own ... it assumes
*-- too much (like array aTemp[] being in existance, and such)
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 02/01/1993 -- Original Release
*-- Calls.......: GRAt() Function in FILES.PRG
*-- Called by...: DirList()
*-- Usage.......: Do WhatDir with <nBar>,<cDir>
*-- Example.....: Do WhatDir with bar(),cUser
*-- Returns.....: Directory
*-- Parameters..: nBar = bar number of popup
*-- cDir = prompt from popup to extract data ...
*-------------------------------------------------------------------------------
parameters nBar, cDir
if nBar # 1
cDir = substr(aTemp[nBar,1],GRAt(aTemp[nBar,1])+1)
nLevel = aTemp[nBar,2]
nBar = nBar - 1
do while nBar # 1
if aTemp[nBar,2] < nLevel
cDir = substr(aTemp[nBar,1],GRAt(aTemp[nBar,1])+1)+"\"+cDir
nLevel = aTemp[nBar,2]
endif
nBar = nBar - 1
enddo
cDir = aTemp[1,1]+cDir
else
cDir = aTemp[1,1]
endif
deactivate popup
RETURN
*-- EoP: WhatDir
FUNCTION GRAt
*-------------------------------------------------------------------------------
*-- Programmer..: Oktay Amiry (Borland Technical Support)
*-- Date........: 02/01/1993
*-- Notes.......: Graphic Reverse At -- Returns position of the first graphic
*-- character from the right of the string.
*-- Originally printed in TechNotes, February, 1993
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 02/01/1993 -- Original Release
*-- Calls.......: None
*-- Called by...: WhatDir
*-- Usage.......: GRAt(<cString>)
*-- Example.....: n = GRAt(cBar)
*-- Returns.....: Numeric
*-- Parameters..: cString = string to search
*-------------------------------------------------------------------------------
parameters cString
nLen = len(cString)
lFound = .f.
do while nLen # 0
cChar = substr(cString,nLen,1)
if asc(cChar) > 175 .and. asc(cChar) < 224
lFound = .t.
exit
endif
nLen = nLen - 1
enddo
RETURN iif(lFound,nLen,-1)
*-- EoF: GRAt()
FUNCTION FF
*-------------------------------------------------------------------------------
*-- Programmer..: Oktay Amiry (Borland Technical Support)
*-- Date........: 02/01/1993
*-- Notes.......: This routine will search a disk and find all occurances
*-- of a specified file or files. It will then allow you
*-- to select said file.
*-- Originally printed in TechNotes, February, 1993
*-- *********************************
*-- **** USES DOS ATTRIB COMMAND ****
*-- *********************************
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 02/01/1993 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: FF(<cFile>[,<cPath>])
*-- Example.....: ?ff("*.dbf","c:\temp")
*-- Returns.....: Selected File
*-- Parameters..: cFile = Filename, or wildcard specification, allows use
*-- of standard ? and * wildcards in the way DOS has
*-- always used them.
*-- cPath = Optional -- specified drive and directory.
*-- If not used, this UDF will start the search at
*-- the root of the default drive.
*-------------------------------------------------------------------------------
parameters cFile,cPath
cCurDir = set("DIRECTORY")
*-- deal with error messages
do case
case type("CFILE") # "C"
RETURN "Invalid Parameter"
case pcount() > 1 .and. type("CFILE") # "C"
RETURN "Invalid Parameter"
case pcount() > 1 .and. type("CFILE") = "C"
lError = .f.
on error lError = .t.
set directory to &cPath.
on error
if lError
RETURN "Invalid Drive\Directory"
endif
endcase
if file("TEMP.XXX")
erase temp.xxx
endif
*-- save screen so we can restore it, and clear ...
save screen to sFF
clear
*-- get the "message" color from the attributes ....
cMsgColor = substr(set("ATTRIBUTE"),at(chr(38),set("ATTRIBUTE"))+3)
cMsgColor = substr(cMsgColor,at(",",cMsgColor)+1)
cMsgColor = substr(cMsgColor,at(",",cMsgColor)+1)
cMsgColor = left(cMsgColor,at(",",cMsgColor)-1)
*-- display message
@ 9,22 fill to 13,60 color n+/n && shadow
@ 8,20 fill to 12,58 color &cMsgColor.
@ 8,20 to 12,58 double color &cMsgColor.
@10,22 say "The directories are being searched" color &cMsgColor.
*-- if no path was given, run the DOS Attrib command on the whole drive
if type("CPATH") = "L"
nDosF = run(.f.,"ATTRIB \&cFile. /s > temp.xxx | sort",.t.)
else && run it on the path that was given ...
nDosF = run(.f.,"ATTRIB &cFile. /s > temp.xxx | sort",.t.)
endif
*-- if there was an error ...
if nDosF # 0 .or. .not. file("TEMP.XXX")
set directory to &cCurDir.
restore screen from sFF
release screen sFF
RETURN iif(nDosF # 0,nDosF,-1)
endif
*-- use LOWLEVEL routines to process the output of the ATTRIB command
nHandle = fopen("TEMP.XXX","R")
cMove = fgets(nHandle,":")
if feof(nHandle)
lClose = fClose(nHandle)
erase temp.xxx
restore screen from sFF
release screen sFF
RETURN "File not found"
endif
*-- ok. Now we create the popup ...
cMove = fseek(nHandle,0,0)
nBar = 1
define popup pFile from 1,1
do while .not. feof(nHandle)
cBar = trim(fgets(nHandle))
cBar = space(2)+substr(cBar,at(":",cBar)-1)+space(5)
define bar nBar of pFile prompt cBar
nBar = nBar + 1
enddo
*-- what do we do with it?
clear
on selection popup pFile deactivate popup
activate popup pFile
cSelect = iif(.not. isblank(prompt()), ltrim(rtrim(prompt())),"")
*-- cleanup
release popup pFile
lClose = fclose(nHandle)
erase temp.xxx
set directory to &cCurDir.
restore screen from sFF
release screen sFF
RETURN cSelect
*-- EoF: FF()
FUNCTION MakeStr
*-------------------------------------------------------------------------------
*-- Programmer..: Angus Scott-Fleming CIS: 75500,3223)
*-- (from code published in DBA)
*-- Date........: 11/25/1992
*-- Notes.......: Creates an empty structure extended database
*-- Written for.: dBASE IV 1.5+
*-- Rev. History: 11/25/1992 - Rev A uses structure of currently open
*-- database, if present
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: MakeStr(<cFileName.Ext>)
*-- Example.....: lDummy = MakeStr("G_HELP.STR")
*-- Returns.....: .F. if no file was created, .T. if one was
*-- Parameters..: cFileName = Name of file to create
*-------------------------------------------------------------------------------
parameters cFileName
private ALL
if isblank(cFileName)
return .F.
endif
if .not. isblank(alias())
copy structure extended to &cFileName.
else
* code from DataBased Advisor to create an empty DBF
nLoopCount = 1 && Loop counter
nDim = 5 && Number of rows in the DBF structure array
* Declare array with the structure of the "structure extended"
* DBF file
DECLARE aDbfStru[nDim,5]
aDbfStru[1,1] = "FIELD_NAME" && field name
aDbfStru[1,2] = "C" && field type
aDbfStru[1,3] = 10 && field length
aDbfStru[1,4] = 0 && number of decimal places
aDbfStru[1,5] = "N" && MDX index tag
aDbfStru[2,1] = "FIELD_TYPE"
aDbfStru[2,2] = "C"
aDbfStru[2,3] = 1
aDbfStru[2,4] = 0
aDbfStru[2,5] = "N"
aDbfStru[3,1] = "FIELD_LEN"
aDbfStru[3,2] = "N"
aDbfStru[3,3] = 3
aDbfStru[3,4] = 0
aDbfStru[3,5] = "N"
aDbfStru[4,1] = "FIELD_DEC"
aDbfStru[4,2] = "N"
aDbfStru[4,3] = 3
aDbfStru[4,4] = 0
aDbfStru[4,5] = "N"
aDbfStru[5,1] = "FIELD_IDX"
aDbfStru[5,2] = "C"
aDbfStru[5,3] = 1
aDbfStru[5,4] = 0
aDbfStru[5,5] = "N"
* Redirect printer output to a file
SET PRINTER TO FILE (cFileName)
SET PRINT ON
* Write DBF file header
* First byte (byte 0)- DBF file indicator
??? '{3}'
* Creation date - bytes 1-3
??? CHR(VAL(RIGHT(STR(YEAR(DATE())),2))) + ;
CHR(MONTH(DATE())) + CHR(DAY(DATE()))
* Number of records in the file (zero) - bytes 1-3
??? REPLICATE('{0}',4)
* Number of bytes in the header - bytes 8-9
??? '{193}{0}'
* Number of bytes in the record (19) - bytes 10-11
??? '{19}{0}'
* Bytes 12-31 of the header - not used here
* Some appear to have constant value
??? REPLICATE('{0}',18)
??? '{57}{1}'
* Field descriptor bytes - looping through the array
* nDim times (5 in this case)
* Field descriptors are each 32 bytes long
DO WHILE nLoopCount <= nDim
* Field name - bytes 0-10
??? aDbfStru[nLoopCount,1] +;
REPLICATE('{0}', 11-LEN(TRIM(aDbfStru[nLoopCount,1])))
* Field type - byte 11
??? aDbfStru[nLoopCount,2]
* Bytes 12-15 - not used here
??? REPLICATE('{0}',2)
??? '{238}{85}'
* Field length - byte 16
??? CHR(aDbfStru[nLoopCount,3])
* Field decimal count - byte 17
??? IIF(aDbfStru[nLoopCount,4] > 0, ;
CHR(aDbfStru[nLoopCount,4]), '{0}')
* Bytes 18-19 - reserved
??? REPLICATE('{0}',2)
* Byte 20 - work area ID. Let's use 1 for simplicity
??? '{1}'
* Bytes 21-31 - MDX index tag flag and reserved bytes
??? IIF(aDbfStru[nLoopCount,5] $ 'YyTt', '{1}', '{0}')
??? REPLICATE('{0}',10)
* Increment loop counter
nLoopCount = nLoopCount + 1
ENDDO
* DBF file header terminator and EOF character - byte n+1
??? '{13}{26}'
SET PRINTER TO
SET PRINT OFF
endif
select (select())
use &cFileName. exclusive
zap
RETURN .T.
*-- EoF: MakeStr()
FUNCTION RecChged
*-------------------------------------------------------------------------------
*-- Programmer..: Angus Scott-Fleming
*-- Date........: 11/25/1992
*-- Notes.......: Test field values against memory variables to see if an
*-- on-screen display has changed from the disk-record
*-- CHANGE() requires the existence of field _DBASELOCK
*-- whereas RecChged does not.
*-- Written for.: dBASE IV 1.1+
*-- Rev. History: 11/25/1992 for dBase IV 1.5
*-- 10/08/1992 don't test memo-fields
*-- 06/09/1992 dropped PCount() for 4.11 use
*-- 06/04/1992 skips any field with REVDATE in its name
*-- Calls.......: FldCount() (1.1)
*-- ExEqual() Function in STRINGS.PRG
*-- Called by...: Any
*-- Usage.......: RecChged(<cTable_Name>)
*-- Example.....: if RecChged("mpl") .and. Confirm("Save?",.Y.)
*-- Returns.....: .T. = record has changed .F. = record has not changed
*-- Parameters..: cTable_Name = (OPTIONAL) alias of table to test
*-------------------------------------------------------------------------------
parameters ctable_name
if empty(ctable_name)
ctable_name = alias()
endif
n = 1
do while n <= fldcount(ctable_name)
test_field = field(n,ctable_name)
test_disk = "&ctable_name->&test_field"
* Thu 06-04-1992 don't test _DBASELOCK or REVDATE fields,
* since they're changed automagically
* if .not. ExEqual(upper(test_field),"_DBASELOCK")
* Thu 10-08-1992 check for existence of the field in the table
* skip check for memo fields
if .not. type("&test_disk") $ "MU" .and. .not. type("m->&test_field") ="U"
if .not. upper(test_field) = "_DBASELOCK" ;
.and. .not.("REVDATE"$test_field)
if .not. ExEqual(m->&test_field,&test_disk)
return .T.
endif
endif
endif
n = n + 1
enddo
RETURN .F.
*-- EoF: RecChged()
FUNCTION CopyFile
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Copies a database plus its production index (if it has one),
*-- and the DBT file if it exists as well.
*-- Use this instead of the COPY TO... WITH PRODUCTION command.
*-- Because it uses the COPY FILE command (a file-to-file copy)
*-- instead of the COPY TO command (a record-by-record copy),
*-- this is much faster.
*-- The DBF must be closed when you use this UDF.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: MdxPoint() Function in FILES.PRG
*-- DbfName() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: CopyFile("<cOldFile>","<cNewFile>")
*-- Example.....: CopyFile("FRED","MARY")
*-- Returns.....: nError - 0 if copy operation worked okay.
*-- 1 if file to be copied didn't exist.
*-- Parameters..: cOldFile - DBF file to be copied
*-- cNewFile - Name for copy of DBF
*-------------------------------------------------------------------------------
parameters cOldFile,cNewFile
private cOldFile, cNewFile, lOpen, nRec, cTag, cAlias, nError
nError = 0
*-- Check if database actually exists
if file(cOldFile + ".DBF")
*-- Copy the file
copy file cOldFile + ".DBF" to cNewFile + ".DBF"
*-- Copy its MDX file
if file(cOldFile + ".MDX")
copy file cOldFile + ".MDX" to cNewFile + ".MDX"
*-- Update the hard-coded database reference in the MDX header
xJunk = MdxPoint(cNewFile)
endif
*-- Copy its memo file
if file(cOldFile + ".DBT")
copy file cOldFile + ".DBT" to cNewFile + ".DBT"
endif
else
nError = 1
endif
RETURN (nError)
*-- EoF: CopyFile()
FUNCTION CopyFil1
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Copies a database plus its production index (if it has one),
*-- and the DBT file if it exists as well.
*-- Based on CopyFile().
*-- With this version, it doesn't matter whether the file
*-- you're copying is open or closed. If it's open, the:
*--
*-- * current index order
*-- * alias
*-- * record pointer
*--
*-- will all be retained.
*-- You must SET DBTRAP OFF before calling this routine from
*-- a program or the dot prompt.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: MdxPoint() Function in FILES.PRG
*-- DbfName() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: CopyFile("<cOldFile>","<cNewFile>")
*-- Example.....: CopyFile("FRED","MARY")
*-- Returns.....: nError - 0 if copy operation worked okay.
*-- 1 if file to be copied didn't exist.
*-- Parameters..: cOldFile - DBF file to be copied
*-- cNewFile - Name for copy of DBF
*-------------------------------------------------------------------------------
parameters cOldFile,cNewFile
private cOldFile, cNewFile, lOpen, nRec, cTag, cAlias, nError
lOpen = .F.
nError = 0
*-- Check whether database exists
if file(cOldFile + ".DBF")
*-- If database is currently open, save info about it
if DbfName() = upper(cOldFile)
nRec = recno()
cTag = tag()
cAlias = alias()
lOpen = .T.
use
endif
*-- Copy the database
copy file cOldFile + ".DBF" to cNewFile + ".DBF"
*-- Copy its MDX
if file(cOldFile + ".MDX")
copy file cOldFile + ".MDX" to cNewFile + ".MDX"
*-- Update the hard-coded database reference in the MDX header
xJunk = MdxPoint(cNewFile)
endif
*-- Copy its memo file
if file(cOldFile + ".DBT")
copy file cOldFile + ".DBT" to cNewFile + ".DBT"
endif
*-- If file was originally open, reopen it and restore its state
if lOpen
use (cOldFile) ALIAS &cAlias
if "" <> cTag
set order to (cTag)
endif
go nRec
endif
else
nError = 1
endif
RETURN (nError)
*-- EoF: CopyFil1()
FUNCTION RenFile
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Renames a .DBF file and its production index and
*-- memo files (if they exist) and correctly updates
*-- the .MDX header.
*-- The DBF must be closed before using this UDF.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: MdxPoint() Function in FILES.PRG
*-- DbfName() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: RenFile("<cOldFile>","<cNewFile>")
*-- Example.....: RenFile("FRED","MARY")
*-- Returns.....: nError - 0 if renaming operation went okay.
*-- 1 if file to be renamed didn't exist.
*-- Parameters..: cOldFile - Current database name
*-- cNewFile - New name for database
*-------------------------------------------------------------------------------
parameters cOldFile,cNewFile
private cOldFile, cNewFile, lOpen, nError, nRec, cTag, cAlias, xJunk
nError = 0
*-- Check whether database exists
if file(cOldFile + ".DBF")
*-- Rename it
rename cOldFile + ".DBF" to cNewFile + ".DBF"
*-- Rename its MDX
if file(cOldFile + ".MDX")
rename cOldFile + ".MDX" to cNewFile + ".MDX"
*-- Update the hard-coded database reference in the MDX header
xJunk = MdxPoint(cNewFile)
endif
*-- Rename its memo file
if file(cOldFile + ".DBT")
rename cOldFile + ".DBT" to cNewFile + ".DBT"
endif
else
nError = 1
endif
RETURN (nError)
*-- EoF: RenFile()
FUNCTION RenFile1
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Renames a .DBF file and its production index and
*-- memo files (if they exist) and correctly updates
*-- the .MDX header.
*-- This is a variant of RenFile().
*-- In this version, it doesn't matter whether the database
*-- is open or closed when you call the UDF. If it is open, the
*--
*-- * current index order
*-- * record pointer
*--
*-- will be restored after the renaming.
*-- You must SET DBTRAP OFF before calling this UDF.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: MdxPoint() Function in FILES.PRG
*-- DbfName() Function in FILES.PRG
*-- Called by...: Any
*-- Usage.......: RenFile("<cOldFile>","<cNewFile>")
*-- Example.....: RenFile("FRED","MARY")
*-- Returns.....: nError - 0 if renaming operation went okay.
*-- 1 if file to be renamed didn't exist.
*-- Parameters..: cOldFile - Current database name
*-- cNewFile - New name for database
*-------------------------------------------------------------------------------
parameters cOldFile,cNewFile
private cOldFile, cNewFile, lOpen, nError, nRec, cTag, xJunk
lOpen = .F.
nError = 0
*-- Check if database exists
if file(cOldFile + ".DBF")
*-- If database is currently open, save record pointer
*-- and index order
if DbfName() = upper(cOldFile)
nRec = recno()
cTag = tag()
lOpen = .T.
use
endif
*-- Rename database
rename cOldFile + ".DBF" to cNewFile + ".DBF"
*-- Rename its MDX
if file(cOldFile + ".MDX")
rename cOldFile + ".MDX" to cNewFile + ".MDX"
*-- Update the hard-coded database reference in the MDX header
xJunk = MdxPoint(cNewFile)
endif
*-- Rename its memo file
if file(cOldFile + ".DBT")
rename cOldFile + ".DBT" to cNewFile + ".DBT"
endif
*-- If file was originally open, reopen it and restore its state
if lOpen
use (cNewFile)
if "" <> cTag
set order to (cTag)
endif
go nRec
endif
else
nError = 1
endif
RETURN (nError)
*-- EoF: RenFile1()
FUNCTION DelFile
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Deletes a database, its production index and its memo
*-- file (if there is one) in one fell swoop.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DelFile("<cDbfName>")
*-- Example.....: DelFile("FRED")
*-- Returns.....: nError - 0 if file deletion went okay
*-- - 1 if file to be deleted didn't exist.
*-- Parameters..: cDbfName - Name of the database you wish to delete.
*-------------------------------------------------------------------------------
parameters cDbfName
private cDbfName, cMdxName, cDbtName, nError
cMdxName = cDbfName + ".MDX"
cDbtName = cDbfName + ".DBT"
cDbfName = cDbfName + ".DBF"
nError = 0
*-- Check database exists
if file(cDbfName)
*-- Delete database
delete file (cDbfName)
*-- Delete its MDX
if file(cMdxName)
delete file (cMdxName)
endif
*-- Delete its memo file if any
if file(cDbtName)
delete file (cDbtName)
endif
else
nError = 1
endif
RETURN (nError)
*-- EoF: DelFile()
FUNCTION DelMdx
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Deletes a production index file, correctly updating
*-- the production index byte in the DBF header, so you
*-- avoid getting the "Production index not found" message.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DelMdx("<cMdx>")
*-- Example.....: DelMdx("fred")
*-- Returns.....: nError = 0 if deletion is okay
*-- 1 if file doesn't exist
*-- Parameters..: cMdx = Production MDX file to delete
*-------------------------------------------------------------------------------
parameters cMdx
private cMdx, cMdxName, cDbfName, nHandle, nError, xJunk
cMdxName = cMdx + ".MDX"
cDbfName = cMdx + ".DBF"
nError = 0
*-- Check if file exists
if file(cMdxName)
*-- Delete MDX file
delete file (cMdxName)
*-- Update MDX byte in DBF header, indicating there is no longer
*-- an MDX for this database.
nHandle = fopen((cDbfName),"rw")
xJunk = fseek(nHandle,28,0)
xJunk = fwrite(nHandle,chr(0))
xJunk = fclose(nHandle)
else
nError = 1
endif
RETURN ("")
*-- EoF: DelMdx()
FUNCTION RestMdx
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Restores a pointer to an (existing) production MDX file
*-- in the DBF header. Only really needed if you make a
*-- mess using the DelMdx() function.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: RestMdx("<cMdx>")
*-- Example.....: RestMdx("FRED")
*-- Returns.....: nError - 0 if pointer restoration went okay
*-- 1 if the MDX didn't exist
*-- Parameters..: cMdx - MDX/DBF file name.
*-------------------------------------------------------------------------------
parameters cMdx
private cMdxName, cDbfName, nHandle, xJunk, nError
cMdxName = cMdx + ".MDX"
cDbfName = cMdx + ".DBF"
if file(cMdxName)
*-- Update MDX byte in DBF header, indicating there is an
*-- MDX for this database.
nHandle = fopen((cDbfName),"rw")
xJunk = fseek(nHandle,28,0)
xJunk = fwrite(nHandle,chr(1))
xJunk = fclose(nHandle)
nError = 0
else
nError = 1
endif
RETURN (nError)
*-- EoF: RestMdx()
FUNCTION MdxPoint
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Changes the hard-coded DBF name in an MDX file header
*-- (either a production or non-production MDX).
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any (Specifically CopyFile() and RenFile())
*-- Usage.......: MdxPoint("<cDbfName>", "<cMdx>")
*-- Example.....: MdxPoint("FRED")
*-- MdxPoint("FRED","FULLNAME")
*-- Returns.....: None
*-- Parameters..: cDbfName - The name of the DBF to be hard-coded into the
*-- MDX header.
*-- cMdx - The name of the MDX file, if it's a
*-- non-production MDX (omit this parameter
*-- completely if it's a production MDX).
*-------------------------------------------------------------------------------
parameters cDbfName, cMdx
private nPadl, cDbfName, nHandle, xJunk, n
*-- Find out how long the DBF filename is and set padding length
nPadl = 8 - len(cDbfName)
cDbfName = upper(cDbfName)
*-- Check how many parameters have been passed: 1 means its a
*-- production index, 2 is a non-production index
if pcount() < 2
nHandle = fopen((cDbfName)+".MDX","rw")
else
nHandle = fopen((cMdx)+".MDX","rw")
endif
*-- Position file pointer to Byte 4, which is start of hard-coded
*-- DBF name in MDX header
xJunk = fseek(nHandle,4,0)
*-- Write the new DBF filename into the header
xJunk = fwrite(nHandle,(cDbfName))
n = 0
do while n < nPadl
*-- Pad filename out to 8 characters in header, using nulls
xJunk = fwrite(nHandle,chr(0))
n = n + 1
enddo
xJunk = fclose(nHandle)
RETURN ("")
*-- EoF: MdxPoint()
FUNCTION DbfName
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Strips the 8-character DBF filename out of the full
*-- pathname returned by the dbf() function. Works on the
*-- database in USE in the current workarea.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any (Specifically CopyFile() and RenFile()).
*-- Usage.......: DbfName()
*-- Example.....: DbfName()
*-- Returns.....: cName = 8-character filename of DBF.
*-- Parameters..: None
*-------------------------------------------------------------------------------
private cFullPath, cName
cFullPath = set("FULLPATH")
set fullpath off
*-- Check if a database is open in the current workarea
if "" <> dbf()
*-- Strip the filename out of the full pathname
cName = ( substr( dbf(), 3, at( ".", dbf() ) - 3 ) )
else
cName = ""
endif
set fullpath &cFullPath
RETURN (cName)
*-- EoF: DbfName()
FUNCTION MdxGauge
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Indexes a database, showing a 'fuel-gauge' style progress
*-- indicator during the process.
*-- You must SET DBTRAP OFF in the calling routine or at the
*-- dot prompt.
*-- This routine slows down indexing, but allows the user to
*-- know what's going on.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: Gauge(), DelGauge()
*-- Called by...: Any
*-- Usage.......: MdxGauge("<cDataFile>","<cIndexExp>","<cMTag>","<cMdxName>",;
*-- "<cClr>",<nURow>,<nLCol>)
*-- Example.....: MdxGauge("FRED","upper(LNAME)+upper(FNAME)","FULLNAME","",;
*-- 0,0)
*--
*-- This example indexes FRED.DBF on the uppercase last and
*-- firstnames, to the production MDX with a tagname of
*-- FULLNAME. It also uses your current default colour scheme,
*-- and positions the fuel gauge at 0,0.
*--
*-- MdxGauge("FRED","substr(LNAME,5)","SHORTNAME","OTHERS",;
*-- "r+/b,r+/b,b+/w";10,15)
*--
*-- This example indexes FRED.DBF on the first 5 characters of
*-- the lastname to a non-production MDX called OTHERS, using
*-- the tagname SHORTNAME. It sets the colours of the fuel-
*-- gauge and the fuel-gauge frame, and positions the gauge
*-- starting at 10,15.
*-- Returns.....: nError = 0 if MDX header was updated correctly
*-- = 1 if MDX header couldn't be updated
*-- Parameters..: cDataFile = DBF to be indexed
*-- cMdxExpr = Indexing expression
*-- cMdxTag = Index TAG name
*-- cMdxName = MDX name - only needed if using a
*-- non-production MDX.
*-- cClr = Colours for fuel gauge. You can include
*-- standard, enhanced and frame colours in the
*-- string. If you don't include a colour string,
*-- the UDF will use the current colours.
*-- nURow = Starting row for the fuel gauge on screen.
*-- Must be less than 20 - if not, the program
*-- will make nURow = 19.
*-- nLCol = Starting column for the fuel gauge.
*-- Must be less than 26 - if not, the program
*-- will make nLCol = 25.
*-------------------------------------------------------------------------------
parameters cDbfName, cMdxExpr, cMdxTag, cMdxName, cClr, nURow, nLCol
private nBarLen, cBarPad, cIndex, nError, nRecInt, nBarFull
use &cDbfName
cStatus = set("STATUS")
cSafety = set("SAFETY")
cTalk = set("TALK")
set status off
set safety off
set talk off
cMdxExpr = upper(cMdxExpr)
cMdxTag = upper(cMdxTag)
*-- If colour parameter is blank, use default colour scheme
if cClr <> ""
cClr = SET("ATTR")
endif
if nURow > 19
nURow = 19
endif
if nLCol > 25
nLCol = 25
endif
*-- Determine width of fuel-gauge
if reccount() > 50
nRecInt = int(reccount()/50)
nBarLen = int( reccount() / nRecInt )
else
nBarLen = reccount() + 1
endif
cBarPad = space(round((nBarLen-16)/3,0))
clear
*-- Display fuel-gauge window and empty gauge
define window wGauge from nURow, nLCol;
to nURow+5,nBarLen+nLCol+2 color &cClr
activate window wGauge
@ 0,0 say "Indexing " + Dbf()
@ 1,0 say "0% " + cBarPad + "25% " + cBarPad + "75% " + ;
cBarPad + "100%"
@ 2,0 say replicate( chr(219), nBarlen )
@ 2,0 say ""
*-- Check if it's a production index or not, and then
*-- use the appropriate index expression. The FOR condition
*-- in the expression "fills up" the fuel gauge.
if "" = cMdxName
index on &cMdxExpr tag &cMdxTag for Gauge()
else
index on &cMdxExpr tag &cMdxTag of &cMdxName for Gauge()
endif
*-- Clean up
clear
@ 2,0 say "Closing files..."
nError = 0
cIndex = mdx()
use
*-- Call UDF to delete reference to Gauge() UDF from MDX header
nError = DelGauge(cIndex, cMdxTag)
deactivate window wGauge
set status &cStatus
set safety &cSafety
set talk &cTalk
RETURN(nError)
*-- EoF: MdxGauge()
FUNCTION Gauge
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Routine used by MdxGauge() to "fill up" the fuel-gauge
*-- on screen during indexing.
*-- It is called from an indexing "FOR" expression, and always
*-- returns .T. to include all records in the index.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: MdxGauge() Function in FILES.PRG
*-- Usage.......: Gauge()
*-- Example.....: Gauge()
*-- Returns.....: .T.
*-- Parameters..: None
*-------------------------------------------------------------------------------
*-- Every time 2% of the file or so is indexed...
if reccount() > 50
if mod( recno(), nRecInt ) = 0
*-- Display a solid bar character to "fill up" the gauge
?? chr(177)
endif
else
?? chr(177)
endif
RETURN(.T.)
*-- EoF: Gauge()
FUNCTION DelGauge
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Deletes all reference to the Gauge() UDF from within
*-- an MDX header file.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: FindTagExp() Function in FILES.PRG
*-- Called by...: MdxGauge()
*-- Usage.......: DelGauge("<cMdx>","<cTag>")
*-- Example.....: DelGauge("FRED","upper(LASTNAME)+upper(FIRSTNAME)")
*-- Returns.....: nError - Error code.
*-- 0 if the UDF managed to delete the Gauge()
*-- reference in the header.
*-- 1 if the UDF failed (it couldn't find the
*-- Gauge() reference.
*-- Parameters..: cMdx = MDX file to search.
*-- cTag = TAG expression to search for.
*-------------------------------------------------------------------------------
parameters cMdx, cTag
private nHandle, nTagExp, nForFlag, nForExp, nError, n, xJunk
*-- Open the MDX file
nHandle = fopen(cMdx,'rw')
*-- Find the information about the TAG in the MDX header
nTagExp = FindTagExp( nHandle, cTag )
*-- Find the byte indicating whether a FOR clause was used
*-- to create this particular TAG.
nForFlag = nTagExp + 245
*-- Find the start of the FOR expression in the TAG information
nForExp = nTagExp + 762
*-- Place 00H in the byte indicating a FOR clause, to delete
*-- reference to the FOR clause.
xJunk = fseek( nHandle, nForFlag, 0 )
xJunk = fwrite (nHandle, chr(0))
*-- Positioning the pointer at the FOR clause in the TAG info.
xJunk = fseek( nHandle, nForExp, 0 )
*-- Check that we've found our UDF reference in the FOR clause
*-- and, if so, delete the reference to the UDF by writing a
*-- series of nulls to the file over the word "GAUGE()".
if upper(fread(nHandle,7)) = 'GAUGE()'
nError = 0
xJunk = fseek( nHandle, nForExp, 0)
n = 1
do while n < 8
xJunk = fwrite(nHandle,chr(0))
n = n + 1
enddo
else
nError = 1
endif
xJunk = Fclose(nHandle)
RETURN (nError)
*-- EoF: DelGauge()
FUNCTION FindTagExp
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153) (dBase version)
*-- Date........: 04/26/1993
*-- Notes.......: Finds the starting position of a specific index TAG
*-- expression within an MDX header.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: FLocate() Function in FILES.PRG
*-- FReadI32() Function in FILES.PRG
*-- Called by...: DelGauge()
*-- Usage.......: FindTagExp(<nHandle>,"<cMdxTag>")
*-- Example.....: FindTagExp( 5, "upper(LASTNAME)+upper(FIRSTNAME)" )
*-- Returns.....: nTagExp - Starting position of the TAG expression
*-- within the MDX header file.
*-- Parameters..: nHandle = DOS file handle of an MDX file.
*-- cMdxTag = MDX TAG expression.
*-------------------------------------------------------------------------------
parameters nHandle, cMdxTag
private nJunk, nPos, nPoint, nTagExp
*-- Shift pointer to byte 512 in the MDX file. At byte 512,
*-- there's an array of TAG names.
nJunk = fseek( nHandle, 512, 0 )
*-- From there, locate our particular TAG in the array
nPos = Flocate( nHandle, cMdxTag, .T. )
*-- Back up and read the preceding 4 bytes, which are a pointer
*-- to the file offset where the information about our TAG
*-- is located in the MDX file.
nJunk = fseek( nHandle, nPos - 4 )
*-- Convert the 4-byte pointer to decimal
nPoint = FreadI32( nHandle )
*-- Return the starting position of the TAG info.
nTagExp = fseek( nHandle, nPoint * 512 )
RETURN( nTagExp )
*-- EoF: FindTagExp()
FUNCTION FLocate
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153) (dBase version)
*-- Matt Whelan (Clipper version - not included here)
*-- Date........: 04/26/1993
*-- Notes.......: Finds a string within a file, starting from the current
*-- position of the file pointer (Operates using low-level
*-- file functions).
*-- Due to the 254-character limitation on dBase string
*-- variables, this is not particularly fast on large files as
*-- it must search through a 254-character buffer.
*-- The Clipper version, which uses a 65,535-character buffer,
*-- is much faster.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: FTell() Function in FILES.PRG
*-- FLen() Function in FILES.PRG
*-- Called by...: Any (Specifically FindTaxExp()).
*-- Usage.......: FLocate(<nHandle>,"<cSearch>",<lWantUpper>)
*-- Example.....: FLocate( 5, "Crabapple Cove", .T.)
*-- Returns.....: nFoundPos - Starting position of the string in the file
*-- Parameters..: nHandle = DOS file handle
*-- cSearch = Search string
*-- lWantUpper = Whether you want the search string first
*-- converted to uppercase.
*-------------------------------------------------------------------------------
parameters nHandle, cSearch, lWantUpper
private cBuffer, nCurPos, nStartPos, nBuffSize, nFlength
private nBufPos, cTxtBuff, nBuffOffset, nFoundPos, cAddBuf
nFoundPos = -2
*-- Convert search string to uppercase if required
if pcount() = 2
lWantUpper = .F.
endif
*-- If a valid file handle has been passed...
if nHandle > 0
*-- Store our current position in the file,
*-- check the file length and then determine the
*-- buffer size.
nCurPos = Ftell( nHandle )
nStartPos = nCurPos
nFlength = Flen( nHandle )
nBuffSize = min( 254, nFlength )
*-- Now start reading characters into the buffer
do while nCurPos < nFlength
cBuffer = ""
do while len(cBuffer) < nBuffSize
cAddBuf = fread( nHandle, 1 )
*-- If you read in a null, replace it in the buffer
*-- by a space
if chr(0) = cAddBuf
cAddBuf = " "
endif
cBuffer = cBuffer + cAddBuf
enddo
if lWantUpper
cBuffer = upper(cBuffer)
endif
*-- See if the search string is in the buffer
nBufPos = at( cSearch, cBuffer )
*-- and if it is, store its position in the file
if nBufPos > 0
nFoundPos = nCurPos + nBufPos - 1
exit
endif
nCurPos = Ftell( nHandle )
enddo
if nFoundPos < 1
nJunk = fseek( nHandle, nStartPos, 0 )
else
nJunk = fseek( nHandle, nFoundPos, 0 )
endif
endif
RETURN( nFoundPos )
*-- EoF: FLocate()
FUNCTION FTell
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: A shorthand way of finding the current position of the
*-- file pointer in a file, without moving the pointer.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any (specifically FLocate()).
*-- Usage.......: FTell(<nHandle>)
*-- Example.....: FTell(5)
*-- Returns.....: Current position of pointer in a file.
*-- Parameters..: nHandle = DOS file handle.
*-------------------------------------------------------------------------------
parameters nHandle
RETURN( fseek( nHandle, 0, 1 ) )
*-- EoF: FTell()
FUNCTION FLen
*-------------------------------------------------------------------------------
*-- Programmer..: Rose Vines (CIS: 100026,3153)
*-- Date........: 04/26/1993
*-- Notes.......: Finds length (in bytes) of a file and then returns
*-- the file pointer to byte 0.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 04/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any (specifically FLocate()).
*-- Usage.......: FLen(<nHandle>)
*-- Example.....: FLen(6)
*-- Returns.....: nLength = Length of file in bytes
*-- Parameters..: nHandle = DOS file handle
*-------------------------------------------------------------------------------
parameters nHandle
private nCurPos, nLength, xJunk
*-- Locate current position in file without moving pointer
nCurPos = Ftell( nHandle )
*-- Find the length of the file by shifting the pointer to the end
nLength = fseek( nHandle, 0, 2 )
*-- Return the pointer to the original starting point
nJunk = fseek( nHandle, nCurPos, 0 )
RETURN( nLength )
*-- EoF: FLen()
FUNCTION FReadI32
*-------------------------------------------------------------------------------
*-- Programmer..: Borland
*-- Date........: 1992
*-- Notes.......: Convert a 4-byte integer to its decimal value.
*-- The UDF reads the next 4 bytes from a file and converts
*-- them to decimal.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: Original
*-- Calls.......: None
*-- Called by...: Any (specifically FindTagExp)
*-- Usage.......: FReadI32(<nHandle>)
*-- Example.....: FReadI32(4)
*-- Returns.....: nResult = Decimal value of next 4 bytes in file
*-- Parameters..: nHandle = DOS file handle
*-------------------------------------------------------------------------------
parameters nHandle
private nResult, nByte1, nByte2, nByte3, nByte4
nResult = 0
nByte1 = asc( fread( nHandle,1 ) )
nByte2 = asc( fread( nHandle,1 ) ) * 256
nByte3 = asc( fread( nHandle,1 ) ) * 256 * 256
nByte4 = asc( fread( nHandle,1 ) ) * 256 * 256 * 256
nResult = nByte1 + nByte2 + nByte3 + nByte4
RETURN (nResult)
*-- EoF: FReadI32()
*-------------------------------------------------------------------------------
*-- EoP: FILES.PRG
*-------------------------------------------------------------------------------