Clipper Reference Guide

Broadcast Messages | 

Introduction
Description

The functions in this chapter provide access to the Netware broadcast message system. With the utility SEND, Netware allows you to send messages between workstations. The NNETSN() functions of CA-Clipper Tools make it possible to send messages from within a CA-Clipper application.

Each Netware user knows the problem of getting a message during a running application: the application is usually interrupted when a message is received. CA-Clipper Tools provide two possibilities to solve this problem: suppressing incoming messages with the NNETBRDCST() function (corresponding to the Novell utility CASTOFF) or using the CA-Clipper Tools broadcast system. The broadcast system allows you to receive messages in the background and read the messages later from the broadcast buffer.

Platforms
Available on MS-DOS
Tag
Intro

Capture Services | 

Introduction
Description

The functions of this chapter allow the start and termination of capture processes from within a CA-Clipper application. Additionally, the most important parameters for a capture process can be set.

The Print Job Definition chapter can be substituted for these functions. When working with print job definitions you do not have to worry about the settings of capture processes. You only have to activate a print job definition that can be created and maintained with the Novell utility PRINTCON.EXE.

Platforms
Available on MS-DOS
Tag
Intro

Connection Services | 

Introduction
Description

This chapter provides functions that return information about the connection between workstations and file servers and allow you to set up or terminate connections. Even the login of a user from within a CA-Clipper application is possible. With the functions in this chapter, you can create a list of file servers within the internal network and all attached file servers, and you can determine the network address of a workstation.

Important! The term "attach" in conjunction with CA-Clipper Tools only describes the setup of a logical connection between a workstation and a file server and does not include a login, as is the case with the Novell utility ATTACH.EXE.

Platforms
Available on MS-DOS
Tag
Intro

Database Functions | 

Introduction
Description
The functions presented in this chapter are a useful extension of database handling. For example, you can determine if there is a memo file (.dbt) associated with a database, the number of decimal places, or the data type of a particular field.
Platforms
Available on MS-DOS
Tag
Intro

Date / Time Functions | 

Introduction
Description

This section contains functions that make many date computations easier to perform. Date-type values have been a feature of the xBASE language standard, and is preserved in CA-Clipper. In spite of this, it is always necessary to develop UDFs to execute certain technical financial computations. CA-Clipper Tools offers an alternative that not only spares you the work of writing a UDF, but also provides implementation in Assembler to guarantee fast execution.

This chapter also contains clock time functions. These include time changes, time span computations, time control of loops, and memory- resident clock display.

Please note that valid date tests are already carried out in CA-Clipper. CA-Clipper internal date tests cannot be canceled, so it is impossible to implement an individual UDF for error handling , if there is an invalid date.

CA-Clipper always replaces an invalid date with a null date. These internal tests are carried out by keyboard input, as well as by CToD() allocation. For this reason, there are no examples with invalid dates in the date function descriptions. Rather, the result of a function with a null date is shown.

Platforms
Available on MS-DOS
Tag
Intro

Devices and Forms | 

Introduction
Description
Netware provides the ability to manage printer and form information in a database (NET$PRN.DAT). The functions of this chapter allow a read access to the contents of NET$PRN.DAT and make it possible to connect an application's printer management with Netware.
Platforms
Available on MS-DOS
Tag
Intro

Disk Utilities | 

Introduction
Description

Fundamental to the disk functions

Fault tolerance and more

One of the biggest problems in stable application development is how to handle errors. Errors that occur during hard or floppy disk operations are especially frustrating. You may also encounter critical errors, which disable the program or operating system. The result, known to all CA-Clipper programmers, are the DOS error choices: (A)bort, (R)etry, (I)gnore.

Avoiding Errors

Error trap functions allow you to react to this type of error, but a strategy to avoid them completely is better. Therefore, CA-Clipper Tools includes functions to make it easier to handle floppy and hard disk errors.

Backup Systems

Backup systems, another component of the CA-Clipper application, are also discussed in this chapter. The recursive FileSeek() system, which allows you to format disks with DISKFORMAT(), is particularly useful. Complete directories can be scanned recursively, and queries regarding detailed information for every file can be made. The ideal time to carry out this process is during source and target drive back ups, because only the information that has changed is copied.

To avoid the annoying and not particularly fault-tolerant "RUN FORMAT", you can format the file disks directly from the application in all commonly available formats. Since the control UDF for DISKFORMAT() uses a concept similar to dbEdit(), you can display the format procedures on the screen as desired.

You can also determine a good deal of varied information about disk drives, files, and other things. This information far exceeds that of the FileSeek() system.

File Attributes

Following is the coding for each function where a file can be designated:

Table 1:

     Value   Symb. constants     Assigned attribute
     0       FA_NORMAL
     1       FA_READONLY         READ ONLY
     2       FA_HIDDEN           HIDDEN
     4       FA_SYSTEM           SYSTEM
     8       FA_VOLUME           VOLUME
     16      FA_DIRECTORY        DIR
     32      FA_ARCHIVE          ARCHIVE

If multiple attributes are implemented for a file, then the table values are added accordingly. For example, if the HIDDEN and SYSTEM attributes are implemented, the function must pass a 6 (2 + 4) as the attribute mask.

All file attributes do not behave the same. To initiate a file into the process, you must explicitly specify the HIDDEN, SYSTEM, VOLUME and DIR attributes. However, if either no attribute, R/O, or ARCHIVE is implemented with a file, it does not matter which value is passed. These rules for attribute handling are grounded in DOS, which compares the specified value with the actual file attributes in this way. Since in some circumstances this may lead to problems, the FileSeek() function allows you to switch on an additional EXACT ATTRIBUTE MATCHING.

Share Modes

For DOS version 3.0 or higher, if a function uses the DOS OPEN FILE call internally, it must pass a share mode. This way, one station determines how all other stations in the network can access the open file. This is valid for as long as the file remains open. The following variations exist:

Table 3: Share Mode

     Code    Symb. constants     Share Modes
     0       SHARE_COMPAT        Compatibility mode.  Here, DOS or the
                                 network software itself, determines the
                                 share mode.  In Novell networks, the
                                 SHAREABLE attribute plays an important role
                                 in this relationship.
     1       SHARE_EXCLUSIVE     Both read and write by other programs are
                                 locked out
     2       SHARE_DENYWRITE     Write by other programs are locked out
     3       SHARE_DENYREAD      Read by other programs are locked out
     4       SHARE_DENYNONE      Not locked.  Read and write by other
                                 programs is allowed

With the basic setting, all files are opened in the compatibility mode (relating to older DOS). As a rule, the share mode depends on file attributes or the network software setting.

Also in this chapter is the SETSHARE() function, which determines the share mode that enables all CA-Clipper Tools functions to open a file. CA-Clipper commands or functions are not affected in any way.

CSetSafety()

Use the CSetSafety() function as a safety switch to protect existing files from unwanted overwriting during file operations with CA-Clipper Tools functions. You will find this function in the chapter on Switches and Status Information, since it concerns all CA-Clipper Tools file operations.

Platforms
Available on MS-DOS
Tag
Intro

Drive Mapping | 

Introduction
Description

The functions in this chapter let you manipulate the drive mapping of workstations. New mappings can be executed, and existing mappings can be deleted. Furthermore, you can query information about current mappings. The basic function of this group of functions is NNETMAP(). NNETMAP() is used to create or delete an allocation. All extended possibilities, such as search drives and fake roots, are supported. Drive mappings can be defined temporarily. Temporary mappings are deleted automatically at the end of an application.

In conjunction with the ability to log in a user with NNETLOGIN(), the functions of this chapter allow you to set up the complete network environment of a workstation within an application.

Platforms
Available on MS-DOS
Tag
Intro

Extended Drivers | 

Introduction
Description

In addition to supporting the window functions, the CTUS.LIB extended driver contains a series of independent functions, all of which are described in this chapter.

We are concerned here with functions that relate directly to CA-Clipper keyboard input, screen and printer output, or other internal functions. To use these internal functions, the driver must be linked in. The use of CTUS.LIB does not mean that all the code for all the functions contained in CTUS.LIB is linked to your application. An intensive modularization effort causes RTLINK to link only those portions that are actually needed.

b>The Use of CTUS.LIB

The extended driver is delivered as an .OBJ file (CTUS.OBJ) to allow replacement of the CA-Clipper driver module in CLIPPER.LIB during linking. The extended driver must be included in the list of object files.

b>Video Modes

Some functions which relate to screen adapters are found in the Video Modes chapter rather than in the Video Functions chapter.

b>Changing Modes

Some settings are reset by a mode change:

Cursor position to: Line 0, Column 0

Screen page 0: SETPAGE()

All font information: SetFont(), FONTLOAD(), FONTSELECT()

All palette information: EGAPALETTE(), VGAPalette()

Border settings: SET COLOR TO

b>DSETWINDOW()/External Screen Output

This is a very important switch for CA-Clipper Tools that impacts many functions and other modules. DSETWINDOW() determines whether or not the output of external programs or modules is redirected to a window. (CA-Clipper Tools functions are considered "external").

The default setting for this switch (.T.) redirects the output. To make this possible, the driver changes the interrupt vector 10H. Under certain circumstances external programs will not accept changes in particular interrupt vectors, which is why you must call DSETWINDOW(.F.) before you call the RUN function.

Certain other functions, like ISANSI() or NUMCOL(), return false or differing values in conjunction with DSETWINDOW(). Pay attention to the accompanying notes in the function descriptions.

b>System Settings Are Saved

When you end an application under CA-Clipper's control (normal program termination, Alt-C, or ending after a CA-Clipper error message), the cursor type, color attribute, and interrupt vectors 0 to 127 are restored.

However, if you exit a program in any other way (usually with an external module containing errors) then the extended driver system settings cannot be restored. Previously changed interrupt vectors are probably still changed, which sooner or later result in a system crash. If this occurs, reboot as soon as possible.

b>The QUIT File

A QUIT file can be added to any of the extended driver functions. The QUIT file provides information at the next program start as to whether the previous run ended correctly. Additionally, the user's keyboard input is also recorded.

The default name for this file is the same name as your CA-Clipper program except that it has a .Q extension instead of a .EXE extension. However, you can select another name for the file. For more information, please see DSETQFILE(), DSETQNAME() and KEYREAD().

Platforms
Available on MS-DOS
Tag
Intro

Functions For IBM PC-LAN | 

Introduction
Description

This chapter includes network functions for IBM PC LAN/Microsoft MS-NET software.

b>PC LAN/MS-NET

PC LAN/MS-NET is software that has been offered for networks by IBM and Microsoft. Both programs are based upon the NETBIOS protocol; CA-Clipper does not directly affect the NETBIOS protocol. All internal function calls to the network software occur under DOS, which requires version 3.1 or higher. The functions in this group are in the format NETXXX().

An exception is the NetDisk() function. It can also determine whether a drive is local or remote under other network software. This assumes that the network software properly supports DOS in the background.

Platforms
Available on MS-DOS
Tag
Intro

Get / Read Functions | 

Introduction
Description

CA-Clipper enables you to program nested GET/READ masks. The functions in this chapter are retained in CA-Clipper Tools for compatibility reasons and to make them easy to use.

The active GET is saved with the help of a character string and restored through this string later. This allows you to newly query inputs without losing your main input mask. You can save KEYTRAP() definitions the same way and redefine them as you wish.

Important! It is impossible to use the saved information any longer that the runtime of an application. The character string that results cannot be saved to a file and reloaded later.

Other functions in this chapter return information about GET fields, such as screen position, the names of the accompanying variables, or information about whether a field is currently active.

Platforms
Available on MS-DOS
Tag
Intro

Installing CA-Clipper Tools | 

Installing CA-Clipper Tools
Description

Requirements

CA-Clipper Tools was designed for use with the CA-Clipper compiler. Therefore it should only be used on IBM PC/XTs, PC/ATs, or completely compatible systems. The screen functions may not work on a system where a modified CA-Clipper driver module has been used. (The string functions, on the other hand, are generally hardware independent.)

CA-Clipper Tools requires PC-DOS or MS-DOS, version 2.10 or higher, but some functions work with system calls which are not supported until PC/MS-DOS version 3.1 or higher. This applies, for example, to network functions: if you work with network functions under a DOS version earlier than 3.1, the functions will not work properly.

We cannot guarantee that CA-Clipper Tools will work under any operating system other than PC-DOS or MS-DOS.

Installation Program

CA-Clipper Tools is supplied with an installation program, located on Disk 1. To install CA-Clipper Tools, perform the following steps:

■ Insert Disk 1 in drive A

■ Type A: and press Return to change the default drive to A

■ Type INSTALL and press Return to start the installation

procedure

The installation procedure is self-explanatory. You will be prompted to insert other disks as the installation program needs them. (Some of the files are compressed; therefore you cannot use the DOS COPY command to copy them to your hard disk. You must use the installation program.)

When the installation is complete, read the READ.ME file (located on disk 1) to learn about any last minute changes or enhancements.

Compatibility

CA-Clipper Tools is generally compatible with previous versions, but there are some deviations. If you require full compatibility for existing applications developed under CA-Clipper S'87, you must link in the #include file ct.ch. Notice, however, that we do not recommend this procedure for development of new applications.

As CA-Clipper develops, some of the functions in previous versions of the CA-Clipper Tools program are no longer meaningful. These functions remain unchanged in CA-Clipper Tools to avoid problems during the compilation of existing applications, but they have been flagged with asterisks (*) at the function name. Again, we do not recommend that you use these functions to develop new applications.

Documentation

All of the CA-Clipper Tools functions are described in detail in this four-volume Reference Guide. To allow you to find the function you need in a particular situation, the Reference Guide is divided into chapters. Each chapter presents a group of functions that serve a particular purpose, such as date functions, database functions, or system functions. Each function is then described in detail on a separate page. Appendixes provide keyboard tables, DOS error codes, and Novell network error codes.

A Quick Reference Guide gives the complete syntax and a short description of every function. In this booklet, the functions are organized in alphabetical order for quick reference. A chapter and page number tells you where to look in this four-volume Reference Guide for a complete description of the function.

The CA-Clipper Tools software contains a text retrieval system that lets you search online for the expression you need. This text retrieval system finds the appropriate function for your purpose in seconds — even if you don't know what that function is — and provides complete documentation on that function online.

Platforms
Available on MS-DOS
Tag
Intro

Introduction | 

Introduction
Description

CA-Clipper Tools contains over 800 functions which you can use to develop CA-Clipper applications and system-level routines. These functions give CA-Clipper programmers capabilities previously reserved for C or Assembler programmers with detailed system knowledge.

In order to use working memory as economically as possible, virtually all the functions are written in Assembler and are highly optimized. This guarantees high speed with a minimal use of memory. This efficiency is further supported by the modularity of the software within the CA-Clipper Tools library.

Platforms
Available on MS-DOS
Tag
Intro

Low Level Bindery Access | 

Introduction
Description

Each Netware file server maintains a database of users and resources available on the network. This special-purpose database is called the bindery. The bindery contains objects uniquely specified by an object name and an object type. Possible object types are: users, user groups, print queues, or print servers. Each object has associated with it a number of properties that can be addressed with names and contain information about the object. For example, the property GROUPS_I'M_IN contains a list of user groups of which a user is a member.

The functions of this chapter allow a low level access to the bindery. This provides you with maximum flexibility for programming within Novell. The low level functions allow the creation of your own bindery objects as well as the development of bindery analyzers.

However, even though the bindery concept has a high security level, incorrect use of the low level bindery functions can be very dangerous if you have supervisor or equivalent access rights. The network could be brought to a standstill. You should use these functions only with extensive knowledge of the bindery concept, the Novell API, and bindery management. For example, you must know the terms object, item, and set property.

For frequent, complex purposes that require bindery access, like adding a user to a group, CA-Clipper Tools provides high level functions that can be used without a problem. These functions are based on the low level functions and are available in CA-Clipper source code.

Netware internally uses a high low sequence to store numeric values, which is contrary to the standard format of the 80x86 processor family (low high sequence). For efficiency reasons, the Netware functions of CA-Clipper Tools expect numeric values that are passed to Netware (object types or object IDs) in the high low sequence. However, this will not affect the practical work with the CA-Clipper Tools because symbolic constants are defined in the high-low format in the header file CTNNET.CH for the most important object types.

Platforms
Available on MS-DOS
Tag
Intro

Mathematical Functions | 

Introduction
Description

This chapter offers an array of interesting mathematical functions to implement in CA-Clipper. It includes trigonometric functions, finance- oriented math computations, and functions to determine the factorial, sign, or the next-largest integer of a value.

SetPrec() is important for trigonometric functions. With this function you can specify the precision as a number of places to the right of the decimal. However, if it is less accurate, the speed is greater.

Platforms
Available on MS-DOS
Tag
Intro

Miscellaneous Functions | 

Introduction
Description

Functions that do not belong in any other module are assembled in this group under the Miscellaneous heading. However, this does not imply they are less useful. For example, use KeyTime() or KeySec() to activate a CA-Clipper procedure at a specific time, after a delay of seconds, implement file saves, or control demo programs.

This module enables you to determine complements, determine data types, and query keyboard scan codes.

b>Passing Parameters by Reference

Finally, this chapter discusses functions that permit you to pass parameters by reference. To find more information on this subject, see Chapter 4, String Manipulations.

Platforms
Available on MS-DOS
Tag
Intro

Miscellaneous Functions | 

Introduction
Description
This chapter contains some useful functions that do not belong in any other chapter of network functions. The functions HexToStr() and StrToHex() are not network functions, but these functions have been included in CA-Clipper Tools specifically for working with internet addresses that are returned or are required by functions such as NNETADR() or IPXOPEN(). The function NNETVER() is very useful if you are developing applications that access Netware 2.2 and Netware 3.11 servers because the behavior of some CA-Clipper Tools functions depends on the Netware version used (for example, NNETRIGHTS(), NNETPURGE()). Other functions are available for only one Netware version (for example, NNETSNDLOG(), NNETSALLST()).
Platforms
Available on MS-DOS
Tag
Intro

Number / Bit Manipulation | 

Introduction
Description

Number and Bit Manipulation

This module discusses number and bit manipulation. Specifically, the numeric section deals with conversions between two different number systems, and the creation of random numbers.

The bit manipulation section covers such required binary operations as AND, OR, XOR, and NOT, and how to test, set and clear bits. The NumLow() and NumHigh() functions are important for CA-Clipper Tools functions that take two 8-bit values and return them as combined 16-bit numbers. An example is the GETCURSOR() function from the Extended Drivers module.

Many of the functions in this module have a value parameter type. In this case, a number can be in the range of 0 to 65535 (or 4 294 967 295) and/or a hexadecimal string in the range of "0000" to "FFFF" (or "FFFFFFFF").

Platforms
Available on MS-DOS
Tag
Intro

Peek / Poke Functions | 

Introduction
Description

Despite the many capabilities of CA-Clipper Tools, there are times when direct port or memory access is needed. The functions in this chapter serve this purpose. For example, you can read memory regions by byte, word, or as a string through the PEEK function. POKE functions enable you to write a byte or word to working memory, but not a string.

Warning! POKE functions can be very dangerous. If you write to the wrong area in memory it can cause a lot of problems you may not foresee. Use POKE functions ONLY if you have extensive system knowledge.

This also applies to all the IN/OUT functions in this chapter, which allow you to directly manipulate a port. For example, if you address a disk controller improperly, the result may lead to data loss.

Platforms
Available on MS-DOS
Tag
Intro

Point-To-Point Communication | 

Introduction
Description

Point-To-Point Communication

The CA-Clipper Tools contain functions that allow direct communication between workstations in Novell or NetBIOS compatible networks by bypassing the file server. This type of communication is called Point- To-Point communication.

The data exchange between two workstations is interrupt controlled. Incoming data is copied in the background to a receiving buffer and can then be read with CA-Clipper Tools functions. As soon as the receiving buffer is full, incoming data is discarded. Outgoing data is copied to a sending buffer. While the CA-Clipper application continues, data is sent in the background from the sending buffer to the target address. Interrupt controlled sending of data is necessary to avoid a long wait when you send large datasets. When you use IPX/SPX communication or one of two possible NetBIOS communication variants, the data is broken up into packets internally. The packet size depends on the protocol used (IPX: 546 bytes, SPX: 534 bytes, NetBIOS: 512 bytes). The packets are sent sequentially.

Normally, the packet structure of the transmitted data is transparent and does not affect the handling of the data. The receiving buffer of the target workstation receives the data in the same way that the data has been written to the sending buffer. When you use IPX/SPX protocols in addition to the data, a header that is included in each IPX or SPX packet can be transmitted to the receiving buffer. This header makes a number of packet specific functions possible. The tables 31.1 and 31.2 describe the structure of the IPX and SPX header. The header positions start with 1, corresponding to string functions.

The NetBIOS communication variants have no similar mechanism available.

Table 31.1: IPX Packet Header

     Position     Length    Description
     1            2         Checksum
     3            2         Packet length in bytes
     5            1         Transmission control
     6            1         Packet type (4=IPX)
     7            4         Network number of target station
     11           6         Station ID of target station
     17           2         Target socket (High, Low format)
     19           4         Network number of source station
     23           6         Station ID of source station
     29           2         Source socket (High,  Low format)

Table 31.2: SPX Packet Header

     Position  Length  Description
     1         2       Check sum
     3         2       Packet length in bytes
     5         1       Transmission control
     6         1       Packet type (5=SPX)
     7         4       Network number of target station
     11        6       Station ID of target station
     17        2       Target socket (High, Low format)
     19        4       Network number of source station
     23        6       Stations ID of source station
     29        2       Source socket (High, Low format)
     31        1       Connection control
     32        1       Datastream type
     33        2       Connection number on source station (High, Low format)
     35        2       Connection number on target station (High, Low format)
     37        2       Sequence number (High, Low format)
     39        2       Acknowledge number (High, Low format)
     41        2       Allocation number (High, Low format)

When you install a communication buffer (a communication buffer can contain a sending and a receiving buffer), you receive a communication handle as a return value. You should store this handle in a variable as it is absolutely necessary for further operations with the communication buffer.

The functions for Point-To-Point communication fall into two groups: protocol specific functions and functions that can be used for any kind of communication buffer. Protocol specific functions are functions for a connection setup: (IPXOPEN(), SPXESTBCON(), SPXLISTCON(), NBDOPEN(), NBSCALL(), and NBSLISTCON()). The name of a protocol specific function always starts with three characters that describe the respective protocol (IPX, SPX, NBD: NetBIOS Datagram, NBS: NetBIOS Session).

Functions that write or read a buffer, or query the buffer status, are not protocol specific and can be used for any kind of communication buffer. The names of these functions start with PPC (Point-To-Point Communication). For example, the function PPCWRITE() is used to write data to a communication buffer. The protocol specific process of the data is regulated internally.

IPX/SPX Communication

Novell Netware (including Netware Lite) allows the direct use of the IPX and SPX communication functions. By loading the Novell NetBIOS emulator (NETBIOS.EXE), you can also use NetBIOS communication functions in Novell networks. However, the use of the emulator compared to IPX/SPX reduces the performance and the available memory. Therefore, you should use the IPX/SPX communication functions for applications running only in Novell networks.

IPX (Internetwork Packet Exchange Protocol) is a rudimentary protocol whose main advantage is that data can be sent to all waiting workstations in an internal network with only one call. However, IPX has no suitable handshake mechanism available that guarantees a successful delivery and a correct process of the sent data on the destination workstation. (Related mechanisms can be implemented with the IPX functions of CA-Clipper Tools. However, these mechanisms are application specific and have no general validity.)

The SPX protocol (Sequenced Packet Exchange Protocol) only allows communication between two workstations within an internal network. SPX has mechanisms available that guarantee the successful delivery of sent data.

Unlike SPX, which can be seen as real Point-To-Point communication protocol, the IPX communication is implemented as a pseudo Point-To- Point communication. When you use IPX, data for a specific workstation can be received by any workstation. However, a destination address is defined for interrupt controlled sending. (This address can specify all workstations within an internal network.) The destination address is not defined by the protocol, so it is not necessary to specify the destination address each time you access the send buffer. When you use the SPX protocol, a connection between two workstations is established.

The IPX/SPX communication between two workstations is based on two sockets on each side of the connection that can be opened and closed, similar to files. Sockets are represented by numeric values between 1 and 65535. Some socket numbers are reserved either by the Netware operating system or by Novell for third party vendors. The sockets between 16384 and 20480 (4000h - 5000h) are the dynamic sockets, meaning there are no reserved sockets in this range. A collision with socket numbers reserved by Netware can be avoided by using sockets out of that range.

NetBIOS Communication

The NetBIOS communication functions can be used in all networks that are based on NetBIOS specifications. In CA-Clipper Tools, two kinds of NetBIOS communication have been implemented: NetBIOS datagram and NetBIOS session communication. The NetBIOS datagram communication can be compared to the IPX communication; a successful delivery of sent data on the destination workstation is not guaranteed by the protocol. Like IPX, the datagram connection can also be implemented as pseudo Point-To- Point communication between two workstations. Additionally, a workstation can communicate with a group of workstations or with all workstations in a network.

Like an SPX connection, a session connection is a fixed connection between two workstations. The dataflow between two workstations is supervised internally by a protocol that guarantees the delivery of sent data on the destination workstation.

For the communication with other workstations in a NetBIOS network, NetBIOS names are used. A NetBIOS name can be up to 15 characters long and is case sensitive. NetBIOS differentiates between two kinds of names: station names that specify a workstation and are unique in a network, and group names that can be assigned to any number of stations. Each workstation contains a local name table with up to 20 NetBIOS names. A workstation can be addressed with each name in the name table. Once you have defined single or group names, messages can be sent easily to a station or a group of stations.

Because of the importance of NetBIOS names for the Point-To-Point communication, CA-Clipper Tools not only includes functions for the sending and receiving of data, but also functions for creating and deleting NetBIOS names.

Platforms
Available on MS-DOS
Tag
Intro

Print Job Definitions | 

Introduction
Description

With the Novell utility PRINTCON.EXE, print job definitions that contain the settings for a capture process can be created. The functions in this chapter allow you to control the print job definitions of the current users and all other users on a file server. You can create new job definitions and query or modify settings in existing definitions. It is possible to read the settings of a job definition and to directly start a capture process (NNETPJCAPF()). This function call is equivalent to a call of the CAPTURE utility with the parameter /J=.

Important! Within the Netware documentation the term "job" is used to describe a print job within a queue and also a set of capture parameters (print job definition). Within this chapter the term "job" or "job definition" only describes the definition of capture parameters.

Platforms
Available on MS-DOS
Tag
Intro

Print Queue Management | 

Introduction
Description

The functions in this chapter cover the entire area of print queue control under Netware. Print queues can be created or deleted. Users, operators, and print servers for a print queue can be defined or removed. The queue functions allow you to manipulate jobs within a queue. All settings for a print job can be queried or modified if the job is not currently processed (provided that you have sufficient access rights). Jobs can be deleted or moved within a queue.

Important! Within the Netware documentation the term "job" is used to describe a print job within a queue and also to describe a set of capture parameters (print job definition). Within this chapter the term "job" only describes a print job.

Platforms
Available on MS-DOS
Tag
Intro

Print Server Access | 

Introduction
Description
Under Netware 3.x, control of network printers is no longer handled by a file server but by a print server. (However, as an NLM, the print server can also run on a file server.) Under Netware 2.2, a print server VAP is available. The functions of this chapter provide the ability to access the most important information and functions of a print server. For example, you can determine the status of a print server printer. In conjunction with the functions for Point To Point communication, a CA-Clipper application is able to emulate a remote printer (see sample program RPRINTER.PRG).
Platforms
Available on MS-DOS
Tag
Intro

Printer Functions | 

Introduction
Description

This chapter discusses printer output. Although CA-Clipper handles printer errors with an error trap, it is always better to avoid them completely. As a result, error traps for printer output will not become superfluous, since errors also occur during output. You can also determine a wide variety of information, such as the number of available printers or the printer status.

This chapter also describes functions that support DOS print spoolers. To implement these functions, prior to starting the respective application, you must run the DOS PRINT program to make the print spooler memory resident. Files can then be exclusively passed from a program to the spooler. However, you must first reroute your print output to a file (SET PRINTER TO file), before you can output it in the background.

Platforms
Available on MS-DOS
Tag
Intro

Semaphores | 

Introduction
Description

A semaphore controls certain states: for example, the states between two applications that run on different workstations. To enable all stations to access existing semaphores, each Netware file server has a table available to manage these semaphores.

Semaphores can be interpreted as variables kept on the file server. Each semaphore is assigned a name when it is created. A semaphore name can be up to 127 characters long and is not case sensitive. An application can access a semaphore by opening the semaphore with its name (NNETSEMOPN()).

A semaphore can be opened by any number of workstations. For each workstation, the semaphore has the same value. The semaphore value cannot be modified; however, by using specific functions it can be incremented (NNETSEMSNG()) or decrements (NNETSEMWAI()) by 1.

Each semaphore is assigned information in addition to the semaphore value. For each semaphore, the file server counts the number of stations currently accessing the semaphore. This information can be determined with the function NNETSEMOPC(). For example, a semaphore named after an application can be used to limit a resource to this application.

Semaphores are often used to implement logical lockings for any kind of resource. A semaphore is assigned to each resource. Before the resource is accessed, the application tries to decrement the semaphore's value by one (NNETSEMWAI()). If the resulting value is negative, the resource is locked by another station. When an application is finished using a semaphore's resource, the function NNETSEMSNG() must be called to increment the semaphore's value.

Platforms
Available on MS-DOS
Tag
Intro

Serial Communication | 

Introduction
Description

There are a number of ways that the serial port can be used. Modems, bar code readers, and many other devices deliver data over this port or are regulated by it. Although standards do exist, in the final analysis, the type of communication is different every time.

The functions in this chapter offer possibilities for data transmission and allow you to influence control signals. These functions do not support any particular protocol or any specific instrument. For a few expanded applications, like the XMODEM protocol, you should find sufficient information in the example programs for CA-Clipper Tools.

b>Port Parameters

All the parameters for the port, like baud rate, parity, file length, and stop bits, are fully adjustable. It is possible to change the settings for a port without closing it. In this way the transmission speed can be changed without losing the contents of the buffer or terminating an existing connection (DTR-signal).

b>Data Transmission

Using CA-Clipper Tools, you can use up to four serial ports simultaneously. You can create a sending and a receiving buffer of up to 64kB in size. The characters for the background transmission mode are placed in the sending buffer, while characters received through the port are stored using an interrupt handler. You can determine the number of characters in the receive buffer from your CA-Clipper program, and as many of the available characters as you like can be read. Additional special control functions exist for the sending buffer that give the governing program full control. It is also possible to engage a software or hardware handshake that is performed completely in the background.

b>Handshake

As previously mentioned, CA-Clipper Tools functions support both a hardware and software handshake. As soon as the receiving buffer threatens to overflow by at least one page, a special handshake character is transmitted that tells the other side that no further data should be transmitted. Whether you implement the hardware or software handshake depends upon the type of data transmission. Hardware handshakes use physical port controls. These port controls are usually RTS and CTS, so within the scope of CA-Clipper Tools functions, these control ports cannot be used for modem transmission. Modems are generally not able to reproduce port controls directly over the transmission route (i.e. telephone connection). A software handshake must be implemented in such cases.

A software handshake uses characters from the ASCII character set to control the data flow. The ASCII character set is a standard which defines the XOFF (stop data, transmission off) as Chr(19) and the XON (continue transmission, transmission on) as Chr(17). (You will recognize the similarity to your keyboard since Chr(19) corresponds to Ctrl-S, and Chr(17) corresponds to Ctrl-Q).

If one of the handshake processes is implemented, the software must test both sides to see if the receiving buffer has been filled. The software then either deactivates the CTS controls or sends an XOFF character. By contrast, when sending data you must constantly test to see if the RTS input from the remote station has been deactivated or if an XOFF character has been received. In both cases transmission must stop immediately.

Since you can never be sure if the remote stations stop immediately after receiving an XOFF character, the internal handshake becomes active when the buffer is 75% full. If the remote stations ignore the handshake, the 75% limit is probably insufficient at a set buffer size of 100 byte (which equals a 25 byte reserve).

The techniques described here for the handshake are managed completely by the CA-Clipper Tools routines. They do not concern themselves with the interface cards or the Universal Asynchronous Receiver Transmitters (UARTS). It is sufficient to activate the selected method, which allows your program to regulate the status of the sending and receiving buffers on an ongoing basis.

b>Protocols

As previously mentioned, remote data transmission is, as a rule, implemented only through a software handshake. A significant disadvantage to this method is that the characters used for flow control, CHR (19) and Chr(17) can no longer appear in the original data. Because these characters appear in binary files, remote data transmission is not possible — transmission protocols must be used. You find XMODEM routines written in CA-Clipper in the example programs. Using the CA-Clipper Tools port functions and this example as a basis, other protocols can be developed fairly simply.

Firm protocols are not provided within CA-Clipper Tools because their realization in CA-Clipper code presents no real advantage. It is more important that you have the ability to create your own protocols so that you are not locked into whatever protocol is within CA-Clipper Tools.

b>Control Signals

You can set or query all important port connector control signals, like CD (carrier detect), DTR (data terminal ready), etc.. To simplify your programming, there is a separate function for each signal. For all other status and control information, which is seldom required in serial communications, you can read or describe the corresponding UARTS register of the port directly.

b>Direct Hardware Access

All CA-Clipper Tools port functions directly address the hardware. Working over BIOS or even DOS calls would be impractical or even impossible. We therefore presuppose 100% hardware compatibility with the established IBM personal computer industry standard.

In order to guarantee that everything is functioning properly, both ports must be equipped with either UART 8250 or the compatible 16450. When you use the 8250, interrupt controlled transmission is only possible up to 2400 baud. Technical details regarding the ports and the UART registers can be found in the corresponding technical instructions, like the IBM Technical Reference Manuals.

b>I/O Addresses and Interrupt Requests

CA-Clipper Tools assumes the following basic settings for the four ports:

Table 1: Standard Port Settings

    Port    I/O Address    IRQ
    COM1:   3F8H           4
    COM2:   2F8H           3
    COM3:   3E8H           4 - Not specifically defined
    COM4:   2E8H           3 - Not specifically defined

In contrast to COM1 and COM2, the I/O addresses and IRQs for other ports are often different. If you want to use hardware that is not entirely compatible, CA-Clipper Tools has additional functions that you can use: com_SetIO() and com_SetIRQ(). When you use these functions, the I/O and IRQ settings for the port routines can be changed to the selected values. However, please notice that incorrect settings can have a wide range of consequences when they come in conflict with other hardware. These consequences include data loss or damage to hardware.

The correct settings for your hardware can be found at any given time in its accompanying documentation.

b>Possible Hardware Conflicts

CA-Clipper Tools recognizes the four addresses mentioned above for the ports COM1 to COM4. The com_Num() function uses these addresses to determine the number of available ports. For example, if the PC has a built-in ArcNet adapter, you can have a conflict between the I/O addresses. The CA-Clipper Tools routine addresses 02EAh, which is defined totally differently for the ArcNet adapter than for a serial interface. In this case an existing network connection would probably be disconnected. The com_SetIO() function can provide assistance by designating the second parameter as 0:

com_SetIO(port,0)

The corresponding standard address within the internal address table is deleted and access to other hardware is avoided. However, this is only possible if the com_Num() function has not previously been called within the program. (In this case the interface would have already been marked "in use.")

b>Important Notes

As the table of default settings indicates, it is possible for multiple ports to use the same IRQ — a procedure known as interrupt sharing.

While CA-Clipper Tools functions support these procedures, standard port hardware usually does not. Specialized multiple port cards are available from different manufacturers for this purpose.

Generally we cannot guarantee that interrupt sharing can be implemented.

CA-Clipper Tools supports up to four ports, each with sending and receiving buffers of up to 64kB and speed of up to 19200 baud. This is not to say that all this could be used at the same time to its highest limit. Eight buffers at 64kB are not possible. The buffers must be in conventional memory because the buffers are handled by interrupt routines. The number of ports and the speed with which they can function correctly is dependent upon the computer being used.

b>Differences from BASIC

In contrast to other programming languages (like BASIC), com_Open()/com_Init() do not influence control signals. If you want to address a modem over the serial port using CA-Clipper, you must set DTR and any other signals yourself, using the corresponding CA-Clipper Tools functions.

Platforms
Available on MS-DOS
Tag
Intro

Set Status | 

Introduction
Description

In this chapter, the group of functions determine the switch status and were implemented in the CA-Clipper Tools (CA-Clipper Summer 1987 release). CA-Clipper implemented the Set() function, so that these settings can be determined, set, and saved with this version. Therefore, some functions in this chapter only exist to enable compatibility with existing programs. All the affected functions are flagged with an "*".

If the functions relate to the CA-Clipper switches (SET's), the function name is represented as follows: CSET + the first four characters of the switch name. For example, if the switch is named CONFIRM, then the function that corresponds is CSETCONF(). If the parameter is optional and unspecified, the function returns the current setting for its switch, without a status change. When called with parameters, the function sets the switch to the passed value and returns the prior status as a value. In this way, a function call can both change a switch and save the old status. The logical value .T. corresponds to the ON setting of a switch; .F. corresponds to OFF.

b>Example

In the following example, the CONFIRM switch was set to .F.:

lOldValue:= CSETCONF(.T.)

After execution, the old variable lOldValue has a value of .F.; while the CONFIRM switch is ON (.T.).

In addition to their usefulness with CA-Clipper switches, these functions determine an assortment of other status information. For example, you can determine the current status of the debugger, set LASTKEY, and differentiate key traps. You can also determine the status of CAPS-LOCK, NUM-LOCK, INSERT, and SCROLL-LOCK.

Platforms
Available on MS-DOS
Tag
Intro

String Manipulation | 

Introduction
Description

There are an abundance of powerful string functions described in this chapter. A high degree of speed is assured because these functions and all of the CA-Clipper Tools are written exclusively in Assembler.

We have made an effort to find an appropriate example for as many unusual variations as possible. In view of this, we would like to take this opportunity to clarify a few ground rules regarding the use of these functions.

b>Passing Parameters by Reference

This chapter includes functions that pass parameters by reference. The following paragraphs contain clarification about these functions.

It has been possible to pass parameters of the character string type by reference to a UDF since the summer of 1987. This means that a reference to the original string is passed, thus avoiding the creation of an internal copy. When a function accepts this type of parameter and changes it, the original string is actually changed. This behavior does not normally apply to CA-Clipper functions. However, some CA-Clipper Tools functions behave differently and take parameters passed by reference. These functions and their corresponding parameters are described as reference sensitive in this section and are identified with [@] in the argument section of each function's description.

Passing parameters by reference has advantages and disadvantages. The most important advantage is that memory requirements are reduced. This allows you to avoid runtime errors that could result when there is insufficient memory available for string manipulation.

Whether or not the insufficient memory is a disadvantage depends on the function being used. Often you will want to change the original string. In a call that does not pass parameters by reference, the copy changed by the function must then be passed back to the "original" string again:

VAR := "Hello" VAR := FUNCTION(VAR)

When you work with very long strings, this method takes memory and time!

Here is an example of the reference method:

VAR := "Hello" FUNCTION(@VAR)

With most CA-Clipper Tools functions, it doesn't make any sense to pass parameters by reference. In some cases, a result is different when a parameter is passed in this way. However, when you do pass by reference, the functions change the parameters passed by the string directly. Memory is saved, and the functions work more quickly because you no longer need to make an internal copy. Watch for the [@] marker, indicating that a parameter is reference sensitive.

Functions which change the length of a string cannot, in principle pass by reference. Here is an overview of the functions that change length, or depending upon usage, could change if you attempt to pass by reference.

AtRepl() PosDel()

CharEven() PosIns()

CharOdd() PosRepl()

CharOne() WordOne()

CharOnly() WordOnly()

CharRem() WordToChar()

b>CSetRef()

This function additionally allows you to significantly optimize reference sensitive functions with regard to execution speed and memory use. Full details can be found in the corresponding function description later in this chapter.

Platforms
Available on MS-DOS
Tag
Intro

System Informations | 

Introduction
Description
The functions in this chapter provide system information about the operating system (MS-DOS), the BIOS, and hardware. It determines a large number of system facts and settings — from the DOS-COUNTRY setting to the mathematical coprocessor. It is even possible to warm or cold boot a computer from within a program. In addition, you can query and set DOS VERIFY and BREAK.
Platforms
Available on MS-DOS
Tag
Intro

Transition Tracking | 

Introduction
Description

Novell Transaction Tracking System (TTS)

This chapter provides functions for the use of the TTS within a CA-Clipper application. The use of the TTS within a CA-Clipper application requires more than start and termination or cancellation of a transaction with the related CA-Clipper Tools functions. With regard to the architecture, the application must be oriented to the specifics of TTS. The TTS takes into consideration only files managed on a server volume.

Transaction tracking occurs only on the files that have been marked as transactional. The transactional bit is an extended file attribute that can be set with the Novell utility FLAG.EXE or with the related CA-Clipper Tools function NNETEXTATT(). All files related to a .DBF file, (.NTX, .DBT) must also be marked as transactional.

The time between the start and the termination or cancellation of a transaction should be as short as possible. Avoid direct entries into database fields. Use memory variables for data input and then update the database within a transaction.

The reason for minimizing the transaction time is a characteristic of the Netware operating system that cannot be influenced by the application. When data in a file is modified, Netware physically locks the affected file area. In contrast to a logical locking with RLock(), the affected data cannot be read as long as the transaction is incomplete. If the transaction has been terminated successfully, the database record is updated. If the transaction has been interrupted, the record is reset to the previous value. A successful read access by another workstation could lead to fatal logical errors. The physical lock is removed automatically after the transaction has been completed or canceled. If a workstation tries to access a physically locked area, CA-Clipper causes an ACCESS DENIED error message and evaluates the error block. Normally, this results in a branch into the error recovery routine. An error message box is displayed, and the user can cause a repetition of the operation that failed. The error message text can be adapted to the running transaction. However, the problem is that from the beginning the application is not able to determine whether the ACCESS DENIED error results from a running transaction or another error source. Therefore, an application using the TTS should have a mechanism available that allows it to determine if a transaction is active for a specified group of files or not. Using Netware semaphores, for example, allows you to check to see if a transaction is active, either during the error recovery or before a file is accessed.

Platforms
Available on MS-DOS
Tag
Intro

User and Group Management | 

Introduction
Description

The functions of the User and Group Management chapter are based exclusively upon low level bindery accesses and could be accomplished completely with the low level bindery functions. However, working with low level bindery functions can be dangerous (see the Introduction to the Low Level Bindery Access chapter). Therefore, CA-Clipper Tools provide a number of high level functions for the most common requirements of user and group management. The functions in this chapter allow you to add or remove users, or groups of users, to or from groups. Various lists can be created: established users or groups, currently logged in users, members of a group, or groups of which a user is a member. You can determine if a user is a member of a specified group. For example, this allows you to combine the availibility of menu options with Netware settings.

A number of functions in this chapter have been developed in CA-Clipper with the use of low level bindery functions. The source code for these functions can be found on the product disks and can be used as an example for the use of the low level bindery functions.

Platforms
Available on MS-DOS
Tag
Intro

Using CA-Clipper Tools | 

Using CA-Clipper Tools
Description

Programming

To use the CA-Clipper Tools functions in your programs, specify the CT.LIB library during the LINK procedure. If required, also specify the CTUS.OBJ Extended Driver file. (See the section called "Extended Driver" below.)

All CA-Clipper rules apply when calling functions. For example, a function's return must not be assigned to a variable.

Both types of calls are possible:

FUNCTION(par1, par2) Var=FUNCTION(par1, par2)

Linking

CA-Clipper Tools functions can be linked with MS-LINK (often referred to as the DOS linker) as well as with RTLink.

Here is an example using MS-LINK:

LINK Prog1+Prog2+CTUS,,,CT/SE:nnn /NOE

With the exception of small test programs, MS-LINK requires that a value be assigned to the /SE: switch. We cannot recommend an adequate value for nnn.

Here is an example using RTLink in FreeFormat mode:

RTLINK FIProg1,Prog2,CTUS LIB CT

RTLink also contains a positional mode. When using this mode, the link command has to be identical to that in MS-LINK. Further information regarding RTLink can be found in the CA-Clipper Programming and Utilities Guide.

PLL Files

CA-Clipper Tools cannot be implemented in conjunction with the BASE50.PLL file created at CA-Clipper installation. You can, however, create a new corresponding .PLL file with the linker script file CT.LNK included in CA-Clipper Tools. Use the following command:

RTLINK @CT

This will exchange a particular module from the CA-Clipper library as well as several I/O routines out of TERMINAL.LIB for others in CTUS.OBJ or CT.LIB. The new .PLL file is called CT.PLL. If a new .PLL file is not created, then the alternative I/O routines and therefore many of the CA-Clipper Tools functions will not work for all the programs generated via prelinking.

If the CT.PLL file has been created once, the link procedure can be called as follows:

RTLINK FI prog LIB CT PLL CT

The CTUS.OBJ Extended Driver must not be specified, since it is already in the .PLL file.

Further CA-Clipper Tools modules have not been included in this or other .LNK files, since prelinked modules are always loaded at program start and increase memory usage accordingly. Creation of a .PLL file in conjunction with other external libraries becomes an individual procedure. However, all CT.LIB modules can be prelinked. You simply need to include a public for the desired module by inserting the REFER command.

Here is an example. By inserting:

REFER COM_BREAK, ACOS

the _COM and _TRI3 modules (serial interfaces and trigonometric functions) will be prelinked. The names of the module and the publics can be determined with a library manager like MS-LIB.

CA-Clipper Libraries

None of the preceding examples mentions any of the files belonging to CA-Clipper itself. This is because, during compiling, CA-Clipper's default setting enters the names of its four libraries in the resulting .OBJ file. When you influence this procedure, for example by using the /r compiler switch, all the required libraries must be called explicitly at linking.

Static Overlays

Most functions or CA-Clipper Tools modules cannot be stored to a static overlay, as they contain interrupt service routines. They may not reside in an overlay. The functions affected are KeySec(), KeyTime(), ShowTime(), SHOWKEY(), PRINTSCR(), PRINTSCRX(), and SETTIC(), as well as serial interface functions that also work interrupt controlled.

The Extended Driver CTUS.OBJ may never be placed in an overlay, since it is needed by CA-Clipper for every input and output. Linking CTUS.OBJ in an overlay will result in a system crash immediately after the start of your application. Therefore, be aware that the overlay will always have to be loaded in order for the function to be available.

All CA-Clipper Tools functions can be called from an overlay. The program code for some functions, however, cannot be placed within an overlay.

Possible Linking Problems

When implementing CA-Clipper Tools in an existing application for the first time, the linker warning message "Duplicate Definitions" may occur. In this case, probably one of your own procedures or functions or a function from another library has a name that was also used by one of the CA-Clipper Tools functions. If the name of this other function or procedure cannot be changed, it must be specified as a separate .OBJ file. Otherwise CT.LIB must be designated as the last library.

Note, also, that an .OBJ file will always overwrite a library module with the same name, independent of its position in the LINK command line. Therefore, the CA-Clipper Tools Extended Driver is delivered as an .OBJ file.

Extended Driver

In addition to the CT.LIB library, you will find a separate .OBJ module on your disk called CTUS.OBJ. This is the CA-Clipper Tools Extended Driver. If this is linked in, it replaces the CA-Clipper library driver. Above all, the Extended Driver is important for the implementation of window functions, but it also offers other interesting possibilities. For this reason all the functions in the chapter on the Extended Driver in this Reference Guide form a part of this module.

The CTUS.OBJ must only be added to the .OBJ file list to be linked. The sequence is not important. The Extended Driver replaces the CA-Clipper library driver module, so storing out to an overlay is not possible. You will find further information in the Extended Driver chapter.

Debugging

Working with CA-Clipper Tools makes additional debugger features available. These features are also controlled via the CLIPPER environmental variable, by setting a switch DEBUG:n.

How Problems Arise

There are many possible screen modes, fonts, windows, and virtual screens, so various problems can arise. The debugger also uses windows, as you can see on the debugger Windows menu. To avoid a collision with the windows of your application, the debugger has an additional windowing system.

Working with One Screen

When working with one screen, the debugger must be able to switch between the application screen and its own screen. The contents of the application screen must be saved. This can happen in an area of the available memory or in a free screen page.

Using a screen page saves memory and offers better performance, but it takes a screen page of the application. This is, however, taken into account by CA-Clipper Tools. The MAXPAGE() function, for example, returns a reduced value. The default value for the application is screen page, which can be changed with the environmental variable.

Working with Two Screens

Working intensively with CA-Clipper Tools video functions and the debugger on one screen is difficult. For this situation, the debugger supports two screens. This is possible because the PC can operate two cards simultaneously, for example, a Hercules card and a VGA card. The application output always occurs on the screen from which it was started, while the debugger output is displayed on the other screen. This capability is set via the CLIPPER environmental variable, by specifying DEBUG:2.

DEBUG Values

The DEBUG: n switch can be set with a numeric value. Each individual bit has a certain meaning. At this time, only two bits are used:

    Bit:      When set:      Default
    1         use PAGE       1
    2         two screens    0

Note: Particular switch combinations in the CLIPPER environmental variable can lead to problems. Please construct your environmental variable as follows:

SET CLIPPER=/Fnnn /Ennnn /DEBUG:2 /SWAPPATH:"path"

Reference Sensitive[@]

CA-Clipper can pass parameters of the character string type to a UDF by reference. This means that what is actually passed is a pointer to the original, thus avoiding the creation of an internal copy. When a function takes on this type of parameter and changes it, it is the original that is actually changed. Here is an example:

VAR := "Hello" MYFUNC(@VAR)

Passing of parameters by reference has advantages and disadvantages. An important advantage is that memory usage is reduced. This avoids runtime errors that result from not having enough memory for string manipulation. If, on the other hand, you do not want the original string to be changed, passing of parameters by reference is a disadvantage.

With a normal call (that is, not by reference), it is the copy that is changed by the function. The change must then be passed back to the original:

VAR := "Hello" VAR :+ MYFUNC(VAR)

Particularly in the case of long strings, this method takes up memory and time.

It is not a good idea to pass parameters by reference for most of the CA-Clipper Tools functions. (In some cases there will even be a difference in the result when a parameter is passed this way.) The functions then change the string passed as a parameter directly. This saves memory space and the functions work more quickly, since there are no internal copy procedures taking place. Watch for the [@] identifier meaning reference sensitive.

CSetRef()

This function allows you to further optimize memory requirements and speed for different string functions. This assumes that a function is only working with data passed as a parameter and avoids internal copies of returned values as well. When CSetRef() is set, the affected function no longer returns a value.

You will find more information on this function in the chapter on string functions.

Platforms
Available on MS-DOS
Tag
Intro

Video Functions | 

Introduction
Description

Working With Video Functions

This module discusses video functions that are either directly or indirectly concerned with the screen. Included are all functions that deal with such screen adapters as CGA, EGA and Hercules. Different modes on various adapters are supported, such as a 40-column CGA, a 43- line EGA, or a 50-line VGA.

DSETWINDOW()

Many of the functions in this chapter depend on setting the DSETWINDOW() switch. This switch determines if the screen output of external programs, as well as DOS, are redirected to a window. CA-Clipper Tools output functions are also valid as external. If the default setting in DSETWINDOW() is .T. or on, this rerouting is carried out. Some functions will then return inaccurate, or at the very least, different results. Examples of this are ISANSI() or NUMCOL()

Attribute

Many of the functions in this module work with color attributes designated as parameters. These arguments are carried out in three different ways:

A numeric value, which corresponds to a combined color attribute (e.g., 7).

A string in the "NN/NN" form, with two specified numeric values (e.g., "7/0").

A string in the "CC/CC" form, with two specified attributes are designated in the form CA-Clipper requires (e.g., "W/N").

With many functions, the attribute returns a combined numeric value. Attributes for the foreground and background are tied together this way.

Color attributes are constructed as follows:

Bit 8 7 6 5 4 3 2 1 Attribute * R G B + R G B

_ _ _ _ _ _ / _ _ _ _ _ _

Background / Foreground

Each attribute consists of four bits, which represent a value in the range of 0 to 15. Therefore, there are a total of 16*16, or 256, different values from 0 to 255. These numeric values can be changed into the "nn/nn" format, that can be used under CA-Clipper with the NTOCOLOR function. However, it is possible to directly influence this combined attribute value. The following examples show this and relate back to the chapter on number and bit manipulation:

NumOr( nattr, 128) // Flashing on NumAnd(nattr, 127) // Flashing off NumXor(nattr, 128) // Change flashing NumOr(nattr, 8) // High intensity on NumAnd(nattr, 247) // High intensity off NumXor(nattr, 8) // Switch high intensity

Special Parameter Type

With many functions, a parameter may be of the mIcCharacter|nCharacter type (e.g., an individual character). This can occur in two different ways:

Numerically, as the ASCII code of the desired character (e.g., 7).

Alphanumeric as the character (e.g., ":").

Because of this, you must not use the Chr() function to change special characters.

CLEARA and CLEARB

Some of the CA-Clipper Tools functions use a standard attribute and character to delete lines or screen areas. This attribute is described as CLEARA; the character as CLEARB. You can query both CLEARA and CLEARB with the corresponding functions. At the same time, certain preset values are in effect for CLEARA and CLEARB. The attribute "W/N" is the standard preset for CLEARA, while Chr(255) is the character used for CLEARB. If you use this character for CLEARB, it fills the background with the corresponding color for every deletion on every screen adapter.

Use the following functions to set standard values for CLEARA and CLEARB:

GetClearA() SetClearA() GetClearB() SetClearB()

If you use the SETCLEARx() functions in conjunction with the corresponding parameters (Attribute or Character), the currently existing default value is replaced by a parameter.

Clipper Functions and Commands Which Delete

If you use the CA-Clipper Extended Drivers, Chr(255) is used instead of a space for all CA-Clipper functions and commands that delete the screen in one way or another (see CLEARB). A Chr(255) is helpful on many screen adapters, since in contrast to a space, you can assign it a color. Then, the screen will not appear so fuzzy.

More precisely, the functions and commands concerned always use the delete character set by SetClearB(), which uses Chr(255) as the default setting. If you want to use a space to clear in CA-Clipper or CA-Clipper Tools, insert a SetClearB(32) into the program.

Re-implement a space for clear:

SetClearB(32) CLEAR // The affected Clipper command

Video Modes

Occasionally, there is some confusion about video modes. You will not be able to work in EGA mode just because your computer has an EGA adapter built into it. By the same token, you will not get either EGA or VGA modes, if you do not work with graphics.

EGA43 / VGA50 / VGA28, etc.

In this section, the concern is not to just get a mode "hardwired"' into a card, but for CA-Clipper Tools it is to generate corresponding fonts and other settings. For these reasons, the GETMODE() and GETSCRMODE() functions generate their own values that are greater than 255.

For example, changes to the screen mode concerned with line count can be combined with a 40-column mode:

CGA40() EGA43() // 43 lines and 40 columns

Video Functions and Windows

You cannot implement functions that change the base address for screen memory while windows are open. This includes all mode changes, as well as SETPAGE and SETSCRSTR.

Platforms
Available on MS-DOS
Tag
Intro

Volumes, Directories, ... | 

Introduction
Description
This chapter combines functions that deal with server volumes and files on server volumes. The NNETVOLXXX() functions return information about server volumes. The functions, NNETDIRS() and NNETFILES(), allow you to determine extended directory information (analogous to the Novell utility NDIR). The chapter also includes functions used to query and set rights, extended file attributes, and functions that can perform the tasks of the Novell utilities PURGE and SALVAGE. The operation of the functions NNETPURGE() and NNETSALVAG() depends on the Netware version.
Platforms
Available on MS-DOS
Tag
Intro

Window Functions | 

Introduction
Description

It is hard to imagine using CA-Clipper without using windows. Windows are the best way to show multiple tasks so you can get a genuine overview of the system operation. The functions in this chapter offer a particularly valuable extension to CA-Clipper in this area.

b>The Window System

If you are only working with one screen, the CA-Clipper Tools functions permit up to 255 windows, depending on available memory. In conjunction with the MONISWITCH() function from the Video Function chapter, CA-Clipper Tools can even support two screens linked to a single CPU, with one monochrome screen and one color screen. In this way two entirely independent window systems, each with 255 windows, are available.

The window functions take into account the fact that CA-Clipper Tools supports larger screens than the common 25 rows x 80 columns. A screen, and therefore also a window, can be up to 255 rows or 255 columns in size. However, the complete contents of a screen can never require more than 32 KB of memory. So with 255 rows, no more than 128 columns are possible.

b>Moving Interactively

As soon as SCROLL LOCK is activated, the active window can be moved with different cursor keys. Depending on how you open them, windows can even overlap. The gray Plus key in the numeric key pad works like the function WCenter(). You use the Plus key to move a partially visible window back into a completely visible area. All window movements done after you activate SCROLL LOCK can be undone using the ESC key.

b>Programming with Window Functions

■ Each window is assigned a number between 1 and 255 when it is

opened. This number is known as the window handle. Handle 0 is the original screen, with no open windows. The window handle returned will be used to refer to that window during programming. (For example, you need the window handle when you select a background window.)

WMode(.T., .T., .T., .T.) // Overlap permitted

nWindow1 := WOpen(....) nWindow2 := WOpen(....) // This is the active window

WSelect(nWindow1) // Activate first window

■ The coordinates used for screen output are relative only to

the selected window, and not the entire screen.

nWindow1 := WOpen(....) // Selected window

@ 02, 02 SAY "CA-Clipper Tools"

■ Since a window behaves exactly as the normal screen would,

QOut() style output (?, ??, etc.) will be scrolled up as soon as it reaches the bottom row.

■ The window in the following example, which extends to row 24,

will not overwrite the help message on row 25:

@ 24, 00 SAY "........ HELP-ROW........" nWindow1 := WOpen(0, 0, 23, 79) // Protects the last row FOR nI = 1 TO 100

? "CA-Clipper Tools ...."

NEXT nI

■ A window displays as a full value, but is a virtual screen,

which differs from the original physical screen only in size. Extended drivers make the MaxRow() and MaxCol() functions available in a version enhanced over and above CA-Clipper to accommodate the changed size. Now the coordinates of virtual screens can also be determined; these functions return the last row or column concerned with the currently selected window:

nWindow1 := WOpen(10, 10, 20, 60)

? MaxRow() // Row: 10 ? MaxCol() // Column: 50

■ The underlying screen area is saved automatically when a new

window is opened. This applies equally to any area of the screen that becomes overlapped by the movement of a window. At the same time, all settings in the areas that have been overwritten are saved. These settings include cursor shape and position, as well as color attributes. So you do not have to save anything out of the affected screen area; CA-Clipper Tools takes over this task automatically.

■ The following example shows you how the window functions save

both the color and cursor setting:

SET COLOR TO R // Set color RED ? "Test-Text 1 ..." // Output in RED nWindow1 := WOpen(10, 10, 20, 55) WBox() // RED window border

SET COLOR TO BG // Set color CYAN ? "Test-Text 2 ..." // Output in CYAN Inkey(0) // Wait for keystroke

WFCLOSE() // Close window again

? "Test-Text 3 ..." // Output again in RED

// and directly below "Text 1"

b>Active Windows

After you close a window, the active window with the highest handle is the one selected, not the window that was previously active. If, for example, the highest window handle is 9 and window 5 was just selected, a newly opened window is assigned handle 10. However, after you close this window number 10, window 9 is selected. It is therefore important to save the window's handle to a variable when you open it, so that you can select the required window later.

You can save the active window handle by calling WSelect() with no parameters.

■ The external output of programs called with RUN within a

CA-Clipper program can be tied to windows:

DSETWINDOW(.T.) nWindow1 := WOpen(10, 10, 22, 70) RUN DIR // Display results in window

The only prerequisite is that such output is through DOS or BIOS. The DSETWINDOW() function controls whether or not this output is subsequently redirected. The Extended Driver chapter has more details.

In addition to the examples shown here there are many more window functions available for use that contribute to a comprehensive windows system.

Platforms
Available on MS-DOS
Tag
Intro

Acos()Harbour implementation  | 

Computes the cosine arc
Syntax
Acos(<nCosine>) → nCosArc
Arguments
nCosine Designates the cosine value for an angle where the response is determined in radians. The value is in the range of -1 to +1 (inclusive).
Returns
Acos() returns the cosine arc for nCosine.
Description
Acos() determines an angle size in radians for a cosine value. The returned value is in the range of 0 to pi.
Notes

■ The precision of the result can be influenced by the SetPrec()

function.

Examples
Compute the cosine arc:

? Str(Acos(0.7), 18, 15)      // 0.795398830184144
Platforms
Available on MS-DOS
See also

AddAscii()Harbour implementation  | 

Adds a value to each ASCII code in a string
Syntax
AddAscii(<cString>,<nValue>,[<nPosition>]) → cString
Arguments
cString [@] Designates the character string that is processed.
nValue Designates the value that is added to the ASCII value of the character.
nPosition Designates the position of the character to which the nValue is added. The default value tells CA-Clipper Tools to add to the ASCII value of the last character.
Returns
AddAscii() returns the modified character string.
Description

This function is very useful when you call procedures using macros. When you use AddAscii(), the string representing the macro can be changed without needing to include functions like Left(), Right(), Asc(), or SubStr() (see example).

This function also allows you to subtract a value. However, a conversion is necessary. If a lower case letter is converted into an upper case letter, a value of 32 must be subtracted. This occurs according to the following formula:

Chr((Asc(Character) + 256 - Difference) % 256)

Notes

■ If the nPosition is greater than the length of cString or

less than 0, the string remains unchanged.

■ Zero changes the value of the last character.

CSetRef() can be used to suppress the returned value for this

function in order to save space in working memory.

Examples
■  A value of 1 is added to the next to the last position in a
   string and to the last position in a string (Chr(Asc("2")+1) yields
   "3" etc.):

   ? AddAscii("macro21", 1, 6)        // "macro31"
   ? AddAscii("macro21", 1)           // "macro22"

■  You can also subtract; -- 32 is the difference between lower
   case and upper case letters, therefore Chr((Asc("m")+256-32) %256):

   ? AddAscii("macro21", 224, 1)      // "Macro21"
Platforms
Available on MS-DOS
See also

Additional Programs | 

Additional Programs
Description

Security

If CA-Clipper Tools functions that change interrupts are not properly uninstalled or if the Extended Driver is not implemented, you could use the INTSAVE.EXE and INTOFF.EXE programs as additional security.

INTSAVE

Drive:INTSAVE[/S|/R[FileName]]RETURN

INTSAVE saves all 256 interrupt vectors to a file called INSAVE.TAB. Alternatively, a different filename can be selected, if multiple applications need to access the same path in a network. A call with the /S switch saves the interrupt vectors,while a call with /R restores them.

If the program is called without parameters, it explains its operation on the screen and, if required, displays a list of interrupt vectors that have been changed.

INTOFF

Drive:INTOFF RETURN

This program represents an "emergency brake". It sets the vectors described below to an IRET in the system ROM, so that there is no danger of a system crash as a result of erroneous interrupt vectors. The mouse interrupt (033h) is also newly initialized and the timer tic rate is reset. Memory resident programs are uncoupled from their interrupt vectors as well and are thereby rendered unusable. The program sets the following interrupt vectors to harmless IRETs:

    Operation    Vector         Use in CA-Clipper Tools
    IRET         Timer 1C       KeySec(), SHOWIME()
                 Alarm 4A       KeyTime()
                 COM1 0C        V24 Functions
                 COM2 0B        V24 Functions
    INIT         Mouse 33       If foreign routines linked in
                 Timerspeed     SETTIC()

Both programs could be linked into a batch job which starts your CA-Clipper application. This would look as follows:

ECHO OFF INTSAVE /S INTSAVE1.TAB

CLIPPROG

INTSAVE /R INTSAVE1.TAB ECHO ON

With INTOFF, it would look like this:

ECHO OFF

CLIPPROG INTOFF

ECHO ON

This will avoid later system crashes.

Platforms
Available on MS-DOS

AddMonth()Harbour implementation  | 

Adds or subtracts months to/from a date
Syntax
AddMonth([<dDate>], [<nMonth>]) → dNewDate
Arguments
dDate Designates the date to which the nMonth months is added. The default is the system date.
nMonth Designates the number of months to add to dDate.
Returns
AddMonth() returns the new date after nMonth is added to dDate.
Description
Use this function to calculate payment due dates based on an invoice date and for similar applications. It permits you to add months to a given date. If you use a negative number, months are subtracted.
Notes
■ An empty date parameter will result in an empty date.
Examples
Show today's date, plus 36 months:

? "The payment period ends on: ", AddMonth(36)
Platforms
Available on MS-DOS

AfterAtNum()Harbour implementation  | 

Returns the remainder of the string after the nth appearance of a sequence
Syntax
AfterAtNum(<cSearchFor>,<cString>,[<nCounter>],
   [<nIgnore>]) → cString
Arguments
cSearchFor Designates the string for which the function searches.
cString Designates the string to search.
nCounter Designates which occurrence of cSearchFor within cString is found. The default value specifies the last occurrence in the search expression.
nIgnore Designates the number of characters that are eliminated from the search. The default value ignores none (0).
Returns
AfterAtNum() returns the remainder of the cString string from the first character after the nth (nCounter) occurrence of cSearchFor. If the last character in the sequence located is also the last character in the string being searched, then a null string is returned.
Description

This function finds the nth (nCounter) occurrence of cSearchFor within cString and returns the remainder of the string from the first position behind the located sequence.

In order to determine the nth (nCounter) occurrence of cSearchFor, AfterAtNum() searches from the left for each instance of this sequence. If CSetAtMupa() is off, then the search is continued after the last character of the sequence most recently found. Otherwise the search is continued after the first character of the sequence most recently found.

Notes

■ Implementing SetAtLike() allows you to use wild card

characters within cSearchFor.

Examples
■  Search a string for the last appearance of "aa" in two
   different ways:

   CSetAtMupa(.T.)
   ? AfterAtNum("aa", "aBaaBaaX")   // "X"

   CSetAtMupa(.F.)
   ? AfterAtNum("aa", "aBaaBaaX")   // "aX"

■  Search a string for the third existing "xx" within the string,
   where the first four characters are ignored!  Notice the differing
   results, depending on the multi-pass mode!

   String  := " AxxBBBBxxCCCCxxxDxxEExx"

   CSetAtMupa(.T.)
   ? AfterAtNum("xx", String, 3, 4)   // "DxxEExx"

   CSetAtMupa(.F.)
   ? AfterAtNum("xx", String, 3, 4)   // "EExx"

■  Examples for SetAtLike() can be found under the corresponding
   function description.
Platforms
Available on MS-DOS
See also

AlloFree()*Harbour implementation  | 

Determines the maximum memory size allocation
Syntax
AlloFree([<lMode>]) → nFreeMemory

*  This has been retained in CA-Clipper for compatibility purposes.
   Use the CA-Clipper Memory() function to develop future
   applications.
Arguments
lMode If passed as .T., the total available memory size is returned. The default value is the largest contiguous block (.F.).
Returns
AlloFree() returns the maximum possible size for a contiguous memory block or the total amount of free memory available.
Description
Use this function to help avoid "memory fault" error messages. You can implement it in conjunction with other functions that use a string area as a buffer (as when you read files).
Notes

■ If there is not enough room on the stack, AlloFree(.T.)

returns a value of -1.

Examples
■  This is what can happen if you try to print a maximum-length
   string without enough free memory:

   Var  :=  Space(65520)

■  Make a string of the maximum-length possible:

   Var  := Space(AlloFree())           // Under no circumstances
                                       // call with .T.!
   ? Len(Var)                          // How long has it become?

■  Read in a file...

   FileStr("Bigfile", AlloFree())      // The largest possible buffer

■  Entire available memory:

   ? AlloFree(.T.)                     // Available memory
Platforms
Available on MS-DOS
See also

AsciiSum()Harbour implementation  | 

Finds the sum of the ASCII values of all the characters of a string
Syntax
AsciiSum(<cString>) → nASCIISum
Arguments
cString Designates the character string for which the sum of all the ASCII values is computed.
Returns
AsciiSum() returns a number that corresponds to the sum of the ASCII codes of all the characters in cString.
Description
AsciiSum() allows you to form simple checksums for character strings. For example, this can be implemented during remote data transmission to identify transmission errors.
Notes

■ This function does not take character position into account,

so it cannot determine a character transposition. The Checksum() function should be used to determine character transposition.

Examples
■  Transposed characters yield identical results:

   ? AsciiSum("abc")          // Result: 294
   ? AsciiSum("cba")          // Result: 294

■  A null string returns 0:

   ? AsciiSum("")             // Result: 0
Platforms
Available on MS-DOS
See also

AscPos()Harbour implementation  | 

Determines the ASCII value of a character at a particular position within a string
Syntax
AscPos(<cString>,[<nPosition>]) → nAsciiValue
Arguments
cString Designates the character string that is searched.
nPosition Designates the character of cString for which the ASCII value is determined. The default character is the last character.
Returns
The function returns the ASCII value for the character at nPosition within cString.
Description
AscPos() allows you to determine the ASCII value of a selected key within a character string.
Notes

■ The returned value can be between 0 and 255.

■ If cString is a null string, or nPosition is larger than

the length of the string, AscPos() returns 0.

■ If nPosition is 0, the ASCII value for the last character is

returned.

Examples
■  You can specify:

   ? AscPos(String, 5)

■  Or you can specify:

   ? ASC (SubStr(String, 5, 1))
Platforms
Available on MS-DOS
See also

Asin()Harbour implementation  | 

Computes the sine arc
Syntax
Asin(<nSine>) → nSineArc
Arguments
nSine Designates the angle sine value for which you want the response determined in radians. The value can be in the range of -1 to +1 (inclusive).
Returns
Asin() returns the arc sine for nSine.
Description
Asin() determines an angle size in radians for a sine value. The return value is in the range of -pi/2 to +pi/2.
Notes
■ The SetPrec() function can influence the result.
Examples
Compute the sine arc:

? Str(Asin(0.5), 18, 15)      // 0.523598775598299
Platforms
Available on MS-DOS
See also

Atan()Harbour implementation  | 

Computes the tangent arc
Syntax
Atan(<nTangent>) → nArcTan
Arguments
nTangent Designates the angle tangent value for which you want the response determined in radians.
Returns
Atan() returns the tangent arc for nTangent.
Description
Atan() determines an angle size in radians for a tangent value.
Notes

■ The SetPrec() function can influence the precision of the

result.

Examples
Compute the arc of the tangent :

? Str(Atan(Pi()/4), 18, 15)      // 0.665773750028354
Platforms
Available on MS-DOS
See also

AtAdjust()Harbour implementation  | 

Adjusts the beginning position of a sequence within a string
Syntax
AtAdjust(<cSearchFor>,<cString>,<nEndpoint>,
   [<nCounter>],[<nIgnore>],[<nCharacter|
   <cCharacter>]) → cString
Arguments
cSearchFor Designates the character string for which the function searches, or the character string that provides the reference point for adjustment.
cString Designates the character string within which the adjustment occurs.
nTargetPosition Designates from which position within the character string the search expression is adjusted.
nCounter Designates which occurrence of the Searchexpression is taken into account. The default value is for the last occurrence.
nIgnore Designates the number of characters at the beginning of the search string that are removed. The default value is none.
nCharacter|cCharacter Designates a character, as necessary, to carry out the adjustment. It can be an individual character or an ASCII value between 0 and 255. The default value is a space Chr(32).
Returns
AtAdjust() returns the modified character string.
Description

The function first looks for the cSearchFor parameter within the character string. From this point, the rest of the cString is moved (adjusted) by either inserting or removing blanks until the nTargetPosition is reached. In lieu of blanks, nCharacter| cCharacter can be used as a fill character.

Additionally you can specify that the nth occurrence of cSearchFor be used and whether or not a specific number of characters at the beginning of the search string is eliminated.

Notes

■ Using CSetAtMupa() can influence how the search is performed.

Using SetAtLike() permits the use of wild cards within the search sequence.

Examples
■  Align comments at column 60.  The search is for the first
   occurrence of "//".  Since there is usually at least one space before
   each "//", search for " //":

   ? AtAdjust(" //", Line, 60, 1)

■  Move the extensions for the following list of file names to
   position 10 and eliminate the ".":

   WINDOW.DBF
   PLZ.DBF
   BACK.DBF
   HELP.DBF
   LOG.DBF

   CharRem(".", AtAdjust(".", File, 10))

   WINDOW      DBF

   PLZ         DBF
   BACK        DBF
   HELP        DBF
   LOG         DBF

■  Use AtAdjust() with CSetAtMupa().  There is always a problem
   determining whether "AA" occurs twice or three times in "AAA".
   Depending on CSetAtMupa(), the function searches behind the last
   character, or starts from the last character of a located sequence:

   CSetAtMupa(.F.)
   ? AtAdjust("AA", "123AAABBB", 7, 2)       // Sequence not found

   CSetAtMupa(.T.)
   ? AtAdjust("AA", "123AAABBB", 7, 2)       // "123A  AABBB"
Platforms
Available on MS-DOS
See also

Atn2()Harbour implementation  | 

Computes the angle size from the sine and cosine
Syntax
Atn2(<nSine>,<nCosine>) → nArc
Arguments
nSine Designates the sine value for an angle.
nCosine Designates the cosine value for an angle.
Returns
Atn2() returns the angle sine in radians.
Description
Atn2() returns the angle sine in radians, where the sine and the cosine of a given point have been specified. The function returns results for all four quadrants and corresponds to a call of Atan(x/y). One advantage of the Atn2() function is that no "divide by zero" error can occur. The returned value is in the range of -pi to +pi.
Notes

■ The SetPrec() function can influence the precision of the

result.

Examples
■  Compute the sine and cosine of 30 degrees.  DToR() is then
   used to convert these into the radian value:

   SET DECIMALS TO 4
   X  :=  Sin(DToR(30))
   Y  :=  Cos(DToR(30))

■  Use RToD() to compute the result in degrees:

   ? RToD(Atn2(x, y))         // 30.0000
Platforms
Available on MS-DOS
See also

AtNum()Harbour implementation  | 

Determines the starting position of a sequence within a string
Syntax
AtNum(<cSearchFor>,<cString>,[<nCounter>],
   [<nIgnore>]) → nPosition
Arguments
cSearchFor Designates the expression for which the function searches.
cString Designates the character string to search.
nCounter Designates which occurrence of cSearchFor within cString is determined. The default value is for the last occurrence of the search expression.
nIgnore Designates the number of characters that should be excluded from the search. The default value is none (0).
Returns
The function returns the position where cSearchFor begins. If no corresponding position can be determined, the function returns 0.
Description

AtNum() determines the initial position of the nth (nCounter) occurrence of cSearchFor within the cString. Additionally, the function takes into account the CSetAtMupa() setting, which causes differing results.

AtNum() searches from the left in order to determine the nth (nCounter) occurrence of the cSearchFor. If CSetAtMupa() is off, the search continues after the last character of the sequence most recently located. However, if the CSetAtMupa() is on, the search always continues after the first character in the most recently located sequence.

If the nIgnore parameter is not specified, the function initiates the search with the first character of cString. If the nIgnore parameter is specified, nIgnore characters are ignored from the start of the string and are excluded from the search.

Notes

■ If no value is specified for nCounter, the function

determines the last occurrence of the cSearchFor sequence.

■ When you implement SetAtLike(), wildcard characters can be

used within the search expression.

Examples
■  Search for the last occurrence:

   ? AtNum("bc", "abcdeabc")               // Result: 7

■  Search for the first occurrence:

   ? AtNum("bc", "abcdeabc", 1)            // Result: 2

■  Search for the first occurrence, excluding the first three
   characters:

   ? AtNum("bc", "abcdeabc", 1, 3)         // Result: 7

■  Determine the impact of CSetAtMupa() on a search for the last
   occurrence of "aa" in "aaa":

   CSetAtMupa(.F.)                         // Off
   ? AtNum("aa", "aaa")                    // Result: 1

   CSetAtMupa(.T.)                         // On
   ? AtNum("aa", "aaa")                    // Result: 2
Platforms
Available on MS-DOS
See also

AtRepl()Harbour implementation  | 

Searches for a sequence within a string and replaces it
Syntax
AtRepl(<cSearchFor>,<cString>,<cReplace>,
   [<nCounter>],[<lMode>]) → cString
Arguments
cSearchFor Designates the expression for which the function searches.
cString [@] Designates the character string that is searched.
cReplace Designates the character string that is exchanged for the sequence in cString.
nCounter Designates which or how many occurrences of cSearchFor within cString are replaced by cReplace. The default value is for the last occurrence of the search expression.
lMode Designates if only the nth (nCounter) sequence is replaced (.T.), or if all sequences up to the nth (nCounter) are replaced (.F.). The default value (.F.) designates that all sequences are replaced.
Returns
The function returns a character string in which one or many of the cSearchFor sequences have been replaced by cReplace.
Description

AtRepl() allows you to replace one or more sequences within cString. cReplace can be shorter or longer than cSearchFor.

nCounter specifies that the function searches for the nth occurrence of the sequence. If no value is specified, then the last occurrence is used. All occurrences of cSearchFor, up to and including the one sought, are replaced unless nCounter is assigned a value greater than 0 and lMode is designated .T..

The CSetAtMupa() setting is only checked when the length of cReplace is shorter than or equal to that of cSearchFor, yielding different results. Beginning on the left, the character string is searched for each occurrence of the cSearchFor sequence. If CSetAtMupa() is off (.F.), then the search continues after the last character of the replaced sequence. However, if CSetAtMupa() is on, the search always continues from the first character of the replaced sequence.

Notes

■ By implementing SetAtLike() you can use wildcard characters

within the search sequence.

cString can be passed by reference. If this is the case,

then both cSearchFor and cReplace must be the same length.

■ If cSearchFor and cReplace are identical, the function

terminates immediately. Such an exchange makes no sense, and if CSetAtMupa() is (.T.), the exchange results in an endless loop.

Examples
■  Exchange all "123" with "ab":

   ? AtRepl("123", "123_123_123", "ab")             // "ab_ab_ab"

■  Replace "789" with a longer string "abcd" (ignore multi-pass):

   ? AtRepl("789", "789_789", "abcd")               // "abcd_abcd"

■  Exchange all "123" with "ab", up to and including the second
   occurrence:

   ? AtRepl("123", "123_123_123", "ab", 2)          // "ab_ab_123"

■  Exchange only the second occurrence of "123" with "ab":

   ? AtRepl("123", "123_123_123", "ab", 2, .T.)     // "123_ab_123"

■  Exchange all "aa" for "a" and the change the influence of
   CSetAtMupa():

   CSetAtMupa(.F.)
   ? AtRepl("aa", "aaaa", "a")                      // "aa"

   CSetAtMupa(.T.)
   ? AtRepl("aa", "aaaa", "a")                      // "a"

■  Exchange "abc" with "ab", with and without multi-pass:

   CSetAtMupa(.F.)
   ? AtRepl("abc", "123abcc456", "ab")              // "123abc456"

   CSetAtMupa(.T.)
   ? AtRepl("abc", "123abcc456", "ab")              // "123ab456"
Platforms
Available on MS-DOS
See also

AtToken()Harbour implementation  | 

Finds the position of a token within a string
Syntax
AtToken(<cString>,[<cDelimiter>],[<nCounter>])
   → nPosition
Arguments
cString Designates the character string that is passed.
cDelimiter Designates the delimiter list used to identify the tokens.
nCounter Designates which token's position is determined. The default value is for the last token located.
Returns
AtToken() returns the beginning position of the nth (nCounter) token within the cString.
Description

AtToken() allows you to determine the beginning position of a token in cString. This value can be extremely helpful when you work with other string functions. The function uses the following list of delimiters as a standard:

CHR 32, 0, 9, 10, 13, 26, 32, 138, 141

and the characters ,.;:!?/<<>>()^#&%+-*

This list can also be replaced with your own list of separators, cDelimiter. Here are some examples of useful delimiters:

Table 4-1: Recommended Delimiter Sequences

    Description         <cDelimiter>
    Pages               Chr(12)(Form Feed)
    Sentences           ".!?"
    File names          ":\."
    Numerical strings   ",."
    Date strings        "/."
    Time strings        ":."

Examples
■  Find the beginning position of the last token:

   ? AtToken("Good Day")                      // 6

■  Find the beginning position of the fourth token:

   ? AtToken("What a beautiful day.", 4)      // 18

■  Attempt to determine the beginning position of an unavailable
   token:

   ? AtToken("What a beautiful day.", 6)      // 0
Platforms
Available on MS-DOS
See also

BeforAtNum()Harbour implementation  | 

Returns the string segment before the nth occurrence of a sequence
Syntax
BeforAtNum(<cSearchFor>,<cString>,[<nCounter>],
   [<nIgnore>]) → cString
Arguments
cSearchFor Designates the string for which the function searches.
cString Designates the string that is searched.
nCounter Designates which occurrence of the cSearchFor within the cString is determined. The default value is for the last occurrence in the search expression.
nIgnore Designates the nuber of characters that are eliminated from the search. The default value ignores none (0).
Returns
The function returns all the characters in cString in front of the sequence determined. If no corresponding sequence is found, then a null string is returned.
Description

This function determines the beginning position of the nth (nCounter) occurrence of cSearchFor within cString and returns the string segment before this sequence. Additionally, the function takes into account the CSetAtMupa() setting, which can cause differing results.

In order to determine the nth (nCounter) occurrence of the cSearchFor, BeforAtNum() searches from the left for each instance of this sequence. If CSetAtMupa() is off, then the search continues after the last character of the sequence most recently found. If CSetAtMupa() is on, the search continues after the first character of the sequence most recently found.

Notes

■ Implementing SetAtLike() allows you to use wildcard characters

within the search sequence.

Examples
■  Search a string for the last appearance of a sequence:

   ? BeforAtNum("ab", "abcabdabe")                  // "abcabd"

■  Search a string for the first occurrence of a sequence:

   ? BeforAtNum("ab", "abcabdabe", 1)               // ""

■  Search a string for the first occurrence of a sequence, where
   the first three characters are not considered in the search:

   ? BeforAtNum("ab", "abcabdabe", 1, 3)            // "abc"

■  Search a string for the third occurrence of "xx", where the
   first four characters are not considered!  Notice the different
   results when you use the multi-pass mode:

   String := "AxxBBBBxxCCCCxxxDxxEExx"

   CSetAtMupa(.T.)
   ? BeforAtNum("xx", String, 3, 4)            // "AxxBBBBxxCCCCx"

   CSetAtMupa(.F.)
   ? BeforAtNum("xx", String, 3, 4)            // "AxxBBBBxxCCCCxxxD"
Platforms
Available on MS-DOS
See also

BitToC()Harbour implementation  | 

Converts position-dependent bits into characters
Syntax
BitToC(<nInteger>,<cBitpattern>,[<lMode>])
    → cCharacterstring
Arguments
nInteger Designates a number in the range of 0 to 65535, which corresponds to a bit pattern.
cBitpattern Designates a character string with a maximum of 16 characters. Each character corresponds to a bit in nInteger, where the last character corresponds to the lowest-value bit.
lMode When this optional parameter is designated as .T., 0 bits change to blanks. The default is no change.
Returns
The returned string contains the corresponding characters passed by the bit pattern.
Description
The BitToC() function changes the bits of a number into a sequence of corresponding characters. This facilitates work with such bit-coded information as file attributes. Depending on the lMode logical parameter (the l in lMode symbolizes logical), 0 bits either displays no character (.F.) or a blank (.T.).
Notes

■ If lMode is designated as .T., the string length that

results always corresponds to cBitpattern.

Examples
■  Change file attributes:

■  The number 2 corresponds to a binary "00000010":

   ? BitToC(2, "ADVSHR")            // "H" as the next to
                                    // last character

■  The number 5 corresponds to a binary "00000101":

   ? BitToC(5, "ADVSHR")            // "SR"

■  The number 5, with the 0 bit displayed as a blank:

   ? BitToC(5, "ADVSHR", .T.)       // "   S R"
Platforms
Available on MS-DOS
See also

BIOSDATE()  | 

Determines the system BIOS date
Syntax
BIOSDATE() → dBIOSdate
Returns
BIOSDATE() returns the ROM BIOS date.
Description
As a rule, all industry-standard PC's insert a generated date at a particular memory location in the BIOS. Based on this date, incompatibilities known to exist up to a particular release can be acknowledged. The function returns a date-type value and spares you an elaborate PEEK.
Notes

■ Although unlikely, you may not find a date at this BIOS

position. Therefore, you should test to see if a date is returned.

Examples
Is this an older computer?

IF BIOSDATE() < CToD("01/01/85")
   ? "Older version ...!"
ENDIF
Platforms
Available on MS-DOS
See also

Blank()Harbour implementation  | 

Creates a blank value for each data type
Syntax
Blank([<expValue>], [<lMode>]) → xBlank
Arguments
expValue[@] Designates any valid expression; the type is not important.
lMode Designates whether or not the length of the expValue is to change in the event that expValue is a string. If .T. is designated, the length is retained. The default value is Change Length (.F.).
Returns
Blank() returns a blank value with the same data type as the expValue parameter.
Description

Blank() clears desired data fields with the variables. Blank() returns the following results:

Table 13-1: Data Type Blank Values

    Argument            Returned Value
    Character string    Null string or blank string
    Numeric             Value of 0
    Logical             .F.
    Date                A blank date

The default for lMode is .F. and produces a null string when a character string is input. However, if this parameter is designated as .T.., the string length is not changed.

Notes

SET DATE has no affect on how Blank() handles a date. The

blank date display is created in the format you select.

■ You can suppress the value this function returns by

manipulating strings through CSetRef() implementation. To save room in the working memory, designate lMode as .T..

Examples
Display blank values for data-type values:

SET DATE AMERICAN
? Blank(Date())          // "  /  /  "
? Blank()                // .F.
? Blank(.T.)             // .F.
? Blank(99)              //  0
? Blank("abc")           // ""
? Blank("11:59:59")      // ""
? Blank("abc", .T.)      // "  " Blank string
Platforms
Available on MS-DOS
See also

BoM()Harbour implementation  | 

Determines the date of the first day of a month
Syntax
BoM([<dDate>]) → dBeginningOfMonth
Arguments
dDate Designates a date for which the first day of the month that contains this date, is determined. The default is the system date.
Returns
BoM() returns the first day of the month in which dDate lies.
Description
BoM() allows you to determine the first day of the month that contains dDate. This allows you to determine how many days have past since the beginning of the month.
Notes

■ If no date is passed, then the function automatically uses the

system date. An empty date parameter always returns an empty date.

Examples
Display the elapsed days in the current month:

? Date() - BoM()
Platforms
Available on MS-DOS
See also

BoQ()Harbour implementation  | 

Determines the date for the beginning of a quarter
Syntax
BoQ([<dDate>]) → dBeginningOfQuarter
Arguments
dDate Designates a date for which the first day of the quarter in which it lies is determined. The default is the system date.
Returns
BoQ() returns the date at the beginning of the quarter that contains dDate.
Description
For example, use BoQ() to determine when the current quarter that contains dDate began, and then compute the number of days that have elapsed since the quarter began.
Notes

■ If you do not specify a date, the function automatically uses

the system date. An empty date parameter always returns an empty date.

Examples
Display the date of the first day of the current quarter:

? "The first day of the current quarter is:", BoQ()
Platforms
Available on MS-DOS
See also

BoY()Harbour implementation  | 

Determines the date for the beginning of a year
Syntax
BoY([<dDate>]) → dBeginningOfYear
Arguments
dDate Designates the date for which the first day of the year is determined. The default is the system date.
Returns
BoY() returns the first of January for the year that contains dDate.
Description
BoY() determines the year without having to create a date-type variable.
Notes

■ If no date is specified, the function automatically uses the

system date. An empty date parameter always returns an empty date.

Examples
The first date of the current year (1991):

? BoY()            // 01/01/91
Platforms
Available on MS-DOS
See also

BOOTCOLD()  | 

Triggers a cold boot
Syntax
BOOTCOLD()
Description
BOOTCOLD() allows you to restart the system after a critical error (assuming anything is still working), or to allow any program changes you have made in CONFIG.SYS or AUTOEXEC.BAT to take effect. The function calls for a cold start. This means a RAM check and POST (power on self test) are carried out.
Notes

■ Close all files prior to a boot. You can use CLOSE DATABASES.

■ If there is a large system memory, a RAM check takes a long

time. To avoid this lengthy procedure, you might consider using the BOOTWARM() function for a restart after changing CONFIG.SYS.

Examples
An error in an error trap can no longer be changed:

CLOSE DATABASES
BOOTCOLD()
Platforms
Available on MS-DOS
See also

BOOTWARM()  | 

Triggers a warm start of the system
Syntax
BOOTWARM()
Description
This function allows changes in CONFIG.SYS or AUTOEXEC.BAT to become effective. This function restarts the system just like BOOTCOLD(), but no RAM check or POST (power on self test) are carried out.
Notes

■ Close all files before you boot. You can use CLOSE DATABASES

to do this.

BOOTWARM() is the same as pressing the Ctrl-Alt-Del keys.

Examples
A new CONFIG.SYS is created within the program and the system reboots:

COPY TO CONFIG.SYS SDF
CLOSE DATABASES
BOOTWARM()
Platforms
Available on MS-DOS
See also

com_Break()Harbour implementation  | 

Creates a break on a transmission line
Syntax
com_Break(<nComPort>,<nDuration>) → lSuccess
Arguments
nComPort Designates the serial interface (1 to 4) where a break is set.
nDuration Designates the time in milliseconds that the break remains active. The default value is 100 milliseconds.
Returns
com_Break() returns .T. when the break has been successfully set.
Description

The output of a break means that the transmission line of an interface is held at a specific level for a fixed period of time. This time can be selected as a numeric parameter between 1 and 65535 milliseconds.

As a rule, a break is usually between 100 and 350 milliseconds long.

Examples
Output a 200 millisecond on interface COM1:

com_Break(1, 200)
Platforms
Available on MS-DOS
See also

com_Close()Harbour implementation  | 

Clears the receiving buffer and closes the com port
Syntax
com_Close(<nComPort>) → lClosed
Arguments
nComPort Designates which port is closed, COM1(1) to COM4(4).
Returns
A return of .T. indicates that the port is open and can be closed successfully.
Description
This function closes one of the ports (1 to 4). This means that the buffer is cleared, and all signals in the modem control register (MCR) are deactivated. Characters remaining in the buffer are lost. The DTR and RTS signals become inactive, and any existing modem connection is broken.
Notes
Warning! All characters in the buffer are cleared, and the status register is set to 0. Existing connections are always broken!
Examples
nCharacter  :=  com_Count(1)      // How many characters in
                                  // the buffer ?

IF nCharacter > 0
   * Read everything from buffer!
   cContent  :=  com_Read(1, nCharacter)
ENDIF

com_Close(1)
Platforms
Available on MS-DOS
See also

com_Count()Harbour implementation  | 

Counts the number of characters in the input buffer
Syntax
com_Count(<nComPort>) → nTotalCharacters
Arguments
nComPort Designates the port (1 to 4) for which the number of characters in the input buffer is determined.
Returns
com_Count() returns the number of characters in the selected buffer.
Description
This function allows you to determine the number of characters in one of the four possible buffers. This lets you determine how many characters can be read with the com_Read() function.
Notes

■ If an attempt is made to read the number of characters

available in a closed port, the function returns a value of -1.

Examples
nCharacter  :=  com_Count(1)   // Number of characters-port 1

IF nCharacter > 0
   com_Read(1, 1)              // Read 1 character
ENDIF
Platforms
Available on MS-DOS
See also

com_CRC()Harbour implementation  | 

Computes a Cyclic Redundancy Check (CRC) for the string
Syntax
com_CRC(<cString>,[<nStart>],[<nPolynomial>])
   → nCRCValue
Arguments
cString Designates the character string for which a CRC is computed.
nStart Designates a starting value that is added to the CRC. This value is computed in order to form a CRC for multiple character strings. The default value is 0.
nPolynomial Designates another polynomial. The maximum is a 17- bit polynomial. The default polynomial is CRC-16 X.25 (see below).
Returns
com_CRC() returns the 16-bit CRC for cString as a numeric value between 0 and 65535.
Description

CYCLIC REDUNDANCY CHECK Many file transfer protocols use CRC for accurate error recognition. This CRC function offers you decisive help when programming your own protocols, like XMODEM or KERMIT.

The specific CRC value always depends on the polynomial that you use. This information can be passed as an optional parameter in the form of an integer so that the function has almost universal utility. The CRC 16 X.25 polynomial used in X.25 systems,. XMODEM is the default value used in the examples below.

A few examples of polynomials:

Table 3-1: The Different Polynomials

    Type           Arguments Polynomial
    Parity         3         2^1+1
    LCR-8          257       2^8+1
    CRC-12         5011      2^12+2^11+2^3+2^2 +2^1+1
    CRC-16 X.25    69665     2^16+2^12+2^5+1
    CRC-16         98309     2^16+2^15+2^2+1

Notes

■ If nStart is not passed, then the loss of the previous

Chr(0) out of cString is not detected by a later CRC review. This can be avoided if nStart is given a starting value that is not equal to 0.

■ A function called XMoBlock() is available for building XMODEM

blocks.

Examples
■  These are simple CRC calculations:

   com_CRC("abc")                 // 40406
   com_CRC("cba")                 // 54260

■  These are calculations for multiple strings:

   nCRC1 := com_CRC("123")
   nCRC2 := com_CRC("456", nCRC1)

   ? nCRC2 == com_CRC("123456")   // .T., values are equal

■  Form a block for data transmission.  The string is appended to
   the data:

   cData   := "ABCDEFGHIJKLMNOP"
   nCRC    :=  com_CRC(cData)

   cCRCSTR := I2Bin(CRC)          // CRC as a string
   cCRCSTR := CharSwap(cCRCSTR)   // Exchange both bytes
   cBlock  := cData + cCRCSTR     // Transmission block

■  The CRC must be 0 for the entire transmitted block!

   ? com_CRC(cBlock)  = 0         // .T., when correctly
                                  // transmitted
Platforms
Available on MS-DOS
See also

com_CTS()Harbour implementation  | 

Queries the Clear To Send (CTS) status
Syntax
com_CTS(<nComPort>) → lCTSActive
Arguments
nComPort Designates the port (1 to 4) for which CTS is tested.
Returns
A return of .T. indicates that CTS is active (MSR Bit 5 = 1). A return of .F. indicates that CTS is inactive (MSR Bit 5 = 0).
Description
com_CTS() lets you check the Clear To Send (CTS) signal within a program. Whether CTS is used for a hardware handshake or for other purposes, depends on the external hardware that you use.
Notes
■ If Delta-CTS is required, you must use com_MSR().
Examples
DO WHILE .NOT. com_CTS(1)           // Wait for CTS
   * ...
ENDDO

com_Send(1, "Good Morning")         // Transmit text
Platforms
Available on MS-DOS
See also

com_DCD()Harbour implementation  | 

Queries the Data Carrier Detect (DCD) status
Syntax
com_DCD(<nComPort>) → lDCDActive
Arguments
nComPort Designates the port (1 to 4) on which DCD is tested.
Returns
A return of .T. indicates that DCD is active (MSR Bit 8 = 1). A return of .F. indicates that DCD is inactive (MSR Bit 8 = 0).
Description
com_DCD() lets you check the Data Carrier Detect signal within a program. When you use a modem, DCD indicates that you have a remote connection.
Notes
■ If Delta-DCD is required, you must use com_MSR().
Examples
A connection is only established when a valid DCD signal has been
recognized:

? "Call recognized..."

DO WHILE .NOT. com_DCD(1)         // Wait for carrier (DCD)
   * ...
ENDDO

? "Carrier recognized - connection established ..."
Platforms
Available on MS-DOS
See also

com_DosCon()Harbour implementation  | 

Provides screen output through DOS (ANSI.SYS terminal emulation)
Syntax
com_DosCon(<cString>,[<nLine>],[<nColumn>]) → cNull
Arguments
cString Designates a string that is output through DOS.
nLine Designates the line number where the string is output. The default position is the cursor position.
nColumn Designates the column number where the string is output. The default position is the cursor position.
Returns
This function always returns a null string.
Description

com_DosCon() allows you to output a string through DOS. This function can be used to provide an interpretation of ANSI control sequences through ANSI.SYS. The installed status of the ANSI driver can be determined using the ISANSI() function.

In this way you can easily create a communications program with ANSI terminal emulation.

Notes

■ Notice that DSETWINDOW() should be switched off when using

this function. Otherwise the output is routed through the CA-Clipper driver module, and operates like a print (?) with a position instruction.

Examples
When ANSI.SYS is linked in, output is through DOS.  This makes a simple
terminal emulation possible!

DSETWINDOW(.F.)               // Important for ISANSI()
cData  := com_Read(1)         // Data read in

IF ISANSI()                   // ANSI driver present?
   com_DosCon(cData)
ELSE
   * Own ANSI handling
ENDIF
Platforms
Available on MS-DOS
See also

com_DSR()Harbour implementation  | 

Queries the Data Set Ready (DSR) status
Syntax
com_DSR(<nComPort>) → lDSRActive
Arguments
nComPort Designates the port (1 to 4) on which DSR is tested.
Returns
A return of .T. indicates that DSR is active (MSR Bit 6 = 1). A return of .F. indicates that DSR is inactive (MSR Bit 6 = 0).
Description
com_DSR() lets you check the Data Set Ready signal within a program.
Notes
■ If Delta-DSR is required, you must use com_MSR().
Examples
Many modems give an active DSR as soon as a connection is established:

DO WHILE .NOT. com_DSR(1)            // Wait for DSR (Call)
   * ...
ENDDO

? "Call recognized."
Platforms
Available on MS-DOS
See also

com_DTR()Harbour implementation  | 

Queries/sets the Data Terminal Ready (DTR) status
Syntax
com_DTR(<nComPort>,[<lNewDTRStatus>]) → lOldDTRStatus
Arguments
nComPort Designates the port (1 to 4) on which DSR is tested.
lNewDTRStatus Designates the status of DTR. .T. designates that the DTR signal is active, and .F. designates that the signal is inactive. If the parameter is not specified, CA-Clipper Tools does not affect the DTR exit signal.
Returns
The returned value corresponds to the DTR signal status prior to the new setting, or in the absence of lNewDTRStatus, the returned value corresponds to the current DTR. A return of .T. indicates that the DTR is active (MCR bit 1 = 1). A return of .F. indicates that the DTR is inactive (MCR bit 1 = 0).
Description
com_DTR() queries the DTR signal status. If the second parameter is not supplied, the DTR signal status does not change.
Notes

■ The com_Close() function resets DTR (to inactive). By

contrast, COM_OPEN does not automatically make DTR active!

Examples
A com_Open() does not set the DTR signal.  You must specifically set the
DTR signal.

nBuff_size  :=  4000                      // 4000 byte buffer
lComOk      :=  com_Open(1, nBuff_size)   // Open COM1

IF lComOk
   com_DTR(1, .T.)                        // Activate DTR Port 1
   * ...
ENDIF
Platforms
Available on MS-DOS
See also

com_ErrChr()Harbour implementation  | 

Defines the replacement character for a character that is not received correctly
Syntax
com_ErrChr(<nComPort>,[<nErrorCharacter|cErrorCharacter>])
   → lChanged
Arguments
nComPort Designates the port (1 to 4) where an external line termination character is established.
nErrorCharacter|cErrorCharacter Designates the individual error character, which can be given as a number or a character. When it is not specified, the port functions do not set any error character in the buffer.
Returns
com_ErrChr() returns .T. when the opened port is addressed.
Description
It is always possible that characters received during a file transmission from the port, UART, are recognized inaccurately. In such cases either an error procedure must be called (i.e. com_Key()) or the inaccurate character must be flagged. During remote transmission, a "trash" character is output. Chr(177) is the default "trash" character; however, you can use whatever error character you choose or you can suppress the output of a "trash" character entirely.
Notes

■ The Line Status Register (LSR) setting is used to determine

whether or not characters were inaccurately received.

Examples
■  Use Chr(250) as an error character for port 2:

   ? com_ErrChr(2, 250)       // .T., when accepted

■  Switch off the use of an error character for port 4:

   ? com_ErrChr(4)            // .T., when accepted
Platforms
Available on MS-DOS
See also

com_Event()Harbour implementation  | 

Designates which event at the port triggered a key trap
Syntax
com_Event(<nComPort>,<nMode>) → nCode
Arguments
nComPort Designates the port (1 to 4) that is tested for the event.
nMode Designates a numeric value between 1 and 5 (see table 3-2).
Returns
This function returns the code of an incoming character, MSR status, LSR status, or the number of errors that have occurred to date as a function of the nMode parameter value.
Description

As a rule, it is necessary to determine the cause of a trap if a character is placed in the keyboard buffer and the procedure specified with SET KEY TO is called. The numeric parameter determines what information is accessed. The information returned for modes 1 to 5 are defined as follows:

Table 3-2: Query Codes for Event Information

    Code    Event Information
    1       The function will return the ASCII code of the incoming
            character.  If no character is available, a -1 is returned.
    2       The function returns the status of the MS register at the time
            of the interrupt.
    3       The function returns the status of the LS register at the time
            of the interrupt.
    4       The value of the internal error counter will be returned. The
            error events in the LSR since the last com_Init() will be
            counted.
    5       Returns the number of characters which had to be rejected
            because the buffer was 100% full.

Notes

■ With the exception of the error counter, all status

information is reset when you open the port or when you call com_Key() again.

■ The conditions of MSR and LSR are considered at each interrupt

and are linked to the respective status byte in the internal environment through a logical OR operation. It is therefore possible to place multiple bits in one of the registers.

■ Overrun errors, parity errors, and frame errors (bits 1 to 3)

are counted as errors exclusively.

Important! The input lines on conventional PC interface cards are normally not terminated. This can lead to inexplicable results when you query the MSR.

Examples
Determine the number of errors that have occurred:

nErrorCnt  :=  com_Event(1, 4)

IF nErrorCnt > 25
   * more than 25 errors?
   ? "Too many errors -  terminate program!"
   lRelease  :=  .T.
ENDIF
Platforms
Available on MS-DOS
See also

com_Flush()Harbour implementation  | 

Clears the receiving buffer
Syntax
com_Flush(<nComPort>) → lClear
Arguments
nComPort Designates the port (1 to 4) for which the receiving buffer is cleared.
Returns
If the receiving buffer can be cleared successfully, the function returns .T..
Description

This function allows you to flush all the characters in a receiving buffer. This makes it unnecessary to tediously determine how many characters are currently in the buffer in order to remove them with a read procedure.

com_Flush() guarantees a truly empty buffer. However, a new character can be received between the time that you call a com_Count() and a com_Read().

Notes
■ A com_Flush() on an unopened port is ineffective.
Examples
cHayes  :=  "ATZ"           // Hayes modem reset command
com_Send(1, cHayes)         // Issue Hayes command
Inkey(1)                    // Wait one second
com_Flush(1)                // Reject modem reply messages
Platforms
Available on MS-DOS
See also

com_GetIO()Harbour implementation  | 

Determines the base address of a port
Syntax
com_GetIO(<nComPort>) → nIOPort
Arguments
nComPort Designates the port (1 to 4) to which the current I/O address is delivered.
Returns
com_GetIO() returns the I/O address of the designated port. With an invalid parameter or an unavailable port, the function returns a value of -1.
Description
com_GetIO() determines with which port I/O address CA-Clipper Tools functions communicate. This function only returns a value known to CA-Clipper Tools software. It cannot determine the I/O address of an interface card!
Examples
■  Determine the COM1 I/O address:

   ? com_GetIO(1)               // 1016

■  Specify that you need the address in hexadecimal form:

   ? NToC(com_GetIO(1), 16)     // "3F8"

■  Specify an invalid port number:

   ? com_GetIO(5)               // -1
Platforms
Available on MS-DOS
See also

com_GetIRQ()Harbour implementation  | 

Determines the interrupt request for a port
Syntax
com_GetIRQ(<nComPort>) → nIRQ
Arguments
nComPort Designates the port (1 to 4) to which the IRQ currently in use is delivered.
Returns
com_GetIRQ() returns the IRQ currently in use for the designated port. When there are incorrect parameters, the function returns a value of -1.
Description
com_GetIRQ() determines which IRQ is served by the CA-Clipper Tools functions for a particular port. This value corresponds to an internal CA-Clipper Tools software setting. You cannot determine which IRQ is using a particular port.
Examples
■  Determine the interrupt request for IRQ to COM2:

   ? com_GetIRQ(2)      // 3

■  Specify an inaccurate port number:

   ? com_GetIRQ(5)      // -1
Platforms
Available on MS-DOS
See also

com_Hard()Harbour implementation  | 

Turns the hardware handshake (automatic CTS) on/off
Syntax
com_Hard(<nComPort>,<lNewHandshake>,[<lDTR/DSR>])
   → lOldHandshake
Arguments
nComPort Designates the port (1 to 4) for which the hardware handshake is switched on or off.
lNewHandshake Designates whether the handshake is on (.T.) or off (.F.).
lDTR/DSR Designates whether the function uses the DTR/DSR handshake or the RTS/CTS handshake. When passed as .T., the function uses the DTR/DSR handshake instead of the RTS/CTS handshake.
Returns
When called only with nComPort, the com_Hard() returns .T. if the hardware handshake is on and .F. if the hardware handshake is off. When lNewHandshake is passed, the function returns the status prior to the new setting.
Description
The size of a receiving buffer is always limited. To avoid overflow, and thereby a loss of characters, software or hardware handshakes are usually implemented. During a hardware handshake, the port monitors the RTS signal. If you use this function to switch this handshake on, the signal is activated as soon as the buffer is 75% full. As soon as the buffer content is once again reduced to 50% or less, the port (the RTS signal) is once again released. Some printers use the port signals, DTR (output like RTS) and DSR (entry like CTS) instead of RTS/CTS, to avoid buffer overflow. In this case, lDTR/DSR can be passed with .T..
Notes

■ The hardware handshake only supports background transmission

(when com_Open() is implemented with the third parameter nBufferOut).

■ This function works for data input as well as output.

■ If you use a hardware handshake, then the RTS signal should no

longer be affected by com_RTS() or com_MCR().

Examples
Turn on the hardware handshake at a port:

com_Open(2, 1000, 1000)          // Open COM2, background send
                                 // buffer
com_Hard(2, .T.)                 // RTS/CTS Hardware handshake
                                 // for port 2
Platforms
Available on MS-DOS
See also

com_Init()Harbour implementation  | 

Initializes the port parameters
Syntax
com_Init(<nComPort>,[<nBaudRate>],[<cParity>],
   [<nDataLength>],[<nStopBits>]) → lInitialized
Arguments
nComPort Designates the port (1 to 4) that is initialized.
nBaudRate Designates the selected baud rate for the port. Settings of 300, 600, 1200, 2400, 4800, 9600 and 19200 baud are possible. The default value is 300 baud.
cParity Designates parity in the following form: (E)ven, (O)dd, (M)ark, (S)pace, or (N)one. The default value is (N)one.
nDataLength Designates the data length; seven or eight bits are possible. The default value is eight bits.
nStopBits Designates the number of stop bits, one or two. The default value is one stop bit.
Returns
If the com port is initialized successfully, the function returns .T..
Description
In order to use the serial port after you open it, four operating parameters must have been passed to this function. These operating parameters are the transmission speed (baud rate), the data length, the parity, and the number of stop bits. Today most bulletin boards use the configuration "300 - 9600 baud, 8N1". This configuration means eight data bits, no parity, and one stop bit. What is important is that all these parameters can be changed while the port is closed. Neither the data buffer or the modem status register (DTR, etc.) are affected.
Notes

■ The port must have been opened previously. It is impossible

to initialize a port prior to opening it.

■ If any or all of the four operating parameters are not

designated, or are designated incorrectly, the standard arguments of 300 baud, no parity, eight data bits, and one stop bit is used.

Examples
■  Open and initialize a port:

   nBuff_size := 4000                     // 4000 character buffer
   lComOk  :=  com_Open(1, nBuff_size)    // Open port

   IF lComOk
         * The port is open, now it is to be initialized with 1200
         * baud, no parity, eight data bits, and one stop bit.

         lInitOk  :=  com_Init(1, 1200, "N", 8, 1)

         IF .NOT. lInitOk
            ? "Port cannot be initialized !"
         ENDIF
   ENDIF

■  You can also omit the last three parameters in the above
   example because they correspond to the default settings:

   lInitOk  :=  com_Init(1, 1200)      // Init. with 1200, N, 8, 1
Platforms
Available on MS-DOS
See also

com_Key()Harbour implementation  | 

Monitors the port using key traps
Syntax
com_Key(<nComPort>,[<nKeyValue1>],[<nKeyValue2>])
   → lActive
Arguments
nComPort Designates the port (1 to 4) where particular activities are monitored.
nKeyValue1 Designates the key code placed in the keyboard buffer in case an interrupt occurs. Values permitted with CA-Clipper's SET KEY TO command are allowed, as a numeric value or a character. If this parameter is not specified, then the port interrupts are not monitored.
nKeyValue2 Designates another key code that is placed in the keyboard buffer when the receiving buffer is 75% or more full. Values permitted with CA-Clipper's SET KEY TO command are allowed, as a numeric value or a character. If this parameter is not specified, the buffer overflow is not monitored.
Returns
com_Key() returns .T. when at least one trap is switched on and returns .F. when all monitoring is switched off.
Description

com_Key() allows you to monitor a port while the program is in a READ. In this way, various events at the port can cause a particular key code, selected by the programmer, to be placed in the keyboard buffer. This happens when:

■ Data arrives at the port.

■ A transmission error or a BREAK is recognized in the LSR.

■ One of the signals in the MSR changes.

■ The receiving buffer becomes 75% or more full.

The MSR and LSR status, the number of errors that have already occurred, and the receipt of individual characters can be monitored through the nKeyValue1 key code. All information is saved in an internal memory area and can be queried from there using the com_Event() function. This procedure is important because the register or the flags that release the interrupt, are automatically reset during read access. Otherwise, the information is lost.

If the nKeyValue2 parameter is specified, then one more procedure can be specified using the SET KEY TO command when the receiving buffer is 75% or more full. If the nKeyValue2 parameter is specified, the nKeyValue1 key code is no longer placed in the keyboard buffer when characters are received. However, you can still monitor the MSR and LSR.

Notes

■ The status of the various interface registers are connected to

the internal memory for as long as the event is "serviced" by a new com_Key() function call. This means that the modifications made during this period cannot be lost.

COM_KEY must be newly activated after every executed trap.

This deletes information concerning the internal environment.

■ When com_Key() places a character into the buffer because the

buffer is close to full, it does so independently of the com_Soft() or com_Hard() functions.

Examples
Chr(227) is placed in the keyboard buffer and calls the COMERRORS
procedure if an error is recognized at port 2 or if the modem status
signal changes.  As soon as the buffer is 75% full or more, Chr(228) is
placed in the keyboard buffer.  When Chr(228) is placed in the keyboard
buffer, the BUFFERFULL procedure is called:

#include ctcom.ch                   // Symbolic constants
                                    // for interface
com_Open(2, 1000)                   // Open COM2
CON_INIT(2, 1200, "N", 8, 1)        // Initialize COM2

SET KEY 227 TO ComErrors
SET KEY 228 TO BufferFull

com_Key(2, 227, 228)                // Monitor COM2

cName  :=  Space(20)                // The port can arrange
PROCEDURE COMMERRORS(A, B, C)

   nMSR_Status  :=  com_Event(2, 2) // Read accumulated
                                    // MSR data

   nLSR_Status  :=  com_Event(2, 2) // Read accumulated
                                    // LSR data
   com_Key(2, 227, 228)             // Reactivate traps, reset
                                    // internal values of COM_EVENT

   IF IsBit(nMSR_Status, MSR_RI)          // Ring bit set?
      ? "Call (ring) acknowledged!"
   ELSE
      IF ISBIR(nLSR_Status, nLSR_Break)   // Break bit set?
         ? "Break acknowledged!"
      ENDIF
   ENDIF
   RETURN
PROCEDURE BUFFERFULL(A, B, C)

   * The input buffer must be read!
   com_Key(2, 227, 228)                 // Traps activated here
   cData  := COM.READ(2)                // Read all data
   SELECT MESSDAT
   REPLACE ComDat WITH cData            // Save data
   SKIP
   SELECT INPUT
   RETURN
Platforms
Available on MS-DOS
See also

com_LSR()Harbour implementation  | 

Reads the Line Status Register (LSR)
Syntax
com_LSR(<nComPort>) → nLSR
Arguments
nComPort Designates the port (1 to 4) that reads the Line Status Register (LSR).
Returns
com_LSR() returns the contents of the Line Status Register.
Description

The Line Status Register makes the following information available:

Table 3-3: LS Register Coding

    Bit     Symb. Const              Definition
     0      LSR_ERROR                Parameter error
     1      LSR_DATA_READY           Data ready
     2      LSR_OVERRUN_ERR          Overflow error
     4      LSR_PARITY_ERR           Parity error
     8      LSR_FRAMING_ERR          Framing error
    16      LSR_BREAK                BREAK recognized
    32      LSR_TRANS_HOLD_EMPTY     Transmission holder register empty
    64      LSR_TRANS_EMPTY          TX shift register empty

Notes

■ The Line Status Register can only be examined using this

function.

■ Some bits in this register are reset by a read.

Examples
nStatus  :=  com_LSR(2)            // Read LSR port 2

IF IsBit(nStatus, 5)               // Set bit 5
   ? "BREAK recognized - Abort!"
ENDIF
Platforms
Available on MS-DOS
See also

com_MCR()Harbour implementation  | 

Reads or sets the Modem Control Register (MCR)
Syntax
com_MCR(<nComPort>,[<nMCR>]) → nMCR
Arguments
nComPort Designates the port (1 to 4) for which the Modem Control Register (MCR) is read or set.
nMCR Designates a specified parameter between 0 and 255. If this parameter is not specified, then MCR is read only.
Returns
com_MCR() returns the contents of the Modem Control Register.
Description

The Modem Control Register can be read only and/or read and set. The second optional parameter determines if a new value is set. The bits have the following meaning:

Table 3-4: MC Register Coding

    Bit     Symb.Const.    Definition
    0       MCR_ERROR      Parameter error
    1       MCR_DTR        Data terminal ready (DTR)
    2       MCR_RTS        Request to send (RTS)
    4       MCR_OUT_1      OUT 1
    8       MCR_OUT_2      OUT 2
    16      MCR_LOOP       LOOP

Notes

■ The OUT1, OUT2, and LOOP control bits can only be changed

using this function. Additional functions are available for DTR and RTS.

Examples
nStatus  :=  com_MCR(1)         // Port 1 MCR is read only

IF NumAnd(nStatus, 3) = 3
   ? "DTR and RTS are active!"
ENDIF
Platforms
Available on MS-DOS
See also

com_MSR()Harbour implementation  | 

Reads the Modem Status Register (MSR)
Syntax
com_MSR(<nComPort>) → nMSR
Arguments
nComPort Designates the port (1 to 4) for which the Modem Status Register is read. COM1(1) to COM4(4) are possible.
Returns
com_MSR() returns a value between 0 and 255 that corresponds to the contents of the MSR.
Description

Not all the values for this status register can be determined from separate functions. For example, if you need Delta status information, you can use this function and test the corresponding bit. The individual bits are defined as follows:

Table 3-5: MC-Register Coding

    Bit     Symb. Const.   Definition
    0       MSR_ERROR      Parameter error
    1       MSR_DELTA_CTS  DELTA ready to send (DCTS)
    2       MSR_DELTA_DSR  DELTA data terminal ready (DDSR)
    4       MSR_TERI       Trailing edge RING (TERI)
    8       MSR_DELTA_DCD  DELTA data carrier detected (DDCD)
    16      MSR_CTS        Clear to send (CTS)
    32      MSR_DSR        Data terminal ready (DSR)
    64      MSR_RI         RING indicator (RI)
    128     MSR_DCD        Data carrier detected (DCD)

Notes

■ The simultaneous testing of multiple bits in the MSR is fairly

simple when using a logical AND operation.

■ All delta bits in this register are reset using a read

procedure.

Examples
nStatus  :=  com_MSR(1)

IF IsBit(nStatus, 5)            // CTS (Bit-5) active?
   . . .
ENDIF
Platforms
Available on MS-DOS
See also

com_Num()Harbour implementation  | 

Gives the number of the highest available serial interface port
Syntax
com_Num() → nMaxCom
Returns
com_Num() returns the number of the highest available serial interface port.
Description

This function returns the number of the serial interface port available. This is not to say that a return value of 3 necessarily means that ports 1 through 3 are available; for example, COM2 could be missing. Whether or not a serial port can actually be used can be tested using the com_Open() or com_Init() functions.

Normally the addresses described in the Introduction to this chapter are scanned for available ports. Scanning can happen over alternate addresses selected through com_SetIO().

Important! Four I/O addresses are assigned to ports COM1 - COM4, internal to the port functions. The com_Num() function goes through these four addresses and tests to see if a port is available there. This can lead to problems if some other hardware is installed in one of the address areas. For example, problems like this have been noted in conjunction with ArcNet network cards, which conflict in the address area with COM4. The critical address areas are listed in the table below.

Table 3-6: I/O Addresses for COM1-COM4

    Port    I/O Addresses
    COM1    03F8h - 03FFh
    COM2    02F8h - 02FFh
    COM3    03E8h - 03EFh
    COM4    02E8h - 02EFh

If any kind of hardware is found within this I/O address area, then the conflicting COM port can be masked. Additionally, using com_SetIO() (nComPort, 0) the accompanying base address within the internal table is deleted. You can only mask the conflicting port when com_Num() has not previously been called in the program. If com_Num() has been called in the program, the interface is marked "in use".

Examples
■  Determine the number of ports at the standard addresses:

   ? com_Num()                 // e.g. 4

■  Determine the number of ports at unusual addresses:

   com_SetIO(3, "110")         // COM3, 110h
   com_SetIO(4, "120")         // COM4, 120h
   ? com_Num()
Platforms
Available on MS-DOS
See also

com_Open()Harbour implementation  | 

Opens the port and initializes the buffer
Syntax
com_Open(<nComPort>,<nBufferIn>,<nBufferOut>,
   [<lTrapMode>]) → lStatus

Tip:  The new optional parameter is an enhancement over previous
versions!
Arguments
nComPort Designates the number of the port (1 to 4).
nBufferIn Designates the size of the receiving buffer up to 64 kByte. The default value is 100 bytes.
nBufferOut Designates the size of the sending buffer for background transmission up to 64 kByte. The default specification is a no send buffer.
lTrapMode Designates when the port triggers an interrupt. When this parameter is .T., the port only triggers an interrupt while receiving data, and not as a result of transmission failure. The default value causes the port to trap all occurrences.
Returns
com_Open() returns .T. when the port has been successfully opened and you can select the buffer.
Description

This function allows you to open a serial interface port from COM1 to COM4. These ports have particular I/O addresses. For example, CA-Clipper Tools uses 3F8H as a base address for COM1. DOS or BIOS routines are not even involved; I/O addresses are not read from the BIOS data area. The default values described in the Introduction to this chapter are applied, or the values are set using com_SetIO(). The availability of a port is tested for these addresses before the port is opened.

Receiving Data A buffer of up to 64 kByte can be reserved for each com port. All arriving characters are saved here, even when the CA-Clipper program is active elsewhere with another process. The number of characters in the buffer can be checked and partially read.

Sending Data You can also reserve a sending buffer. If you reserve a sending buffer, com_Send() controls the interrupt function for data transmission, which means that the interrupt occurs in the background. Several functions are available to control the send buffer.

Interrupts during Transmission Errors If lTrapMode is specified as .T., the UART port only triggers an interrupt when there is data incoming or interrupt driven data being sent. Events connected with the MSR or the LSR are no longer taken into account. This affects the status signal and particularly affects transmission errors.

This capability was added as the result of research that indicated that some adapter ports seemed to trigger interrupts for no reason. These interrupts are caused by "trash" on the lines; as a rule, serial port incoming lines were not terminated (electronically closed). Overflowing interrupts can disturb program execution and lead to significant loss of performance.

Notes

Important! In contrast to other programming languages, like Basic, com_Open() and com_Init() do not affect any control signals. If you want to address a modem at the serial interface through CA-Clipper, you must set the DTR and every other signal using the correct CA-Clipper Tools functions.

■ Buffer size can be between 100 bytes and 64 kByte. Settings

too large or too small are corrected, increased or decreased, accordingly.

■ To ensure compatibility with earlier versions of CA-Clipper

Tools, the nComPort, nBufferIn, and lTrapMode parameters can be used without nBufferOut (see the example).

Examples
■  Open a port with monitoring:

   IF com_Num() > 0
      nBuffSize := 4000                     // 4000 byte buffer

      ComOk  :=  com_Open(1, nBuffSize)     // Open COM1

      IF .NOT. ComOk
         ? "Port cannot be opened  !"
      ENDIF
   ENDIF

■  Open COM3 with the corresponding send and receive buffer:

   ? com_Open(3, 1000, 1000)           // .T. when successful

■  Trigger interrupts for incoming data only, not for
   transmission failure (receiving buffer 1000 characters, normal
   transmission):

   ? com_Open(3, 1000, .T.)            // .T. when successful
Platforms
Available on MS-DOS
See also

com_Read()Harbour implementation  | 

Reads characters from the receiving buffer
Syntax
com_Read(<nComPort>,[<nLength>],[<lNoDelete>])
   → cCharacterstring
Arguments
nComPort Designates the port (1 to 4) that is read.
nLength Designates the number of the characters in the buffer that are read. The default value reads all characters.
lNoDelete Designates whether or not characters are removed from the buffer as they are read. The default setting removes all characters from the buffer as they are read. However, if the parameter is .T., the characters remain in the buffer as long as it is not full.
Returns
The returned string contains the corresponding characters from the receiving buffer.
Description
All characters arriving at the serial port are stored in the appropriate buffer under interrupt control. It is possible to determine the number of characters in the buffer and to read one, several, or all of the characters. If the nLength parameter is not specified, then all the characters in the buffer are read.
Notes

■ Remember that you can receive additional characters between

calling com_Count() and com_Read().

Examples
Wait until at least 10 characters have been received:

DO WHILE com_Count(1) < 10             // Wait until 10
                                       // characters in buffer
   *...
ENDDO

cInput := com_Read(1, 10)              // Read in 10 characters
? cInput                               // Display characters
                                       // that are read
Platforms
Available on MS-DOS
See also

com_Remote()Harbour implementation  | 

Determines the clear character for the receiving buffer
Syntax
com_Remote(<nComPort>,[<nCharacter|cCharacter>])
   → lActive
Arguments
nComPort Designates the port (1 to 4) where an external line termination character is established.
nCharacter|cCharacter Designates a line termination character, which could be a numeric value or a character. When it is not specified, the existing line termination character (if any) is canceled. The default character is the no line termination character.
Returns
com_Remote() returns .F. if the specified port is invalid.
Description

When longer text is sent, the receiver should be able to break off the transmission session or to delete the sending buffer. To do this, a character can be defined as an external line termination character. If this character is received, it deletes the background buffer of the sending station, as if you had called com_SFlush(). The sending CA-Clipper program no longer concerns itself with this session.

com_SMode() can help you determine if the buffer of the remote station has been deleted.

Notes

■ Before a binary file transfer, an existing line termination

character should be canceled because the transmission could be terminated accidentally.

Examples
■  The remote station can terminate using Ctrl-X (Port 2):

   com_Remote(2, 24)
   com_Send(2, cLongText)

   IF IsBit(com_SMode(2), 4)
      ? "Sending buffer is deleted automatically by remote station!"
   ENDIF

■  Eliminate the external line termination character:

   com_Remote(2)
Platforms
Available on MS-DOS
See also

com_Ring()Harbour implementation  | 

Queries the ring line
Syntax
com_Ring(<nComPort>) → lActiveRing
Arguments
nComPort Designates the port (1 to 4) on which the ring line is tested.
Returns
A return of .T. indicates that the ring line is active (MSR bit-7 = 1). A return of .F. indicates that the ring line is inactive (MSR bit-7 = 0).
Description
com_Ring() lets you check the ring line of a port from within a program.
Notes

■ When TERI (Trailing edge ring) is required, use the com_MSR()

function.

Examples
Modems generally show the ring signal of an incoming call.  This does
not mean that a trouble free connection has been established.

DO WHILE .NOT. com_Ring(1)            // Wait for call (RING)
   * ...
ENDDO

?  "Call detected..."
Platforms
Available on MS-DOS
See also

com_RTS()Harbour implementation  | 

Queries or sets the Request To Send (RTS)
Syntax
com_RTS(<nComPort>,[<lNewRTSStatus>]) → lOldRTSStatus
Arguments
nComPort Designates the port (1 to 4) where the RTS signal is queried or changed.
lNewRTSStatus Designates the RTS signal status. When the parameter is .T., the function activates the RTS signal. When the parameter is .F., the function deactivates the RTS signal. If no parameter is specified, CA-Clipper Tools does not affect the current DTR output signal setting.
Returns
The returned status corresponds to the RTS signal status prior to the new setting.
A return of .T. indicates that the RTS signal is active (MCR Bit-2 = 1). A return of .F. indicates that the RTS signal is inactive (MCR Bit-2 = 0).
Description
com_RTS() queries or changes the status of the Request To Send signal (RTS). If lNewRTSStatus is not specified, the RTS status remains unchanged.
Notes

■ The com_Close() function resets (deactivates) the RTS signal.

The com_Open() function does not automatically activate it!

Examples
Set an individually programmable hardware handshake:

com_RTS(2, .T.)      // Request to send a port 2

DO WHILE .NOT. com_CTS(2)
   *...
ENDDO

com_Send(2, "The quick brown fox jumps over the lazy dog")
Platforms
Available on MS-DOS
See also

com_SCount()Harbour implementation  | 

Counts the number of characters in the background sending buffer
Syntax
com_SCount(<nComPort>) → nLength
Arguments
nComPort Designates the port (1 to 4) for which the send buffer length is returned.
Returns
com_SCount() returns the number of characters in the sending buffer of the selected port.
Description
com_SCount() determines the number of characters in one of the four possible sending buffers. This is only possible when the com interface is interrupt controlled, meaning that data is sent in the background.
Notes

■ If you attempt to determine the character count in a port that

is not open, the function returns a value of -1.

Examples
nCharacter := com_SCount(1)            // Number of characters
                                       // in Port 1
Platforms
Available on MS-DOS
See also

com_Send()Harbour implementation  | 

Transmits data directly or in the background
Syntax
com_Send(<nComPort>,<cString>) → nLength

Tip:  An enhancement over previous versions is that there are no new
parameters!
Arguments
nComPort Designates the port (1 to 4) from which transmission occurs.
cString Designates the string that is transmitted by the selected port. If you only need to transmit a single character, then the second parameter can also be numeric and thereby pass the ASCII character code directly.
Returns
When transmission is successful, a 0 is returned. If transmission is not successful, the number of characters that have not been transmitted or could not be placed in the sending buffer is returned.
Description

com_Send() transmits one or more characters from one of four ports. This transmission can be interrupt driven (i.e. occurs in the background). The third parameter of com_Open() determines whether or not the transmission is direct or occurs in the background.

"Normal" Transmission During "normal" transmission, program execution can continue only when all of the characters have been sent to the port. A unique situation presents itself when the hardware handshake is activated. As soon as the receiving station deactivates the CTS signal from the sending station, any transmission is immediately stopped. To prevent the CA-Clipper program from hanging, com_Send() is terminated and a numeric value representing the number of characters not yet sent is returned. com_CTS() can determine if CTS input has been deactivated by the remote station. The software handshake is not supported in this mode!

Background Transmission The background mode supports software and hardware handshakes. The handshake automatically occurs in the background. Several new functions are available to help you maintain control of the transmission buffer in this situation. For example, com_SMode() allows you to determine if the buffer is waiting for an XON character to release the software handshake. Since this kind of wait can prove futile, you can use com_Flush() from within the program to empty the transmission buffer.

Notes

■ The handshake is only supported when the transmission buffer

is sending in the background. Use small packets during direct transmissions, and regularly query com_Soft_R().

■ Software and hardware handshakes are switched on using the

com_Soft() and com_Hard() functions.

Examples
■  This is an example of "normal" transmission at port 1, with no
   transmission buffer open:

   com_Open(1, 1000)                    // Receiving buffer only
   com_Hard(.T.)                        // Hardware handshake
   ACCEPT "Please input name " TO cInput
   nRest := com_Send(1, cInput)         // 1st attempt to transmit

   DO WHILE nRest > 0
      cInput := Right(cInput, nRest)    // Characters not yet sent
      nRest := com_Send(1, cInput)
   ENDDO

■  Here is an example for background or interrupt controlled
   transmission at port 1.  Everything else can proceed through "normal"
   transmission:

   com_Open(1, 1000, 1000)           // 1000 byte transmission buffer
   nRest := com_Send(1, "Attempt")   // Place characters in buffer
Platforms
Available on MS-DOS
See also

com_SetIO()Harbour implementation  | 

Changes the base address for a port
Syntax
com_SetIO(<nComPort>,<nIOPort|cIOPort>) → lChanged
Arguments
nComPort Designates the port (1 to 4) for which a new I/O address is selected.
nIOPort|cIOPort Designates a valid I/O address for the selected port. The parameter can be a decimal or hexadecimal string. For information about the default value, see the Introduction this chapter.
Returns
com_SetIO() returns .T. if the new I/O address is successfully set.
Description
As is the case for other interface card settings, no true standard exists for I/O addresses. This is particularly true for the COM3 and COM4 ports. By using com_SetIO(), CA-Clipper Tools software can be adapted to the I/O addresses of the most eccentric interface card.
Notes

■ The function tests to see if there is a port available at the

selected I/O address. com_SetIO() returns .T. or .F. accordingly.

Examples
■  This is an example of a setting for port 2, with the I/O
   address as a decimal:

   com_SetIO(2, 504)               // Address 1F8h

■  This is an example of a setting for port 4, with the I/O
   address as a hexadecimal:

   com_SetIO(4, "1F8")             // .T.

■  This is an example of an invalid I/O address; the value
   exceeds 1023:

   com_SetIO(4, "10F8")            // .F.
Platforms
Available on MS-DOS
See also

com_SetIRQ()Harbour implementation  | 

Changes the interrupt request for a port
Syntax
com_SetIRQ(<nComPort>,<nIRQ|cIRQ>) → lChanged
Arguments
nComPort Designates the port (1 to 4) where the interrupt request (IRQ) is set.
nIRQ|cIRQ Designates the new IRQ number for the selected port. This parameter can be a decimal or a hexadecimal string and can be from 2 to 15.
Returns
The function returns .T. when the new IRQ has been successfully set.
Description

Unfortunately, there is not a binding standard for serial ports, particularly for COM3 and COM4.

Each interface card uses an interrupt request line to advise the interrupt controller that a character has been received. The controller then passes this information on to the CPU, which calls a service routine through the corresponding interrupt vector. XT systems have eight such interrupt lines available. AT systems have more than 16 available interrupt lines, some of which are usually occupied with other peripherals. The allocation of a new IRQ is no small matter and requires considerable technical expertise. Determining which IRQ is available and is not currently in use can usually be done by studying the configuration of all external devices and the technical documentation that accompanies your computer system. Typically IRQ's 0 and 1 are used for internal purposes (timer), 2 and 9 for network adapters, 5 and 7 for the printer, and 6 and 14 for floppies or hard disks.

Tip: As you will notice from the default setting in the Introduction to this chapter, it is possible for multiple ports to use the same IRQ (interrupt sharing). While CA-Clipper Tools functions do support this process, standard port hardware usually does not. However, special multiple port cards for this purpose are offered by a variety of manufacturers.

Notes

■ Please notice that the base settings that CA-Clipper Tools

uses for COM1 to COM4 are described in the Introduction to this chapter.

com_SetIRQ() does not test to see if a port is actually

serving the selected IRQ.

Examples
■  Set COM3 and COM4 to IRQ 5.  This example requires two calls:

   ? com_SetIRQ(3, 5)            // .T.
   ? com_SetIRQ(4, 5)            // .T.

■  Set port 4 to IRQ 10. IRQ in hex:

   ? com_SetIRQ(4, "A")          // .T.

■  This is an example of an incorrect value for IRQ:

   ? com_SetIRQ(2, 0)            // Timer tick not allowed  .F.
   ? com_SetIRQ(3, "10")         // This would be decimal 16  .F.
Platforms
Available on MS-DOS
See also

com_SFlush()Harbour implementation  | 

Deletes the sending background buffer
Syntax
com_SFlush(<nComPort>) → lDeleted
Arguments
nComPort Designates the port (1 to 4) for which the sending buffer is deleted.
Returns
If the selected sending buffer is successfully deleted, the function returns a .T.
Description
com_SFlush() eliminates all the characters in a sending buffer. This can be useful when the send routine has been futilely waiting for an XON character (bad software handshake).
Notes

■ A com_SFlush() to a closed port does not work.

■ It is not necessary to test for characters in the sending

buffer to carry out a com_SFlush().

Examples
When the sending buffer is waiting for an XON character and the
transmission has been delayed 30 seconds, the sending buffer is deleted:

nStart  := Seconds()                    // When sent

com_Send(2, cSendText)

IF IsBit(com_SMode(2), 2)               // Waiting for XON?
   IF Seconds() - nStart > 30           // 30 second delay ...
      com_SFlush(2)                     // Delete sending buffer
   ENDIF
ENDIF
Platforms
Available on MS-DOS
See also

com_SKey()Harbour implementation  | 

Monitors the port using key traps during background transmission
Syntax
com_SKey([<nComPort>],[<nKeyValue1|cKeyValue1>],
   [<nKeyValue2|cKeyValue2>]) → lActive
Arguments
nComPort Designates the port (1 to 4) that is monitored in the background during transmission.
nKeyValue1|cKeyValue1 Designates the key code placed in the keyboard buffer as soon as the port send buffer has been cleared. Like the values available in CA-Clipper's SET KEY TO command, the key value can be a numeric value or an individual character. When this parameter is not passed, the supervision of buffer overflow can be switched off.
nKeyValue2|cKeyValue2 Designates the key code that the function places in the keyboard buffer at the start of a software or hardware handshake. Like the values in CA-Clipper's SET KEY TO command, the key value can be a numeric value or an individual character. When this parameter is not passed, the supervision of buffer overflow can be switched off.
Returns
com_SKey() returns .T. when the selected character is placed in the keyboard buffer by the corresponding event.
Description

This function allows you to monitor a transmission in the background with regard to the hardware or software handshake and the contents of the buffers. If you have designated nKeyValue1, it is deposited in the keyboard buffer as soon as the sending buffer is empty.

If the software or hardware handshake has been implemented by com_Soft() or com_Hard(), then the COM interface program places nKeyValue2 in the keyboard buffer when an XOFF is encountered or the CTS input is deactivated. If you have passed nKeyValue1, it is deposited in the keyboard buffer as soon as the sending buffer is empty.

Both events can prove very effective when combined with a CA-Clipper key trap. In this way the program does not constantly have to review the status of the sending buffer; it simply "takes note" when something happens. The specific event is then determined with com_SMode() within the called procedure.

Notes
Important! After each execution of a trap, com_SKey() must be reactivated.
Examples
■  Determine if the port 2 buffer is empty:

   com_SKey(2, , 225)            // Place code 225

■  Monitor the software and hardware handshakes for port 2:

SET KEY 225 TO HANDSHAKE
   ? com_SKey(2, , 225)          // OK when returns .T.

   com_Soft(2, .T.)              // Software handshake on
   com_Hard(2, .T.)              // Hardware handshake on

   com_Send(2, LongText)         // Transmit something...

■  It is important that you always send the parameter:

   PROCEDURE HANDSHAKE(A, B, C)

      * Your Program

      com_SKey(2, 225)           // Must be reactivated
      RETURN
Platforms
Available on MS-DOS
See also

com_SMode()Harbour implementation  | 

Determines the current status of a background transmission
Syntax
com_SMode(<nComPort>) → nSendMode
Arguments
nComPort Designates the port (1 to 4) for which the background transmission status is returned.
Returns
com_SMode() returns a number for which the bits represent various meanings shown in the table below.
Description

The ability to transmit in the background demands the ability to control the sending buffer. For example, com_SMode() allows you to check to see if the sending buffer is waiting for an XON character when the software handshake is enabled. The bits in the returned value represent the different modes:

Table 3-7: Coding the Sending Mode

    Bit  Symb. Const.   Definition
    1    SMODE_EMPTY    Sending buffer empty
    2    SMODE_SOFT     Wait for software handshake release(XON)
    4    SMODE_HARD     Wait for hardware handshake release(CTS)
    8    SMODE_RFLUSH   Deleted from remote station

Notes

■ If no sending buffer has been set up for the designated port

using com_Open(), the function returns a value of 0.

Examples
■  Determine whether the port 2 sending buffer is empty:

   IF IsBit(com_SMode(2), 1)
      ? "Port 2 sending buffer empty!"
   ENDIF

■  Wait 20 seconds while the send buffer for port 2 is waiting
   for an XON, then release:

   WaitPeriod(2000)

   DO WHILE IsBit(com_SMode(2), 2) .AND. WaitPeriod()
      *...
   ENDDO

■  Clear the send buffer when XON is not received:

   IF IsBit(com_SMode(2), 2)
      com_SFlush(2)            // Clear send buffer port 2
   ENDIF
Platforms
Available on MS-DOS
See also

com_Soft_R()Harbour implementation  | 

Tests to see if an XOFF character has been received
Syntax
com_Soft_R(<nComPort>,[<lXOFFFlag>]) → lXOFFFlag
Arguments
nComPort Designates the port (1 to 4) for which the XOFF flag is tested.
lXOFFFlag Designates whether the flag is set (.T.) or reset (.F.). The default value (.F.) resets the flag.
Returns
This function returns .T. after the last inquiry or after you open the port when the port has received an XOFF character (Ctrl-S). Subsequently the port does not receive an XON character (Ctrl-Q).
Description
If the software handshake is turned on, the receipt of an XOFF character is noted with an internal flag. This flag can be queried using com_Soft_R(). The receipt of an XON character resets that flag again. Since in some situations an XON character is never transmitted by the remote station, the flag can be reset using the second parameter.
Notes

■ If incoming XOFF characters are monitored, then it is best to

transmit relatively small strings through com_Send(). You can use com_Soft_R() to monitor between incoming XOFF characters.

Examples
■  First open the port:

   com_Open(1, 1000)

■  Transmit until an XOFF character is recognized:

   nPos := 1

   DO WHILE .NOT. com_Soft_R() .AND. nPos <= Len(cString)
      com_Send(1, SubStr(cString, nPos, 1))
      nPos := nPos + 1
   ENDDO
Platforms
Available on MS-DOS
See also

com_Soft_S()Harbour implementation  | 

Tests to see if the buffer has automatically sent an XOFF character
Syntax
com_Soft_S(<nComPort>) → lXOFFFlag
Arguments
nComPort Designates the port (1 to 4) for which the XOFF flag is tested.
Returns
This function returns .T. when the remote station indicates that the buffer is 75% or more full.
Description
If the software handshake has been selected and the buffer is more than 75% full, an XOFF character is automatically transmitted to the remote station. This is noted with an internal flag, which can be queried using com_Soft_S(). When the buffer empties to 50% or less, it generates the transmission of an XON character, and this flag is reset.
Notes

■ When selecting the size of the buffer, decide whether the

remaining 25% will be sufficient at high baud rates.

Examples
Test to see if a 75% full buffer automatically transmits an XOFF
character:

IF = com_Soft_S(1)
   ? "It's time to empty the buffer! "
   ...
ENDIF
Platforms
Available on MS-DOS
See also

com_Soft()Harbour implementation  | 

Queries or sets the software handshake (automatic XON/XOFF)
Syntax
com_Soft(<nComPort>,[<lNewHandshake>],[<cXONchar>],
   [<cXOFFchar>]) → lOldHandshake
Arguments
nComPort Designates the port (1 to 4) for which the software handshake is set.
lNewHandshake Designates whether the handshake is on (.T.) or off (.F.). If this parameter is omitted, the function returns the current setting.
cXONchar Designates any character you choose as an XON character. The default character is ASCII 19 - Ctrl-S.
cXOFFchar Designates any character you choose as an XOFF character. The default value is ASCII 17 - Ctrl-Q.
Returns
The function returns the previously set value.
Description
With modem connections, a hardware handshake is impossible, which is why we are making a software handshake available with this function. When a buffer is 75% full, an XOFF character (Ctrl-Q) is transmitted to the remote station. As soon as the buffer has again been emptied to 50% or less, the XON character (Ctrl-S) is transmitted. You can use characters other than Ctrl-S or Ctrl-Q for individual protocols, which would then be taken into account in the situations described above.
Notes

■ The software handshake only supports background transmission

(when com_Open() has been implemented with the third parameter nBufferOut).

■ When you want to transmit binary data, the software handshake

must always be turned off.

Examples
com_Open(1, 1000, 1000)   // Open port, background transmission
com_Soft(1, .T.)          // Software handshake COM1
Platforms
Available on MS-DOS
See also

Ceiling()Harbour implementation  | 

Rounds up to the next integer
Syntax
Ceiling(<nValue>) → nLargerInteger
Arguments
nValue Designates the number for which the next-largest integer is determined.
Returns
Ceiling() returns the next-largest integer to the one that is passed as a parameter.
Description
Ceiling() returns the next-largest integer to the one passed as a parameter. This applies to positive and negative numbers.
Examples
Show the next-largest integer (including positive and negative numbers):

? Ceiling(1.9)            // Result:   2
? Ceiling(1.1)            // Result:   2
? Ceiling(0.9)            // Result:   1
? Ceiling(-0.1)           // Result:   0
? Ceiling(-0.9)           // Result:   0
? Ceiling(-1.1)           // Result:-1
Platforms
Available on MS-DOS
See also

Celsius()Harbour implementation  | 

Converts a Fahrenheit temperature value into Celsius
Syntax
Celsius(<nFahrenheit>) → nCelsius
Arguments
nFahrenheit Designates a temperature in Fahrenheit.
Returns
Celsius() returns the converted temperature in degrees Celsius.
Description
This function converts Fahrenheit temperature values directly into Celsius values.
Examples
Convert to Celsius:

CODEX = Celsius(33.8)   // Result:  1
Celsius(338.0)          // Result:  170
Celsius(3380.0)         // Result:  1860
Celsius(-33.8)          // Result:  -36.555555...
Platforms
Available on MS-DOS
See also

Center()Harbour implementation  | 

Centers a string using pad characters
Syntax
Center(<cString>,[<nLength>],[<cPadCharacter>],
   [<lMode>]) → cString
Arguments
cString Designates the character string that you choose to center.
nLength Designates the length of the line within which the cString sequence is centered.
cPadCharacter Designates the character with which the cString sequence is centered. The default character is a space.
lMode Designates whether only the beginning, or both sides of cString are padded. The default value (.F.) only fills the beginning.
Returns
The processed string is returned.
Description

The Center() function provides a simple way to center text in any line. Center() is able to pad only on the left or on the left and right using any selected character. Leading and trailing blanks (if any) are replaced with the new character.

When nLength is not specified, Center() assumes the maximum available line width to be MaxCol() + 1, so that the correct output appears in the windows. Additionally, the current cursor position or the column position selected through a SAY command is also noted. So, if there is an output on an 80-column line that begins at column 20, a section of 40 characters from column 20 is used to center the output.

Notes

■ If the sum of the pad characters is odd, then one more

character is inserted at the beginning of the character string.

Examples
■  Center the output with an available line length of 10, and
   insert the leading characters:

   ? Center("xx", 10)                     // "    xx"

■  Fill on the left and on the right:

   ? Center("xx", 10, .T.)                // "    xx    "

■  When characters that match the <cPadCharacter> are present,
   these characters are removed prior to centering:

   ? Center("xx     ", 10, .T.)           // "    xx    "

■  Fill with other characters:

   ? Center("xx", 10, ".")                // "....xx"
   ? Center("xx", 10, ".", .T.)           // "....xx...."
   ? Center("x", 10, ".", .T.)            // ".....x...."

■  In the following example, the "X" is intended to represent a
   40-character wide screen.  The string "CLIPPER" is centered there
   with the "." character, starting at position 10:

   @@ 1, 10 SAY Center("CLIPPER", ".", .T.)

   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
   XXXXXXXXX.......CLIPPER......XXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Platforms
Available on MS-DOS
See also

CGA40()Harbour implementation  | 

Switches to 40-column mode (color or monochrome)
Syntax
CGA40([<lMonochromeMode>]) → lSwitch
Arguments
lMonochromeMode Designates the 40ûcharacter mode. If this parameter is .T., the function switches to the monochrome CGA 40-character mode. If this parameter is.F., the function switches to the 40-character color mode. The default value is .F..
Returns
CGA40() returns .T. if the screen adapter you use permits a switch.
Description
This function can be used with any screen adapter that has CGA emulation capability. You can switch to CGA 40-character mode, color or monochrome. The function IsColor() also returns .T. in the monochrome mode because this option activates a "color summing" of the screen adapter and does not switch to the monochrome mode for a hercules adapter or a monochrome text adapter.
Notes

Important! This function cannot be implemented when windows are open.

■ Modes set through this function can also be combined with

other line counts, i.e. EGA43().

■ A call with .T. corresponds to BIOS mode 0. A call with .F.

corresponds to BIOS mode 1.

Examples
■  Switch to 40-character mode (color):

   ?  CGA40()         //  .T., if successful

■  Switch to 40-character mode (monochrome):

   ?  CGA40(.T.)      //  .T., if successful
Platforms
Available on MS-DOS
See also

CGA80()Harbour implementation  | 

Switches to 80-column mode (color or monochrome)
Syntax
CGA80([<lMonochromeMode>]) → lSwitch
Arguments
lMonochromeMode Designates the 40ûcharacter mode. If this parameter is .T., the function switches to the monochrome CGA 80-character mode. If this parameter is .F., the function switches to the 80-character color mode. The default value is .F..
Returns
CGA80() returns .T. when the screen adapter you use permits a switch.
Description
This function can be used with any screen adapter that has CGA emulation capability. You can switch to CGA 80-character mode, color or monochrome. The function IsColor() also returns .T. in the monochrome mode because this option activates a "color summing" of the screen adapter and does not switch to the monochrome mode for a hercules adapter or a monochrome text adapter.
Notes

Important! This function cannot be implemented when windows are open.

■ A call with .T. corresponds to BIOS mode 2. A call with .F.

corresponds to BIOS mode 3.

Examples
■  Switch to 80-character mode (color):

   ?  CGA80()         //  .T., if successful

■  Switch to 80-character mode (monochrome):

   ?  CGA80(.T.)      //  .T., if successful
Platforms
Available on MS-DOS
See also

CharAdd()Harbour implementation  | 

Adds the corresponding ASCII codes of two strings
Syntax
CharAdd(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the character string to which values from a second character string cString2 are added.
cString2 Designates the character string that is added, character for character, to cString1.
Returns
The processed character string is returned.
Description
You can use CharAdd() to produce simple character string coding. The function can prove very useful when processes are coded by individual characters in a string.
Notes

■ When both character strings are the same length, then the

first byte of cString1 can be linked with the first byte of cString2, and the second byte of cString1 can be linked with the second byte of cString2, and so on. If cString2 is shorter than cString1, then as soon as the last byte of cString2 is reached, the process continues and starts again with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates with the end of cString1.

■ Values greater than 256 can result when adding values. The

new value is then formed based on the following formula:

(Asc(Character1) + Asc(Character2))% 256.

■ Implementing CSetRef() can suppress the return value for this

function to save room in working memory.

Examples
■  Add a value of 1 to each character:

   ? CharAdd("01234", Chr(1))        // "12345"

■  Adding a value of 255 to each character corresponds to
   subtracting 1:

   ? CharAdd("12345", Chr(255))      // "01234"
Platforms
Available on MS-DOS
See also

CharAnd()Harbour implementation  | 

Links corresponding ASCII codes of paired strings with an AND operation
Syntax
CharAnd(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the character string to which characters are added.
cString2 Designates the character string that contains the characters that are added to the characters in cString1.
Returns
The processed string is returned.
Description
CharAnd() can be used as a simple way to reset the high bit for all the characters in a string. The function joins (links bit by bit using an AND operation) each character in cString1 with the corresponding character in cString2.
Notes

■ When both character strings are the same length, then the

first byte of cString1 can be linked with the first byte of cString2, and the second byte of cString1 can be linked with the second byte of cString2, and so on. If cString2 is shorter than cString1, then as soon as the last byte of cString2 is reached, the process continues and starts again with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates with the end of cString1.

■ Implementing CSetRef() can suppress the return value for this

function to save room in working memory.

Examples
The second parameter is shorter than the first parameter in this
example.  As a result, the "1", the "a", and the first blank are joined
with AND to the "1" in "123"; the "2", the "b", and the second blank are
joined with AND to the "2" in "123"; and the "3", the "c", and the third
blank are joined with AND to the "3" in "123":

? CharAnd("123abc   ", "123")      // "123!"#   "
Platforms
Available on MS-DOS
See also

CharEven()Harbour implementation  | 

Returns characters in the even positions of a string
Syntax
CharEven(<cString>) → cString
Arguments
cString Designates the character string from which all even characters are returned.
Returns
CharEven() returns a string containing all the even characters of cString.
Description
CharEven() assembles all even characters within a string into a new character string. This allows you to process variables consisting of the characters and attributes of a video screen's contents very simply. This function can be implemented in conjunction with functions from the video section. You can return the attributes from a screen string, with all the characters removed.
Notes

■ The first position in a string is 1, and therefore is not

even.

Examples
■  Assemble all even characters:

   ? CharEven("1234a")              // "24"

■  Return the expanded text to "normal":

   ? CharEven(" H e l l o")         // "Hello"
Platforms
Available on MS-DOS
See also

CharList()Harbour implementation  | 

Lists each character in a string
Syntax
CharList(<cString>) → cString
Arguments
cString Designates the string that is processed.
Returns
CharList() returns a list in which each character in cString appears only once.
Description
CharList() determines the list of characters that appear in the cString. Each character only appears in the list once.
Notes

■ The CharList() function's return value is never longer than

256 characters.

■ If you sort this result with CharSort(), you have an ascending

list of characters.

Examples
■  What letters are contained in the text?

   ? CharList("Hello goodbye")                // "Helo gdby"

■  Show a sorted list of all letters in a text:

   ? CharSort(CharList("Hello goodbye"))      // "Hbdegloy"
Platforms
Available on MS-DOS
See also

CharMirr()Harbour implementation  | 

Mirrors characters within a string
Syntax
CharMirr(<cString>,[<lBlank>]) → cString
Arguments
cString [@] Designates the character string that is mirrored.
lBlank Designates whether the function mirrors everything (.F.) or does not mirror the blanks at the end of a character string (.T.). The default value is .F..
Returns
CharMirr() returns the processed cString.
Description

CharMirr() reverses a string. The function returns a palindrome of cString.

The optional logical parameter allows you to mirror a string and ignore the blanks. This permits you to build index entries that end with a particular sequence.

Notes

■ The returned value of this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
■  This example shows a simple exchange:

   ? CharMirr("abc321")         // Result: "123cba"

■  This example shows one of the best known palindromes:

   ? CharMirr("ABLE WAS I ERE I SAW ELBA")

■  When you index, you must do it without spaces because this is
   the only way a reverse string can be searched for:

   INDEX ON CharMirr(Field, .T.) TO Index

■  Search for all expressions in the mirrored index, ending in
   "per":

   SEEK "rep"
Platforms
Available on MS-DOS
See also

CharMix()Harbour implementation  | 

Mixes two strings together
Syntax
CharMix(<cString1>,<cString2>) → cString
Arguments
cString1 Designates a string that is mixed with cString2.
cString2 Designates a string that is mixed with cString1.
Returns
CharMix() returns a string that is double the length of cString1, assuming that cString2 contains at least one character.
Description
This function allows you to mix the characters from two character strings together. The characters from cString1 and cString2 appear alternately in the result string. The length of cString1 forms the basis for the maximum count of the resulting mix. A longer cString2 string is cut down to the length of cString1. A shorter cString2 is processed from beginning to end, wrapping to the beginning again until there are no more characters in cString1.
Notes

■ This function can be used to recombine strings extracted by

CharEven() or CharOdd().

Examples
■  This is an example of a simple mix:

   ? CharMix("ABC", "123")       // "A1B2C3"

■  This is a mix where the second string is shorter:

   ? CharMix("ABCDE", "12")      // "A1B2C1D2E1"

■  This is a mix where the second string is longer:

   ? CharMix("AB", "12345")      // "A1B2"

■  What you can do with this?

   ? CharMix("HELLO". " ")       // "H E L L O"

■  If the second parameter is null, then the first parameter is
   returned unchanged:

   ? CharMix("HELLO", "")        // "HELLO"
Platforms
Available on MS-DOS
See also

CharNoList()Harbour implementation  | 

Lists the characters that do not appear in a string
Syntax
CharNoList([<cString>]) → cNotContained
Arguments
cString Designates the string that is processed. The default value is for an empty string.
Returns
CharNoList() returns a character string that contains all characters not found in cString.
Description
This function determines all characters that are not contained in cString. The resulting characters might be used as replacement characters or for complex deletion procedures.
Examples
■  Delete all characters except "XYZ":

   String := "ABXCDYEF"
   ? CharRem(CharNoList("XYZ"), String)               // "XY"

■  Generate a list of all 256 ASCII characters:

   ? CharNoList()

■  To save text to a memo field, all null characters (Chr(0))
   must be exchanged for a character that is not being used:

   cNoList   := CharNoList(cMemoText)
   cNoChar   := SubStr(cNoList, 1, 1)
   CharRepl(Chr(0), @cMemoText, cNoChar)
Platforms
Available on MS-DOS
See also

CharNot()Harbour implementation  | 

Complements each character in a string
Syntax
CharNot(<cString>) → cString
Arguments
cString [@] Designates the string that is negated.
Returns
The processed cString is returned.
Description
This function negates each bit in cString. This makes it possible to get a decreasing index sequence.
Notes

■ The returned value of this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
When a character string that has already been negated is negated again,
the result is identical to the original:

CharNot("123ABCabc")     // "     ¥£ "
CharNot("      ¥£")      // "123ABCabc"
Platforms
Available on MS-DOS
See also

CharOdd()Harbour implementation  | 

Returns characters in the odd positions of a string
Syntax
CharOdd(<cString>) → cString
Arguments
cString Designates the character string from which all the odd characters are returned.
Returns
CharOdd() returns a character string that contains all the odd characters from cString.
Description
CharOdd() assembles all odd characters within a string into a new character string. This allows you to process variables where screen content, consisting of characters and attributes, is saved. This function can then be used in conjunction with functions from the video section.
Notes
■ The first position in a string is 1, and therefore is odd.
Examples
■  Assemble all odd characters:

   ? CharOdd("1234a")            // "13a"

■  Return the expanded text to "normal":

   ? CharOdd("H e l l o ")       // "Hello"
Platforms
Available on MS-DOS
See also

CharOne()Harbour implementation  | 

Reduces adjoining duplicate characters in a string to one character
Syntax
CharOne([<cDeleteCharacters>],<cString>) → cString
Arguments
cDeleteCharacter Designates the characters that have their adjoining duplicates removed from cString. The default value removes all adjoining duplicate characters.
cString Designates the character string that is processed.
Returns
The processed cString is returned.
Description
CharOne() searches within the cString for repetitions of adjoining characters. When a character is removed, all of the characters but the first are deleted. This differs significantly from the CharList() function, where multiple occurrences of characters within the context of the string are removed.
Notes

■ Without the cDeleteCharacter parameter, all the repeating

characters are removed. If the parameter is specified, only those characters in cDeleteCharacter are removed.

Examples
■  Check for double occurrences of each character in the
   character string:

   ? CharOne("122333a123")             // "123a123"
   ? CharOne("A  B  CCCD")             // "A B CD"

■  Delete multiple side-by-side blanks:

   ? CharOne(" ", "A  B  A  B")        // "A B A B"

■  Make the letter "o" only appear once in the character string:

   ? CharOne("o", "122oooB12o")        // "122oB12"
Platforms
Available on MS-DOS
See also

CharOnly()Harbour implementation  | 

Determines the common denominator between two strings on the basis of individual characters
Syntax
CharOnly(<cString1>,<cString2>) → cString
Arguments
cString1 Designates a sequence of characters that are not removed from cString2.
cString2 Designates the string that is processed.
Returns
CharOnly() returns the processed string cString2.
Description
CharOnly() removes all characters from cString2 that are not in cString1. The function is particularly useful when comparing data that should have a standard format but has been input by different people. This category can consist of things like telephone numbers, part numbers, customer numbers, etc. (see example).
Examples
Since numbers are the only characters that are relevant in a telephone
number, any characters that are not numbers are removed.  The result in
each case is "2133907923":

? CharOnly("0123456789", "213 - 39 07 923")
? CharOnly("0123456789", "213 / 390 7923")
Platforms
Available on MS-DOS
See also

CharOr()Harbour implementation  | 

Joins the corresponding ASCII code of paired strings with an OR operation
Syntax
CharOr(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the string upon which the OR operation is performed.
cString2 Designates the characters that are used when performing the OR operation on cString1.
Returns
CharOr() returns the processed cString1.
Description
The function joins (links bit by bit using an OR operation) each character in cString1 with the corresponding characters in cString2. CharOr() can therefore place particular bits within the characters.
Notes

■ If both character strings are the same length, then the first

byte of cString1 is linked with the first byte of cString2, and the second byte of cString1 is linked with the second byte of cString2, etc.. If cString2 is shorter than cString1, then when the last byte of cString2 is reached, it continues with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates at the end of cString1.

■ The return value of this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
■  Both bytes in the first parameters are joined with OR using
   the "0" character.  This means that Chr(1) is converted into the
   ASCII character æ1", Chr(2) into the ASCII character "2", etc.:

   ? CharOr(Chr(1) + Chr(2), "0")            // "12"

■  All bytes in the first parameters are joined (OR) with Chr(32)
   (set bit 5 only):

   ? CharOr("123ABCC[\]abc", CHR (32))       // "123abc(|)abc"
Platforms
Available on MS-DOS
See also

CharPack()Harbour implementation  | 

Compresses (packs) a string
Syntax
CharPack(<cString>,[<nMethod>]) → cPackString
Arguments
cString Designates the character string that is packed.
nMethod Designates which pack algorithm is used on the designated character string. The default value is method 0.
Returns
CharPack() returns the compressed string.
Description

This function allows you to compress (pack) the contents of strings. The function supports two different pack methods:

Table 4-2: Pack Methods Supported

    <nMethod>    Pack Algorithm
    0            Modified run length encoding
    1            Bit oriented algorithm

Notes
Important! A packed string can contain Chr(0) or other control characters.
Examples
Using the bit pack method, compress a text from a DOS file:

Var := CharPack(FileStr("C:\TEXT\TEST.TXT"), 1)
StrFile(Var, "C:\TEXT\TEST.PAK")      // New save
Platforms
Available on MS-DOS
See also

CharPix()Harbour implementation  | 

Returns the number of pixel lines per character
Syntax
CharPix() → nPixelline
Returns
CharPix() returns a value that corresponds to the number of pixel lines per character.
Description

Different screen adapters build characters from a different numbers of pixel lines. Based on the installed mode, the number of pixel lines for a particular type of screen adapter may also vary.

Use CharPix() to determine the number of pixel lines available in the currently installed mode. This information is useful when used in conjunction with SetCursor().

Examples
Display the number of pixel lines:

? CharPix()         // VGA, no mode change - 16
Platforms
Available on MS-DOS
See also

CharRelA()Harbour implementation  | 

Correlates the character positions in paired strings
Syntax
CharRelA(<cSearchFor1>,<cString1>,<cSearchFor2>,
   <cString2>) → nPosition
Arguments
cSearchFor1 Designates the character that is searched for in cString1.
cString1 Designates the character string to search with cSearchFor1.
cSearchFor2 Designates the character that is searched for in cString2.
cString2 Designates the character string to search with cSearchFor2.
Returns
CharRelA() returns the positions where cSearchFor1 and cSearchFor2 occur in the corresponding character strings.
Description
This function builds a relationship (CHAR RELAtion) between two character strings. It determines the positions where the characters in cSearchFor1 appear in cString1 and where the characters in cSearchFor2 appear in cString2.
Notes
■ The function returns a value of 0 if no relationship is found.
Examples
Search for the first position in which a "b" appears in the first string
and a "1" appears in the second:

? CharRelA("b", "b b b b", "1", "bbb11111")      // 5
Platforms
Available on MS-DOS
See also

CharRelRep()Harbour implementation  | 

Replaces characters in a string depending on their correlation
Syntax
CharRelRep(<cSearchFor1>,<cString1>,<cSearchFor2>,
   <cString2>,<cReplaceExpression>) → cString
Arguments
cSearchFor1 Designates one or more characters within cString1 for which to search.
cString1 Designates the character string where cSearchFor1 is found.
cSearchFor2 Designates one or more characters within cString2 for which to search.
cString2 [@] Designates the character string where cSearchFor2 is found.
cReplaceExpression Designates one or more characters to replace those at the established corresponding position within cString2.
Returns
The processed cString2 is returned.
Description

This function is easier to use than it seems. If we proceed on the assumption that both search expressions and the replacement expression are only one character long, then the following steps occur:

■ All positions are determined where cSearchFor1 is found

within cString1.

■ All positions are found where cSearchFor2 is found within

cString2.

■ The character in the cString2 string is replaced by the

character in the cReplaceExpression.

This function can be used to simplify work with variables that contain screen memory. If cPict1 contains the character "|"at position 34 and cPict2 contains the character "-" at the same position, then this position within cPict2 can be replaced with a new character, "+"', which represents the combination of the two.

Multiple Exchanges Both search expressions and the replacement expression can be longer than one character. The previously described exchange procedure occurs repeatedly — initially with the first character in the three character strings, then with the second, and so on. The number of iterations is regulated by the length of cSearchFor1. If cSearchFor2 or the cReplaceExpression are shorter, then the last byte is used again.

Notes

■ The length of cString2 determines the number of search

procedures at any one time. The length of cSearchFor1 determines the number of possible exchanges.

■ The return value of this function can be suppressed by

implementing CSetRef() to save space in working memory.

■ A use for multiple replacement using CharRelRep() can be found

in the accompanying sample programs.

Examples
Determine every position where a "b" occurs in the first string and a
"1" occurs in the second string.  The respective character is then
exchanged for the one designated as the fifth parameter.

? CharRelRep("b", "b b b b", "1", "bbb11111", "x")
                                                   //"bbb1x1x1"
Platforms
Available on MS-DOS
See also

CharRem()Harbour implementation  | 

Removes particular characters from a string
Syntax
CharRem(<cDelCharacterstring>,<cString>) → cString
Arguments
cDelCharacterstring Designates the characters that are removed from cString.
cString Designates the string that is processed.
Returns
The processed cString is returned.
Description
With this function you can remove particular characters from any position in cString. It is possible to ensure that the character string does not contain these characters later.
Notes
■ No changes occur if you pass invalid or incorrect parameters.
Examples
■  Remove the blanks from a string:

   ? CharRem(" ", " 1  2   ")     // "12"

■  Remove the number "3" and the letter "y":

   ? CharRem("3y", "xyz123")      // "xz12"
Platforms
Available on MS-DOS
See also

CharRepl()Harbour implementation  | 

Replaces certain characters with others
Syntax
CharRepl(<cSearchFor>,<cString>,   <cReplaceExpression>,
   [<lMode>]) → cString
Arguments
cSearchFor Designates a list of characters to search for in cString.
cString [@] Designates the character string within which to search for and replace the characters in cSearchFor.
cReplaceExpression Designates the character list that replaces characters in cString.
lMode Designates whether multiple replacements are made.
lMode Designates one pass of the cString (.T.) or multiple replacements (.F.). The default value is for .F..
Returns
The processed cString is returned.
Description

This function allows you to carry out very complex replacement procedures. Every character in the cSearchFor is searched for within the cString. If found, the character is replaced by the corresponding character in the cReplaceExpression.

If lMode is not passed, characters are exchanged repeatedly as required. This means that the function goes through each individual character in the found characters in sequence, and then searches the entire cString, exchanging cSearchFor for corresponding characters in cReplaceExpression. When you use this technique, characters that have already been replaced are exchanged again if the replacement character also appears in the search list.

However, if the optional lMode parameter is specified, the function proceeds differently. It goes through each character in cString in sequence, determining whether or not it should be replaced. Characters that have been replaced are not replaced again.

As a rule, if the same characters appear within cReplaceExpression and cSearchFor, you must check very closely to determine which lMode parameter should be used (see example).

Notes

■ If the cReplaceExpression sequence is shorter than

cSearchFor, the characters that do not have a corresponding replacement in cReplaceExpression are replaced with the last character of cReplaceExpression (see example).

■ The return value of this function can be suppressed by

implementing CSetRef() to save space in working memory.

Examples
■  The number "1" is replaced with the letter "a", the number "2"
   with the letter "b", etc..  If the number "4" appeared in the
   character string, it would be replaced with a "d":

   ? CharRepl("1234", "1x2y3z", "abcd")              // "axbycz"

■  The letters a-j are replaced with the numbers 0-9; for
   example, an "f" is replaced with a "6":

   ? CharRepl("abcdefghij", "jhfdb", "1234567890")   // "08642"

■  The third parameter makes fewer characters available for the
   exchange.  Therefore the letters f-j are replaced with the last
   characters from "12345":

   ? CharRepl("abcdefghij", "jhfdb", "12345")        // "55542"

■  Here is an example of the difference between a specified
   <lMode> parameter (.T.) and the default parameter (.F.):

   ? CharRepl("1234", "1234", "234A")                // "AAAA"
   ? CharRepl("1234", "1234", "234A", .T.)           // "234A"
Platforms
Available on MS-DOS
See also

CharSort()Harbour implementation  | 

Sorts sequences within a string
Syntax
CharSort(<cString>,[<nElementlength>],
   [<nComparisonlength>],[<nIgnore>],
   [<nElementPosition>],[<nSortlength>],
   [<lDescending>]) → cString


Note:  This version of CA-Clipper Tools contains an optional
parameter that previous versions did not include.
Arguments
cString [@] Designates the character string that is sorted.
nElementlength Designates the length of the sorting element. The default value is for 1 character.
nComparisonlength Designates the number of characters that a sorting element takes into account in a comparison. The default value is nElementlength characters.
nIgnore Designates the number of characters at the beginning of the cString that should not be taken into account in the sorting.
nElementPosition Designates an offset. This parameter designates from what position within the sorting element the comparison is made. The default value is the first character (0).
nSortlength Designates the length of the sort area relative to the nIgnore offset.
lDescending Designates whether the function sorts in ascending or descending order. If this parameter is not specified, or is specified as .F., then the function sorts in ascending order. When specified as .T., the function sorts in descending order. The default value is .F..
Returns
The sorted cString is returned.
Description
CharSort() allows you to sort the characters in a string in many different ways. Everything from the length of the sorting elements to the sort sequences is taken into account.
Notes

■ Invalid parameters return a null string.

■ The function uses a fast sort algorithm.

■ The return value of this function can be suppressed by

implementing CSetRef() to save space in working memory.

Examples
■  Sort characters in a string according to their ASCII code:

   ? CharSort("qwert")                           // "eqrtw"

■  Sort 2-byte length elements:

   ? CharSort("qwert", 2)                        // "erqwt"

■  Sort 2-byte length elements, but only use the first character
   for the comparison:

   ? CharSort("bla4a3a2a1", 2, 1)                // "a2a1a3a4b1"

■  Sort individual characters, excluding the first three:

   ? CharSort("XXXqwert", 1, 1, 3)               // "XXXeqrtw"

■  Sort paired sequences for the entire string, where only the
   second character within each sequence is used:

   ? CharSort("bla4a3a2a1", 2, 1, 0, 1)          // "a1b1a2a3a4"

■  Sort only the first four characters within a string:

   ? CharSort("384172852", 1, 1, 0, 0, 4)        // "134872852"

■  Sort in descending order:

   ? CharSort("qwert", .T.)                      // "wtrqe"
Platforms
Available on MS-DOS
See also

CharSpread()Harbour implementation  | 

Expands a string at the tokens
Syntax
CharSpread(<cString>,<nLength>,
   [<cCharacter|nCharacter>]) → cString
Arguments
cString Designates a character string that is expanded with spaces or cCharacter|nCharacter characters to nLength length.
nLength Designates the length of the return string.
cCharacter|nCharacter Designates the fill character and token delimiter. It can be a numeric value or a character. If it is a numeric value, it must be between 0 and 255. The default value is a space Chr(32).
Returns
CharSpread() returns the expanded string.
Description

CharSpread() expands a string to a preset length. However, it behaves differently than the Expand() function.

CharSpread() uses cCharacter|nCharacter as the character to insert during the expansion. The string is expanded between tokens delimited by this character up to the length specified by nLength. This is similar to full justification in a text editor.

Notes

■ Previously existing fill characters cCharacter|nCharacter

are not taken into account in the redistribution (see examples). If this procedure is not satisfactory to you, then you can call the CharOne() for the string before you call CharSpread().

Examples
For clarity, these examples do not contain blanks.

■  When the delimiter does not appear in the string, no expansion
   takes place:

   ? CharSpread("123456", 20, ".")          // "123456"

■  This example shows a numeric code for the (".") character:

   ? CharSpread("1.2.3.4.5.6", 20, 46)      // "1...2...3..4...5...6"

■  In this example, the fill character is already there:

   ? CharSpread("11..22..33", ".")          // "11.......22.......33"
   ? CharSpread("11.22........33", 20, ".")
                                            // "11....22..........33"
Platforms
Available on MS-DOS
See also

CharSwap()Harbour implementation  | 

Exchanges all adjoining characters in a string
Syntax
CharSwap(<cString>) → cString
Arguments
cString [@] Designates the character string that is processed.
Returns
The processed character string is returned.
Description

CharSwap() takes all neighboring characters in cString and exchanges them. As a result, bytes in even positions are exchanged for those in odd positions.

CharSwap() is very important when you use string integers generated by the CA-Clipper I2Bin() function that must be saved or sorted. The CharSwap() exchange must be carried out prior to calling CharSort() (low/high ordering of 16-bit integers) to achieve an accurate result.

Notes

■ Since the length of the character string is not changed, a

call by reference is recommended. This increases the speed of the function.

■ The value this function returns can be suppressed by setting

CSetRef() to save working memory space.

Examples
■  Exchange characters that can be displayed:

   ? CharSwap("0123456789")               // "1032547698"

■  Work with I2BIN:

   ? I2BN(256)                            // 00000000 00000001
   ? I2Bin(1)                             // 00000001 00000000
   ? I2Bin(256) > I2Bin(1)                          // .F.
   ? CharSwap(I2Bin(256)) > CharSwap(I2Bin(1))      // .T.
Platforms
Available on MS-DOS
See also

CharUnpack()Harbour implementation  | 

Decompresses (unpacks) a string
Syntax
CharUnpack(<idPackCharacterstring>) → cString
Arguments
idPackCharacterstring Designates a string that was previously compressed with the CharPack() function.
Returns
CharUnpack() returns an uncompressed string.
Description
This function unpacks strings compressed by the CharPack() function. Notice that the related pack method is automatically recognized. Since we presuppose that the CharUnpack() string parameter was compressed previously with CharPack(), it is assured that the returned string is not longer than the maximum permitted under CA-Clipper.
Examples
The CharUnpack() function recreates a string:

? CharUnpack(CharPack("AAAAAAAAAAAA"))   // "AAAAAAAAAAAA"
Platforms
Available on MS-DOS
See also

CharWin()Harbour implementation  | 

Exchanges particular characters in a screen area.
Syntax
CharWin([<nTopline>,<nLeftcolumn>,<nBottomline>,
   <nRightcolumn>, [<cNewcharacter|nNewcharacter>],
   [<cOldcharacter|nOldcharacter>]]) → cNull
Arguments
nTopline Designates the line for the top-left corner of the area.
nLeftcolumn Designates the column for the top-left corner the area.
nBottomline Designates the line for the bottom-right corner of the area.
nRightcolumn Designates the column for the bottom-right corner of the area.
cNewcharacter|nNewcharacter Designates the new character for the screen area. Specify the parameter as a numeric in the range of 0 to 255 or as a character string. The default value is the CLEARB.
cOldcharacter|nOldcharacter Designates which character to exchange. Specify the parameter as a numeric in the range of 0 to 255 or as a character string. The default is to exchange all characters.
() When no parameter is designated, the function replaces all characters in the screen area with CLEARB.
Returns
The function always returns a null string.
Description
Within a screen area, CharWin() replaces all characters or just a particular character with a new one. If cNewcharacter|nNewcharacter is not designated, the function uses the character set with SetClearB(), where the preset value is Chr(255). The upper-left and lower-right corner rows and columns are given for the borders of the area. If these arguments are missing, then the entire screen area is exchanged.
Examples
■  Exchange all characters for CLEARB:

   SetClearB("X")       // Exchanges within CharWin() entire screen

■  Exchange all "A" for "B":

   CharWin(10, 10, 20, 70, "B", "A")    // Always returns a ("") null
                                        // string

■  Numeric characters can also be designated:

   CharWin(10, 10, 20, 70, 66, 65)      // A = 65, B = 66
Platforms
Available on MS-DOS
See also

CharXor()Harbour implementation  | 

Joins corresponding ASCII codes of paired strings using an exclusive OR operation
Syntax
CharXor(<cString1>,<cString2>) → cString
Arguments
cString1 [@] Designates the character string on which the exclusive OR (XOR) operation is performed.
cString2 Designates the characters that are joined using XOR with cString1.
Returns
The processed cString1 is returned.
Description

The function performs an exclusive OR operation on each character in cString1 with the corresponding characters in cString2.

You can use CharXor() to code passwords and text. The advantage of this function is that it can be used for both encryption and decryption.

Notes

■ If both character strings are the same length, then the first

byte of cString1 is linked with the first byte of cString2, and the second byte of cString1 is linked with the second byte of cString2, etc.. If cString2 is shorter than cString1, then when the last byte of cString2 is reached, it continues with the first byte of cString2. However, if cString1 is shorter than cString2, the process terminates at the end of cString1.

■ The return value of this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
■  CharXor() returns the coded value once.  The password should
   be as long as possible:

   ? CharXor("Secret", "Password")

■  Call CharXor() twice to return the initial value:

   ? CharXor(CharXor("Secret", "Password"), "Password")

■  A double encryption is also possible:

   ? CharXor(CharXor("Secret", "Password"), "A12B44")
Platforms
Available on MS-DOS
See also

Checksum()Harbour implementation  | 

Calculates the checksum for a character string (algorithm)
Syntax
Checksum(<cString>) → nCheckSum
Arguments
cString Designates the character string for which the checksum is computed.
Returns
The number returned is the checksum for the cString.
Description
Checksum() calculates the checksum for a character string. This checksum can determine if a character string has been changed, or transmitted or typed incorrectly. Checksum() is position dependent, so the likelihood of error recognition is greater than with AsciiSum().
Notes

■ The return value is a 32-bit whole number.

■ The checksum cannot be used for definitive coding of data

because the calculated sum for two different character strings could be the same. For example, the checksum for "PASTETEN" and "PERSONAL" are identical.

■ If character strings have different lengths, the strings

cannot have identical values.

Examples
■  In this example, AsciiSum() would have returned identical
   results:

   ? Checksum("abc")               // Result: 247334
   ? Checksum("cba")               // Result: 246822

■  Different character strings of identical length can produce
   identical results:

   ? Checksum("PASTETEN")          // Result: 530020
   ? Checksum("PERSONAL")          // Result: 530020

■  A null string returns a result of 0:

   ? Checksum("")                  // Result: 0
Platforms
Available on MS-DOS
See also

ClearBit()Harbour implementation  | 

Clears one or more bits within a number to zero
Syntax
ClearBit(<nLONG|cHexLONG>,<nBitPos1>,
   [...<nBitPos32>]) →  nNewValue
Arguments
nLONG|cHexLONG Designates either a decimal number or hexadecimal character string.
nBitPos32 Designates the bit numbers to delete.
Returns
ClearBit() returns a value in which the designated bits are cleared.
Description
ClearBit() resets particular bits within a field to change something like a serial port register. In contrast to NumAnd(), the bit numbers are given and do not need to be converted beforehand. The value 1 represents the bit with the lowest value, and the value 32, the bit with the highest value.
Notes
■ An invalid parameter returns a result of -1.
Examples
Bits 3, 4, and 6 are cleared in a bit pattern:

nBitPattern  := 255
nBitPattern  := ClearBit(nBitPattern, 3, 4, 6)   // Result:  211
Platforms
Available on MS-DOS
See also

ClearEol()Harbour implementation  | 

Clears from the cursor position to the end of line
Syntax
ClearEol([<nRow>], [<nColumn>], [<cAttr|nAttr>],
   [<cCharacter|nCharacter>]) → cNull
Arguments
nRow Designates the line to be erased. The default is the cursor line.
nColumn Designates the column where the erasure is to begin. The default is the cursor column.
cAttrn|nAttr Designates the attribute used to clear. The default is CLEARA.
cCharacter|nCharacter Designates the character used to clear. The default is CLEARB.
Returns
ClearEol() always returns a null string.
Description

Use ClearEol() to clear a specific line from a given position to the end of that line. If arguments are not specified, then the current nRow cursor line and nColumn cursor column are used as the starting location. The clear always goes to the end of the line specified with the CLEARA attribute and CLEARB character, or with the Attr|nAttr attribute and cCharacter|nCharacter character.

ClearEol() has some advantages over the CA-Clipper @ Row, Column commands:

1. It lets you take the returned value of the character string type and

combine it with string outputs (e.g., LIST...ClearEol()).

2. The cursor position is not affected.

3. The arguments are optional. If they are not specified, the function

clears from the current cursor position with the CLEARA attribute and CLEARB character.

Notes

■ You can specify the cAttr|nAttr attribute and the

cCharacter|nCharacter character in a number of ways. Please refer to the chapter introduction.

■ Default attribute and character can be set with SetClearA()

and SetClearB().

■ If no arguments are specified for line or column, then the

function will automatically orients itself to the current cursor position.

Examples
■  Clear from the cursor position to the end of the line with the
   CLEARB character and CLEARA attribute:

   ClearEol()

■  Do the same for line 23 from the current cursor position:

   ClearEol(23)

■  Do the same as before, but begin the erasure at column 55:

   ClearEol(23, 55)

■  The attributes can be specified in different ways.  In the
   following three examples, the clear character is set with
   SetClearB():

   ClearEol(23, 55, 4)         // red on black
   ClearEol(23, 55, "4/7")     // red on white
   ClearEol(23, 55, "B/W")     // blue on white

■  Clear with special attribute and character:

   ClearEol(23, 55, "3/1", ":")
   ClearEol(23, 55, "B/W", "+")
Platforms
Available on MS-DOS
See also

ClearSlow()Harbour implementation  | 

Deletes a screen area from the outside in with a delay
Syntax
ClearSlow(<nDelay>, [<nTopline>], [<nLeftcolumn>],
   [<nBottomline>], [<nRightcolumn>],
   [<cCharacter|nCharacter>]) → cNull
Arguments
nDelay Designates the time delay in milliseconds for the individual steps in the delete procedure. The value is in the range of 1 to 65535.
nTopline Designates the line for the top-left corner of the area. The default value is the topmost line.
nLeftcolumn Designates the column for the top-left corner of the area. The default value is the leftmost column.
nBottomline Designates the line for the bottom-right corner of the area. The default value is the bottommost line.
nRightcolumn Designates the column for the bottom-right corner of the area. The default value is the rightmost column.
cCharacter|nCharacter Designates the character to use to clear the screen. The character can be numeric in the range of 0 to 255 or a character string. The default is the character set using SetClearB().
Returns
The function always returns a null string.
Description
ClearSlow() clears a screen area from the outside in, step by step, with time delays. You can designate the delay in milliseconds. If the parameters for the area coordinates are left out, the function clears the entire screen. In this case, the delete character set through SetClearB() is used. The preset value is Chr(255). CA-Clipper Tools uses this character because, in contrast to Chr(32), it accepts a color attribute on all screen adapters.
Notes

■ If no screen coordinates are designated, the entire screen is

cleared.

Examples
■  Use Chr(255) to clear the entire screen with a 50-millisecond
   delay:

   ClearSlow(50)                       // Always returns ""

■  Clear an area with spaces and use a 10-millisecond delay:

   ClearSlow(10, 4, 4, 20, 76, 32)     // Delete character 32 (Blank)
Platforms
Available on MS-DOS
See also

ClearWin()Harbour implementation  | 

Clears a screen area
Syntax
ClearWin([<nTopLine>], [<nLeftCol>], [<nBottomLine>],
   [<nRightCol>], [<cAttr|nAttr>],
   [<cCharacter|nCharacter>]) → cNull
Arguments
nTopLine Designates the topmost line where clearing is to begin. The default value is the cursor line.
nLeftCol Designates the leftmost column from which clearing is to begin. The default value is the cursor column.
nBottomLine Designates the bottommost line to clear. The default is the last screen line or window line.
nRightCol Designates the rightmost column to clear. The default is the right screen border or window border.
cAttr|nAttr Designates the attribute to use to clear. The default is the standard attribute CLEARA.
cCharacter|nCharacter Designates the character to use to clear. The default is the standard character CLEARB.
Returns
ClearWin() always returns a null string.
Description

ClearWin() clears a specified screen area. This area extends from

< nTopLine> to nBottomLine and from nLeftCol to nRightCol.

Without these parameters, the line and column that correspond to the current cursor position for nTopLine and nLeftCol, and the bottommost line and rightmost column are used for nBottomLine and nRightCol.

You can clear with the standard attribute and character (CLEARA and CLEARB), or with the cAttr|nAttr attribute and the cCharacter|nCharacter character.

Notes

■ The cAttr|nAttr attribute and cCharacter|nCharacter

character are specified in different ways. Please refer to the Introduction of this chapter for more details

■ The standard attribute and character are set with SetClearA()

and SetClearB().

■ If no parameters are specified for the line or column, the

function automatically orients itself to the current cursor position.

Examples
■  Clear from the cursor position to the end of the line with the
   CLEARB character and CLEARA attribute:

   ClearWin()

■  Do the same for line 23 from the current cursor position:

   ClearWin(23)

■  Clear a window between line 23, column 15 and line 24, column
   70:

   ClearWin(23, 15, 24, 70)

■  You can specify the attributes in different ways.  In the
   following three examples, the CLEARB() clear character is used.

   ClearWin(23, 15, 24, 70, 4)            // red on black<
   ClearWin(23, 15, 24, 70, "4/7")        // red on white
   ClearWin(23, 15, 24, 70, "B/W")        // blue on white

■  Clear when specifying attribute and character:

   ClearWin(23, 15, 24, 70, "B/W", "+")   // blue on white
Platforms
Available on MS-DOS
See also

ClEol()Harbour implementation  | 

Clears characters and attributes to the end of a line
Syntax
ClEol([<nRow>], [<nColumn>]) → cNull
Arguments
nRow Designates the line to clear. The default is the cursor line.
nColumn Designates the column from which to clear. The default is the cursor column.
Returns
ClEol() always returns a null string.
Description

Implement the ClEol() function when you need to clear to black and cannot use the standard attribute and character. This function is especially useful with a monochrome video card. A significant advantage of ClEol() over ClearEol(), is the omission of the cAttr|nAttr and cCharacter|nCharacter parameters, which increase the speed of ClEol(). The function is faster because it does not note the CLEARA and CLEARB settings.

ClEol() has some advantages over the CA-Clipper @ Row, Column commands:

1. The function allows you to take the returned value of the character

string type and combine it with string outputs (e.g., LIST...ClEol()).

2. The cursor position is not affected.

3. The parameters are optional. If they are not specified, the function

clears from the current cursor position with the CLEARA attribute and the CLEARB character.

Notes

■ If no parameters are specified for line or column, the

function automatically orients itself to the current cursor position.

Examples
■  Clear from the current cursor position to the end of the line:

   ClEol()

■  Clear line 23, starting from the cursor column position to the
   end of the line:

   ClEol(23)

■  Clear line 23 from column 15 to the end of the line.

   ClEol(23, 15)
Platforms
Available on MS-DOS
See also

ClWin()Harbour implementation  | 

Clears character and attribute from a screen area
Syntax
ClWin([<nTopLine>], [<nLeftCol>], [<nBottomLine>],
   [<nRightColumn>]) → cNull
Arguments
nTopLine Designates the topmost line where clearing should begin. The default is the cursor line.
nLeftCol Designates the leftmost column where erasure should begin. The default is the cursor column.
nBottomLine Designates the bottommost line to clear. The default is the last screen line or window line.
nRightColumn Designates the rightmost column to clear. The default is the right screen border or window border.
Returns
ClWin() always returns a null string.
Description

Implement ClWin() when you need to clear to black without the use of the standard attribute and character. This function is helpful when you use a monochrome video card. A significant advantage of ClWin() over ClearWin(), is the omission of the cAttr|nAtt and cCharacter|nCharacter parameters, because it increases the speed of ClWin(). The function is faster because it does not note the CLEARA and CLEARB settings.

ClWin() has some advantages over the Clipper @ Row, Column commands:

1. This function takes the returned value of the character string type

and combines it with string outputs (e.g., LIST...ClWin()).

2. The cursor position is not affected.

3. The parameters are optional. If they are not specified, the function

clears from the current cursor position.

Notes

■ If no parameters are specified for the line or column, the

function automatically orients itself to the current cursor position.

Examples
■  Clear from the cursor position to the end of the screen area:

   ClWin()

■  Do the same from the current cursor position in line 23:

   ClWin(23)

■  Clear from line 23, column 15, to the end of line 24:

   ClWin(23, 15, 24)

■  Clear a window between line 23, column 15, and line 24, column
   70:

   ClWin(23, 15, 24, 70)
Platforms
Available on MS-DOS
See also

CLOSESOCK()  | 

Closes the socket and all connected IPX/SPX handles
Syntax
CLOSESOCK(<nSocket>) → NIL

Netware: 2.2 and 3.11
Arguments
nSocket Designates the number of the socket that is closed.
Returns
CLOSESOCK() always returns NIL when closing a socket according to IPX.
Description
CLOSE SOCKET CLOSESOCK() allows you to close a socket that is used for IPX/SPX communication. At the same time, all IPX/SPX communication buffers for which nSocket has been specified as the source socket are closed. The related communication handles are then invalid.
Examples
Open and close the IPX receiving buffer with source socket 20000:

nHandle=IPXOPEN(20000,2000)
CLOSESOCKET(20000)  // nHandle is now invalid
Platforms
Available on MS-DOS
See also

ColorRepl()Harbour implementation  | 

Exchanges particular screen attributes
Syntax
ColorRepl([<cNewAttr|nNewAttr>],
   [<cOldAttr|nOldAttr>]) → cNull
Arguments
cNewAttr|nNewAttr Designates the new attribute. The default is CLEARA.
cOldAttr|InOldAttr Designates the old attribute to exchange. The default is all existing attributes.
Returns
ColorRepl() always returns a null string.
Description

ColorRepl() simplifies screen handling. This function exchanges all occurrences of the cOldAttr|nOldAttr attribute for the cNewAttr|nNewAttr attribute.

For example, after a READ, you could take the colors in all input fields, (assuming they have a common attribute), and change them. This designates these fields as no longer active.

Notes

■ If the cOldAttr|nOldAttrparameter is not specified, then all

screen attributes (without exception) are exchanged for cNewAttr|nNewAttr. If cNewAttr|nNewAttr is also missing, then cOldAttr|nOldAttr is exchanged for the CLEARA standard attribute.

Examples
■  Exchange the attribute 7 (white on black) for 0 (black on
   black= invisible):

   ColorRepl(0, 7)

■  Replace all attributes for attribute 116 (red on white):

   ColorRepl(116)

■  Exchange the attribute "7/0" (white on black) for 116 (red on
   white):

   ColorRepl(116, "7/0")

■  Exchange all attributes for the CLEARA standard attribute:

   ColorRepl()

■  Change the display from white on black to black on white.  You
   can specify different parameters:

   ColorRepl("0/7", "7/0")
   ColorRepl(112, 7)

■  Mixed formats are also possible:

   ColorRepl("0/7", 7)
Platforms
Available on MS-DOS
See also

ColorToN()Harbour implementation  | 

Converts NN/NN or CC/CC color values into numeric values
Syntax
ColorToN(<cAttr>) → nAttr
Arguments
cAttr Designates the alphanumeric color attribute that is converted in NN/NN or CC/CC form.
Returns
ColorToN() returns a number that corresponds to the combined numeric color attribute.
Description

COLOR TO (N)umeric The function changes an alphanumeric color attribute from NN/NN or CC/CC into a combined numeric attribute. These combined attribute values are useful with the CA-Clipper Tools functions StrScreen(), ScreenMix(), ScreenAttr(), and the CA-Clipper commands SAVE/RESTORE SCREEN.

ColorToN() makes it easy to create numeric attributes for the CA-Clipper Tools functions.

Notes

■ If you specify an invalid attribute string, ColorToN() returns

the numeric attribute 0, meaning black on black (invisible).

Examples
■  Show the "normal" display (white on black); all alphanumeric
   forms yield 7:

   ? ColorToN("07")
   ? ColorToN("07/00")
   ? ColorToN("W/N")

■  Display red on white; all alphanumeric forms yield the numeric
   attribute 116:

   ? ColorToN("04/07")
   ? ColorToN("R/W")

■  If the foreground color is missing,  0 is assumed.  Here it
   corresponds to an inverse video display:

   ? ColorToN("/7")

■  High intensity (+) and flashing (*) are also recognized:

   ? ColorToN("BR+")
   ? ColorToN("BR+*")
   ? ColorToN("G/BR+*")
   ? ColorToN("+G*/BR")

■  An invalid parameter returns 0:

   ? ColorToN()

■  Parameters of the <cAttr|nAttr> type are allowed.  A numeric
   attribute remains numeric.

   ? ColorToN(112)         // Result:  112
Platforms
Available on MS-DOS
See also

ColorWin()Harbour implementation  | 

Exchanges particular attributes in a screen area
Syntax
ColorWin([<nTopLine>], [<nLeftCol>],
   [<nBottomLine>], [<nRightCol>],
   [<cNewAttr|nNewAttr>], [<cOldAttr|nOldAttr>])
    → cNull
Arguments
nTopLine Designates the topmost line to begin processing. The default is the cursor line.
nLeftCol Designates the leftmost column to begin processing. The default is the cursor column.
nBottomLine Designates the bottommost line that is processed. The default is the last screen line or window line.
nRightCol Designates the rightmost column to clear. The default is the right screen border or window border.
cNewAttr|nNewAttr Designates the new attribute to replace the old one. The default is the standard attribute CLEARA.
cOldAttr|nOldAttr Designates the old character to exchange. The default is "exchange all attributes".
Returns
ColorWin() always returns a null string.
Description

ColorWin() exchanges all occurrences of cOldAttr|nOldAttrfor the cNewAttr|nNewAttr attribute, within a particular screen or window area. The function operates in a similar way to ColorRepl(), except with ColorWin() you can define the screen area to work on.

The parameters nTopLine and nLeftCol define the row and column for the top-left corner; nBottomLine and nRightCol define the row and column for the bottom-right column.

Notes

■ If cOldAttr|nOldAttr is not specified, all attributes are

exchanged for cNewAttr|nNewAttr; if cNewAttr|nNewAttr is not specified, the attributes are exchanged for CLEARA.

Examples
■  Exchange attribute 7 (white on black) for 0 (black on black =
   invisible) from the current cursor position to the end of the screen
   area:

   ColorWin(0, 7)

■  Exchange all attributes in the area from line 23, column 15 to
   line 24, column 70 for the standard attribute CLEARA:

   ColorWin(23, 15, 24, 70)

■  Replace all attributes for attribute 116 (red on white) in the
   region from line 23, column 15 to line 24, column 70:

   ColorWin(23, 15, 24, 70, 116)

■  Change the white on black display to black on white.  You can
   specify different parameters:

   ColorWin(23, 15, 24, 70, "0/7", "7/0")

■  Mixed formats are also possible:

   ColorWin(23, 15, 24, 70, "0/7", 7)
Platforms
Available on MS-DOS
See also

Complement()Harbour implementation  | 

Forms the complement value of a data type
Syntax
Complement(<expValue>) → xComplement
Arguments
expValue[@] Designates any valid expression of any data type to form a complement value. Complement() only allows a character string to be passed by reference.
Returns
Complement() returns the complement value that corresponds to the same data type for expValue.
Description
Complement() returns the respective opposite value of the expValue parameter. In contrast to CharNot(), which only permits character strings, this function permits all data types. The result is the same data type as the parameter. For example, a date returns a date as a result. It corresponds to the difference between the indicated date and 12/31/2999.
Notes

■ Complement(Complement(expValue)) always returns expValue

as output.

Examples
■  The complement of a logical value corresponds to the use of
   .NOT.:

   ? Complement(.T.)                  // .F.
   ? Complement(.F.)                  // .T.

■  Numeric values change sign:

   ? Complement(99)                   // -99.00
   ? Complement(0)                    // 0
   ? Complement(-99)                  // 99.00
   ? Complement(-9.9)                 // 9.90
   ? Complement(9.9)                  // -9.9

■  With strings, the function works like CHARNOT:

   ? Complement("123ABCabc")          // "       <157><156>"

■  The difference between 1/1/1900 and 01/01/3000:

   SET CENTURY ON
   ? Complement(CToD("01/01/00"))     // 12/31/1099

■  An empty or invalid date gives the same result -- 01/01/3000:

   SET CENTURY ON
   ? Complement(CToD("  /  /  "))     // 01/01/3000
   ? Complement(CToD("77/77/77"))     // 01/01/3000
Platforms
Available on MS-DOS
See also

Cos()Harbour implementation  | 

Computes the cosine
Syntax
Cos(<nArc>) → nCosine
Arguments
nArc Designates a radian value for which the cosine is determined.
Returns
Cos() returns the cosine value specified in nArc.
Description
Cos() computes the angle cosine measured in radians.
Notes

■ If you want the values specified in degrees, you can convert

them with the DToR() function.

Examples
Compute the cosine:

? Str(Cos(0), 18, 15)               // 1.000000000000000
? Str(Cos(Pi() /4), 18, 15)         // 0.707106781186548
? Str(Cos(Pi() /2), 18, 15)         // 0.000000000000000
? Str(Cos(Pi() *99.5), 18, 15)      // 0.000000000000000
? Str(Cos(Pi() /9), 18, 15)         // 0.939692620785908
Platforms
Available on MS-DOS
See also

Cot()Harbour implementation  | 

Computes the cotangent
Syntax
Cot(<nArc>) → nCoTangent
Arguments
nArc Designates a radian value for which the cotangent is determined.
Returns
Cot() returns the cotangent of the value specified in nArc.
Description
Cot() computes the cotangent of an angle measured in radians.
Notes

■ If the values are specified in degrees, use the DToR()

function to convert them.

Examples
Computes the cotangent:

? Str(Cot(Pi() /4), 18, 15)      // 1.000000000000000
? Str(Cot(Pi() /2), 18, 15)      // 0.000000000000000
? Str(Cot(Pi() /9), 18, 15)      // 2.747477419454622
Platforms
Available on MS-DOS
See also

CountGets()Harbour implementation  | 

Determines the number of posted GET fields
Syntax
CountGets() → nFields
Returns
CountGets() returns the number of currently posted fields within a READ.
Description
CountGets() determines how many GET fields are currently open in a VALID UDF or within a KEYTRAP procedure. Posted means the GET fields have been recently defined before with @ ...GET ...
Examples
■  Display the number of GET fields that are currently posted
   from within a valid UDF:

      @ 10, 10 GET Field1
      @ 10, 20 GET Field2 VALID MYFUNC()
      @ 10, 30 GET Field3
   READ
   RETURN

■  Returns CountGets() within the UDF:

   FUNCTION MYFUNC
      ? CountGets()          // Result: 3
      RETURN(.T.)
Platforms
Available on MS-DOS
See also

CountLeft()Harbour implementation  | 

Counts a particular character at the beginning of a string
Syntax
CountLeft(<cString>,[<cCharacter|nCharacter>])
   → nNumber
Arguments
cString Designates the character string in which the cCharacter|nCharacter character is counted.
cCharacter|nCharacter Designates the character at the beginning of the cString that is counted. The default value is a space, Chr(32).
Returns
CountLeft() returns the number of cCharacter|nCharacter characters that appear in an uninterrupted sequence at the beginning of cString.
Description
While RemLeft() removes leading characters from the cString, CountLeft() only determines the number of leading cCharacter| nCharacter characters appearing in an uninterrupted sequence at the beginning of the cString.
Examples
■  Count the blanks:

   ? CountLeft("   123")               // Result: 3

■  Count the "." characters:

   ? CountLeft("..4.123", ".")         // Result: 2

■  In this example, there is nothing to count:

   ? CountLeft("123456")               // Result: 0
Platforms
Available on MS-DOS
See also

CountRight()Harbour implementation  | 

Counts a particular character at the end of a string
Syntax
CountRight(<cString>,[<cCharacter|nCharacter>]) → nNumber
Arguments
cString Designates the character string in which the cCharacter|nCharacter character is counted.
cCharacter|nCharacter Designates the character at the end of the cString that is counted. The default value is a space, Chr(32).
Returns
CountRight() returns the number of cCharacter|nCharacter characters that appear in an uninterrupted sequence at the end of the cString.
Description
While RemRight() removes trailing characters from the cString, CountRight() only determines the number of trailing cCharacter| nCharacter characters appearing in an uninterrupted sequence at the end of the cString.
Examples
■  Count the blanks:

   ? CountRight("abc   ")            // Result: 3

■  Count the "." characters:

   ? CountRight("abc.d..", ".")      // Result: 2

■  In this example, there are no spaces to count:

   ? CountRight("123456")             // Result: 0
Platforms
Available on MS-DOS
See also

CPUType()Harbour implementation  | 

Determines what type of microprocessor in use
Syntax
CPUType() → nCPUType
Returns
CPUType() returns a numeric code that identifies the microprocessor in use.
Description

This function determines which microprocessor is in use. For instance, a PC may use a Vnn microprocessor or an AT may use a 386 microprocessor. The microprocessors have the following codes:

Table 12-1: Microprocessor Coding

    Value   Symb. constant    Processor
    0       CPU_8088          8088
    1       CPU_8086          8086
    2       CPU_V20           V20
    3       CPU_V30           V30
    4       CPU_80188         80188
    5       CPU_80186         80186
    6       CPU_80286         80286
    7       CPU_80386         80386
    8       CPU_80486         80486

Examples
What type of microprocessor is on the AT?

IF CPUType() == CPU_80386
   ? "A 386 ..."
ENDIF
Platforms
Available on MS-DOS
See also

Crypt()Harbour implementation  | 

Encrypts and decrypts a string
Syntax
Crypt(<cString>,<cKeystring>) → cString
Arguments
cString Designates the string that is that is encrypted.
cKeystring Designates the password with which the string is encrypted.
Returns
Crypt() returns the encrypted string.
Description

In contrast to a simple lock using CharXor(), this function has a random number generator that uses a "random seed" algorithm. This makes the lock even more secure, at least as long as this additional algorithm is not known. Of course, this additional security costs some computer time.

Encrypted character strings can be decrypted with the same password. With multiple encryptions, the decryption must occur in reverse order.

Notes

■ Passwords should be as long as possible — a minimum of six

characters, preferably more.

■ The return value of this function can be suppressed by

implementing CSetRef() to save space in working memory.

Examples
■  This example shows a simple encryption:

   cVar:= Crypt("CLIPPER", "CA")

■  This example shows the decryption:

   ? Crypt(cVar, "CA")         // "CLIPPER"
Platforms
Available on MS-DOS
See also

CSetAtMupa()Harbour implementation  | 

Determines the setting of the multi-pass mode for ATXXX() functions
Syntax
CSetAtMupa(<lNewMode>) → lOldMode
Arguments
lNewMode Designates the setting for the multi-pass switch for all AT functions. The default value (.F.) sets the multi-pass switch to off
Returns
If lNewMode is not specified, the current setting is returned. If lNewMode is specified, CSetAtMupa() returns the previous setting.
Description

CSetAtMupa() sets a switch, internal to CA-Clipper Tools, that affects the operation of several other CA-Clipper Tools functions. These functions permit targeted, extremely flexible substring manipulation. The affected functions are:

AtNum() AfterAtNum() BeforAtNum()

AtRepl() NumAt() AtAdjust()

WordToChar() WordRepl()

The CSetAtMupa() function sets the multi-pass mode on or off for these functions.

Notes

■ The default setting for CSetAtMupa() is .F., indicating that

the multi-pass mode is off.

Examples
Switch the multi-pass mode on and save the previous setting:

lOldMupa  :=  CSetAtMupa(.T.)
Platforms
Available on MS-DOS
See also

CSetKey()*Harbour implementation  | 

Queries the setting for SET KEY TO
Syntax
CSetKey(<nKeyValue>) → cProcedureName

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Arguments
nKeyValue Designates the Inkey() for which the associated procedure name is determined.
Returns
CSetKey() returns a character string that names the procedure associated with nKeyValue.
Description
This function queries the setting for SET KEY..TO.
Notes

■ To use this function, you must include the ct.ch file at the

beginning of your program with the command:

#include "CT.CH"

Find more information on this function in CH.CH.

Examples
Save the assignment for the function key F2:

cOldF2Proc  :=  CSetKey(-1)
Platforms
Available on MS-DOS
See also

CSetRef()Harbour implementation  | 

Determines whether or not reference sensitive functions return a value
Syntax
CSetRef([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether the return value is suppressed for specified functions. When this parameter is .T., it suppresses the return value of the functions listed below. When the parameter is .F. (default value), these functions return a value.
Returns
If no parameter is specified, the function returns the current setting. If a parameter is specified, the function returns the previous setting.
Description

A series of CA-Clipper Tools functions enable you to pass parameters by reference. After executing the function, the passed parameter already contains the result. However, each of these functions also returns this result as a value. A copy of the passed string exists for a short time in working memory, but it is invisible to you. In the worst possible case, two adjoining memory blocks would require up to 64 kB.

This behavior can be influenced by implementing CSetRef(.T.). Then the group of affected string functions no longer return a value, which can save you up to 64k of memory with large strings.

Functions affected by CSetRef():

AddAscii() Blank() CharAdd()

CharAnd() CharMirr() CharNot()

CharOr() CharRelRep() CharRepl()

CharSort() CharSwap() CharXor()

Crypt() JustLeft() JustRight()

PosChar() PosRepl() RangeRepl()

ReplAll() ReplLeft() ReplRight()

TokenLower() TokenUpper() WordRepl()

WordSwap()

Notes

■ If, in spite of having CSetRef(.T.), you need one of the

previously listed functions to return a value, then the target variable contains .F. instead of the anticipated string.

Examples
■  Here is how CSetRef() is set to .F.:

   CSetRef(.F.)
   cStr1  :=  "HAGBDCFE"
   cStr2  :=  CharSort(@cStr1)
   ? cStr1, cStr2        // "ABCDEFGH" - cStr1,cStr2 are identical

■  Here is how CSetRef() is set to .T.:

   CSetRef(.T.)

   cStr1  :=  "HAGBDCFE"
   cStr2  :=  CharSort(@cStr1)
   ? cStr1               // "ABCDEFGH" - Sort cStr1
   ? cStr2               // .F.

■  Determine when memory will be needed:

   cStr1  :=  Space(32000)       // Create large string

   CSetRef(.F.)
   CharSort(@cStr1)              // Additional 32000 bytes

   CSetRef(.T.)
   CharSort(@cStr1)              // Needs no additional memory
Platforms
Available on MS-DOS
See also

CSetSafety()Harbour implementation  | 

Queries/sets the safety mode switch
Syntax
CSetSafety([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether existing files should not be overwritten during CA-Clipper Tools file operations. Designates .F. for yes; .T. for no.
Returns
CSetSafety() returns the current setting for the CA-Clipper Tools safety mode switch; or if lNewSwitch is passed, the previous setting.
Description
CSetSafety() returns a logical value for the current setting of the CA-Clipper Tools internal safety mode switch. If you designate CSetSafety() as .T., the CA-Clipper Tools functions do not overwrite existing files.
Notes
Warning! CSetSafety() only works with CA-Clipper Tools functions..
Examples
■  Query the SAFETY function:

   lSafety:=  CSetSafety()

■  Turn safety mode on and save the previous status:

   lOldSafety:= CSetSafety(.T.)
Platforms
Available on MS-DOS

CSETALL()  | 

Saves all ON/OFF switch settings
Syntax
CSETALL([<cNewSwitchList>]) → cOldSwitchList
Arguments
cNewSwitchList Designates in a specific format (shown in the tables on the next page), which switches are to be on or off.
Returns
CSETALL() returns the current setting of all ON/OFF switches when no parameter is specified. When the parameter is specified, the function returns the previous setting.
Description

This function allows you to query the current setting for all CA-Clipper ON/OFF switches and change them. Since you can save 21 different switches, the function returns a 21-character string made with 0's and 1's, rather than logical values. This function makes it easy to save all the ON/OFF switches in a CA-Clipper error trap, and reset them when you exit. The following switches are contained in the character string (in the order they occur in the returned string):

Table 11-1: Clipper Switch Status

    Byte    Function      Clipper Switch
    1       CSETALTE()     SET ALTERNATE
    2       CSETBELL()     SET BELL
    3       CSETCARR()     SET CARRY
    4       CSetCent()     SET CENTURY
    5       CSETCONF()     SET CONFIRM
    6       CSETCONS()     SET CONSOLE
    7       CSetCurs()     SET CURSOR
    8       CSETDELE()     SET DELETED
    9       CSETDELI()     SET DELIMITERS
    10      CSETDEVI()     SET DEVICE
    11      CSETESCA()     SET ESCAPE
    12      CSETEXAC()     SET EXACT
    13      CSETEXCL()     SET EXCLUSIVE
    14      CSETFIXE()     SET FIXED

Table 11-2: Clipper Switch Status

    Byte    Function       Clipper Switch
    15      ReadInsert()   INSERT Mode
    16      CSETINTE()     SET INTENSITY
    17      CSETPRIN()     SET PRINT
    18      CSETSCOR()     SET SCOREBOARD
    19      CSETSOFT()     SET SOFTSEEK
    20      CSETUNIQ()     SET UNIQUE
    21      CSETWRAP()     SET WRAP

Notes

■ If you specify an invalid parameter, the function returns a

null string and does not reset any switch.

Examples
Display the current bell status:

cSwitches  :=  CSETALL()         // 010000000000000000000

IF SubStr(cSwitches, 2, 1) == "1"
   ? " BELL is on!"
ENDIF
Platforms
Available on MS-DOS
See also

CSETCLIP()  | 

Determines the content of CA-Clipper environmental variables
Syntax
CSETCLIP(<cEnvParameter>) → nEnvParameterValue

Important!  CA-Clipper no longer supports all possible settings for
environmental variables in the CA-Clipper Summer 1987 release.
Therefore, CSETCLIP() is modified to reflect these changes.
Arguments
cEnvArguments Designates which SET CA-Clipper setting to return.
Returns
SETCLIP() returns the setting of the requested SET CLIPPER= option.
Description
The CA-Clipper environmental variable contains settings for a CA-Clipper application. Use CSETCLIP() to query these values from within the application. The letter you use for the respective SET CLIPPER= option is given as a parameter. This value cannot be set from a running program since memory allocation is already determined. (You must determine memory allocation before you start an application.)
Notes

■ Uppercase or lowercase letters have no impact on the

parameter.

Examples
■  Uppercase or lowercase letters do not impact the parameter:

   ? CSETCLIP("F")       // SET CLIPPER= Fnnn
   ? CSETCLIP("e")       // SET CLIPPER= Ennn
   ? CSETCLIP("X")       // SET CLIPPER= Xnnn
   ? CSETCLIP("SWAPK")   // SET CLIPPER= SWAPK:nnn

■  With an invalid parameter:

   ? CSETCLIP("z")       // -1
Platforms
Available on MS-DOS

CSETDATE()*  | 

Queries the SET DATE setting
Syntax
CSETDATE() → nDateFormat

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
The returned numeric code signifies the current setting for SET DATE.
Description

This function allows you to query the current setting for SET DATE. The table below describes the numeric codes that are returned:

Table 11-3: Coding for country specific date formats

    Code    Definition
    1       AMERICAN
    2       ANSI
    3       BRITISH
    4       FRENCH
    5       GERMAN
    6       ITALIAN

Notes
■ This function cannot alter the status of SET DATE.
Examples
For SET DATE AMERICAN, CSETDATE() returns a value of 1.

SET DATE AMERICAN ? CSETDATE()      // 1
Platforms
Available on MS-DOS

CSETDECI()*  | 

Queries the setting for SET DECIMALS TO
Syntax
CSETDECI() → nDecimalPlaces

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETDECI() returns the value of the current number of decimal places that are displayed.
Description
This function queries the current setting for SET DECIMALS TO.
Notes
■ This function cannot change the number of decimal places.
Examples
■  Set decimal places with CA-Clipper:

   SET DECIMALS TO 2

■  Returns the number of decimal places previously set:

   ? CSETDECI()      // 2
Platforms
Available on MS-DOS

CSETDEFA()*  | 

Queries the setting for SET DEFAULT
Syntax
CSETDEFA() → cDefaultPath

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETDEFA() returns the current DEFAULT path setting.
Description
This function queries the current SET DEFAULT TO setting.
Notes
■ This function cannot change the DEFAULT path.
Examples
■  A path set under CA-Clipper:

   SET DEFAULT TO C:\DATA

■  Query the previously set DEFAULT path:

   ? CSETDEFA()      // "C:\DATA"
Platforms
Available on MS-DOS

CSETFUNC()*  | 

Queries the setting for SET FUNCTION TO
Syntax
CSETFUNC(<nFunctionKey>) → cCharacterString

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Arguments
nFunctionKey Designates the function key for which the associated character string is determined.
Returns
CSETFUNC() returns the character string associated with nFunctionKey.
Description
This function queries the setting for SET FUNCTION TO.
Notes

■ To use this function, you must include the ct.ch file at the

beginning of your program with the command:

#include "CT.CH"

Find more information on this function in ct.ch.

Examples
The F10 key is assigned to Ctrl-C.  The setting changes in a function
Test().  Since it is saved, you can restore it upon return:

SET FUNCTION 10 TO Chr(3)
cOldFunc  := CSETFUNC(10)      // Save assignment
Test()                         // Call UDF
SET FUNCTION 10 TO cOldFunc
Platforms
Available on MS-DOS

CSETLDEL()*  | 

Queries the setting for the left delimiters
Syntax
CSETLDEL() → cLeftDelimiter

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETLDEL() returns the character established as the left delimiter.
Description
This function queries the current character used in GET fields as a left delimiter.
Notes
■ This function cannot change the delimiter.
Examples
Query the character for the left delimiter:

cLeftDelim:= CSETLDEL()
Platforms
Available on MS-DOS
See also

CSETMARG()*  | 

Queries the setting for SET MARGIN TO
Syntax
CSETMARG() →    nLMargin

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETMARG() returns a value that corresponds to the value SET MARGIN determined for the left print border.
Description
This function determines the current setting for the left print border.
Notes
■ This function cannot change the value set for the margin.
Examples
Save the value for SET MARGIN:

nPrintBound:=  CSETMARG()
Platforms
Available on MS-DOS

CSETPATH()*  | 

Queries the setting for SET PATH TO
Syntax
CSETPATH() → cSearchPath

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETPATH() returns a value that corresponds to the current CA-Clipper file search path.
Description
This function returns the file search path set by SET PATH TO.
Examples
Save the path set with SET PATH TO:

cSearchPath:=  CSETPATH()
Platforms
Available on MS-DOS

CSETRDEL()*  | 

Queries the setting for the right delimiter
Syntax
CSETRDEL() → cRightDelimiter

*  This function is retained for compatibility purposes.  Use the
   CA-Clipper Set() function to develop future applications.
Returns
CSETRDEL() returns the character established as the right delimiter.
Description
This function queries the current character used as a right delimiter in GET fields.
Notes
■ This function cannot change the delimiter.
Examples
Query the character for the right delimiter:

cRightDelim:= CSETRDEL()
Platforms
Available on MS-DOS
See also

CSETRDONLY()*  | 

Queries/sets the read-only mode switch
Syntax
CSETRDONLY([<lR/O-NewMode>]) → lR/O-OldMode

*  This function is retained in CA-Clipper Tools II/5.0 for
   compatibility purposes.  Use the READ-ONLY clause of the
   CA-Clipper  USE command to develop future applications.
Arguments
lR/O-NewMode Designates the new switch status. .T. turns the read-only mode on; .F. turns it off. The default value is off.
Returns
If no parameter is passed, the function returns to the current switch setting; otherwise, it returns the previous setting.
Description

Important! Please note the changes in the CA-Clipper USE command!

This function was implemented in the CA-Clipper Summer 1987 release to allow you to open files in read-only mode. This function was also useful for CD-ROM access and the enabled you to open a network database if you lacked write permission.

However, in CA-Clipper READONLY you can append to the USE command and do not have to implement CSETRONLY(). The switch has been retained in this release to insure compatibility with previous versions of CA-Clipper Tools. You can still use it to query, but it no longer has direct impact on the open mode.

This switch functions in the enclosed CA-Clipper Tools ct.ch definition file.

Notes

■ For new applications, use the read-only key word in

conjunction with the USE command.

Examples
Set the read-only mode switch (it only functions when you use the ct.ch
header file):

? CSETRDONLY(.T.)         // Returns old setting
USE ....                  // Open with READ ONLY access
Platforms
Available on MS-DOS

CSETSNOW()  | 

Helps prevent snow on the screen
Syntax
CSETSNOW([<lNewSwitch>]) → lOldSwitch

*  This function is retained in CA-Clipper Tools for compatibility
   purposes.  Use the CA-Clipper NoSnow() function to develop future
   applications.
Arguments
lNewSwitch Designates the new status for "Snow Prevent". A .T. signifies on; .F. means off. The default value for Snow Prevent is off (.F.).
Returns
CSETSNOW() returns the current setting, when no parameter is designated; otherwise, it returns the previous setting.
Description

Snow tends be is especially bad in CGA card screen output. To prevent it, set the CSETSNOW switch.

Use the CA-Clipper NoSnow() function for new applications.

Notes
CSETALL() does not acknowledge the CSETSNOW() setting.
Examples
■  Output with Snow Prevent on:

   CSETSNOW(.T.)                   // Returns old setting

■  Acknowledge existing hardware:

   CSETSNOW(IsCGA())               //  Snow prevent if CGA card
Platforms
Available on MS-DOS
See also

CSETxxxx()*  | 

Queries the SET position of a particular ON/OFF switch and provides the option to set it
Syntax
CSETxxxx([<lNewSwitch>]) → lOldSwitch

*  This function is retained in CA-Clipper Tools for compatibility
   purposes.  Use the CA-Clipper Set() function to develop future
   applications.
Arguments
lNewSwitch Designates the new status for the SET xxxx command. .T. corresponds to on; .F. signifies off.
Returns
If no parameter is passed, the function returns the current setting; otherwise, it returns the previous setting.
Description

This is a group of 20 functions. If you call all these functions the same way, they return the same value. Each function name consists of "CSET", and the first four characters of the respective CA-Clipper set condition:

Table 11-4: Functions to Query Clipper Set Conditions

    Function       Set Condition
    CSETALTE()     SET ALTERNATE ON/OFF
    CSETBELL()     SET BELL ON/OFF
    CSETCARR()     SET CARRY ON/OFF (See note)
    CSetCent()     SET CENTURY ON/OFF
    CSETCONF()     SET CONFIRM ON/OFF
    CSETCONS()     SET CONSOLE ON/OFF
    CSetCurs()     SET CURSOR ON/OFF
    CSETDELE()     SET DELETED ON/OFF
    CSETDELI()     SET DELIMITERS ON/OFF
    CSETDEVI()     SET DEVICE TO PRINT (.T.)/SCREEN (.F.)
    CSETESCA()     SET ESCAPE ON/OFF
    CSETEXAC()     SET EXACT ON/OFF
    CSETEXCL()     SET EXCLUSIVE ON/OFF
    CSETFIXE()     SET FIXED ON/OFF
    CSETTINTE()    SET INTENSITY ON/OFF
    CSETPRIN()     SET PRINT ON/OFF
    CSETSCOR()     SET SCOREBOARD ON/OFF
    CSETSOFT()     SET SOFTSEEK ON/OFF
    CSETUNIQ()     SET UNIQUE ON/OFF
    CSETWRAP()     SET WRAP ON/OFF

Notes

CSETCARR() is not useful in CA-Clipper. Since this function

was in CA-Clipper Tools and also occupies a position in CSETALL(), it is retained for compatibility purposes.

Examples
■  Switch SET UNIQUE on:

   ? CSETUNIQ(.T.)         // Returns previous setting

■  Save a setting:

   lOldWRAP:= CSETWRAP()
Platforms
Available on MS-DOS
See also

CToBit()Harbour implementation  | 

Converts a character string into a bit pattern
Syntax
CToBit(<cCharacterstring>,<cBitpattern>) → nWORD
Arguments
cCharacterstring Designates a character sequence. When this sequence occurs in the second character string, each corresponding bit is set to 1.
cBitpattern Designates a sequence, with a maximum of 16 characters, from which the bit position is assigned.
Returns
CToBit() returns a number in the range of 0 to 65535 that corresponds to the created bit pattern.
Description
The CToBit() function delivers a bit pattern that corresponds to a string of individual characters. When used in conjunction with its sister function BitToC(), it facilitates work with such bit-coded information as file attributes.
Notes

■ Characters in cCharacterstring that are not found in

cBitpattern are ignored.

Examples
■  The second bit in the resulting value is set, since the letter
   "H" appears in the next-to-last position in "ADVSHR":

   ? CToBit("H", "ADVSHR")          // Result:  00000010

■  Two characters also in ADVSHR, appear at the first and final
   positions in this 6-character string:

   ? CToBit("RA", "ADVSHR")         // Result:  00100001

■  <cBitpattern> ignores previously unavailable characters:

   ? CToBit("XRYA", "ADVSHR")       // Result:  00100001
Platforms
Available on MS-DOS
See also

CToDoW()Harbour implementation  | 

Converts the name of the day of the week into a corresponding number
Syntax
CToDoW(<cDayofWeek>) → nDayofWeek
Arguments
cDayofWeek Designates a character string that contains the name of a day of the week.
Returns
CToDoW() returns the number of the day for the day name.
Description
Use CToDoW() to change the name of a day of the week to a number. Sunday corresponds to 1, Monday 2, etc.. If the function returns a 0 value, an invalid parameter has been passed. You can shorten the day names, but these abbreviations must be explicit to return an accurate value.
Notes

■ Uppercase and lowercase letters do not affect the name of the

day of the week.

■ The function's operation depends on the country-specific

adaptation of your CA-Clipper compiler. With an English version of CA-Clipper, only English day names are recognized.

Examples
■  What number of the day of the week is Sunday?

   ? CToDoW("Sunday")         // Result:  1

■  Show several ways to get the day of the week for Wednesday:

   ? CToDoW("WEDNESDAY")      // Result:  4
   ? CToDoW("Wednesday")      // Result:  4
   ? CToDoW("Wed")            // Result:  4

■  What number of the day of the week is Monday?

   CToDoW("M")                // Result:  2
Platforms
Available on MS-DOS
See also

CToF()Harbour implementation  | 

Converts a special 8-byte string into a floating point number
Syntax
CToF(<cFloatingPointNumber>) → nFloatingPointNumber
Arguments
cFloatingPointNumber Designates an 8-byte character string that contains a CA-Clipper number in the 64-bit floating point format.
Returns
CToF() returns the number that corresponds in the passed string.
Description
Character strings created with FToC() or XToC() are changed into CA-Clipper numbers. Note that when you use XToC(), character strings or portions of character strings, can be switched back, if they have been displayed as CA-Clipper floating point numbers.
Examples
■  Change a number and then change it back:

   CToF(FToC(1234.55))        // Result:  1234.55

■  This also works for XToC():

   ? CToF(XToC(1234.55))      // Result:  1234.55
Platforms
Available on MS-DOS
See also

CToMonth()Harbour implementation  | 

Converts the name of the month into a corresponding number
Syntax
CToMonth(<cMonth>) → nMonth
Arguments
cMonth Designates the name of one of the 12 months.
Returns
CToMonth() returns the number for the designated month name.
Description
Use CToMonth() to change the name of a month into a number. January corresponds to 1, February 2, etc.. If the function returns a 0 value, then an invalid parameter has been passed. If you shorten the month name, use explicit abbreviations to return an accurate return value.
Notes

■ Uppercase and lowercase letters do not affect the name of the

month.

■ The function's operation depends on the country-specific

adaptation of your CA-Clipper compiler. With an English version of CA-Clipper, only English month names are recognized.

Examples
■  Show the number for January:

   ? CToMonth("January")      // Result: 1

■  Show several ways to determine the month number for August:

   ? CToMonth("AUGUST")       // Result: 8
   ? CToMonth("August")       // Result: 8
   ? CToMonth("Au")           // Result: 8

■  The number for April:

   ?CToMonth("A")             // Result: 4
Platforms
Available on MS-DOS
See also

CToN()Harbour implementation  | 

Converts a numeric string into a different base
Syntax
CToN(<cNumericstring>,[<nBase>],[<lMode>])
    → nInteger
Arguments
cNumericstring Designates a numeric string to convert into a number in base nBase.
nBase Designates the number base to use in the conversion. Can be in the range of 2 to 36. The default is the decimal system, base 10.
lMode When designated as .T., allows a negative result. The default allows only positive results.
Returns
CToN() returns the converted number that corresponds to the string. The values lie in the range of 0 and 65535 or, if lMode is .T., in the range of -32768 and +32767.
Description
CToN() offers a number of ways to covert a number string into numeric data format. Almost any number can be converted, as long as the base nBase for the number system lies between 2 and 36.
Notes

■ The cNumericstring string is automatically TRIMmed left and

right.

■ If you have invalid parameters or combinations, the function

returns a value of 0.

Examples
■  Convert to base 10:

   ? CToN("60000")                    // Result:  60000

■  Convert to base 2:

   ? CToN("11", 2)                    // Result:  3

   ? CToN("1110101001100000", 2)      // Result:  60000

■  Convert to base 16:

   CToN("A", 16)                      // Result:  10

   ? CToN("ABCD", 16)                 // Result:  43981

   ? CToN("FFFF", 16, .T.)            // Result:  -1

■  Convert to base 36:

   ? CToN("XXP", 36)                  // Result:  43981
Platforms
Available on MS-DOS
See also

CurrentGet()Harbour implementation  | 

Determines the number of the currently active GET field
Syntax
CurrentGet() → nField
Returns
CurrentGet() returns the number of the currently active GET field.
Description
CurrentGet() determines the number of the currently active GET fields. This information is useful in functions called through VALID.
Examples
Pass the number of the active GET fields as a parameter:

@@ XX,YY GET field  VALID MYFUNC(CurrentGet())
Platforms
Available on MS-DOS
See also

DATATYPE()*  | 

Determines the data type of a variable or UDF
Syntax
DATATYPE(<expValue>) → nDataType

*  This is retained in CA-Clipper for compatibility purposes.  Use the
   CA-Clipper ValType() function to develop future applications.
Arguments
expValue Designates any valid CA-Clipper expression.
Returns
DATATYPE() returns a value that corresponds to the data type in expValue.
Description

DATATYPE() is similar to the CA-Clipper Type() function, but returns more extensive information in numeric value form. The bits in the result correspond to specific data types. Two bits can be set at the same time. It is easy to recognize specific data types with the IsBit() function. The following codes apply:

Table 13-2: Data Type Coding

    Value   Symb. Const.   Data Type
     0      TYPE_UNDEF     Undefined
     1      TYPE_STR       Character string
     2      TYPE_NUM       Numeric
     4      TYPE_LOG       Logical
     8      TYPE_DATE      Date
    16      TYPE_ALIAS     Alias
    64      TYPE_MEMO      Memo field
    128     TYPE_WORD      Word
    512     TYPE_ARRAY     Array
    4096    TYPE_BLOCK     Code block

In addition, DATATYPE() returns the respective data type for a CA-Clipper Tools function or one of your own UDF's. This is impossible with Type().

Notes

■ An invalid expValue output results in a runtime error.

■ The function cannot determine if a parameter has passed to a

function by reference (32 + type), because this information is no longer available in CA-Clipper.

Examples
Return values of DATATYPES() used for different data types:

? DATATYPE()                 //    0, undefined
? DATATYPE("XXX")            //    1, string
? DATATYPE(123)              //    2, numeric
? DATATYPE(DoY())            //    2, numeric result
? DATATYPE(.T.)              //    4, logical
? DATATYPE(3 > 2)            //    4, logical expression
? DATATYPE(Eof())            //    4, logical result
? DATATYPE(Date())           //    8, date
? DATATYPE(memofld)          //    1, memo field
? DATATYPE(@crlf)            //   33, reference to string
? DATATYPE(@array)           //  544, reference to array
? DATATYPE(array[1])         //    2, numeric element
? DATATYPE(array[2])         //    1, string element
? DATATYPE(myfunc())         //       type for your own UDF
Platforms
Available on MS-DOS

DbfSize()Harbour implementation  | 

Determines the size of a selected (.dbf) file in memory
Syntax
DbfSize() → nFileSize
Returns
DbfSize() returns the byte size of the current database in working memory.
Description
DbfSize() determines how much room a database occupies, before you write this file to a disk. The function is also useful when used in conjunction with DBFDSKSIZE(). When the results for both functions indicate there is a deviation in the size of a database, this means a portion of the data is not yet written to the floppy/hard disk. You can also determine if and when new input is written to a floppy/hard disk.
Notes

■ This function always operates on the currently SELECTed work

area.

Examples
Can a (.dbf) file be copied to the target disk?

USE DATA.
IF DiskFree("A") < DbfSize().
   ? "The file can not be copied.".
   ? "Insufficient space remaining on disk.".
ELSE.
   COPY TO A:COPY.
ENDIF
Platforms
Available on MS-DOS
See also

DBFDSKSIZE()  | 

Determines the size of a selected (.dbf) file on a disk drive
Syntax
DBFDSKSIZE() → nFileSize
Returns
DBFDSKSIZE() returns the size of the current database on the floppy or hard disk (i.e., how many bytes are saved in this file).
Description
One of the DBFDSKSIZE() function's most useful applications is when it is used in conjunction with DbfSize(). When the results for both functions indicate there is a deviation in the size of a database, this means a portion of the data is not yet written to the floppy/hard disk. You can also determine if and when new input is written to a floppy/hard disk.
Notes
■ This function operates on the currently SELECTed work area.
Examples
Determine if a portion of data input has been written out to disk yet:

SIZEIF Dbf() - DBFDSKSIZE() >= 512
   * COMMIT               //  Warning! Works only with DOS 3.3 and up
   USE File
ENDIF
Platforms
Available on MS-DOS
See also

DeleteFile()Harbour implementation  | 

Deletes an error-tolerant file
Syntax
DeleteFile(<cFileName>) → nErrorCode
Arguments
cFileName Designates which file name to delete.
Returns
DeleteFile() returns a code that signifies its completion status:
Table 7-1: DeleteFile() Error Codes
    Code    Symb. constants     Definition
     0      NO_DISK_ERR         No error occurs
    -2      ER_FILE_NOT_FOUND   File not found
    -3      ER_PATH_NOT_FOUND   Path not found
    -5      ER_ACCESS_DENIED    Access denied (e.g., file is read-only)
Description
In contrast to FileDelete(), which permits you to specify file groups with wildcards, DeleteFile() only accepts specific file names. However, the function avoids all DOS error messages and returns an error code directly to the calling program. This makes error-tolerant erasures in networks possible (see Examples).
Notes

■ You can use a drive designator and path name, but no

wildcards.

Examples
■  How NOT to delete a file in a network environment:

   IF FILE ("TEST.DBF")
      * Is it actually possible to delete the file?
      DELETE FILE TEST.DBF
   ENDIF

■  This is a better way:

   nStatus  :=  DeleteFile("TEST.DBF")
   IF nStatus == 0
      ? "File deleted."
   ELSE
      IF nStatus == -5
         ? "ACCESS DENIED!"
         ? "File in use elsewhere!"
      ENDIF
   ENDIF
Platforms
Available on MS-DOS
See also

DirChange()  | 

Changes the current directory
Syntax
DirChange(<cDirectory>) → nErrorCode
Arguments
cDirectory Designates the path of the directory that is changed.
Returns
DirChange() returns a 0 when it successfully changes the directory; otherwise, an error code is passed. The codes are defined as follows:
Table 7-2: DirChange() Error Codes
    Code    Symb. constants     Definition
     0      NO_DISK_ERR         No error occurred
    -2      ER_FILE_NOT_FOUND   File not found
    -3      ER_PATH_NOT_FOUND   Path not found
    -5      ER_ACCESS_DENIED    Access denied (e.g., in network)
DirChange() changes the current subdirectory or determines if a directory exists. This allows DOS error messages to be intercepted. (See also DirMake()).
Notes

cDirectory may contain a drive designator and a path.

Wildcards are not allowed.

Examples
Change to the "\DATA" directory:

IF DirChange("\DATA") == 0
   ? "Current directory is now:  " + DirName()
ENDIF
Platforms
Available on MS-DOS
See also

DirMake()Harbour implementation  | 

Creates a directory
Syntax
DirMake(<cDirectory>) → nErrorCode
Arguments
cDirectory Designates the directory name to create.
Returns
DirMake() returns a 0 when it has successfully created the directory; otherwise, an error code is passed. The codes are defined as follows:
Table 7-3: DirMake() Error Codes
    Code    Symb. constants     Definition
     0      NO_DISK_ERR         No error occurred
    -2      ER_FILE_NOT_FOUND   File not found
    -3      ER_PATH_NOT_FOUND   Path not found
    -5      ER_ACCESS_DENIED    Access denied (e.g., in network)
Description
When you install the program, directories must be the first thing you create. The DirMake() function allows you to create new directories from within your CA-Clipper application.
Notes

cDirectory can contain a drive designator and a path,

wildcards are not allowed.

Examples
Change to the "\DATA" directory:

IF DirChange("\DATA") == -3         // Path not found
   DirMake("\DATA")
ENDIF
Platforms
Available on MS-DOS
See also

DirName()Harbour implementation  | 

Determines the name of the current directory
Syntax
DirName([<cDrive>]) → cDirectory
Arguments
cDrive Designates the drive for which the current directory is determined (a colon is unnecessary). The default is the current drive.
Returns
DirName() returns the current directory name on the cDrive.
Description
DirName() determines the current directory name on the selected drive. You can use this function to construct complete access paths.
Notes

■ The maximum length of the returned value is 65 characters. If

no drive designator is specified, the current drive is assumed.

■ If there is an invalid drive designation, DirName() returns a

null string.

Examples
■  Display the current directory name:

   ? "Current Directory:  " + DirName()

■  With a drive designator:

   ? DirName("A")               // Current directory on Drive A:
Platforms
Available on MS-DOS
See also

DirRemove()  | 

Removes a directory
Syntax
DirRemove(<cDirectory>) → nErrorCode
Arguments
cDirectory Designates which directory name to remove.
Returns
DirRemove() returns a 0 when the designated directory is successfully removed; otherwise, an error code is returned. The codes are defined as follows:
Table 7-4: DirRemove() Error Code
    Code    Definition
     0      Directory has been successfully removed.
    -3      Access path not found or directory not empty.
    -5      Access denied (e.g., in a network)
    -16     Current directory (cannot be removed)
Description
DirRemove() removes a designated directory. This frees up the memory disk that an empty subdirectory occupies.
Notes

■ Use a drive designator and access path with cDirectory,

wildcards are not permitted.

■ The directory must be empty before you can remove it.

Examples
Remove the "\DATA" directory:

IF DirRemove("\DATA") == 0
   ? "Directory deleted."
ENDIF
Platforms
Available on MS-DOS
See also

DiskChange()  | 

Changes the current disk drive
Syntax
DiskChange(<cDrive>) → lChanged
Arguments
cDrive Designates which disk drive that you want to use.
Returns
DiskChange() returns .T., when the designated disk drive is successfully changed.
Description
DiskChange() allows you to change from the current disk drive to another. To do this, call DiskChange() with the disk drive identifier (A,B,C, etc.). The drive identifier can be specified with a colon (:).
Examples
Change to drive C:

? DiskChange("C")         // Returns .T. when successful
Platforms
Available on MS-DOS
See also

DiskFree()Harbour implementation  | 

Determines the space available on a floppy or hard disk
Syntax
DiskFree([<cDrive>]) → nFreeByte
Arguments
cDrive Designates for which drive (A, B, C, etc.) the open capacity is determined. The default value is the current drive.
Returns
DiskFree() returns the available memory capacity of the selected drive.
Description
DiskFree() determines if a disk has sufficient storage capacity for a file.
Notes

■ When cDrive is not specified, the function automatically

uses the current drive.

Examples
Determine if there is enough space to copy a database:

Required  :=  DbfSize()         // Database size
IF DiskFree("A") < Required
   ? "Insufficient disk space for copying!"
ENDIF
Platforms
Available on MS-DOS
See also

DiskName()  | 

Determines the drive designator for the current drive
Syntax
DiskName() → cDrive
Returns
DiskName() returns a letter that identifies the designator as the current drive.
Description
DiskName() determines the current drive designator for the construction of complete path names.
Notes
■ The designator does not contain a colon.
Examples
Display the drive designator for the current drive:

? DiskName()      // Returns a "C" with most hard disk systems
Platforms
Available on MS-DOS
See also

DiskTotal()Harbour implementation  | 

Determines the total capacity of a floppy or hard disk
Syntax
DiskTotal([<cDrive>]) → nTotalSpace
Arguments
cDrive Designates the drive for which memory capacity is determined. The default is the current drive.
Returns
DiskTotal() returns a value that corresponds to the total capacity of the data carrier in the selected drive. The default is the current disk drive.
Description
DiskTotal() determines if the capacity of the disk in use is sufficient for back up. The advantage of DiskTotal() over any capacity determined by the system, is that it recognizes bad sectors and does not include them.
Examples
Determine if disk capacity is sufficient:

nRequired  :=  DbfSize()
IF DiskTotal("A") < nRequired
   ? "Error! Insufficient disk capacity!"
ENDIF
Platforms
Available on MS-DOS
See also

DISKCHECK()  | 

Creates a checksum for a disk
Syntax
DISKCHECK(<cDrive>, [<nStartSector>]) → nCheckSum
Arguments
cDrive Designates which drive (A, B, C, etc.) you want to check.
nStartSector Designates a sector to serve as a starting point to check the disk in the direction of the first sector.
Returns
DISKCHECK() returns a number that corresponds to a checksum for the data carrier in cDrive. If read errors occur, the function returns a negative number when the first bad sector is found.
Description

DISKCKECK() begins its check with the last sector of the designated drive or with the nStartSector value, and works in the direction of the first sector. If a sector is found to contain errors, then it returns a negative value.

If it returns a -1, continue to check for other errors (such as a missing disk). The CA-Clipper Tools function ERRORCODE() is quite useful here. Error code returns a value that symbolizes the most-recent DOS error.

Since DISKCHECK() returns a checksum, it is easy to check for disk changes.

Notes

■ You must specify the cDrive parameter. If you omit it or

specify an unavailable drive, DISKCHECK() returns an error code of - 1. DISKCHECK() takes more time to check a hard disk.

Examples
■  Create a checksum for a floppy:

   Checksum  :=  DISKCHECK("A")

■  Show that the disks are changed:

   IF DISKCHECK("A") == Checksum
      ? "You have not changed disks!"
   ENDIF
Platforms
Available on MS-DOS
See also

DISKFORMAT()  | 

Formats disks, controlled through a UDF
Syntax
DISKFORMAT(<cDrive>, [<nCapacity>], [<cUDF>],
   [<cBootText>], [<nRepetitions>]) → nErrorCode
Arguments
cDrive Designates the disk drive to format. Only a floppy drive is permitted. You may optionally specify a colon (:).
nCapacity Designates the appropriate disk capacity for the disk you are about to format. Possible values are 160, 180, 320, 360, and 1200 for 5.25"; 720 and 1440 for 3.5" disks. The default is the maximum drive capacity.
cUDF Designates the name of a user-defined function call before each format step (track or head change). The default is no UDF called.
cBootText This optional parameter designates text, with a maximum of 255 characters, to display if the formatted disk is booted. The default is described in the "Notes" section on the following page.
nRepetitions Designates the number of repeat attempts you should make, to format a track before the function aborts. The default is one repetition.
Returns
The function returns 0 when the disk is successfully formatted.
Table 7-5: DISKFORMAT() Error Codes
    Error Codes  Symb. constants     Definition
     0           NO_DISK_ERROR       Format successful
    -1           DF_WRONG_DRIVE      Illegal drive, only A: and B:  allowed
    -2           DF_WRONG_DISK_SIZ   kB value not supported
    -3           DF_INTERRUPTED      Terminated by control UDF
    -4           DF_WRITE            Write error
Description

DISKFORMAT() formats a disk under full CA-Clipper program control, so there is no need for a RUN FORMAT. You cannot create bootable disks, only data disks.

Since you can call a separate function (UDF) prior to every track and head change and the respective track and head number are passed, you can construct the visual display of the format process constructed as desired.

You can only format floppy disks, so even with unforeseen incorrect parameters, your hard disk is safe. All the standard floppy types are supported — 160kB, 180kB, 320kB, 360kB, 1.2MB, 720kB, and 1.44MB.

DISKFORMAT() is useful for formatting disks, at least when the preset repetition rate is retained or decreased. After an unsuccessful attempt to format a track, the process is repeated one more time. If this repetition also fails, the entire format is aborted. If you want to be as safe as possible about the quality of the disk in used, select a repetition rate of 0.

The Control UDF

DISKFORMAT() calls the control UDF, which is specified as the third parameter, prior to each head and track change. Both values, head and track, are passed as a parameter to the function. As soon as all tracks are formatted and DISKFORMAT() has initialized the FAT and directory area, a value of -1 is passed for both parameters to the UDF. Please be aware that both parameters must be passed.

The numeric value returned for UDF can further influence DISKFORMAT():

Table 7-6: Control UDF Returned Values

    Returned Value    Explanation
    0                 Continue format
    1                 Do not format this track (parameter 1)
    2                 Abort format

Notes

■ If the defined control UDF does not exist, the function

uninstalls itself and triggers a runtime error. If an error message concerning a missing procedure is required during linking, you can specify EXTERNAL function in the program.

■ If you attempt to boot with a data disk created with

DISKFORMAT() and did not designate any other text for the cBootText parameter, the following text is displayed:

"No system disk. Insert new disk, press any key to continue"

DISKFORMAT() begins to format a disk with the highest track

number. Therefore, an existing FAT and directory label are the last items deleted.

DISKFORMAT() always reformats a track, even if it is already

formatted. Therefore, when a format is successful, all the data is deleted.

■ Each track is verified again after it is formatted.

■ After the last track is formatted, the function continues to

work a few seconds more. The FAT and directory must be established and the boot text must be written.

Examples
■  An example for formatting a disk in A: drive:

   DISKFORMAT() first determines whether the desired capacity is
   appropriate for the drive.  The control UDF "CONTROL" is concerned
   with the display of the track and head that are currently being
   formatted.  "This is a data diskette" is used as boot text for the
   disk.  The repeat rate is highly effective at 0.  Only the highest-
   quality disks are accepted.

   To provide an additional example of the return value for the UDF,
   only tracks 80 to 11 are formatted here, not the first 10:

   CLEAR
   cBootText  :=  "This is a data diskette"
   @ 10, 02 SAY "Track:
   "@ 11, 02 SAY "Head:
   "IF FLOPPYTYPE("A:") = 2
                                 // 1.2 MB disk
      nErrCode := DISKFORMAT("A:", 1200", CONTROL", cBootText, 0)
      IF nErrCode = 0
         ? "Format successful!"
      ENDIF
   ENDIF
   RETURN

   FUNCTION CONTROL(nTrack, nHead)
      LOCAL nRetval
      IF Track >= 11
         @ 10, 08 SAY Str(nTrack)
         @ 11, 08 SAY Str(nHead)
         nRetval := 0            // Continue format
      ELSE
         nRetval := 2            // Abort
      ENDIF
      RETURN(nRetval)

■  Shown below is another variation of the UDF.  Press the ESC
   key to abort the format.  If the format is completed, then the
   function displays the FAT initialization and root directory:

   FUNCTION CONTROL(nTrack, nHead)
      LOCAL nRetval
      IF Inkey() = 27
         nRetval := 2            // Abort
      ELSE
         nRetval := 0            // Continue format
      ENDIF
      IF nTrack = -1
         @ 10, 10 SAY "Initializing FAT and Root Directory!"
      ENDIF
      RETURN(nRetval)
Platforms
Available on MS-DOS
See also

DISKREADY()  | 

Tests to see if a disk drive is ready
Syntax
DISKREADY([<cDrive>], [<lDOS/BIOS>]) → lDiskReady
Arguments
cDrive Designates the drive designator (A, B, C, etc.) of the drive to test. The default is the current disk drive.
lDOS/BIOS This logical parameter allows you to designate whether you want the function tested through the BIOS (.F.) or DOS (.T.). The default is discussed in the Description below.
Returns
DISKREADY() returns .T. when the drive being tested is ready to use.
Description

To save space, you must frequently make multiple disk copies. DISKREADY() allows you to wait for a user disk change, without having to confront known DOS errors, or use CA-Clipper error trap functions. Be sure to differentiate between floppy tests and "true" hard disks and logical partitions.

DOS or BIOS

In the simplest case, this function tests the respective drive through DOS. If drive B is unavailable, the message "Please insert disk in drive B:..." is output from the operating system. When you test floppy drives, drive A: and B:, the BIOS route is recommended, since no message is output. In any event, A: and/or B: can be mapped drives within a network. Use the following logical expression for all the previous situations:

(NetDisk(cDrive) .OR. cDrive >= "C")

This logical expression returns .T. when the respective drive is either on the network or has a drive identifier of C: or higher.

Examples
The system waits between individual copy procedures until drive A: is
ready again:

DO Copy                        // Call copy procedure
? "Please insert a disk in Drive A:!"
DO WHILE .NOT. DISKREADY("A")
   *...
ENDDO
DO Copy                        // Call copy procedure
Platforms
Available on MS-DOS
See also

DISKREADYW()  | 

Queries whether you can write to a drive
Syntax
DISKREADYW([<cDriveId>]), [<lDOS/BIOS>]) → lDiskReady
Arguments
cDriveId Designates which drive designator (A, B, C, etc.) to query. The default value is the current disk drive.
lDOS/BIOS This logical parameter allows you to specify whether you want to query the function through the BIOS (.F.) or DOS (.T.). The default is described in the Description below.
Returns
DISKREADYW() returns .T. when you query a drive that is operational and can be written to.
Description

As with DISKREADY(), this function determines if a drive is ready to use. DISKREADYW() also determines if you can write to a drive. DISKREADY() cannot tell if a disk has a write-protect marker on it. In this case, drive A: might be ready, but you could not write to it. Use this function to build write-protect detection for important disks into the program.

Network Drives

In general, drives mapped within networks are viewed by the function as accessible and return .T. as a result. For a disk, "accessible" means you can create, open, and delete files. You can clearly differentiate these rights within networks such as Novell NETWARE. Therefore, you must test for these accordingly.

DOS or BIOS

In the simplest case, this function always tests the respective drive through DOS. If drive B: is unavailable, the message "Please insert disk in drive B:" is output from the operating system. When you test floppy drives drive A: and B:, the BIOS route is recommended, since no message is output. In any event, A: and/or B: can be mapped drives within a network. Use the following logical expression to cover all the previous situations:

(NetDisk(cDrive) .OR. cDrive >= "C")

This logical expression returns .T. when the respective drive is either on the network or has a drive identifier of C: or higher.

Notes

■ Research indicates work in the OS/2 compatibility box must be

in the BIOS mode.

Examples
Determine if you can write a file to A: drive:

IF DISKREADY("A")
   IF NETDISK ("A")
      IF NNETRIGHTS ("A:\")      // complete path
      * ...
      ENDIF
   ELSE
      IF DISKREADYW("A")
      ? "Disk is not write protected!"
      ELSE
      ? "Disk is write protected!"
      ENDIF
   ENDIF
ELSE
   ? "Disk drive not ready!"
ENDIF
Platforms
Available on MS-DOS
See also

DISKSPEED()  | 

Determines a comparison value for the drive speed
Syntax
DISKSPEED(<cDrive>) → nDriveSpeed
Arguments
cDrive Designates for which physical drive identifier (A, B, C, etc.) to determine the speed. You do not need to use the colon (:).
Returns
DISKSPEED() returns a percentage comparison value to a floppy drive of a 4.77 MHz PC, which corresponds to 100%.
Description

Use this function when you want to calculate the approximate duration of such complex file operations as INDEX or SORT. Since the total duration always depends upon the remaining computer speed, you should also use the SPEED() function..

If the designated drive is unavailable or cannot be checked (network drive), the function returns a 0 value.

Notes

■ You can only implement DISKSPEED() for physical drives, not

network drives.

Examples
■  Show the speed of drive A:

   ? DISKSPEED("A")            // depends on drive

■  Show the factor for your hard disk:

   ? DISKSPEED("C")            // e.g. 720  Factor 7.2
Platforms
Available on MS-DOS
See also

DISKSTAT()  | 

Determines the status of a drive.
Syntax
DISKSTAT([<cDrive>]) → nStatus
Arguments
cDrive Designates the drive designator (A, B, C, etc.) of the drive for which the status of the last operation is determined. The default is the current disk drive.
Returns
DISKSTAT() returns the status of the floppy or hard disk operation as a number. The bits have the following meanings:
Table 7-7: Drive Status Coding
    Bit     Symb. constants     Definition
    1       DST_INVALID         Unknown command
    2       DST_READONLY        Address marker not found
    3       DST_SECTOR          Sector not found
    4       DST_DMA             DMA overflow
    5       DST_CRC             CRC error
    6       DST_CONTROLLER      Controller error
    7       DST_SEEK            Seek operation failure
    8       DST_TIMEOUT         Timeout error
Description
When DOS returns a "block device error" message (See ERRORORG()) and DISKSTAT() to determine a more detailed cause of the error).
Notes

■ This function passes the system status to a CA-Clipper

application. The system saves a status value for all floppy and hard disk operations. When you reaccess a floppy disk drive from within your program, the previous disk operation status is lost. The same applies to hard disk status.

Examples
Determine if the system was unable to find an address marker:

IF ERRORORG() == DST_READONLY
   DiskError  :=  DISKSTAT("A")
ENDIF
Platforms
Available on MS-DOS
See also

DISKTYPE()  | 

Determines the type of data carrier
Syntax
DISKTYPE([<cDrive>]) → nDiskType
Arguments
cDrive Designates the drive designator (A, B, C, etc.) for which you want to determine the data carrier. The default is the current drive.
Returns
The returned value corresponds to the FAT-ID byte of a floppy or hard disk. The following codes apply:
Table 7-8: FAT-ID Definitions
    FAT-ID  Symb. constants     Definition
    255     DT_DS_SEC_8         Double sided 8 sectors
    254     DT_SS_SEC_8         Single sided 8 sectors
    253     DT_DS_SEC_9         Double sided 9 sectors
    252     DT_SS_SEC_9         Single sided 9 sectors
    249     DT_DS_SEC_15        Double sided 15 sectors (HD-Disk)
    249     DT_35_SEC_9         Double sided 3.5" 9 sectors (ident. to 5.25"
                                HD)
    240     DT_35_SEC_18        Double sided 3.5" 18 sectors
    248     DT_HARDDISK         Hard disk
Description
If a 360K floppy is written on an AT in a 1.2 MB drive, you may not be able to read it on other systems, particularly on PC XTs. This function determines how the floppy you are about to use is formatted and provides the corresponding warning.
Examples
Determine if an XT disk is being written to an AT:

IF IsAt() .AND. DISKTYPE("A") == DT_DS_SEC_9
   ? "Warning!"
   ? "Under certain circumstances this disk not"
   ?? " readable on other systems!"
ENDIF
Platforms
Available on MS-DOS
See also

DMY()Harbour implementation  | 

Returns a date in "DD Month YY" format
Syntax
DMY([<dDate>], [<lMode>]) → cDate
Arguments
dDate Designates the date from which to create a string. The default is the system date.
lMode Designates whether to insert a period (.) after the day (see Examples). The default is no period (.F.).
Returns
DMY() returns a character string in "DD[.] Month YY" format or "DD[.] Month YYYY" format.
Description
Use DMY() to return the date as a character string using the day, name of month, and year. The CA-Clipper SET CENTURY ON/OFF switch determines whether or not the year is displayed in two or four digits. If the lMode parameter is designated .T., the function builds in a "." after the day designation. If no date is designated as a parameter, the function automatically uses the current system date.
Notes

■ The month name returned depends on which CA-Clipper nations

module is in use.

Examples
■  Display the system date (1/1/89):

   SET CENTURY OFF
   ? DMY()                            // 1 January 89

■  With ".":

   ? DMY(.T.)                         // 1. January 89

■  Display a different date:

   SET CENTURY ON
   ? DMY(CToD("02/01/89"), .T.)       // 1. February 1989
Platforms
Available on MS-DOS
See also

DosParam()Harbour implementation  | 

Retrieves the DOS command line as a string
Syntax
DosParam() → cDOSCommandLine
Returns
DosParam() returns the parameters from the DOS command line.
Description
DosParam() returns all the parameters passed from the DOS command when you run the application. Use DosParam() when you do not want the parameters to be separated. With this function, it is no longer necessary to check each individual parameter in a loop.
Notes

■ With the Token() function, it is easy to break down the

returned character string. It can also use your own rules.

Examples
Given the DOS command line C>MyApp A: C: /a ,
the following is true:

DosParam()                // "A: C: /a"
TOKEN(DosParam())         // "A"

This way, it is easy to break down parameter lines according to your own
rules.
Platforms
Available on MS-DOS
See also

DoY()Harbour implementation  | 

Determines the day of the year for a specific date
Syntax
DoY([<dDate>]) → nDayOfYear
Arguments
dDate Designates which date to use to calculate the day of the year. The default is the system date.
Returns
DoY() returns a calendar day number that specifies which day of the year dDate represents.
Description
If you frequently work with time periods, then this function is quite useful. DoY() lets you assign a calendar day number to a date that relates to the beginning of the year.
Notes

■ When no date is specified, DoY() uses the system date.

January 1 is always 1, December 31 is 366 in a leap year; otherwise, it is 365. An empty date returns a 0 result.

Examples
How long is it until Christmas?

? "There are", NToC(DoY(CToD("12/24/91"))- DoY())  ;
   , " days until Christmas!"
Platforms
Available on MS-DOS

DriveType()Harbour implementation  | 

Determines the drive type
Syntax
DriveType([<cDrive>]) → nDriveType
Arguments
cDrive Designates the drive (A, B, C, etc.) for which the type is determined. The default is the current drive.
Returns
DriveType() returns a numeric value for the drive type. The following codes apply:
Table 7-9: Drive Type Coding
    Code    Definition
    0       RAM Disk
    1       Floppy Disk (disk change cannot be established by system)
    2       Floppy Disk (disk change can be established by system)
    3       Hard Disk
Description

Warning! Only for AT-class computers.

This function determines if you are dealing with a floppy drive, a hard disk, or a RAM disk.

Notes

■ Although DriveType() returns a 0 value for logical DOS

partitions, RAM floppies, and unavailable drives, you must also differentiate with DISKTYPE(). Here, each hard disk partition returns a 248 value. A RAM floppy created with VDISK.SYS behaves like a single-sided floppy with eight sectors, which returns a 254 value. If there is an unavailable drive, the DISTYPE() returns a value of 0.

Examples
Determine if the drive is a RAM floppy:

IF DriveType() == 0 .AND. DISKTYPE() == 254
   ? "Drive " + DiskName() + ":  is a RAM-disk!"
ENDIF
Platforms
Available on MS-DOS
See also

DSetKBIOS()Harbour implementation  | 

Turns the extended keyboard mode on or off through BIOS (additional keys F11, F12)
Syntax
DSetKBIOS([<lNewKeyboardMode>]) → lOldKeyboardMode
Arguments
lNewKeyboardMode Designates whether the extended keyboard input mode is on (.T.) or off (.F.). The default value (.T.) designates that the extended keyboard input mode is on.
Returns
When called without the parameter, this function returns the current setting for DSetKBIOS(). If you pass a parameter, then it returns the previous setting.
Description
Beginning with CA-Clipper 5.0, all keyboard entries are read through the BIOS instead of DOS. The default setting for DSetKBIOS() is now the opposite of what it was in previous versions. The default setting for the enhanced keyboard is on (.T.). When the enhanced keyboard mode is off, keyboard entries are redirected through DOS. This function is very useful if file inputs must be read at program start.
Notes

■ Symbolic constants for keyboard coding are found in the

CTSCAN.CH include file and in Appendix A.

Examples
■  This example shows a keyboard entry that is redirected through
   DOS:

   C:\>TEST < KEYS.DAT

■  This example shows the application TEST.EXE:

   DSetKBIOS(.F.)            // Switch to DOS input mode
   ACCEPT "" TO cInput
Platforms
Available on MS-DOS
See also

DSETNOLINE()  | 

Ignores the next line feed sent to the screen
Syntax
DSETNOLINE([<lNewLFMode>]) → lOldLFMode
Arguments
lNewLFMode Designates whether the next line feed for the screen is ignored (.T.) or not (.F.). The default value (.F.) designates that the next line feed is not ignored.
Returns
When called without a parameter, the function returns the current setting for DSETNOLINE(). If a parameter is passed, it returns the previous setting.
Description
DSETNOLINE() can be used in conjunction with a LIST command when you have empty lines you want overwritten by the next line (see example). You can also suppress a line feed issued by CA-Clipper before each LIST. This makes it possible to begin LIST output on line 0.
Examples
When you use DSETNOLINE(), records with the Art_nr field empty are
written to the screen but are overwritten by the next record where
Art_nr is present:

LIST Art_nr, Art_bez, DSETNOLINE(Empty(Art_nr))
Platforms
Available on MS-DOS

DSETQFILE()  | 

Creates a protocol file when the program ends normally
Syntax
DSETQFILE([<lNewQuitMode>]) → lOldQuitMode
Arguments
lNewQuitMode Designates whether the automatic QUIT file is created (.T.) or not (.F.). The default value (.F.) does not create an automatic QUIT file.
Returns
When called without parameter, the function returns the current DSETQFILE() setting. If a parameter is passed, it returns the previous setting.
Description

This function allows for the creation of a QUIT file. This file can be used to determine if an application has been terminated normally or not (i.e. Ctrl-Alt-Del). When the program ends, the contents of the keyboard buffer are written to a file. This allows you to determine what keyboard input the user made, which can be used to trace errors and reconstruct files. The size of the QUIT file corresponds to the size of the keyboard buffer. To save more than the 16 default characters, you must increase the keyboard buffer size with SET TYPEAHEAD. (The maximum buffer size 32768 keystrokes.)

The name for the QUIT file is normally constructed from the name of the .EXE file with a .Q extension. SETQNAME() lets you use any file name you choose.

Notes

■ The keyboard data appears in KEYREAD() format in the QUIT file

(see Appendix A: Key Codes/ ctscan.ch).

■ Only those keyboard inputs already processed by the program

are written to the QUIT file.

■ An existing QUIT file is overwritten automatically if it has

the same name as the QUIT file that is currently being written.

Examples
■  This statement causes the program to create a standard QUIT
   file when you exit the program:

   DSETQFILE(.T.)       // QUIT file will be created

■  Select the name of the QUIT file:

   SETQNAME("C:\LOGS\PROTO.LOG")
   DSETQFILE(.T.)       // QUIT file will be created
                        // with an alternate name
Platforms
Available on MS-DOS
See also

DSETTYPE()  | 

Determines the size of the keyboard buffer (SET TYPEAHEAD TO)
Syntax
DSETTYPE() → nBufferSize
Returns
DSETTYPE() returns the current size of the CA-Clipper keyboard buffer.
Description
DSETTYPE() allows you to determine what size the CA-Clipper keyboard buffer has been set to with SET TYPEAHEAD TO. You can use the function to determine the number of characters that can be placed in the keyboard buffer using KEYSEND().
Notes

■ The keyboard buffer is made of memory that is internal to

CA-Clipper, which is independent of the system buffer. In CA-Clipper, the standard setting for TYPEAHEAD is 16 characters. (This corresponds to the size of the system buffer.)

■ For every character that is processed in a CA-Clipper program,

two bytes must be allocated in the keyboard buffer. DSETTYPE() determines the number of CA-Clipper characters, not the number of bytes! The standard buffer size is not 16, but 32 bytes.

Examples
The current size of the keyboard buffer is queried and increased if
needed:

nSize  :=  DSETTYPE()

IF nSize < 256
   SET TYPEAHEAD TO 256
ENDIF
Platforms
Available on MS-DOS
See also

DSETWINDOW()  | 

Reroutes external functions and programs to a window
Syntax
DSETWINDOW([<lNewDisplayMode>]) → lOldDisplayMode
Arguments
lNewDisplayMode Designates whether the screen output from external programs or other language UDF's displays in the current window.
Returns
When called without a parameter, the function returns the current setting for DSETWINDOW(). If a parameter is passed, it returns the previous setting.
Description

DSETWINDOW() allows you to determine if only CA-Clipper screen outputs should appear in a window, or if all outputs (all external modules and programs, including DOS) should appear. If you would like to implement a subroutine for screen handling with CA-Clipper Tools window functions, you can use this switch to turn off these functions for a short time.

Important! Before you call external programs using RUN, you should set DSETWINDOW() to .F.; if you do not, some programs will not run correctly.

Notes

Important! The standard setting for DSETWINDOW() is on. This means that all program output, not written directly into the screen memory, displays in the currently active window.

■ CA-Clipper screen output is always written in a window if one

is open and active. Only screen output from external routines (like Assembler or C UDF's, or external programs called using RUN) can be affected. CA-Clipper Tools functions are also viewed as foreign or external.

■ If you call DSETWINDOW() with .T., a change in cursor position

in an external module or program also affects the cursor position in CA-Clipper. If you do not want to change the cursor position in CA-Clipper, then set DSETWINDOW() to .F. so that the CA-Clipper cursor position remains unchanged. If you still want to pass the cursor position to CA-Clipper, then use the SetRC() function without parameters.

■ Some CA-Clipper Tools functions ignore this switch because

they work directly with the physical screen memory.

■ CA-Clipper Tools has a public variable available for your own

Assembler or C routines to affect the DSETWINDOW() function. It can be addressed as follows:

EXTR _WINDOW:WORD MOV _WINDOW, 0 // Window functions OFF, all

// other values switched ON!

■ If the switch is set to on, then interrupt 16 (10h, video) and

function 19 (13h, write string), normally only available on AT's, become available on PC XT's.

Examples
■  Do not reroute other program output to the selected window:

   DSETWINDOW(.F.)

■  Do a test to see if ANSI.SYS has been linked in to CONFIG.SYS:

   lVar  :=  DSETWINDOW(.F.)
   ? ISANSI()
   DSETWINDOW(lVar)              // Reset to old status
Platforms
Available on MS-DOS
See also

DToR()Harbour implementation  | 

Converts from a degree to radian measure
Syntax
DToR(<nAngle>) → nArc
Arguments
Angle Designates a valid angle measurement in degrees.
Returns
DToR() returns the radian of the specified value.
Description
In addition to expressing angle measurements in degrees, you may also need to express an angle in radians. With DToR(), you can convert degree measurements into radians.
Examples
Show some calculations accurate to 15th place:

? Str(DToR(360), 18, 15)     // Result: 6.283185307179588
? Str(DToR(180), 18, 15)     // Result: 3.141592653589794
? Str(DToR(180.5), 18, 15)   // Result: 3.150319299849766
? Str(DToR(720), 18, 15)     // Result: 12.566370614359180
? Str(DToR(-180), 18, 15)    // Result:-3.141592653589794
Platforms
Available on MS-DOS
See also

EGA43()Harbour implementation  | 

Switches to the 43-line EGA mode
Syntax
EGA43() → lSwitched
Returns
EGA43() returns .T. if the screen graphics adapter successfully switched to the 43-line mode.
Description
This function can be used with either an EGA or VGA card. A 43-line mode is requested, and the maximum number of coordinates for the CA-Clipper screen output is automatically increased. It isn't necessary to also call the SETMAXROW() and SETMAXCOL() functions.
Notes
Important! This function cannot be implemented when windows are open.
Examples
The following example switches to 43-line mode, making lines 0 to 42
available:

IF IsEGA()
   EGA43()
ENDIF

@ 42, 10 SAY "CA-Clipper"      // Last line
WAIT
CGA80()                        // Return to 25-line mode
Platforms
Available on MS-DOS
See also

EGAPALETTE()  | 

Changes EGA palette colors
Syntax
EGAPALETTE([<cColor1|nColor1>, [<nPalette>])
    → lValid

or

EGAPALETTE([<cColor1|nColor1>, [<cColor2>]])
    → lValid
Arguments
cColor1|nColor1 Designates the color to change as a CA-Clipper color code or a numeric in the 0 to 15 range. If only this color is given, the accompanying palette is reset to its default value.
nPalette Designates which color palette the color cColor1|nColor1 is assigned to. May be in the range of 0 to 63.
cColor1|nColor1, cColor2 If a color is also designated as a second parameter, then that color's palette is designated as cColor1|nColor1.
() When no parameters are designated, all color palettes are reset to their default values.
Returns
EGAPALETTE() returns .T. when the selected setting is successfully implemented.
Description

EGAPALETTE() allocates one of the 16 colors available to another color palette. Since the function changes the screen adapter, everything on the screen designated with cColor1|nColor1 also changes.

Instead of a palette value, you can designate a second color. Its palette setting is allocated to the one designated in cColor1|nColor1, so that two of the 16 colors are identical.

If only the cColor1|nColor1 parameter is given, then the accompanying palette is reset to its default value. When calling the function without parameters, all palettes are reset.

Notes

■ You can also implement EGAPALETTE() in VGA mode, although

VGAPalette() provides more flexibility.

FONTRESET() resets all color palettes.

Examples
■  Redefine the color blue to dark blue:

   SET COLOR TO B            // Set blue
   ? "Nantucket"             // Appears in blue
   EGAPALETTE("B", 8)        // Affects everything blue.

■  Reset the palette for the color blue:

   EGAPALETTE("B")
   Reset all palettes
   EGAPALETTE()
Platforms
Available on MS-DOS
See also

Enhanced()Harbour implementation  | 

Selects the enhanced color value for SET COLOR TO output
Syntax
Enhanced() → cNull
Returns
Enhanced() always returns a null string
Description
Use Enhanced() to specify the color attribute designated as enhanced (second color value), with SET COLOR TO as the active attribute for CA- Clipper @...SAY and ? output. Use Standard() to switch back to the default attribute.
Examples
Output with enhanced attribute:

? "........"
? "........"

Enhanced()
   ? "Different Attribute!"
Standard()
? "........"
? "........"
Platforms
Available on MS-DOS
See also

EnvParam()Harbour implementation  | 

Reads the entire DOS environment table into a string
Syntax
EnvParam() → cEnvironment
Returns
EnvParam() returns a string that corresponds to the complete environment table.
Description
This function returns the entire DOS environment table. The DOS Chr(0) delimiter, which follows each variable and its setting, is replaced with CR/LF. This allows the returned string to work well with the CA-Clipper Tools string functions (especially the tokenizer).
Notes

■ With the CA-Clipper function GetEnv(), you can query

individual parameters from the environment. Initially, this may seem convenient, but there is a problem because no blanks are allowed before and after the '='.

Examples
Read in the environment and analyze it:

cVar  :=  EnvParam()                           // CR/LF as delimiter
TOKENINIT (@cVar, Chr(13) + Chr(10),2)         // CR/LF as delimiter,
skip 2
DO WHILE .NOT. TokenEnd()
   Env  :=  TokenNext(cVar)
   ? Env
ENDDO
Platforms
Available on MS-DOS
See also

EoM()Harbour implementation  | 

Determines the date for the last day of a month
Syntax
EoM([<dDate>]) → dEndOfMonth
Arguments
dDate Designates the date for which the last day of the month it lies in, is calulated. The default is the system date.
Returns
EoM() returns the date of the last day of the month in dDate.
Description
EoM() determines the last day of the month in which dDate lies. It also allows you to calculate how many days remain until the end of the month.
Notes

■ If no date is specified, the function automatically uses the

system date. An empty date parameter will always return an empty date.

■ Unlike LastDayOM(), EoM() does not return a numeric value (the

number of days in the month), but another date.

Examples
Display the remaining days in the current month:

? EoM() - Date()
Platforms
Available on MS-DOS
See also

EoQ()Harbour implementation  | 

Determines the date for the end of a quarter
Syntax
EoQ([<dDate>]) → dEndOfQuarter
Arguments
dDate Designates the date for the last day of the quarter in which it lies, is calculated. The default is the system date.
Returns
EoQ() returns the last day for the quarter that contains dDate.
Description
EoQ() determines when the current quarter that contains dDate ends. For example, it lets you calculate the number of days that remain before the end of the quarter.
Notes

■ If you do not specify a date, the function automatically uses

the system date. An empty date parameter results in an empty date.

Examples
The last day of the current quarter is:

? "The last day of the current quarter is:", EoQ()
Platforms
Available on MS-DOS
See also

EoY()Harbour implementation  | 

Determines the date for the end of the year
Syntax
EoY([<dDate>]) → dEndOfYear
Arguments
dDate Designates the date determined for the last day of the year. The default is the system date.
Returns
The returned date is December 31 of the specified year.
Description
EoY() determines the date for the end of year without having to create a date-type variable.
Notes

■ If no date is specified, the function automatically uses the

system date. An empty date parameter always returns an empty date.

Examples
■  The last day of the current year (1991):

   ? EoY()            // 12/31/91
Platforms
Available on MS-DOS
See also

ERRORACT()  | 

Recommends an action for a DOS error that has occurred previously
Syntax
ERRORACT() → nActionCode

Warning!  This function requires DOS 3.1 or higher.
Returns
ERRORACT() returns a numeric code that provides more information on how to react to the last DOS error. Coding is as follows:
Table 12-2: DOS Error Action Codes
    Code    Definition
    1       Try several times, then ask user
    2       Try several times with pauses, then ask user
    3       Ask user for data
    4       Leave program normally
    5       Leave program as soon as possible
    6       Ignore
    7       User should correct error and try again
Description
DOS reacts to errors in several ways. One of the best known and least preferred by programmers is the question: "(A)bort, (R)etry, (I)gnore". ERRORACT() tells you how the application should react to the last DOS error that occurred.
Examples
Show an error that requires the program to terminate:

nAction  :=  ERRORACT()
IF nAction = 4
   ? "Unfortunately, the program must be terminated!"
   QUIT
ENDIF
Platforms
Available on MS-DOS
See also

ERRORBASE()  | 

Source of the most-recent DOS error
Syntax
ERRORBASE() → nErrorCode

Warning!  This function requires DOS 3.1 or higher.
Returns
ERRORBASE() returns a numeric code that provides additional information about the cause of the error. These codes and their definitions are in the table below:
Table 12-3: Causes for DOS Errors
    Code      Definition
    1         Insufficient memory
    2         Access temporarily denied
    3         No access for this user
    4         Internal error, system software
    5         Hardware error
    6         Error in system software
    7         Error in applications program
    8         File not found
    9         Wrong file format or type
    10        File is protected
    11        Incorrect medium in drive
    12        Other error
Description
If an error is detected with ERRORCODE(), use ERRORBASE() for more information about the cause of the error, from within the data returned by DOS.
Examples
Determine the cause for an error:

nCause  :=  ERRORBASE()
IF nCause = 3
   ? "Access denied!"
ENDIF
Platforms
Available on MS-DOS
See also

ERRORCODE()  | 

Identifies a DOS error that has occurred previously
Syntax
ERRORCODE([<lKeep>]) → nDosErrorCode

Warning!  This function requires DOS 3.1 or higher.
Arguments
lKeep When this parameter is designated as .T., the function returns the internal error code memory value.
Returns
ERRORCODE() returns a value that represents the error code that occurred during the most-recently executed DOS function.
Description

If you do not specify a parameter or if the parameter is .F., then ERRORCODE() calls the DOS error function (INT 21h, 59h) and returns the code value stored for the most-recent error. DOS stores the most-recent error code until a new error occurs. If your operation is error free, this value is not reset.

To take this situation into account, ERRORCODE() can alternatively be called with lkeep set to .T.. If called like this, the error code always relates to the last CA-Clipper Tools function that was executed. Since the respective CA-Clipper Tools function behavior is stored at an internal memory location, it is impossible to implement this option with regular CA-Clipper functions.

Notes

■ You can find a table that contains all the error codes in

Appendix B: Error Codes.

Examples
■  This example attempts to copy a file.  If an error occurs,
   FileCopy() returns a value of 0 which offers no specific error
   information:

   nBytes  :=  FileCopy("TEST\TEST.PRG", "NEW.PRG")
   IF nBytes = 0 .AND. ERRORCODE() = 3
      ? "File path not found!"
   ENDIF

■  An example of two file copies is illustrated below:

  The first file is unsuccessful, but the second file is not:

   FileCopy("XXXXX.TXT", "YYYY.TXT")
   ? ERRORCODE(.T.)                  // 2 - File not found
   ? ERRORCODE()                     // 2 - File not found
   FileCopy("SOURCE.TXT", "TARGET.TXT")
   ? ERRORCODE(.T.)                  // 0 - Last Tools
                                     // function was successful
   ? ERRORCODE()                     // 2 - File not found

Warning!  Any CA-Clipper Tools function that contains a DOS call
resets the internal variable retrieved by setting <lKeep> .  The
following call series never returns the desired result, because the
first call of ERRORCODE() contains a DOS call:

? ERRORCODE(), ERRORCODE(.T.)        // Result: x, 0
Platforms
Available on MS-DOS
See also

ERRORORG()  | 

Origin of the most-recent DOS error
Syntax
ERRORORG() → nError

Warning!  This function requires DOS 3.1 or higher.
Returns
ERRORORG() returns a numeric code that provides more information about the device on which the error occurred. The table below details this information:
Table 12-4: Origin of DOS Errors
    Code    Definition
    1       Unknown
    2       Block device (floppy, hard disk, etc.)
    3       Network
    4       Character device (COM, SCRN, etc.)
    5       RAM
Description
ERRORORG() tells what type of device generated the most-recent DOS error. This essential information allows you to handle the error in an appropriate way.
Examples
Determine the source of an error:

nSource  :=  ERRORORG()
IF nSource = 3
   ? "Error is on the network!"
ENDIF
Platforms
Available on MS-DOS
See also

ExeName()Harbour implementation  | 

Returns name and directory of the current CA-Clipper program
Syntax
ExeName() → cProgram
Returns
ExeName() returns the name and path of the current .EXE program.
Description
This function determines the name and path of the CA-Clipper application in use.
Notes

■ Use the Token() function to determine the name portion of a

program within a path.

Examples
Determine if the name or path of an EXE file has changed:

cOrigPath  :=  "C:\DATA\ADDRESS.EXE"
IF ExecName() <> cOrigPath
   ? "Program name or directory have been changed!"
   QUIT
ENDIF
Platforms
Available on MS-DOS
See also

Expand()Harbour implementation  | 

Expands a string by inserting characters
Syntax
Expand(<cString>,[<nNumber>],[<cCharacter|    nCharacter>])
   → cString
Arguments
cString Designates the string that is processed.
nNumber Designates the number of the cCharacter|nCharacter characters that are inserted between each character in the cString. The default value is one character.
cCharacter|nCharacter Designates the character that is inserted between each character in cString. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
Expand() can be used to justify text output, although the text is stored normally. This saves memory capacity with text constants or in databases.
Notes

■ Expansion only takes place when the cString contains at

least two characters.

■ To fill out a character string at the ends, use the PadLeft()

and PadRight() functions.

Examples
■  Use the default value and expand with one space:

   ? Expand("123456")               // "1 2 3 4 5 6"

■  Expand with two spaces:

   ? Expand("123456", 2)            // "1  2  3  4  5  6"

■  Expand with a ".":

   ? Expand("123456", ".")          // "1.2.3.4.5.6"

■  Expand with two "."s:

   ? Expand("123456", 2, ".")       // "1..2..3..4..5..6"
Platforms
Available on MS-DOS
See also

Exponent()Harbour implementation  | 

Determines the exponent of a floating point number (base 2)
Syntax
Exponent(<nFloatingPointNumber>) → nExponent
Arguments
nFloatingPointNumber Designates any decimal number.
Returns
Exponent() returns the exponent of the nFloatingPointNumber number in base 2.
Description
CA-Clipper stores all numbers in a floating point format (called "double" in C). Exponent() only returns exponents in this format, and they are always expressed in base 2.
Notes

■ The expression Exponent(0) returns a value of 0. However, the

expression 20 returns a value of 1. In this case, the mantissa must also equal 0 (see Mantissa()).

Examples
■  The following calculation produces the original number:
   ^2 Exponent(nValue) * Mantissa(nValue)= nValue

   ? Exponent(0)                     // Result:  0
   ? Exponent(Infinity())            // Result:  1023
   ? Exponent(100)                   // Result:  6

■  The sign for nValue will not be considered:

   ? Exponent(-100)                  // Result:  6
   ? Exponent(-1.01)                 // Result:  0
   ? Exponent(-2.01)                 // Result:  1

■  Values in the range of -1 < nValue < +1, yield negative
   exponents regardless of the sign:

   ? Exponent(0.01)                  // Result:  -7
   ? Exponent(-0.01)                 // Result:  -7
Platforms
Available on MS-DOS
See also

Fact()Harbour implementation  | 

Computes the factorial
Syntax
Fact(<nValue>) → nFactorial
Arguments
nValue Designates a value between 0 and 21.
Returns
Fact() returns the factorial of the specified value.
Description
Fact() computes the factorial of a value in the range of 0 to 21. Since results for factorials over 21 are too large, the function returns -1 to indicate an error.
Examples
Show some factorials:

? Fact(1)         // Result: 1
? Fact(5)         // Result: 120
? Fact(21)        // Result: 51090942171709440000
? Fact(25)        // Result: -1 (Value too large !)
? Fact(0)         // Function returns 1
Platforms
Available on MS-DOS

Fahrenheit()Harbour implementation  | 

Converts a temperature value from Celsius into Fahrenheit
Syntax
Fahrenheit(<nCelsius>) → nFahrenheit
Arguments
nCelsius Designates a temperature in Celsius.
Returns
Fahrenheit() returns the converted temperature in degrees Fahrenheit.
Description
This function converts Celsius temperatures into Fahrenheit equivalents.
Examples
Convert the following Celsius temperatures to Fahrenheit:

Fahrenheit(12.5)            // Result:  54.5
Fahrenheit(125.0)           // Result:  257
Fahrenheit(1250.0)          // Result:  2282
Fahrenheit(-155.0)          // Result:  -247
Platforms
Available on MS-DOS
See also

FieldDeci()  | 

Determines the number of decimal places in a field
Syntax
FieldDeci(<nField>) → nDecimalPlaces
Arguments
nField Designates for which numeric data field to determine the number of decimal places.
Returns
When a field number is valid, FieldDeci() returns the number of decimal places in a numeric data field.
Description
It is important to know how many decimal places are in a data field so you can limit the input of significant digits in the corresponding number. FieldDeci() determines the number of decimal places available. This allows you to tailor inputs to the database without changing the program.
Notes

■ If you have an invalid field number, the function returns a

value of 0.

Examples
Convert the second field to a string with the correct number of decimal
places:

@ 0, 60 SAY "Price:  " + Str(cField2, 8, FieldDeci(2))
Platforms
Available on MS-DOS
See also

FieldNum()  | 

Determines the field number for a specific field in a database file
Syntax
FieldNum(<cFieldName>) → nFieldNumber
Arguments
cFieldName Designates to the field name.
Returns
FieldNum() returns the number of the data field.
Description
FieldNum() is the exact opposite of the CA-Clipper Field() function. Use this function when you need a data field number instead of the data field name. FieldNum() determines if a symbol name pertains to a data field or a memory variable (see Examples).
Notes

■ If a data field with the name cFieldName is not available,

the function returns a value of 0.

Examples
Is it a field or a variable?

IF FieldNum("cName") > 0.
   REPLACE cName WITH Upper(cName).
ELSE.
   cName  :=  Upper(cName).
ENDIF
Platforms
Available on MS-DOS
See also

FieldSize()  | 

Determines the size of a field
Syntax
FieldSize(<nField>) → nLength
Arguments
nField Designates the number of the field to evaluate.
Returns
FieldSize() returns a numeric value that corresponds to the field length of a valid field number.
Description
Use FieldSize() to determine the length (or size) of data field of desired data types. This determines the window width needed for output to appear without a line break, or the length needed for an input to automatically fit in the database.
Notes

■ If there is an invalid data field number, the function returns

a value of 0.

Examples
Determine the total length of fields 3 to 5:

nLength  :=  0
FOR I = 3 TO 5
   nLength := nLength + FieldSize()
NEXT
Platforms
Available on MS-DOS
See also

FieldType()  | 

Determines the data type for a field
Syntax
FieldType(<nField>) → cType
Arguments
nField Designates the data field for which the data type is determined.
Returns
FieldType() returns a single character that designates the data type of the data field (assuming the data field number is valid). FieldType() returns the following characters for the various data field types:
Table 10-1: Coding for Data Field Types
    Character    Data Type
    C            Character string
    N            Numeric
    D            Date
    L            Logical
    M            MEMO
Description
FieldType() operates in a similar fashion to the CA-Clipper Type() function. With Type(), you must always know only the name of the data field. However, FieldType() requires that you only know the data field, not its name. Use the function to confirm data types for data fields when a program is working with different databases that have different field names.
Notes

■ If there are invalid data field numbers, the function returns

a null string.

Examples
Data type for field number 5:

IF FieldType(5) = "C"
   ? "Field No. 5 is a character field!"
ENDIF
Platforms
Available on MS-DOS
See also

FileAppend()Harbour implementation  | 

Appends data to a file
Syntax
FileAppend(<cSourceFile>, <cTargetFile>)
   → nAttachedByte
Arguments
cSourceFile Designates the file that is appended to cTargetFile.
cTargetFile Designates the file to which cSource is appended. Drive and path designation are permitted for both files, wildcards are not.
Returns
FileAppend() returns the number of characters appended on to cTargetFile.
Description

FileAppend() takes fragmented files, split them up on different floppies and reassemble them. This sort of fragmented file could be created with the FileCopy() system described in this chapter. You only need explicit information, such as VOLUME labels, to recognize the different disks. If the target file does not exist, it is created with FileAppend(). If an error occurs while appending to the target file, the file deletes completely to avoid accidental and incorrect results.

Never append data to file if there is no backup copy.

Notes

■ Use SetFCreate(), if FileAppend() creates a new file and an

alternative attribute needs to be specified.

■ Use SETSHARE() to protect a target file from access, if it is

on a network drive.

Examples
Shown below is a simplified program to reassemble a file that is divided
among several disks by a FileCopy() backup.

A catalog contains a list of the disks used during backup in the form of
volume labels and backup file names.

Structure of the DISKLIST catalog:

Table 7-10: DISKLIST File Structure
<table>
    Field Name     Field Content

    VolLabel       Back up disk drive and volume label
    BackupName     Back up file name, incl. drive and path
   </table>

The data in DISKLIST is created by a FileCopy() backup:

USE DISKLIST                                 // Saved volume labels
cTargetFile  :=  "C:\TARGET.TXT"
DO WHILE .NOT. Eof()
   IF .NOT. Empty(FileSeek(cVolLabel, 8)     // Correct disk ?
      FileAppend(cBackupName, cTargetFile)   // Yes, append data
      SKIP
   ELSE
      ? "Please insert the correct disk  !"
   ENDIF
ENDDO
Platforms
Available on MS-DOS
See also

FileAttr()Harbour implementation  | 

Determines a file's attributes
Syntax
FileAttr([<cFile>]) → nFileAttr
Arguments
cFile Designates the file name, including the path and drive designation.
Returns
FileAttr() returns the attributes for the researched entry or the attribute from the FileSeek() buffer (when called without a parameter).
Description

FileAttr() is implemented alone or in conjunction with FileSeek(). If the function is called with the cFile parameter, it returns the attribute of the first entry found. If no acceptable entry is available, a value of 0 is returned.

When called without a parameter, FileAttr() returns the attribute for the most-recent file located with FileSeek(). When used with FileSeek(), you can determine the attribute for file groups (wildcards).

When you call FileAttr() with the cFile parameter, the function internally passes 63 (all attributes) as a mask. When used in conjunction with FileSeek(), you should also designate all 63 as an attribute mask, if all files are to be acknowledged.

Table 7-11: Coding the File Attribute

    Value   Symb. constants     Assigned attribute
    0       FA_NORMAL
    1       FA_READONLY         READ ONLY (Read-only)
    2       FA_HIDDEN           HIDDEN (Hidden files)
    4       FA_SYSTEM           SYSTEM (System files)
    8       FA_VOLUME           VOLUME (Name of a floppy/hard disk)
    16      FA_DIRECTORY        DIR (Directory)
    32      FA_ARCHIVE          ARCHIVE (Changes since last backup)

If multiple attributes are implemented for a file, the value of each corresponding attribute is added.

Examples
■  Show the attribute of a specific file:

   ? FileAttr("C:\TEXT\TEXT.TXT")      // 32  ARCHIVE

■  The attribute for an ARCHIVE/HIDDEN file:

   ? FileAttr("C\HIDE.TXT")            // 34  HIDDEN + ARCHIVE

■  Used in conjunction with FileSeek():

   cFile  :=  FileSeek("C:\TEXT\TEXT.TXT")
   DO WHILE .NOT. EMPTY (cFile)
      ? cFile, FileAttr()              // Name & file attribute
      cFile  :=  FileSeek()            // Search for next entry
   ENDDO
Platforms
Available on MS-DOS
See also

FileCCLose()Harbour implementation  | 

Closes a file after backup mode
Syntax
FileCCLose() → lClosed
Returns
FileCCLose() returns .T., when the the file that was opened with FileCopy() is successfully closed.
Description
FILE COPY CLOSE After you copy on multiple disks, this function should be routinely called. This is to prevent the source file, previously designed with FileCopy(), from remaining open. For example, this may occur if you terminate the copy procedure.
Notes

■ Regardless of the share mode, all other users are not allowed

access. This situation stays this way without needing a file handle.

Examples
Show a back up with FileCopy().  After terminating, close the source
file:

FileCopy(cSource, cTarget, .T.)      // Back up mode
DO NEXTDISK                          // When terminated   Terminated =
.T.
DO WHILE FileCOpen() .AND. .NOT. Terminated
   FileCCont(cTarget)                // Next disk, new name
   DO NEXTDISK                       // Request for disk exchange
ENDDO
IF Terminated
   FileCCLose()                      // Close source file!
ENDIF
Platforms
Available on MS-DOS
See also

FileCCont()Harbour implementation  | 

Copies sections of a file in backup mode
Syntax
FileCCont(<cFile>) → nCopyByte
Arguments
cFile Designates the file name for the target file.
Returns
FileCCont() returns the number of bytes copied.
Description
FILE COPY CONTINUE Use this function primarily after a FileCopy(). As much as possible of the remaining data is written to a new disk. If the remaining data still does not fit on the designated target disk, call this function repeatedly until it writes all the remaining data. Each time you call FileCCont(), a new name can be designated for the target file. These files are then numbered consecutively (see Examples).
Notes

■ If a copy procedure on multiple disks terminates for any

reason, call FileCCLose().

■ Use SetFCreate() to designate an attribute to form a new file.

■ The function acknowledges the CSetSafety() implementation, as

does FileCopy()

Examples
Show a back up with FileCopy().  After terminating, close the source
file:

FileCopy(cSource, cTarget, .T.)   // Back up mode
DO NEXTDISK                       // When terminated  Terminated = .T.
DO WHILE FileCOpen() .AND. .NOT. Terminated
   FileCCont(cTarget)             // Next disk, new name
   DO NEXTDISK                    // Request for disk exchange
ENDDO
IF Terminated
   FileCCLose()                   // Close source file!
ENDIF
Platforms
Available on MS-DOS
See also

FileCDaTi()Harbour implementation  | 

Determines whether a source file's date and time stamp or the system's date and time stamp, should be used to create or copy a file. Use original or
Syntax
FileCDaTi([<lNewMode>]) → lOldMode
Arguments
lNewMode Designates the new status for FileCDaTi(). When .T. is designated, the target file contains the source file date; when it is .F., the system date. The default is the source file date (.T.).
Returns
If no parameter is designated, FileCDaTi() returns the current setting for FileCDaTi(); otherwise, it returns the previous setting.
Description
FILE COPY DATE TIME FileCDaTi() determines which date the target file contains with a FileCopy(). When you partition to several disks in backup mode, this concerns all target files. The CA-Clipper Tools default is .T., where the target file contains the date and time of the source file. If you call FileCDaTi() with the parameter designated .F., then the target file contains the system date and time.
Notes

■ Use this function before FileCopy().

■ If the target file contains a unique setting such as a pseudo

serialization, use the SetFDaTi() function.

Examples
■  Query the FileCDaTi() setting:

   ? FileCDaTi()            // The current setting

■  The target file is to contain the system date and time:

   ? FileCDaTi(.F.)         // Returns the previous setting
Platforms
Available on MS-DOS
See also

FileCopy()Harbour implementation  | 

Copies files normally or in backup mode
Syntax
FileCopy(<cSourceFile>, <cTargetFile>, [<lMode>])
   → nCopyByte
Arguments
cSourceFile Designates the source file. Drive and path designations are permitted, but not wildcards.
cTargetFile Designates the target file. Drive and path designations are permitted, but not wildcards.
lMode Designates the backup mode on when designated as .T. The default is no backup mode (.F.).
Returns
FileCopy() returns the number of bytes copied.
Description
This function has additional uses besides allowing you to quickly copy files. When you use the optional lMode parameter, a unique backup mode is switched on. This allows files that are larger than the target disks to be copied. This function writes the maximum possible number of bytes to a disk. FileCOpen() allows you to determine whether all data from the source file has been copied. It then continues with the next disk. The target disks should contain unique labels and be saved to a catalog.
Notes

■ The attribute to be used when newly creating a file can be

specified with SETCREATE().

■ As a minimum, the share mode recommends that you do not write

other program source and target files.

■ This function acknowledges the CSetSafety() setting, and as a

result, cannot overwrite a target file.

Examples
■  Show a simple copy:

   ? FileCopy("A:\TEXT.TXT", "C:\TEST.TXT")      // Bytes copied

■  A back up using FileCopy():

   nCounter  :=  1                               // "BIG.001" etc.
   cTargetFile  := "BIG" + NToC(nCounter, 10, 3, "0")
   FileCopy("BIG.DBF", "A:\" + cTargetFile, .T.)
                                                 // Back up mode
   DO WHILE FileCOpen()
      DO NEXTDISK                                // Request disk change
      nCounter     := nCounter + 1
      cTargetFile  := "BIG" + NToC(nCounter, 10, 3, "0")
      FileCCont(cTargetFile)                     // Next disk - new name
   ENDDO
   RETURN

   PROCEDURE NEXTDISK
      ? "Please insert new diskette in Drive A:!"
      WAIT
      RETURN
Platforms
Available on MS-DOS
See also

FileCOpen()Harbour implementation  | 

Tests to see if the file is still open in the backup mode
Syntax
FileCOpen() → lOpenFile
Returns
FileCOpen() returns .T. when all data is not copied during a FileCopy() or FileCCont().
Description
FILE COPY OPEN FileCOpen() determines whether all data is copied. This concerns the source file, which is specified when the FileCopy() function is called. FileCOpen() returns .T. until all the data in the source file is read, whether by FILECOPY or the follow-on function FileCCont()
Notes

■ If you must abort the copy process, and FileCOpen() continues

to returns .T., use FileCCLose().

Examples
Show a back up with FileCopy():

nCounter   := 1                   // "BIG.001" etc.
cTargetFile   := "BIG" + NToC(nCounter, 10, 3, "0")
FileCopy("BIG.DBF", "A:\" + cTargetFile, .T.)
                                  // Back up mode
DO WHILE FileCOpen()
   DO NEXTDISK                    // Request disk change
   nCounter     := nCounter + 1
   cTargetFile  := "BIG" + NToC(nCounter, 10, 3, "0")
   FileCCont(cTargetFile)         // Next disk - new name

ENDDO
FILECCLOSE                        // For safety
Platforms
Available on MS-DOS
See also

FileDate()Harbour implementation  | 

Determines the file date
Syntax
FileDate([<cFileMap>, [<nFileAttr>]]) → dFileDate
Arguments
cFileMap Designates a file name, including its path and drive designation.
nFileAttr Designates the file attribute explained in the table below. The default value is 0.
() If you call this function without parameters, it returns the file date from the current FileSeek() buffer.
Returns
FileDate() returns the date of the searched for entry, the date from the FileSeek() buffer (when called without parameters), or an empty date.
Description

You can implement FileDate() alone or in conjunction with FileSeek(). If you use the cFileMap parameter to call this function, it returns the date of the first entry found. If a suitable entry is not present, an empty date is returned.

When called without parameters, FileDate() returns the date of the last file it located with FileSeek(). You could also determine the dates for a file group (wildcards), when used it in conjunction with FileSeek().

The attribute for the desired file can be specified in numeric form:

Table 7-12: Coding the File Attribute

    Value   Symb. constants     Assigned attribute
    0       FA_NORMAL
    1       FA_READONLY         READ ONLY (Read-only)
    2       FA_HIDDEN           HIDDEN (Hidden files)
    4       FA_SYSTEM           SYSTEM (System files)
    16      FA_DIRECTORY        DIR (Directory)
    32      FA_ARCHIVE          ARCHIVE (Changes since last backup)

To find a file, specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes. If multiple attributes are implemented simultaneously, the table values are added accordingly. Of course, not all combinations are useful.

Examples
■  Show the date of a particular file:

   ? FileDate("C:\TEXT\TEXT.TXT")     // The date

■  The date of an ARCHIVE/HIDDEN file:

   ? FileDate("C:\HIDE.TXT", 34)      // The date

■  Used in conjunction with FileSeek():

   cFile  :=  FileSeek("C:\TEXT\*.TXT")
   DO WHILE .NOT. Empty(cFile)
      ? cFile, FileDate()             // Name & date of file
      cFile  :=  FileSeek()           // Search for next entry
   ENDDO
Platforms
Available on MS-DOS
See also

FileDelete()Harbour implementation  | 

Deletes file(s) by name and attribute
Syntax
FileDelete(<cFileMask>, [<nFileAttr>]) → lDeleted
Arguments
cFileMask Designates the file or files to delete.
nFileAttr Designates one of the following file attributes. The default value is 32.
Table 7-13: File Attribute Coding
    Value     Symb. constants   Definition
    0         FA_NORMAL
    1         FA_READONLY       Read-only
    2         FA_HIDDEN         HIDDEN (Concealed files)
    4         FA_SYSTEM         SYSTEM (System files)
    8         FA_VOLUME         VOLUME (Name of floppy/hard disk)
    32        FA_ARCHIVE        ARCHIVE (Changed since last backup)
Returns
FileDelete() returns .T. when at least one or more files are deleted; otherwise, .F. is returned.
Description
Occasionally, you will need to clean up a floppy or a hard disk or delete whole file groups. This function deletes entire file groups with a function call, without using the RUN command.
Notes

Warning! FileDelete() can also delete system files.

■ The default standard attribute is archive (32). Drive and

path designations, and wildcards are permitted.

■ Subdirectories must be deleted with the help of the

DirRemove() function.

Examples
Attempt to delete all index files, then display the completion status:

IF FileDelete("*.NDX")
   ? "Files deleted."
ELSE
   ? "No files found."
ENDIF
Platforms
Available on MS-DOS
See also

FileMove()Harbour implementation  | 

Moves files to another directory
Syntax
FileMove(<cSourceFile>, <cTargetFile>) → nErrorCode
Arguments
cSourceFile Designates the name and the path of the source file.
cTargetFile Designates the name and the path of the target file.
Returns
FileMove() returns a value of 0 when the file can be moved; otherwise, an error code is returned. The codes are defined below:
Table 7-14: FileMove() Error Codes
    Code    Symb. constants        Definition
     0      NO_DISK_ERR            No errors
    -2      ER_FILE_NOT_FOUND      File not found
    -3      ER_PATH_NOT_FOUND      Access path not found
    -5      ER_ACCESS_DENIED       Access denied (e.g., network)
    -17     ER_DIFFERENT_DEVICE    Target file not on same drive
Description
If a file is to be copied within a drive and then deleted it from the original position, it is quicker to move the file. FileMove() makes this possible. The directory entries are also changed, which is much quicker than copying and deleting.
Notes

■ You can use drive designators and access paths in

cSourceFile and cTargetFile file names. Wildcards are not permitted.

■ You can only move a file within a drive. If the target

directory already contains a file with the same name as the one from cSourceFile, the move is not completed. In this case, FileMove() returns a value of -5. The only option available in this situation, is to delete the file in the target directory.

Examples
Move a file from "\OLD" to "\NEW":

IF FileMove("\OLD\CUST.DBF", "\NEW\CUST.DBF") = 0
   ? "The file is now in the \NEW directory"
ENDIF
Platforms
Available on MS-DOS
See also

FileScreen()Harbour implementation  | 

Reads screen content from a file
Syntax
FileScreen(<cFileName>, [<nOffset>]) → nByte
Arguments
cFileName Designates the name and path of the screen file.
nOffset Designates from which part of the file offset the screen is to be read. The default is the beginning of file.
Returns
FileScreen() returns the number of bytes read.
Description
FILESCREEEN() is the opposite of ScreenFile(). Use FileScreen() to read and display a screen stored with ScreenFile(). Use the nOffSet parameter to indicate an offset from which the file is to be read. Since the number of bytes written with ScreenFile() is known, you can compute the location within the file of the beginning of the new screen. This allows you to save multiple screens in a single file.
Notes

■ The file read with FileScreen() can also contain end of file

markers. The read procedure does not end prematurely as a result, since the function always reads 4000 bytes.

Examples
■  Read a screen from the beginning of a file:

   FileScreen("screen.tst")

■  Read the second screen.  Since the offset is specified as
   4000, the first screen is skipped:

   FileScreen("screen.tst", 4000)

■  Drive and path are permitted:

   FileScreen("\screen.tst")
   FileScreen("a:screen.tst")

■  Wildcards are not permitted:

   FileScreen("screen.*")         // Result:  0
Platforms
Available on MS-DOS
See also

FileSeek()Harbour implementation  | 

Searches for files by name and attribute
Syntax
FileSeek([<cFileMap>, [<nFileAttr>], [<lExact>]])
    → cFileName
Arguments
cFileMap Designates a file name including its path and drive designation. It may contain wildcards.
nFileAttr Designates the file attribute that corresponds to the ones described in the table on the next page. The default value is 0.
lExact If you designate .T. as the optional parameter, FileSeek() also checks for the exact agreement of the file attributes of the respective file with the value passed by nFileAttr.
() If you call the function without parameters, it serves as a sequential call for a FileSeek() with file specifications, and returns sequential entries as long as these are found.
Returns
FileSeek() returns the name of the first or next entry (when called without parameter) located in the selected directory.
Description

FileSeek() provides the foundation for a variety of functions. As a group, they permit access to desired information about directory entries. Implement the FileSeek() function when you want information about a file group (wildcards). When you call it with the cFileMap parameter, it searches for the first entry in the designated directory. If you call it without parameters, it searches for the next matching entry in the directory. If no more entries are present, it returns a null string. An attribute mask can further define a file group that is being searched for. The desired file attributes are coded as follows:

Table 7-15: Coding the File Attribute

    Value   Symb. constants     Assigned attribute
    0       FA_NORMAL
    1       FA_READONLY         READ ONLY (Read-only)
    2       FA_HIDDEN           HIDDEN (Hidden files)
    4       FA_SYSTEM           SYSTEM (System files)
    8       FA_VOLUME           VOLUME (Name of a floppy/hard disk)
    16      FA_DIRECTORY        DIR (Directory)
    32      FA_ARCHIVE          ARCHIVE (Changes since last backup)

If you implement multiple attributes simultaneously, the table values are added accordingly. Of course, not all combinations are useful.

Exact File Attributes

DOS does not make an exact comparison with a designated attribute mask and attributes actually found in a file. Specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes for an entry to be found. Files with only one other attribute bit set are always returned, regardless of the value specified in the attribute mask. This way, a function call with a mask value of 16 returns not only subdirectories, but all files without a set attribute (e.g., all the ARCHIVE and R/O files).

To avoid this, you can designate .T. as the third parameter. The function itself also reviews the designated attribute mask with the actual file attributes, for an exact agreement. Then, the designation of a 16 mask and .T., only returns subdirectories.

Internal Data Buffer

Every time you use FileSeek() all the data for a directory entry is saved to an internal buffer. Individual information such as size, time, or date is easily accessible. To do this, the FileTime(), FileDate(), etc., functions are called without parameters; otherwise, it requires another call to the disk, instead of taking the data from an internal buffer.

Notes

■ Use the recursive sample function SCANFILES() in the

accompanying Tooldemo.prg file, to produce the most effective programs to work with entire directory structures.

■ Display the date and size of all files with the extension .TXT

in a directory:

cFile := FileSeek("C:\TEXT*.TXT") DO WHILE .NOT. Empty(cFile)

? FileSize() // Size of file in buffer ? FileDate() // Date of file in buffer cFile := FileSeek() // Search for next entry

ENDDO

■ Display system files in the root directory. Attribute: READ

ONLY, HIDDEN, SYSTEM, ARCHIVE → 39, although 6(2 + 4) will suffice as an attribute:

cFile := FileSeek("C:*.*", 39) DO WHILE .NOT. Empty(cFile)

? cFile // File name cFile := FileSeek() // Look for next entry

ENDDO

■ Only query the subdirectory:

cSubDir := FileSeek("C:*.*, 16, .T.) DO WHILE .NOT. Empty(cSubDir)

? cSubDir // Name of the directory cSubDir := FileSeek() // Search for next directory

ENDDO

Platforms
Available on MS-DOS
See also

FileSize()Harbour implementation  | 

Determines the size of a file
Syntax
FileSize([<cFileMap>, [<FileAttr>]]) → nFileSize
Arguments
cFileMap Designates the file name, path, and drive designation.
FileAttr Designates the file attribute that is explained in the table below. The default value is 0.
() If the function is called without parameters, it returns the file size from the current FileSeek() buffer.
Returns
FileSize() returns the designated file's size, the size from the FileSeek() buffer (when called without a parameter), or -1.
Description

Implement FileSize() alone or in conjunction with FileSeek(). If the function is called with the cFileMap parameter, it returns the size of the first entry found. If no matching entry is available, then a value of -1 is returned

When called without parameters, FileSize() returns the size of the most recent file found with FileSeek(). Used in conjunction with FileSeek(), you can also determine the size of file groups (wildcards).

You can designate the attribute for the desired file in numeric form:

Table 7-16: Coding the File Attribute

    Value   Symb. constants     Assigned attribute
    0       FA_NORMAL
    1       FA_READONLY         READ ONLY (Read-only)
    2       FA_HIDDEN           HIDDEN (Hidden files)
    4       FA_SYSTEM           SYSTEM (System files)
    32      FA_ARCHIVE          ARCHIVE (Changes since last backup.)

Specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes for an entry to be found. If multiple attributes are implemented simul-taneously, the table values are added accordingly. Of course, not all combinations are useful.

Examples
■  Show the size of a particular file:

   ? FileSize("C:\TEXT\TEXT.TXT")      // File size or -1

■  The size of an ARCHIVE/HIDDEN file:

   ? FileSize("C:\HIDE.TXT", 34")      // File size or -1

■  Used in conjunction with FileSeek():

   cFile  :=  FileSeek(C:\TEXT.TXT")
   DO WHILE .NOT. Empty(cFile)
      ? cFile, FileSize()              // File name and size
      cFile  := FileSeek()             // Search for next entry
   ENDDO
Platforms
Available on MS-DOS
See also

FileSMax()Harbour implementation  | 

Specifies the maximum number of files that can be open at one time
Syntax
FileSMax() → nMaxHandles
Returns
FileSMax() returns the maximum number of files that can be open at once.
Description
The value set for FILES= within the CONFIG.SYS, and the number of available handles, influences the maximum number of files that can be open simultaneously. The maximum number is determined by the smaller of the two values respectively.
Notes

■ The returned value is subtracted from the handles already

occupied by the operating system. This value is usually 5.

■ This function cannot determine if an additional operating

system adaptation (Novell's SHELL.CFG) has been made under a Novell network. These adaptations are only used for the current network drive under Novell.

Examples
How many files can be opened in the system?

? FileSMax()            // e.g. 100
Platforms
Available on MS-DOS
See also

FileStr()Harbour implementation  | 

Reads a portion of a file into a string
Syntax
FileStr(<cFile>, [<nLength>], [<nOffset>],
   [<lCtrl-Z>]) → cCharacterstring
Arguments
cFile Designates the file from which a string is read.
nLength Designates how many characters you want to read from a file (up to a maximum of 65520 bytes). The default is read all characters.
nOffset Designates an offset within the file from which the nLength characters or the rest of the file, are read. The default is from the first character (0).
lCtrl-Z If this parameter is designated as .T., only data up to the first Ctrl-Z is read in. The default is read all data (.F.).
Returns
FileStr() returns the string read in from the designated file.
Description

FileStr() also offers the capability to read files or a portion of them, into a string. This is only possible with a function call, where the file name may contain a drive and path designation. If you implement the lCtrl-Z parameter, you can be sure the function only reads data up to the first Ctrl-Z and ignores whatever might remains in of the file.

In contrast to the CA-Clipper Fxxxx() functions, a disadvantage of FileStr() is a slower access speed, since the file you want to read cannot be held open.

Notes

■ This function reads all available bytes in working memory (up

to 65520). The amount of available free memory is determined by calling Memory(1).

■ As recommended in share mode, no other programs should write

in the net through SETSHARE(2) for the duration of the read.

Examples
■  Read in a file completely:

   ? FileStr("C:\TEXT\TEST.TXT")            // Displays file text

■  Read in everything to the first Ctrl-Z:

   cVar  := FileStr("C:\TEXT\TEST.TXT", .T.)

■  The file TEST.TXT contains "ABCDEFGHIJ".  Four characters,
   beginning from position 3, are to be read:

   ? FileStr("C:\TEXT\TEST.TXT", 4, 3)      // "CDEF"

■  Read the maximum that fits into the available working memory:

   cVar  := FileStr("C:\TEXT\TEST.TXT", Memory(1) *1024 -100)
Platforms
Available on MS-DOS
See also

FileTime()Harbour implementation  | 

Determines a file's time
Syntax
FileTime([<cFileMap>, [<nFileAttr>]]) → cFileClockTime
Arguments
cFileMap Designates the file name, including the path and drive designation.
nFileAttr Designates the file attribute explained in the table below. The default value is 0.
() If the function is called without parameters, it returns the file time from the current FileSeek() buffer.
Returns
FileTime() returns the clock time for the "searched for" entry, the clock time from the FileSeek() buffer (when called without parameters), or a null string.
Description

Implement FileTime() alone or in conjunction with FileSeek(). If the function is called with the cFileMap parameter, it returns the time of the first entry found. If no matching entry is available, a null string is returned.

When called without parameters, FileTime() returns the clock time of the last file found with FileSeek(). You can also determine the clock time of file groups (wildcards) when the function is used in conjunction with FileSeek().

You can designate the attribute for the desired file in numeric form:

Table 7-17: Coding the File Attribute

    Value   Symb. constants     Assigned attribute
    0       FA_NORMAL
    1       FA_READONLY         READ ONLY (Read-only)
    2       FA_HIDDEN           HIDDEN (Hidden files)
    4       FA_SYSTEM           SYSTEM (System files)
    16      FA_DIRECTORY        (Subdirectory)
    32      FA_ARCHIVE          ARCHIVE (Changes since last backup)

Only the SYSTEM, HIDDEN, VOLUME, or DIR attributes must be specified for an entry to be found. If multiple attributes are implemented simultaneously, the table values are added accordingly. Of course, not all combinations are useful.

Examples
■  The clock time of a particular file:

   ? FileTime("C:\TEXT\TEXT.TXT")      // File clock time or ""

■  The clock time of an ARCHIVE/HIDDEN file:

   ? FileTime("C:\HIDE.TXT", 34")      // File clock time or ""

■  Used in conjunction with FileSeek():

   cFile  :=  FileSeek(C:\TEXT.TXT")
   DO WHILE .NOT. Empty(cFile)
      ? cFile, FileTime()              // File name and clock time
      cFile  := FileSeek()             // Search for next entry
   ENDDO
Platforms
Available on MS-DOS
See also

FILECHECK()  | 

Calculates/computes/determines a checksum for a file
Syntax
FILECHECK(<cFile>) → nCheckSum
Arguments
cFile Designates which file name (with path, if required), to check.
Returns
FILECHECK() returns a checksum value for cFile.
Description
FILECHECK() determines if there have been changes or read errors in a file, and then takes note of data backup. This also allows you to protect your hard disk from simple viruses (see Examples).
Notes

■ You must specify the argument. If it is omitted or an

unavailable file is specified, FILECHECK() returns an error code of - 1. You may use a drive and access path, but no wildcards.

Examples
■  Check database for changes:

   IF FILECHECK("CUST.DBF") <> Old_ChkSum
      ? "Warning! Data back-up required."
   ENDIF

■  Check COMMAND.COM for changes:

   IF FILECHECK("\COMMAND.COM") <> Cmd_ChkSum
      ? "COMMAND.COM has been changed! Caution, Virus!"
   ENDIF
Platforms
Available on MS-DOS
See also

FILESFREE()  | 

Specifies the number of files you can open
Syntax
FILESFREE() → nFreeHandles
Returns
FILESFREE() returns the number of available handles.
Description
This function returns the number of available handles that correspond to the number of files you can open. This enables you to avoid DOS error 4.
Notes

■ Immediately after you start a CA-Clipper application, a value

— smaller than that of FileSMax() — is returned. This happens because the operating system and application itself is already using handles.

Examples
■  Can I still open a file?

   IF FILESFREE() > 0                // At least 1 handle free?
      USE CUSTOMER                   // Open a file
   ENDIF

■  Be careful when you open multiple indexes at the same time!

   IF FILESFREE() > 1                // At least 2 handles free?
      USE CUSTOMER INDEX CUSTNR      // Open 2 files
   ENDIF
Platforms
Available on MS-DOS
See also

FILEVALID()  | 

Tests whether a string has a valid file name
Syntax
FILEVALID(<cFileName>) → lValid
Arguments
cFileName Designates the file name you want to test for validity.
Returns
FILEVALID() returns .T. when the designated name is valid.
Description
FILEVALID() determines if a string contains a valid file name. You could also test the validity of user input in this way. If necessary, path and drive designations must be removed from the string. The tokenizer described in the string chapter is available for this purpose (see Examples).
Examples
The last token in a string with drive and path designations should
contain the file name:

ACCEPT "Target_File  " TO cVar
cFileName  := TOKEN(cVar, " \:")        // Last token
DO WHILE .NOT. FILEVALID(cFileName)
   * Error message ...
   ACCEPT "Target_File  " TO cVar
   cFileName  := TOKEN(cVar, "\:")      // Last token
ENDDO
Platforms
Available on MS-DOS
See also

FIRSTCOL()  | 

Sets the first visible column of a virtual screen
Syntax
FIRSTCOL(<nFirstNewColumn>) → nFirstOldColumn
Arguments
nFirstNewColumn Designates which column is the first visible column on the left side of a virtual screen.
Returns
If the parameter is passed, the function returns the previous setting. If no parameter is passed, it returns the current setting.
Description
This function is important for use in setting virtual screen size in conjunction with SETMAXROW() and SETMAXCOL(). You can select the first column that you would like to be visible on the left side of the screen. In this way the screen can be moved in any direction.
Notes

■ To simplify programming, values outside of the permissible

range are automatically corrected to the maximum or minimum values (see example).

Examples
The following example sets up a screen with 100 lines and 120 columns.
To help you with screen orientation, the current column number is
displayed at three locations on this virtual screen.  The virtual screen
can be moved in any direction using cursor keys and PgUp and PgDn:

SETMAXROW( 99)                        // screen with 100 lines
SETMAXCOL(119)                        // and 120 columns
CLEAR

FOR nCount = 0 TO MaxRow()            // Build screen
   @ nCount, 0 SAY "Line" + NToC(nCount, 10, 4)
   @ nCount, MaxCol()/2 -5 SAY "Line" + NToC(nCount, 10, 4)
   @ nCount, MaxCol()  -10 SAY "Line" + NToC(nCount, 10, 4)

NEXT nCount

@ 99, 00 SAY Center("This is the last line")

nKeyVal  := 0
DO WHILE nKeyVal <> 27
   nKeyVal  := Inkey(0)
   DO CASE
   CASE nKeyVal = 5
      FIRSTROW(FIRSTROW() -1)
   CASE nKeyVal = 24
      FIRSTROW(FIRSTROW() +1)
   CASE nKeyVal = 4
      FIRSTCOL(FIRSTCOL() +1)
   CASE nKeyVal = 19
      FIRSTCOL(FIRSTCOL() -1)
   CASE nKeyVal = 18
      FIRSTROW(FIRSTROW() -10)
   CASE nKeyVal = 3
      FIRSTROW(FIRSTROW() +10)
   ENDCASE
ENDDO

FIRSTROW(0)                           // reset
FIRSTCOL(0)
SETMAXCOL(79)
SETMAXROW(24)
CLEAR
Platforms
Available on MS-DOS
See also

FIRSTROW()  | 

Sets the first visible line of a virtual screen
Syntax
FIRSTROW(<nFirstNewLine>) → nFirstOldLine
Arguments
nFirstNewLine Designates which line is displayed as the top line on the virtual screen.
Returns
If the parameter is passed, the function returns the previous setting each time. If no parameter is passed, it returns the current setting.
Description
This function is important for use in setting virtual screen size in conjunction with SETMAXROW() and SETMAXCOL(). You can select the first line that you would like to have visible at the top side of the screen. In this way the screen can be moved in any direction.
Notes

■ To simplify programming, values outside of the permissible

range are automatically corrected to the maximum or minimum values (see example).

Examples
The following example sets up a screen with 100 lines and 120 columns.
To help you with screen orientation, the current column number is
displayed at three locations on this virtual screen. The virtual screen
can be moved in any direction using cursor keys and PgUp and PgDn:

SETMAXROW( 99)                        // screen with 100 lines
SETMAXCOL(119)                        // and 120 columns
CLEAR

FOR nCount = 0 TO MaxRow()            // Build screen
   @ nCount, 0 SAY "Line" + NToC(nCount, 10, 4)
   @ nCount, MaxCol()/2 -5 SAY "Line" + NToC(nCount, 10, 4)
   @ nCount, MaxCol()  -10 SAY "Line" + NToC(nCount, 10, 4)
NEXT nCount

@@ 99, 00 SAY Center("This is the last line")

nKeyVal  := 0
DO WHILE nKeyVal <> 27
   nKeyVal  := Inkey(0)
   DO CASE
   CASE nKeyVal = 5
   FIRSTROW(FIRSTROW() -1)
   CASE nKeyVal = 24
      FIRSTROW(FIRSTROW() +1)
   CASE nKeyVal = 4
      FIRSTCOL(FIRSTCOL() +1)
   CASE nKeyVal = 19
      FIRSTCOL(FIRSTCOL() -1)
   CASE nKeyVal = 18
      FIRSTROW(FIRSTROW() -10)
   CASE nKeyVal = 3
      FIRSTROW(FIRSTROW() +10)
   ENDCASE
ENDDO

FIRSTROW(0)                           // reset
FIRSTCOL(0)
SETMAXCOL(79)
SETMAXROW(24)
CLEAR
Platforms
Available on MS-DOS
See also

Floor()Harbour implementation  | 

Rounds down to the next integer
Syntax
Floor(<nValue>) → nSmallerInteger
Arguments
nValue Designates the number for which the next-smaller integer is determined.
Returns
Floor() returns the next-smaller integer of the one passed as a parameter.
Description
Floor() always returns the next-smaller integer of the one passed as a parameter. This applies to positive and negative numbers.
Examples
Show the next-smaller integer for positive and negative numbers:

? Floor(1.9)       // Result:  1
? Floor(1.1)       // Result:  1
? Floor(0.9)       // Result:  0
? Floor(-0.1)      // Result: -1
? Floor(-0.9)      // Result: -1
? Floor(-1.1)      // Result: -2
Platforms
Available on MS-DOS
See also

FLOPPYTYPE()  | 

Determines the exact type of floppy drive
Syntax
FLOPPYTYPE([<cDrive>]) → nFloppyType
Arguments
cDrive Designates the drive (A, B, C, etc.) for which you want a type determined. The default is the current disk drive.
Returns
The function returns the exact type of the designated disk drive, coded as follows:
Table 7-18: Coding of Drive Types
    Code    Definition
     0      No floppy drive
     1      360-kB drive
     2      1.2-MB drive
     3      720-kB drive
     4      1.44-MB drive
Description
This function gives you a numeric value that specifies exact type and capacity of the selected floppy drive. Whether or not the device is a floppy drive, is determined beforehand by DriveType().
Notes

■ The drive type is determined without actually accessing the

drive. Therefore, a disk does not have to be in the drive.

Examples
Is the current disk drive a floppy and what type?

IF DriveType() = 1 .OR. DriveType() = 2
   DO CASE
   CASE FLOPPYTYPE() = 0
   ? "No floppy drive!"
   CASE FLOPPYTYPE() = 1
   ? "360 kB drive"
   CASE FLOPPYTYPE() = 2
   ? "1.2 MB drive"
   CASE FLOPPYTYPE() = 3
   ? "720 kB drive"
   CASE FLOPPYTYPE() = 4
   ? "1.44 MB drive"
   ENDCASE
ENDIF
Platforms
Available on MS-DOS
See also

FONTLOAD()  | 

Loads EGA/VGA fonts from another file
Syntax
FONTLOAD(<cFileName>, <nFontArea>, [<nOffset>],
   [<nCounter>]) → nErrorCode

or

FONTLOAD (<cFileName>, <nFontArea>,
   [<lOtherPixelHeight>])→ nErrorCode
Arguments
cFileName Designates the name and path of the font file.
nFontArea Designates the number of the specified font area. For EGA, the values 1 to 4 are allowed, or whatever values MAXFONT() permits. For VGA, the values 1 to 8 are allowed, or whatever MAXFONT() permits.
nOffset Designates from what character position the screen adapter font table is overwritten. The default value is 0.
nCounter Designates how many characters to load from the new font. The default value is 256.
lOtherPixelHeight Designates .T. to allow the function to modify the pixel height. This leads to a mode change and character count. Please note that you must designate both nOffset and nCounter to implement this parameter.
Returns
The function returns an error code which corresponds to the explanation below:
Table 6-1: Values returned for FONTLOAD()
    Error Code   Explanation
     0           Font loaded successfully
    -2           Impossible in current video mode
    -3           Font file not found
    -4           The <lOtherPixelHeight> mode is not possible (the Extended
                 Drivers are not linked in)
Description

FONTLOAD() allows you to load the font definitions from a file into the font area of an EGA or VGA card. Use FONTSELECT() to determine which fonts serve as normal and high density for output.

You may already have some of these fonts on the CA-Clipper Tools disk, and others can be created with the accompanying font editor.

Technical Background

The EGA and VGA cards permit you to modify a portion or all 256 characters of the character generator with software. To do this, a previously created pixel pattern for the character is loaded in the corresponding position in a font area on the screen card. Normally, an EGA card has a maximum of four font areas and a VGA has eight, within which you can redefine all 256 characters. Use MAXFONT() to determine the exact count of font areas.

Building fonts into a program requires unnecessary memory space. Constructing fonts as a string within a program is also awkward. With the GETFONT() and SetFont() functions, you can load a font from a screen card into a string variable, or from such a variable, into a font area on the card. However, FONTLOAD() only allows you to load a font from a file into a particular area of the screen card. In both cases, use ONTSELECT() to activate the loaded font.

On the CA-Clipper Tools sample disk, you will find a font editor to construct new fonts in CA-Clipper source code.

Variable Pixel Height

In principle, EGA and VGA screen adapters provide the opportunity to display fonts with 2 to 32 pixels per character (1 pixel/character only, when there are 200 scan lines). ROM fonts are only available for pixel heights of 8, 14 and 16, which accounts for the great expansion of the EGA 25-/43-line modes and VGA 25-/28-/50-line modes. You must construct individual fonts for all other pixel heights. The CA-Clipper font editor can make this easy.

When FONTLOAD() loads a font, it also computes the pixel height from the font data length. Since a font file always contains all 256 character definitions, there is a formula:

Pixel height = Len(Font-Data)/256

The lOtherPixelHeight parameter determines whether the fonts that do not match the pixel height just set are accepted. This must be explicitly indicated, since the line count and screen mode will change. For this reason, you must always link in the CTUS.LIB Extended Drivers (see Table 6-1, returned value -4).

Notes

■ You cannot use FONTRESET() when a font is loaded for which

there is no associated ROM font (all pixel heights except 8, 14, 16). Prior to a FONTRESET(), switch back to a permissible mode.

■ All previously successful FONTSELECT() settings are discarded

again during FONTLOAD().

■ If an EGA card does not span the entire memory range, then you

can reduce a maximum of four available font areas. MAXFONT() determines the number of available fonts.

Examples
■  Load all 256 characters of an EGA font in area 2:

   ? FONTLOAD("\FONTS\OLDENG.014", 2)              // 0 OK<
   FONTSELECT(2)

■  Exchange the fonts for the upper 128 characters in area 3:

   ? FONTLOAD("\FONTS\OLDENG.EGA", 3, 128, 128)    // 0 OK
   FONTSELECT(3)                                   // Select

■  Load a 24-pixel font in the last font area:

   ? FONTLOAD("\FONTS\PC.024", MAXFONT(), .T.)
Platforms
Available on MS-DOS
See also

FONTRESET()  | 

Resets all font and palette changes to the ROM defaults
Syntax
FONTRESET() → lReset
Returns
FONTRESET() returns .T. when all font and palette settings are reset.
Description

This function resets all the settings implemented with FONTLOAD(), SetFont(), and FONTSELECT(). Settings implemented with EGAPALETTE() or VGAPalette() are also reset. In addition, the border color set with SET COLOR TO is reset.

Table 6-2: Settings affected by FONTRESET()

    Settings                    Functions concerned
    All font information        FONTLOAD(), FONTSELECT, SetFont()
    All palette information.    EGAPALETTE(), VGAPalette()
    Border attribute            CA-Clipper:  SET COLOR TO

Notes

■ No ROM fonts exist for screen modes that are not based on 8,

14 or 16 pixels. You cannot implement FONTRESET() in this situation.

Examples
Reset all changes to fonts and palettes:

? FONTRESET()         // .T., if ok
Platforms
Available on MS-DOS
See also

FONTROTATE()  | 

Rotates and mirrors images within a font string
Syntax
FONTROTATE(<cFontstring>,<nTurnDirection>
   [<nPixelHeight>],[<nStart>]) → cNewFontString
Arguments
cFontstring[@] Designates the font in character string form, within which the characters are rotated or mirrored.
nTurnDirection Designates the rotation axis or rotation direction in numeric form with a value from 1 to 3 (see Description).
nPixelHeight Designates the accompanying pixel height and number of bytes that represent an individual character within a font string. This is only necessary for modes 1 and 3.
nStart (This is for only for mode 1.) Designates from which pixel line (from which byte), the 8 bytes are rotated. Based on nPixelHeight, the bytes before and after this range are deleted (set to 0). The first byte of the character corresponds to the 0 value.
Returns
If CSetRef() is not implemented, FONTROTATE() returns an amended font string.
Description

FONTROTATE() rotates the characters within a font string in different directions. Rotation direction affects the number of characters that can rotate.

Constructing Fonts

If a font is transferred to a string with GETFONT() and the same number of bytes are used for an individual character each time, as specified by the current font height from CharPix(). For example, if a 14-pixel font is installed, then the font string contains 256 groups of 14 bytes. Each of these bytes represents a horizontal pixel line. Since the characters are always 8 pixels wide, one bit always represents this pixel.

Direction of Rotation 1

If a font uses GETFONT() to transfer a string, then a comparable number of bytes are used each time for an individual character, as specified by the current font height in CharPix(). Since only an 8-pixel width is ever available, only 8 bytes are rotated for each character every time. To determine these bytes, you must designate the pixel height nPixelheight and the start of the 8-byte area

nStart . All bytes above and below the rotation are cleared (set to

0). The rotation point is determined by the computation nStart + 4.

Direction of Rotation 2

In this mode, the characters are rotated 180 degrees on the vertical axis (the Y-axis), and thereby mirrored. The nPixelheight and nStart parameters are unnecessary, since only the bits in each byte are mirrored.

Direction of Rotation 3

In this mode, the characters are rotated 180 degrees on the horizontal axis (X-axis), and thereby mirrored in the other direction. You must specify the nPixelheight parameter. The nStart parameter is not needed, since the character is affected through its entire height.

Combinations

Since modes 1 to 3 support all three rotation directions, multiple function calls allow you to combine the rotation operations and create rotated and mirrored characters.

Notes

■ The entire string is always worked on. If you only want to

change a region of characters on the screen, it can be done easily and is regulated by the SetFont() optional parameter, when you write the font back to the screen adapter.

■ If the parameter is passed by reference, use CSetRef() to

suppress the return value and increase the speed.

Examples
In the following example, the screen is first filled with characters and
then rotated.  This is particularly useful in the VGA 50-line mode,
since it has an 8 x 8 pixel matrix and none of the characters are cut
off.

All parameters for FONTROTATE() are designated in such a generalized
manner that you can use them for other pixel relationships.

CSetRef(.T.)                   // Optimize by reference method
nMODE  := GETSCRMODE()         // Save old mode
VGA50()
FOR I := 0 TO MaxRow()         // Build screen
   @ I, 0 SAY Center("ABCDEFGHIJKLMNOPQRSTUVWXYZ- 1234567890")
NEXT I
nPixel  :=  CharPix()          // Determine font pixel count
cFont   :=  GETFONT()          // Load font to variable
nKey      :=  0
DO WHILE Key <<>> 27
   Millisec(100)               // Time delay
   FONTROTATE(@cFont, 1, nPixel, (nPixel-8)/2)
   SetFont(cFont)
   nKey  :=  Inkey()
ENDDO
SETSCRMODE(nMODE)              // Reset to original mode
RETURN
Platforms
Available on MS-DOS
See also

FONTSELECT()  | 

Determines font areas for normal- and high-intensity output
Syntax
FONTSELECT(<nFontArea>, [<nIntensiveFontArea>])
    → nErrorCode
Arguments
nFontArea Designates which font area the normal output mode should use.
nIntensiveFontArea Designates which font area the higher- intensity output mode should use. The default is nFontArea.
Returns
FONTSELECT() returns an error code with the following meaning:
Table 6-3: Error code definitions
    Code    Definition
     0      Font loaded successfully
    -1      Invalid font area specified
    -2      Impossible in current video mode
Description
This function selects the font areas for both normal output and higher- intensity output. Use SET COLOR TO with "+", to bring up to 512 different characters to the screen at the same time. The second font is displayed at a higher intensity. If this is not what you want, you can change the display (not the attribute itself) with EGAPALETTE()/VGAPalette(). The system is preset for both output modes and corresponds to a call of FONTSELECT(1, 1).
Notes

■ After you change the video mode with SETSCRMODE(), the fonts

must be re-selected.

Examples
■  Show font area 1 with normal output and area 4 with high
   intensity:

   ? FONTSELECT(1, 4)      // 0  OK
   SET COLOR TO W
   ? "Nantucket"           // Output over font 1
   SET COLOR TO W+         // Output over font 4

■  Show font area 2 for both output modes:

   ? FONTSELECT(2)
Platforms
Available on MS-DOS
See also

FToC()Harbour implementation  | 

Converts a floating point number into a special 8-byte string
Syntax
FToC(<nFloatingPointNumber>) → cFloatingPointNumber
Arguments
nFloatingPointNumber Designate any CA-Clipper number.
Returns
FToC() returns an 8-byte character string.
Description
CA-Clipper internal numbers are displayed as 64-bit floating point numbers. FToC() returns these 64 bits as an 8-byte string. In this way, numbers can be locked and/or saved more compactly.
Notes

■ The XToC() function converts floating point numbers in the

same way.

Examples
It is not useful to display the return value on the screen:

NumberString  :=  FToC(274711.335)      // 8 byte string
Platforms
Available on MS-DOS
See also

FV()Harbour implementation  | 

Computes future value of capital
Syntax
FV(<nInstall>,<nInterestRate>,<nNumberofPayments>)
    → nCapital
Arguments
nInstall Designates the installment amount to pay for the period.
nInterestRate Designates the interest rate calculated for the payment period. 1 corresponds to 100%.
nNumberofPayments Designates the number of payments.
Returns
FV() returns the future capital value of the total deposits, plus the interest generated.
Description
FUTURE VALUE FV() returns the capital available after the nNumberofPayments total installments at nInstall payment, at an nInterestRate interest charge for the period.
Examples
What amount would you save, if you pay $150.00 per month for 3 years
into a fund that pays an annual interest rate of 6%?

nRate  :  0.06/12         // Monthly interest rate
? FV(150, nRate, 36)      // Result: 5900.42
Platforms
Available on MS-DOS
See also

GetClearA()Harbour implementation  | 

Queries the current attribute for the clearing functions
Syntax
GetClearA() → nClearAttribute
Returns
GetClearA() returns the value of the current standard attribute.
Description
GET CLEAR (A)ttribute This function determines the standard attribute for some CA-Clipper Tools functions with screen output. In this discussion, the attribute is referred to as CLEARA and the character as CLEARB. GetClearA() queries the current standard attribute.
Notes

■ The standard attribute is 7 (white on black), if no other

attribute is set with SetClearA().

Examples
Display the current standard attribute:

GetClearA()         // e.g. 7
Platforms
Available on MS-DOS
See also

GetClearB()Harbour implementation  | 

Queries the default character for the clearing functions
Syntax
GetClearB() → nClearCharacter
Returns
GetClearB() returns the value of the current standard character CLEARB.
Description
GET CLEAR (B)yte This function determines the standard character for some CA-Clipper Tools functions with screen output. In this discussion, the attribute is referred to as CLEARA and the character as CLEARB. GetClearB() queries the current standard character set as CLEARB.
Notes

■ The standard character is Chr(255) when no other character is

set with SetClearB().

Examples
Display the current standard character:

? GetClearB()         // e.g. 255
Platforms
Available on MS-DOS
See also

GetFldCol()Harbour implementation  | 

Determines the screen column of a GET field
Syntax
GetFldCol([<nField>]) → nColumn
Arguments
nField Designates the number of the GET field for which the screen column is determined. The default is the currently active field.
Returns
GetFldCol() returns the screen column for the first position of the currently active or the specified field. If there is an invalid parameter, a value of -1 is returned.
Description
GET FIELD COLUMN This function determines the first column of an input field. If the nField parameter is not specified, the function returns the column for the currently active field. With an invalid field number or in a situation where there is no active field, a value of -1 is returned.
Examples
■  Display the screen column for the second posted GET:

   @ 10, 10 GET....
   @ 10, 20 GET....
   @ 10, 30 GET.....

   ? GetFldCol(2)            // Result: 20

■  Display the column for the currently active GET field:

   READ                      // Assuming field 1 is active
   Within a UDF or KEYTRAP procedure:
   ? GetFldCol()             // Result: 10
Platforms
Available on MS-DOS
See also

GetFldRow()Harbour implementation  | 

Determines the row of a GET field on the screen
Syntax
GetFldRow([<nField>]) → nRow
Arguments
nField Designates the number of the GET field for which the screen is determined. The default is the currently active field.
Returns
GetFldRow() returns the screen row for the first position of the currently active or specified field. If there is an invalid parameter a value of -1 is returned.
Description
GET FIELD ROW This function determines the first row of an input field. If the nField parameter is not specified, the function returns the row for the currently active field. When nField is an invalid field number or if there are no active GET fields, a value of -1 is returned.
Examples
■  Display the row for the second posted GET:

   @ 10, 10 GET....
   @ 11, 20 GET....
   @ 12, 30 GET.....

   ? GetFldRow(2)            // Result: 11
   READ                      // Assuming field 1 is active
   ? GetFldRow()             // Result: 10
Platforms
Available on MS-DOS
See also

GetFldVar()Harbour implementation  | 

Determines the name of a GET field
Syntax
GetFldVar([<nField>]) → cField
Arguments
nField Designates for which number of the GET field to determine the name of the accompanying variable. The default is the currently active field.
Returns
GetFldVar() returns the name for the first position of the currently active or specified field. If there is an invalid parameter, a value of -1 is returned.
Description
GET FIELD VARIABLE This function determines the name of an input field. If the nField parameter is not specified, the function returns the name for the currently active field. With an invalid field number or if there is on active field, a value of -1 is returned
Examples
■  Display the name of the variable associated with the second
   posted GET:

   @ 10, 10 GET VAR1
   @ 10, 20 GET VAR2
   @ 10, 30 GET VAR3

   ? GetFldVar(2)               //  "VAR2"

■  Display the name for the active field:

   READ                         // Assuming field 1 is active
   ? GetFldVar()                // "VAR1"

■  Within a UDF or KEYTRAP procedure:

   ? GetFldVar()                // "VAR1"
Platforms
Available on MS-DOS
See also

GetInput()Harbour implementation  | 

Keyboard input function similar to a GET field
Syntax
GetInput(<cDefault>,[<nRow>],[<nColumn>],[<lSAY>],
   [<cPrompt>]) → cInput
Arguments
cDefault Designates the content and length of the input field.
nRow Designates the row in which the input occurs. The default is the current cursor position.
nColumn Designates the column in which the input occurs. The default is the current cursor position.
lSAY When you specify .T. and close GetInput(), the actual data input is displayed with the standard color attribute.
cPrompt Designates text to display in front of the input field at the selected coordinates. The default is no prompt text.
Returns
GetInput() returns the input string.
Description

If you call this function, a simple input field is made available. All control keys are interpreted exactly as in a CA-Clipper GET mask. The length and default for the string are specified in the cDefault parameter. This allows you to portray a normal input field with VAR= Space(length). The input field starts at the current cursor position or at the designated row and column. Similar to @ ... SAY...GET, you can also display text just before the input text. The field starting position is moved accordingly.

In the CA-Clipper SET COLOR TO command, the first color you designate stands for screen output; the second for input fields. GetInput() uses these color designators exactly like CA-Clipper. If you designate the lSAY parameter as .T., you can determine (as with a SAY), whether to redisplay the data in its amended form at the point of input. After data input is complete, the data displayed on the screen is the same as the values returned by the function. This is useful when an input breaks off due to an ESC. For example, the data is "the quick brown fox" and you change it to "the slow brown fox". If lSAY is .T. and you press escape, the original data (the quick brown fox) is restored. The affected area also contains the default color attribute.

Notes

GetInput() uses the CA-Clipper console input internal routines

and supports the INS display in SCOREBOARD. In addition, the SET ESCAPE, SET BELL, SET INTENSITY, SET DELIMITERS, and SET CONFIRM switches are acknowledged.

■ Key traps may occur within GetInput() when the cursor position

within a field is saved. GetInput() is then called recursively, as long as sufficient stack memory is available.

Examples
■  Input at the current cursor position:

   cVar := Space(20)           // 20 position input field
   cVar := GetInput(cVar)      // Retain input attribute

■  Input a 10 space field, row 10, column 20:

   cVar := GetInput(Space(10), 10, 20)

■  After input is finished, the actual data input is redisplayed
   on the screen.  This area contains the standard color attribute.  The
   input is moved by the text preceding the input field:

   SET CONFIRM ON              //  Close with RETURN
   cVAR := "Default text"
   GetInput(cVar, 10, 20, .T., "Please input: ")
Platforms
Available on MS-DOS
See also

GetKXLat()Harbour implementation  | 

Determines the current key code table
Syntax
GetKXLat(<nKeyValue>) → nKeyValue
Arguments
nKeyValue Designates the original key code so that its current value can be tested for translation or lock out.
Returns
GetKXLat() returns the status of the key designated by nKeyValue. A return value of 0 indicates that there is no translation. A return value of -1 indicates that the key is locked out. And any other return indicates that the designated key is translated into that key value.
With Chr(NumLow(nkeyValue)) + Chr(NumHigh(nkeyValue)) the return value can be converted to the form used in the include file ctscan.ch
Description
GetKXLat() allows you to test to see if a key designated under SetKXLat() has been locked out or translated. nKeyValue is the original key code. The key codes used are described in detail in the SetKXLat() function.
Notes

■ Symbolic constants for key codes can be found in the ctscan.ch

file.

■ You can also use the symbolic constants from the CA-Clipper

file inkey.ch for cKeyValue.

Examples
Has the "A" key been locked out or translated?

nVar  := GetKXLat(KS_A)

IF nVar <> 0
   * Undo translation/lock out for "A"
   SetKXLat(KS_A)               // "A" returns to "A"
ENDIF
Platforms
Available on MS-DOS
See also

GetKXTab()Harbour implementation  | 

Retrieves the entire key code table
Syntax
GetKXTab() → cTable
Returns
GetKXTab() returns a character string that contains all of the previously defined key translations.
Description

A CA-Clipper Tools key table can be as large as the maximum allocatable string. The number of translations corresponds to:

((Memory(1) * 1024)/4),

where the required memory is allocated dynamically. The key code translations can be done through SetKXLat() or SetKXTab().

GetKXTab(), in contrast to GetKXLat(), always returns a table of all defined key code translations as a string. A translation table can then be saved in a variable and reset using SetKXTab().

Examples
Save the entire key table and reinstall it later:

cKXTab  := GetKXTab()

   DO KEYCHANGE

SetKXTab(cKXTab)
Platforms
Available on MS-DOS
See also

GetPrec()Harbour implementation  | 

Determines the level of precision that is set
Returns
GetPrec() returns the level of precision currently installed for CA-Clipper Tools trigonometric functions. The value corresponds to the number of digits to the right of the decimal in the range of 1 to 16.
Description
GET PRECISION GetPrec() queries the currently installed precision level for CA-Clipper Tools trigonometric functions. The returned value corresponds to the number of digits to the right of the decimal, that are being worked with. Although the default is 16, you can change this value with SetPrec().
Examples
What precision has been set?

? GetPrec()      //  e.g. 10
Platforms
Available on MS-DOS
See also

GetSecret()Harbour implementation  | 

Keyboard input function for hidden input (similar to a GET field)
Syntax
GetSecret(<cDefault>,[<nRow>],[<nColumn>],[<lSAY>],
   [<cPrompt>]) → cInput
Arguments
cDefault Designates the length and contents of the input field.
nRow Designates the row in which the input occurs. The default is the current cursor position.
nColumn Designates the column in which the input occurs. The default is the current cursor position.
lSAY When you specify .T. and close GetSecret(), the actual data input is displayed with the default color attribute.
cPrompt Designates the text to display in front of the input field at the selected coordinates.
Returns
GetSecret() returns the input string.
Description

If you call this function, a simple input field is made available. All characters input are displayed as asterisks (*) to hide the actual input. All control keys are interpreted exactly as in a CA-Clipper GET mask.

The length and default for the string are specified in the cDefault parameter. This allows a normal input field to be portrayed with VAR = Space(length). The input field starts at the current cursor position or at the designated row and column.

Similar to @ ... SAY ... GET, you can also display text just before the input field. The field starting position is moved accordingly

In the CA-Clipper SET COLOR TO command, the first color you designate is used for screen output; the second for input fields. GetSecret() uses these color designators exactly like CA- Clipper. If you designate the lSAY parameter as .T., you can determine (as with a SAY), whether the data is redisplayed in its amended form at the point of input. However, GetSecret() only displays asterisks to hide this data. This is useful when input breaks off due to an ESC, because at least the correct number of asterisks is displayed. The affected area also contains the standard color attribute.

Notes

GetSecret() uses the CA-Clipper console input internal

routines and supports the INS display in SCOREBOARD. In addition, the SET ESCAPE, SET BELL, SET INTENSITY, SET DELIMITERS, and SET CONFIRM switches are acknowledged.

■ Key traps may occur with GetSecret() when the cursor position

within a field is saved. You can then call GetSecret() recursively, as long as sufficient stack memory is available.

Examples
■  Show the secret field at the current cursor position:

   cVar:= Space(20)            // 20 position secret field
   cVar:= GetSecret(cVar)      // Retain input attribute

■  Show the secret a 10-space field,  row 10, column 20:

   cVar:= GetSecret(Space(10), 10, 20)

■  After input is finished, the actual data input is redisplayed
   on the screen.  This area contains the standard color attribute.  The
   input is moved by the text preceding the input field:

   SET CONFIRM ON              //  Close with RETURN
   cVar:= "Default text"
   GetSecret(cVar, 10, 20, .T., "Please input: ")
Platforms
Available on MS-DOS
See also

GETBOXGROW()  | 

Gets the time delay with which boxes are opened
Syntax
GETBOXGROW() → nTimeDelay
Returns
GETBOXGROW() returns the value set in SETBOXGROW() for the delay in creating a box.
Description
GETBOXGROW() retrieves the time delay that a box in "grow" mode has when it is opened.
Examples
Here is an example of a box with 10 milliseconds between each growth
step:

SETBOXGROW(10)
WOpen(2, 2, 23, 78)            // Sets box coordinates only
WBox()                         // Generates box with delay
? GETBOXGROW()                 // Result: 10
Platforms
Available on MS-DOS
See also

GETCOUNTRY()  | 

Queries country setting for the operating system
Syntax
GETCOUNTRY() → nDosCountryCode

Warning!  This function requires DOS 3.1 or higher.
Returns
GETCOUNTRY() returns the current DOS country code setting.
Description
GETCOUNTRY() returns an integer that gives the current DOS COUNTRY code setting. Returns a number that corresponds to the value set within CONFIG.SYS.
Notes

■ You can find a table of country codes in the section of the

DOS manual that describes CONFIG.SYS construction.

Examples
Query the country code:

CountryCode  :=  GETCOUNTRY()
IF CountryCode = 49
   ? "The country code for Germany has been set!"
ENDIF
Platforms
Available on MS-DOS

GETCURSOR()*  | 

Determines the setting for the cursor form
Syntax
GETCURSOR([<lMode>]) → nCursorForm

*  This function has been retained for compatibility reasons only.
   Its use in development of future applications is not recommended.
   For future applications use the SetCursor() function.
Arguments
lMode Sets the cursor form to the overwrite (.F.) or the insert (.T.) mode. The default value (.F.) sets the cursor form to the overwrite mode.
Returns
The returned value designates how many scan lines are used to display the cursor.
Description

GETCURSOR() allows you to save the current cursor form for an input field in a function called with a VALID, before you change it in a UDF. GETCURSOR() then allows you to restore its old form before returning to the GET field.

CA-Clipper Tools stores the form for two cursor displays: one for overwriting and one for inserting. If lMode is .F. or omitted, then the overwrite cursor form is returned. If lMode is .T., then the insert cursor form is returned. (See the note with SetCursor()).

The cursor is broken down into lines on the screen called scan lines. The form and height of the cursor are specified by two instructions that correspond to the first and the last line used for the cursor display. GETCURSOR() returns both numbers combined into one value, according to the following formula:

(Starting Line * 256) + Final Line

The NumHigh() and NumLow() functions let you separate the starting and final lines very easily.

Notes

■ The word "line" here does not mean a screen (output) line, but

the scan or pixel lines from which screen characters are created.

■ This function works independently of the SET CURSOR setting.

Examples
Break down cursor information into a starting line and a final line:

nCursor  :=  GETCURSOR()
? NumHigh(nCursor)            // Cursor start line
? NumLow(nCursor)             // Cursor final line
Platforms
Available on MS-DOS
See also

GETFONT()  | 

Queries the current font
Syntax
GETFONT([<nFontArea>]) → cFontString
Arguments
nFontArea Designates out of which font area within the screen adapter, the font is loaded into a string. Values from 1 to MAXFONT() are permitted.
Returns
GETFONT() returns a font from the selected area in string form.
Description
GETFONT() transfers a font table from an available font area on the screen card into a string. This allows you to store loaded fonts.
Notes

■ If an invalid value is specified for nFontArea, the function

returns a null string.

Examples
■  Save font 1 ...

   cVar  := GETFONT(1)

■  ...and reset again:

   ? SetFont(cVar, 1)      // 0, if OK
Platforms
Available on MS-DOS
See also

GETLINES()  | 

Determines the number of lines after which the screen display pauses
Syntax
GETLINES() → nLineNumber
Returns
GETLINES() returns the value established with SETLINES()
Description
GETLINES() queries the value previously set with SETLINES().
Examples
■  Set a value:

   SETLINES(20)

      LIST ...

■  Query that value:

   ? GETLINES()               // Result: 20
Platforms
Available on MS-DOS
See also

GETMODE()  | 

Uses the current screen mode as a function name
Syntax
GETMODE() → cFunctionName
Returns
GETMODE() returns a character string that represents the active mode. The character string corresponds to the CA-Clipper Tools function call used to switch to that mode.
Description
This function substitutes for a difficult to understand numeric code for the return value of a function. This character string corresponds to the function call used to switch to the current mode. The returned value can be held in a variable, and this function can be called later using the compile and run operator.
Notes
Important! You must declare all function calls for setting a mode which could occur as a return value from this function as EXTERNAL.
Examples
Notice the mode and reset it later:

cVar := GETMODE()                 // Save current mode
? cVar                            // For example "CGA80(.T.)"

CGA40(.T.)                        // Select other mode

? &(cVar)                         // Reset old mode.
Platforms
Available on MS-DOS
See also

GETPAGE()  | 

Determines the current screen page
Syntax
GETPAGE([<lHiddenPage>]) → nScreenPage
Arguments
lHiddenPage Designates an optional parameter. If this parameter is .T., the function returns the number of the currently hidden page. If this parameter is .F., the function returns the number of the visible screen page. The default value is .F..
Returns
GETPAGE() returns the number of the currently set screen pages.
Description

GETPAGE() allows you to determine which screen page is currently available. The screen page that is currently available can be switched by using the SETPAGE() function.

Since screen output can be directed to a hidden screen page, you can determine the number of this hidden page by setting the parameter to .T.

Examples
Determine the active screen page:

? GETPAGE()                        // i.e. 2
Platforms
Available on MS-DOS
See also

GETPBIOS()  | 

Determines if printing is through DOS or the BIOS
Syntax
GETPBIOS() → nPrintMode
Returns
GETPBIOS() returns the setting made in SETPBIOS() as a numeric value between 0 and 3.
Description
This function allows you to determine the current setting for rerouting the printer through extended drivers. If the function returns a value of 0, the print output is through DOS. If the value is between 1 and 3, the output is through the BIOS on the corresponding printer.
Examples
Determine the current setting:

? GETPBIOS()                        // 0  Output via DOS
Platforms
Available on MS-DOS
See also

GETPXLAT()  | 

Retrieves the current printer table
Syntax
GETPXLAT() → cPrintTable
Returns
GETPXLAT() returns the entire print table or returns an empty character string if a print table has not been defined.
Description
GETPXLAT() retrieves the current printer table set by SETPXLAT(). The string returned can be assigned to a variable and restored later. If you use a printer with different font styles, this function allows you to switch print tables as required.
Examples
■  Save the existing table:

   cOldTab  := GETPXLAT()

■  Install new table:

   SETPXLAT(......)
   SETPXLAT(......)
   SETPXLAT(......)

■  Output to another printer:

   SET PRINTER TO LPT2

■  Restore the old table starting at position 0:

   SETPXLAT(0, cOldTab)
Platforms
Available on MS-DOS
See also

GETSCRMODE()  | 

Determines the number of the active video mode
Syntax
GETSCRMODE() → nModeNumber
Returns
The function returns the mode number of the currently set video mode.
Description

In contrast to GETMODE(), GETSCRMODE() returns the current video mode as a numeric value. This allows you to query special modes for particular screen adapters and reset them using SETSCRMODE(). The following modes are accommodated by other functions within CA-Clipper Tools:

Table 2-1: Modes and Their Coding

    Mode                Mode Number
    CGA40 Monochrome    0
    CGA40 Color         1
    CGA80 Monochrome    2
    CGA80 Color         3
    Monochrome          7
    EGA43 (EGA only)    299 (43+256)
    VGA28 (VGA only)    284 (28+256)
    VGA50 (VGA only)    306 (50+256)

Notes

GETSCRMODE() returns the value previously set with

SETSCRMODE() and the current BIOS or CA-Clipper Tools mode. If you switch into a special mode for a particular screen adapter, there is no guarantee that this is the mode number that GETSCRMODE() returns. This is a factor of the unique behavior of the specific screen adapter.

Examples
■  Set the EGA 43-line mode:

   EGA43()

■  The current video mode is saved:

   nOldMode  := GETSCRMODE()

■  The current video mode is restored later:

   SETSCRMODE(nOldMode)
Platforms
Available on MS-DOS
See also

GETSCRSTR()  | 

Queries screen output that was redirected by SETSCRSTR()
Syntax
GETSCRSTR() → cHiddenCharacterstring
Returns
GETSCRSTR() returns the content of the internal memory area determined by SETSCRSTR().
Description
GETSCRSTR() returns the contents of the internal memory area (determined by SETSCRSTR(.T.)) for hidden screen output . This return value has a length that always corresponds to SCREENSIZE(.T.). You can pass it to a variable and after the mode is switched off, transfer it to the CA- Clipper RestScreen() function. The variable must be passed before the redirected output mode is shut off with SETSCRSTR(.F.). Otherwise, the internal memory area is deallocated and GETSCRSTR() returns a null string.
Notes

■ Since the entire screen output is always redirected

(independent of its actual size), you should always call RestScreen() with the maximum coordinates of 0, 0, MaxRow(), and MaxCol()

Examples
■  Show hidden output, switched back to the physical screen, if
   the need should arise:

   WSelect(0)
   ? SETSCRSTR(.T.)            // .T., when mode on
   @ 10, 10 SAY "XXXXXXX"      // Normal screen output
      *...
   @ 15, 10 SAY "YYYYYYY"

■  Always call the GETSCRSTR() function before SETSCRSTR(.F.)

   cVar  :=  GETSCRSTR()
   ? SETSCRSTR(.F.)            // .F. when mode off
   RestScreen(0, 0, MaxRow(), MaxCol(), cVar)
Platforms
Available on MS-DOS
See also

GETSHARE()  | 

Determines the file open (share) mode
Syntax
GETSHARE() → nShareMode
Returns
GETSHARE() returns the current share mode setting as a value between 0 and 4.
Description
GETSHARE() determines the current share mode set with SETSHARE(). The coding that is used is described in this function.
Examples
The current share mode:

IF GETSHARE() == 4
   ? "Reading and writing permitted for other programs !"
ENDIF
Platforms
Available on MS-DOS
See also

GETTAB()  | 

Retrieves tab values for CA-Clipper screen output
Syntax
GETTAB() → cTabTable
Returns
GETTAB() returns the currently installed tab locations for CA-Clipper screen output in the form of a character string.
Description
This function gives the tab definitions specified in SETTAB() for CA-Clipper screen output. You can use this function to save the active tab definitions.
Examples
Save the tab definitions:

cTabs := GETTAB()
Platforms
Available on MS-DOS
See also

GETTIC()  | 

Determines the number of timer ticks
Syntax
GETTIC() → nTickCount
Returns
GETTIC() returns the number of timer ticks executed since the last SETTIC (.T.).
Description
Use this function in conjunction with SETTIC(). At any given time, it returns the number of completed timer ticks since the timer was set in motion (by calling SETTIC(.T.)).
Examples
An individual UDF is to be measured in ticks.  The tick rate counter is
started with the SETTIC(.T.) call, then stopped after execution of the
UDF (by passing .F. to SETTIC()) and the number of completed ticks is
queried:

SETTIC(.T.)
   MY_UDF(I)
SETTIC(.F.)
? " Required ticks:", GETTIC()
Platforms
Available on MS-DOS
See also

GETVGAPAL()  | 

Determines the palette settings on a VGA card
Syntax
GETVGAPAL(<nColor|cColor>,<cRGB>)
    → nPaletteValue
Arguments
nColor|cColor Designates a color represented by a number in the range of 0 to 15, or a color code that corresponds to the one in SET COLOR TO.
cRGB May designate as R, G, or B to determine the corresponding palette value.
Returns
GETVGAPAL() returns the red, green, or blue palette value for the designated color. When invalid paramerters are specified, a value of -1 is returned.
Description

On a VGA adapter, each color is a combination of the three values for red, green and blue. Each value can be in the range of 0 to 63, to permit you to install different color palettes.

GETVGAPAL() queries the R, G, and B values for all 16 colors. The individual color can be a number in the range of 0 to 15, or represented as a color code corresponding to the CA-Clipper SET COLOR TO.

Notes

■ This function is implemented in the enclosed Colorpal.prg

program.

Examples
Determines the palette value of red in the color cyan:

GETVGAPAL("BG", "R")
Platforms
Available on MS-DOS
See also

HexToStr()  | 

Converts a hexadecimal string into a byte sequence
Syntax
HexToStr(<cHex>) → cBytes

Netware: 2.2 and 3.11
Arguments
cHex Designates a character string of which two characters are recognized as a hexadecimal form of a byte. cHex can contain only the characters "0" to "9" and "A" to "F".
Returns
HexToStr() returns a character string that contains a byte sequence in which each byte corresponds to two characters of its hexadecimal form. The return value is half as long as cHex.
Description
HexToStr() is useful when working with the internet addresses that are required in conjunction with the IPX/SPX functions of Point To Point communication.
Examples
Convert the hexadecimal string into a byte sequence:

? HexToStr('4130')   // "A0"
Platforms
Available on MS-DOS
See also

Infinity()Harbour implementation  | 

Creates the largest number possible (21023)
Syntax
Infinity() → nLargestNumber
Returns
Infinity() returns the largest number possible.
Description
When you divide by zero, use the Infinity() value as a result (i.e., for comparisons).
Notes
■ The number value is approximately (1.999 * 21023).
Examples
Display the largest number possible in CA-Clipper:

? Infinity()
Platforms
Available on MS-DOS
See also

IntNeg()Harbour implementation  | 

Converts an unsigned integer into a signed integer
Syntax
IntNeg(<nUnsigned|cHexUnsigned>,[<l32Bit>)
    → nSigned
Arguments
nUnsigned|cHexUnsigned Designates either a numeric value or hexadecimal digit string to convert into a 16-bit or 32-bit signed integer.
32Bit If this optional parameter is designated as .T., the function processes the designated value as a 32-bit unsigned integer. The default value is a 16-bit unsigned integer (.F.).
Returns
IntNeg() returns a signed 16-bit or 32-bit integer.
Description

This function converts unsigned integers into signed integers.

All 16-bit or 32-bit integers are accepted, depending on whether there is a second parameter and the logical value is assigned. For the 16-bit variant, all values for nUnsigned|cHexUnsigned that are less than or equal to +32767 (hex=7FFF), are positive. Values in the range of +32768 (hex=8000) to +65535 (hex=FFFF), have a negative result. When you work with 32-bit values, the positive range goes to 2147483647 (inclusive). All values beyond that are negative.

Notes

■ The function returns a value of 0 for invalid, too large, or

negative parameters.

Examples
■  Show valid parameters:

   ? IntNeg(0)                   // Result:  0
   ? IntNeg(-1)                  // Result:  0
   ? IntNeg(30000)               // Result:  30000
   ? IntNeg(32767)               // Result:  32767
   ? IntNeg(32768)               // Result: -32768
   ? IntNeg(32769)               // Result: -32767
   ? IntNeg(60000)               // Result: -5536
   ? IntNeg(65535)               // Result: -1
   ? IntNeg("FFFF")              // Result: -1
   ? IntNeg("D0000000", .T.)     // Result: -805306368
   ? IntNeg("FFFFFFFF", .T.)     // Result: -1

■  Show incorrect instructions or instructions that are too
   large:

   ? IntNeg("GGGG")              // Result:  0
   ? IntNeg(90000)               // Result:  0
   ? IntNeg("FFFFFFFFF")         // Result:  0
Platforms
Available on MS-DOS
See also

IntPos()Harbour implementation  | 

Converts a signed integer into an unsigned integer
Syntax
IntPos(<nSigned|cHexSigned>,[<l32Bit>])
    → nUnsigned
Arguments
nUnsigned|cHexUnsigned Designates either a numeric value or hexadecimal digit string to convert into a 16-bit or 32-bit unsigned integer.
l32Bit If this optional parameter is designated as .T., the function processes the designated value as a 32-bit signed integer. The default value is a 16-bit signed integer (.F.).
Returns
IntPos() returns an unsigned 16-bit or 32-bit integer.
Description

This function converts signed 16-bit or 32-bit integers into the corresponding unsigned number. Based on the optional parameter and the logical value it is assigned, you can work with 16-bit or 32-bit values.

For the 16-bit variant, all values in the 0 to 32767 range are unchanged. However, all negative values from -1 to -32768 are changed. When the optional parameter is designated as .T., the range of values stretches from -2147483648 to +2147483647.

Notes
■ This function returns a 0 result for invalid paramerters.
Examples
■  Show simple conversions:

   ? IntPos(-1)               // 65535
   ? IntPos(-2)               // 65534
   ? IntPos(30000)            // 30000
   ? IntPos(60000)            // 60000

Warning!  When working with 16-bit values IntPos(0) = IntPos(65536):

   ? IntPos(0)                // 0
   ? IntPos(65536)            // 0

■  Show values larger than 65536 in 16-bit mode.  For example,
   the difference between 90000 and 65536 is 24464:

   ? IntPos(90000)            // 24464

■  However, in 32-bit mode:

   ? IntPos(90000, .T.)       // 90000
   ? IntPos(-1, .T.)          // 4294967295
                              // (largest 32-bit number)
   ? IntPos(-60000, .T.)      // 4294907296
   ? IntPos(-90000, .T.)      // 4294877296
Platforms
Available on MS-DOS
See also

InvertAttr()Harbour implementation  | 

Inverts the foreground and background of an attribute
Syntax
InvertAttr(<cAttr|nAttr>) → nInvertAttr
Arguments
cAttr|nAttr Designates the attribute to process.
Returns
InvertAttr() returns the value of the inverted attribute.
Description

InvertAttr() returns a value that corresponds to the opposite of an individual screen attribute. This is same as if you were to exchange the foreground color for the background. For example, red characters on a white background, become white characters on a red background.

This new attribute can be used in conjunction with such functions as ScreenAttr(), ColorWin(), and ColorRepl().

Notes

■ The flashing and high-intensity attributes are not affected.

■ The result is always numeric, regardless of the parameter's

data type.

Examples
■  Invert the attributes at the current cursor position.  In
   doing so, the attribute is not set:

   ? INVERATTR(ScreenAttr())

■  You can represent the attribute in a number of different ways.
   The returned value is always numeric:

   8                           // Result:  30

■  An invalid attribute:

   ? InvertAttr("xx/yy")       // Result:  0
Platforms
Available on MS-DOS
See also

InvertWin()Harbour implementation  | 

Inverts all attributes in an area of the screen
Syntax
InvertWin([<nTopLine>], [<nLeftColumn>],
   [<nBottomLine>], [<nRightColumn>]) → cNull
Arguments
nTopLine Designates the topmost line for the top-left corner of the area. The default is the cursor position.
nLeftColumn Designates the leftmost column for the top-left corner of the area. The default is the cursor position.
nBottomLine Designates the bottommost line for the bottom-right corner of the area. The default is the end of the screen area.
nRightColumn Designates the rightmost column for the bottom-right corner of the area. The default is the end of the screen area.
Returns
The function always returns a null string.
Description
This function permits you to invert all attributes within a screen area. Background attributes are exchanged for those in the foreground.
Examples
■  Invert the attributes in an area:

   InvertWin(10, 10, 20, 70)      // Always returns a null string

■  Invert to end of screen:

   InvertWin(10, 10)
Platforms
Available on MS-DOS
See also

INBYTE()  | 

Reads an 8 byte from a port
Syntax
INBYTE(<nPort|cHexPort>) → nByte
Arguments
nPort|cHexPort Designates a port address from which a byte is read. This value can be a decimal integer or hexadecimal string.
Returns
INBYTE() returns the byte read from the specified port; or a value of - 1, if a parameter error occurs.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standared hardware as a serial interface port. However, if you read a highly specialized systems and their ports from CA-Clipper, use INBYTE() or INWORD().
Notes

■ A random return value is produced for a nonexistent port or

one that cannot be read.

Examples
These examples read the first port address of the first serial interface
port.  This is only an example, since the CA-Clipper Tools contains
special port functions.

■  With a decimal parameter:

   ? INBYTE(1016)       // 1st Port (COM1)

■  With a hexadecimal parameter:

   ? INBYTE("3F8")      // Also 1st Port (COM1)
Platforms
Available on MS-DOS
See also

INKEYTRAP()  | 

Behaves like Inkey() with support for key traps
Syntax
INKEYTRAP(<nDelay>) → nKeyCode
Arguments
nDelay Designates the delay time in seconds.
Returns
The function returns the same key code as Inkey().
Description
This function operates in essentially the same way as Inkey(). It supports the same time delays and returns the same key codes as values. The most significant difference to Inkey() is that all key traps defined using SET KEY Key TO Procedure are supported. This function saves the programmer time; for example, the programmer does not have to develop extensive CASE constructs after each Inkey().
Notes
■ After the trap procedure ends, the nDelay time is reset.
Examples
SET KEY 28 TO HELP               // F1 Key
nVar  :=  INKEYTRAP(10)          // 10-second delay
RETURN

PROCEDURE Help(a, b, c)          // Parameter c is always
                                 // a null string
("")

* Program code desired

RETURN
Platforms
Available on MS-DOS
See also

INPUTMODE()  | 

Determines the previously active or the currently active input mode
Syntax
INPUTMODE([<lActiveMode>]) → nInputMode
Arguments
lActiveMode Designates an optional parameter. If this parameter is .T., the function returns the currently active mode.
Returns
INPUTMODE() returns a numeric value that indicates the input command for the previously active or the currently active input mode.
Description
INPUTMODE() allows you to determine what type of input command has been interrupted. When called without a parameter or with .F., the function returns the currently active mode or, if no input has occurred, the previously active input mode.
If the function is called with lActiveMode set to .T., then only the currently active input mode or 0 is returned. The following table shows the return values as well as the symbolic constants and their accompanying definitions.
Table 2-2 Coding the Input Mode
    Return  Symbolic Const.    Definition
    0      IMODE_NO            No input command currently.
    1      IMODE_WAIT          WAIT
    2      IMODE_ACCEPT        ACCEPT
    3      IMODE_INPUT         INPUT
    4      IMODE_READ          READ
    5      IMODE_MEMOEDIT      MemoEdit()
    6      IMODE_MENU          MENU
    7      IMODE_INKEY         Inkey()
    8      IMODE_DEBUG         Debugger input
    9      IMODE_GETINPUT      Input within GetInput()
    10     IMODE_GETSECRET     Input within GetSecret()
Examples
PROCEDURE HELP(A, B, C)

   nArea  := Select()
   nMode  := INPUTMODE()

   IF nMode = 5               // Calling from MemoEdit()
      SELECT MEMOHELP
   ELSE
      SELECT HELP
   ENDIF

   SELECT (nArea)

   RETURN
Platforms
Available on MS-DOS

INWORD()  | 

Reads in a 16-bit word from a port
Syntax
INWORD(<nPort|cHexPort>) → nWord
Arguments
nPort|cHexPort Designates a port address from which a word with a 16-bit value is read. This value can be a decimal integer or hexadecimal string.
Returns
INWORD() returns the word read from the designated port, or a value of - 1 when an error occurs.
Description
CA-Clipper Tools always attempts to offer finished solutions at the highest-possible level for such standard hardware as a serial interface port. However, if you read highly specialized systems and their ports from CA-Clipper, use INBYTE() or INWORD(). INWORD() allows you to read from interfaces that return the data from a port as a 16-bit value.
Notes

■ A returns random value for a nonexistent port or one that

cannot be read.

Examples
Show a read from a 16-bit port:

■  With a decimal parameter:

   ? INWORD(512)           // Read from an additional device

■  With a hexadecimal parameter:

   ? INWORD("200")         // The same port address
Platforms
Available on MS-DOS
See also

IPXERROR()  | 

Determines the error code of the last IPX/SPX call
Syntax
IPXERROR() → nErrorCode

Netware: 2.2 and 3.11
Returns
IPXERROR() returns the error code of the previous IPX/SPX call by a CA-Clipper Tools function. There is a table containing the error codes in Appendix D.
Description

IPXERROR() allows you to locate the source of an error that occurred during the execution of a CA-Clipper Tools function for IPX/SPX communication (for example IPXOPEN() or SPXESTBCON()). If the IPX/SPX call has been terminated without an error, IPXERROR() returns 0.

IPXERROR() returns an error code that is the direct result of an IPX/SPX call. If the IPX/SPX call initiates the interrupt controlled receiving of a packet, the error code cannot return any information about the success or failure of the receiving process. You can use the PPCRECERR() and PPCSNDERR() functions to determine this information.

Examples
Open the socket.  If an error occurs, determine the reason for the
error:

IF OPENSOCK(20000)=0                           // Error?
   IF IPXERROR()=254
      ? 'Local socket table full!'
   ENDIF
ENDIF
Platforms
Available on MS-DOS
See also

IPXOPEN()  | 

Opens the IPX sending and receiving buffer
Syntax
IPXOPEN(<nSourceSocket>,[<nRecBuffer>],
   [[<nSendBuffer>],[<cTargetAddr>]],
   [<nTargetSocket>],[<nPacket>],[<lHeader>])
    → nHandle

Netware: 2.2 and 3.11
Arguments
nSourceSocket Designates the number of the communication's source socket.
nRecBuffer Designates the selected size of the receiving buffer. If no value is passed for nRecBuffer, no receiving buffer is established. The minimum size of the receiving buffer is nPacket. If the value for nRecBuffer is too small, it is changed automatically by IPXOPEN(). The maximum size of the receiving buffer is 64 KByte.
nSendBuffer Designates the selected size of the sending buffer. If no value is passed for nSendBuffer, no sending buffer is established. The minimum size of the sending buffer is nPacket. If the value for nSendBuffer is too small, it is changed automatically by IPXOPEN(). The maximum size of the sending buffer is 64 KByte.
cTargetAddr Designates the target address for the sending operations. The target address is a 20-character string that represents a 10-character hexadecimal byte sequence. The leading eight characters of cTargetAddr specify the network number of the target. The following 12 characters contain the station ID of the target station (node address). cTargetAddr is mandatory to establish a sending buffer.
nTargetSocket Designates the number of the communication's target socket. The default value is nSourceSocket.
nPacket Designates the packet size in bytes of the data that is sent. The packet size can be between 1 and 546 bytes. Values outside this range are changed automatically. The default value is 546 Bytes.
lHeader Designates whether the data and the header (.T.), or the data (.F.) alone, are transmitted to the receiving buffer.
Returns
If an operation is successful, IPXOPEN() returns a communication handle. The return value contains a numeric value that is greater than 0. You should store the handle in a variable because all further operations that refer to an established buffer require a communication handle. If an error occurs, the function returns 0.
Description

IPXOPEN() allows you to establish a communication buffer for an IPX communication with other workstations in the network. The communication buffer can contain a sending and receiving buffer through which data is processed.

nSourceSocket is the socket address of the process that transmits the data (see the Introduction to this chapter). The socket can be opened with the function OPENSOCK() before the call of IPXOPEN(). If nSourceSocket has not been opened, it is automatically opened by IPXOPEN(). If nSourceSocket is passed with 0, IPXOPEN() opens an available socket.

The parameters nRecBuffer and nSendBuffer determine the size of the receiving and sending buffers. The buffers are automatically designed for one IPX packet. Each buffer can be up to 64 KByte. However, the size of the buffer that is allocated by IPXOPEN() depends on the application and the configuration of the computer used.

The parameter cTargetAddr is mandatory to establish a sending buffer. All following sending operations are addressed to cTargetAddr. Remember that an IPX communication is implemented as a pseudo Point-To- Point communication. Data is received by any station addressed to the current workstation but is sent only to a defined target address. The target address must be passed as a 20- character string (for example, "4921750400001B025A99"), where two characters represent one byte in hexadecimal code.

If the current workstation is logged in to a Netware server, the destination's network address can be determined with NNETADR() , using the user name. However, the target workstation must be logged in. Under Netware Lite, the leading eight characters of cTargetAddr must be passed with 0. A character string consisting of "FFFFFFFFFFFFFFFFFFFF" specifies all stations within an internal network as the target address (broadcast packages).

nTargetSocket allows you to determine the communication's target socket. The default value is nSourceSocket.

nPacket determines the maximum size of the data range of the IPX packets that are sent or received. The maximum value (and the default value) is 564 bytes. The value of nPacket is also valid for sending data.

With lHeader you can determine if the header (30 bytes) of an IPX packet is transmitted to the receiving buffer. The header can contain important information about the received packet. For a description about the header structure, see the Introduction to this chapter.

If the buffer has been established successfully, IPXOPEN() returns an integer value that is greater than 0, called a communication handle. If a value has been passed for nRecBuffer, IPXOPEN() initiates an interrupt controlled receiving mechanism that receives incoming packets in the background and then copies to an receiving buffer. The data can then be read with the PPCREAD() function within a CA-Clipper application. If the receiving buffer is full, incoming data is discarded without notifying the sender. Data should be removed from the receiving buffer and processed as soon as possible. You should either read the contents of the buffer periodically (polling) or supervise the buffer on an event-oriented basis: for example, with the function PPCKEY().

Notes

■ IPX is a protocol that is not based on a connection. There is

no guarantee or verification of a successful delivery to the target workstation. The implementation of specific protocols with the aid of CA-Clipper Tools functions can be necessary. (For your information: Netware usually uses IPX communication, and Netware Lite exclusively uses IPX communication, which is now available under CA-Clipper with the IPXOPEN() function.)

■ Several communication buffers can be established for one

source socket. However, you cannot know when you establish the communication buffers how the data will be distributed to the receiving buffers.

■ Network addresses can be determined under Netware with

"USERLIST /A", and under Netware Lite with "NET ULIST".

Examples
■  Open the 5 KByte IPX receiving buffer for socket 20000:

   nHandle=IPXOPEN(20000,5120)
   IF nHandle=0
      ? 'Buffer could not be established!'
   ENDIF

■  Open the 2 KByte IPX sending buffer for socket 20000.  The
   target address is "4921750400001B025A99":

   nHandle=IPXOPEN(20000,,2048,"4921750400001B025A99")

■  Open the 1 KByte IPX sending and receiving buffer for socket
   20000.  The target address is the first workstation where user MIKE
   is currently logged in:

   nHandle=IPXOPEN(20000,1024,1024,NNETADR("MIKE"))

■  For this example, the current workstation must be logged into
   a file server.  As NNETADR() is based on Netware-API, this call
   cannot be used under Netware Lite.
Platforms
Available on MS-DOS
See also

IsAt()Harbour implementation  | 

Determines if a program is running on an AT
Syntax
IsAt() → AT
Returns
IsAt() returns .T. value when the program is running on an AT-compatible system.
Description
IsAt() determines if your CA-Clipper application is running on an AT-class system.
Notes

■ The function also returns .T. for systems with an 80386 or

80486 processor.

Examples
Since you can set the hardware clock on an AT (in contrast to an XT),
use IsAt() to determine if SetDate() and SetTime() function properly:

IF IsAt()
   ? "The internal clock can be changed."
ELSE
   ? "Time and date will be lost after booting!"
ENDIF
Platforms
Available on MS-DOS
See also

IsBit()Harbour implementation  | 

Tests the bits in a number
Syntax
IsBit(<nLONG|cHexLONG>,[<nBitPos>]) → lSet
Arguments
nLONG|cHexLONG Designates either a decimal number or hexadecimal digit string.
nBitPos Designates the bit number to test. The value can lie in the range of 1 to 32. The default is the least-significant bit.
Returns
When the designated bit is set, the function returns a result of .T..
Description
IsBit() tests a particular bit within a numeric field, without having to mask it or do a comparison.
Examples
Tests the BREAK bit in the line status register of the COM1 serial
interface:

IF IsBit(com_LSR(1), 5)
   ? "BREAK condition detected!"
ENDIF
Platforms
Available on MS-DOS
See also

IsCGA()Harbour implementation  | 

Tests for presence of a CGA card or if one can be emulated
Syntax
IsCGA([<lMode>]) → lCGA
Arguments
lMode When designated as .T., tests to see if a CGA card is available. The default value of .F. tests to see if a CGA adapter can be emulated.
Returns
Depending on the lMode parameter, IsCGA() returns .T. when a CGA card is available, or if a CGA adapter can be emulated.
Description
You can determine two things with this function. When designated as .F. or when called without a parameter, IsCGA() tests it see if a CGA adapter can be emulated. This can be the case with an EGA or VGA card. When designated as .T., the function determines if a CGA card is available.
Notes
■ Use GETMODE() to determine which mode is active.
Examples
Can CGA be emulated?

IF IsCGA()
*...
ENDIF
CGA-Card?
IF IsCGA(.T.)
*...
ENDIF
Platforms
Available on MS-DOS
See also

IsEGA()Harbour implementation  | 

Determines if an EGA card is present or can be emulated
Syntax
IsEGA([<lMode>]) → lEGA

Important!  Contains <lMode>, an additional optional parameter over
and above the original CA-Clipper Tools.
Arguments
lMode When designated as .T., determines if an EGA card is present. The default value of .F. tests to see if an EGA adapter can be emulated.
Returns
In conjunction with the lMode parameter, IsEGA() returns .T. when an EGA card is present or an EGA adapter can be emulated.
Description
This function determines two things. When lMode is designated as .F. or the function is called without a parameter, IsEGA() determines if an EGA adapter can be emulated. This could be the case with a VGA card. When lMode is .T., it determines if an EGA card present.
Notes
■ Use GETMODE() to determine the active mode.
Examples
Can EGA be emulated?

If IsEGA()
   * ...
ENDIF
EGA card?
IF IsEGA(.T.)
   * ...
ENDIF
Platforms
Available on MS-DOS
See also

IsHercules()Harbour implementation  | 

Determines if a HERCULES card is present or can be emulated
Syntax
IsHercules([<lMode>]) → lHERCULES

Important!  Contains <lMode>, an additional optional parameter over
and above the original CA-Clipper Tools.
Arguments
lMode When designated as .T., determines if a HERCULES card is present. The default value .F. tests to see if a Herculess adapter can be emulated.
Returns
In conjunction with the lMode parameter, IsHercules() returns a .T. when a HERCULES card is present or a HERCULES adapter can be emulated.
Description
This function determines two things. When lMode is designated as .F., or the function is called without parameter, IsHercules() determines if a HERCULES adapter can be emulated. This could be the case with a VGA or EGA card. When lMode is .T., it determines if there is a HERCULES card present.
Notes

GETMODE() determines the active mode.

Warning! Although our function implies it, not all EGA and VGA cards can emulate HERCULES. In most cases, a HERCULES emulation on a VGA card is possible , but it cannot be determined with absolute certainty. As long as the text is output under CA-Clipper, working with IsMono() should be sufficient

Examples
Can HERCULES be emulated?

If IsHercules()
   * ...
ENDIF
HERCULES card?
IF IsHercules(.T.)
   * ...
ENDIF
Platforms
Available on MS-DOS
See also

IsLeap()Harbour implementation  | 

Tests if a specific year is a leap year
Syntax
IsLeap([<dDate>]) → lLeapYear
Arguments
dDate Designates whether or not the specified date is in a leap year. The default is the system date.
Returns
IsLeap() returns .T. when dDate lies in a leap year; otherwise, it returns .F..
Description
A number of technical financial calculations need to know if a year has 365 or 366 days. IsLeap() determines this.
Notes

■ When parameters are missing, the function automatically uses

the system date. You must adhere to all rules for leap year tests. In the rare occurrence of a century change, the function also returns a correct result.

Examples
Determine if the following dates are in a leap year:

? IsLeap(CToD("01/01/1901"))      // .F., No leap year
? IsLeap(CToD("09/30/1988"))      // .T., leap year
? IsLeap(CToD("01/01/2000"))      // .T., leap year
Platforms
Available on MS-DOS
See also

IsMath()Harbour implementation  | 

Determines if a math coprocessor is installed
Syntax
IsMath() → lCoprocessor
Returns
IsMath() returns .T. value when a math coprocessor is installed in the system.
Description
IsMath() determines if a math coprocessor is available to your CA- Clipper application.
Examples
Determine if a math coprocessor is available to the application:

IF IsMath()
   ? "Coprocessor available."
ENDIF
Platforms
Available on MS-DOS
See also

IsMCGA()Harbour implementation  | 

Determines if an MCGA card is present or can be emulated
Syntax
IsMCGA([<lMode>]) → lMCGA
Arguments
lMode When designated as .T. tests to see if an MCGA card is actually available. The default value of .F. tests to see if a monochrome adapter can be emulated.
Returns
Depending on the lMode parameter, the function returns .T. when a MCGA card is available or if an MCGA adapter can be emulated.
Description
You can determine two things with this function. When designated as .F. or when called without a parameter, IsMCGA() tests to see if a monochrome adapter can be emulated. This can happen with a HERCULES, EGA, or VGA card. When designated as .T., the function determines if a Monochrome card is available.
Notes
GETMODE() determines the active mode.
Examples
Can MCGA be emulated?

IF IsMCGA()
*...
ENDIF
MCGA-Card?
IF IsMCGA(.T.)
*...
ENDIF
Platforms
Available on MS-DOS
See also

IsMono()Harbour implementation  | 

Determines if a monochrome card is present or can be emulated
Syntax
IsMono([<lMode>]) → lMonochrome
Arguments
lMode When designated as .T., tests to see if a monochrome card is available. The default value of .F. tests to see if a monochrome card can be emulated.
Returns
Depending on the lMode parameter, IsMono() returns .T. when a monochrome card is available, or if a monochrome adapter can be emulated.
Description
This function determines two things. When designated as .F. or when called without a parameter, IsMono() tests to see if a monochrome adapter can be emulated. This can be the case with a HERCULES, EGA, or VGA card. When designated as .T., the function determines if a monochrome card is available.
Notes
GETMODE() determines the active mode.
Examples
■  Can monochrome be emulated?

   IF IsMono()
      *...
   ENDIF

■  Monochrome adapter?

   IF IsMono(.T.)
      *...
   ENDIF
Platforms
Available on MS-DOS
See also

IsPGA()Harbour implementation  | 

Determines if a PGA card is present or can be emulated
Syntax
IsPGA([<lMode>]) → lPGA
Arguments
lMode When designated as .T., tests to see if a PGA card is available. The default value of .F. tests to see if a PGA adapter can be emulated.
Returns
Depending upon the lMode parameter, IsPGA() returns .T. when a PGA card is available or if a PGA adapter can be emulated.
Description
This function can determine two things. When designated as. F. or when called without a parameter, IsPGA() tests to see if a PGA adapter can be emulated. This can be the case with an EGA or VGA card. When designated as .T., the function determines if a PGA card is actually available.
Notes
■ Use GETMODE() to determine the active mode.
Examples
■  Can PGA be emulated?

   IF IsPGA()
      *...
   ENDIF

■  PGA card?

   IF IsPGA(.T.)
      *...
   ENDIF
Platforms
Available on MS-DOS
See also

IsVGA()Harbour implementation  | 

Determines if a VGA card is present
Syntax
IsVGA() → lVGA
Returns
IsVGA() returns .T. when a VGA card is available.
Description
The function tests to see if the screen card is a VGA adapter. Use GETMODE() to determine the active mode.
Examples
Is VGA adapter available?

IF IsVGA()<R>
   *...
ENDIF
Platforms
Available on MS-DOS
See also

ISANSI()  | 

Tests to see if the ANSI screen driver is installed
Syntax
ISANSI() → lInstalledDriver
Returns
ISANSI() returns .T. when ANSI.SYS or a comparable driver has been loaded from CONFIG.SYS.
Description
ISANSI() determines if ANSI.SYS or another comparable driver has been loaded from CONFIG.SYS. Some full-page displays require the ANSI driver. If the driver is present, the display is fully operational.
Notes
Warning! You must implement DSETWINDOW(.F.) for ISANSI() to return a correct result.
Examples
If ANSI.SYS is present, output through DOS.  This allows a simple
terminal emulation:

IF ISANSI()                  // ANSI driver present?
   com_DosCon(dDate)         // Output via DOS
ELSE
   *...                      // Individual ANSI handling
ENDIF
Platforms
Available on MS-DOS
See also

ISDBT()  | 

Determines if a memo file (.dbt) is present
Syntax
ISDBT() → lPresent
Returns
ISDBT() returns .T., if a database has a memo file associated with it.
Description
ISDBT() determines if a database has a memo file associated with it, and allows you to compress that memo file.
Examples
If the database has a memo file, the database is copied to minimize the
memo file:

USE DATA
IF ISDBT()
   COPY TO TEMP
   CLOSE DATABASES
   DeleteFile("DATA.DBF")
   DeleteFile("DATA.DBT")
   RenameFile("TEMP.DBF", "DATA.DBF")
   RenameFile("TEMP.DBT", "DATA.DBT")
ENDIF
Platforms
Available on MS-DOS

ISDEBUG()  | 

Determines if the debugger is available in the application
Syntax
ISDEBUG() → lDebugger
Returns
ISDEBUG() returns a value that signifies if the CA-Clipper debugger is available.
Description
This function determines if the debugger is available in an application. This enables a program to acknowledge this special situation and then conditionally execute or ignore portions of the program.
Notes

■ This is not a CA-Clipper switch. This information is provided

by CA-Clipper Tools.

Examples
Indicate if the debugger is active:

IF ISDEBUG()
   ? "The debugger is being used!"
ENDIF
Platforms
Available on MS-DOS

ISIPX()  | 

Checks for IPX support
Syntax
ISIPX() → lInstalled

Netware: 2.2 and 3.11
Returns
ISIPX() returns .T. if IPX support is available. The IPX communication functions of CA-Clipper Tools can be used.
Description
ISIPX() allows you to check to see if IPX support is available. If it is not, an application can be terminated.
Examples
Check to see if IPX support is available.  If it is not, terminate the
program:

IF ISIPX()
   nHandle=IPXOPEN(20000,2000)
ELSE
   ? 'IPX support not available, load IPX.COM!'
   QUIT
ENDIF
Platforms
Available on MS-DOS
See also

ISNETBIOS()  | 

Checks for NetBIOS support
Syntax
ISNETBIOS() → lInstalled

Netware: 2.2 and 3.11
Returns
ISNETBIOS() returns .T. if NetBIOS support is available. If the function returns .T., the NetBIOS communication functions of CA-Clipper Tools can be used.
Description
ISNETBIOS() allows you to check to see if NetBIOS support is available. If it is not, an application can be terminated.
Examples
Check to see if NetBIOS support is available.  If it is not, terminate
the program:

IF ISNETBIOS()
   nHandle=NBDOPEN("STAT1",2000)
ELSE
   ? 'NetBIOS support not available!'
   QUIT
ENDIF
Platforms
Available on MS-DOS
See also

ISSPX()  | 

Checks for SPX support
Syntax
ISSPX() → lInstalled

Netware: 2.2 and 3.11
Returns
ISSPX() returns .T. if SPX support is available. The SPX communication functions of CA-Clipper Tools can be used.
Description
ISSPX() allows you to check to see if SPX support is available. If it is not, an application can be terminated.
Examples
Check to see if SPX support is available.  If it is not, terminate the
program:

IF ISSPX()
   nHandle=SPXLISTCON(20000,2000)
ELSE
   ? 'SPX support not available, load IPX.COM!'
   QUIT
ENDIF
Platforms
Available on MS-DOS
See also

JustLeft()Harbour implementation  | 

Moves characters from the beginning to the end of a string
Syntax
JustLeft(<cString>,[<cCharacter|nCharacter>])
   → cString
Arguments
cString [@] Designates the string that is processed.
cCharacter|nCharacter Designates the character that is moved from the beginning of the cString to the end. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
JustLeft() moves the characters specified in cCharacter|nCharacter from the beginning of a character string to the end. Then the remaining text in the character string is left justified, without affecting the length.
Notes

■ If the cCharacter|nCharacter parameter is not specified,

spaces are automatically moved.

■ The return value for this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
■  Move the blanks:

   ? JustLeft("   123")              // "123   "

■  Move the "." character:

   ? JustLeft("..123"," ".)          // "123.."
Platforms
Available on MS-DOS
See also

JustRight()Harbour implementation  | 

Moves characters from the end of a string to the beginning
Syntax
JustRight(<cString>,[<cCharacter|nCharacter>])
   → cString
Arguments
cString [@] Designates the string that is processed.
cCharacter|nCharacter Designates the character that is moved from the end of the cString to the beginning. The default value is a space, Chr(32).
Returns
The processed cString is returned.
Description
JustRight() moves the characters specified in cCharacter| nCharacter from the end of a character string to the beginning. Then the remaining text in the character string is right justified, without affecting the length.
Notes

■ If the cCharacter|nCharacter parameter is not specified,

spaces are automatically moved.

■ The return value for this function can be suppressed by

implementing CSetRef() to save room in working memory.

Examples
■  Move the blanks:

   ? JustRight("123   ")           // "   123"

■  Move the "." character:

   ? JustRight("123..", ".")       // "..123 "
Platforms
Available on MS-DOS
See also

KbdStat()Harbour implementation  | 

Tests for key shift state status, such as Ctrl and Shift
Syntax
KbdStat() → nKeyStatus
Returns
KbdStat() returns a numeric code that corresponds to the status of certain keys.
Description

This function determines the status of all shift state keys (e.g., Ctrl, Shift or Alt, Scroll-Lock or Num-Lock). The information KDBSTAT() returns depends on the keyboard itself.

Table 13-5: Applies to all Keyboards

    Bit     Key
    1       Right shift currently pressed
    2       Left shift currently pressed
    3       Ctrl currently pressed (left or right)
    4       Alt currently pressed (Alt or Shift-Alt)
    5       Scroll-Lock ON/OFF
    6       Num-Lock ON/OFF
    7       Caps-Lock ON/OFF
    8       Insert ON/OFF

Notes

■ Since KbdStat() depends on the type of keyboard, use KBDTYPE()

to determine whether or not the left and right Ctrl or Alt keys are valid return values.

Examples
This example tests the Alt key.  You could use it to display an
additional prompt menu when the Alt key is depressed:

IF IsBit(KBSTAT(), 4)
   * . . .
ENDIF
Platforms
Available on MS-DOS
See also

KBDDISABLE()  | 

Locks/unlocks the keyboard
Syntax
KBDDISABLE(<lSwitch>) → cNull
Arguments
lSwitch Designates whether the keyboard is switched on (.T.) or off (.F.).
Returns
KBDDISABLE() always returns a null string.
Description
With the help of this function, the keyboard can be turned on or off. This allows you to prevent any user input for a specific time through program control (even Ctrl-Alt-Del).
Notes

■ Be sure the program reenables the keyboard and does not leave

it locked when the program terminates.

Examples
Switch off the keyboard for 5 seconds:

KBDDISABLE(.F.)        // Turn off keyboard
   Inkey(5)            // Can't be shortened by input!
KBDDISABLE(.T.)        // Turn on keyboard
Platforms
Available on MS-DOS
See also

KBDEMULATE()  | 

Inserts characters into the BIOS keyboard buffer to emulate keyboard input
Syntax
KBDEMULATE(<cListKeyValue>) → nValue
Arguments
cListKeyValue Designates a keyboard input sequence to emulate. Use a maximum of 15 characters.
Returns
KBDEMULATE() returns the number of key codes it could not place in the BIOS buffer.
Description

KBDEMULATE() emulates keyboard input at a very low level. This function uses the BIOS input buffer to emulate input. This emulated input can then be used by another program. For example, you might stuff the next DOS command prior to the end of the application. Keyboard input for programs that use RUN() to be called is also feasible. The buffer capacity is a maximum of 15 characters. Some of the key codes may vary from keyboard to keyboard, but they still correspond to the values returned by SCANKEY(). Construct the codes as follows:

Chr(ASCII code) + Chr(Scan code)

As a rule, a scan code that is transmitted this way cannot be acknowledged by CA-Clipper or any subsequent program. For example, a DOS command can be passed as a string with spaces at each even position. This emulation of a scan code with a value of 32, would only cause problems when a subsequent program also checks the scan code (see Examples on the next page).

Notes

■ You can find the symbolic constants for key codes in the

include file ctscan.ch.

■ Problems may arise if you have incompatible hardware/BIOS, or

programs that extend the keyboard buffer.

■ Even though these emulated inputs occur at a low level, the

code translations defined with SetKXLat() still function.

Examples
■  These two programs always call each other reciprocally.
   Before returning to DOS, each program wedges the keys necessary to
   execute the other program in the BIOS buffer:

   Program 1 (PROG1.EXE)
   CLEAR
      @ 10, 10 SAY "Here is program 1  !"
      Inkey(5)                                // Wait a while...
      KBDEMULATE("P R O G 2 " + Chr(13))      // Start PROG2 in DOS
   RETURN

   Program 2 (PROG2.EXE)
   CLEAR
      @ 10, 10 SAY "Here is program 2  !"
      Inkey(5)                                // Wait a while...
      KBDEMULATE("P R O G 1 " + Chr(13))      // Start PROG1 in DOS
   RETURN

■  This program returns to DOS and then re-calls itself.  In this
   case, the desired extra byte is created with the Expand() function.
   The last token in the full path is the EXE name which includes the
   file extension.  The first token is the file name:

   xeName  :=  TOKEN(ExeName(), ":\")
   ExeName  :=  TOKEN(ExeName, ".", 1)
   KBDEMULATE(Expand(ExeName + Chr(13)))      // Expansion with blanks
   QUIT

■  The correct way to implement Expand():

   * WRONG! No blank before Chr(13)
   KBDEMULATE(Expand("TEST") + Chr(13))
   * RIGHT! Blank before Chr(13)
   KBDEMULATE(Expand("TEST" + Chr(13)))
Platforms
Available on MS-DOS
See also

KBDSPEED()  | 

Sets keyboard auto repeat speed
Syntax
KBDSPEED(<nDelay>,<nFrequency>) → lAmended

Warning!  Use AT keyboards only.
Arguments
nDelay Designates the amount of delay before you begin auto repeat. Possible values are from 0 to 3. The default value is 1.
nFrequency Designates the number of times a character repeats per second. Possible values are from 0 to 31. The default value is 12.
Returns
KBDSPEED() returns .T. when a new repeat rate is set successfully.
Description

KBDSPEED() sets the auto repeat rate for AT keyboards. Both the time delay and repeat rate for auto repeat can be set. The table below provides the values, their corresponding times, and repeat rates:

Table 13-3: Auto Repeat Time Delay

    <nDelay>     Delay Time
    0            250 millisecond
    1            500 millisecond
    2            750 millisecond
    3            1000 millisecond

Table 13-4: Repeat Rate for Depressed Keys

    <nFrequency>     Repeat Rate
    0                30 characters per second
    12               10 characters per second
    31               2 characters per second

Notes
■ It is best to determine valid values experimentally.
Examples
The quickest setting possible:

IF KBDTYPE() >0         // Only possible for AT's
   KBDSPEED(0, 0)
ENDIF
Platforms
Available on MS-DOS
See also

KBDTYPE()  | 

Determines the type of keyboard in use
Syntax
KBDTYPE() → nKeyboardType
Returns
KBDTYPE() returns a value that corresponds to the type of keyboard.
Description

KBDTYPE() determines the type of keyboard in use. This lets you check if the keyboard has F11/F12 keys available (which the CA-Clipper Tools supports). The possible keyboard values are:

Table 13-7: Coding of Keyboard Types

    Value   Keyboard Type
    0       PC keyboard
    1       AT keyboard
    2       Extended keyboard w/101/102 keys,  F11/F12

Notes

■ This function has been thoroughly tested, but there may be

problems with keyboards that are not fully compatible.

Examples
Query the keyboard:

? KBDTYPE()         // 2  Extended keyboard
Platforms
Available on MS-DOS
See also

KeySec()Harbour implementation  | 

Triggers a key trap after a time delay
Syntax
KeySec([<nKeyValue>,<nTime>, [<nCounter>],
   [<lMode>]]) → lActivated
Arguments
nKeyValue Designates the key code to place in the keyboard buffer.
nTime Designates the time, in seconds, after which the character is placed in the buffer. Negative values correspond to multiples of 1/18.2 seconds.
nCounter Designates the number of times the function occurs before it uninstalls itself. A value of -1 indicates that KeySec() will continue until it is specifically uninstalled. The default value is "Uninstall after the first call" (1).
lMode Designates whether the internal time counter restarts at the beginning (.T.) or not (.F.), after you press a desired key. The default value is "No new start with key stroke" (.F.).
() When called without parameters, the function is completely uninstalled.
Returns
KeySec() returns a value of .T. when installed correctly, so that the desired character will be placed in the keyboard buffer after the specified time.
Description

This function is useful in DEMO programs. If used in conjunction with KEYSEND(), you can simulate any keyboard input with time delays.

Use KeySec() in conjunction with CA-Clipper's SET KEY..TO, for key traps (just like KeyTime()). For example, this makes it possible to automatically write data still in the DOS buffer, to the hard drive at specific intervals during a GET..READ.

As soon as the character is placed in the keyboard buffer nCounter times, KeySec() uninstalls itself.

If the lMode parameter is specified as .T., the elapsed time counter is reset when you press any key.

If you want to specifically uninstall the function from the program, call it without parameters.

Notes

Warning! Always uninstall the function before you leave the program or use the CTUS.LIB Extended Drivers found in CA-Clipper Tools. The function changes interrupt vectors, and if the previous status is not restored before you exit the program, the system will eventually crash.

■ Only one time delay can be active. A new KeySec() deactivates

the previous one.

■ You can use any symbols defined in the CA-Clipper file

INKEY.CH. You can set any other keys described in the CA-Clipper Tools header file ctscan.ch.

Examples
■  Place Chr(7) in the keyboard buffer three times, every 5
   seconds:

   ? KeySec(7, 5, 3)             // (.T.)

■  Place Chr(255) in the keyboard buffer every 60 seconds until
   an uninstall occurs:

   ? KeySec(255, 60, -1)         // (.T.)

■  As soon as a key is pressed, the internal counter restarts
   from the beginning:

   ? KeySec(13, 60, -1, .T.)     // (.T.)
Platforms
Available on MS-DOS
See also

KeyTime()Harbour implementation  | 

Triggers a key trap at a specific clock time
Syntax
KeyTime([<nKeyValue>,<cClocktime>]) → lActivated
Arguments
nKeyValue Designates the character to place in the keyboard buffer.
cClocktime Designates the specified time to place the character in the keyboard buffer.
() When called without parameters, the function completely uninstalls.
Returns
KeyTime() returns a .T. to indicate the specified character was placed in the keyboard buffer at the desired time.
Description

Warning! Use on AT-class systems only!

KeyTime() executes a specific program at an indicated time. To do this, the function places the desired key code in the keyboard buffer at the selected clock time. If a procedure is established with SET KEY..TO, CA-Clipper calls the procedure if, or when, you are in a wait state. This allows you to perform specific tasks at a particular time of day such as file backups.

There is also a special variant over and above an exact time designation. You can specify "99" for hours, minutes, or seconds, which modifies the interpretation of this portion of the time designation. A time string of "10:99:00" instructs the function to trigger a key trap every minute between 10:00 and 10:59.

If you want to specifically uninstall the function from the program, call it without specifying parameters.

Notes

Warning! Always uninstall the function before you leave the program or use the CTUS.LIB Extended Drivers found in CA-Clipper Tools. This function changes the interrupt vectors, and if the previous status is not restored before you leave the program, a system crash will eventually occur.

■ Only one time monitor can be active at any given time. A

subsequent call to KeyTime() deactivates the previous one.

■ You can use any symbols defined in the CA-Clipper file

INKEY.CH. You can set any other keys described in the CA-Clipper Tools header file ctscan.ch.

Examples
■  Place key code 7 in the keyboard buffer at 12:30:

   ? KeyTime(7, "12:30:00")      // .T.

■  Place key code 255 in the keyboard buffer at 2:00 PM:

   ? KeyTime(255, "2")           // .T.

■  Place key code 7 in the keyboard buffer at midnight:

   ? KeyTime(7, "00:00:00")      // .T.

■  Set a key trap every second, starting at 11:59 PM:

   ? KeyTime(7, "11:59:99")      // .T.

■  Set a key trap every full hour:

   ? KeyTime(7, "99:00:00")      // .T.

■  Call with an invalid time:

   ? KeyTime(7, "25:30:00")      // .F.

■  Uninstall KeyTime():

   ? KeyTime()                   // .F.
Platforms
Available on MS-DOS
See also

KEYREAD()  | 

Reads already processed CA-Clipper keyboard buffer input
Syntax
KEYREAD() → cKeyValue
Returns
The returned string contains the characters from the CA-Clipper keyboard buffer that have already been read and processed by the program.
Description
With KEYREAD() you can read the keys that have already been processed by your application from the keyboard buffer. KEYREAD() offers the possibility of "looking into the past" of the current program execution so you can determine what the user has done up to that point. This gives you the ability to repeat particular actions, perform and undo functions, or build keyboard macros. KEYREAD() can also be very useful in searching for errors.
Notes

■ All the keys processed since the last execution of SET

TYPEAHEAD TO or KEYSEND() are placed in the keyboard buffer. Characters already in the buffer, but not yet read by a CA-Clipper program through an input instruction, are ignored by KEYREAD(). If the keyboard buffer is empty (as at program start, or after executing a KEYSEND() or SET TYPEAHEAD TO), the function returns a null string.

■ In contrast to the Clipper release form the Summer of 1987,

KEYREAD() in CA-Clipper returns the entire BIOS key code as defined in the ctscan.ch include file. If complete key code compatibility is required for an existing application, the ct.ch include file must be included. The ctscan.ch file also contains information regarding new keyboard function behavior.

Examples
cHistory   :=  KEYREAD()                  // Prior input
IF Right(cHistory, 2) == cSequence
   ? "You have left MEMOEDIT using Ctrl-END!"
ENDIF
Platforms
Available on MS-DOS
See also

KEYSEND()  | 

Simulates CA-Clipper keyboard buffer input
Syntax
KEYSEND(<cKeyValue>,[<lAdditiveMode>]) → lPassed
Arguments
cKeyValue Designates one or more sequences that are placed in the keyboard buffer.
lAdditiveMode Designates an optional parameter. If this parameter is .T., then the key codes passed are added to the contents of the keyboard buffer. If the parmeter is .F. or if no parameter is passed, the contents of the keyboard buffer are overwritten.
Returns
When the string has been placed successfully in the CA-Clipper keyboard buffer, the function returns a value of .T.. If an error occurs, the return value is .F..
Description

KEYSEND() works similarly to the CA-Clipper KEYBOARD command. However, it allows you to use other codes for the characters that are stuffed. Symbolic constants for these key codes can be found in the ctscan.ch include file and in Appendix A. By using this unique coding for characters in the keyboard buffer, KEYSEND() allows you to place keys in the buffer that CA-Clipper's KEYBOARD command does not permit, such as codes smaller than 0 or greater than 255 (e.g. all function keys and most Alt combinations). This unique coding is also helpful for two keys that have the same Inkey() value and cannot be differentiated with the KEYBOARD command.

If you want to place normal characters like letters and numbers in the keyboard buffer, it is better to use the CA-Clipper KEYBOARD command. Using CA-Clipper Tools functions for normal characters provides no real advantage. If, on the other hand, you want to simulate other keyboard input, like function or control keys, then KEYSEND() is best to use because function and control keys can be clearly differentiated.

As with the CA-Clipper KEYBOARD command, the entire contents of the keyboard buffer are cleared as soon as KEYSEND() passes a new character. If lAdditiveMode is .T., the function adds the key codes to the current buffer contents.

Notes

■ Key codes in CA-Clipper Tools have been extended, but the old

codes are still valid (see include file ctscan.ch).

■ The maximum length of the string to be saved is now calculated

as follows:

maximum allocatable memory / 2

Examples
Simulate the function key Alt-F10:

KEYSEND(KS_ALT_F10)
Platforms
Available on MS-DOS
See also

KSetCaps()Harbour implementation  | 

Queries/sets the system setting for CAPS LOCK
Syntax
KSetCaps([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates "CAPS LOCK" as on (.T.) or off (.F.). The default value is the system setting.
Returns
KSetCaps() returns the current setting for CAPS LOCK when no parameter is specified; otherwise, it returns the previous setting.
Description
KSetCaps() returns the current system setting for CAPS LOCK. If the lNewSwitch is specified, CAPS LOCK is set accordingly.
Examples
■  Query the CAPSLOCK function:

   lCaps:= KSetCaps()

■  Switch on CAPSLOCK and save the previous status:

   lOldCaps:= KSetCaps(.T.)
Platforms
Available on MS-DOS
See also

KSetIns()Harbour implementation  | 

Queries/sets the system setting for "INSERT"
Syntax
KSetIns([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether INSERT is on (.T.) or off (.F.). The default value is the system setting.
Returns
KSetIns() returns the current setting for INSERT when no parameter is specified; otherwise, it returns the previous setting.
Description
KSetIns() returns the current system setting for INSERT. If the lNewSwitch is specified; INSERT is set accordingly.
Examples
■  Query the INSERT function:

   lInsert: = KSetIns()

■  Switch on INSERT and save the previous status:

   lOldInsert: = KSetIns(.T.)
Platforms
Available on MS-DOS
See also

KSetNum()Harbour implementation  | 

Queries/sets the system setting for NUMLOCK
Syntax
KSetNum([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether "NUM LOCK" is on (.T.) or off (.F.). The default value is the system setting.
Returns
KSetNum() returns the current setting for NUM LOCK when no parameter is specified; otherwise, it returns the previous setting.
Description
KSetNum() returns the current system setting for NUM LOCK. If the lNewSwitch is specified, NUM LOCK is set accordingly.
Examples
■  Query the NUMLOCK function:

   lNumLock: = KSetNum()

■  Switch on NUMLOCK and save the previous status:

   lOldNumLock: = KSetNum(.T.)
Platforms
Available on MS-DOS
See also

KSetScroll()Harbour implementation  | 

Queries/sets the system setting for SCROLL LOCK
Syntax
KSetScroll([<lNewSwitch>]) → lOldSwitch
Arguments
lNewSwitch Designates whether "SCROLL LOCK" is on (.T.) or off (.F.). The default value is the system setting.
Returns
KSetScroll() returns the current setting for SCROLL LOCK when no parameter is specified; otherwise, it returns the previous setting.
Description
KSetScroll() returns the current system setting for SCROLL LOCK. If the lNewSwitch is specified, SCROLL LOCK is set accordingly.
Notes

■ This function turns the interactive movement mode for windows

on or off.

Examples
■  Query the SCROLL LOCK function:

   Scroll: = KSetScroll()

■  Switch on SCROLL LOCK and save the previous status:

   OldScroll: = KSetScroll(.T.)
Platforms
Available on MS-DOS
See also

LastDayOM()Harbour implementation  | 

Determines the number of days in a month
Syntax
LastDayOM([<dDate|nMonth>]) → nDaysInMonth
Arguments
dDate|nMonth Designates either a date or the number of a month. The default is the system date.
Returns
LastDayOM() returns the number of days in the month specified by dDate|nMonth.
Description
To administer due dates and other similar dates, it is useful to know the number of days that remain in a month. Specify either the day's date or month as a parameter, and you get the length of the month in days. If you subtract the number of days until today's date, you are left with the days that remain until month end.
Notes

■ Without the dDate|nMonth parameter, the function

automatically uses the system date. If there is an invalid number of months, LastDayOM() returns 0 as an error code.

Examples
How many days remain before the end of the month?

? "There are " + Str(LastDayOM() - Day(), 2) +;
   " days until the end of the month"
Platforms
Available on MS-DOS
See also

LASTKFUNC()  | 

Returns the function name that created the most-recent key trap
Syntax
LASTKFUNC() → cFunctionName
Returns
LASTKFUNC() returns the function name (KeyTime(), KeySec(), or com_Key()) that placed the character in the keyboard buffer.
Description
This function determines if a key code was placed in the keyboard buffer by KeyTime(), KeySec(), or com_Key().
Notes

■ If a trap is created by com_Key(), the last character of the

function name that is returned, is a number that corresponds to the port that triggered an interrupt.

Examples
Name the function that created the last error:

cTrapFunc: = LASTKFUNC()
IF cTrapFunc = "COM_KEY"
   ? "Interrupt via port", Right(cTrapFunc, 1)
ENDIF
Platforms
Available on MS-DOS
See also

LASTKLINE()  | 

Returns the line number of the most-recent key trap
Syntax
LASTKLINE() → nLineNumber
Returns
LASTKLINE() returns a source code line number.
Description
This function notes the program lines where KeyTime(), KeySec(), com_Key(), or com_SKey() placed a key code in the keyboard buffer. With CA-Clipper, key traps only become active when a wait state is triggered. This function differs from the CA-Clipper ProcLine() function because it returns the line number where the respective result occurs, rather than the line of the input command that triggered the trap.
Notes

LASTKLINE() returns a value, only if the program compiles

without the compiler switch value of -l (suppress line number information).

■ The function returns a value of 0 when the executed line is in

CA-Clipper Tools, the external function, or -1 option.

Examples
Return the line number of the last key trap:

? "Trap by", LASTKFUNC(), "in line", LASTKLINE()
Platforms
Available on MS-DOS
See also

LASTKPROC()  | 

Returns the procedure name that was interrupted
Syntax
LASTKPROC() → cProcedureName
Returns
LASTKPROC() returns the name of the procedure or function (KeyTime(), KeySec(), com_Key(), or com_SKey()) that places a character in the keyboard buffer when executed.
Description
CA-Clipper Tools notices when other procedures or functions encounter an interrupt. LASTKPROC() does not return the procedure name triggered by an input field key trap (as with GET..READ); instead, it returns the procedure name that was interrupted.
Notes

■ This function also returns the names of user-defined functions

(UDFs).

Examples
Return the procedure name that was interrupted:

IF LASTKPROC() = "INPUT"
   * Note to user
   @ 24, 30 SAY "One moment please!"
ENDIF
Platforms
Available on MS-DOS
See also

Like()Harbour implementation  | 

Compares character strings using wildcard characters
Syntax
Like(<cString1>,<cString2>) → lEqual
Arguments
cString1 Designates the wildcard string for comparison. All wildcards must be in this character string.
cString2 Designates the string to compare to cString1.
Returns
Like() returns .T. when, after taking wildcards into account, both character strings are equal.
Description
This function allows you to compare two character strings with one another, where the first can contain wildcard characters. This is similar to the way wildcard characters are used in conjunction with DOS commands but not identical. Any single character matches a "?" in the first string (see examples). The "*" within cString1 can be placed anywhere and matches multiple characters. You can also use multiple "*".
Notes

■ You can also use wildcard characters in conjunction with an

array of other string functions by using the SetAtLike() switch, but only for the "?".

Examples
■  This example shows differences from DOS:

   Dir XYZ?.DBF                     // shows XYZ.DBF and XYZ1.DBF

   ? Like("XYZ?", "XYZ")            // .F.
   ? Like("XYZ?", "XYZ1")           // .T.

■  This example shows other combinations:

   ? Like("*OG.*", "PROG.PRG")      // .T.
   ? Like("*OG.*", "LOG.PRG")       // .T.
   ? Like("*R*T*", "PROTO")         // .T.
   ? Like("*R*T*?", "PROTO")        // .F.
   ? Like("*R*T*?", "PROTO2")       // .T.

■  Use wildcards in the first parameter only:

   ? Like("*PER", "CLIPPER")        // .T.
   ? Like("CLIPPER", "*PER")        // .F.
Platforms
Available on MS-DOS
See also

Log10()Harbour implementation  | 

Computes the common logarithm
Syntax
Log10(<nValue>) → nLog10
Arguments
nValue Designates a number for which the base 10 logarithm is determined.
Returns
Log10() returns the base 10 logarithm for the nValue number.
Description
Log10() determines the common logarithm for a number.
Notes

■ For non-mathematicians, look at it this way: to what power

must 10 be raised (10n) so that nValue results?

Examples
Display common logarithm values:

? Log10(0.01)            // -2.00
? Log10(2)               //  0.30
? Log10(100)             //  2.00
? Log10(Infinity())      //  308.25
Platforms
Available on MS-DOS

LToC()Harbour implementation  | 

Converts a logical value into a character
Syntax
LToC([<lValue>]) → cCharacter
Arguments
lValue Designates the logical value that is converted. The default value is .F..
Returns
The character returned corresponds to the logical value specified in the parameter.
Description
In contrast to the LToN() function, which converts a logical value into a number, LToC() returns a value for the type character string. This can be particularly helpful with combined index keys.
Examples
■  Without parameters, .F. is assumed:

   ? LToC()               // "F"

■  Return a letter that corresponds to the specified logical
   value:

   ? LToC(.F.)            // "F"

   ? LToC(.T.)            // "T"

■  Other functions can return the logical value:

   ? LToC(Deleted())      // "T" or "F"
Platforms
Available on MS-DOS
See also

LToN()Harbour implementation  | 

Converts a logical value into a numeric value
Syntax
LToN([<lValue>]) → nLogicalValue
Arguments
lValue Designates the logical expression to convert. The default value is .F..
Returns
If you designate a .T., LToN() returns a 1; with .F., it returns a 0.
Description
LToN() converts a logical value into a numeric value. This allows indexing on a logical field.
Notes
■ The function treats a missing parameter as .F..
Examples
Determines the number of days in a year:

? "The year has " + Str(365 + LToN(IsLeap()), 3) + "  days."
Platforms
Available on MS-DOS
See also

Mantissa()Harbour implementation  | 

Determines the mantissa of a floating point number (base2)
Syntax
Mantissa(<nFloatingPointNumber>) → nMantissa
Arguments
nFloatingPointNumber Designates any decimal number.
Returns
Mantissa() returns the mantissa of the nFloatingPointNumber number.
Description
This function supplements Exponent() to return the mantissa of the nFloatingPointNumber number.
Notes

■ The mantissa value can be 0 or in the range of 1 to 2.

■ The following calculation reproduces the original value:

Mantissa(nFloatingPointNumber)* 2^Exponent(`FloatingPointNumber =

nFloatingPointNumber)

Examples
Display the mantissa for the following values:

? Mantissa(0)            // Result:  0.00
? Mantissa(100)          // Result:  1.56
? Mantissa(INFINITY)     // Result:  2.00
? Mantissa(0.01)         // Result:  1.28
? Mantissa(-100)         // Result: -1.56
? Mantissa(-0.01)        // Result: -1.28
? Mantissa(-1.01)        // Result: -1.01
? Mantissa(-2.01)        // Result: -1.01
Platforms
Available on MS-DOS
See also

MaxCol()  | 

Extends the CA-Clipper MaxCol() function
Syntax
MaxCol([<lMode>]) → nMaxColumn
Arguments
lMode When .F. is passed, or when no parameter is specified, the function returns the highest column number of the selected window. When .T. is passed, it returns the highest column number for the entire screen. The default value (.F.) returns the highest column number for the selected window.
Returns
MaxCol() returns the highest column number available within a window or within the physical screen.
Description
MaxCol() is also a CA-Clipper function. Without parameters, or when specifying .F., MaxCol() always returns a value for the selected window. In the absence of CA-Clipper Tools, this value is always Window 0, which is exactly the same size as the entire screen. However, if the extended driver CTUS.LIB and the CA-Clipper Tools window functions are implemented, this value can change. If you want the highest column for the entire screen, regardless of the window selected, you can pass .T. for the optional lMode parameter.
Notes

■ The explanation of this function was taken from the Video

Functions chapter and placed in the Extended Driver chapter. Now all CA-Clipper Tools functions that replace and/or extend CA-Clipper functions when CTUS.LIB is linked in are in the same chapter. The extensions to the CA-Clipper versions of these functions are only of interest when used in conjunction with the other extended driver functions and their accompanying windows.

Examples
Display the highest column number:

WOpen(10, 10, 20, 70)            // Open a window
? MaxCol()                       // Relates to a window
? MaxCol(.T.)                    // Back to the physical screen
Platforms
Available on MS-DOS
See also

MaxLine()Harbour implementation  | 

Finds the longest line within a string
Syntax
MaxLine(<cString>) → nLength
Arguments
cString Designates the string that is processed.
Returns
The function returns the maximum line length necessary to display the cString text without automatic line breaks.
Description
MaxLine() looks for the longest line within a character string. This allows you to determine the required width for a window to display text (MEMO fields). In this way the text can be displayed without additional line breaks.
Notes

■ With the exception of the carriage return and the line feed,

this function treats all characters as printable with a width of 1. If the cString text contains tabs, then you must first use the TabExpand() function to expand the tabs to spaces.

Examples
A function, based on the maximum line length, automatically performs a
suitable call of MemoEdit():

FUNCTION SHOWMEMO(cMemo)

LOCAL cMessage, nHeight, nWidth

   nHeight   :=  Min(NumLine(cMemo), MaxRow() -1)
   nWidth    :=  Min(MaxLine(cMemo), MaxCol() -1)

   IF nWidth = 0
      cMessage  :=  "The memo field is empty"
   ELSE
      cMessage  :=  ""
      @ 0, 0 TO nHeight +1, nWidth +1 DOUBLE
      MemoEdit(cMemo, 1, 1, nHeight, nWidth, .F.)
   ENDIF
   RETURN(cMessage)
Platforms
Available on MS-DOS
See also

MaxRow()  | 

Extends the CA-Clipper MaxRow() function
Syntax
MaxRow([<lMode>]) → nMaxRow
Arguments
lMode Designates the highest row nmber for the selected window or for the entire screen. When .F. is passed, or when no parameter is specified, the function returns the highest row number of the selected window. When .T. is passed, it returns the highest row number for the entire screen. The default value (.F.) returns the highest row number for the selected window.
Returns
MaxRow() returns the highest row number available within a window or within the physical screen.
Description
MaxRow() is also a CA-Clipper function. Without parameters, or when you specify .F., MaxRow() always returns a value for the selected window. In the absence of CA-Clipper Tools, this value is always Window 0, which is exactly the same size as the entire screen. However, if the extended driver CTUS.LIB and the CA-Clipper Tools window functions are implemented, this value can change. If you want the highest row for the entire screen, regardless of the window selected, you can pass .T. for the optional lMode parameter.
Notes

■ The explanation of this function was taken from the Video

Functions chapter and placed in the Extended Driver chapter. Now all CA-Clipper Tools functions that replace and/or extend CA-Clipper functions when CTUS.LIB is linked in are in the same chapter. The extensions to the CA-Clipper versions of these functions are only of interest when used in conjunction with the other extended driver functions and their accompanying windows.

Examples
Display the highest row number:

WOpen(10, 10, 20, 70)         // Open a window
? MaxRow()                    // Relates to a window
? MaxRow(.T.)                 // Back to the physical screen
Platforms
Available on MS-DOS
See also

MAXFONT()  | 

Determines the number of available fonts
Syntax
MAXFONT() → nFontCount
Returns
MAXFONT() returns the number of fonts you can load simultaneously within the screen card in use.
Description
Depending upon the screen adapter and its available memory, a various number of screen fonts can be loaded simultaneously. MAXFONT() returns the maximum number of loadable fonts and is very helpful when used in conjunction with FONTLOAD() or SetFont().
Notes

■ As a rule, EGA adapters support four different font areas and

VGA adapters support eight.

Examples
■  Load a font in the highest font area available...

   FONTLOAD("ITALIC.016", MAXFONT())

■  ...and then select that font:

   FONTSELECT(MAXFONT())
Platforms
Available on MS-DOS
See also

MAXPAGE()  | 

Determines the number of available screen pages
Syntax
MAXPAGE() → nMaxPage
Returns
This function returns the number of the maximum available video "pages". A return of 0 means that only one page is available; so, the actual number of available pages is MAXPAGE() +1.
Description
MAXPAGE() allows you to determine the number of screen pages that are available for use on the display adapter. This information can be particularly valuable when you use the SETPAGE() or PAGECOPY() function.
Examples
Find the maximum number of available screen pages:

? MAXPAGE()                  // Result 3 means 4 pages
Platforms
Available on MS-DOS
See also

MDY()Harbour implementation  | 

Returns a date in the "Month DD, YY" format
Syntax
MDY([<dDate>]) → cDate
Arguments
dDate Designates the date from which to create a string. The default is the system date.
Returns
MDY() returns a character string in Month DD, YY, or "Month DD, YYYY" format.
Description

MDY() returns the date in a character string that contains the day, name of month, and year. The CA-Clipper SET CENTURY ON/OFF switch determines whether or not the year is displayed in 2 or 4 digits.

If the function is called without a parameter, it automatically uses the current system date.

Notes

■ The returned month name always depends on which CA-Clipper

nations module is in use. A German or French version of CA-Clipper returns the appropriate month names, despite its characteristically American display.

Examples