home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-21 | 84.3 KB | 2,264 lines |
- *-----------------------------------------------------------------------
- *-- Program...: MISC.PRG
- *-- Programmer: Ken Mayer (CIS: 71333,1030)
- *-- Date......: 08/31/1993
- *-- Notes.....: These are the miscellaneous functions/procedures from
- *-- the PROC file that aren't as commonly used as the
- *-- others. See README.TXT for details on how to use this
- *-- library file.
- *-----------------------------------------------------------------------
-
- FUNCTION PlayIt
- *-----------------------------------------------------------------------
- *-- Programmer..: Mike Carlisle (A-T)
- *-- Date........: 01/21/1992
- *-- Notes.......: This function (from Technotes, issue??) will play a
- *-- song stored in a memory variable (array).
- *-- This is a two dimensional array, with the first
- *-- dimension defined being the # of notes, each note
- *-- having two parts.
- *-- For a song with 12 notes, the declare statement is:
- *-- DECLARE aSong[12,2]
- *-- aSong[1,1] is the pitch of the first note.
- *-- aSong[1,2] is the duration of the first note.
- *-- Pitches are defined from C below Middle C to B below
- *-- Middle C. These are from a "tempered" scale. Values
- *-- can be raised an octave by doubling the number,
- *-- lowered by halving it.
- *-- Duration can be from 1 to 20.
- *-- Note Value
- *-- C 261
- *-- C# 277
- *-- D 294
- *-- D# 311
- *-- E 329
- *-- F 349
- *-- F# 370
- *-- G 392
- *-- G# 415
- *-- A 440
- *-- A# 466
- *-- B 494
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 01/21/1992 - Modified to allow use of parameter to
- *-- choose the song to be played. This alleviates the
- *-- need for the procedures SONG1 and SONG2 and the
- *-- memfile created by them.
- *-- Two songs are provided (see below) ...
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: PlayIt(<nSong>)
- *-- Example.....: @5,10 say "Enter last name: " get lName valid required
- *-- .not. empty(lName);
- *-- error PlayIt(1)+"There must be a lastname ..."
- *-- Read
- *-- && OR
- *-- ?? PlayIt(2)
- *-- Returns.....: Nul (or Beep on invalid parameter)
- *-- Parameters..: nSong = Song number. Programmer might consider adding
- *-- to the list below for any songs added for
- *-- documentation purposes ...
- *-- VALID VALUES/SONGS:
- *-- 1 = Dirge
- *-- 2 = "Touchdown"
- *-----------------------------------------------------------------------
-
- parameter nSong
- private aSong, nCounter
-
- *-- check for valid type of parameter ... must be numeric ...
- if .not. type("nSong") $ "NF"
- return chr(7)
- endif
-
- *-- get the integer value of nSong ... in case someone tries a
- *-- "fast one"
- m->nSong = int(m->nSong)
-
- *-- load song
- do case
- case m->nSong = 1 && dirge
- declare aSong[12,2] && 12 notes, 2 parts each
- store 220 to aSong[1,1] && pitch
- store 10 to aSong[1,2] && duration
- store 220 to aSong[2,1]
- store 10 to aSong[2,2]
- store 220 to aSong[3,1]
- store 2 to aSong[3,2]
- store 220 to aSong[4,1]
- store 10 to aSong[4,2]
- store 261.63 to aSong[5,1]
- store 7 to aSong[5,2]
- store 246.94 to aSong[6,1]
- store 2 to aSong[6,2]
- store 246.94 to aSong[7,1]
- store 5 to aSong[7,2]
- store 220 to aSong[8,1]
- store 5 to aSong[8,2]
- store 220 to aSong[9,1]
- store 5 to aSong[9,2]
- store 205 to aSong[10,1]
- store 5 to aSong[10,2]
- store 220 to aSong[11,1]
- store 15 to aSong[11,2]
- case m->nSong = 2 && "touchdown"
- declare aSong[7,2] && 7 notes, 2 parts each
- store 523.5 to aSong[1,1] && pitch
- store 2 to aSong[1,2] && duration
- store 587.33 to aSong[2,1]
- store 2 to aSong[2,2]
- store 659.29 to aSong[3,1]
- store 2 to aSong[3,2]
- store 783.99 to aSong[4,1]
- store 7 to aSong[4,2]
- store 659.29 to aSong[5,1]
- store 2 to aSong[5,2]
- store 783.99 to aSong[6,1]
- store 10 to aSong[6,2]
- otherwise && not song 1 or 2, return nothing
- return chr(7)
- endcase
-
- *-- playback
- m->nCounter = 1
- do while type("aSong[m->nCounter,1]") = "N"
- set bell to aSong[m->nCounter,1],aSong[m->nCounter,2]
- ?? chr(7) at col()
- m->nCounter = m->nCounter + 1
- enddo
- set bell to && return value to original
-
- RETURN ""
- *-- EoF: PlayIt()
-
- PROCEDURE PageEst
- *-----------------------------------------------------------------------
- *-- Programmer..: Rachel Holmen (RAEHOLMEN)
- *-- Date........: 02/04/1992
- *-- Notes.......: This procedure estimates the number of pages needed
- *-- for an output list.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 01/15/1992 - original procedure.
- *-- 02/04/1992 - Ken Mayer - overhaul to allow the sending
- *-- of parameters for fields, rather than hard coding.
- *-- Attempted to make this a "black box" procedure.
- *-- Calls.......: CENTER Procedure in PROC.PRG
- *-- SHADOW Procedure in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: Do PageEst with <nCount>,"<cReport>",<nRecords>
- *-- Example.....: Use printers
- *-- Do PageEst with 0,"Printer for 'Hew' $ Brand",55
- *-- Returns.....: None
- *-- Parameters..: nCount = record count for records to be printed ...
- *-- if sent as "0", system will do a RECCOUNT()
- *-- for you
- *-- cReport = name of report, with any filters ...
- *-- (FOR ...)
- *-- nRecords = number of records per page the report will
- *-- handle. If sent as "0", system will
- *-- assume 60 ...
- *-----------------------------------------------------------------------
-
- parameters nCount,cReport,nRecords
- private cReport2,nPos,nPage,cPage,cChoice,cCursor
-
- cReport2 = upper(m->cReport)
-
- *-- make sure we have a number of records to work with ...
- if m->nCount = 0
- if at("FOR",m->cReport2) > 0 && if a filter, extract the filter
- m->nPos = at("FOR",m->cReport2) && so we can count records
- && that match
- cFilter = substr(m->cReport,m->nPos+3,;
- len(m->cReport)-(m->nPos-1))
- count to m->nCount for &cFilter.
- else
- m->nCount = reccount()
- endif
- endif
-
- if m->nRecords = 0
- m->nRecords = 60
- endif
-
- *-- calculate the number of pages for the report ...
- store int(m->nCount/m->nRecords) to m->nPage
- if mod(m->nCount,m->nRecords) > 45
- store m->nPage+1 to m->nPage
- else
- store (m->nCount/m->nRecords) to m->nPage
- endif
- if m->nCount>0 .and. m->nCount < m->nRecords
- store 1 to m->nPage
- endif
-
- *-- deal with displaying info, and printing the report ...
- save screen to sPrinter
- activate screen && in case there are other
- && windows on screen ...
- define window wPrinter from 8,15 to 15,65 double color;
- rg+/gb,w/n,rg+/gb
- do shadow with 8,15,15,65
- activate window wPrinter
-
- *-- figure out how much to tell the user ...
- if mod(m->nCount,m->nRecords) > 19 .and. ;
- mod(m->nCount,m->nRecords) < 46
- store ltrim(str(m->nPage))+" and a half pages.)" to cPage
- else
- store ltrim(str(m->nPage))+" pages.)" to cPage
- endif
-
- if m->nPage = 1
- store "one page.)" to cPage
- endif
-
- *-- display info ...
- do center with 1,50,"",;
- "There are "+ltrim(str(m->nCount))+" records."
- do center with 2,50,"","(That's approximately "+m->cPage
-
- *-- ask if they want to generate the report?
- store space(1) to cChoice
- @4,8 say "Do you want to print the list? " get m->cChoice ;
- picture "!" ;
- valid required m->cChoice $ "YN";
- error chr(7)+"Enter 'Y' or 'N'!"
- read
-
- *-- if yes, do it ...
- if m->cChoice = "Y"
- clear && just this window ...
- do center with 2,50,"","Align paper in your printer."
- do center with 3,50,"","Press any key to continue ..."
- x=inkey(0)
- clear
- do center with 2,50,"","... Printing ... do not disturb ..."
- cCursor = set("CURSOR")
- set cursor off
- set console off
- report form &cReport. to print
- set console on
- set cursor &cCursor.
- endif
-
- *-- cleanup
- deactivate window wPrinter
- release window wPrinter
- restore screen from sPrinter
- release screen sPrinter
-
- RETURN
- *-- EoP: PageEst
-
- FUNCTION Permutes
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Permutations of nNum items taken Nhowmany at a time
- *-- That is, the number of possible arrangements, as
- *-- the different ways a president, V.P. and sec'y may
- *-- be chosen from a club of 10 members
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Permutes(<nNum>,<nHowMany>)
- *-- Example.....: ?Permutes(10,3)
- *-- Returns.....: Numeric
- *-- Parameters..: nNum = number of items in the entire set
- *-- nHowMany = number to be used at once
- *-----------------------------------------------------------------------
-
- parameters nNum, nHowmany
- private nResult, nCounter
- store 1 to nResult, nCounter
- do while m->nCounter <= m->nHowmany
- m->nResult = m->nResult * ( m->nNum + 1 - m->nCounter )
- m->nCounter = m->nCounter + 1
- enddo
-
- RETURN m->nResult
- *-- EoF: Permutes()
-
- FUNCTION Combos
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Combinations, similar to Permutations
- *-- Combinations treat "1, 3" as the same as
- *-- "3, 1", unlike permutations. This gives the
- *-- games needed for a round robin and helps with
- *-- figuring odds of most state lotteries.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Combos(<nNum>,<nHowMany>)
- *-- Example.....: ?Combos(10,2)
- *-- Returns.....: Numeric
- *-- Parameters..: nNum = number of items in the entire set
- *-- nHowMany = number to be used at once
- *-----------------------------------------------------------------------
-
- parameters nNum, nHowmany
- private nResult, nCounter
- store 1 to nResult, nCounter
- do while m->nCounter <= m->nHowmany
- m->nResult = m->nResult * ( m->nNum + 1 - m->nCounter ) / ;
- m->nCounter
- m->nCounter = m->nCounter + 1
- enddo
-
- RETURN m->nResult
- *-- Combos()
-
- FUNCTION BinLoad
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Function to manage .bin files
- *-- A call to this function results in the following
- *-- actions:
- *--
- *-- If the name of a binary module alone is given as the
- *-- argument, the module is loaded if necessary, and .T.
- *-- is returned. If the file cannot be found, returns .F.
- *-- An error occurring during the load will cause a dBASE
- *-- error.
- *--
- *-- If the argument "" is given, RELEASES all loaded
- *-- modules and returns .T.
- *--
- *-- If the argument contains the name of a loaded binary
- *-- file and "/R", RELEASEs that file only and returns .T.
- *-- If the file is not listed in "gc_bins_in", returns .F.
- *--
- *-- This function uses the public variable "gc_bins_in".
- *-- It keeps track of the modules loaded by changing the
- *-- contents of that variable. If modules are loaded or
- *-- released without the use of this function, the
- *-- variable will contain an inaccurate list of the
- *-- modules loaded and problems will almost surely occur
- *-- if this function is used later.
- *--
- *-- If more than 16 binary modules are requested over
- *-- time through this function, the one that was named
- *-- least recently in a call to load it by this function
- *-- is released to make room for the new one. This
- *-- will not necessarily be the module last used,
- *-- unless care is taken to use this function to "reload"
- *-- the .bin before each call.
- *--
- *-- Suggested syntax, to call the binary routine
- *-- "Smedley.bin" which takes and returns two arguments:
- *--
- *-- IF binload( "Smedley" )
- *-- CALL Smedley WITH Arg1, Arg2
- *-- ELSE
- *-- ? "binary file not available"
- *-- ENDIF
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: ATCOUNT() Function in MISC.PRG
- *-- Called by...: Any
- *-- Usage.......: BinLoad(<cBinName>)
- *-- Example.....: ?BinLoad("Smedley")
- *-- Returns.....: Logical (.T. if successful )
- *-- Parameters..: cBinName = name of bin file to load ...
- *-----------------------------------------------------------------------
-
- parameters cBinname
- private cBin, nPlace, nTemp, lResult
- cBin = ltrim( trim( upper( m->cBinName ) ) )
- if type( "gc_bins_in" ) = "U"
- public gc_bins_in
- m->c_Bins_In = ""
- endif
- m->lResult = .T.
- do case
- case "" = m->cBin
- do while "" # m->c_Bins_In
- m->nPlace = at( "*", m->c_Bins_In )
- m->cBin = left( m->c_Bins_In, m->nPlace - 1 )
- m->c_Bins_In = substr( m->c_Bins_In, m->nPlace + 1 )
- release module &cBin.
- enddo
- release m->c_Bins_In
- case "/R" $ m->cBinName
- m->cBin = trim( left( m->cBin, at( m->cBin, "/" ) - 1 ) )
- if "." $ m->cBin
- m->cBin = left( m->cBin, at( ".", m->cBin ) - 1 )
- endif
- m->nPlace = at( m->cBin, m->c_Bins_In )
- if m->nPlace = 0
- m->lResult = .F.
- else
- m->c_Bins_In = substr( m->c_Bins_In, m->nPlace + 1 )
- release module &cBin.
- endif
- otherwise
- if "." $ m->cBin
- m->cBin = left( m->cBin, at( ".", m->cBin ) - 1 )
- endif
- if .not. file( m->cBin )
- m->lResult = .F.
- else
- if atcount( "*", m->c_Bins_In ) > 15
- m->nPlace = at( "*", m->c_Bins_In )
- cTemp = left( m->c_Bins_In, m->nPlace - 1 )
- release module &cTemp.
- m->c_Bins_In = substr( m->c_Bins_In, m->nPlace + 1)
- endif
- load &cBin
- m->nPlace = at( m->cBin, m->c_Bins_In )
- if nPlace > 0
- m->c_Bins_In = stuff( m->c_Bins_In, m->nPlace, ;
- len( m->cBin ) + 1, "" )
- endif
- m->c_Bins_In = m->c_Bins_In + m->cBin + "*"
- endif
- endcase
-
- RETURN m->lResult
- *-- EoF: BinLoad()
-
- FUNCTION DialUp
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 06/17/1992
- *-- Notes.......: Dial the supplied telephone number. Returns .F. for
- *-- error. This is not a full communications routine.
- *-- It is designed to be used to place voice telephone
- *-- calls, with the user picking up the handset after
- *-- using this function to dial.
- *--
- *-- This will work only with a modem using the standard
- *-- Hayes commands, and only if the port has already
- *-- been set to the desired baud rate, etc., by the DOS
- *-- MODE command or otherwise. If the port and dialing
- *-- method are not constant for the application, rewrite
- *-- the function to accept them as additional parameters.
- *--
- *-- Written for.: dBASE IV, 1.1, 1.5
- *-- Rev. History: 03/01/1992 - original function.
- *-- 04/01/1992 - Jay Parsons - modified for Version 1.5.
- *-- 04/03/1992 - Jay Parsons - ferror() call added.
- *-- 06/17/1992 - Jay Parsons - 1.1 version changed to use
- *-- SET PRINTER TO Device rather than .bin.
- *-- Calls.......: Strpbrk() Function in MISC.PRG
- *-- Called by...: Any
- *-- Usage.......: DialUp(<cPhoneNo>)
- *-- Example.....: x = DialUp( "555-1212" )
- *-- Returns.....: Logical (connect made or not)
- *-- Parameters..: cPhoneNo = Phone number to dial ...
- *-- Side effects: When used for versions before 1.1, sets the printer to
- *-- a COM port and does not reset it.
- *-----------------------------------------------------------------------
-
- parameters cPhoneNo
- private cNumber, cPort, cDialtype, cCallarg, xTemp, nHandle,;
- cString, lResult
- cPort = "Com2" && specify Com1 or Com2 as required
- cDialtype = "Tone" && specify Tone or Pulse ( rotary ) dialing
- cNumber = m->cPhoneNo
- if type( "cPhoneno" ) $ "NF"
- cNumber = ltrim( str( m->cPhoneNo ) )
- else
- do while .t.
- m->xTemp = Strpbrk( m->cNumber, " ()-" )
- if m->xTemp = 0
- exit
- endif
- m->cNumber = stuff( m->cNumber, m->xTemp, 1, "" )
- enddo
- endif
- cString = "ATD" + upper( left( cDialtype, 1 )) + m->cNumber + chr(13)
- if val( substr( version(), 9, 5 ) ) < 1.5
- SET PRINTER TO &cPort.
- ??? m->cString
- m->lResult = .T.
- else
- nHandle = fopen( cPort, "w" )
- if ferror() # 0
- RETURN .F.
- endif
- m->lResult = (fwrite( m->nHandle, m->cString) = len( m->cString ))
- m->xTemp = fclose( m->nHandle )
- endif
-
- RETURN m->lResult
- *-- EoF: Dialup()
-
- FUNCTION CurrPort
- *-----------------------------------------------------------------------
- *-- Programmer..: David P. Brown (RHEEM)
- *-- Date........: 03/22/1992
- *-- Notes.......: This procedure gets the current SET PRINTER TO
- *-- information. Will return a port or a filename if set
- *-- to a file. This also requires a DBF file called
- *-- CURRPRT.DBF, with an MDX tag set on the only field
- *-- CURRPRT, which is a character field of 80 characters.
- *--
- *-- Structure for database: CURRPRT.DBF
- *-- Number of data records: 0
- *-- Date of last update : 03/22/92
- *-- Field Field Name Type Width Dec Index
- *-- 1 CURRPRT Character 80 Y
- *-- ** Total ** 81
- *--
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/18/1992 - original function.
- *-- 03/18/1992 -- Ken Mayer (CIS: 71333,1030) to clean it
- *-- up a bit, and make it a function (not requiring the
- *-- public memvar that was originally required).
- *-- 03/21/1992 -- David P. Brown (RHEEM) found bug while
- *-- selecting a previous work area (stored on cDBF).
- *-- Changed 'select cDBF' to 'select (cDBF)'.
- *-- 03/22/1992 -- David P. Brown (RHEEM) final revision.
- *-- Added check for no available work areas. If none is
- *-- available then the program returns a null.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: CurrPort()
- *-- Example.....: ? CurrPort()
- *-- Returns.....: the current port, as a character value
- *-- Port: LPTx:, COMx:, PRN:
- *-- File: Filename (with or without drive and path,
- *-- depends on how the user entered it in the
- *-- SET command)
- *-- Other: Null (no work area available)
- *-- Parameters..: None
- *-----------------------------------------------------------------------
-
- private cSafety, cConsole, cDBF, cPort
-
- *-- Check for available work area (safety check)
- if select() = 0
- return ""
- endif
- *-- Setup
- cSafety = set("SAFETY")
- set safety off
- *-- so user can't see what's going on
- cConsole = set("CONSOLE")
- set console off
-
- if file("CURRPRT$.OUT") && if this file exists
- erase CURRPRT$.OUT && delete it, so we can write on it
- endif
-
- cDBF = alias() && get current work area, so we can return
-
- *-- Get current printer
- *-- note that we are not using 'Set Printer to file ...' due to the
- *-- fact that this will change the info that the 'LIST STAT' command
- *-- issues ...
- set alternate to currprt$.out && direct screen input to file
- set alternate on
- list status && returns environment information
- set alternate off && turn off 'capture'
- close alternate && close file 'currprt$.out'
-
- select select() && grab next available work area ...
-
- use currprt order currprt excl && open database called CURRPRT
- zap && clean out old copy of this file
-
- append from currprt$.out type sdf
- && import the data for manipulation
-
- seek "Print"
- *-- This is setup to do an indexed search, since the printer
- *-- information will not always be on the same line. If it were,
- *-- we could issue a 'GO <n>' command, which would speed up the
- *-- routine. Somewhere on line 8 to 12 (or record) is 'Print
- *-- destination: <port/file>'. The seek looks for the first word.
- *-- The command below trims out the first part of the line, and
- *-- extra spaces as well. This will return the information after
- *-- the colon.
- cPort = upper(trim(right(currprt->currprt,60)))
- && always in upper case
-
- *-- clean up
- use
-
- if len(trim(m->cDBF)) > 0
- select (m->cDBF)
- else
- select 1
- endif
-
- *-- erase this file
- erase currprt$.out
-
- *-- return safety and console to previous states ...
- set safety &cSafety.
- set console &cConsole.
-
- RETURN m->cPort
- *-- EoF: CurrPort()
-
- FUNCTION FileLock
- *-----------------------------------------------------------------------
- *-- Programmer..: Miriam Liskin
- *-- Date........: 04/27/1992
- *-- Notes.......: Taken from Miriam Liskin's dBASE IV, 1.1 Programming
- *-- Book. This routine modified by Ken Mayer to handle
- *-- slightly fancier processing ...
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 04/27/1992 -- Modified by Ken Mayer to give cleaner
- *-- windows and such.
- *-- Calls.......: CENTER Procedure in PROC.PRG
- *-- SHADOW Procedure in PROC.PRG
- *-- COLORBRK() Function in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: FileLock("<cColor>")
- *-- Example.....: if FileLock(cl_Wind1)
- *-- *-- pack/reind/whatever you need to do to database
- *-- else
- *-- *-- do whatever processing necessary if file not
- *-- *-- available for locking at this time
- *-- endif
- *-- Returns.....: Logical (.t./.f.)
- *-- Parameters..: cColor = Color combination for window ...
- *-----------------------------------------------------------------------
-
- parameters cColor
- private nCount,lLock,x,cCurNorm,cCurBox,cTempCol
-
- *-- deal with dBASE IV standard errors -- we don't want program
- *-- bombing
- on error ??
-
- *-- deal with screen stuff ...
- *-- get it started ...
- m->nCount = 1 && start at 1
- m->lLock = .t. && assume true
-
- *-- try 100 times
- do while m->nCount <= 100 .and. .not. flock() .and. inkey() = 0
- m->nCount = m->nCount + 1
- enddo
-
- *-- if we can't lock the file, let the user know ...
- if .not. flock()
- m->lLock = .f.
- save screen to sLock
- *-- save colors
- cCurNorm = colorof("NORMAL")
- cCurBox = colorof("BOX")
- *-- set new colors
- cTempCol = colorbrk(cColor,1)
- set color of normal to &cTempCol.
- cTempCol = colorbrk(cColor,3)
- set color of box to &cTempCol.
- *-- define window, display message
- activate screen
- define window wLock from 10,15 to 18,65 double
- do shadow with 10,15,18,65
- activate window sLock
- do center with 1,50,"","The file cannot be locked at this time"
- do center with 2,50,"","Please try again."
- x = inkey(0)
- *-- cleanup
- deactivate window wLock
- release window wLock
- restore screen from sLock
- release screen sLock
- *-- reset colors
- set color of normal to &cCurNorm.
- set color of box to &cCurBox.
- endif
-
- *-- clean up screen, etc.
- on error
-
- RETURN m->lLock
- *-- EoF: FileLock()
-
- FUNCTION RecLock
- *-----------------------------------------------------------------------
- *-- Programmer..: Miriam Liskin
- *-- Date........: 04/27/1992
- *-- Notes.......: Taken from Miriam Liskin's dBASE IV, 1.1 Programming
- *-- Book. This function attempts to lock current record
- *-- in active database.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 04/27/1992 -- Modified by Ken Mayer to give cleaner
- *-- windows and such.
- *-- Calls.......: SHADOW Procedure in PROC.PRG
- *-- COLORBRK() Function in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: RecLock("<cColor>")
- *-- Example.....: if RecLock("&cl_Wind1")
- *-- *-- process record
- *-- else
- *-- *-- return to menu, or whatever processing your
- *-- *-- routine does at this point
- *-- endif
- *-- Returns.....: Logical (.t./.f.)
- *-- Parameters..: cColor = Color combination for window ...
- *-----------------------------------------------------------------------
-
- parameters cColor
- private nCount, lLock, cRetry, cCurNorm, cCurBox, cTempCol
-
- *-- deal with dBASE IV standard errors -- we don't want program
- *-- bombing
- on error ??
-
- *-- deal with screen
- *-- start trying -- we will give the user the option to exit -- each
- *-- time they unsuccessfully lock the record.
- m->lLock = .t. && assume true
- do while .t. && main loop
- m->nCount = 1 && initialize each time we try ...
-
- *-- effectively a time-delay loop ...
- do while m->nCount <= 100 .and. .not. rLock() .and. inkey() = 0
- m->nCount = m->nCount + 1
- enddo
-
- *-- if we CAN lock it, we're done, get outta here ...
- if rlock()
- m->lLock = .t.
- exit
-
- else
-
- *-- otherwise, let the user know we couldn't do it, and ask if
- *-- they want to try again ...
- save screen to sLock
- *-- save colors
- cCurNorm = colorof("NORMAL")
- cCurBox = colorof("BOX")
- *-- set new colors
- cTempCol = colorbrk(cColor,1)
- set color of normal to &cTempCol.
- cTempCol = colorbrk(cColor,3)
- set color of box to &cTempCol.
- *-- define window ...
- activate screen
- define window wLock from 10,15 to 18,65 double
- do shadow with 10,15,18,65
- activate window wLock
- m->lLock = .f.
- cRetry = 'N'
- @1,3 say "This record is being updated at another"
- @2,3 say "workstation. You can try again now,"
- @3,3 say "to access the record, or return to it"
- @4,3 say "later."
- @6,3 say "Do you want to try again now? " get m->cRetry;
- picture "!";
- valid required m->cRetry $ "YN";
- error chr(7)+"Enter 'Y' or 'N'"
- read
- *-- cleanup
- deactivate window wLock
- release window wLock
- restore screen from sLock
- release screen sLock
- *-- reset colors
- set color of normal to &cCurNorm.
- set color of box to &cCurBox.
-
- if cRetry = "N"
- exit
- endif && cRetry = "N"
-
- endif && rLock()
-
- enddo && end of main loop
-
- *-- cleanup
- on error
-
- RETURN m->lLock
- *-- EoF: RecLock()
-
- FUNCTION UserId
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (ANGUSSF)
- *-- Date........: 04/20/1992
- *-- Notes.......: Returns log-in USER ID regardless of Network Type
- *-- *************************************************
- *-- ** IF DBASE IV VERSION IS < 1.5 THIS REQUIRES **
- *-- ** USERID.BIN **
- *-- *************************************************
- *-- Written for.: dBASE IV v1.5, will work in 1.1, if you use EMPTY()
- *-- Rev. History: 10/27/1992 -- Ken Mayer cleaned up a tad ...
- *-- Calls.......: None if version 1.5, EMPTY() if version 1.1
- *-- Called by...: Any
- *-- Usage.......: UserID()
- *-- Example.....: ? UserID()
- *-- Returns.....: Character String (up to 8 characters)
- *-- Parameters..: None
- *-----------------------------------------------------------------------
-
- private cTemp
- if network()
- if .not. isblank(getenv("USERID"))
- *-- if you're working on a Lantastic net, USERID will lock the
- *-- system up. Use a DOS environment variable USERID instead.
- *-- This also works as a temporary override for testing access
- *-- levels.
- cTemp = left(getenv("USERID"),8)
- else
- if val(right(version(),3)) => 1.5 && version 1.5 of dBASE IV
- cTemp = id()
- else
- cTemp = space(48)
- if file("USERID.BIN")
- load userid
- call userid with cTemp
- release module userid
- endif && file("USERID.BIN")
- endif && val(right...)
- endif && .not. isblank(getenv ...
- else
- cTemp = ""
- endif && network()
-
- RETURN left(m->cTemp,8) && which MIGHT be empty ...
- *-- EoF: UserID()
-
- PROCEDURE DosShell
- *-----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 06/10/1992
- *-- Notes.......: Swaps out dBASE from memory, loads a DOS shell
- *-- Written for.: dBASE IV v1.5
- *-- Rev. History: 06/10/1992 -- Original Release
- *-- Calls.......: TempName() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: do DosShell with <cAppName>
- *-- Example.....: do DosShell with "MyApp"
- *-- Parameters..: cAppName - the name of the application
- *-----------------------------------------------------------------------
- parameter cAppName
-
- private cDir, lCursOff, cBatFile, nFH, nResult
- cAppName = iif(pcount() = 0, "the application", m->cAppName)
- private all
- cDir = set("directory")
- lCursOff = ( set("cursor") = "OFF" )
- cBatFile = tempname("bat") + ".bat"
- nFH = fcreate(m->cBatFile)
- if m->nFH > 0
- nBytes = fputs(m->nFH,"@echo off")
- nBytes = fputs(m->nFH,"cls")
- nBytes = fputs(m->nFH,"echo " + chr(255)) && echo a blank line
- nBytes = fputs(m->nFH,"echo NOTE: Enter EXIT to resume " + ;
- m->cAppName + ".")
- nBytes = fwrite(m->nFH,getenv("comspec"))
- null = fclose(m->nFH)
- set cursor on
- m->nResult = run(.f., m->cBatFile, .t.)
- if m->nResult # 0
- run &cBatFile.
- endif
- erase (m->cBatFile)
- else
- cComSpec = getenv("comspec")
- set cursor on
- run &cComSpec.
- endif
- if m->lCursOff
- set cursor off
- endif
- set directory to &cDir.
-
- RETURN
- *-- EoP: DosShell
-
- FUNCTION IsDisk
- *-----------------------------------------------------------------------
- *-- Programmer...: Ken Mayer (CIS: 71333,1030)
- *-- Date.........: 07/13/1992
- *-- Notes........: This routine is useful to check a drive for a valid
- *-- disk in in it (Valid means it is in the drive, with
- *-- the door closed, and is formatted ...).
- *-- ***********************
- *-- ** REQUIRES DISK.BIN **
- *-- ***********************
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 07/13/1992 -- Original Release
- *-- Called by...: None
- *-- Calls.......: CENTER Procedure in PROC.PRG
- *-- SHADOW Procedure in PROC.PRG
- *-- Usage.......: IsDisk(<cDrive>,<cMessCol>,<cErrCol>)
- *-- Example.....: IsDisk("cDrive","rg+/gb","rg+/r")
- *-- Returns.....: Logical
- *-- Parameters..: cDrive = drive name -- single letter, no colon
- *-- (i.e., "A")
- *-- cMessCol = color for message box
- *-- cErrCol = color for error message
- *-----------------------------------------------------------------------
-
- parameters cDrive, cMessCol, cErrCol
-
- private nX, cDrive2
-
- *-- deal with message window
- save screen to sDisk
- activate screen
- define window wDisk from 9,15 to 12,65 double color ;
- &cMessCol.,,&cMessCol.
- do shadow with 9,15,12,65
- activate window wDisk
- *-- display message ...
- do center with 0,50,m->cMessCol,;
- "Place disk in drive "+m->cDrive+": and close drive door."
- do center with 1,50,cMessCol,;
- "Press any key when ready ..."
- set cursor off
- nX=inkey(0)
- set cursor on
- deactivate window wDisk
- restore screen from sDisk
-
- *-- check for a valid drive. This uses the BIN file: DISK.BIN to
- *-- do so.
- load disk && load the BIN file
- cDrive2 = m->cDrive && save the current setting in case
- && there's a prob.
- call disk with m->cDrive2 && check to see if it's valid
- activate screen
- define window wDisk from 7,10 to 14,70 double ;
- color &cErrCol.,,&cErrCol.
- do while m->cDrive2 = 'X'
- && perform loop if value of cDrive2 is 'X' (error)
- do shadow with 7,10,14,70
- activate window wDisk
- do center with 0,60,m->cErrCol,;
- "** DRIVE ERROR **"
- do center with 2,60,m->cErrCol,;
- "Check to make sure a valid (formatted) disk is in drive,"
- do center with 3,60,m->cErrCol,;
- "and that the drive door is closed properly."
- do center with 5,60,m->cErrCol,;
- "Press <Esc> to exit, any other key to continue ..."
- set cursor off
- nX=inkey(0)
- set cursor on
- deactivate window wDisk
- restore screen from sDisk
- if m->nX = 27 && user pressed <Esc>
- release module disk
- release window wDisk
- release screen sDisk
- RETURN .F.
- endif
- cDrive2 = m->cDrive && reset cDrive2 from original
- call disk with m->cDrive2 && check for validity again ...
- enddo
-
- *-- cleanup
- release module Disk && remove module from RAM so we can continue
- restore screen from sDisk
- release screen sDisk
- release window wDisk
-
- RETURN .t.
- *-- EoF: IsDisk()
-
- FUNCTION IsDisk2
- *-----------------------------------------------------------------------
- *-- Programmer...: Ken Mayer (CIS: 71333,1030)
- *-- Date.........: 12/15/1993
- *-- Notes........: This routine is useful to check a drive for a valid
- *-- disk in in it (Valid means it is in the drive, with
- *-- the door closed, and is formatted ...). This version
- *-- of the above (ISDISK()) checks to see if the disk
- *-- is write-protected, also.
- *-- *************************
- *-- ** REQUIRES ISDISK.BIN **
- *-- *************************
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 07/13/1992 -- Original Release
- *-- Called by...: None
- *-- Calls.......: CENTER Procedure in PROC.PRG
- *-- SHADOW Procedure in PROC.PRG
- *-- Usage.......: IsDisk(<cDrive>,<cMessCol>,<cErrCol>)
- *-- Example.....: IsDisk("cDrive","rg+/gb","rg+/r")
- *-- Returns.....: Logical
- *-- Parameters..: cDrive = drive name -- single letter, no colon
- *-- (i.e., "A")
- *-- cMessCol = color for message box
- *-- cErrCol = color for error message
- *-----------------------------------------------------------------------
-
- parameters cDrive, cMessCol, cErrCol
- private nX, cDrive2
-
- *-- deal with message window
- save screen to sDisk
- activate screen
- define window wDisk from 9,15 to 12,65 double color ;
- &cMessCol.,,&cMessCol.
- do shadow with 9,15,12,65
- activate window wDisk
- *-- display message ...
- do center with 0,50,m->cMessCol,;
- "Place disk in drive "+m->cDrive+": and close drive door."
- do center with 1,50,cMessCol,;
- "Press any key when ready ..."
- set cursor off
- nX=inkey(0)
- set cursor on
- deactivate window wDisk
- restore screen from sDisk
-
- *-- check for a valid drive. This uses the BIN file: ISDISK.BIN to
- *-- do so.
- load isdisk && load the BIN file
- cDrive2 = m->cDrive && save the current setting in case
- && there's a prob.
- call isdisk with m->cDrive2 && check to see if it's valid
- activate screen
- define window wDisk from 7,10 to 14,70 double ;
- color &cErrCol.,,&cErrCol.
- do while m->cDrive2 $ 'WX' && 'W' = Write protected
- && 'X' = other error
- do shadow with 7,10,14,70
- activate window wDisk
- do center with 0,60,m->cErrCol,;
- "** DRIVE ERROR **"
- if m->cDrive2 = "X"
- do center with 2,60,m->cErrCol,;
- "Check to make sure a valid (formatted) disk is in drive,"
- do center with 3,60,m->cErrCol,;
- "and that the drive door is closed properly."
- else
- do center with 2,60,m->cErrCol,;
- "Disk is write-protected -- remove write-protect tab."
- endif
- do center with 5,60,m->cErrCol,;
- "Press <Esc> to exit, any other key to continue ..."
- set cursor off
- nX=inkey(0)
- set cursor on
- deactivate window wDisk
- restore screen from sDisk
- if m->nX = 27 && user pressed <Esc>
- release module isdisk
- release window wDisk
- release screen sDisk
- RETURN .F.
- endif
- cDrive2 = m->cDrive && reset cDrive2 from original
- call isdisk with m->cDrive2 && check for validity again ...
- enddo
-
- *-- cleanup
- release module IsDisk && remove module from RAM so we can continue
- restore screen from sDisk
- release screen sDisk
- release window wDisk
-
- RETURN .t.
- *-- EoF: IsDisk()
-
- PROCEDURE BlankIt
- *-----------------------------------------------------------------------
- *-- Programmer..: Bill Garrison (BILLG), Roger Breckenridge
- *-- Date........: 08/29/1993
- *-- Notes.......: Screen Saver from within dbase - uploaded to Public
- *-- Domain
- *-- Written for.: dBase IV 1.5 (probably work with 1.1 though)
- *-- Rev. History: Original clock prg was from Michael Irwin, who I
- *-- believe expanded on it from source unknown.
- *-- 10/29/1992: Modified original program received at
- *-- Ashton-Tate Seminar a year or so ago.
- *-- Fine tuned it and added moving-clock
- *-- feature.
- *-- 11/02/1992: Modified -- Ken Mayer -- dUFLP and added
- *-- Jay's RECOLOR routine, as SET COLOR TO
- *-- does not reset properly.
- *-- 01/08/1992: Fixed ON KEY reset, which was to "Blanker",
- *-- not "Blankit".
- *-- 08/29/1993 - Jay Parsons. Tightened code, added notes
- *-- about "ON KEY" usage, changed to halt on
- *-- any keypress.
- *-- Calls.......: CLOCKDEF Procedure in MISC.PRG
- *-- : RECOLOR Procedure in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: Do BLANKIT
- *-- Example.....: ON KEY LABEL Alt-B DO BlankIt
- *-- Returns.....: None
- *-- Parameters..: None
- *-----------------------------------------------------------------------
-
- * The next code line, and the later on key line restoring the trap,
- * should be changed to the label of the key being used, and the
- * asterisk removed, if this is being called by an on-key trap.
- * on key label alt-B && turn off key that called this prg
-
- save screen to sBlanker
- private cTimeAll,cChar,m->nTX,nTY,lNoKey,clSet2,cTalk,cCursor,cEsc
-
- *-- save settings
- cCursor= set("CURSOR")
- cEsc = set("ESCAPE")
- cTalk = set("TALK")
- set cursor off
- set talk off
- set escape off
-
- *-- screen colors
- clSet2 = set("ATTRIBUTES")
- set color to N/N,N/N,N/N
- activate screen
- clear
-
- *-- declare arrays and initialize display strings
- declare cChar[ 11 ] && 10 digits and colon
- declare cTimeAll[ 3 ] && the display strings
- store space( 27 ) to cTimeall[ 1 ], cTimeall[ 2 ], cTimeall[ 3 ]
-
- *-- define the big characters
- do ClockDef
-
- *-- wait for user to do something ...
- store 0 to m->nTX,m->nTY
- lNoKey = .T.
- do while m->lNoKey
- do ClockIt with 10 && display clock 10 seconds
- m->nTX = iif( m->nTX > 16, 0, m->nTX + 2 ) && move the clock
- m->nTY = iif( m->nTY > 46, 0, m->nTY + 4 )
- enddo
-
- *-- reset
- do recolor with m->clSet2
- if m->cCursor = "ON"
- set cursor on
- endif
- if m->cEsc = "ON"
- set escape on
- endif
- if m->cTalk = "ON"
- set talk on
- endif
- restore screen from sBlanker
- release screen sBlanker
- * see note above about next line
- * on key label alt-B do blankit && reset on key
-
- RETURN
- *-- EoP: BlankIt
-
- PROCEDURE ClockIt
- *-----------------------------------------------------------------------
- *-- Programmer..: Bill Garrison (BILLG) and Roger Breckenridge
- *-- Date........: 08/29/1993
- *-- Notes.......: Display clock for BLANKIT routine.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/19/1992 -- Original Release
- *-- : 08/29/1993 - Jay Parsons - made nSecs a parameter,
- *-- revised algorithm slightly
- *-- Called by...: BLANKIT Procedure in MISC.PRG
- *-- Usage.......: do ClockIt with <nSecs>
- *-- Example.....: do clockit with 10
- *-- Returns.....: None
- *-- Parameters..: nSecs Number of seconds before clock shifts
- *-- on screen
- *-----------------------------------------------------------------------
-
- parameters nSecs
- private nCount, cTime, cOld, nChar, nRow, nDigit, cAPm, nHrs, nAt
- define window wClock from m->nTX,m->nTY to m->nTX+5,m->nTY+30 ;
- color W+/N+,,GR+/R
- activate window wClock
- m->nCount = 0
- cTime = time()
- cOld = space( 8 )
- do while m->nCount < nSecs
-
- * convert time to AM/PM
- nHrs = val( left( m->cTime, 2 ) )
- if m->nHrs > 11
- cAPm = "P.M."
- if m->nHrs > 12
- nHrs = m->nHrs - 12
- endif
- cTime = right( str( 100 + m->nHrs ), 2 ) + right( m->cTime, 6 )
- else
- cAPm = "A.M."
- endif
-
- * stuff each display row with the corresponding 3 chars of the
- * new big char for that digit if changed.
- nRow = 1
- do while m->nRow < 4
- nChar = 8
- nAt = 25
- * since time changes right to left, stuff accordingly, stopping
- * when no change appears
- do while m->nChar > 0 .and. substr( m->cOld, m->nChar, 1 ) ;
- # substr( m->cTime, m->nChar, 1 )
- * colons are 11th element of array of big chars
- * others are in place of their digit except 0 = cChar[10]
- if mod( m->nChar, 3 ) = 0
- if cOld # space( 8 ) && colons are already done
- nChar = m->nChar - 1
- loop
- endif
- nDigit = 11
- else
- nDigit = val( substr( m->cTime, m->nChar, 1 ) )
- nDigit = iif( m->nDigit = 0, 10, m->nDigit )
- endif
- * select the three chars in the string for the digit that
- * correspond to the row and stuff them in place in the
- * display string for that row
- cTimeall[ m->nRow ] = stuff(cTimeall[ m->nRow ], m->nAt, 3,;
- substr( cChar[ m->nDigit ], 3 * m->nRow - 2, 3 ) )
- nChar = m->nChar - 1
- * leave spaces after digits 1, 4 and 7 to separate the
- * big digits of the hours, etc.
- nAt = m->nAt - 3 - iif( mod( m->nChar, 3 ) = 1, 1, 0 )
- enddo
- nRow = m->nRow + 1
- enddo
- *-- display it
- @ 0, 25 say m->cAPm
- @ 1, 1 say cTimeAll[1]
- @ 2, 1 say cTimeAll[2]
- @ 3, 1 say cTimeAll[3]
-
- *-- get input from user?
- cOld = m->cTime
- do while right( m->cOld, 1 ) = right( m->cTime, 1 )
- if inkey() # 0
- lNoKey = .F.
- exit
- endif
- cTime = time()
- enddo
- if .not. m->lNoKey
- exit
- endif
- m->nCount = m->nCount + 1
- enddo
- release window wClock
-
- RETURN
- *-- EoP: ClockIt
-
- PROCEDURE ClockDef
- *-----------------------------------------------------------------------
- *-- Programmer..: Bill Garrison (BILLG) and Roger Breckenridge
- *-- Date........: 08/29/1993
- *-- Notes.......: Clock Routine (part of BLANKIT) -- defines big chars,
- *-- ten digits and colon, used for clock.
- *-- In addition to the space, the characters used are:
- *-- fl chr(223), top half block
- *-- € chr(219), full block
- *-- ‹ chr(220), bottom half block
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/29/1992 -- Original Release
- *-- 08/29/1992 - Jay Parsons - rearranged arrays and the
- *-- digits for clarity
- *-- Calls.......: None
- *-- Called by...: BLANKIT Procedure in MISC.PRG
- *-- Usage.......: do clock
- *-- Example.....: do clock
- *-- Returns.....: None
- *-- Parameters..: None
- *-----------------------------------------------------------------------
-
- cChar[ 1 ] =" €";
- +" €";
- +" fl"
- cChar[ 2 ] ="flfl€";
- +"€flfl";
- +"flflfl"
- cChar[ 3 ] ="flfl€";
- +" fl€";
- +"flflfl"
- cChar[ 4 ] ="€ €";
- +"flfl€";
- +" fl"
- cChar[ 5 ] ="€flfl";
- +"flfl€";
- +"flflfl"
- cChar[ 6 ] ="€flfl";
- +"€fl€";
- +"flflfl"
- cChar[ 7 ] ="flfl€";
- +" €";
- +" fl"
- cChar[ 8 ] ="€fl€";
- +"€fl€";
- +"flflfl"
- cChar[ 9 ] ="€fl€";
- +"flfl€";
- +"flflfl"
- cChar[ 10 ] ="€fl€";
- +"€ €";
- +"flflfl"
- cChar[ 11 ] =" ‹ ";
- +" ‹ ";
- +" "
-
- RETURN
- *-- EoP: ClockDef
-
- FUNCTION AuxMsg
- *-----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- From ideas by Robert Scola & Sal Ricciardi
- *-- published in PC Magazine, Volume 11, Number 21
- *-- Date........: 11/21/1992
- *-- Notes.......: AuxMsg will output a character string to the DOS AUX
- *-- device. If a dual monitor system is in use and the
- *-- DOS device driver OX.SYS is loaded, the string will
- *-- print on the mono monitor. Parameter 2 determines
- *-- whether the string is preceeded by a linefeed or not.
- *-- ******************************************************
- *-- * OX.SYS must be loaded in CONFIG.SYS file, and *
- *-- * machine booted with it ... *
- *-- ******************************************************
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 11/21/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: AuxMsg( cMsg, lLF )
- *-- Example.....: ? AuxMsg( time(), .t. )
- *-- cJunk = AuxMsg( cMemVar, .f. )
- *-- cJunk = AuxMsg( "Hello! )
- *-- Returns.....: ""
- *-- Parameters..: cMsg = string to output to AUX
- *-- lLF = .t. or .f., linefeed or not
- *-----------------------------------------------------------------------
-
- parameters cMsg, lLF
- private nAux, CRLF
- CRLF = chr(13) + chr(10)
- nAux = fopen( "aux", "w" )
- if m->lLF
- l = fwrite( m->nAux, m->CRLF )
- endif
- if type( "cMsg" ) = "C"
- l = fwrite( m->nAux, m->cMsg )
- endif
- l = fclose( m->nAux )
-
- RETURN ""
- *-- EoF: AuxMsg()
-
- FUNCTION Gcd
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/03/1992
- *-- Notes.......: Greatest common divisor of two integers. Given two
- *-- integers, returns their largest common divisor.
- *-- Returns 0 if one or both are not integers, but returns
- *-- the absolute value of the gcd if one or both are
- *-- negative.
- *-- If one is 0, returns the other.
- *-- Usually known as "Euclid's algorithm."
- *-- The algorithm used is discussed in 4.5.2 of
- *-- Volume II, "The Art of Computer Programming", 2d
- *-- edition, Addison-Wesley, Reading, MA, by Donald Knuth.
- *-- Written for.: dBASE IV, 1.1 and 1.5
- *-- Rev. History: 12/03/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Gcd( <n1>, <n2> )
- *-- Example.....: ? Gcd( 24140, 40902 )
- *-- Returns.....: numeric, the Gcd, or 0 if not both integers ( 34 in
- *-- example).
- *-- Parameters..: n1 = numeric, one of the integers
- *-- n2 = numeric, the other
- *-----------------------------------------------------------------------
-
- parameters n1, n2
-
- private nMin, nMax, nMod
-
- nMax = iif( int( m->n1 ) = m->n1 .and. int( m->n2 ) = m->n2, 1, 0 )
-
- if m->nMax # 0
- m->nMin = min( abs( m->n1 ), abs( m->n2 ) )
- m->nMax = max( abs( m->n1 ), abs( m->n2 ) )
-
- do while m->nMin > 0
- m->nMod = mod( m->nMax, m->nMin )
- m->nMax = m->nMin
- m->nMin = m->nMod
- enddo
- endif
-
- RETURN m->nMax
- *-- EoF: Gcd()
-
- FUNCTION RandSel
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/03/1992
- *-- Notes.......: Random selection of integers. The function requires
- *-- two numeric parameters, the number nN to select and
- *-- the number of items nT to select from. It fills the
- *-- first nN rows of a one-column array with an ordered
- *-- random selection of the integers from 1 to nT, which
- *-- may of course be used as record numbers or indices
- *-- into some other data structure to select items from
- *-- it. If passed a third, character, parameter, it will
- *-- place the selected numbers in the array of that name,
- *-- otherwise in the array "RandSel". If passed a fourth
- *-- parameter that evaluates to .T., it will reseed the
- *-- random number generator, otherwise use the next random
- *-- numbers.
- *-- If the array does not exist, it will be created.
- *-- If it does exist but with two dimensions or too few
- *-- rows, it will be recreated with one dimension and
- *-- enough rows. If the first parameter is larger than
- *-- the second, they will be swapped.
- *-- The random-number generator should usually be
- *-- reseeded, either by using the "lReseed" parameter or
- *-- before calling the function, except where the function
- *-- is being called repeatedly either within a very short
- *-- time or for related applications in which a repetition
- *-- of the sequence would defeat the randomness.
- *-- For dBASE IV versions before 1.5, revise this to
- *-- take only the two numeric parameters by commenting out
- *-- the first "parameters" line of code below and
- *-- including the next three commented lines. The array
- *-- "RandSel" will be used, and reseeding if needed must
- *-- be done before calling the function.
- *-- The algorithm used is "Algorithm S" discussed
- *-- in 3.4.2 of Volume II, "The Art of Computer
- *-- Programming", 2d edition, Addison-Wesley, Reading,
- *-- MA, by Donald Knuth.
- *-- Written for.: dBASE IV, 1.1 and 1.5
- *-- Rev. History: 12/03/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: RandSel( "<nN>,<nT> [,<cArray>] [,<lReseed>]" )
- *-- Example.....: lX = RandSel( 100, reccount(), "MyArray", .T. )
- *-- Returns.....: .T. if successful, or .F. if given number < 1 as
- *-- parameter.
- *-- Parameters..: nN = numeric, number of integers to select
- *-- nT = numeric, highest integer to select from
- *-- cArray = character, name of the array to hold the
- *-- selected integers. If not furnished, array
- *-- "RandSel" will be used.
- *-- lReseed = logical, .T. to reseed the random-number
- *-- generator. Default is .F., no reseed.
- *-- Side effects: Creates as needed and fills the array.
- *-- Uses some random numbers from the sequence.
- *-----------------------------------------------------------------------
-
- parameters nN, nT, cArray, lReseed
-
- *-- users of versions below 1.5, comment out the line above and
- *-- include the three lines below
-
- * parameters nN, nT
- * private cArray, lReseed
- * store .F. to cArray, lReseed
- private nChoose, nTotal, lReturn, nX, nChosen, nSeen
-
- nChoose = int( min( m->nN, m->nT ) )
- nTotal = int( max( m->nN, m->nT ) )
- lReturn = ( m->nChoose >= 1 )
-
- if lReturn
- if type( "cArray" ) = "L"
- cArray = "RandSel"
- endif
-
- if type( "&cArray.[ m->nT ]" ) = "U"
- release &cArray.
- public &cArray.
- declare &cArray.[ m->nT ]
- endif
-
- if m->lReseed
- nX = rand( -1 )
- endif
-
- store 0 to m->nChosen, m->nSeen
- do while m->nChosen < m->nChoose
- m->nX = rand() * ( m->nTotal - m->nSeen )
- if m->nX < m->nChoose - m->nChosen
- m->nChosen = m->nChosen + 1
- store m->nSeen+1 to &cArray.[ m->nChosen ]
- endif
- m->nSeen = m->nSeen + 1
- enddo
- endif
-
- RETURN m->lReturn
- *-- EoF: RandSel()
-
- FUNCTION Bell
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 11/25/1992
- *-- Note........: Ring my chimes
- *-- Written for.: dBASE IV 1.1+
- *-- Rev. History: 11/25/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Bell()
- *-- Example.....: lDummy = Bell()
- *-- Returns.....: .T.
- *-- Parameters..: none
- *-----------------------------------------------------------------------
-
- set console on
- if col() = 80 && to avoid spacing past the end of the screen
- @ row(), 79 say ""
- endif
- ?? chr(7)
- set console off
-
- RETURN .T.
- *-- EoF: Bell()
-
- FUNCTION Alarm
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 10/05/1993
- *-- Note........: Ring my chimes in a warbling pattern
- *-- Written for.: dBASE IV 1.5+
- *-- Rev. History: 10/05/1993 -- Original
- *-- 11/02/1993 -- (Ken Mayer) added nDur parameter
- *-- so we could lengthen or shorten
- *-- duration of each part of "warble"
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Alarm([<nRings>][,nDur])
- *-- Example.....: lDummy = Alarm(3) or
- *-- lDummy = Alarm(3,5)
- *-- Returns.....: .T.
- *-- Parameters..: nRings = how many times to warble? (optional --
- *-- default is 10)
- *-- nDur = duration (1-20) -- Optional, but if used
- *-- you must have a value for nRings --
- *-- using '0' will give default of 10. Duration
- *-- defaults to 10.
- *-----------------------------------------------------------------------
-
- parameters nRings, nDur
- private lSaveBell, lConsole, nTimesRung, nLastKey
-
- * default is 10 rings
- if pcount() < 1
- m->nRings = 10
- endif
- *-- if we have a value for first parameter
- if pCount() => 1
- if m->nRings = 0 && if it's zero, set default to 10
- m->nRings = 10
- endif
- endif
- *-- nDur has been passed
- if pCount() = 2
- if m->nDur < 0 .or. m->nDur > 20 && if invalid (1-20!)
- m->nDur = 10
- endif
- else
- m->nDur = 10 && if nothing passed at all ...
- endif
-
- *-- init a couple fields
- store 0 to m->nTimesRung, m->nLastKey
- m->lConsole = (set("console") = "ON")
- set console on
- m->lSaveBell = (set("BELL") = "ON")
- set bell on
- if col() = 80 && to avoid spacing past the end of the screen
- @ row(), 79 say ""
- endif
-
- * Ring the bells. Exit if user is paying attention and presses a key
- do while m->nTimesRung < m->nRings .and. m->nLastKey = 0
- set bell to 400,nDur
- ?? chr(7)
- set bell to 1200,nDur
- ?? chr(7)
- m->nLastKey = inkey()
- m->nTimesRung = m->nTimesRung + 1
- enddo
-
- * reset the bell, both ON/OFF and tone/duration
- if m->lSaveBell
- set bell on
- endif
- set bell to
-
- * reset the console
- if .not. m->lConsole
- set console off
- endif
-
- RETURN .T.
- *-- EoF: Alarm()
-
- FUNCTION GetPorts
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming, GeoApplications [75500,3223]
- *-- Date........: 10/26/1993
- *-- Notes.......: Get list of available printer ports
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/26/1993 -- Original
- *-- Calls.......: PortCheck, Warning (use your own)
- *-- Called by...: Any
- *-- Usage.......: ? GetPorts()
- *-- Example.....: PrinterList = GetPorts()
- *-- Returns.....: space-separated list of available ports
- *-- : list looks like "LPT1 LPT2 LPT3"
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- private lDummy, cOldDevice, lPrintOK, cPrinters
- cOldDevice = set("device")
- set device to screen
- store "" to cPrinters
- do PortCheck with m->cPrinters, "LPT1"
- do PortCheck with m->cPrinters, "LPT2"
- do PortCheck with m->cPrinters, "LPT3"
- do case
- case trim(m->cOldDevice) = "PRINT"
- set device to PRINT
- case trim(m->cOldDevice) = "SCREEN"
- set device to SCREEN
- case left(m->cOldDevice,4) = "FILE"
- store substr(m->cOldDevice,5) to cOldDevice
- set device to FILE (m->cOldDevice)
- otherwise
- lDummy = warning("UNKNOWN DEVICE IN GetPorts: "+m->cOldDevice)
- endcase
-
- RETURN ltrim(rtrim(m->cPrinters))
- *-- EoF: GetPorts()
-
- PROCEDURE PortCheck
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming, GeoApplications [75500,3223]
- *-- Date........: 10/26/1993
- *-- Notes.......: Part of GetPorts
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/26/1993 original
- *-- Calls.......: E_Check, GetInfo
- *-- Called by...: GetPorts()
- *-- Usage.......: do PortCheck with <portlist>, <port>
- *-- Example.....: do PortCheck with m->cPrinters, "LPT3"
- *-- Returns.....: adds <port> to <portlist> if port is available
- *-- Parameters..: cPrinters = character - list of available ports
- *-- cPort = character - port to test for
- *-- availability
- *----------------------------------------------------------------------
-
- parameters cPrinters, cPort
- private lPrintOK, cCurrPort, lPrintON
- lPrintOK = .T.
- on error do e_check with error(), cPrinters, cPort, lineno(), ;
- lPrintOK
- set printer to &cPort.
- store GetInfo("PRINT") to cCurrPort
- if m->cCurrPort = m->cPort .and. m->cPort = m->cCurrPort
- if .not. m->cPort $ m->cPrinters
- set device to print
- if .not. m->cPort $ m->cPrinters
- lPrintON = set("print")="ON"
- set print on
- if .not. lPrintON
- set print off
- endif
- endif
- endif
- endif
- if m->lPrintOK
- store m->cPrinters + m->cPort + " " to cPrinters
- endif
- on error
-
- RETURN
- *-- EoP: PortCheck
-
- PROCEDURE E_Check
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming, GeoApplications [75500,3223]
- *-- Date........: 10/26/1993
- *-- Notes.......: Part of GetPorts
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/26/1993 original
- *-- Calls.......: LStr, Warning (insert your own Warning function here)
- *-- Called by...: PortCheck
- *-- Usage.......: on error do e_check with error(), <portlist>, ;
- *-- <port>, lineno(), <logical>
- *-- Example.....: on error do e_check with error(), cPrinters, ;
- *-- cPort, lineno(), lPrintOK
- *-- Returns.....: checks error condition after SET PRINTER TO <Port>
- *-- adds <port> to <portlist> if port is available
- *-- Parameters..: error_no = numeric - error that called E_Check
- *-- cPrinters = character - list of available ports
- *-- cPort = character - port to test for
- *-- availability
- *-- nLineNo = numeric - line number of calling
- *-- program
- *-- lPrintOK = logical - flag to set; used by
- *-- PortCheck
- *----------------------------------------------------------------------
-
- parameters error_no, cPrinters, cPort, nLineNo, lPrintOK
- private lDummy, cOldDevice, cErrorMsg
- cErrorMsg = message()
- * Mon 10-25-1993 store old device information
- cOldDevice = set("device")
- set device to screen
- lPrintOK = .F.
- do case
- case error_no = 123 && Invalid printer port
- case error_no = 124 && Invalid printer redirection
- case error_no = 125 && Printer not ready - but the port is there!
- store m->cPrinters + m->cPort + " " to cPrinters
- case error_no = 126 && Printer is either not connected or
- && turned off
- store m->cPrinters + m->cPort + " " to cPrinters
- otherwise
- lDummy = Warning("Error # "+str(error_no,3,0)+" w/ driver " +;
- _pdriver + " from " + prg_name,m->cErrorMsg,;
- "Line: "+lstr(nLineNo))
- endcase
-
- do case
- case trim(m->cOldDevice) = "PRINT"
- set device to PRINT
- case trim(m->cOldDevice) = "SCREEN"
- set device to SCREEN
- case trim(m->cOldDevice) = "FILE"
- store substr(m->cOldDevice,5) to cOldDevice
- set device to FILE (m->cOldDevice)
- otherwise
- lDummy = warning("UNKNOWN DEVICE IN GetPorts/E_Check: "+;
- m->cOldDevice)
- endcase
-
- RETURN
- *-- EoP: E_Check
-
- FUNCTION Warning
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming, GeoApplications [75500,3223]
- *-- Date........: 10/26/1993
- *-- Notes.......: quick-and-dirty warning message for testing
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 10/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: ? Warning(<c1>[,<c2>,<c3>,<c4>,<c5>])
- *-- Example.....: ? Warning("You dummy!")
- *-- Returns.....: .F.
- *-- Parameters..: up to five character strings to display at EoScreen
- *----------------------------------------------------------------------
-
- parameters cM1, cM2, cM3, cM4, cM5
- private cDevice, lConsole, lPrintON
- lConsole = set("console") = "ON"
- lPrintON = set("printer") = "ON"
- cDevice = set("device")
- set print off
- set device to screen
- set console on
- do case
- case pcount() = 1
- @ 23,0 clear to 24,79
- @ 23,0 say left(m->cM1,79)
- case pcount() = 2
- @ 22,0 clear to 24,79
- @ 22,0 say left(m->cM1,79)
- @ 23,0 say left(m->cM2,79)
- case pcount() = 3
- @ 21,0 clear to 24,79
- @ 21,0 say left(m->cM1,79)
- @ 22,0 say left(m->cM2,79)
- @ 23,0 say left(m->cM3,79)
- case pcount() = 4
- @ 20,0 clear to 24,79
- @ 20,0 say left(m->cM1,79)
- @ 21,0 say left(m->cM2,79)
- @ 22,0 say left(m->cM3,79)
- @ 23,0 say left(m->cM4,79)
- otherwise
- * use the first five
- @ 19,0 clear to 24,79
- @ 19,0 say left(m->cM1,79)
- @ 20,0 say left(m->cM2,79)
- @ 21,0 say left(m->cM3,79)
- @ 22,0 say left(m->cM4,79)
- @ 23,0 say left(m->cM5,79)
- endcase
- @ 24,0 say "Press any key to continue ... " + chr(7)
- lDummy = inkey(0)
- do case
- case trim(m->cDevice) = "PRINT"
- set device to PRINT
- case trim(m->cDevice) = "SCREEN"
- set device to SCREEN
- case left(m->cDevice,4) = "FILE"
- store substr(m->cDevice,5) to cDevice
- set device to FILE (m->cDevice)
- otherwise
- @ 24,0 clear to 24,79
- @ 24,0 say chr(7) + "UNKNOWN DEVICE IN Warning: "+;
- m->cDevice+" press any key"
- lDummy = inkey(0)
- endcase
- if .not. m->lConsole
- set console off
- endif
- if m->lPrintON
- set printer on
- endif
-
- RETURN .F.
- *-- EoF: Warning()
-
- *-----------------------------------------------------------------------
- *-- The following are here as a courtesy ...
- *-----------------------------------------------------------------------
-
- FUNCTION AtCount
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: returns the number of times FindString is found in
- *-- Bigstring
- *-- Written for.: dBASE IV
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: AtCount("<cFindStr>","<cBigStr>")
- *-- Example.....: ? AtCount("Test",;
- *-- "This is a Test string, with Test data")
- *-- Returns.....: Numeric value
- *-- Parameters..: cFindStr = string to find in cBigStr
- *-- cBigStr = string to look in
- *-----------------------------------------------------------------------
-
- parameters cFindstr, cBigstr
- private cTarget, nCount
-
- cTarget = m->cBigstr
- m->nCount = 0
-
- do while .t.
- if at( m->cFindStr,m->cTarget ) > 0
- m->nCount = m->nCount + 1
- m->cTarget = substr( m->cTarget, at( m->cFindStr, ;
- m->cTarget ) + 1 )
- else
- exit
- endif
- enddo
-
- RETURN m->nCount
- *-- EoF: AtCount()
-
- FUNCTION Dec2Hex
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an integral number ( in decimal notation)
- *-- to a hexadecimal string
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Hex(<nDecimal>)
- *-- Example.....: ? Dec2Hex( 118 )
- *-- Returns.....: Character = Hexadecimal equivalent ( "F6" in example )
- *-- Parameters..: nDecimal = number to convert
- *-----------------------------------------------------------------------
-
- parameters nDecimal
- private nD, cH
- nD = int( nDecimal )
- cH= ""
- do while m->nD > 0
- m->cH = substr( "0123456789ABCDEF", mod( m->nD, 16 ) + 1 , 1 );
- + m->cH
- m->nD = int( m->nD / 16 )
- enddo
-
- RETURN iif( "" = m->cH, "0", m->cH )
- *-- Eof: Dec2Hex()
-
- FUNCTION StrPBrk
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Search string for first occurrence of any of the
- *-- characters in charset. Returns its position as
- *-- with at(). Contrary to ANSI.C definition, returns
- *-- 0 if none of characters is found.
- *-- Written for.: dBASE IV
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: StrPBrk("<cCharSet>","<cBigStr>")
- *-- Example.....: ? StrPBrk("Tt",;
- *-- "This is a Test string, with Test data")
- *-- Returns.....: Numeric value
- *-- Parameters..: cCharSet = characters to look for in cBigStr
- *-- cBigStr = string to look in
- *-----------------------------------------------------------------------
-
- parameters cCharset, cBigstring
- private nPos, nLooklen
- m->nPos = 0
- nLooklen = len( m->cBigString )
- do while m->nPos < m->nLooklen
- m->nPos = m->nPos + 1
- if at( substr( m->cBigString, m->nPos, 1 ), m->cCharset ) > 0
- exit
- endif
- enddo
-
- RETURN iif(m->nPos=m->nLookLen,0,m->nPos)
- *-- EoF: StrPBrk()
-
- FUNCTION IsSet
- *-----------------------------------------------------------------------
- *-- Programmer..: Frank A. Deviney, Jr. (CIS: 72357,345)
- *-- Date........: 12/18/1993
- *-- Notes.......: Checks if a bit (within a byte) is "set" to 1.
- *-- Written for.: dBASE IV, v2.0
- *-- Rev. History: 12/18/1993 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: IsSet( <expC>, <expN> )
- *-- Example.....: ? IsSet( chr(202), 4 )
- *-- Returns.....: logical
- *-- Parameters..: cFlags = a single ascii character, but if a string is
- *-- passed, the first character in the string will
- *-- be used.
- *-- nWhich = which bit to check. LSB = 0, MSB = 7
- *-----------------------------------------------------------------------
- parameters cFlags, nWhich
- private n, nCurr, nMid
-
- m->n = asc(cFlags)
- m->nCurr = 7
- m->nMid = 128
- do while .not. (nWhich = m->nCurr)
- if (m->n >= m->nMid)
- m->n = m->n - m->nMid
- endif
- m->nCurr = m->nCurr - 1
- m->nMid = m->nMid / 2
- enddo
-
- RETURN (m->n >= m->nMid)
- *-- EoF: IsSet()
-
- *----------------------------------------------------------------------
- *-- The following are here to work with the GETPORTS() function
- *-- above. Copies will be found in other parts of the library.
- *----------------------------------------------------------------------
-
- FUNCTION GetInfo
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 10/26/1993
- *-- Notes.......: 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
- *-- : 10/26/1993 Angus Scott-Fleming
- *-- : replace cSafety w lSafety
- *-- : upper-case cStart
- *-- : minor bug fixes as noted by && <date>
- *-- 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 current work area - whether
- *-- or not database is in use
- *-- PRINT Current printer destination (PRN, NUL,
- *-- LPT1, COM1) as set by SET PRINTER TO.
- *-- ERROR Error condition set by ON ERROR
- *-- ESCAPE 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
- *-- OR
- *-- cKeyWord, cKeyWord2 = Items you are checking the
- *-- status of, options return the following:
- *-- 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>
- *----------------------------------------------------------------------
-
- parameters cKeyWord, cKeyWord2
- private cKey, l2Parms, cStart, lSafety, cTempTxt, nLines, cTmpArray
-
- cKey = upper(m->cKeyWord)
- l2Parms = (pcount() = 2)
-
- do case
- case m->cKey = "CTRL-" .or. m->cKey = "SHIFT" .or. ;
- (","+m->cKey+"," $ ",F2,F3,F4,F5,F6,F7,F8,F9,F10,")
- cStart = m->cKey + space(9 - len(m->cKey))+"-"
-
- case m->cKey = "PRINT"
- cStart = "Print Destination:"
-
- case m->cKey = "WORK"
- cStart = "Current work area ="
- if "" <> dbf()
- RETURN select(alias())
- endif
-
- case m->cKey = "ERROR"
- cStart = "On Error:"
-
- case m->cKey = "ESCAPE"
- cStart = "On Escape:"
-
- case m->cKey = "PAGE"
- cStart = "On Page At Line"
-
- case m->cKey = "HANDLE" .or. m->cKey = "NAME" .or. ;
- m->cKey = "MODE"
- cStart = "Low level files opened"
-
- otherwise && none of the above
- RETURN ""
-
- endcase
-
- 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
- && double 'dot' is required
- set alternate on
- list status
- close alternate
- set console on
-
- nLines = TextLine(m->cTempTxt)
- aTmpArray = right(m->cTempTxt,8)
- cTmp = AAppend(m->cTempTxt,m->aTmpArray)
- nHandle = fopen(m->cTempTxt,"R")
- cResult = ""
-
- nX = 1
- cStart = upper(m->cStart) && Tue 10-26-1993 upper case
- nStartLen = len(m->cStart) && Tue 10-26-1993 pre-load LEN
- do while m->nX <= m->nLines
- if upper(left(&aTmpArray.[m->nX],m->nStartLen)) = m->cStart
- cResult = ltrim(substr(&aTmpArray.[m->nX],m->nStartLen+1))
- exit
- endif
- nX = m->nX + 1
- enddo
-
- *-- 2 parameters?
- if m->l2Parms .and. "" # m->cResult
- do case
- case m->cKey = "PAGE"
- if upper(m->cKeyWord2) = "LINE"
- cResult = left(m->cResult,at(" ",m->cResult) - 1)
- else
- cResult = substr(m->cResult,at(" ",m->cResult) + 1)
- endif
-
- case m->cKey = "HANDLE" .or. m->cKey = "NAME" .or. ;
- m->cKey = "MODE"
- cResult = ""
- nX = m->nX + 2
- do while val(&aTmpArray.[m->nX]) <> 0
- do case
- case m->cKey = "HANDLE" .and. ;
- upper(m->cKeyWord2) $ &aTmpArray.[m->nX]
- cResult = str(val(&aTmpArray.[m->nX]))
-
- case m->cKey = "NAME" .and. ;
- m->cKeyWord2 = val(&aTmpArray.[m->nX])
- cResult = substr(&aTmpArray.[m->nX],10,40)
-
- case m->cKey = "MODE" .and. ;
- m->cKeyWord2 = val(&aTmpArray.[m->nX])
- cResult = substr(&aTmpArray.[m->nX],50,5)
- endcase
- if "" <> m->cResult
- exit
- endif
- nX = m->nX + 1
- enddo
- endcase
- endif
-
- release &aTmpArray.
- nClose = fclose(m->nHandle)
- lSafety = set ("safety") = "ON" && Tue 10-26-1993
- set safety off
- erase (m->cTempTxt + ".")
- if lSafety && Tue 10-26-1993 replace
- set safety ON && the dreaded macro expansion
- endif
- cResult = ltrim(rtrim(m->cResult))
-
- RETURN iif(right(m->cResult,1) = ":",;
- left(m->cResult,len(m->cResult)-1),m->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(m->cTextFile) && if it exists ...
- nHandle = fopen(m->cTextFile,"R")
- do while .not. feof(m->nHandle)
- cTemp = fgets(m->nHandle,254)
- nLines = m->nLines + 1
- enddo
- nClose = fclose(m->nHandle)
- endif
-
- RETURN m->nLines
- *-- EoF: TextLine()
-
- 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.......: none
- *-- Called by...: Any
- *-- Usage.......: TempFile([cFileExt])
- *-- Example.....: cVarFile = TempFile("$XY")
- *-- Returns.....: Filename
- *-- Parameters..: cFileExt = optional parameter - allows you to assign
- *-- file extension to the end of the filename.
- *----------------------------------------------------------------------
-
- parameters cFileExt
-
- RETURN TempDir() + "TMP"+right(ltrim(str(rand(-1)*10000000)),5);
- +iif(pcount() = 0 .or. "" = m->cFileExt,"","."+m->cFileExt)
- *-- EoF: TempFile()
-
- FUNCTION AAppend
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 10/26/1993
- *-- Notes.......: Appends a text file into an array. This routine is
- *-- limited to text files of 1,170 lines, and 254 char-
- *-- acters 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
- *-- : 10/26/1993 Angus Scott-Fleming release "ALL LIKE"
- *-- 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 = m->aArrayName
- *-- if it exists, get rid of it, and then re-define it
- *-- Tue 10-26-1993 original code release &aTArray. wasn't working
- release all like &aTArray.
- aTArray = m->aArrayName
- public &aTArray.
- nLines = TextLine(m->cFileName) && get number of lines
- declare &aTArray.[min(m->nLines,1170)]
-
- *-- get file handle
- nHandle = fopen(m->cFileName)
-
- *-- store the file into the array
- nX = 1
- do while m->nX <= m->nLines
- store fgets(m->nHandle,254) to &aTArray.[m->nX]
- nX = m->nX + 1
- enddo
-
- *-- close the file
- nHandle = fClose(m->nHandle)
-
- RETURN .T.
- *-- EoF: AAppend()
-
- 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.......: none
- *-- 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()
-
- *-----------------------------------------------------------------------
- *-- EoP: MISC.PRG
- *-----------------------------------------------------------------------