


               Z O R T E C H  C+
             Compiler Version 3.0
      L I B R A R Y   R E F E R E N C E
                  G U I D E






















        Copyright (c) 1991 by Zortech Ltd. - All Rights Reserved

Table Of Contents
1 Introduction to the Libraries . . . . . . . . . . . . . . . . . . .
  1.1 Summary of the Zortech Libraries  . . . . . . . . . . . . . . .
  1.2 Typographic Conventions . . . . . . . . . . . . . . . . . . . .

2 Include Files, Globals and Types  . . . . . . . . . . . . . . . . .
  2.1 Include Files . . . . . . . . . . . . . . . . . . . . . . . . .
  2.2 Global Variables  . . . . . . . . . . . . . . . . . . . . . . .
  2.3 Standard Types  . . . . . . . . . . . . . . . . . . . . . . . .

3 The TSR Package . . . . . . . . . . . . . . . . . . . . . . . . . .
  3.1 Introduction  . . . . . . . . . . . . . . . . . . . . . . . . .
  3.2 Supplied Files  . . . . . . . . . . . . . . . . . . . . . . . .
  3.3 Writing Your TSR Pop Up . . . . . . . . . . . . . . . . . . . .
  3.4 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . .
  3.5 Problems  . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 The IOStreams Library . . . . . . . . . . . . . . . . . . . . . . .

  4.1 Stream Control - Class ios  . . . . . . . . . . . . . . . . . .
  4.2 Class ios Function Reference  . . . . . . . . . . . . . . . . .
  4.3 Output - Class ostream  . . . . . . . . . . . . . . . . . . . .
  4.4 Class ostream Function Reference  . . . . . . . . . . . . . . .
  4.5 Input - Class istream . . . . . . . . . . . . . . . . . . . . .
  4.6 Class istream Function Reference  . . . . . . . . . . . . . . .
  4.7 Input and Output - class iostream . . . . . . . . . . . . . . .
  4.8 Class iostream - Public Interface . . . . . . . . . . . . . . .
  4.9 Streams with Assignment . . . . . . . . . . . . . . . . . . . .
  4.10 Streams with Assignment - Function Reference . . . . . . . . .
  4.11 Buffering - Class streambuf  . . . . . . . . . . . . . . . . .
  4.12 Class streambuf - Function Reference . . . . . . . . . . . . .
  4.13 A streambuf Specialized for Files - filebuf  . . . . . . . . .
  4.14 Class filebuf - Function Reference . . . . . . . . . . . . . .
  4.15 File Based Input Streams - Class ifstream  . . . . . . . . . .
  4.16 Class ifstream - Function Reference  . . . . . . . . . . . . .
  4.17 File Based Output Streams - Class ofstream . . . . . . . . . .
  4.18 Class ofstream - Function Reference  . . . . . . . . . . . . .
  4.19 File based Output Streams - Class fstream  . . . . . . . . . .
  4.20 Class fstream - Function Reference . . . . . . . . . . . . . .
  4.21 A streambuf Specialized for In Memory Operations . . . . . . .
  4.22 Class strstreambuf - Function Reference  . . . . . . . . . . .
  4.23 Input and Output Streams Using strstreambuf  . . . . . . . . .
  4.24 Strstream Classes - Function Reference . . . . . . . . . . . .
  4.25 A stdio FILE streambuf . . . . . . . . . . . . . . . . . . . .
  4.26 Class stdiobuf - Function Reference  . . . . . . . . . . . . .
  4.27 Manipulators with Parameters . . . . . . . . . . . . . . . . .

5 The Complex Class . . . . . . . . . . . . . . . . . . . . . . . . .
  5.1 Class Definition  . . . . . . . . . . . . . . . . . . . . . . .
  5.2 Function Reference  . . . . . . . . . . . . . . . . . . . . . .

6 A C++ Shell for the Flash Graphics Facilities . . . . . . . . . . .
  6.1 Graphics Functions  . . . . . . . . . . . . . . . . . . . . . .
  6.2 Class Definition - FgDisp . . . . . . . . . . . . . . . . . . .
  6.3 Function Reference - FgDisp . . . . . . . . . . . . . . . . . .
  6.4 Class Description - Fg  . . . . . . . . . . . . . . . . . . . .
  6.5 Function Reference - Fg . . . . . . . . . . . . . . . . . . . .
  6.6 Class Description - FgDot . . . . . . . . . . . . . . . . . . .
  6.7 Function Reference - FgDot  . . . . . . . . . . . . . . . . . .
  6.8 Function Reference - FgLine . . . . . . . . . . . . . . . . . .
  6.9 Function Reference - FgThickLine  . . . . . . . . . . . . . . .
  6.10 Function Reference - FgBox . . . . . . . . . . . . . . . . . .
  6.11 Function Reference - FgFillBox . . . . . . . . . . . . . . . .
  6.12 Function Reference - FgChar  . . . . . . . . . . . . . . . . .
  6.13 Function Reference - FgMatrix  . . . . . . . . . . . . . . . .
  6.14 Function Reference - FgString  . . . . . . . . . . . . . . . .
  6.15 Function Reference - FgCircle  . . . . . . . . . . . . . . . .
  6.16 Function Reference - FgArc . . . . . . . . . . . . . . . . . .
  6.17 Function Reference - FgEllipse . . . . . . . . . . . . . . . .
  6.18 Function Reference - FgPolygon . . . . . . . . . . . . . . . .
  6.19 Function Reference - FgFilledPolygon . . . . . . . . . . . . .

7 The C Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8 The List Toolkit  . . . . . . . . . . . . . . . . . . . . . . . . .
  8.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  8.2 Variables, Typedefs and Defines . . . . . . . . . . . . . . . .
  8.3 Function Reference  . . . . . . . . . . . . . . . . . . . . . .

9 Debugging Dynamic Memory Allocation . . . . . . . . . . . . . . . .
  9.1 Introduction  . . . . . . . . . . . . . . . . . . . . . . . . .
  9.2 The MEM Package . . . . . . . . . . . . . . . . . . . . . . . .
  9.3 Conclusion  . . . . . . . . . . . . . . . . . . . . . . . . . .

10 Other C Tools  . . . . . . . . . . . . . . . . . . . . . . . . . .
  10.1 The Name Unmangling Toolkit  . . . . . . . . . . . . . . . . .
  10.2 The File Toolkit . . . . . . . . . . . . . . . . . . . . . . .
  10.3 The Filespec Toolkit . . . . . . . . . . . . . . . . . . . . .
  10.4 Pop-up Menus . . . . . . . . . . . . . . . . . . . . . . . . .

11 The C Standard Libraries . . . . . . . . . . . . . . . . . . . . .

A Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . .

B Technical Support . . . . . . . . . . . . . . . . . . . . . . . . .

1. INTRODUCTION TO THE LIBRARIES
Chapter 1 - Introduction to the Libraries
Introducing the Function Reference
This manual describes the run-time libraries supplied with the Zortech
C++ compiler. It covers all the Zortech functions supplied with all
editions of the compiler. Functions not supported under any particular
operating system or DOS Extender are clearly labeled as such.

The Standard Edition of the compiler contains 16 bit versions of the
libraries that support MS-DOS, 16 bit protected mode and Microsoft
Windows. The Developer & Engineering and Science Editions are
supplied with additional libraries designed to support OS/2 and 32 bit
protected mode applications.

Zortech C++ includes a number of run-time libraries. Which of these are
used for a compilation depends on the memory model selected and whether
the compilation is generating a Microsoft Windows application. These
libraries are automatically handled by the Zortech Programming System and
do not normally have to be specified to ZTC, ZWB or the system linker.
There is an additional set of libraries to provide the Flash Graphics
routines. The appropriate library must be specified to ZTC, ZWB or the
linker separately.

1.1  Summary of the Zortech Libraries
1.1.1  The Standard Libraries
The standard libraries include the implementation of iostreams, the
complex number routines the IEEE floating point routines and the C
Standard Library Functions. These have been designed for compatibility
with MS-DOS, OS/2 and UNIX systems as well as with the ANSI standard for
C compilers. The standard libraries contain many functions that allow
direct access to the facilities of the target operating environment. Many
of these are provided via special function "packages". Here is a summary
of the major packages provided.

The BIOS Package

This package of functions forms an interface to many of the useful
facilities provided by the IBM PC BIOS. These include disk functions,
time and date control, serial and parallel communications and many other
routines. Some of these functions may not be available when using the DOS
extenders.


The Disp Package

A full set of high performance screen writing functions is provided in
the Disp package. The package uses direct screen writing techniques to
provide text and attribute control, box drawing, screen save and restore
facilities and many more facilities for the manipulation of text screens.

The DOS Package

This is analogous to the BIOS package except that it provides an
interface to operating system calls. These functions are supported under
both MS-DOS and OS/2 and most of these functions are available when using
the DOS extenders.

The EMM Package (MS-DOS only)

This contains a full set of functions for allocating and using expanded
(EMS or LIMS) memory. It is provided as an alternative to the support
built into the compiler via the handle pointer type. For details of the
latter refer to the chapter The Handle Pointer Type in the Compiler
Guide. These functions are supported under real mode MS-DOS only.

The Handle Package

This package allows the allocation of handle memory to __handle pointers.
For OS/2 and 32 bit memory models these are equivalent to normal far
pointers.

The Interrupt Package

This package allows the programmer great flexibilty in installing and
removing interrupt handlers, including provision for internal stack
handling and for chaining existing interrupts. These functions are
supported under MS-DOS only.

The Mouse Package

This package provides an interface to a compatible mouse driver. It
allows full control of the mouse including position reports, button
status and counters, sensitivity, cursor shape and control and the
ability to install a mouse signal handler.

The Page Package

The Page package allows the programmer to turn a block of memory from
almost any source into a heap, from which memory can be dynamically
allocated and freed.

The Sound Package

Functions are provided for producing sounds of controllable duration and
pitch via the computer & built-in speaker.

The Swap Package (MS-DOS only)

The Swap package allows programs that use the spawn() or system()
functions to temporarily remove themselves from memory so that the
spawned program can execute with the maximum possible memory available.
It does this by swapping the programs memory image out to a temporary
disk file. Facilities are provided for piping the spawned program s
standard output to a disk file or screen area (window),

The Time Package

Functions are provided to obtain and manipulate time and dates in various
formats.

The TSR Package

Small model programs can be simply and easily turned into Pop-Up or TSR
programs by means of the routines in this library. Many of the standard
library functions can be used within a TSR. These functions are only
supported under real mode MS-DOS.
1.1.2  The Flash Graphics Library
This library contains the functions that implement the Zortech graphics
capability. Zortech Flash Graphics is a very high performance graphics
system providing a full set of graphics primitives. Sophisticated
graphics systems can be built up using these routines and support for a
wide range of display adaptors is provided.
1.1.3  C Tools
The C tools are a series of programming aids that are provided as source
for use by the C/C++ programmer if required. They do not form part of the
C standard library and their portability is not guaranteed.

1.2  Typographic Conventions
 There are a number of ways in which the information in this manual is
 presented. The double line in the margin is used to emphasize important
 points and these paragraphs are boxed for further emphasis. Code examples
 and screen output are set in a typewriter face. New concepts and keywords
 are set in italics when first introduced, as are references to other
 sections of the manual. In the initial chapters of the manual, as in
 other Zortech C++ manuals, the left hand column of each page provides
 key referencing information, including section numbers, figure and
 diagram information and section titles. The header of the left hand page
 shows the current page and chapter. Similarly the right hand page header
 provides the specific section and the page number. Within the
 alphabetical listing of library functions, the left hand column contains
 the function name for each new function description. The left and right
 hand page headers contain the current page, and the last function
 described on each double-page spread is shown on the right.

NOTE: Much of the formatting described above is not possible in this
on-line version of the manual.

2. INCLUDE FILES, GLOBALS AND TYPES
Chapter 2 - Include Files, Globals and Types
2.1  Include Files
This section details the contents of the Zortech C++ standard header
files. Those header files that are included in the ANSI specification are
so labelled. This does not mean that all the functions declared in that
file are ANSI. Refer to the individual entry for a function to determine
whether it is included in the ANSI C specification.

2.1.1  assert.h (ANSI)
Defines the assert macro. The definition of assert is dependent on
whether or not the identifier NDEBUG has been defined. If NDEBUG is
defined the assert macro is defined as empty text.

2.1.2  bios.h
This file contains structure definitions and function declarations for
the BIOS package.

2.1.3  cerror.h
This file contains function prototypes for the critical error handling
routines. It also contains the pointer to the user supplied error
handler: int (* _far _cdecl _cerror_handler)(int *ax, int *di);

2.1.4  conio.h
This file contains function prototypes for the console and port I/O
routines:

2.1.5  cerror.h
This file contains function prototypes for the Ctrl-C handling routines.
It also contains the pointer to the user supplied Ctrl-C handler: void (*
_far _cdecl _controlc_handler)(void);

2.1.6  ctype.h (ANSI)
This file defines macros used in character classification. These macros
are:

   isalnum               isalpha               iscntrl
   isdigit               isgraph               islower
   isprint               ispunct               isspace
   isupper               isxdigit              isascii
   toascii

2.1.7  direct.h
This file contains prototypes for the functions involved with directory
handling.

2.1.8  disp.h
This file declares the global variables and associated functions that
comprise the Disp Package. There are a number of global variables
declared in this file. They should be considered read-only.

2.1.9  dos.h
This file contains global variable declarations, type and macro
definitions and function declarations for the MS-DOS interface functions,
including the DOS package. It also contains inline versions of inp, inpw,
outp and outpw.

The macros defined are:

   FP_SEG                FP_OFF                MK_FP

2.1.10  emm.h
This file contains structure and function declarations for the EMM
package. One structure is defined:

    struct emm_handle_s

2.1.11  errno.h (ANSI)
This file contains the declaration and defined values for the global
variable errno.

2.1.12  exitstate.h
This is the header file for the exitstate functions. These functions are
used to push and pop the exit frame, so exit & atexit return points can
be controlled. This is useful when writing for Microsoft Windows and for
turning a standalone program into a subroutine.

2.1.13  fcntl.h
This file contains the definition of the Microsoft compatible read/write
modes for the open function. This file need only be included if the extra
modes are required, otherwise the inclusion of io.h is sufficient.

2.1.14  fg.h
This file defines the BIOS video modes, rotation modes, writing modes,
line types, colors, basic types and macros, and declares global variables
and functions for the Flash Graphics package. Also defined is a symbol of
the form fg_version_sync_month_date_year to ensure that the header file
matches the library.

2.1.15  float.h (ANSI)
This file contains the definition of constants that specify the
implementation limits of the floating point types.

2.1.16  fltenv.h
This file contains the macro definitions and function prototypes for the
floating point environment. It is documented in the Numerics Programming
Guide supplied with the Engineering and Science Edition.

2.1.17  fltpnt.h
This file contains the macro definitions and function prototypes for the
floating point NCEG floating point. It is documented in Numerics
Programming Guide supplied with the Engineering and Science Edition.

2.1.18  handle.h
This file contains the function prototypes and macros for the functions
involved with the implementation of handle pointers.

2.1.19  hugeptr.h
This file contains the function prototypes and macros for the hugeptr_
routines.

2.1.20  int.h
This file contains the function declarations for the Interrupt Package as
well as the definition of the structure used to pass information to the
interrupt service routine: struct INT_DATA

2.1.21  io.h
This file contains function declarations for the majority of the low
level file handling and I/O functions.

2.1.22  limits.h (ANSI)
This file contains the definition of constants that specify the
implementation limits of the integral data types.

2.1.23  locale.h (ANSI)
Contains country (locale) related information. Defines the structure
lconv.

2.1.24  math.h (ANSI)
This file defines the structure exception used by the function matherr,
as well as the function declarations of the math functions and the
definition of math related manifest constants.

2.1.25  msmouse.h
This file contains function declarations for the Mouse package.

2.1.26  page.h
This file contains macro definitions and function declarations for the
Page memory allocation package.

2.1.27  process.h
This file declares the process control functions.

2.1.28  setjmp.h (ANSI)
This file defines one type jmp_buf, which is the buffer used by the
functions setjmp and longjmp. It also contains their prototypes.

2.1.29  share.h
This file declares manifest constants for opening files in shared mode as
used with sopen().

2.1.30  signal.h (ANSI)
This file declares the signal handling functions and their related
manifest constants. The type sig_atomic_t is defined.

2.1.31  sound.h
This file contains the function declarations for the sound package.

2.1.32  stdarg.h
This file defines the type va_list and a number of macros involved with
accessing arguments in functions that take variable length arguments,
such as vprintf. The macro definitions in stdarg.h are:

   va_start              va_arg                va_end

2.1.33  stddef.h (ANSI)
This file contains the definition of one macro, and those of a number of
commonly used types. There is a declaration for one global variable,
errno, (which is also declared in errno.h). The following types are
defined:

   ptrdiff_t             size_t                wchar_t

The macro is:

   offsetof

2.1.34  stdio.h (ANSI)
This file contains the definitions of constants, macros and types along
with the declarations for the buffered I/O functions. A number of
manifest constants are also defined. The FILE structure type is also
defined. The other types defined are:

   size_t                fpos_t

The following macros are prototyped and defined:

   getchar         putchar         getc            putc
   ferror          feof            clearerr        fileno

2.1.35  stdlib.h (ANSI)
This file contains the definition of a number of types as well as
function prototypes for commonly used library functions. The types
defined are:

   size_t          wchar_t
   div_t           ldiv_t;

2.1.36  string.h (ANSI)
This file contains function declarations for the string and memory
manipulation functions.

2.1.37  swap.h
This file contains function prototypes and macros for the SwapX routines.

2.1.38  sys\locking.h
This file contains definitions of modes used in the locking function.

2.1.39  sys\stat.h
This file defines one structure type and declares two functions, stat and
fstat, concerned with determining file status information. This structure
type is: struct stat

2.1.40  tabsize.h
This file contains function definitions for the tab_size functions.

2.1.41  termio.h
UNIX compatibility header.

2.1.42  time.h (ANSI)
This file defines two macros, the structure tm and a number of other
types used by the Time package and declares all of the time related
functions. The types defined are

   size_t                clock_t               time_t;

The macros defined are:

   difftime              gmtime

2.1.43  tsr.h
This file contains the function declarations for the TSR package.

2.1.44  varargs.h
This file contains macros for UNIX C style variable arguments, as well as
the typedef va_list. The macros are:

   va_dcl                va_start              va_arg
   va_end

2.1.45  windows.h
Include file for Microsoft Windows applications

2.1.46  zpmapi.h
Include file for the ZPM DOS extender application programmer's interface.

2.2  Global Variables
There are several global variables that define the state of parts of the
program. The variable names and usage are described here.

2.2.1  _8087
Each time a program begins execution, a determination is made as to
whether an 8087 family co-processor is present. If it is, all floating
point calculations are performed using it. If not, all floating point
calculations are performed by software emulation. The _8087 global
variable defined in the compiler runtime module can be tested to see if a
coprocessor is present. Possible values are:

    0 - No coprocessor present
    1 - 8087 present
    2 - 80287 present
    3 - 80387 present

This is useful for code that must account for the differences between
coprocessors, or that could take advantage of the new instructions of the
80387. The behavior of the Zortech libraries is also controlled by this
flag.

2.2.2  _okbigbuf (T and S Memory Models Only).
This variable defines which memory allocation scheme will be used. There
are two methods.

Method 1    Allocate all available memory up to 64 kb to the heap upon
program startup. This is the default method.

Method 2    Allocate memory to the heap only as needed. This method is
to be used if a spawn function will be needed. To use, declare _okbigbuf
as shown below. For more information see the chapter The Zortech C++
Compiler in the Compiler Guide.

Usage:
int _okbigbuf = 0;
/* Allocate memory as needed */

_okbigbuf != 0 also means that large disk buffers are used for stream I/O
that are outside the data segment. This is all controlled by c.asm.

2.2.3  _osmajor
This variable defines the major version number of MS-DOS that is
executing. The value of _osmajor would be 3 running under MS-DOS 3.21 or
2 running under MS-DOS 2.11.

Usage:
extern unsigned char _osmajor;

2.2.4  _osminor
This variable defines the minor version number of MS-DOS that is
executing. The value of _osminor would be 0x11 running under MS-DOS 2.11
or 0x10 running under MS-DOS 3.1.

Usage:
extern unsigned char _osminor;

2.2.5  _psp
This variable contains the segment paragraph address of the program
segment prefix. This can be used to construct a far pointer allowing
access to the program segment prefix from within the program.

Usage:
extern unsigned _psp;

2.2.6  errno
This variable will be assigned error numbers after using certain library
functions, if errors occur. Below is a list of the defined constants for
errno, together with the error messages that are returned by the perror
function for each constant.

Constant         Meaning


E2BIG            Either the argument list, or the space required for the
                 environment information exceeds the system limit.

EACCES           Permission to access the file or a directory on the path
                 prefix has been denied, or the specified file has a
                 locking or sharing violation.

EBADF            The file specifier used is not a valid open file
                 descriptor.

EDEADLK          The file is locked and the retry limit has been exceeded.

EDOM             A math argument is out of DOMAIN.

EEXIST           The named file already exists.

EMFILE           The number of open files would exceed the system limit.

ENOENT           A path argument points to a null path name. The file or
                 path name cannot be found.

ENOEXEC          The specified file is not executable, or it has an invalid
                 executable file format.

ENOLCK           There are no more record locks available because the
                 system maximum has been exceeded.

ENOMEM           Not enough memory is available to carry out the requested
                 action.

ENOTDIR          A component of the path prefix is not a directory.

ERANGE           Result out of range (an argument to a math function is
                 too large).

Usage:
extern int errno;

See the library example for the perror function for a description of how
these error messages are used.

2.3  Standard Types
A number of library routines use values whose types are defined in
include files. These types are listed and described as follows, and the
include file that defines each type is given.

Standard Type    Description

clock_t          Defined in time.h, stores time values and is used by the
                 clock function.

diskinfo_t       Defined in bios.h, records information about disk drives
                 returned by the _bios_disk function.

div_t, ldiv_t    Structures, defined in stdlib.h. Used to store the values
                 returned by the div and ldiv functions.

dosdate_t        Defined in dos.h, records the current system date used in
                 the _dos_getdate and _dos_setdate functions.

dostime_t        Defined in dos.h, records the current system time used in
                 the _dos_gettime and _dos_settime routines.

DOSERROR         A structure, defined in dos.h. Used to store values
                 returned by the DOS "extended" error system call
                 (available under MS-DOS 3.0 and later).

double_t         The type that is the most efficient for double precision
                 floating point calculations.

emm_handle_s     A structure, defined in emm_h. Used to store information
                 relating to the number of pages owned by an EMS handle.

exception        The exception structure. defined in math.h, stores error
                 information for math routines and is used by the matherr
                 routine.

FILE             A structure, defined in stdio.h and used in all stream
                 input and output operations. The fields of the structure
                 hold information about the current state of the stream.

FIND             The FIND structure, defined in dos.h, stores information
                 returned by the findfirst and findnext functions.

float_t          The type that is the most efficient for single precision
                 floating point calculations.

INT_DATA         This structure is defined in int.h and is used by the
                 interrupt package to pass register information to the
                 user's interrupt service routine.

jmp_buf          An array type, defined in setjmp.h, that defines the
                 buffer used by the setjmp and longjmp routines to save
                 and restore the program environment.

REGS             This union, defined in dos.h, stores byte and word
                 register values to be passed to and returned from calls
                 to the MS-DOS interface functions, int86 etc.

size_t           Defined in stddef.h and several other include files, is
                 the result of the sizeof operator.

sig_atomic_t     Defined in signal.h, is the type of an object that can be
                 modified as an atomic entity in the presence of
                 asynchronous interrupts. It is used in the signal
                 routine.

SREGS            This structure, defined in dos.h, stores the values of the
                 segment registers. This structure is used by the MS-DOS
                 interface routines int86x, intdosx, and segread.

stat             This structure, defined in sys\stat.h, contains file
                 information returned by the stat and fstat routines.

time_t           Defined in time.h, represents time values in the time
                 package.

tm               This structure, defined in time.h, is used by the asctime,
                 gmtime, and localtime functions to store and retrieve
                 time information.

va_list          This array type, defined in stdarg.h, is used to hold
                 information needed by the va_arg and va_end macros. The
                 called function declares a variable of type va_list,
                 which may be passed as an argument to a variadic
                 function.

3. THE TSR PACKAGE
                                                                                                                                        3. THE TSR PACKAGE
Chapter 3 - The TSR Package
3.1  Introduction
The routines supplied with this package allow you to write programs in
Zortech C and C++ that can optionally become memory resident. Such
programs are often called TSRs or Pop Ups. In addition your programs can
optionally be given a slice of the processor's time, allowing a carefully
written program to run as a background process.

 The TSR package is only intended for use with real-mode MS_DOS. It is
 not supported with OS/2 or when using the 16 or 32 bit DOS extender. The
 terms, TSR and Pop Up mean the same thing. When your program is run it
 will become an extension to DOS. It will constantly monitor the keyboard
 looking for a key press that matches the key combination that you have
 declared in your program. This hotkey combination will be the signal for
 your program to spring into life, or pop up.

The term TSR comes from the fact that when invoked from the DOS prompt
your program can Terminate just like normal programs but it can also Stay
Resident in memory. You have probably seen and used many TSR programs,
now you will be able to write your own.

The difference between a Pop Up and a background program is quite
fundamental. The Pop Up is only active when the user invokes it with its
hot key, while the background program is automatically invoked by the
processor about 18 times every second. Do not worry too much at this
stage about the implications of each type of program, this will become
apparent when we go into more detail later.

3.1.1  History of the TSR
From day one, DOS was designed as a single tasking, single user operating
system and, since day two, programmers world wide have striven to change
this. The way this was finally achieved was to write programs that make
themselves extensions to DOS. They take over certain operating system
functions and provide additional facilities without the operating system
knowing anything about it. This is achieved via the terminate but stay
resident procedure mentioned earlier.

The first successful commercial TSR was a program called PROKEY from
Rosesoft released in 1982. Borland soon followed this with a program
called SIDEKICK, which sold beyond their wildest dreams.

With the next major release of DOS (2.0) in March 1983, Microsoft had
slipped in a couple of major TSRs of their own. These were ASSIGN,
GRAPHICS and most importantly PRINT (the print spooler).

However to help with the introduction of these programs they had also
modified the operating system to be slightly more welcoming to potential
TSR programs. They added the DOS function 31h, that allows .exe programs
to become memory resident and they added the background scheduler,
int 28h, so that PRINT could spool out documents while DOS, or the user,
was doing something else.

This new facility of the background scheduler was not made common
knowledge by Microsoft, but it was not long before astute programmers
realized that PRINT was in effect "multi-tasking". They began to work on
finding out how this was achieved.

As the new releases of DOS have come and gone, there have been no further
enhancements that have had any significant impact on the TSR programmer.
The only item of interest was the release of a little known (and little
used) special OEM version of DOS called MS-DOS 4.0 and later updated to
MS-DOS 4.1. This is not to be confused with the later release of a
commercial version 4.0 of MS-DOS and PC-DOS which is an altogether
different product.

The development of this OEM DOS version 4.0 was started in January 1983
but it did not become available until 1987. This version of DOS was an
attempt at providing a multi-tasking operating system. In the original
version (4.0) you could run all your normal programs exactly as you could
on DOS 3, but in addition you could multi-task certain specially written
programs in the background. The main problem with this was that it was
still a real mode operating system. This meant that it would run on
8088/86 chips and was limited to the 640k of memory. The next release
4.1, followed quickly. This still ran in real mode, but allowed the use
of expanded (EMS) memory to multi-task the special application software.
This OEM version of DOS is very rare and of no great value except to
certain hardware manufacturers.

3.1.2  How a TSR works
When you enter the name of a TSR program at the DOS prompt, it is treated
just like any other program. Indeed, at this stage it is exactly that.
DOS will allocate memory for it and load the .exe or .com file. It will
then pass control to the first instruction in the program.

Since DOS is a single tasking operating system, it hands the entire
resources of the computer over to the program, to do as it pleases. When
a program decides to become a TSR, it is giving up the safe world
controlled by DOS, for a hostile world in which it is every program for
itself. Therefore it must do certain things to protect itself.

Firstly it must intercept certain interrupts. For instance if it wants to
monitor the keyboard, to check for a special key combination, it would
normally capture interrupt 9 (although there other ways of doing this).
Interrupt 9 is an event that happens every time you press or release any
key on the keyboard. If it wants to take advantage of the background
scheduler, it must also capture int 28h.

What is an Interrupt?
On the PC there are 256 interrupts (0 through 255). Each interrupt has an
associated vector in memory. A vector consist of four bytes that contains
the far address of a routine to be performed when the associated
interrupt occurs. So when you press a key, an interrupt 9 is generated.
This results in the CPU freezing whatever it is doing, picking up the
address held in the associated vector and passing control to this
routine. When this called routine returns the processor will continue
from where it left off.

Capturing an interrupt consists of placing the address of your own
program in the interrupt vector. Thus we can see that if you capture int
9 for example, and point this to a section of your program, this will
automatically be called every time someone presses a key. If the program
intends to let itself be unloaded, it obviously has to first save the
contents of the vector, so that it can return it to its original state.

The next thing a TSR must do is decide on the minimum amount of memory it
requires. Once it has established this, it can ask DOS to terminate but
to leave its image in memory. When this is done DOS will terminate the
program and return to the DOS prompt. The memory that is requested by the
TSR will be reserved and any subsequent programs will be loaded into
memory after it.

At this stage the program is in a state of suspended animation. Its image
is in memory but it is not doing anything. Then when an interrupt that
has been captured occurs, the program will activate.

Let us add to the above scenario, by considering the timer interrupt, 8h.
This is automatically invoked by hardware 18 times a second. So if a TSR
also captures this interrupt, its chosen routines will also be serviced
18 times a second. Therefore if the TSR is written with this in mind it
can become a pseudo multi- tasking program, like PRINT.

3.1.3  What a TSR Can and Cannot Do
When a TSR is given control via one of the captured interrupts it cannot
do anything until it has checked to see if MS-DOS and the BIOS are
stable. Remember that MS-DOS is a single user operating system so it is
not surprising that when certain parts of it were written they were not
made to be re-entrant. In other words if MS-DOS is doing something and a
TSR "pops up" and asks it to do something else, the most likely result
will be a frozen computer.

This is overcome by the TSR program monitoring certain events. For
instance, it monitors any non-re-entrant code and refuses to pop up when
this is active. The TSR must monitor such things as disk access, and
MS-DOS operations to detect if they are in use.

The algorithm looks something like this:

1.  Is the TSR already active?...if yes end
        else
2.  Is Disk service busy?...if yes end
        else
3.  Is a graphics application running?...if yes end
        else
4.  Is DOS busy?...if yes then are we inside scheduler...if no end

The last condition needs a little explanation. Most TSRs chain into the
scheduler, int 28h. As explained earlier this is an interrupt that is
used by such programs as PRINT. It can be considered as an "all clear"
indicator. Whenever DOS finds itself free it will fire off an int 28h.
When this happens any program that is chained into int 28h will have a
chance to do some processing.

By chaining into this as well as another interrupt like 9 (keyboard) or 8
(timer), TSRs give themselves two bites at the cherry in their attempts
to pop up. What this actually means is that if your int 28h handler is
given control it can ignore the test to see if DOS is busy, because it
knows that int 28h is only fired when DOS is free. However if it is
another handler that gets control it must not continue if DOS is busy.
This can be demonstrated by attempting to pop up a TSR program, while at
the DOS prompt.

C>

When you see this on the screen, DOS is waiting for a command. This means
that it is busy. So any pop up that relies on only an interrupt 8 or 9,
will never pop up. However when DOS is waiting for input, there are a few
seconds here and there when it is safe to pop up and in these few
seconds, DOS will repeatedly issue interrupt 28hs.

Once your TSR gets past the above maze, it can then virtually continue as
normal. With one small proviso, it must not use a DOS service below 0Dh.
(A DOS service is called by placing the service number in AH and issuing
an interrupt 21h.)

You will be pleased to know that you do not need to concern yourself with
this housekeeping. The TSR routines will only let you proceed if it is
considered safe to do so. In addition if you attempt to perform any
illegal DOS services you will be given a warning on the screen. (See
Debugging later).

3.1.4  Pop Ups Within Pop Ups
We have seen that DOS has become more sociable towards memory resident
programs, (even though it actually thinks it is being sociable to
print.com), but what about TSRs being sociable with each other. The
original release of SIDEKICK demonstrated how not to write a sociable
program. It contained features such as forcing the contents of interrupt
vectors to a value it thought was correct even when another program was
using the same vector. This meant that dozens of other TSRs had trouble
running alongside SIDEKICK, and instructions like "Load this program
before SIDEKICK" became common place.

There are some guidelines that make for a more compatible TSR. These are:

1.  Chain into as few interrupts as possible

2.  In your interrupt handlers, always service the old interrupt
routine first. Unless of course you are adding features to an existing
service.

3.  Do not restore interrupt vectors unless you know that you are the
owner of the vector. In which case restore them as you found them.

All the above are implemented by the TSR routines. There is only one rule
that you must adhere to (if you want to write friendly TSRs): When inside
your pop up, at times when you are looping (for a key press etc.) give
other pop ups a chance by executing an int 28h (see function
tsr_service).

3.2  Supplied Files
tsr.h
This is the header file for the TSR package. It must be included in your
TSR program. It contains #defines for the scan codes and shift values
that you can use when declaring your hotkey combination in your programs.
It also contains the prototypes for the functions in the toolkit. Most
importantly it ensures that the correct memory allocation method is used
by the compiler. Failure to use this header file could result in your
programs taking far more memory than it actually needs.

resdemo.c
This file contains a sample program that you may wish to use for
reference when writing your own programs. It shows exactly how to declare
the necessary hot key and finger print declarations. It makes use of many
standard library functions, including the Display package.

tsrclock.c
This sample file is a program that uses the background option of the TSR
package. Use this as an example when attempting to write this type of
program. Background mode is explained in detail later.

3.3  Writing Your TSR Pop Up
Writing your TSR could not be simpler. Write and debug your program as
you would any normal program. Do not attempt to make it memory resident
until you are confident that it is bug free.

While writing your program keep the following points in mind:

 Do NOT use any functions that allocate memory (malloc etc.). You can
 use the Page package to manage your own memory if you wish.

 Do NOT use buffered file (*FILE) routines (fgets etc.), use the
 untranslated functions instead (open/read/close).

 Do NOT exit from any function, simply return.

3.3.1  Making Your Program Resident
If you examine the resdemo.c source code you will see that this program
starts in exactly the same way as any other program. The main function is
entered and the program examines the command line arguments. If none are
supplied it presumes you are attempting to load the software in memory
resident mode. So the software attempts to make itself resident by
calling:

tsr_install (int argument)

If this is successful, the function will NOT return. If it does return it
will pass back an error code which is covered later. Remember that you do
not have to make your programs immediately become memory resident. For
instance you could have a menu option that makes your program memory
resident.

You can see from the above that the function tsr_install takes one
argument, this can currently be one of two alternatives, depending on the
type of program your are writing. These alternatives are POPONLY and
TIMESLICE.

tsr_install (POPONLY);

This will make your program into a normal TSR pop up and the special
function popmain will only be called when the user presses the chosen
hotkey combination. The other alternative is:

tsr_install (TIMESLICE);

If you use this method, your program will be converted into a background
task and popmain will be entered repeatedly up to a maximum of 18 times
per second. With this latter method, popmain will also be entered when
the user presses the correct hotkey. Usually you will wish to determine
whether popmain was entered through the hotkey or because of the
timeslice algorithm.

You can ascertain the answer to this by examining a global variable
called _tsr_timeslice. Quite simply if popmain() was entered by the
timeslice algorithm this variable will be set to 1, otherwise it will be
set to 0. Examine the tsrclock.c source code to see this in action.

This example uses the hotkey to toggle the time display on or off. If you
decide to write a background task, you should design your program to be
as efficient as possible. Try and keep the processing done in each time
slice to a minimum. In other words keep your background tasks efficient
and brief. As mentioned in the earlier introduction to memory resident
programming you can make your program more compatible with other TSRs by
giving them a chance to pop up when you are at a convenient point within
your own TSR. You can do this with the tsr_service function.

void tsr_service (void)

For instance instead of waiting for a key press like this:

    bioskey(0);

Try this instead:

    while (bioskey(1) == 0)     /* while no key press */
        tsr_service();          /* give others a chance */
    bioskey(0);                 /* then get key as normal */

The function tsr_service, simply fires off a scheduler interrupt (int
28h). No value is passed to or returned from tsr_service.

3.3.2  Debugging
When you enter the world of TSR programming, you have to accept that
there are certain things you can never do and other things that you can
only do at certain times. Failure to adhere to these rules will probably
result in a frozen computer. However these problems are compounded in a
TSR written in C or C++, because you may know the rules, but you could
call a function that does not. This could result in difficult to trace
problems.

To help you with this, we have included a facility that will trap and
alert you to any possible bad practice within your TSR program. When you
use this facility and any illegal actions are detected, a window will
open with a (hopefully) meaningful message within it. This will help you
to track down the particular function call that is causing the problems.

To switch this debugging aid on, simply add the command,

    |TSR_DEBUG

to your existing tsr_install command. For instance, if you normally use
the form:

    tsr_install (POPONLY);

Simply extend this to,

    tsr_install (POPONLY|TSR_DEBUG);

likewise you could use,

    tsr_install (TIMESLICE|TSR_DEBUG);

 This facility does NOT attempt to cure any illegal actions it only
 alerts the user (programmer), waits for a key press and then allows the
 request to continue as normal. It will not stop a faulty program from
 freezing the computer, but it will explain why the computer is about to
 freeze!

When invoked the debugging routines can trap several of the most common
pitfalls that you may encounter. For each different problem you will see
a meaningful message displayed. These are as follows:

Dos function 0dh
Press a key

This means that some function in your program has made a call to INT 21h
(DOS function dispatcher) with the ah register set to a value below
hexadecimal 0dh. This is illegal in a TSR program.

To cure this, you could place displays in your code to track down the
exact function call causing the problem. Likely culprits are the getch
family.

Attempt to close std handle
Press a key

Every time you open a file, DOS allocates an handle to that file. Then
when you want to read or write to it, you use the handle that DOS gave
you on opening. The handles that DOS allocates start from 5 and increment
with each open request. The handles from 0000 to 0004 are reserved by DOS
for its standard devices. These are such things as keyboard / screen /
printer and com port.

It is quite possible for your program to close these reserved devices,
either intentionally or by accident. If you do ask DOS to close one of
its standard handles, the debugging code will presume you have done so in
error and it will inform you accordingly.

Memory Allocation
Not inside TSR!

Memory resident programs are given a chunk of DOS' 640k when they make
the transition from normal programs to TSRs. If they later make further
requests for additional memory, DOS will try to oblige and get itself
well and truly tangled. With this in mind the debugging software will
watch for any attempts to get additional memory and the above window will
appear to alert you of the request.

 If you want to dynamically manage memory within your TSR you should
 create a static buffer and turn this into a heap using page_initialize.
 You can then use page_malloc etc. to manage your memory. See the library
 entry for the Page package for more details.

There is one further error mesage that may be observed:

Exit detected
Use return instead

In a normal program you have probably used the exit function to abort
your program. However you must remember that DOS does not really know
about or understand TSR programs. It thinks that there is only ever one
program running. It presumes that the underlying application (Wordstar
etc.) and your TSR are one and the same. So if you end your program with
a call to exit, DOS will presume the underlying program has asked to exit
and it will duly abort it. To avoid any such conflict you should use
return only, never use exit.

3.3.3  Removing your Program
You will notice in the resdemo.c source code, that if a /R is placed on
the command line, the program will attempt to unload a PREVIOUSLY LOADED
copy of itself. It does this with a call to:

int tsr_uninstall (void);

This function will always return a value. The various return codes are
shown later. This function can be called, either from within the TSR when
it is active, or from a routine that is executed when your program is
called from the DOS prompt. If it is called from within the pop up when
it is active it will remove the current copy of the TSR program from
memory. So once the program has "popped down" it will not be able to pop
up again. If it is called when the program is executed from DOS it will
remove any previously loaded copy of itself.

If you intend to remove your program from memory, when it is popped up,
it is worth understanding a little of how DOS allocates and de-allocates
memory.

When a program is loaded by DOS, it is allocated one or more segments of
memory. A segment is up to 64k bytes. A clever program can trace through
the DOS allocated memory records and ascertain the owner of any segment
(or part segment) of memory. When you use the TSR toolkit, your programs
automatically have this ability and this is used when you try to remove
your program from memory.

When you call tsr_uninstall, it will look through the memory and return
to DOS any segments that have been allocated to your program. It will
also unhook any interrupts that are used by the TSR routines. However it
is important to realize that just because the segments are returned to
DOS it does not mean that your program is no longer in memory, it is and
it will continue to run after tsr_uninstall returns. Although DOS now
considers the memory previously allocated to your program to be free, in
reality it still contains an image of your program, this is why it will
continue to run. The freed blocks of memory will only be reused when DOS
needs to allocate memory for another program.

Consider the following situation:

1.  You load your TSR program, DOS allocates memory to it and returns
to the DOS prompt.

2.  You load an ordinary program, Wordstar for instance.

3.  You pop up your program from within Wordstar and it contains an
option to remove itself from memory. (just like the RESDEMO example)

4.  You select the option to uninstall the pop up.

In the above scenario you have in effect created an hole in DOS' memory,
this is because the memory was allocated as follows:

    DOS DRIVERS
    ...
    Your POP UP
    Wordstar

Now that DOS has regained the memory allocation blocks that were
allocated to your pop up a hole as appeared. However, DOS is perfectly
capable of managing such situations. It will only use the memory in the
"hole" if it is sufficient for its needs, it will not overwrite Wordstar
(or what ever).

Finally when Wordstar is exited, DOS will regain all the memory
associated with it and the hole will disappear. The return values from
tsr_install and tsr_uninstall are as follows:

Return      Description


0           Function successful

1           Can not load, program already loaded

2           Can not remove, the program is NOT loaded

3           Can not remove, another TSR program has been loaded on top of
            your program

3.3.4  Globals
In your source file you must specify certain variables that will be
referenced by the TSR routines. The value that you place in these
variables will determine how the TSR routines work.

HOTSHIFT and HOTSCAN

We have already stated that your (or any other) pop up TSR program must
have a special key sequence that it recognizes as being the signal for it
to pop up. This is usually called the hotkey combination. It is called a
combination because it is the combination of one or more shift keys and
an ordinary key (usually in the range A-Z). When this key combination is
pressed the pop up will take control of the machine resources and can run
as if it was the only program in the machine. The way that you specify
your hotkey combination in your programs is to declare and initialize two
variables called HOTSHIFT and HOTSCAN.

HOTSHIFT is an integer that must contain a value that represents the
shift keys you have chosen. The way to determine the value you should
place in this integer is as follows:

Choose your shift keys from one or more of the following available keys:

    LSHIFT  Left Shift key
    RSHIFT  Right Shift key
    CTRL    Control key
    ALT     Alt key

Then simply declare an int called HOTSHIFT and initialize it with your
chosen hot shift, like this:

    int HOTSHIFT=ALT+RSHIFT;

This would declare your hot shift as being the alt key + the right shift
key. You must also choose and declare the key that is to be used with the
shift. Choose a key in the range A-Z and declare an int called HOTSCAN.
Initialize it like this:

    int HOTSCAN=SCAN_Q;

This will declare your key to be Q, so when someone presses:

    ALT+RIGHT SHIFT+Q

Your program will pop up. Note that you must initialize HOTSCAN with a
scan value not the character itself:

    int HOTSCAN='Q'     /* WRONG! */
    int HOTSCAN=SCAN_Q  /* RIGHT! */

All the scan values for the keys A-Z and F1 to F10 are defined in the
tsr.h file. If you really need to use a key outside the A-Z range, simply
consult your favourite manual to find the scan value for the key you want
to use and initialize HOTSCAN with this value.

If you prefer not to use a scan value and you only want your hot key to
consist of shift keys all you have to do is declare HOTSCAN as follows:

    HOTSCAN=NO_SCAN;

This will instruct the TSR routines to ignore the scan value and only
test the shift key values.

tsr_fprint

This is a character string, 20 bytes long and it is your programs unique
finger print. This is used by the install and uninstall functions to
determine if your program is loaded in memory.

For example:

    char tsr_fprint[20]= "Prog ID";

Every time you write a new TSR program give it a unique finger print.

_okbigbuf

The TSR routines have to determine how much memory your program requires,
so that it can free the remaining memory and thus make it available to
any applications that may be run. In order for the routines to arrive at
an optimum figure your program should contain the following line above
your main function.

    extern int _okbigbuf = 0;

Failure to do this will simply result in a TSR which takes up too much
system memory.

_tsr_timeslice

As mentioned earlier, if you need to ascertain whether your popmain() was
called because the hotkey was pressed or because of the timeslice
algorithm, you can use the global _tsr_timeslice.

If the hot key was responsible this will be set to zero, if the algorithm
was responsible it will be set to 1. Using this you can provide a
background task that can still be popped up and configured in some way by
the user. For example, examining the tsrclock.c source code will show
that this is how it displays a clock on the screen and allows you to
press the hotkey to toggle the display on or off.

3.3.5  The Special Function popmain
When your hotkey combination is pressed the TSR routines will pass
control to a function in your program called popmain. When writing this
function, remember that at that point you are handed control of the
computer, it is up to you to save any areas of screen that you may
destroy, also remember to save the cursor position and shape. The
functions to do all this are supplied in the standard Zortech library,
see the library entry for the Display package.

When you have completed processing restore any areas of the screen that
you may have overwritten and return control from popmain back to the
calling TSR functions, they will return control to the underlying
application.

3.4  Limitations
The limitations of programs that use these routines are the same as for
any TSR program. Namely you can only pop up when DOS is stable and no
disk access is taking place. This is taken care of by the TSR routines.
However no TSR program can allocate memory or make calls to DOS functions
below 0Dh. There is the added problem that you may use a library function
that performs some invalid task and not know it. Library functions to
avoid are:

        malloc (or any other memory related command)

        Any buffered file usage (fread, fgets etc.).

3.4.1  A Complete Example
This is an example of the TIMESLICE facility of the TSR toolkit. If you
press the hotkey, you will toggle ON/OFF a clock on the screen. This
clock will run in the background, while you continue to work as normal in
the foreground.

/*
   TSRCLOCK.C
   Demo program for Zortech's Memory Resident Toolkit
*/
/* #include other.h here */

/*  ***********************************************  */
/*      All programs must have these statements      */

#include <tsr.h>                     /*must use this */
unsigned TSR_HOTSHIFT = CTRL+LSHIFT; /* Your hotkey  */
char     TSR_HOTSCAN  = SCAN_Q;      /* combination  */
char tsr_fprint[20] = "tsrclock.v1"; /* unique string*/

/*  In addition background programs must have this   */
extern unsigned _tsr_timeslice;

/*  ***********************************************  */
/*  ------------ Then enter your program ---------   */

union REGS regs;
int cur_pg, cur_s, cur_p;
int toggle = 1;
int hours, mins, secs;

int main (int argc, char *argv[])
{
    int i;

    if ((strncmp(argv[1],"/R",2) == 0) || (strncmp(argv[1],"/r",2) == 0))
        {
            i = tsr_uninstall();
            if (i == 0)
                printf ("Program removed\n");
                if (i == 2)
                    printf ("Can not remove, Program not loaded!\n");
                if (i == 3)
                    printf ("Can not remove,
                             Another program loaded above\n");
                exit (EXIT_SUCCESS);
            }

            printf ("Press Control+Left Shift+Q to
                     toggle clock ON/OFF\n");

            i = tsr_install (TIMESLICE | TSR_DEBUG);

            /* if it returns, error has occurred */
            if (i == 1)
                printf ("Can not load, program already loaded!\n");
            else
                printf ("Failed to install, error %i\n",i);
    return (EXIT_FAILURE);
}

void popmain (popmain)
{
/*
    POPMAIN is a special "reserved name" function, which
    the TSR routines will pass control to when the hot
    key is pressed.
*/
    if (_tsr_timeslice == 0)       /* if hotkey */
    {
        toggle = toggle * -1;      /* set toggle on/off */
        return;
    }
    if (toggle)                    /* only display when on */
        return;

    regs.h.ah = 0x2c;
    intdos (&regs, &regs);
    if (secs == regs.h.dh)         /* and if secs changed */
        return;

    hours = regs.h.ch;
    mins  = regs.h.cl;
    secs  = regs.h.dh;             /* save_cursor will destroy */

    save_cursor();
    disp_open();
    disp_move (0, 66);
    disp_setattr (14);
    disp_printf ("TIME: %2.2i:%2.2i:%2.2i", hours, mins, secs);
    disp_close();
    restore_cursor();
}

save_cursor()
{
     regs.x.ax = 15*256;
     int86 (0x10, &regs, &regs);
     cur_pg = regs.x.bx;
     regs.x.ax = 3*256;
     int86 (0x10, &regs, &regs);
     cur_p = regs.x.dx;
     cur_s = regs.x.cx;

     regs.x.dx = (24*256)+80;
     regs.x.ax = 2*256;
     regs.x.bx = cur_pg;
     int86 (0x10, &regs, &regs);
}

restore_cursor()
{
     regs.x.ax = 256;
     regs.x.bx = cur_pg;
     regs.x.cx = cur_s;
     int86 (0x10, &regs, &regs);

     regs.x.dx = cur_p;
     regs.x.ax = 2*256;
     int86 (0x10, &regs, &regs);
}

The above example can also be found on your distribution disks.

3.5  Problems
This package allows someone who has never heard of a "DOS BUSY FLAG" or
even seen an assembler program to write pop ups easily and quickly.
However, when you enter the world of the TSR you must expect problems. We
have taken every care to ensure that self induced problems are kept to a
minimum by trapping almost every action that you could inadvertently
perform to crash your own TSR.

If you experience problems with one of your programs, (most common will
be a complete lock up), please follow these simple steps to track down
the problem.

1.  Ensure that the debugging window does NOT open at any stage inside
your TSR.

2.  Place displays in your program in order to identify the instruction
or section of code that is causing problems.

3.  Check your own code thoroughly!

The TSR package has had an extensive testing period and so far no
problems have been found with it. So please ensure that your own code is
sound before assuming that the TSR package is at fault.

4. THE IOSTREAMS LIBRARY
Chapter 4 - The IOStreams Library
The IOStreams library was first published by AT&T as part of the version
2.0 release of their C++ compiler Cfront. A modified version has been
submitted to the ANSI committee to be considered for inclusion into the
C++ standard. The standardization process is not yet completed, but this
implementation of IOStreams is as close as practicable to that presented
to the ANSI committee.

4.1  Stream Control - Class ios
Input and output streams have features in common, including the need to
keep track of errors, control details of representation of numbers, the
treatment of whitespace and padding etc.

Class ios is a base class that provides this sort of functionality, from
which input and output classes (istream, ostream and iostream) are
derived.

The error handling features are particularly important. Three classes or
error are noted, described as eof, fail, and bad.

1. End of file (eof) errors indicate that no further characters could be
sent to or got from the associated stream.

2. Errors classed as fail mean that the particular operation attempted
was unsucessful, but generally that use of the stream can continue once
the error has been cleared.

3. Errors classed as bad probably mean that the stream is no longer
usable.

The public interface of class ios is as follows:

class ios {
  public:
    enum io_state {
        goodbit=0,
        eofbit =1,
        failbit=2,
        badbit =4
    };

    enum relative_to {
        beg,
        cur,
        end
    };

// The following enumeration applies to file related streams:

    enum open_mode {
        in         = 0x01,
        out        = 0x02,
        ate        = 0x04,
        app        = 0x08,
        trunc      = 0x10,
        nocreate   = 0x20,
        noreplace  = 0x40,
        translated = 0x80
    };

    enum format_mode {
        skipws     = 0x0001,
        left       = 0x0002,
        right      = 0x0004,
        internal   = 0x0008,
        dec        = 0x0010,
        oct        = 0x0020,
        hex        = 0x0040,
        showbase   = 0x0080,
        showpoint  = 0x0100,
        uppercase  = 0x0200,
        showpos    = 0x0400,
        scientific = 0x0800,
        fixed      = 0x1000,
        unitbuf    = 0x2000,
        stdio      = 0x4000,
    };

    static const long stickywidth;  // = 0x08000
    static const long spacing;      // = 0x10000

// Format bit sets
    enum format_mode_mask {
        basefield   = dec|oct|hex,
        adjustfield = left|right|internal,
        floatfield  = scientific|fixed
    };

// Constructor & destructor
    ios(streambuf *buffer);
    virtual ~ios();

// Functions to interrogate the error state
    int rdstate() const { return error_state; };

    int good() const;
    int eof() const;
    int fail() const;
    int bad() const;

    int operator!() const;
    operator void*();

// Set the error state
    void clear(int = 0);

// Set/ read the fill character
    char fill(char);
    char fill() const;

// Set/ read floating point precision
    int precision(int);
    int precision() const;

// Set/ read a tied output stream

    ostream *tie(ostream*);
    ostream *tie() const;

// Set/ read the format flags
    long flags(long);
    long flags() const;
    long setf(long bits_to_set, long mask = 0);
    long unsetf(long bits_to_clear);

// Set/ read a field width
    int width(int);
    int width() const;

// Other utilities

    streambuf *rdbuf() const;

    static void sync_with_stdio();

    static int bitalloc();

    static int xalloc();

    long  &iword(int index);
    void* &pword(int index);
};

The enum io_state is used when the state of the stream is to be reported:

goodbit          No errors - everything ok!

eofbit           Normally set when there is a genuine end of file
                 condition.

failbit          An error has ocurred, but is probably recoverable. The
                 stream is still in a useable state

badbit           An error has occurred such that the stream is not suitable
                 for further use.

The enum relative_to contains values used when moving the stream (file)
pointer within a stream:

beg              For seek operations relative to the beginning of the
                 stream (file)

cur              relative to the current position in the stream (file)

end              relative to the end of the stream (file)

The enumeration open_mode applies to file related streams:

in               Input allowed.

out              Output allowed.

ate              A seek to the end of the file to be performed during open.

app              All writes are to the end of  the file - implies out.

trunc            Existing contents of the file to be discarded. Implies out
                 unless ate or app specified as well.

nocreate         Open will fail if the file does not already exist

noreplace        Open will fail if the file does already exist

translated       CR/LF pairs to be translated to newline characters on
                 input and newline characters to be translated to CR/LF
                 pairs on output (the normal behavior for MS-DOS and
                 OS/2)

The enum format_mode is used in selecting stream formatting:

skipws           Skip past leading white space when extracting.

left             Left-adjust values when inserting (fill on the right).

right            Right-adjust values when inserting (fill on the left).

internal         When inserting, fill between the numeric sign or base
                 indicator and the value.

dec, oct, hex    Default radix for integers. If none specified, default is
                 decimal and normal C++ conventions will be respected on
                 input, as per showbase.

showbase         If this is set, base-16 numbers will be inserted with a
                 leading "0x", and base-8 numbers will have a leading
                 zero.

showpoint        If this is set, the floating-point inserters will print a
                 decimal point and trailing zeroes, even when the
                 trailing places are not significant.

uppercase        If this is set, "E" instead of "e" will be used to
                 indicate the exponent of a floating point number, and
                 "A" through "F" will be used to represent hex digits
                 instead of "a" through "f". If uppercase and showbase
                 are both set, the string "0X" instead of "0x" will be
                 used to indicate a base-16 number.

showpos          If this is set, positive numbers will be inserted with a
                 leading "+".

scientific       If this is set, the floating-point inserters will print a
                 number with one digit before the decimal point, and the
                 number of digits after the decimal point equal to the
                 value of precision(). The character "e" will introduce
                 the exponent.

fixed            If this is set, the floating-point inserters will use
                 precision() to determine the number of digits after the
                 decimal point. If neither scientific or fixed is set,
                 numbers with exponents smaller than -4 or greater than
                 precision() will be printed as if scientific were set.
                 Other numbers will be printed using zeroes to show the
                 decimal place explicitly.

unitbuf          When this is set, a flush is performed after each
                 insertion.

stdio            When this is set, streams using stdiobufs will flush
                 stdout and stderr after each insertion.

Field width settings usually lapse after each output operation, this
format bit makes them persistent:

    static const long stickywidth;  // = 0x8000

This format bit causes insertion of a single space after each item output
except the endl manipulator (see later):

    static const long spacing;      // = 0x10000

The format bit sets in the enum format_mode_mask allow the the control of
formatting in a logical manner:

    basefield   = dec|oct|hex,
    adjustfield = left|right|internal,
    floatfield  = scientific|fixed

4.2  Class ios Function Reference
Class ios is a virtual base class for ostreams, istreams and iostreams,
so any of the following functions can be called for objects of any of
these types, or types derived from them.

All functions described here require the inclusion of iostream.hpp or
some header file that itself includes iostream.hpp.

ios::ios
Usage:
#include <iostream.hpp>
ios::ios(streambuf *);

Description:
The constructor for an ios object requires a single argument, a pointer
to the streambuf object that is to act as intermediary between the stream
and the actual input/output device.

ios::rdstate
Usage:
#include <iostream.hpp>
int ios::rdstate() const;

Description:
Reads the error state.

Example:
double d;
cin >> d;
if (cin.rdstate() & ios::failbit)
    cout << "Bad input\n";

Return Value: Returns the current value of the stream error state
              variable.

ios::good
Usage:
#include <iostream.hpp>
int ios::good() const;

Description:
Equivalent to !rdstate().

Example:
double d;
cin >> d;
if (!cin.good())
    cout << "Bad input\n";

Return Value: Returns non-zero value if no error bits are set.

ios::eof
Usage:
#include <iostream.hpp>
int ios::eof() const;

Description:
Equivalent to (rdstate() & ios::eofbit).

Example:
double d;

ifstream infile("somefile.dat");  // a file sourced istream
infile >> d;
if (infile.eof())
    cout << "No more input\n";

Return Value: Returns non-zero value if eofbit is set.

ios::fail
Usage:
#include <iostream.hpp>
int ios::fail() const;

Description:
Equivalent to (rdstate() & (ios::failbit | ios::badbit)).

Example:
double d;

ifstream infile("somefile.dat");   // a file sourced istream
infile >> d;

if (infile.fail())
    cout << "Bad data in input file\n";

Return Value: Returns non-zero value if failbit or badbit set.

ios::bad
Usage:
#include <iostream.hpp>
int ios::bad() const;

Description:
Equivalent to (rdstate() & ios::badbit).

Example:
double d;

ifstream infile("somefile.dat");  // a file sourced istream
infile >> d;
if (infile.bad())
    cout << "Input file stream in trouble\n";

Return Value: Returns non-zero value if badbit is set.

ios::operator!
Usage:
#include <iostream.hpp>
int ios::operator!() const;

Description:
Equivalent to (rdstate() != 0).

Example:
double d;

cin >> d;
if (!cin)
    cout << "Bad input\n";

Return Value: Returns non-zero value if stream state is not good.

ios::operator void*
Usage:
#include <iostream.hpp>
int ios::operator void*() const;

Description:
Equivalent to (rdstate()? 0: this). Used for state testing as per the
example below.

Example:
double d;

while (cin >> d) {
    cout << "All is well\n";
    ...;
}

Return Value: Returns a null (zero) pointer if any error flag is set,
              some other pointer value otherwise.

ios::clear
Usage:
#include <iostream.hpp>
void ios::clear(int new_value = 0);

Description:
Sets a new value for the error state variable.

Example:
double d;

cin >> d;
if (cin.fail()) {
    cout << "try again\n";
    cin.clear();
    cin >> d;
}

ios::fill
Usage:
#include <iostream.hpp>
int ios::fill(char filler);
int ios::fill() const;

Description:
The fill function is used to set or read the current filler character,
that is the character used to pad output to any field width that may be
specified. The filler character defaults to the space character.

Example:
cout << "fill character is " << cout.fill() << endl;
int i = 22, oldfill = cout.fill('*');
cout.width(6);          // see below
cout << i;              // output is    ****22
cout.fill(oldfill);

Return Value: The const version returns the current fill character.
              The non-const version returns the previous fill character.

ios::precision
Usage:
#include <iostream.hpp
int precision(int new_precision);
int precision() const;

Description:
Set or reads the current floating point precision. This is the number of
digits that will be displayed after the decimal point in floating point
representations. The default precision is six digits.

Example:
double d = 1.0/3;

cout << "Default precision = " << cout.precision() << endl;
int oldprec = cout.precision(3);
cout << d;                      // output is    0.333
cout.precision(oldprec);
cout << d;                      // output is    0.333333

Return Value: The const version returns the current precision.
              The non-const version returns the previous value.

ios::tie
Usage:
#include <iostream.hpp>
ostream *ios::tie(ostream *stream_to_tie);
ostream *tie() const;

Description:
Any stream can have a specified output stream (ostream) tied to it. This
means that before any input or output operation on the stream, the stream
that is tied to it is to be flushed, that is its output is to be brought
completely up to date, with anything that has been buffered sent to its
final destination.

For example, the standard input and standard error streams have the
standard output stream tied to them. This means that before any input is
taken via cin, cout is flushed so that all previous output appears before
waiting for input commences. The tie functions set or read the current
tied ostream. By default stream objects have no ostream tied to them.
Such tying must be done explicitly.

Example:
ofstream outfile("somefile.dat");  // an output file stream
outfile.tie(&cout);
outfile << "Something";
cout << "Output to the file is flushed before this appears";

Return Value: The const version returns a pointer to the currently tied
              ostream, zero if there is none. The non-const version
              returns the previous pointer.

ios::flags
Usage:
#include <iostream.hpp>
long ios::flags(long new_flags);
long ios::flags() const;

Description:
Sets or reads the current settings of the format flags, which are bits in
a long integer value.

Example:
int fv = cout.flags();

if (!(fv & ios::uppercase))
    cout.flags(fv | ios::uppercase);
cout  < 0.000000123;            // output is 1.23E-07

Return Value: The const version returns the current flags. The non-const
              version returns the previous value.

ios::setf
Usage:
#include <iostream.hpp>
long ios::setf(long bits_to_set, long mask = 0);

Description:
Sets the flormat flag bits specified by the first argument, having first
cleared any bits specified by the second mask argument. The default mask
does no clearing.

Example:
cout.setf(ios::scientific, ios:floatfield);

// set scientific notation, making sure that fixed is
// not specified at the same time.

Return Value: Returns the value of the flags before the specified
              alteration.

ios::unsetf
Usage:
#include <iostream.hpp>
long ios::unsetf(long bits_to_clear);

Description:
Clears (resets) the bits in the format flags specified by the argument
value.

Example:
cout.unsetf (ios::floatfield);   // restore default behavior

Return Value: Returns the value of the flags before the specified
              alteration.

ios::width
Usage:
#include <iostream.hpp>
int width(int next_field_width);
int width() const;

Description:
Sets or reads the field width that will be used for the next I/O
operation. Formatted output operations will have their length padded out
to this specified field width according to the setting of the
left/right/internal format flags. Default padding is such as to give
right justification. The width setting normally affects only a single
output operation, the output operation setting the width back to zero,
which is the default condition, and means no padding. If the
ios::stickywidth format flag is set, the field width value persists until
it is set to some other value by a call to width.

Example:
cout.width(6);

cout << '!' << 333 << 999;      // output is    !   333999
cout.width(6);
cout.setf(ios::stickywidth);
cout << '!' << 333 << 999;      // output is    !   333   999
cout.width(6);
cout << '!' << 333 << 999;      // output is    !   333999

Return Value: The const version returns the currently set width, the
              other returns the width before modification.

ios::rdbuf
Usage:
#include <iostream.hpp>
streambuf *ios::rdbuf() const;

Description:
Returns a pointer to the buffer (streambuf) associated with the stream.

Example:
cout.rdbuf()->sync();
// Flush the associated buffer (same as cout.flush()).

Return Value: As description

ios::sync_with_stdio
Usage:
#include <iostream.hpp>
static void ios::sync_with_stdio();

Description:
Causes the standard streams cin cout, cerr, and, if applicable, clog, to
use alternative buffers (type stdiobuf) that are linked to stdin , stdout
and stderr respectively. The format flags are also set so that unit
buffering is in force, that is so that the stream is flushed after each
operation, and so that stdout and stderr are also flushed after each
operation. This provides the capability to mix code using the stdio
functions like printf() and putc() with IOStream style I/O. -   Using
this option will substantially reduce efficiency. It should not be used
for new code.

Example:
ios::sync_with_stdio();

for (int i = 100, i--;) {
    printf("This is from stdio,\n");
    cout << "but this came from cout\n";
}

ios::bitalloc
Usage:
#include <iostream.hpp>
static long ios::bitalloc();

Description:
In stream classes derived from class ios, and in code providing inserters
for user defined types it may be desired to introduce extra format flag
type information. The bitalloc function provides the capability to extend
class ios in this way. It returns a long integer with one previously
unused bit set.

Example:
long ext_format_bit = ios::bitalloc();
cout.setf(ext_format_bit);

Return Value: Returns a long with one previously unallocated bit set,
              or zero if no further format bits are available.

ios::xalloc
Usage:
#include <iostream.hpp>
static int ios::xalloc();

Description:
In stream classes derived from class ios, and in code providing inserters
for user defined types it may be desired to introduce extra format
parameter information. The xalloc function provides the capability to
extend class ios in this way. It returns a previously unused index into
an array of doublewords that can then be used to access the corresponding
array element either as a long or as a void*.

Example:
int ext_param_index = ios::xalloc();
iword(ext_param_index) = 0;

Return Value: Returns an integer that is a previously unused index
              into an array of extended format parameter doublewords.

ios::iword
Usage:
#include <iostream.hpp>
long &ios::iword(int index);

Description:
The iword function gives access to the extended format parameter array
element corresponding to its argument value, as a reference to a long.

Example:
int ext_param_index = ios::xalloc();
iword(ext_param_index) = 0;

Return Value: A reference to a long.

ios::pword
Usage:
#include <iostream.hpp>
void* &ios::pword(int index);

Description:
The pword function gives access to the extended format parameter array
element corresponding to its argument value, as a reference to a void*.

Example:
int ext_param_index = ios::xalloc();
pword(ext_param_index) = 0;

Return Value: A reference to a void pointer.

4.3  Output - Class ostream
In many C++ publications the first piece of the language presented is the
traditional "Hello World" program:

    #include <iostream.hpp>
    #include <stdlib.h>

    int main ()
    {
        cout << "Hello world\n";
        return EXIT_SUCCESS;
    }

The overloading of the left shift operator that allows this simple
notation is provided by class ostream. This deals with output of the
built-in types, and is designed to make implementation of output for user
defined types simple and type-safe.

The multiple overloads of the operator<< function are known as inserters,
that is they insert representations of types into the output stream. It
is the intention of the IOStream system that given:

    class T;        // T is a type, built in or user defined
    ostream s;
    T x;

Then:

    s << x;

is either a compilation error, or will insert a proper representation of
x in the output stream.

This is to be contrasted with the facilities available in C, where for
instance:

    enum dummy { first, second };
    printf("%ld, %ld\n", first, second);

will compile, but may print garbage.

 The ostream class is derived from class ios, so all the functions listed
 for class ios can be called for an ostream object.

The ostream class is defined in the IOstreams header file iostream.hpp.
Its public interface is as follows:

class ostream {
public:
// Constructor/ destructor
    ostream(streambuf *);
    virtual ~ostream();

//  Functions to simplify user defined inserters
    int  opfx();
    void osfx();

// Overloads of <<, these are called "Inserters"
    ostream &operator<<(const char*);
    ostream &operator<<(const signed char*);
    ostream &operator<<(const unsigned char*);
    ostream &operator<<(char c);
    ostream &operator<<(signed char);
    ostream &operator<<(short);
    ostream &operator<<(int);
    ostream &operator<<(long);
    ostream &operator<<(unsigned char);
    ostream &operator<<(unsigned short);
    ostream &operator<<(unsigned int);
    ostream &operator<<(unsigned long);
    ostream &operator<<(float);
    ostream &operator<<(double);
    ostream &operator<<(void *);
    ostream &operator<<(streambuf *);
    ostream &operator<<(ostream &(*)(ostream &));
    ostream &operator<<(ios &(*)(ios &));

// Unformatted output functions
    ostream &put(char c);
    ostream &write(const void *data, size_t size);
    size_t pcount();

// Synchronize the output device with what has been dispatched
    ostream &flush();

// Seek and tell functions for file like streams
    ostream &seekp(streampos position);
    ostream &seekp(streamoff offset, seek_dir direction);
    streampos tellp();
};

4.4  Class ostream Function Reference
All functions described here require the inclusion of iostream.hpp or
some header file that itself includes iostream.hpp.

ostream::ostream
Usage:
#include <iostream.hpp>
ostream::ostream(streambuf *);

Description:
The ostream constructor requires as its argument a pointer to the
streambuf object that is to be used as the intermediary between the
ostream and the actual output device.

ostream::opfx    ostream::osfx
Usage:
#include <iostream.hpp>
int ostream::opfx();
void ostream::osfx();

Description:
These functions are provided to simplify the coding of inserters. They
are responsible for error checking and propagation. The prefix function
does any flushing required by tie(), and the suffix function does that
required if either of ios::unitbuf or ios::stdio are set. The suffix
function restores the default value (0) for width() unless
ios::stickywidth is set, and inserts a space character into the output
stream if ios::spacing is set, except in the case of the endl
manipulator.

Example:
struct Pair {
    int a, b;
};
ostream &operator<<(ostream &s, const Pair &p)
{
    if (opfx())
        s << '(' << p.a << ':' << p.b << ')';
    osfx();
    return s;
}

Return Value: The prefix function returns a non-zero int if translation
              can proceed, zero otherwise. The suffix function has no
              return value.

ostream::operator<<
Usage:
#include <iostream.hpp>
The prototypes of the inserter functions are shown in the public
interface listing above.

Description:
The built-in inserters first call the inserter prefix function opfx().
If that returns zero, i.e. some error has occured, then the inserter does
nothing. Otherwise it inserts a character sequence representing the
argument object into the associated streambuf.

If the operation fails the error flags will be set, in conceivable cases
this will be because of an end of file condition returned by the
associated streambuf, in which case the stream will no longer be usable,
and the flags will be set to (ios::bad | ios::fail | ios::eof).

The conversion process is controlled by the format flags and state
variables of the ios part of the ostream object. For the built-in types
this happens as follows:

char

No translation is performed.

char *
unsigned char *
signed char *

The sequence of characters that the pointer addresses, up to but not
including the terminating '\0' character is translated as is, treating
each element as type char.

Integral types

Translation is to a string of digits consisting of '0' - '7' if format
flag ios::oct is set, '0' - '9' and 'a' - 'f' if ios::hex is set, or '0'
- '9' otherwise. If ios::oct or ios::hex is set, the representation is of
the argument as an unsigned value. Otherwise, if the argument is negative,
a minus sign is generated. If the argument is positive, and the
ios::showpos flag is set, a plus sign is generated.

If the representation is octal or hex, and format flag ios::showbase is
set, then octal values will be prefixed with a '0' character, and hex
values will be prefixed with "0x", or with "0X" if the format flag
ios::uppercase is set.

 The distinct types signed char and unsigned char are treated as byte
 wide integers, that is values in the ranges -128 to 127, and 0 to 255
 respectively.

void *

In the 16 bit compilers, pointers are translated to a four digit
hexadecimal representation, as if ios::showbase were not set, in the S
and M models (xxxx), or to a segment:offset representation (xxxx:xxxx) in
the C, L, V and Z models or their equivalents. In the 32 bit compilers (X
and P memory models) pointers are converted to int and then represented
as if ios::hex and ios::showbase were set.

float
double
long double

If the ios::scientific format flag is set, the floating-point inserters
will produce a representation with one digit before the decimal point,
and a number of digits after the decimal point equal to the value of
precision(). The character "e" will introduce the exponent, unless
ios::uppercase is set in which case 'E' will be used.

Extraneous trailing zeros, and, if there are no non-zero numbers after
it, the decimal point also, are stripped unless ios::showpoint is set, in
which case the decimal point and all trailing zeroes up to the precision
are retained.

If the ios::fixed format flag is set, the floating-point inserters will
use precision() to determine the number of digits after the decimal
point. Trailing zeros and the decimal point will be stripped unless
ios::showpoint is set.

Negative numbers will be preceded by a minus sign, and positive numbers
by a plus sign only if ios::showpos is set.

If neither scientific or fixed is set, numbers with exponents smaller
than -4 or greater than precision() will be printed as if scientific were
set. Other numbers will be printed using zeros as required to show the
decimal point explicitly.

streambuf &

All the characters that can be extracted from the streambuf are sent
without padding or translation to the ostream. This stops only when the
source streambuf signals an end of file condition.

The suffix function osfx() does not get called after this inserter.

ostream &(*)(ostream &)
ios &(*)(ios &)

Pointers to functions of this particular form (pointer to function taking
ostream reference argument, and returning ostream reference, and pointer
to function taking ios reference argument, and returning ios reference)
are treated specially. They act as parameterless manipulators; the
operator<< function does not translate them into characters in the output
stream, rather it has an effect on the ostream object involved.
Manipulators of this sort are provided for most of the changes that can
be made by appropriate setting of format state flags, specifically, for
ostream os:

os << leftjust;
os.setf(ios::left, ios::adjustfield);

os << rightjust;
os.setf(ios::right, ios::adjustfield);

os << dec;
os.setf(ios::dec, ios::basefield);

os << oct;
sets ios::oct similarly

os << hex;
etc

os << showbase;
os.setf(ios::showbase);

os << showpoint;
os.setf(ios::showpoint);

os << uppercase;
os.setf(ios::uppercase);

os << fixed;
os.setf(ios::fixed, ios::floatfield);

os << scientific;
os.setf(ios::scientific, ios::floatfield);

os << floating;
os.unsetf(ios::floatfield | ios::showpoint | ios::showpos);
  (floating point defaults)

os << stickywidth;
os.setf(ios::stickywidth);

os << spacing;
os.setf(ios::spacing);

os << defaults;
sets os to default format flag values

os << endl;
Adds a newline and flushes

os << ends;
Null terminates a string

These manipulators are implemented by providing functions like:

    ostream &leftjust(ostream &s)
    {
        s.setf(ios::left, ios::adjustfield);
        return s;
    }
    ios &dec(ios &s)
    {
        s.setf(ios::dec, ios::basefield);
        return s;
    }

After the translation as above, if width() is non-zero, then padding
takes place: fill() characters are added until the representation
contains width() characters. If ios::left is set, the padding characters
are added after the translated string. If ios::right is set they are
added before the translated string (this is the default state of an
ostream). If ios::internal is set, the padding is added after any sign
information, or integer base information, but before the rest of the
translation. Finally the ostream suffix function osfx() is called. User
defined inserters should generally follow the spirit of these conversion
rules, and in particular should call opfx() and osfx() in the same way.

Example:
int i;
double d;

char *string;
void *p;
cout << spacing << i << d << string << p << endl;

Return Value: Inserter functions must return a reference to the ostream
              into which the insertion was made.

ostream::put
Usage:
#include <iostream.hpp>
ostream &ostream::put(char c);

Description:
This should be regarded as an unformatted or raw output operation. The
prefix function is called. If this returns a non-zero value, the
character is stuffed into the associated streambuf. The error flags are
set if the operation fails. The suffix function is not called.

Example:
cout << spacing;
cout << 1 << 'a';
cout.put('b');
cout << endl;       // output is: 1 ab

Return Value: Returns a reference to the ostream for which it was called.

ostream::write
Usage:
#include <iostream.hpp>
ostream &ostream::write(const void *data, size_t size);

Description:
This should be regarded as an unformatted or raw output operation. The
prefix function is called. If this returns a non-zero value, an attempt
is made to stuff size characters starting at address data into the
associated streambuf. The error flags are set if the operation fails. The
suffix function is not called.

The number of characters sucessfully transferred can be read by a call to
ostream::pcount(). The pcount() function is used by inserters etc., so it
should be used immediately after the write().

Example:
Thing x;
ofstream osf("output.dat");     // a file based ostream
osf.write(&x, sizeof(Thing));   // copy x as is
if (osf.pcount() != sizeof(Thing))
    ...;                        // something went wrong

Return Value: Returns a reference to the ostream for which it was called.

ostream::pcount
Usage:
#include <iostream.hpp>
size_t ostream::pcount();

Description:
Returns the number of characters sucessfully transferred by the last
unformatted output operation (put or write). Should be used immediately
after such an operation or sequence of operations as its potential return
value may be modified by other output operations.

Example:
See ostream::write

Return Value: An int that is the number of characters transferred by the
              last write or put.

ostream::flush
Usage:
#include <iostream.hpp>
ostream &ostream::flush();

Description:
The flush function calls the sync() function of the associated streambuf
to ensure that all output is up to date, that is all characters that have
been sent to the streambuf have been sent to their final destination, the
external device to which the streambuf relates. Equivalent to
rdbuf()->sync();.

Example:
cout << "Enter a number between one and ten: ";
cout.flush();   // this is actually extraneous because
                // cin's tie to cout will do the same.

int i;
cin >> i;

Return Value: The flush function returns a reference to the ostream object
              for which it was called.

ostream::seekp
Usage:
#include <iostream.hpp>
ostream &ostream::seekp(streampos);
ostream &ostream::seekp(streamoff, relative_to);

// iostream.hpp has - typedef long streampos, streamoff

Description:
Positions the put pointer of the associated streambuf. In the case of a
file based ostream, the action is similar to that of the stdio fseek()
function. Positioning is discussed further in the section that describes
classes streambuf and filebuf.

The absolute form (seekp(pos)) is to be interpreted as seekp(pos,
ios::beg), that is relative to the start of the streambuf.

The value used as an argument to seekp should have been one previously
obtained from the complementary member function tellp(). In general, it
should not be calculated, except that the particular value streampos(0)
is safe.

In the case of relative seeks (e.g. seekp(0, end)) the streamoff value
zero is safe, but other values should be treated with caution. Remember
that under DOS it is normal to convert newline characters to CR/LF pairs
before they are sent to an actual output device, and to convert CR/LF
pairs to newline characters on input.

Example:
ofstream ofs("output.dat");

ofs.seekp(0);       // position at start of file
ofs.put('\0');      // modify status
ofs.seekp(0, end);  // back to appending

Return Value: Returns a reference to the ostream object for which it was
              called.

ostream::tellp
Usage:
#include <iostream.hpp>
streampos ostream::tellp();

Description:
Returns the current "position" in the associated streambuf (see the
sections on classes streambuf, filebuf and strstreambuf). The return
value of tellp can be used as an argument to seekp to return to the same
position later.

Example:
ofstream ofs("output.dat");
streampos sp = ofs.tellp();

ofs.seekp(0);       // position at start of file
ofs.put('\0');      // modify status or whatever
ofs.seekp(sp);      // go back to whatever

Return Value: A value of type streampos, a long in most implementations
              of IOStreams.

4.5  Input - Class istream
Class istream provides input operations that mirror the output operations
of class ostream.

The right shift operator is overloaded to provide a similar convenient
notation for most input operations.

This deals with input of the built-in types, and is designed to make
implementation of input for user defined types simple and type-safe. The
multiple overloads of the operator>> function are known as extractors,
that is they extract typed values from sequences of characters in the
input stream. It is the intention of the IOStream system that given:

    class T;        // T is a type, built in or user defined
    istream s;
    T x;

Then:

    s >> x;

is either a compilation error, or will cause the input to be parsed to
translate it into a value of type T. If the character stream is
inconsistent with the type, the error state will be set appropriately.

 The istream class is derived from class ios, so all of the functions
 listed for class ios can be called for an istream object.

The istream class is defined in the IOstreams header file iostream.hpp.
Its public interface is as follows:

class istream {
public:
    istream(streambuf *);
    virtual ~istream();
    int ipfx(int need = 0);

    istream &operator>>(char *);
    istream &operator>>(signed char *s);
    istream &operator>>(unsigned char *s);
    istream &operator>>(char &);
    istream &operator>>(signed char &c);
    istream &operator>>(unsigned char &);
    istream &operator>>(short &);
    istream &operator>>(int &);
    istream &operator>>(long &);
    istream &operator>>(unsigned short &);
    istream &operator>>(unsigned int &);
    istream &operator>>(unsigned long &);
    istream &operator>>(float &);
    istream &operator>>(double &);
    istream &operator>>(streambuf*);
    istream &operator>>(istream &(*)(istream&));
    istream &operator>>(ios &(*)(ios&));

    int sync();

    istream &get(char *data, int length, char delimiter = '\n');
    istream &get(signed char *data, int length, char delimiter = '\n');
    istream &get(unsigned char *data, int length, char delimiter = '\n');
    istream &get(char &destination);
    istream &get(signed char &destination);
    istream &get(unsigned char &destination);
    istream &get(streambuf &destination, char delimiter = '\n');
    int get();
    int peek();
    istream &read(void *data, int size);
    istream &getline(char *data, int length, char delimiter = '\n');
    istream &getline(signed char *data, int length, char delimiter = '\n');
    istream &getline(unsigned char *data, int length, char delimiter = '\n');
    size_t gcount();
    istream &ignore(int length, int delimiter = EOF);
    istream &putback(char c);
    istream &seekg(streampos);
    istream &seekg(streamoff, relative_to);
    streampos tellg();
    static int is_white_space(char c);
};

4.6  Class istream Function Reference
All functions described here require the inclusion of iostream.hpp or
some header file that itself includes iostream.hpp.

istream::istream
Usage:
#include <iostream.hpp>
istream::istream(streambuf *);

Description:
The istream constructor requires as its argument a pointer to the
streambuf object that is to be used as the intermediary between the
istream and the actual input device.

istream::ipfx
Usage:
#include <iostream.hpp>
int istream::ipfx(int need = 0);

Description:
This function is provided to simplify the coding of extractors. It is
responsible for error checking and propagation. If the error status is
non-zero, ipfx returns zero immediately.

Otherwise, if necessary, it does any flushing required by tie(). Flushing
is required if the argument value is zero.

Then if the ios::skipws format flag is set, and if need is zero,
whitespace characters are extracted from the input stream until an end of
file condition or a non-whitespace character is detected. If an error is
detected during this process, ipfx sets the error state accordingly, and
returns zero.

Formatted input functions call ipfx with need == 0, and unformatted input
functions call ipfx with need == 1.

Example:
struct Pair {
    int a, b;
};
ostream &operator>>(ostream &s, Pair &p)
{
    if (ipfx(0)) {
        // whatever is required
    }
    return s;
}

Return Value: The prefix function returns a non-zero int if the extraction
              can proceed, zero otherwise.

istream::operator>>
Usage:
#include <iostream.hpp>
The prototypes of the extractor functions are listed in the public
interface shown above.

Description:
The built-in extractors first call the extractor prefix function ipfx().
If that returns zero, i.e. some error has ocurred, then the inserter does
nothing. Otherwise it parses the incoming character sequence in an
attempt to form a value of the required type.

If the operation fails the error flags will be set. If input of the
required type was detectably incomplete, and either an unexpected
character or end of file is detected, the failbit flag is set. In the end
of file case, eofbit is also set. If under these circumstances characters
have been lost, that is removed from the associated streambuf, the badbit
flag will also be set. The failbit flag will also be set if the input is
such as to cause overflow of the specified type.

For example, scanning the stream:

    abcdefg

for an integer will result in failbit being set. No suitable characters
were found, and therefore none were lost.

In the case of the stream:

    0xhijklm

then both failbit and badbit will be set. The extractor happily removed
0x from the stream, but could then make no sense of what followed.

For the stream:

    0x

each of failbit, badbit, and eofbit will be set, since the input was not
complete, characters have been taken, and there is an end of file
condition. The conversion process is controlled by the format flags and
state variables of the ios part of the istream object. For the built-in
types this happens as follows:

char&

A single character is taken from the input stream and stored in the
character variable referred to.

char *
signed char *
unsigned char *

Characters are extracted and stored in the indicated array until a
whitespace character is encountered, or until width()-1 characters have
been extracted, or until an end of file condition is encountered. If
termination is by a whitespace character, the whitespace character is not
extracted.

A terminating null character is then stored into the array, and if eof
was encountered this may be the only result. The field width is reset to
zero.

signed char&
short &
int &
long &
unsigned char &
unsigned short &
unsigned &
unsigned long &

Conversion is controlled by the basefield format flags. The first
character may be a sign, either + or -. Digits are then accepted until a
non-digit is encountered.

If ios::oct is set the acceptable digits are 0 through 7. If ios::dec is
set, 0 through 9, and if ios::hex is set, 0 through 9 and a through f
(either upper or lower case).

If none of the basefield format flags are set, then the character stream
is interpreted as per the language conventions: if the number starts with
a 0, then scanning proceeds as if ios::oct were set, or if the sequence
begins with 0x or 0X, then scanning proceeds as if ios::hex were set.
Otherwise scanning looks for a decimal integer.

If no digits are found other than the 0 in 0x or 0X, the error flags are
set, and if the value read in this way can not be accomodated in a
variable of the type being extracted into, i.e. there is overflow, the
error flags are set (to badbit and failbit in the latter case, otherwise
as discussed above).

float &
double &
long double &

Conversion is as per the C++ syntax for constants of these types,
excluding any suffix character.

The error flags are set if no digits are scanned, or if the stream does
not contain a complete representation of a floating point number, or if
there is an overflow condition.

streambuf &

All the characters that can be extracted from the input source are
transferred as is to the referenced streambuf. Extraction stops only when
an end of file condition occurs on the istream or on the streambuf.

istream &(*)(istream &)
ios &(*)(ios &)

Pointers to functions of this particular form (pointer to function taking
istream reference argument, and returning istream reference, and pointer
to function taking ios reference argument, and returning ios reference)
are treated specially. They act as parameterless manipulators, that is,
the operator>> function does not neccessarily cause characters to be
taken from the input stream and translated to give a value, rather it has
an effect on the istream object involved. Manipulators of this sort are
provided as follows:

is >> dec;      // is.setf(ios::dec, ios::basefield);
is >> oct;      // sets ios::oct similarly
is >> hex;      // etc
is >> ws;       // strips whitespace from input stream

Example:
int i;
double d;
char buffer[10];
cin.width(10);

cin >> i >> d >> buffer;

Return Value: Extractor functions must return a reference to the istream
              that is being extracted from.

istream::get    istream::peek
Usage:
#include <iostream.hpp>
int istream::get();
int istream::peek();

Description:
These unformatted input functions return the value of the next character
in the input stream, or end of file if no further character is available.
The prefix function is called (ipfx(1)), but the error state is not
effected. Get removes the character from the input stream, while peek
leaves it there.

Example:
// Input stream "abcdefg"
int c = cin.peek()

if (c != EOF)
    cout << char(c);    // output is 'a'

c = cin.get();
if (c != EOF)
    cout << char(c);    // output is 'a'

c = cin.get();
if (c != EOF)
    cout << char(c);    // output is 'b'

Return Value: An int representing the character peeked or got, or
              EOF if no character was available.

istream::get
Usage:
#include <iostream.hpp>
istream &istream::get(char &c);
istream &istream::get(char *dest, int length, char delim = '\n');
istream &istream::get(streambuf &sb, char delim = '\n');

Description:
The unformatted input get functions call the istream prefix function with
argument value zero, which means that no whitespace stripping takes
place, so these input functions are essentially binary or raw.

The first of them extracts a single character, and places it in the
referenced variable.

The second stores characters in the indicated array, dest, until either
the character nominated as delimiter is encountered (the delimiter is
defaulted to the newline character), or until length-1 characters have
been extracted, or until an end of file condition is encountered. A null
terminating character is then stored in the array.

The third version extracts characters and places them in the specified
streambuf until the delimiter character is encountered, or an EOF
condition is encountered on thre destination streambuf.

The failbit flag is set if no characters can be got before and end of
file condition.

The number of characters transferred can be determined by an immediately
following call to gcount().

Example:
// Input stream contains
// "The quick brown fox! - jumped or not?"

char buffer[80];
cin.get(buffer,80, '!');  // gets "The quick brown fox" into buffer

Return Value: The get functions return a reference to the ostream object
              for which they are called.

istream::getline
Usage:
#include <iostream.hpp>
istream &istream::getline(char *dest, int length, char delim);

Description:
Acts in the same way as get(char*, int, char), except that the delimiting
character is extracted if there is room for it in the array. The number
of characters transferred can be determined by an immediately following
call to gcount().

Example:
// Input stream contains
// "The quick brown fox! - jumped or not?"

char buffer[80];
cin.get(buffer,80, '!');   // gets "The quick brown fox!" into buffer

Return Value: The get functions return a reference to the ostream object
               for which they are called.

istream::read
Usage:
#include <iostream.hpp>
istream &istream::read(void *dest, size_t n);

Description:
A raw or binary input function. Attempts to extract n bytes from the
input stream and to place then at the specified address, dest. If less
than n characters are transferred because of an end of file condition the
error state is set to (ios::eofbit|ios::failbit|ios::badbit).

The number of characters transferred can be determined by an  immediately
following call to gcount().

Example:
Thing x;
ifstream ifs("things.dat");
ifs.read(&x, sizeof(Thing));

Return Value: Returns a reference to the istream object for which it was
              called.

istream::gcount
Usage:
#include <iostream.hpp>
int istream::gcount();

Description:
May be called after any of the unformated input functions (get, getline,
read) to determine how many characters were transferred. gcount()  should
be called immediately after the unformatted input function, since
formatted input functions may use the unformatted functions, and thus
reset the value.

Example:
ifstream ifs("things.dat");
ifs.read(&x, sizeof(Thing));
if (ifs.gcount() != sizeof(Thing))  // something wrong

istream::ignore
Usage:
#include <iostream.hpp>
istream &istream::ignore(int n, int delim = EOF);

Description:
The ignore function causes characters to be taken from the input and
wasted, until n characters have been wasted, or until a character
matching delim is extracted, or until an end of file condition is
encountered. If the default value for delim (EOF) is used, ignore will
stop  only when n characters have been wasted, or end of file is reached.

Example:
// Input stream "abcdefghijk\n"

char buffer[80];
if (!cin.ignore(80,'h')) {  // end of file

} else {
    cin >> buffer;
    cout << buffer; // output is "ijk"
}

Return Value: Returns a reference to the istream object for which it was
              called.

istream::putback
Usage:
#include <iostream.hpp>
istream &istream::putback(char c);

Description:
This function attempts to put the streambuf associated with the istream
back into the condition it was in before the last character was
extracted.  The argument character should be the one that was just
extracted from  the stream, and if it is not, the behavior of the putback
function is  undefined.

If putback fails, the error state will be set. The istream prefix
function is  not called. However if the error state was set when putback
was called it  will do nothing.

istream::sync
Usage:
#include <iostream.hpp>
int istream::sync();

Description:
Attempts to make the external source of characters (the source that feeds
the associated streambuf), consistent with the characters that have been
extracted. This may effectively put characters which had been buffered
back into their original source.

This function is implemented as rdbuf()->sync(), it simply calls the sync
function for the associated streambuf. EOF is returned if any error
occurs.

Example:
istream is(...);

// Ultimate source "abcdefghijklmnopqrstuvwxyz"
// bold characters not yet read
// streambuf contents "opqr"
// last character read was 'n'

is.sync();

// Ultimate source "abcdefghijklmnopqrstuvwxyz"
// bold characters not yet read
// streambuf empty
// last character read was 'n'

Return Value: Returns EOF if an error occurs, otherwise some other
              int value.

istream::seekg
Usage:
#include <iostream.hpp>
istream &istream::seekg(streampos);
istream &istream::seekg(streamoff, relative_to);
// iostream.hpp has - typedef long streampos, streamoff

Description:
Positions the get pointer of the associated streambuf. In the case of a
file  based ostream, the action is similar to that of the stdio fseek()
function.  Positioning is discussed further in the section describing
classes  streambuf and filebuf.

The absolute form (seekg(pos)) is to be interpreted as seekg(pos,
ios::beg), that is relative to the start of the streambuf.

The value used as an argument to seekg should have been one previously
obtained from the complementary member function tellg(). In general, it
should not be calculated, except that the particular value streampos(0)
is safe.

In the case of relative seeks (e.g. seekg(0, end)) the seekoff value zero
is  safe, but other values should be treated with caution. Remember that
under DOS it is normal to convert newline characters to CR/LF pairs
before they are sent to an actual output device, and to convert CR/LF
pairs to newline characters on input.

Example:
ifstream ifs("input.dat");
. . . ;
streampos pos = ifs.tellg()

ifs.seekg(0);                   // position at start of file
int status = ifs.get();         // read status for example
ifs.seekg(pos)                  // back to where we were

Return Value: Returns a reference to the istream object for which it was
              called.

istream::tellg
Usage:
#include <iostream.hpp>
streampos istream::tellg();

Description:
Returns the current "position" in the associated streambuf (see the
section on classes streambuf, filebuf and strstreambuf). The return
value of tellg can be used as an argument to seekg to return to the same
position later.

Example:
ifstream ifs("input.dat");
. . . ;
streampos sp = ifs.tellg();
ifs.seekg(0);       // position at start of file
. . . ;
ifs.seekg(sp);      // go back to whatever

Return Value: A value of type streampos, a long in most implementations
              of IOStreams.
4.7  Input and Output - class iostream
The iostream class combines the properties of an istream and an ostream
so as to allow both input and output. In addition to the public
interfaces of  an istream an ostream and an ios, it has the following
public interface:

public:
    iostream (streambuf *buf);
    virtual ~iostream();
};
4.8  Class iostream - Public Interface
iostream::iostream
Usage:
#include <iostream.hpp>
iostream::iostream(streambuf *);

Description:
Like the constructors for istream and ostream, the constructor takes as
its  argument a pointer to an appropriate streambuf.

4.9  Streams with Assignment
The streams already discussed have had assignment operations explicitly
excluded by being given a private copy constructor and operator=. This is
because it is not clear what constitutes appropriate assignment behavior
for streams.

It has been the practice, however, to write code like:

if (argc) > 1) {   // file name supplied as source
    ifstream *ifp = new ifstream(argv[1]);
    cin = *ifp;
}

Here, if a filename was provided as a source of input, then an istream
was  constructed using the file, and this istream was assigned to cin.
The rest of the program simply assumed that input came from the  standard
input.

Classes that support assignment are defined to support code which uses
this technique, and the C++ standard streams cin, cout, cerr (and where
applicable) clog, are instances of stream classes of this sort.

The additional public interfaces provided by these classes are as
follows:

class istream_withassign : public istream {
public:
    istream_withassign();
    istream_withassign(streambuf *);
    ~istream_withassign();
    istream_withassign &operator=(istream &);
    istream_withassign &operator=(streambuf *);
};

class ostream_withassign : public ostream {
public:
    ostream_withassign();
    ostream_withassign(streambuf *);
    ~ostream_withassign();
    ostream_withassign &operator=(ostream &);
    ostream_withassign &operator=(streambuf *);
};

class iostream_withassign : public iostream {
public:
    iostream_withassign();
    iostream_withassign(streambuf *);
    ~iostream_withassign();
    iostream_withassign &operator=(ios &);
    iostream_withassign &operator=(streambuf *);
};

4.10  Streams with Assignment - Function Reference
Only the extra facilities are described here.
istream_withassign::istream_withassign
Usage:
#include <iostream.hpp>
istream_withassign::istream_withassign();

Description:
Creates an istream_withassign object that is not functional, but which
can be assigned to. The error state of the created istream_withassign is
set to ios::badbit.

Example:
istream_withassign cin2;
cin2 = cin;
int i;
cin2 >> i;      // same as input from cin

istream_withassign::operator=
Usage:
#include <iostream.hpp>
istream_withassign &operator=(istream &);
istream_withassign &operator=(streambuf *);

Description:
An istream_withassign object can be can have either another istream  type
object, or a streambuf pointer assigned to it. When assignment is from an
istream, the state variables of the istream  assigned from are inherited
unchanged. When from a streambuf, the state  of the istream_withassign is
the default state.

Example:
istream_withassign cin2;
cin2 = cin;
int i;
cin2 >> i;      // same as input from cin
istream_withassign cin3;
cin3 = cin.rdbuf();
cin3 >> i;      // same as input from cin

Return Value: Assignment operators return a reference to the object
              assigned to.

ostream_withassign::ostream_withassign
Usage:
#include <iostream.hpp>
ostream_withassign::ostream_withassign();

Description:
Creates an ostream_withassign object that is not functional, but which
can be assigned to. The error state of the created ostream_withassign is
set to ios::badbit.

Example:
ostream_withassign cout2;
cout2 = cout;

int i;
cout2 << i;     // same as output to cout

ostream_withassign::operator=
Usage:
#include <iostream.hpp>
ostream_withassign &operator=(ostream &);
ostream_withassign &operator=(streambuf *);

Description:
An ostream_withassign object can be can have either another ostream  type
object, or a streambuf pointer assigned to it.

When assignment is from an ostream, the state variables of the ostream
assigned from are inherited unchanged. When from a streambuf, the state
of the ostream_withasssign is the default state.

Example:
ostream_withassign cout2;
cout2 = cout;
int i;
cout2 << i;     // same as output to cout

ostream_withassign cout3;
cout3 = cout.rdbuf();
cout3 << i;     // same as output to cout

Return Value: Assignment operators return a reference to the object
              assigned to.

iostream_withassign::iostream_withassign
Usage:
#include <iostream.hpp>
iostream_withassign::iostream_withassign();

Description:
See the descriptions for istream_withassign and ostream_withassign.

iostream_withassign::operator=
Usage:
#include <iostream.hpp>
istream_withassign &operator=(istream &);
istream_withassign &operator=(streambuf *);

Description:
See the descriptions for istream_withassign and ostream_withassign.

Return Value: Assignment operators return a reference to the object
              assigned to.

4.11  Buffering - Class streambuf
The streambuf class is an abstraction of a buffer.  It usually acts as an
intermediary between a consumer of characters and some ultimate source,
or between a producer of characters and some ultimate destination. A
streambuf can be thought of as having a get pointer, which points at a
position from which the next character can be got, or before which a
character may be put back, and a put pointer at which position the next
character to be put may be placed.

A streambuf will actually be of some finite size, probably unrelated to
the size of the ultimate source or sink of characters. A part of the
abstraction therefore enables it to replenish itself from the ultimate
source when there are no remaining characters in its get area
(underflow), or to move characters to the ultimate destination when its
put area is full (overflow). These operations are transparent to the user
of a streambuf, and will operate differently for derivatives of streambuf
which are specialized for some particular combination of ultimate source
and destination.

The concept of get and put pointers extends to the provision of functions
to reposition these pointers. Such repositioning should be though of as
relative to the total contents of the ultimate source and the ultimate
destination.

The public interface of the base class streambuf is as follows:

#ifndef EOF
const int EOF = -1;
#endif

#define seek_dir relative_to

class streambuf {
public:
    enum relative_to { beg, cur, end };
    enum open_mode { in, out, ate, app, trunc, nocreate,
                     noreplace };

// Constructors, destructor
    streambuf();
    streambuf(char *memory, int length);
    virtual ~streambuf();

// Status functions
    int in_avail() const;
    int out_waiting() const;

// Take or examine characters from the get area
    int sgetc();
    int sbumpc();
    void stossc()
    int snextc();
    int sgetn(char *buffer, int count);

// Place characters in the put area
    int sputc(int c);
    int sputn(const char *string, int length);

// Return a character to the get area
    int sputbackc(char c);

// Make the streambuf consistent with the ultimate
// source and destination
    virtual int sync();

// Position the get and put pointers
    virtual streampos  seekpos(streampos position,
                               int which=ios::in|ios::out);
    virtual streampos seekoff(streampos offset, relative_to pos,
                              int which=ios::in|ios::out);

// Offer an area of memory for use as a buffer
    virtual streambuf *setbuf(char *memory, int length);
};

4.12  Class streambuf - Function Reference
All functions described here require the inclusion of iostream.hpp or
some header file that itself includes iostream.hpp.

streambuf::streambuf
Usage:
#include <iostream.hpp>
streambuf::streambuf();
streambuf::streambuf(char *memory, int length);

Description:
The default constructor will set up a streambuf that will allocate memory
as required.

The constructor with arguments allows the user to specify an area of
memory that will be used to locate the get and put areas. If the latter
form is used, and the memory argument is zero, or the length is less than
or equal to zero, then the streambuf will be set up to operate without
buffering: all characters will be got directly from the ultimate source,
and put directly to the ultimate destination.

streambuf::sgetc
Usage:
#include <iostream.hpp>
int streambuf::sgetc();

Description:
The sgetc function returns the value of the character at the get pointer,
without moving the get pointer.

If the get pointer is already beyond the end of the get area, the
underflow function will be called to attempt to replenish the get area.

If this fails to do so, sgetc returns EOF.

Example:
streambuf sb;
int c;

if ((c = sb.sgetc()) != EOF)
    cout << "Next char is ", << char(c);
else
    cout << "No more chars in sb";

Return Value: An int that will be EOF if some error occurs, or there are
              no more characters to be had, or otherwise a positive int
              representing the character (treating the character as
              unsigned char).

streambuf::sbumpc
Usage:
#include <iostream.hpp>
int streambuf::sbumpc();

Description:
The sbumpc function returns the value of the character at the get
pointer, then moves the get pointer along one. If the get pointer is
already beyond the end of the get area, the underflow function will be
called to attempt to replenish the get area. If this fails to do so,
sbumpc returns EOF.

Example:
streambuf sb;
...;
// stream is "abcdefg", get pointer on 'a'

int c = sb.sgetc();
cout << char(c);    // output 'a'
c = sb.sbumpc();

cout << char(c);    // output 'a'
c = sb.sgetc();
cout << char(c);    // output 'b'

Return Value: An int that will be EOF if some error occurs, or there are
              no more characters to be had, or otherwise a positive int
              representing the character (treating the character as
              unsigned char).

streambuf::stossc
Usage:
#include <iostream.hpp>
void streambuf::stossc();

Description:
The stossc function advances the get pointer one position, effectively
rejecting the character at that position. If the get pointer is past the
end of the get area, the stossc function has no effect. The stossc
function has no return value. It cannot provoke failure, since it does
not call the underflow function.

It is usually used in conjunction with sgetc to implement a conditional
csbumpc.

Example:
streambuf sb;
int c;

while ((c = sb.sgetc()) != EOF && isspace(c))
    sb.stossc();

if (c != EOF) {
    c = sb.sbumpc();    // get first non-whitespace character
    ...;
} else {
    ...;

Return Value: None.

streambuf::snextc
Usage:
#include <iostream.hpp>
int streambuf::snextc();

Description:
Moves the get pointer forward one, skipping the current character, and
returning the character at the new position.

If the get pointer is already beyond the end of the get area, or it is
beyond the end when it has moved on one, the underflow function will be
called to attempt to replenish the get area. If this fails to do so,
snextc returns EOF.

Example:
streambuf sb;
...;
// stream is "abcdefg", get pointer on 'a'

int c = sb.sgetc();
cout << char(c);    // output 'a'
c = sb.snextc();

cout << char(c);    // output 'b'

c = sb.sgetc();
cout << char(c);    // output 'b'

Return Value: An int that will be EOF if some error occurs, or there are
              no more characters to be had, or otherwise a positive int
              representing the character (treating the character as
              unsigned char).

streambuf::sgetn
Usage:
#include <iostream.hpp>
int streambuf::sgetn(char *p, int n);

Description:
Attempts to take n characters starting with that at the current position
of the get pointer, and putting them in the area of memory pointed at by
p. The get pointer is left pointing at the position after the got
pointers. If less than n characters are available, as many as possible
are transferred. The return value , <= n, indicates how many were
transferred.

Example:
char buffer[128];
streambuf sb;

int howmany = sb.sgetn(buffer,20);

if (howmany < 20)
    ...;    // end of file on sb

Return Value: An int indicating how many characters were transferred.

streambuf::sputc
Usage:
#include <iostream.hpp>
int streambuf::sputc(int c);

Description:
Stores the char value of c at the current position of the put pointer.,
then moves the put pointer on one place. If the put pointer was already
beyond the end of the put area, the overflow function is called to
attempt to empty the put area to the ultimate destination. Then the
character is placed in the empty put area and the put pointer positioned
after it.

Passing the EOF value as argument has no effect on the base streambuf,
but derived classes may have special behavior in response to this value.
EOF is returned if the underflow function needs to be called, and fails
to make space in the put area available.

Example:
streambuf sb;
sp.putc('a');

Return Value: Returns EOF if an error occurs, or some other unspecified
              value if all is well.

streambuf::sputn
Usage:
#include <iostream.hpp>
int streambuf::sputn(const char *source, int n);

Description:
Attempts to put n characters starting from source into the put area. The
put pointer is then advanced to the position following the characters
transferred.

The return value gives the number of characters sucessfully transferred,
which may be less than n if an end of file condition occurs.

Example:
char string = "whatever";
streambuf sb;
sb.putn(string, 8);

Return Value: Returns the number of characters sucessfully transferred.

streambuf::sputbackc
Usage:
#include <iostream.hpp>
int streambuf::sputbackc(char c);

Description:
In principle this function moves the get pointer back one character, and
in the base class streambuf, this is all that happens. EOF is returned if
sputbackc fails, as it will do for instance in class streambuf if the get
pointer is at the beginning of the get area. Derived classes may actually
be able to store the sputbackc argument character under these
circumstances, but in general the behavior of sputbackc is not guaranteed
unless the argument character was obtained from the streambuf by the
immediately previous get operation.

Example:
streambuf sb
...;

int c = sb.sbumpc();
sputbackc(c);
c = sgetc();            // c has same value as sbumpc got

Return Value: Returns EOF if an error occurs, some other int otherwise.

streambuf::sync
Usage:
#include <iostream.hpp>
virtual int streambuf::sync();

Description:
Synchronizes the streambuf object with its ultimate source and its
ultimate destination. This means that characters in the get area are
effectively given back to the source (though this may only mean that the
source read pointer is moved back), and the characters in the put area
are sent to the destination.

The get and put areas will be empty after a sucessful sync. The sync
function returns EOF if an error occurs.

Example:
// ostream flush() is implemented as:
rdbuf()->sync();

Return Value: EOF on error, some other int on success.

4.13  A streambuf Specialized for Files - filebuf
The filebuf class is a derivation of streambuf that uses a file as
ultimate source and or destination. Characters are obtained (underflow)
from the file by reading, and disposed of (overflow) by writing.

The get and put pointers of a filebuf are notionally tied together. If
the file involved supports seeking, the filebuf seekpos() and seekoff()
functions support seek operations.

Four characters of putback are supported. The extra public interface is
as follows:

class filebuf : public streambuf {
public:
    enum { openprot = 0644 };

// Constructors
    filebuf();
    filebuf(int file_descriptor);
    filebuf(int descriptor, char *memory, int length);
    ~filebuf();

// Attach a file to an existing filebuf
    filebuf *attach(int file_descriptor);

// Close the file associated with the filebuf
    filebuf *close();

// Open a file and attach it to an existing filebuf
    filebuf *open(const char *name, int io_mode,
                  int protection = openprot);

// Information functions
    int fd() const;
    int is_open() const;

// Seek functions
    virtual streampos seekpos(streampos, int which_pointers);
    virtual streampos seekoff(streamoff offset, relative_to,
                              int which_pointers);

// Offer a buffer area for use
    streambuf *setbuf(char *memory, int length);

// Synchronize the file with the filebuf
    virtual int sync();
};

4.14  Class filebuf - Function Reference
The following functions require the inclusion of file fstream.hpp.

filebuf::filebuf
Usage:
#include <fstream.hpp>
filebuf::filebuf();
filebuf::filebuf(int file_descriptor);
filebuf::filebuf(int file_descriptor, char *memory, int length);

Description:
The default constructor creates a filebuf with dynamic get and put area
allocation, and with its associated file descriptor set to EOF, to
signify that it is unattached.

The constructor with the file descriptor argument also creates a dynamic
allocating filebuf, but associates it with the specified file.

The third constructor creates a filebuf using user specified memory for
its get and put areas. For efficiency a multiple of 1024 bytes is
suggested as a buffer size for DOS applications. Larger buffers may be
appropriate for UNIX systems. As is customary with streambuf derivatives,
a zero memory pointer or a length less than or equal to zero causes
unbuffered operation.

Example:
filebuf fb1;
filebuf fb2(1)  // suitable for cout
filebuf(2,0,0)  // unbuffered error output

char buffer[1024];

int fd = open(...);
filebuf fb3(fd, buffer, 1024);

filebuf::attach
Usage:
#include <fstream.hpp>
filebuf *filebuf::attach(int file_descriptor);

Description:
Attaches the specified file to an existing filebuf. Returns a pointer to
itself if successful, or zero if a file was already attached. If a file
is already attached, call close() first.

Example:
filebuf fb;
int fd = open(...);
fb.attach(fd);

Return Value: Pointer to the object for which it was called, or zero on
              failure.

filebuf::close
Usage:
#include <fstream.hpp>
filebuf *filebuf::close();

Description:
Any output held in the put area is flushed to the file. The file is then
closed, and the filebuf marked as unattached (file descriptor == EOF). If
an error occurs, the error state will be set, and close will return zero.
Otherwise it returns a pointer to the cfilebuf object.

Example:
filebuf fb;

int fd = open(...);
fb.attach(fd);
...;

if (!fb.close())
   // error
fd = open(...);
fb.attach(fd);

Return Value: Pointer to the filebuf object for which it was called, or
              zero on error.

filebuf::open
Usage:
#include <fstream.hpp>
filebuf *filebuf::open(const char *name, int io_mode,
                       int protection = openprot);

Description:
Opens file name, in mode io_mode, with protection defaulted to openprot
(0644), and attaches it to the filebuf. The io_mode argument should be a
bit-mask containing one or more of the values from enum open_mode:

ios::in          Open for reading.

ios::out         Open for writing.

ios::ate         Position to the end-of-file.

ios::app         Open the file in append mode.

ios::trunc       Truncate the file on open.

ios::nocreate    Do not attempt to create the file if it does not exist.

ios::noreplace   Cause the open to fail if the file exists. Open will
                 fail if the filebuf is already attached - it should be
                 closed first in that case.

Example:
filebuf fb;
fb.open("thing.dat", ios::out|ios::app);

Return Value: Pointer to the filebuf object for which it was called, or
              zero on error.

filebuf::fd
Usage:
#include <fstream.hpp>
int filebuf::fd() const;

Description:
Returns the file descriptor which the filebuf is attached to, EOF if it
is unattached.

Return Value: As description

filebuf::is_open
Usage:
#include <fstream.hpp>
int filebuf::is_open() const;

Description:
Returns non-zero if the filebuf is attached to a file, zero otherwise.

Return Value: As description.

filebuf::seekpos
Usage:
#include <filebuf.hpp>
virtual streampos filebuf::seekpos(streampos, int mode=ios::in|ios::out);

Description:
Moves the file currency (file pointer), and adjusts the contents of the
get and put areas so that any subsequent put or get will effectively be
to the specified position in the file. Remember, in a filebuf the get and
put pointers are tied - they are effectively the same. For this reason,
the mode argument is ignored.

The streampos values should be regarded as fixed. Values provided by the
seekpos and seekoff functions can subsequently be used as an argument to
the seekpos function, but should not be modified. However, streampos(0)
and streampos(EOF) are special cases. The former may safely be used as an
argument to seekpos, and the latter is returned by seekpos if an error
occurs.

The seekpos function will do nothing but return an error value if the
file does not report seeking.

Example:
filebuf fb;
fb.open(...);
...;
streampos newpos = fb.seekpos(0);
// position at start of file

// Also see function seekoff

Return Value: A value of type streampos that indicates the current file
              pointer position.

filebuf::seekoff
Usage:
#include <fstream.hpp>
virtual filebuf::seekoff(streamoff, relative_to,
                         int mode = ios::in|ios::out);

Description:
Similar to seekpos except that the position specification is relative to
either the beginning, the end, or the current get/put position. The only
restriction on the streamoff type is that it must be large enought to
represent any offset in a file. It is implemented here as a long.

The enumeration relative_to is called seek_dir in some other
implementations. This is confusing; the seek direction is controlled by
the sign of the streamoff argument, which may be negative. A #define of
seek_dir to relative_to is included to help portability.

Moves the file currency (file pointer), and adjusts the contents of the
get and put areas so that any subsequent put or get will effectively be
to the specified position in the file. Remember, in a filebuf the get and
put pointers are tied, so are effectively the same. For this reason, the
mode argument is ignored.

The seekoff function will merely return an error value if the file does
not report seeking.

Example:
filebuf fb;

fb.open(...);
...;
streampos pos = fb.seekoff(0,cur);
fb.seekpos(0);      // do something at start of file
fb.seekoff(0,end);  // do something at end
fb.seekpos(pos);    // back to where we were

Return Value: A value of type streampos that indicates the current file
              pointer position.

filebuf::setbuf
Usage:
#include <fstream.hpp>
streambuf *filebuf::setbuf(char *memory, int length);

Description:
Nominally offers a buffer area for use by the filebuf. The offer is
ignored unless memory is zero, or if its length is less than or equal to
zero, in which case unbuffered operation is initiated.

Example:
filebuf fb(fd);
...;        // buffered operations

fb.setbuf(0,0);
...;        // unbuffered operations

Return Value: A pointer to the streambuf for which it was called if the
              operation succeeded (unbuffered operation initiated), zero
              otherwise.

filebuf::sync
Usage:
#include <fstream.hpp>
virtual int filebuf::sync();

Description:
The file pointer is moved back by the number of characters available to
be got from the get area, and the contents of the get area are thrown
away. If the file does not support seeking, the contents of the get area
are thrown away.

The contents of the put area are then written to the current file pointer
position, the file pointer being advanced as this happens.

Example:
// Used by ostream flush() as in:
rdbuf()->sync();

Return Value: EOF on failure, some other int value otherwise.

4.15  File Based Input Streams - Class ifstream
Input streams specialized on files are provided for by class ifstream.
Objects of type ifstream have the public interface of classes ios and
istream, and their own public interface is as follows:

class ifstream : public fstream_common, public istream {
public:
    ifstream();
    ifstream(const char *name, int io_mode = ios::in,
             int protection = filebuf::openprot);
    ifstream(int file_descriptor);
    ifstream(int file_descriptor, char *memory, int length);

    ~ifstream();

    void attach(int file_descriptor);
    void open(const char *name, int io_mode = ios::in,
              int protection = filebuf::openprot);
    void close();
    filebuf *rdbuf() const;
};

4.16  Class ifstream - Function Reference
The following functions require the inclusion of file fstream.hpp.

ifstream::ifstream
Usage:
#include <fstream.hpp>
ifstream::ifstream();
ifstream(const char *name, int io_mode = ios::in,
         int protection = filebuf::openprot);
ifstream(int file_descriptor);
ifstream(int file_descriptor, char *memory, int length);

Description:
Four constructor options are provided. The default constructor sets up a
filebuf which will dynamically allocate its buffer area, and can be
associated with a file later using the attach() or open() functions. The
default constructor sets the error state to ios::badbit, since the stream
is initially unusable.

The second constructor attempts to open the named file. The default open
mode may be overriden, as may the file protection. The third constructor
sets up an ifstream using the file descriptor of an already opened file,
while the fourth does the same but allows the user to specify a buffer
area. Unbuffered operation may be forced by a zero memory argument or a
length argument <= zero.

Example:
ifstream ifs1;
ifstream ifs2("input.dat");
int fd = open(...);
ifstream ifs3(fd);
ifstream ifs4(fd,0,0);  // unbuffered

ifstream::attach
Usage:
#include <fstream.hpp>
void ifstream::attach(int file_descriptor);

Description:
Attaches the ifstream to the specified file. Fails if the stream is
already attached to a file, and sets the error state to ios::failbit.

Example:
ifstream ifs;
int fd = open(...);
ifs.attach(fd);

Return Value: None.

ifstream::open
Usage:
#include <fstream.hpp>
void open(const char *name, int io_mode = ios::in,
          int protection = filebuf::openprot);

Description:
Opens the specified file and attaches it to the ifstream. The default
open mode and protection may be overriden.

Failure to open the specified file will result in the error state being
set to (ios::failbit|ios::badbit). The open function will also fail if
the stream is already attached to a file, in this case, the error state
will be set to (rdstate()|ios::failbit).

Example:
ifstream ifs;
ifs.open("input.dat");

Return Value: None.

ifstream::close
Usage:
#include <fstream.hpp>
void ifstream::close();

Description:
The associated file is closed, and the filebuf put into an unattached
state. The error state will be set (ios::failbit|ios::badbit) if
rdbuf()->close() fails.

Example:
ifstream ifs;
ifs.open("input.dat");
ifs.close();

Return Value: None.

ifstream::rdbuf
Usage:
#include <fstream.hpp>
filebuf *ifstream::rdbuf() const;

Description:
Returns a pointer to the associated filebuf.

 This is typed differently from istream::rdbuf() which returns a
 streambuf pointer.

4.17  File Based Output Streams - Class ofstream
Output streams specialized on files are provided for by class ofstream.
Objects of type ofstream have the public interface of classes ios and
ostream, and their own public interface is as follows:

class ofstream : public fstream_common, public ostream {
public:
    ofstream();
    ofstream(const char *name, int io_mode = ios::out,
             int protection = filebuf::openprot);
    ofstream(int file_descriptor);
    ofstream(int file_descriptor, char *memory, int length);

    ~ofstream();

    void attach(int file_descriptor);
    void open(const char *name, int io_mode = ios::in,
              int protection = filebuf::openprot);
    void close();
    filebuf *rdbuf() const;
};

4.18  Class ofstream - Function Reference
The descriptions of the ifstream functions apply equally to class
ofstream.

4.19  File based Output Streams - Class fstream
Class fstream provides the capability to use both the istream and ostream
paradigms on the same file. Objects of type fstream have the public
interface of classes ios, istream and ostream, and their own public
interface is as follows:

class fstream : public fstream_common, public iostream {
public:
    fstream();
    fstream(const char *name, int io_mode = ios::in|ios::out,
            int protection = filebuf::openprot);
    fstream(int file_descriptor);
    fstream(int file_descriptor, char *memory, int length);

    ~fstream();

    void attach(int file_descriptor);
    void open(const char *name, int io_mode = ios::in,
              int protection = filebuf::openprot);
    void close();
    filebuf *rdbuf() const;
};
4.20  Class fstream - Function Reference
The descriptions of the ifstream functions apply equally to class
fstream.

4.21  A streambuf Specialized for In Memory Operations
The strstreambuf class is a derivation of streambuf that uses an area of
memory, either user nominated or dynamically allocated.

The extra public interface is as follows:

const int default_allocation = 32;

class strstreambuf : public streambuf {
public:
    strstreambuf(int = default_allocation);
    strstreambuf(char *memory, int length, char *put_area);
    strstreambuf(void *(*allocator)(size_t),
                 void (*deallocator)(void *), int = default_allocation);
    void freeze(int n=1);
    char *str();
    streambuf *setbuf(char *memory, int length);
};
4.22  Class strstreambuf - Function Reference
The following functions require the inclusion of file sstream.hpp.

strstream::strstream
Usage:
#include <sstream.hpp>
strstreambuf(int = default_allocation);
strstreambuf(char *memory, int length = 0, char *put_area = 0);
strstreambuf(void *(*allocator)(size_t), void (*deallocator)(void *),
             int = default_allocation);

Description:
The first constructor creates an empty strstreambuf in dynamic allocation
mode. Memory will be allocated as required starting with an allocation of
the size specified by the argument, defaulted to 32 bytes. Subsequent
allocations will increase the size of the strstreambuf by a factor of
3/2. The get and put areas of such a streambuf are contiguous. It will
not be possible to get characters until some have been put.

The second constructor creates a strstreambuf to use a user nominated
area of memory. There will be no dynamic reallocation. If length is
positive, then the length bytes starting at memory are used. If length is
zero, then memory is assumed to point at a null terminated string, and
strlen(memory) bytes will be used. If length is negative, the memory
region is assumed to be of indefinite length. The put area argument is
used to divide up the strstreambuf into get and put areas. If put_area is
zero or less than memory, then attempts to put to the strstreambuf will
be treated as errors, and the whole of the memory is a get area. If
put_area is greater than memory, then the area between memory and
put_area is the get area, and the area pointed at by put_area is the put
area.

The third constructor is similar to the first except that the allocator
and deallocator functions required to manage the dynamic allocation can
be specified.

Example:
strstreambuf ssb1;  // dynamic

char buffer[1024];
...;
strstreambuf ssb2(buffer,1024,buffer+512);  // half get, half put
strstreambuf ssb3(buffer,1024,buffer);      // no get area
strstreambuf ssb4(0, -1);                   // arbitrary get source
strstreambuf ssb2("abcdefghijklmnopqrstuvwxyz")
                               // get only, length is strlen() - 26

strstreambuf::freeze
Usage:
#include <sstream.hpp>
void strstreambuf::freeze(int = 1);

Description:
If the argument is nonzero, deletion of the current memory area by
dynamic allocation, or by the strstreambuf destructor is inhibited. Put
operations to a frozen strstreambuf are an error, though the effect is
not defined. A zero argument to freeze unfreezes the strstreambuf.

Example:
strstreambuf d;

d.sputn("some arbitrary source",21);
d.freeze();
d.sputn("xxxxxxxxxxxxxxxxxxxxxxxxxxx", 32);
    // will not cause further allocation, d will
    // end up with just "some arbitrary
    // sourcexxxxxxxxxxx" (the default allocation)

Return Value: None.

strstreambuf::str
Usage:
#include <sstream.hpp>
char *strstream::str();

Description:
Freezes the streambuf and returns a pointer to the start of the memory
area. If there is room in the current put area, a precautionary null byte
is appended.

Example:
char *foo()
{
    strstreambuf d;

    d.sputn("Speed the plough");
    // dynamically allocated
    return d.str();
    // allocation not deleted when d destructor called
}

strstream::setbuf
Usage:
#include <sstream.hpp>
streambuf *setbuf(char *memory, int length);

Description:
The memory argument is ignored. The length argument is used by
dynamically allocating strstreambufs as the size for the next allocation.

Example:
strstreambuf d;

d.setbuf(0,1024);
for (int i = 1024; i--;)
    d.sputc(' ');   // only one allocation

Return Value: Always returns a pointer to the object for which it was
              called.

4.23  Input and Output Streams Using strstreambuf
Classes istrstream, ostrstream and strstream provide input, output, and
bidirectional stream facilities to memory, using a strstreambuf. Objects
of these types share the public interface of classes ios, istream or
ostream or iostream, and their own public interface is as follows:

class istrstream : public istream {
public:
    istrstream(char *string);
    istrstream(char *memory, int length);
    strstreambuf *rdbuf() const;
};

class ostrstream : public ostream {
public:
    ostrstream();
    ostrstream(char *memory, int length, int mode = ios::out);
    char *str();
    int pcount() const;
    strstreambuf *rdbuf() const;
};

class strstream : public iostream {
public:
    strtream();
    strstream(char *memory, int length, int mode);
    char *str();
    strstreambuf *rdbuf() const;
};

4.24  Strstream Classes - Function Reference
iststream::istrstream
Usage:
#include <sstream.hpp>
istrstream::istrstream(char *string);
istrstream::istrstream(char *memory, int length);

Description:
The first constructor allows the creation of an istrstream from a null
terminated string. The second from an arbitrary area of memory of
specified length.

Example:
char *s = "a string which is to serve as source";
istrstream iss(s);

ostrstream::ostrstream
Usage:
#include <sstream.hpp>
ostrstream::ostrstream();
ostrstream::ostrstream(char *memory, int length, int mode = ios::out);

Description:
The first constructor creates a dynamically allocating ostrstream. The
second uses an arbitrary area of memory of specified length. If the mode
argument has ios::ate or ios::app (or both) set, the memory specified is
assumed to start with a null terminated string, and storage of put
characters starts at the null character.

strstream::strstream
Usage:
#include <sstream.hpp>
strstream::strstream();
strstream::strstream(char *memory, int length,
                     int mode = ios::in | ios::out);

Description:
The first constructor creates a dynamically allocating ostrstream. The
second uses an arbitrary area of memory of specified length. If the mode
argument has either or both of ios::ate or ios::app set, the memory
specified is assumed to start with a null terminated string, and storage
of put characters starts at the null character.

Example:
char buffer[80];
strcpy(buffer,"a string");
strstream ss1;  // dynamic
strstream ss2(buffer, 80, ios::app);

istrstream::rdbuf    ostrstream::rdbuf    strstream::rdbuf
Usage:
#include <sstream.hpp>
strstreambuf *istrstream::rdbuf() const;
strstreambuf *ostrstream::rdbuf() const;
strstreambuf *strstream::rdbuf() const;

Description:
Similar to istream::rdbuf() except that these return a pointer of type
strstreambuf* to the associated strstreambuf.

Example:
strstream ss;
strstreambuf *sbp = ss.rdbuf();

Return Value: A pointer to the associated strstreambuf.

ostrstream::str    strstream::str
Usage:
#include <sstream.hpp>
char *ostrstream::str();
char *strstream::str();

Description:
Returns a pointer to the memory being used by the associated
strstreambuf. See strstreambuf::str above.

4.25  A stdio FILE streambuf
An stdiobuf can be used instead of a filebuf when it is desired to mix
I/O using the C standard library stdio facilities, and C++ stream output.
New code should use filebufs, which should be substantially more
efficient, since stdiobuf operations are unbuffered.

The public interface differs from that of class streambuf as follows:

class stdiobuf : public streambuf {
public:
    stdiobuf(FILE *);
    FILE *stdiofile() const;
    ...;
};

4.26  Class stdiobuf - Function Reference
Users of this class need to include stdiobuf.hpp.
stdiobuf::stdiobuf
Usage:
#include <stdiobuf.hpp>
stdiobuf::stdiobuf(FILE *);

Description:
The single constructor takes as argument a FILE pointer as defined in
stdio.h.

Example:
FILE *fp = fopen(...);
stdiobuf stdb(fp);

stdiobuf::stdiofile
Usage:
#include <stdiobuf.hpp>
FILE *stdiobuf::stdiofile() const;

Description:
Returns the file pointer associated with the stdiobuf.

Return Value: As description.

4.27  Manipulators with Parameters
Manipulators with parameters allow simple expressions like:

    cout << setw(12) << setfill('#');

To modify the state of a stream in some way needs not only an indication
of what state variable to change, but also an argument to change it to.
These arguments are provided by a set of template types like the
following, SMANIP, parameterized on type T, and defined by suitable
macros in manip.hpp.

class SMANIP(T) {
public:
    SMANIP(T)(ios &(*)(ios &, T), T);
    friend istream &operator>>(istream &, SMANIP(T) &);
    friend ostream &operator<<(ostream &, SMANIP(T) &);
private:
    ios &(*func)(ios &, T);
    T value;
};

The constructor for a manipulator class like this stores a pointer to a
function that takes a stream reference and the required type as arguments.
It returns a reference to the argument stream, and also stores a value of
the required type.

The friend extractor or inserter function can then call the function
pointed at by the stored pointer, with the stream as its first argument
and the stored value as its second:

    istream &operator>>(istream &s, SMANIP(T) &m)
    {
        (*m.func)(s, m.value);
        return s;
    }

An alternative, called an applicator, is provided of the form:

class SAPP(T) {
    SAPP(T)(ios &(*)(ios &, T));
    SMANIP(T) operator()(T);
private:
    ios &(*func)(ios &, T);
};

This stores only the function pointer, and uses an overload of the
function call operator to provide the parameter value of type T. This
pseudo function call returns an SMANIP(T) object, so can be used with the
same extraction and insertion operator functions.

The header file manip.hpp declares template classes like these for class
ios, and for classes istream, ostream, and iostream:

SMANIP(T)
SAPP(T)
IMANIP(T)
IAPP(T)
OMANIP(T)
OAPP(T)
IOMANIP(T)
IOAPP(T)

Classes for types int and long are instantiated from these templates in
the same header file, along with appropriate extractor and inserter
functions (the friends of the manipulator classes). The header file then
defines the following functions that return manipulator objects:

SMANIP(long) resetiosflags(long);
SMANIP(int) setfill(int);
SMANIP(long) setiosflags(long);
SMANIP(int) setprecision(int);
SMANIP(int) setw(int);

These are implemented like this:

    static ios &_setw(ios &s, int w)
    {
        s.width(w);
        return s;
    }

    SMANIP(int) setw(int w)
    {
        return SMANIP(int)(_setw, w);
    }

These functions can then be embedded in the normal usage of extractors or
inserters:

    cout << resetiosflags(ios::floatfield) << setw(12);

Applicators can be used as follows:

    static ostream &_inschr(ostream &s, int c)
    {
        s << char(c);
        return s;
    }

    OAPP(int) character(_inschr);

Given the definition of this applicator, character, it can then be used
in a similar way:

    cout << character('a'); // output is 'a'

This is a trivial example, but applicators of this sort can be used as
shorthand for complex output operations that might otherwise be verbose
to express.

5. THE COMPLEX CLASS
                                                                                                                                      5. THE COMPLEX CLASS
Chapter 5 - The Complex Class
The class complex is implemented as a set of overloaded operators and
functions which provide a general complex mathematics capability. A
complex number is defined by a real part re, and an imaginary part im,
which are each stored in the complex class with type double.

5.1  Class Definition
class complex
{
public:
//constructors
    complex();
    complex(double re, double im );
    complex(const complex& z);

// operators
    // arithmetic:
    friend complex operator+(const complex&, const complex&);
    friend complex operator-(const complex&, const complex&);
    friend complex operator*(const complex&, const complex&);
    friend complex operator/(const complex&, const complex&);

    // relational:
    friend int operator&&(const complex&, const complex&);
    friend int operator||(const complex&, const complex&);
    friend int operator!=(const complex&, const complex&);
    friend int operator==(const complex&, const complex&);

    // assignment:
    complex& operator=(const complex&);
    complex& operator+=(const complex&);
    complex& operator-=(const complex&);
    complex& operator*=(const complex&);
    complex& operator/=(const complex&);

    // unary:
    int operator! () const;
    complex operator- () const;

    // streams:
    friend ostream& operator<<(ostream& s, const complex& x);
    friend istream& operator>>(istream& s, const complex& x);

// Functions
    double& real ();
    double& imag ();
    friend double real(const complex&);
    friend double imag(const complex&);
    friend complex conj(const complex&);
    friend double norm(const complex&);
    friend double modulus(const complex&);
    friend double arg(const complex&);
    friend complex polar(double range, double theta);

// Trigonometric and Hyperbolic functions
    friend complex cos(const complex&);
    friend complex cosh(const complex&);
    friend complex sin(const complex&);
    friend complex sinh(const complex&);
    friend complex tan(const complex&);
    friend complex tanh(const complex&);
    friend complex asin(const complex&);
    friend complex acos(const complex&);
    friend complex atan(const complex&);
    friend complex asinh(const complex&);
    friend complex atanh(const complex&);

// Mathematical functions
    friend complex exp(const complex&);
    friend complex log(const complex&);
    friend complex log10(const complex&);
    friend complex sqrt(const complex&);
    friend double abs(const complex&);
    friend complex pow(const complex&, double);
    friend complex pow(const complex&, const complex &);
    friend complex pow(double, const complex&);
    friend complex pow(const complex&, int);
};

5.2  Function Reference
complex::complex
Usage:
#include <complex.hpp>
complex();
complex(double re, double im );
complex(const complex& z);

Description:
double re       real portion
double im       imaginary portion
complex & z     complex variable

The constructors initialize an instance of a complex variable or an
instance of a temporary variable. The first complex class constructor
complex::complex(), an unadorned constructor, requires no arguments. The
last constructor complex::complex(const complex& x ) is the copy or X(X&)
constructor and is used to instantiate one complex with another. This
constructor is also available to the compiler.

Example:
A complex instance is defined using these constructors as follows:
complex myfunc()
{
    complex z;      // invokes complex::complex()

// invokes complex::complex(double, double)
    complex z1(1.2,3.0);

// invokes complex::complex(const complex &)
    complex z2 = z1;
    z = z2;
 // a temporary instance is created and added to z
    return complex(3.0, 2.0) + z;
}

See Also: Complex Class, operators, trigonometric and hyperbolic functions,
          complex functions, math functions

complex::operator
Usage:
#include <complex.hpp>

// arithmetic:
friend complex operator+(const complex&, const complex&);
friend complex operator-(const complex&, const complex&);
friend complex operator*(const complex&, const complex&);
friend complex operator/(const complex&, const complex&);

// relational:
friend int operator&&(const complex&, const complex&);
friend int operator||(const complex&, const complex&);
friend int operator!=(const complex&, const complex&);
friend int operator==(const complex&, const complex&);

// assignment:
complex& operator=(const complex&);
complex& operator+=(const complex&);
complex& operator-=(const complex&);
complex& operator*=(const complex&);
complex& operator/=(const complex&);



// unary:
int operator! () const;
complex operator- () const;

// streams:
friend ostream& operator<<(ostream& s, const complex& x);
friend istream& operator>>(istream& s, const complex& x);

Description:
The operators defined for class complex are overloaded to have an
analogous meaning to built-in operators; i.e. "+" is the addition of two
complex variables just as it is used for the addition of two variables of
type double. The operators in the complex class maintain conventional
operator precedence.

The following summarizes the operators defined for the complex class. The
variables z, z1 and z2 are of type complex. The variable i is of type int.

Arithmetic

z = z1 + z2 addition
z = z1 - z2 subtraction
z = -z1 negation
z = z1 * z2 multiplication
z = z1 / z2 division

Relational

i = z1 == z2    equality
i = z1 && z2    logical AND
i = z1 || z2    logical OR
i = z1 != z2    inequality

Assignment

z1 = z2
z1 += z2
z1 -= z2
z1 *= z2
z1 /= z2

Stream

cout << z1  output to ostream in the form ( re, im).
cin >> z1   input from istream of the form re im.

Example:
#include <iostream.hpp>
#include <stdlib.h>

int main()
{
    complex a(1,3), b(2,3);
    cout << a + b*5;
    return EXIT_SUCCESS;
}

See Also: Complex Class, operators, trigonometric functions, hyperbolic
          functions, complex functions, math functions

complex::function
Usage:
#include <complex.hpp>

double& real ();
double& imag ();
friend double real(const complex&);
friend double imag(const complex&);
friend complex conj(const complex&);
friend double norm(const complex&);
friend double modulus(const complex&);
friend double arg(const complex&);
friend complex polar(double range, double theta);

Description:
The functions described in this section are unique to complex type and do
not overload the names of the C math library. In the following z is
treated as a variable of type complex with a real part x and an imaginary
part y both of type double. The variables a, z1 and z2 are of type
complex while the variables u, r and t are of type double.

x = real(z)         Returns the real portion of z.
y = imag(z)         Returns the imaginary portion of z.
z1 = conj(z)        Returns the complex conjugate of z. If z
                    is x+iy, then conj(z) is x-iy.
u = arg(z)          Returns the argument of the complex
                    number z in radians.
u = norm(z)         Returns the square of the absolute value
                    or modulus of z. norm(z) = x + y
u = modulus         Returns the absolute value z.
                    modulus(z) = abs(z) = (x+y)
a = polar(r,theta)  Returns the complex that is the result of
                    converting polar coordinates r and theta
                    to x and y coordinates.

See Also: Hyperbolic functions, complex functions, math functions

Trigonometric Functions    Hyperbolic Functions
Usage:
#include <complex.hpp>

friend complex cos(const complex&);
friend complex cosh(const complex&);
friend complex sin(const complex&);
friend complex sinh(const complex&);
friend complex tan(const complex&);
friend complex tanh(const complex&);
friend complex asin(const complex&);
friend complex acos(const complex&);
friend complex atan(const complex&);
friend complex asinh(const complex&);
friend complex atanh(const complex&);

Description:
The trigonometric and hyperbolic functions displayed in this section
overload the names of the C library floating point trigonometric and
hyperbolic functions.

These functions perform complex class calculations using, in part, the C
library math and trigonometric functions. As such, error handling for the
routines is through the matherr function. This function may be overridden
to provide user defined exception handling.

In the following a and z are variables of type complex.

a = sin(z)      Returns the sine of z.
a = cos(z)      Returns the cosine of z.
a = tan(z)      Returns the tangent of z.
a = sinh(z)     Returns the hyperbolic sine of z.
a = cosh(z)     Returns the hyperbolic cosine of z.
a = tanh(z)     Returns the hyperbolic tangent of z.
a = asin(z)     Returns the arcsin of z.
a = acos(z      Returns the arccos of z.
a = atan(z)     Returns the arctangent of z.
a = asinh(z)    Returns the hyperbolic arcsin of z.
a = atanh(z)    Returns the hyperbolic arctangent of z.

See Also: Complex Class, operators, trigonometric and hyperbolic functions,
          complex functions, math functions

Mathematical Functions
Usage:
#include <complex.hpp>
friend complex exp(const complex&);
friend complex log(const complex&);
friend complex log10(const complex&);
friend complex sqrt(const complex&);
friend double  abs(const complex&);
friend complex pow(const complex&, double);
friend complex pow(const complex&, const complex &);
friend complex pow(double, const complex&);
friend complex pow(const complex&, int);

Description:
The functions described in this section overload functions contained in
the C math library to provide consistent complex support.

In the following z is treated as a variable of type complex with a real
part x and an imaginary part y both of type double. The variables a, z
and z1 are of type complex, u is of type double and n is of type integer.

a = log(z)      Returns the logarithm base e of z.
a = log10(z)    Returns the logarithm base 10 of z.
a = exp(z)      Returns the value of ez.
a = sqrt(z)     Returns the square root of z, z.
u = abs(z)      Returns the absolute value of z, (x+y)
a = pow(z,n)    Returns z to the integer power of n.
a = pow(z,u)    Returns z to the power of u.
a = pow(z,z1)   Returns z to the power of z1.
a = pow(u,z)    Returns u to the power of z.

See Also: Complex Class, operators, trigonometric and hyperbolic functions,
          complex functions, mathematical functions

6. A C++ SHELL FOR THE FLASH GRAPHICS FACILITIES
Chapter 6 - A C++ Shell for the Flash Graphics Facilities
6.1  Graphics Functions
The supplied C++ library provides an interface to the Zortech Flash
Graphics library facilities. The Flash Graphics library provides a set of
fast and flexible low level graphics primitives. However, these are often
cumbersome to use and provide an ideal candidate for a C++ encapsulation.
This is done by providing a class to represent the raw statistics of the
display itself and a hierarchy of classes which represent graphical
objects. Examine the file fgpptest.cpp on the distribution disks for
examples of how to use these functions.

6.2  Class Definition - FgDisp
The class which represents the display is a collection of static class
member functions which return information about the display area and
type. There is also a clear function, which wipes the screen clean in a
specified color, defaulted to black.

class FgDisp {
public:
    static fg_const_pbox_t box();
    static fg_coord_t left();
    static fg_coord_t right();
    static fg_coord_t bottom();
    static fg_coord_t top();

    static int height();
    static int width();
    static int inside (fg_coord_t x, fg_coord_t y);
    static int type();
    static void clear (fg_color_t color = FG_BLACK);
};

6.3  Function Reference - FgDisp
FgDisp::box
Usage:
#include <fg.hpp>
Static fg_const_pbox_t FgDisp::box();

Description:
Get pointer to a box describing the edges of the display.

Return Value: Returns fg.displaybox.

FgDisp::left    FgDisp::right    FgDisp::bottom    FgDisp::top
Usage:
#include <fg.hpp>
static fg_coord_t FgDisp::left();
static fg_coord_t FgDisp::right();
static fg_coord_t FgDisp::bottom();
static fg_coord_t FgDisp::top();

Description:
Inquire about the coordinates of the edges of the display.

Return Value: The relevant coordinate from fg.displaybox.

FgDisp::height    FgDisp::width
Usage:
#include <fg.hpp>
static int FgDisp::height();
static int FgDisp::width();

Description:
Inquire about the height and width of the display.

Return Value: The height or width of the display in pixels.

FgDisp::inside
Usage:
#include <fg.hpp>
static int FgDisp::inside(fg_coord_t x, fg_coord_t y);

Description:
Determine if point x, y is inside the display.

Return Value: 1 if the coordinate is inside the display area, else 0
              if the coordinate is outside the display area.

FgDisp::type
Usage:
#include <fg.hpp>
static int FgDisp::type();

Description:
Inquire about the display type (FG_EGAECD, etc.).

Return Value: The display type as an integer value defined in fg.h.

FgDisp::clear
Usage:
#include <fg.hpp>
static void FgDisp::clear(fg_color_t color = FG_BLACK);

Description:
Clear the display (set it to color).

6.4  Class Description - Fg
The hierarchy of classes representing graphical objects has the base
class Fg. This is an abstract class; that is, no instance of it will ever
be declared, it is merely a vehicle for the derivation of other graphical
classes which will actually be instantiated and used. The abstract nature
of the class is enforced by giving it a number of pure virtual functions.
Classes with one or more pure virtual functions may not be created except
as base objects for derived classes. The Fg class also has a number of
static access functions so that various features of an object can be
checked and features of the display can be adjusted.

The mode() and setmode() functions return and set the mode (SET or XOR).
Functions mask and setmask control the mask, which in turn controls
writing to the bit planes of the display adaptor. For many applications a
mask value of ~0 (all bits set) is appropriate, see under Flash Graphics
in the alphabetical list of functions for more details. The static
functions backg() and setbackg() report and set the background color for
all subsequently drawn objects. The function foreg() returns the set
foreground color for the particular instance of the class and setforeg()
sets this value. Function setdefforeg() sets the foreground color for all
following instantiations of objects unless they are specifically set to a
chosen foreground color. These functions are called with respect to an
instance of an object, they are not static.

The virtual functions to draw, move and zap objects are next, drawc()
(draw clipped) is a pure virtual function whose argument is a pointer to
the clipping box. Plain draw() is a call to drawc() with a pointer to the
full screen box, it is virtual though, since it is not possible to say
with certainty that this will suffice for all graphics objects and
circumstances. The erasec() and erase() functions are an analogous pair,
while the translate() function re-positions an object. One of the drawing
functions must be called to show it in its new position. Finally there is
a constructor taking no arguments and a virtual destructor. If deleting a
derived object via an Fg pointer, we want the derived class constructor
to be called, not the one for the base class.

class Fg    {   // Base class of all drawing objects
public:
    enum MODE { SET = FG_MODE_SET, XOR = FG_MODE_XOR };
    static int mode();
    static int setmode(enum MODE newmode);
    static int mask();
    static int setmask(int newmask);

    static fg_color_t backg();
    static fg_color_t setbackg(fg_color_t bg)};
    fg_color_t foreg();
    fg_color_t setforeg(fg_color_t fg);
    fg_color_t setdefforeg(fg_color_t dfg);

    virtual void drawc(fg_const_pbox_t clip) = 0;
    virtual void draw();
    virtual void erasec(fg_const_pbox_t clip) = 0;
    virtual void erase();
    virtual void translate(fg_coord_t xoffset, fg_coord_t yoffset) = 0;

// Constructor and Destructor:
    Fg();
    virtual ~Fg();
};

6.5  Function Reference - Fg
Fg::Fg
Usage:
#include <fg.hpp>
Fg::Fg();

Description:
Constructor.

Fg::mode
Usage:
#include <fg.hpp>
static int Fg::mode();

Description:
Returns the current drawing mode, either FG_MODE_SET or FG_MODE_XOR.

Return Value: See description

Fg::setmode
Usage:
#include <fg.hpp>
static int Fg::setmode(enum MODE newmode);

Description:
Resets the current drawing mode.

Return Value: The new mode setting.

Fg::mask
Usage:
#include <fg.hpp>
static int Fg::mask();

Description:
Returns current mask setting.

Return Value: See description

Fg::setmask
Usage:
#include <fg.hpp>
static int Fg::setmask(int newmask);

Description:
Sets mask, that is, which bit planes will be written to.

Return Value: The new mask setting.

Fg::backg
Usage:
#include <fg.hpp>
static fg_color_t Fg::backg();

Description:
Returns the current background color.

Return Value: See Description

Fg::setbackg
Usage:
#include <fg.hpp>
static fg_color_t Fg::setbackg(fg_color_t bg);

Description:
Sets the background color. Note that the background color variable is
static.

Return Value: The new background color.

Fg::foreg
Usage:
#include <fg.hpp>
fg_color_t Fg::foreg();

Description:
Returns the current foreground color.

Return Value: See Description

Fg::setforeg
Usage:
#include <fg.hpp>
fg_color_t Fg::setforeg(fg_color_t fg);

Description:
Sets the foreground color.

Return Value: The new foreground color.

Fg::setdefforeg
Usage:
#include <fg.hpp>
fg_color_t Fg::setdefforeg(fg_color_t dfg);

Description:
Sets the default foreground color for newly constructed objects unless
specifically overridden.

Return Value: The new default foreground color

Fg::drawc    (Pure Virtual Function)
Usage:
#include <fg.hpp>
virtual void Fg::drawc(fg_const_pbox_t clip);

Description:
Draw the object. Note that the drawing is not guaranteed to be complete
until fg_flush() is called. Note, drawc is given a fg_const_pbox_t as its
argument. This is the box against which to clip all output:

Fg::draw
Usage:
#include <fg.hpp>
virtual void Fg::draw();

Description:
Draw the object. Clip against the edge of screen.

Fg::erasec (Pure Virtual Function)
Usage:
#include <fg.hpp>
virtual void Fg::erasec(fg_const_pbox_t clip)

Description:
Corresponding function to erase the object:

Fg::erase
Usage:
#include <fg.hpp>
virtual void Fg::erase();

Description:
Erase an object clipped against edge of screen.

Fg::translate
Usage:
#include <fg.hpp>
virtual void Fg::translate(fg_coord_t xoffset, fg_coord_t yoffset);

Description:
Translate the object, that is, move it by xoffset, yoffset.

6.6  Class Description - FgDot
The first actual graphical object is the dot. As might be expected this
is quite simple. There are functions to set the coordinates of the dot
and functions to read them. The drawc(), erasec() and translate()
functions all MUST be redefined, since they are instances of a pure
virtual base function. FgDot also has a constructor, which requires the
programmer to specify where it is to appear. There seems no good reason
for providing a default value.

class FgDot : public Fg {
public:
    fg_coord_t setx(fg_coord_t x);
    fg_coord_t sety(fg_coord_t y);

    fg_coord_t x();
    fg_coord_t y();

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);
    virtual void translate(fg_coord_t xoffset, fg_coord_t yoffset);

// Constructor
    FgDot(fg_coord_t x, fg_coord_t y);
};

6.7  Function Reference - FgDot
The functions available are the same as for class Fg except for the
following:

FgDot::FgDot
Usage:
#include <fg.hpp>
FgDot::FgDot(fg_coord_t x, fg_coord_t y);

Description:
Constructor specifying where to draw the dot.

FgDot::setx FgDot::sety
Usage:
#include <fg.hpp>
fg_coord_t FgDot::setx(fg_coord_t x);
fg_coord_t FgDot::sety(fg_coord_t y);

Description:
Reset the x and y coordinates of the dot.

FgDot::x FgDot::y
Usage:
#include <fg.hpp>
fg_coord_t FgDot::x();
fg_coord_t FgDot::y();

Description:
Access the respective x and y coordinates of the dot.

Class Description - FgLine
The FgLine object has essentially the same set of functions. It is
possible to set and read the individual coordinates of each end of the
line and the pure virtual functions are redefined. Constructors provide
for initializing the line from four fg_coord_t values, or from a pointer
to a suitable set of values.

The line object adds the capability to set and read the line style, as
described under Flash Graphics in the alphabetical list of functions.

class FgLine : public Fg {
public:
    fg_const_pline_t line();

    fg_coord_t setx1(fg_coord_t x);
    fg_coord_t sety1(fg_coord_t y);
    fg_coord_t setx2(fg_coord_t x);
    fg_coord_t sety2(fg_coord_t y);

    fg_coord_t x1();
    fg_coord_t y1();
    fg_coord_t x2();
    fg_coord_t y2();

    static int type();
    static int settype(int type);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);
    virtual void translate(fg_coord_t xoffset, fg_coord_t yoffset);

    FgLine(fg_coord_t x1, fg_coord_t y1, fg_coord_t x2, fg_coord_t y2);
    FgLine(fg_const_pline_t pline);
};

6.8  Function Reference - FgLine
The functions available are the same as for class Fg except for the
following:

FgLine::FgLine
Usage:
#include <fg.hpp>
FgLine::FgLine(fg_coord_t x1, fg_coord_t y1, fg_coord_t x2,
               fg_coord_t y2);
FgLine::FgLine(fg_const_pline_t pline);

Description:
Constructors, either specifying the coordinates between which the line is
to be drawn individually, or initializing with an existing line.

FgLine::line
Usage:
#include <fg.hpp>
fg_const_pline_t FgLine::line();

Description:
Returns the current coordinates of the line as a fg_line_t variable.

FgLine::setx1 FgLine::sety1 FgLine::setx2 FgLine::sety2
Usage:
#include <fg.hpp>
fg_coord_t FgLine::setx1(fg_coord_t x);
fg_coord_t FgLine::sety1(fg_coord_t y);
fg_coord_t FgLine::setx2(fg_coord_t x);
fg_coord_t FgLine::sety2(fg_coord_t y);

Description:
Reset the respective coordinates between which the line is to be drawn.

FgLine::x1 FgLine::y1 FgLine::x2 FgLine::y2
Usage:
#include <fg.hpp>
fg_coord_t FgLine::x1();
fg_coord_t FgLine::y1();
fg_coord_t FgLine::x2();
fg_coord_t FgLine::y2();

Description:
Access the respective coordinates between which the line is to be drawn.

FgLine::type
Usage:
#include <fg.hpp>
static int FgLine::type();

Description:
Access the line style (FG_LINE_XXXX).

FgLine::settype
Usage:
#include <fg.hpp>
static int FgLine::settype(int type);

Description:
Set the style with which the line will be drawn, see the section Types of
Lines under Flash Graphics in the alphabetical list of functions.

Class Description - FgThickLine
FgThickLine is a simple derivation from FgLine. Everything is inherited
from FgLine. Functions are added to read and set the line thickness and
the constructors provide for this to be specified.

class FgThickLine: public FgLine {
public:
    int thickness();
    int setthickness(int t);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);
    virtual void translate(fg_coord_t xoffset, fg_coord_t yoffset);

// Constructors
    FgThickLine(fg_coord_t x1, fg_coord_t y1,
                fg_coord_t x2, fg_coord_t y2, int t);
    FgThickLine(fg_const_pline_t pline, int t);
};

6.9  Function Reference - FgThickLine
The functions available are the same as for class FgLine.

Class Description - FgBox
FgBox is similarly derived from FgLine. Basically it provides different
names for the same access and setting functions and redefines the drawc()
and erasec() functions. These inlined functions should not introduce any
noticeable overhead. FgBox is nearly identical to the FgLine class, the
main difference being the redefinition of the drawing functions.

class FgBox : public FgLine {
public:
    fg_const_pbox_t box();

    fg_coord_t setleft(fg_coord_t x);
    fg_coord_t setbottom(fg_coord_t y);
    fg_coord_t setright(fg_coord_t x);
    fg_coord_t settop(fg_coord_t y);
    fg_coord_t left();
    fg_coord_t bottom();
    fg_coord_t right();
    fg_coord_t top();

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructors
    FgBox(fg_coord_t left, fg_coord_t bottom, fg_coord_t right,
          fg_coord_t top);
    FgBox(fg_const_pbox_t pbox);
};

6.10  Function Reference - FgBox
The functions available are the same as for class Fg except for the
following:

FgBox::FgBox
Usage:
#include <fg.hpp>
FgBox::FgBox(fg_coord_t left, fg_coord_t bottom, fg_coord_t
right, fg_coord_t top);
FgBox(fg_const_pbox_t pbox);

Description:
Constructors, either specifying the coordinates between which the box is
to be drawn individually, or initializing with an existing box.

FgBox::box
Usage:
#include <fg.hpp>
fg_const_pbox_t FgBox::box();

Description:
Returns a constant pointer to the box.

FgBox::setleft FgBox::setbottom FgBox::setright FgBox::settop
Usage:
#include <fg.hpp>
fg_coord_t FgBox::setleft(fg_coord_t x);
fg_coord_t FgBox::setbottom(fg_coord_t y);
fg_coord_t FgBox::setright(fg_coord_t x);
fg_coord_t FgBox::settop(fg_coord_t y);

Description:
Reset the respective coordinates of the box.

FgBox::left FgBox::bottom FgBox::right FgBox::top
Usage:
#include <fg.hpp>
fg_coord_t FgBox::left();
fg_coord_t FgBox::bottom();
fg_coord_t FgBox::right();
fg_coord_t FgBox::top();

Description:
Access the current coordinates of the box.

Class Description - FgFillBox
FgFillBox can then be derived from the FgBox. It redefines the pure
virtual functions and provides constructors. It is nearly identical to
the FgBox class, the main difference being the redefinition of the
drawing functions.

class FgFillBox : public FgBox {

public:
    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructors
    FgFillBox(fg_coord_t left, fg_coord_t bottom,
              fg_coord_t right, fg_coord_t top);
    FgFillBox(fg_const_pbox_t pbox);
};

6.11  Function Reference - FgFillBox
The functions available are the same as for class FgBox except for the
following:

FgFillBox::FgFillBox
Usage:
#include <fg.hpp>
FgFillBox(fg_coord_t left, fg_coord_t bottom, fg_coord_t right,
          fg_coord_t top);
FgFillBox(fg_const_pbox_t pbox);

Description:
Constructors, either specifying the coordinates between which the box is
to be drawn individually, or initializing with an existing box.

Class Description - FgChar
FgChar is derived from FgDot, the dot part of FgChar is used to determine
the position of the lower left corner of the character. Set and read
functions are provided for the actual character and for the required
rotation. The constructor allows the character and rotation to be
specified, with the rotation defaulted to zero.

class FgChar : public FgDot {
public:
    char ch();
    char setch(char ch);

    char rot();
    char setrot(int rot);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgChar(fg_coord_t x, fg_coord_t y, char ch, int rot =
    FG_ROT0);
};
6.12  Function Reference - FgChar
The functions available are the same as for class FgDot except for the
following:

FgChar::FgChar
Usage:
#include <fg.hpp>
FgChar::FgChar(fg_coord_t x, fg_coord_t y, char ch, int rot = FG_ROT0);

Description:
Constructor specifying the coordinates at which the character is to be
written, the character, and an optional rotation. This is defaulted to
FG_ROT0.

FgChar::ch
Usage:
#include <fg.hpp>
char FgChar::ch();

Description:
Accesses the current character value.

FgChar::setch
Usage:
#include <fg.hpp>
char FgChar::setch(char ch);

Description:
Resets the character, and returns its new value.

FgChar::rot
Usage:
#include <fg.hpp>
char FgChar::rot();

Description:
Returns the current rotation.

FgChar::setrot
Usage:
#include <fg.hpp>
char FgChar::setrot(int rot);

Description:
Resets and returns a new rotation.

Class Description - FgMatrix
The FgMatrix object is multi-purpose and may be used to draw icons or to
implement alternative fonts. It is derived from FgBox and the associated
box encloses the matrix. It has set and read functions for the matrix to
be displayed and the required rotation. The matrix is copied, so the
array arguments to setmatrix() and the constructor may be automatic.

Since it has a pointer member and a destructor, it gets a copy
constructor and operator= to avoid duplicating pointers to the same block
of allocated memory.

class FgMatrix : public FgBox { // FgBox encloses the matrix
public:
    const char *matrix();
    const char *setmatrix(const char *matrix);

    char rot();
    char setrot(int rot);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Standard constructor
    FgMatrix(fg_coord_t x, fg_coord_t y, fg_const_pbox_t box,
             char *matrix, int rot = FG_ROT0);

// Copy constructor and operator=
    FgMatrix(const FgMatrix&);
    operator=(const FgMatrix&);

// Destructor.
    ~FgMatrix();
};

6.13  Function Reference - FgMatrix
The functions available are the same as for class FgBox except for the
following:

FgMatrix::FgMatrix
Usage:
#include <fg.hpp>
FgMatrix::FgMatrix(fg_coord_t x, fg_coord_t y, fg_const_pbox_t box,
                   char *matrix, int rot = FG_ROT0);
FgMatrix::FgMatrix(const FgMatrix&);

Description:
This first constructor is the standard one. box is the enclosing box for
the matrix. matrix is a pointer to the matrix data and it will be drawn
with rotation rot. This is defaulted to FG_ROT0. x and y will move the
initial position of the box by x and y pixels.

The copy constructor is provide to prevent the duplication of pointers.

FgMatrix::operator=
Usage:
#include <fg.hpp>
FgMatrix::operator=(const FgMatrix&);

Description:
An operator= is necessary to prevent the duplicating of pointers.

FgMatrix::matrix;
Usage:
#include <fg.hpp>
const char *FgMatrix::matrix();

Description:
Returns a const pointer to the matrix data.

FgMatrix::setmatrix
Usage:
#include <fg.hpp>
const char *FgMatrix::setmatrix(const char *matrix);

Description:
Provide new matrix data. setmatrix() takes a pointer to the new data,
however a local copy is made.

Class Description - FgString
FgString, like FgChar, is derived from FgDot. Otherwise it is rather like
FgMatrix. It too, has set and read functions for the string to be
displayed and for the required rotation. Again the string is copied, so
the arguments to setstring() and the constructor may be automatic. Since
it has a pointer to dynamic memory and a destructor, it also gets a copy
constructor and operator= to avoid duplicating pointers to the same chunk
of allocated memory.

class FgString : public FgDot {
// FgDot is the position of the lower left corner
public:
    char *string();
    char *setstring(char *string);

    char rot();
    char setrot(int rot);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgString(fg_coord_t x, fg_coord_t y, char *string,
             int rot = FG_ROT0);

// A copy constructor and operator=
    FgString(const FgString&);
    FgString& operator=(const FgString&);

// Destructor.
    ~FgString();
};

6.14  Function Reference - FgString
The functions available are the same as for class FgDot except for the
following:

FgString::FgString
Usage:
#include <fg.hpp>
FgString::FgString(fg_coord_t x, fg_coord_t y, char *string,
                   int rot = FG_ROT0);
FgString::FgString(const FgString&);

Description:
Parameters x and y are the lower left corner from which the string will
be displayed. string is a pointer to the data, a local copy of which will
be made. It will have rotation rot. This is defaulted to FG_ROT0.

The copy constructor is provide to prevent the duplication of pointers.

FgString::operator=
Usage:
#include <fg.hpp>
FgString::operator=(const FgString&);

Description:
An operator= is necessary to prevent the duplicating of pointers.

FgString::string
Usage:
#include <fg.hpp>
char *FgString::string();

Description:
Returns the current string.

FgString::setstring
Usage:
#include <fg.hpp>
char *FgString::setstring(char *string);

Description:
Change the current string. A local copy of the data is kept. A pointer to
the local copy is returned.

Class Description - FgCircle
An FgCircle is just a fat FgDot and the simplicity of its implementation
illustrates this.

class FgCircle : public FgDot {
public:
    fg_coord_t setradius(fg_coord_t radius);
    fg_coord_t radius();

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgCircle(fg_coord_t x, fg_coord_t y, fg_coord_t radius);
};

6.15  Function Reference - FgCircle
The functions available are the same as for class FgDot except for the
following:

FgCircle::FgCircle
Usage:
#include <fg.hpp>
FgCircle::FgCircle(fg_coord_t x, fg_coord_t y, fg_coord_t radius);

Description:
Constructor. The circle will have a centre at x, and the final argument
contains the radius.

FgCircle::setradius
Usage:
#include <fg.hpp>
fg_coord_t FgCircle::setradius(fg_coord_t radius);

Description:
Sets the radius of the circle and returns the new value.

FgCircle::radius
Usage:
#include <fg.hpp>
fg_coord_t FgCircle::radius();

Description:
Returns the current radius.

Class Description - FgArc
FgArc is derived from FgCircle, with extra functions to set the start and
end angle.

class FgArc : public FgCircle {
public:
    fg_coord_t setstart(fg_coord_t start);
    fg_coord_t setend(fg_coord_t end);
    fg_coord_t start();
    fg_coord_t end();

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgArc(fg_coord_t x, fg_coord_t y, fg_coord_t radius,
             fg_coord_t start, fg_coord_t end);
};

6.16  Function Reference - FgArc
The functions available are the same as for class FgCircle except for the
following:

FgArc::FgArc
Usage:
#include <fg.hpp>
FgArc::FgArc(fg_coord_t x, fg_coord_t y, fg_coord_t radius,
             fg_coord_t start, fg_coord_t end);

Description:
Constructor. The arc will have a centre at x and y, a radius, radius.
start and end are the start and end angles, measured in 10ths of a
degree.

FgArc::setstart
Usage:
#include <fg.hpp>
fg_coord_t FgArc::setstart(fg_coord_t start);

Description:
Resets the start angle of the arc.

FgArc::setend
Usage:
#include <fg.hpp>
fg_coord_t FgArc::setend(fg_coord_t end);

Description:
Resets the end angle of the arc.

FgArc::start
Usage:
#include <fg.hpp>
fg_coord_t FgArc::start();

Description:
Returns the current start angle.

FgArc::end
Usage:
#include <fg.hpp>
fg_coord_t FgArc::end();

Description:
Returns the current end angle.

Class Description - FgEllipse
FgEllipse is derived in much the same way from FgArc.

class FgEllipse : public FgArc {
public:
    fg_coord_t setxradius(fg_coord_t xrad);
    fg_coord_t setyradius(fg_coord_t yrad);
    fg_coord_t xradius();
    fg_coord_t yradius();

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgEllipse(fg_coord_t x, fg_coord_t y, fg_coord_t radius,
              fg_coord_t yradius, fg_coord_t start, fg_coord_t end);
};

6.17  Function Reference - FgEllipse
The functions available are the same as for class FgArc except for the
following:

FgEllipse::FgEllipse
Usage:
#include <fg.hpp>
FgEllipse::FgEllipse(fg_coord_t x,      fg_coord_t y,
                     fg_coord_t radius, fg_coord_t yradius,
                     fg_coord_t start,  fg_coord_t end);
Description:
Constructor. The parameters x and y are the coordinates of the centre of
the ellipse. It has a radius of xradius in the x direction and a radius
of yradius in the y direction. start and end are the start and end angles
respectively in 10ths of a degree.

FgEllipse::setxradius
Usage:
#include <fg.hpp>
fg_coord_t FgEllipse::setxradius(fg_coord_t xrad);

Description:
Reset the radius in the x direction.

FgEllipse::setyradius
Usage:
#include <fg.hpp>
fg_coord_t FgEllipse::setyradius(fg_coord_t yrad);

Description:
Reset the radius in the y direction.

FgEllipse::xradius
Usage:
#include <fg.hpp>
fg_coord_t FgEllipse::xradius();

Description:
Returns the current radius in the x direction.

FgEllipse::yradius;
Usage:
#include <fg.hpp>
fg_coord_t FgEllipse::yradius();

Description:
Returns the current radius in the y direction.

Class Description - FgPolygon
FgPolygon breaks the established mould, since it is a completely new
derivation from Fg. However it follows much the same pattern. Its data
consists of a note of the number of vertices and the line type and a list
of coordinate pairs, one more pair than there are vertices. The first and
last pairs overlap. The polygon is drawn in the order in which the
vertices appear in the list. As usual there are setting and reading
functions for the private data and since FgPolygon allocates memory,
there are the required copy constructor and operator=.

class FgPolygon : public Fg {
public:
    unsigned int vertices();

    const fg_coord_t *polygon();
    const fg_coord_t *setpolygon(unsigned int vertices,
                                 const fg_coord_t *poly);

    void setvertex (unsigned int vertex,fg_coord_t x,fg_coord_t y);

    int type();
    int settype(int type);

    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);
    virtual void translate(fg_coord_t xoffset, fg_coord_t yoffset);

// Constructor

    FgPolygon(unsigned int vertices, const fg_coord_t
              *poly = 0, int type = FG_LINE_SOLID);

// Copy constructor and operator=
    FgPolygon(const FgPolygon&);
    virtual FgPolygon& operator=(const FgPolygon&);

// Destructor.
    ~FgPolygon();
};

6.18  Function Reference - FgPolygon
The functions available are the same as for class Fg except for the
following:

FgPolygon::FgPolygon
Usage:
#include <fg.hpp>
FgPolygon::FgPolygon(unsigned int vertices, const fg_coord_t
                     *poly = 0, int type = FG_LINE_SOLID);
FgPolygon::FgPolygon(const FgPolygon&);

Description:
Constructor. vertices is the number of corners. poly is a pointer to a
list of coordinate pairs. The final pair should be the same as the first
pair if the figure is to be closed.

A copy constructor is provided to prevent pointer duplication.

FgPolygon::operator=
Usage:
#include <fg.hpp>
virtual FgPolygon& FgPolygon::operator=(const FgPolygon&);

Description:
An operator= function is provided to prevent pointer duplication.

FgPolygon::vertices
Usage:
#include <fg.hpp>
unsigned int FgPolygon::vertices();

Description:
Returns the number of corners in the polygon.

FgPolygon::polygon
Usage:
#include <fg.hpp>
const fg_coord_t *FgPolygon::polygon();

Description:
Returns a pointer to the list of allocated vertices. These will be in
pairs. The last pair must be the same as the first pair to make a closed
figure.

FgPolygon::setpolygon
Usage:
#include <fg.hpp>
const fg_coord_t *FgPolygon::setpolygon(unsigned int vertices,
                                        const fg_coord_t *poly);
Description:
Resets the number of vertices to vertices, poly is a pointer to a new
list of coordinates.

FgPolygon::setvertex
Usage:
#include <fg.hpp>
void FgPolygon::setvertex (unsigned int vertex,fg_coord_t x,
                           fg_coord_t y);

Description:
Resets a vertex to x and y coordinates.

FgPolygon::type
Usage:
#include <fg.hpp>
int FgPolygon::type();

Description:
The type of line to draw with.

FgPolygon::settype
Usage:
#include <fg.hpp>
int FgPolygon::settype(int type);

Description: Resets the line type. It will be of type FG_LINE_XXXX.

Class Description - FgFilledPolygon
FgFilledPolygon class is a simple derivation from FgPolygon. It redefines
the pure virtual functions and provides constructors which pass their
arguments along to the base class. There is no need for an alternative
implementation of operator=, since that in FgPolygon is virtual so it can
be used equally well by either.

class FgFilledPolygon : public FgPolygon {
public:
    virtual void drawc(fg_const_pbox_t clip);
    virtual void erasec(fg_const_pbox_t clip);

// Constructor
    FgFilledPolygon (unsigned int vertices, const fg_coord_t *poly);

// Copy constructor
    FgFilledPolygon(const FgFilledPolygon &a);
};
6.19  Function Reference - FgFilledPolygon
The functions available are the same as for class Fg except for the
following:

FgFilledPolygon::FgFilledPolygon
Usage:
#include <fg.hpp>
FgFilledPolygon::FgFilledPolygon (unsigned int vertices,
                                  const fg_coord_t *poly);
FgFilledPolygon::FgFilledPolygon (const FgFilledPolygon &a);

Description:
Constructor. vertices is the number of corners of the polygon. poly is a
list of coordinate pairs for each corner. The last pair and the first
should be the same for a closed figure.

A copy constructor is provided to prevent pointer duplication.

7. THE C TOOLS
Chapter 7 - The C Tools
Introduction to the C Tools
The Zortech C++ compiler includes a number of C tools that have been in
use within Zortech for many years and which are included in the Zortech
C++ package for the convenience of those who may not already have written
their own versions. This chapter contains details of some of these tools
and explains how they can be used to improve your productivity. The C
Tools are normally installed in the sample directory by the installation
program. You can, of course, remove them if they are not required.

Several C tools are provided with the compiler. They are all supplied in
source form. Here are brief descriptions of the most important ones.

The List Toolkit
Provides a straightforward singly linked list implementation for standard
C programs. This is provided in the files list.h and list.c.

The MEM Toolkit
Provides facilities for monitoring memory allocation and deallocation
making it much simpler to track down allocation and pointer bugs in your
applications. This is provided in the files mem.h and mem.c.

The Name Unmangling Toolkit
Provides pre-written C routines for unmangling C++ "mangled" function
names, together with a sample application which can be used on map files
and the output of the linker. These are provided in the files unmangle.c
and um.c.

The File Toolkit
Provides a number of portable routines for handling files. The source is
contained in file.h and file.c.

The Filespec Toolkit
Provides a set of portable routines for handling file specifications,
that is file paths, names and extensions. The source is contained in
filespec.h and filespec.c.

Pop-up Menus
A pop-up menu facility, written in C, is provided in the files menu.h and
menu.c. It uses functions from both the disp and mouse (msm) packages.

Other Utilities
There are also a number of other useful utilities provided in source form
in this directory, as well as the source to some of the standard compiler
support tools such as PATCHOBJ and MAKEDEP.

A makefile is provided for many of these utilities.

8. THE LIST TOOLKIT
Chapter 8 - The List Toolkit
List is a complete package of C functions to deal with singly linked
lists of pointers or integers. It has three main features:

1. It has loop-back tests.

2. Each item in the list can have multiple predecessors, enabling
different lists to "share" a common tail. This is done using the
reference counting method.

3. The list package enables extra debugging checks if the macro MEM_DEBUG
is defined when it is compiled. This is designed to work with the
debugging features of the MEM package. This is why list is supplied in
source, not library, form.

8.1  Example
/* Read list of lines from stdin, reverse it,   */
/* and write result to stdout                   */
/* To compile: ZTC LISTDEMO LIST MEM            */

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#include  "list.h"

int main()
{
    list_t list = NULL;
    list_t le;              /* list walker */
    char buffer[81];        /* line buffer */

    mem_init();             /* list uses mem, so initialize mem */
    list_init();            /* and initialize list package */

    /* Read in list, in reverse order */

    while (fgets(buffer,sizeof(buffer),stdin))
    {
        char *p;

        p = strdup(buffer);     /* make copy */
        if (!p || !list_prepend(&list, p))
                                /* add to front */
            break;              /* no memory */
    }

    /* Write out list */
    for (le = list; le; le = list_next(le))
        fputs((char *) list_ptr(le),stdout);

    list_free(&list,free);  /* free list */
    list_term();            /* terminate list package */
    mem_term();             /* terminate mem package */

    return EXIT_SUCCESS;
}

8.2  Variables, Typedefs and Defines
list_t             List type

FPNULL             Null function pointer designed to be a
                   NULL argument to list_free

int list_inited    != 0 if list package is initialized

8.3  Function Reference
list_append
Usage:
#include "list.h"
list_t list_append (list_t *plist,void *ptr);

Description:
Append ptr to *plist.

Return Value: Pointer to list item created, NULL if out of memory.

list_appenddata
Usage:
#include "list.h"
void list_appenddata (list_t *plist,int d);

Description:
Append integer item to list.

Return Value: None.

See Also: list_append

list_cmp
Usage:
#include "list.h"
int list_cmp(list_t list1,list_t list2,
             int (_cdecl *func)(void *,void *));

Description:
Compare two lists using the specified comparison function. The comparison
function is the same as used for qsort().

Return Value: If they compare equal, return 0 else value returned by func.

list_copy
Usage:
#include "list.h"
list_t list_copy(list_t list);

Description:
Copy a list and return it.

Return Value: New list.

list_data
Usage:
#include "list.h"
int list_data(list_t list);

Description:
Return integer item from list entry. If a pointer was stored in this list
instead of an int, then garbage will be returned.

Return Value: The int.

See Also: list_ptr

list_equal
Usage:
#include "list.h"
int list_equal(list_t list1,list_t list2);

Description:
Compare two lists.

Return Value: If they have the same pointers, return 1 else 0.

list_free
Usage:
#include "list.h"
void list_free(list_t *plist,void (_cdecl freeptr)(void *));

Description:
Free list, optionally calling a function on each entry to free. On input,
plist is a pointer to the list to free. freeptr is a pointer to the
freeing function for the data pointer. Typically, one of the following
values for freeptr are used:

free        The standard free function from stdlib.h.

mem_freefp  The corresponding routine if the MEM
            package was used to allocate the data.

FPNULL      If no function is to be called.
            On completion, *plist is set to NULL.

Return Value: None.

list_init
Usage:
#include "list.h"
void list_init(void);

Description:
Initialize list package. Output: list_inited = 1

Return Value: None.

See Also: list_term

list_inlist
Usage:
#include "list.h"
list_t list_inlist(list_t list,void *ptr);

Description:
Search for ptr in list.

Return Value: If found, return list entry that it is, else NULL.

list_last
Usage:
#include "list.h"
list_t list_last(list_t list);

Description:
Return last list entry in list.

Return Value: Last entry in list.

list_link
Usage:
#include <list.h>
list_t list_link(list_t list);

Description:
Create link to existing list, that is, increment the reference count of
list. list can be NULL.

Return Value: The value of list.

list_next
Usage:
#include "list.h"
list_t list_next(list_t list);

Description:
Used to proceed to the next entry in a list.

Return Value: The next list_t in the list.

list_nitems
Usage:
#include "list.h"
int list_nitems(list_t list);

Description:
Count and return number of items in list.

Return Value: Number of entries in list.

list_nth
Usage:
#include "list.h"
list_t list_nth(list_t list,int n);

Description:
Return nth list entry in list.

Return Value: Nth list entry in list.

list_prepend
Usage:
#include "list.h"
list_t list_prepend(list_t *plist,void *ptr);

Description:
Prepend ptr to *plist.

Return Value: Pointer to list item created (which is also the start
              of the list), NULL if out of memory.

list_prependdata
Usage:
#include "list.h"
void list_prependdata(list_t *plist,int d);

Description:
Prepend integer item to list.

Return Value: None

list_prev
Usage:
#include "list.h"
list_t list_prev(list_t start,list_t list);

Description:
Return pointer to previous item in list. Since this is a singly linked
list, the start of the list is needed so that the predecessor can be
found.

Return Value: The previous list_t in the list. It is an error if list is
              not in the list for which start is the start. If list is at
              the beginning of the list (list == start), then NULL is
              returned.

list_pop
Usage:
#include "list.h"
void *list_pop(list_t *plist);

Description:
Remove first entry from list pointed to by *plist.

Return Value: First entry, NULL if *plist is NULL.

list_ptr
Usage:
#include "list.h"
void *list_ptr(list_t list);

Description:
Return pointer from list entry. If an int was stored in this list instead
of a pointer, then garbage will be returned.

Return Value: The pointer.

See Also: list_data

list_subtract
Usage:
#include "list.h"
void *list_subtract(list_t *plist,void *ptr);

Description:
The list is traversed until the list entry holding ptr is found. That
entry is removed from the list. On completion, *plist is updated to be
the start of the new list.

Return Value: NULL if *plist is NULL or ptr is not found in the list,
              otherwise ptr.

list_term
Usage:
#include "list.h"
void list_term(void);

Description:
Terminate list package. It is an error if there are any unfreed lists.
Set list_inited to 0.

Return Value: None.

9. DEBUGGING DYNAMIC MEMORY ALLOCATION
Chapter 9 - Debugging Dynamic Memory Allocation
9.1  Introduction
The C and C++ programming languages are extremely powerful, but with that
power comes problems. The use of pointers and dynamic memory allocation
can lead to very hard to track "pointer bugs". Normally confident and
capable programmers have been known to turn white and cower under their
desks at the mere mention of the phrase. The symptoms of pointer bugs are
core dumps, scrambled disks and, even worse, failures that occur once in
10,000 iterations giving rise to non-reproducible results. Zortech C++ is
unique. It provides a powerful technique for isolating and correcting
pointer bugs. This technique requires the use of a package of C
functions, the MEM package, which can be used during program development
to help prevent pointer bugs from occurring in the first place and is
portable to most C compilers and operating systems.

This technique works by monitoring the memory allocation mechanism and
free space chains and reporting any problems that occur. The MEM package
can be built into the project and provides continuous monitoring.

9.2  The MEM Package
The technique adopted by the MEM package has been used and refined
internally for several years. It has reduced the number of pointer bugs
in developed code by as much as 75%, resulting in a major productivity
boost. It is simple to incorporate into existing programs, and produces
little or no overhead.

9.2.1  Philosophy
Programs are getting larger and more sophisticated, hence more difficult
to debug. A major aid to testing and debugging programs is to insert code
into the program to check for out-of-range values, and other so-called
"impossible" values. The idea behind the MEM package described here is to
add as much of this checking as possible to aid in testing and debugging
the use of free store by a program.

There are two schools of thought on the action to take when a program
diagnoses a bug in itself. The first school states that the program
should terminate immediately, with a message describing the problem. The
second states that the program should ignore or try to repair the damage,
and continue on.

The MEM package adopts the first philosophy. There is no point in
continuing if the program has already failed, it must be stopped
immediately, since:

1. It may prevent a protection violation under OS/2, DOS 386 or UNIX or
the necessity of re-booting the machine under MS-DOS.

2. The closer the program is to the point where the bug occurred, the
easier the bug will be to find.

3. A runaway program may scramble the hard disk.

4. The software may be running mission or life critical software.
(Such critical applications should have a human backup, another computer
running similar software in parallel, or have the ability to reset and
restart itself. The self-detected fault should cause the operator to be
alerted, notify the other computer that it is to take charge, or reset
itself.)

Errors like disk full, out of memory, etc. are not program bugs, unless
the program fails to take account of these exceptions.

The MEM package will abort the application with a message if any faults
are directly detected, and will hopefully cause the application to fail
quickly on faults that cannot be directly detected.

9.2.2  Using MEM
These functions exactly parallel the storage allocator functions. Use
#include "mem.h" in all source files. Then do a global search and
replace, replacing all functions:

malloc()        becomes         mem_malloc()
calloc()        becomes         mem_calloc()
realloc()       becomes         mem_realloc()
free()          becomes         mem_free()
strdup()        becomes         mem_strdup()

At the beginning of main(), add a call to mem_init(). At the points where
the program returns to the operating system, add a call to mem_term().
Add mem.c to the list of files to be compiled and linked in.

MEM has two modes of operation, debugging on and debugging off. Debugging
on is used during program development. Debugging off is used for the
production compile (to eliminate most of overhead from the MEM package).
This is controlled by predefining the macro MEM_DEBUG to turn debugging
on, the default is off. If debugging is off, these functions become
trivial shells around malloc/free etc.

9.2.3  What MEM Does
Logging of all Allocations and Deallocations

All MEM's allocation and free functions pass the arguments __FILE__ and
__LINE__. When an allocation is done, an entry in a linked list is made
for that allocation, and the file and line information is stored in that
list. Thus, every outstanding allocation is represented in that list.
This list forms the basis of many of the package s operations. If a bug
is detected, usually the file and line number of where the pointer was
allocated can be printed, greatly facilitating tracking it down.

Verification of Calls to free

Since all allocations are known, when a pointer is freed, MEM can check
to make sure it is an outstanding allocation. MEM will only allow a
pointer to be freed once.

p = mem_malloc(5);
mem_free(p);
mem_free(p);
     /* this will cause an assertion failure from mem */

The data that is freed is overwritten with a non-zero known value. This
is to flush out problems which occur when continuing to refer to data
after it has been freed. The value with which the data is overwritten is
selected to maximize the probability of a segment fault or assertion
failure if the application continues to refer to it. MEM obviously cannot
directly detect instances like:

mem_free(p);
    if (*p) ...

But by guaranteeing that p points to garbage after mem_free() returns, it
is likely that such code will never work, and thus be easier to find.

Detection of Pointer Over and Underrun

Pointer overrun occurs when a program stores data past the end of an
allocated buffer. A common programming error that does this is:

p = malloc(strlen(s));
        /* didn't allocate space for terminating 0 */
strcpy(p,s);
        /* overrun: storing 0 past end of p */

Pointer underrun is when a program stores data before the beginning of
the allocated buffer; this error occurs less often. MEM detects this
error by allocating a few extra bytes at each end of the buffer. A known
value, referred to as a sentinel, is placed in these extra bytes. When
the buffer is freed, if the sentinels have changed value, then an
underrun or overrun has occurred.

Dependence on Values in Buffer Obtained from malloc

The most common value in a buffer obtained from malloc() is 0. Programs
can develop creeping dependencies on values being 0 in data returned by
malloc(), or on other specific values being present. The function
mem_malloc() prevents this by always setting the data in a buffer to a
known non-zero value before returning a pointer to it. This also prevents
another common error that can occur in some operating systems: MS-DOS,
for instance, does not clear unused memory when loading a program. Thus,
memory returned by malloc() may contain values left over from a previous
program. The use of mem_malloc() prevents this possibility.

realloc Problems

Common problems with using realloc() are associated with a tendency to
depend on its not shifting the location of the buffer in memory or
depending on the values in the uninitialized region of the buffer after
the realloc is completed. MEM flushes these errors out by always moving
the buffer and by changing values past the initialized portion.

p = mem_malloc(5);
memset(p,0,5);
mem_realloc(p,10);      /* error: p may be shifted */
memset(p+5,0,5);
mem_free(p);            /* will flag an error  */

Memory Leak Detection

Memory "leaks" are storage that is allocated but never freed. One problem
resulting from this concerns programs that have to run for many days at a
time (like bulletin board software). If there are leaks, eventually the
program will run out of memory and fail. Another problem is that a memory
leak may indicate that a piece of memory allocated should have been added
into some central data structure, but was not, and thus is a bug. MEM
finds memory leaks by keeping track of all allocations and deallocations.
When mem_term() is called, a list of all unfreed allocations are printed
out, along with the file and line number of the place where they were
allocated.

Pointer Checking

Sometimes it is useful to verify that a pointer is actually pointing into
free store. The function mem_checkptr(void *p) does this.

Consistency Checking

Occasionally even the internal data structures of the MEM package become
corrupted by a wild pointer. When this happens, it can be tracked down by
temporarily sprinkling the code with calls to mem_check(), which does a
consistency check on the free storage.

Out of Memory Handling

An irritation in using dynamic storage is handling the cases where the
storage allocator runs out of memory. MEM can be set to exhibit various
behaviors when out of memory. They are:

1. Present an "out of memory" message and terminate the program. This is
the most common usage, and relieves the burden on the programmer of
checking the return value of every malloc.

2. Return NULL to the caller. This mimics the behavior of the ANSI
malloc/calloc/realloc/strdup.

3. Call a specified function. This is useful if the program has an
"emergency reserve" pool of memory. If a program is using software
virtual memory, this function can flush buffers to disk, thereby freeing
up system memory. If a program needs to do some special cleanup before
terminating the program, this function can do it before invoking case 1.

Companion Techniques

The following describes a method of detecting whether pointers point to
valid data. It takes advantage of the fact that mem_free changes the
value of freed data. For each generally used structure, add the
definitions:

struct ABC {
#if MEM_DEBUG
    #define ABC_SIGNATURE 0x1234 /* arbitrary value */
    #define abc_validate(p) assert((p)->id == ABC_SIGNATURE)
    #define abc_init(p) ((p)->id = ABC_SIGNATURE)
    int id;
#else
    #define abc_validate(p)
    #define abc_init(p)
#endif
    .. other members ..
};

Whenever a struct ABC is allocated,

p = (struct ABC *) mem_malloc(sizeof(struct ABC));
abc_init(p);

Sprinkle the code in strategic locations with:

abc_validate(p);
     /* verify that p points to a valid ABC */

If p does not point to a valid ABC, abc_validate() will cause an
assertion failure.

9.3  Conclusion
The MEM package is no panacea for pointer bugs. For example, if a pointer
bug corrupts MEM itself or its internal data structures, MEM is likely to
fail. However, MEM has been in use for a number of years with several
large and successful products. It incorporates the suggestions of many
users and has proved to be very useful. MEM is a small overhead to pay
for the return obtained in increased program debuggability.

10. OTHER C TOOLS

Chapter 10 - Other C Tools
As well as the MEM and List toolkits there are a number of other useful
tools provided with the compiler, and these can also be found in the
sample directory. This chapter will cover these in turn, with a brief
description of each and some details of how they can be used.

10.1  The Name Unmangling Toolkit
The functions provided in this toolkit will be of particular interest to
those developing third party tools to work with Zortech C++, for example
class browsers or debugging tools. The example program will be of
interest to almost everyone developing software in Zortech C++ since it
provides a quick and convenient way of resolving C++ mangled names in map
files etc. and in the output of programs like linkers.

The toolkit consists of two files: unmangle.c contains the name
unmangling code and um.c contains the example program.

10.1.1  The Unmangling Routines
The file unmangle.c contains a number of functions which allow the
unmangling of C++ mangled names as used in Zortech C++. The primary
function is unmangle_ident() which takes a character string containing
the mangled name and returns a pointer to the unmangled name. The pointer
returned is to a string which is malloc ed by the unmangle_ident()
function, since neither the function nor the caller can know how much
space will be required for the unmangled name. The returned pointer
should be freed by the caller when it no longer requires it. The
prototype for this function is:

char *unmangle_ident(char *);

Where the argument is a pointer to a string containing the mangled C++
identifier.

10.1.2  The UM Utility
The um.c utility will, once compiled, provide a quick and convenient
method of unmangling identifiers both in pre-existing files such as a map
file produced from a linker, or in the output of the linker itself. It
can also be used with the LIBUNRES utility to unmangle the names of
unresolved externals in library files.

Here is the source to um.c:

/*
   UM.C unmangle C++ names in a file.

   This program may be freely distributed provided it is included
   with the file unmangle.c. This program is provided 'as is' with
   no warranties as to its suitability for any usage, whether implied
   or otherwise.

   This file can be compiled as is with Zortech C++ v2 and will produce
   an executable which can be run on a text file to demonstrate the use
   of the name unmangling functions.

   compile with:

     ztc -mti um unmangle

   and the usage is:

     um file
     um <file
     ztc test | um

  The input can come from either a text file or from standard input.
  The name unmangled output is sent to stdout and can be redirected
  to a file.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char *unmangle_ident(char *);

int _cdecl main(int argc, char *argv[])
{
    FILE *fp;
    char *line, *s, *s0, *s1;
    int x;

    if (argc > 1)
    {
        if ((fp = fopen(argv[1],"r")) == NULL)
        {
        fputs("Can't open ",stdout);
        puts(argv[1]);
        exit(EXIT_FAILURE);
        }
    }
    else
        fp = stdin; /* get input from standard in   */

    line = malloc(255);

    while (fgets(line,255,fp))
    {   char *p = line;

        /* mangled identifiers always start with a '_' */
        while ((s0 = strchr(p,'_')) != NULL)
        {   char c;

            /* Point s1 at end of identifier    */
            s1 = s0;
            while (isascii(*s1) &&
                (*s1 == '_' || isalpha(*s1) || isdigit(*s1)))
                s1++;

            c = *s1;
            *s1 = 0;        /* terminate identifer */

            s = unmangle_ident(s0);
            *s1 = c;        /* restore string   */
            if (s)
            {
                *s0 = 0;
                fputs(p,stdout);
                fputs(s,stdout);
                free(s);
            }
            else
            {   *s1 = 0;
                fputs(p,stdout);
                *s1 = c;
            }
            p = s1;     /* remainder of line    */
        }
        fputs(p,stdout);
    }
    free(line);
    if (fp != stdin)
        fclose(fp);
    return EXIT_SUCCESS;
}

 This code is included with the compiler and has been made distributable
 as an aid to those who are developing third party tools to work with the
 Zortech C++ compiler. It is strongly recommended that these functions be
 used where name unmangling is required.

10.2  The File Toolkit
This toolkit contains several useful functions for manipulating files. It
has functions for carrying out many common file operations and has been
written in a portable way. Like the other toolkits it is provided in
source form in the files file.h and file.c. The file toolkit.h is
required by these routines, as is the list toolkit.

The following is a reference list of the functions provided by the file
toolkit.

file_append
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_append(char *from, char *to);

Description:
Appends the file from to the file to. Uses low-level file I/O routines
for speed.

Return Value: Returns zero if successful, otherwise non-zero.

file_copy
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_copy(char *from, char *to);

Description:
Copy the file from to the path and filename to. Uses low-level file I/O
routines for speed.

Return Value: Returns 0 if successful, otherwise non-zero.

file_directory
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_directory(char *Filespec, int Attr, char ***Files_ppp,
                   unsigned *Nfiles_p);

Description:
Obtains the directory of files matching the supplied filespec. The file
specification may contain wild cards as appropriate to the operating
system being used.

Input:

The argument filespec contains the file specification to match and can
contain wild cards. Examples are:

NULL             Free the data in ***Files_ppp and *Nfiles_p. The data
                 must have been created by a previous call to this
                 function. Always returns 1 in this case.

null string ("") All files in default directory

*                All files in default directory

.                All files in default directory

\                All files in root directory

\bin\ *.c        All .c files in \bin

d:\bin           All files in \bin on drive d:

\bin\            All files in \bin

Also ? and [] type wild carding will work, but {} and ~ will not.

The argument attr can be:

0     All normal files (other values not supported yet)

The arguments *Nfiles_p and ***Files_ppp contain previous results from a
previous call to file_directory that will be freed on this call.

Output:

*Nfiles_p        The number of files that match filespec.

***Files_ppp     A pointer to an array of pointers to strings (which must
                 be freed later by a further call to file_directory())
                 containing the filenames of the files that were found to
                 match filespec.

Return Value: Returns non-zero if successful or zero if out of memory,
              in which case *Files_ppp is NULL and *Nfiles_p is 0.

file_exists
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_exists(char *path);

Description:
Tests for the existance of the specified file.

Return Value: Returns non-zero if the file exists, else zero.

file_mkdir
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_mkdir(char *dir);

Description:
Creates the specified directory, including any intervening directories in
the path that do not already exist.

Return Value: Returns 0 on success, otherwise non-zero.

file_read
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
list_t file_read(char *name);

Description:
Reads a simple ascii text file and breaks it up into a linked list of
lines using the list toolkit. Each line is a zero terminated string, with
the trailing \n removed. ASCII zeros in the file are ignored.

Input: name - File name to read

Return Value: Returns a linked list of strings for use with the list
              toolkit.

Limitations: Out of memory errors will result in an assertion failure.
             File read errors will result in a shortened list being
             returned.

file_rename
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_rename(char *from, char *to));

Description:
Renames the specified file.

Return Value: Returns non-zero if successful or 0 if it fails.

file_same
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_same(char *filespec1, char *filespec2);

Description:
Determines if filespec1 and filespec2 refer to the same file. This will
work even if the file does not yet exist.

Return Value: Returns non-zero if they refer to the same file, otherwise
              zero.

file_searchpath
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
char *file_searchpath(char *path, char *filename);

Description:
Searches for the specified file along the supplied path.

Input:

filename         Name of file to look for. If the filename contains a
                 complete path specification, only that path is searched.

path             Path to search. Individual paths are separated by space
                 or ;. If path is NULL, then the current directory is
                 searched.

Return Value: Returns a mem_malloc'ed string containing the complete file
              specification if the file is found or NULL if the file is
              not found or there is insufficient memory for the file
              specification string.

file_settime
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_settime(char *name,time_t newtime);

Description:
Sets the time of the file specified by name to the time newtime.

Return Value: Returns 0 if successful, otherwise non-zero.

file_size
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
unsigned long file_size(char *path);

Description:
Determines the size of the specified file.

Return Value: The size of the file in bytes as a long or -1L if the file
              does not exist.

file_time
Usage:
#include "toolkit.h"
#include "list.h"
#include <sys\types.h>
#include <time.h>
time_t file_time(char *file);

Description:
Returns the time that the operating system associates with a file. The
format is operating system dependent.

Return Value: The time that the operating system associates with file
              as a system dependent value.

file_write
Usage:
#include "toolkit.h"
#include <sys\types.h>
#include <time.h>
int file_write(char * name,list_t lines);

Description:
Writes a list of zero terminated strings out as a file. A newline (\n) is
added to the end of each string.

Input:

name     The name of the file.
lines    A linked list of strings which are the lines in the file.

Return Value: Returns 0 if successful or non-zero if it fails.

10.3  The Filespec Toolkit
This toolkit contains many useful functions for manipulating file names,
directory paths and file extensions. These three properties together
constitute a file specification. These functions have been written in a
portable way and provide a useful adjunct to the file handling toolkit
just presented. Like that toolkit it is provided in source form in the
files filespec.h and filespec.c. The file toolkit.h is required by these
routines, as are the List and MEM toolkits.

The following is a reference list of the functions provided by the
Filespec toolkit.

filespecaddpath
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecaddpath(char *path, char *filename);

Description:
Combines path and filename to form a file specification.

Input:
path         Path, with or without trailing \.
filename     The filename, which must not be NULL

Return Value: A pointer to the mem_malloc'ed file specification.

filespecbackup
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecbackup(char *filespec);

Description:
Convert filespec into a backup filename appropriate for the operating
system.

Input: filespec - A string that may or may not contain an extension

Return Value: A pointer to a mem_malloc'ed string containing the backup
              filename. A NULL pointer is returned if an error has occured
              or if the filespec argument is NULL.

filespeccmp
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
int filespeccmp(char *f1, char *f2);

Description:
Does a string compare of filenames. Under MS-DOS and OS/2 it behaves like
strcmpl(); refer to the documentation for that function for details of
usage and return values. Under UNIX it behaves like strcmp().

filespecdefaultext
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecdefaultext (char *filespec, char *ext);

Description:
Adds an extension onto filespec, if there is not one already there.

Input:

filespec     The file specification, which must not be NULL.
ext          The extension (without the dot).

Return Value: A pointer to a mem_malloc'ed string containing the file
              specification and extension or a NULL pointer if an error
              occurred.

filespecdotext
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecdotext(char *filespec);

Description:
Finds the the dot and extension within filespec and returns a pointer to
it. The string returned is not mem_malloc'ed.

Return Value: A pointer to dot and extension or to the 0 at the end of
              filespec if the dot is not found. It returns NULL if
              filespec is NULL.

filespecforceext
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecforceext(char *filespec, char *ext);

Description:
Forces the specified extension onto filespec.

Input:

filespec      The file specification as a string that may or may not
              contain an extension.

ext           The extension to add (should not contain a dot).

Return Value: A pointer to a mem_malloc'ed string containing the file
              specification and extension or a NULL pointer if an error
              occurred. If ext is NULL, it returns mem_strdup(filespec).

filespecgetroot
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecgetroot(char *name);

Description:
Get root name of file name.

Return Value: Returns a mem_strdup'ed version of the file name
              without the extension.

filespecmultitilde
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecmultitilde(char *);

Description:
If any character of filespec is a ~, performs tilde expansion. Note that
this does nothing under MS-DOS or OS/2.

Return Value: A pointer to the expanded file specification that is stored
              in a mem_malloc'ed buffer. The input filespec is mem_free'ed.

filespecname
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecname(char *filespec);

Description:
Strips the path from a file specification and returns a string that is
the filename.

Return Value: A pointer to a string containing the file name plus
              extension. The string returned is NOT mem_malloc'ed.

filespecrootpath
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespecrootpath(char *path);

Description:
Expands a relative path into an absolute path. The input string is
mem_free'ed.

Return Value: Returns a mem_malloc'ed string containing the absolute path
              or a NULL pointer if some failure has occurred.

filespectilde
Usage:
#include "toolkit.h"
#include "filespec.h"
#include <string.h>
char * pascal filespectilde (char *filespec);

Description:
If the first character of filespec is a ~, performs tilde expansion. Note
that this does nothing under MS-DOS or OS/2.

Return Value: A pointer to the expanded file specification that is stored
              in a mem_malloc'ed buffer. The input filespec is mem_free'ed.

10.4  Pop-up Menus
The sample directory also contains two files which provide the basis of a
pop-up menu system. These files are menu.h and menu.c. They provide an
alternative to the C++ menu functions provided in C++ Tools. The menu
system consists of only one public function menu_enter() which brings up
a menu, performs all the menu processing, calls the selected function (if
any) and exits after cleaning the display. Menus consist of two data
types, a menu item, menu_item_t, and the menu itself, typedef'ed as
menu_t.

10.4.1  The Menu Item
There should be one item per line in the menu, each consisting of the
following components:


typedef struct
{
     char *text;           /*      text of item               */
     int result;           /*      return from menu_enter()   */
                           /*      if this item is selected   */
     unsigned key;         /*      key value to select it     */
     unsigned char flags;
#define MENU_enabled 1     /*      set if item enabled        */
     int (*func)           /*      semantic routine           */
        (int,              /*      value from this struct     */
         unsigned,         /*      top row of this menu       */
         unsigned);        /*      left column of this menu   */
                           /*      Returns:                   */
                           /*                0   Continue     */
                           /*              !=0   Return from  */
                           /*                    menu_enter() */
        int value;         /*      value to pass to func      */
} menu_item_t;

The function pointed to by func is called when the menu item is selected,
but before the menu is removed from the display. It is primarilly useful
for accessing submenus or dialog boxes. Since menu_enter() is re-entrant,
it can be used to generate submenus as shown in the example program
provided.

When *func returns, if the return value is 0 the original menu is
reentered. If it is non-zero, the menu is terminated and that value
becomes the return value of menu_enter(). If func is NULL, the return
value of menu_enter() is given by the result member of menu_item_t. This
value must be non-zero otherwise the menu code will ignore the selection.

10.4.2  The Menu
The menu consists of a structure which contains an array of menu items as
well as other necessary information.

typedef struct MENU_T
{
    unsigned char selected;     /* which is selected    */
    unsigned char width;        /* excluding border     */
    unsigned char nitems;       /* items in menu        */
    menu_item_t *items;         /* array of items       */
} menu_t;

The function that uses these data types is menu_enter(). It has the
following prototype.

int menu_enter (menu_t *m, int row, int col);

The two integer arguments are the row and column coordinates of the upper
left corner of the menu. They decide where the menu, specified by the
menu_t argument, will appear.

10.4.3  The Menu Example
An example program can be compiled from menu.c by defining a macro TEST.
For example, a suitable command line for ZTC would be:

    ztc -mti -DTEST menu

The example program defines a main menu and a number of submenus and
demonstrates their use. The source code to the actual test program
extracted from menu.c is as follows:

#include    <stdlib.h>
#include    <disp.h>
#include    <msmouse.h>
#include    <dos.h>
#include    "menu.h"

#define TEST 1

/************** TEST PROGRAM AND DEMO *************/

#if TEST

menu_item_t items2[] =
{
    { "submenu B",1,'A',MENU_enabled },
    { "submenu F2",2,0x3C00,MENU_enabled },
    { "submenu 3 +",3,'+' },
    { "bufblah 4",4,0,MENU_enabled },
    { "abcblah 4",5,0,MENU_enabled },
};

menu_t submenu =
{ 1,12,sizeof(items2)/sizeof(items2[0]),items2 };

int fsubmenu(int i,unsigned row,unsigned col)
{
    return menu_enter(&submenu,row+i,col+2);
}

menu_item_t items[] =
{
    { "line 1 A",6,'A',MENU_enabled },
    { "subm 2 F1",7,0x3B00,MENU_enabled,fsubmenu,3 },
    { "line 3 +",8,'+' },
    { "subm 4",9,0,MENU_enabled,fsubmenu,5 },
    { "blah 4",10,0,MENU_enabled },
};

menu_t testmenu =
{ 1,10,sizeof(items)/sizeof(items[0]),items };

int main()
{
    unsigned x,y;
    int result;

    disp_open();            /* initialize display   */
    msm_init();             /* initialize mouse */
/*
    Mouse driver sometimes gets the number of screen rows
    wrong, so here we force it to whatever disp_open()
    discovered.
*/
    msm_setareay(0,(disp_numrows - 1) * 8);
    msm_showcursor();       /* turn mouse cursor on */
    result = 0;

    do
    {
       if (key_avail())     /* wait for key     */
       {   key_read();      /* throw away key value */
           result = menu_enter(&testmenu,10,10);
       }

       if (msm_getstatus(&x,&y) & 2)
                            /* if right button down */
       {   mouse_tocursor(&x,&y);
                            /* translate to cursor coords */
           result = menu_enter(&testmenu,y,x);
       }

    } while (result == 0);

    msm_hidecursor();       /* turn mouse cursor off*/
    msm_term();             /* terminate mouse use  */
    disp_printf("Value returned is %d\n",result);
    disp_close();           /* terminate display use*/
    return EXIT_SUCCESS;
}

#endif /* TEST */

11. THE C STANDARD LIBRARIES
Chapter 11 - The C Standard Libraries
Alphabetical Listing of Library Functions
This section describes the C library functions, which are arranged
broadly in alphabetical order. Underscores are ignored in determining
this order. Some functions share common descriptions (e.g. FP_OFF and
FP_SEG), and in such cases the alphabetical order is determined by the
first in the group. All functions, including those described in other
chapters, are listed in the index at the back of the manual, where
underscores are taken into account in the sequence.

 Users should note that the order departs from being strictly
 alphabetical so as to keep together those functions which are part of
 the same package - an example of this is the fg_ functions in the Flash
 Graphics package. Functions grouped in this way are distinguished by
 lighter separating horizontal rules.

Each alphabetical group of functions starts on a new right hand page,
which means that you will find some left hand pages left intentionally
blank.

The function descriptions have a number of sub-headings; here is a
description of each one:

Function Name

Each library function begins with the function name, which appears in the
proper case to be used in a C or C++ program, including any leading
underscores and capital letters. It is important to observe the case used
for a function because printf and PRINTF are not equivalent.

Usage

First is the compiler directive #include <filename.h>. The identifier
filename.h is the name of the header file containing the prototype of the
function. The prototype declares the data type for return values and
arguments passed to a function. Header files can also contain types,
structures, and constant definitions to be used by a function. Header
files are typically included at the beginning of the program prior to the
first function.

Following the directive is the function prototype. It appears in largely
the same form as declared in the header file. The appropriate header file
must be included for any function that is used in C++. It is highly
recommended that you include it even if you are only using the C
compiler, to ensure proper type-checking of function arguments and return
types.

Description

Encapsulates what the function is intended to do. It describes the
arguments that are to be passed to the function and any other details
needed to use the function correctly.

Example

In most cases a complete stand alone executable example is presented
which you may type in and execute. Each example includes all header files
needed by the functions used. In some cases it is not practical to
include a full example, for example, the Flash Graphics library
functions. In that case a meaningful partial example is given.

Return Value

Explains any value returned by a function. In many cases the return value
indicates success or failure. If this entry is omitted it means that
there is no return value from the function.

See Also

Lists other related or complementary functions.

abort
Usage:
#include <stdlib.h>
void abort(void);
ANSI

Description:
The abort function terminates the currently executing program. It is the
same as a function call to _exit with a non-zero status. abort can be
intercepted using the signal SIGABRT (see the function signal). abort
does not flush the buffers nor does it call C++ static destructors. It is
preferable to use exit rather than abort for C++ programs.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fp = fopen("file.dat","r");
    if(fp == NULL)
        {
            fprintf(stderr,"Could not open file.dat\n");
            abort();
        }
    printf("File opened\n");
    return EXIT_SUCCESS;
}

See Also: exit, _exit, raise

abs
Usage:
#include <stdlib.h>
int abs(int i);
ANSI

Description:
abs produces the absolute value of its integer argument.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int numbr, absval;
    numbr = -3;
    absval = abs(numbr);
    printf("The abs of (%d) is %d\n",numbr,absval);
    return EXIT_SUCCESS;
}

Return Value: abs returns the absolute value of its integer argument.

See Also: labs

access
Usage:
#include <io.h>
int access(char *path, int mode)

Description:
access determines whether the file or directory specified by path exists
and can be accessed in the file mode specified by mode. Possible values
for mode are:

    F_OK    Check for existence only
    X_OK    Check for execute permission
    W_OK    Check for write permission
    R_OK    Check for read permission

mode can be combined using the bitwise or operator, thus:

    W_OK | R_OK Check for read and write permission

Example:
#include <io.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    if ((access("temp.fil",F_OK)) == -1) {
        perror("File 'temp.fil' does not exist");
        return EXIT_FAILURE;
    } else
        printf("File 'temp.fil' found\n");
    return EXIT_SUCCESS;
}

Return Value: Returns 0 if the file exists and can be accessed in mode.
              A value of -1 means that the file does not exist or cannot
              be accessed in mode, and errno is set.

See Also: fstat, open, stat

acos
Usage:
#include <math.h>
double acos(double x);
ANSI

Description:
acos returns the arc cosine of x in the range of 0<=acos<=p. The argument
x must be in the range of -1 <= x <= 1.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x, y;
    x = .94;
    y = acos(x);
    printf("The arc cosine of %f is %f\n",x,y);
    return EXIT_SUCCESS;
}

Return Value: acos returns the arc cosine of the input value. If the
              value x is less than -1 or greater than 1, acos sets errno
              to EDOM and returns 0. Error handling can be modified
              through the function matherr.

See Also: asin, atan, atan2

asctime
Usage:
#include <time.h>
char *asctime(struct tm *ntime);
ANSI

Description:
asctime converts a time structure into an ASCII string of 26 characters
including the null having the form of:

    DDD MMM dd hh:mm:ss YYYY\n\0

Where:

    DDD         =   day of the week
    MMM         =   month
    dd          =   day of the month
    hh:mm:ss    =   hour:minutes:seconds
    YYYY        =   year

The usual method of obtaining the time is to first call the time function
to get the number of seconds elapsed since 00:00:00 GMT on January 1,
1970. This is passed as an argument to the localtime function which
returns a pointer to the structure tm as defined in time.h. This is then
used as the ntime argument to asctime.

Example:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    time_t tclock;
    time(&tclock);
    printf("The current date and time: %s\n", asctime(localtime(&tclock)));
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to a character string containing the date
              and time. The string is static and is overwritten with each
              call to asctime.

See Also: Time package, clock, ctime, difftime, localtime

asin
Usage:
#include <math.h>
double asin(double x);
ANSI

Description:
asin returns the arc sine of x in the range of -p2 <=  asin<= p2. The
value of x must be between -1<=x<=1.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x, y;
    x = .94;
    y = asin(x);
    printf("The arc sine of %f is %f\n",x,y);
    return EXIT_SUCCESS;
}

Return Value: asin returns the arc sine of the input value. If the value
              is less than -1 or greater than 1, asin sets errno to EDOM
              and returns 0. Error handling can be modified through the
              function matherr.

See Also: atan, atan2, acos

assert
Usage:
#include <assert.h>
void assert(expression);
ANSI

Description:
The assert macro is useful for adding internal consistency checks to
programs. When the assert macro is executed it checks the expression
argument and if it is zero, then the following message is printed on the
standard error device and the program aborts.

Assertion failure: 'expression' on line ?? in file '???'

The assert function can be deactivated by defining the macro NDEBUG prior
to the inclusion of assert.h header file. This has the effect of turning
all assertions into null statements.

Example:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

char *string = "";      /* empty string */
int value = 1;

int main()
{
    assert(value > 0);
    printf("Passed assert(value > 0)\n");
    assert(*string != '\0');
    return EXIT_SUCCESS;
}
atan
Usage:
#include <math.h>
double atan(double x);
ANSI

Description:
atan returns the arc tangent of x in the range of -p2 to p2. matherr can
be used to modify error handling.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x, y;
    x = 1.0;
    y = atan(x);
    printf("The arc tangent of %.7f is %.7f\n",x,y);
    return EXIT_SUCCESS;
}

Return Value: atan returns the arc tangent of its argument.

See Also: acos, asin, atan2

atan2
Usage:
#include <math.h>
double atan2(double y, double x);
ANSI

Description:
atan2 returns the arc tangent of y/x in the range of -p to p. atan2 uses
the signs of y and x to determine the quadrant of the return value.

Return Value: atan2 returns the arc tangent of the input values. If x and
              y are both 0, atan2 sets errno to EDOM and returns 0. Error
              handling can be modified through the function matherr.

See Also: acos, asin, atan

atexit
Usage:
#include <stdlib.h>
int atexit(void (*func)(void));

Description:
atexit registers the function func such that when the program terminates
normally by returning from main or by calling exit, the registered
functions are called. A maximum of 32 functions can be registered by
successive calls to the atexit function. Registered functions are passed
no arguments and no values are returned.

 The registered functions must have "C" linkage. Functions compiled with
 the C++ compiler must be specified as having "C" linkage in order to be
 registered with atexit. See the example for more information.

When exit is called (either explicitly or via the return from main):

1.  Functions registered via atexit are called in the reverse order
that they were registered. (last in, first out)

2.  If this is a C++ program, the static destructors are called.

3.  All open streams are flushed and closed.

4.  _exit is called with the exit status, which returns to the
operating system.

Example:
#include <stdio.h>
#include <stdlib.h>
#if __cplusplus
    extern "C"              /* force C linkage */
#endif
void xmess(void);

int main()
{
    atexit(xmess);
    return EXIT_SUCCESS;
}

void xmess(void)
{
    printf("Program exiting.\n");
}

Return Value: atexit returns 0 if func was successfully registered,
              non-zero if not.

See Also: exit, _exit

atof
Usage:
#include <stdlib.h>
double atof(const char *nptr);
ANSI

Description:
This converts the string pointed to by nptr into a double-precision
floating point number. The string may have leading spaces, tabs, and +
or -. Conversion stops on the first unrecognized character. If there are
no recognized characters, the result is 0.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("atof function = %e\n",atof("123.5e15"));
    return EXIT_SUCCESS;
}

Return Value: Returns the double value derived from converting the string.
              Zero is returned if the input string does not have any
              recognizable characters.

See Also: atoi, atol, ecvt, fcvt, strtol, strtod, scanf

atoi
Usage:
#include <stdlib.h>
int atoi(const char *nptr);
ANSI

Description:
This converts the string pointed to by nptr into an integer. The string
may have leading spaces, tabs, and + or -. Conversion stops on the first
unrecognized character. If there are no recognized characters, the result
is 0.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("atoi function = %d\n",atoi("153"));
    return EXIT_SUCCESS;
}

Return Value: Returns the integer value derived from converting the string.
              Zero is returned if the input string does not have any
              recognizable characters.

See Also: atof, atol, ecvt, fcvt, strtol, strtod, scanf

atol
Usage:
#include <stdlib.h>
long atol(const char *nptr);
ANSI

Description:
Converts the string pointed to by nptr into a long. The string may have
leading spaces, tabs, and + or -. Conversion stops on the first
unrecognized character. If there are no recognized characters, the result
is 0.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("atol function = %ld\n",atol("1234 String"));
    return EXIT_SUCCESS;
}

Return Value: Returns the long value derived from converting the string.
              Zero is returned if the input string does not have any
              recognizable characters.

See Also: atof, atoi, ecvt, fcvt, strtol, strtod, scanf

bdos
Usage:
#include <dos.h>
int bdos(int func, unsigned DX, unsigned AL);

Description:
The bdos function calls a DOS function (int 21h) where func is the
function number and DX and AL are the values to be loaded into the DX and
AL registers prior to the function call. DOS function calls are used to
access the facilities of the operating system. A list of system calls and
their register requirements for MS-DOS can be found in the MS-DOS
Technical Reference manual. Another good source of information is
Advanced MS-DOS by Ray Duncan, published by Microsoft Press. Some system
calls require registers other than DX and AL to be set up and therefore
bdos cannot be used. In such cases use the intdos or intdosx functions.

Under the X and P memory models bdos() and bdosx() carry out some
filtering of parameters sent to the real mode interrupt. This enables
MS-DOS functions running in real mode to access data stored in extended
memory.

 Some of the available DOS functions are not supported or only partially
 supported in the X and P memory models, refer to the entry for int86()
 for more information.

Example:
#include <dos.h>
#include <stdlib.h>

int main()
{
    bdos(2,'C');        /* display the letter C */
    return EXIT_SUCCESS;
}

Return Value: Returns the value in AX after the system call.

See Also: bdosx, intdos, intdosx, int86, int86x

bdosx
Usage:
#include <dos.h>
int bdosx(int func, char *ptr);

Description:
Calls a DOS function (int 21h) where func is the function number and the
ptr argument is loaded into the DS:DX register pair. The argument ptr is
a standard C near or far pointer depending on the memory model. Do not
specifically use a declared near or far pointer unless it matches the
default pointer type for the memory model in use. Use intdosx for system
calls that require registers to be set up.

Under the X and P memory models bdos() and bdosx() carry out some
filtering of parameters sent to the real mode interrupt. This filtering
allows data stored in extended memory to be passed to the DOS function so
that, for instance, much larger buffers than normal can be used with the
DOS disk functions. Where pointers are passed to bdosx(), they are
assumed to contain protected mode addresses. The filtering routine used
for these functions assumes that all far pointers passed in registers to
DOS have a segment address of DGROUP. If you use bdosx() and specify a
selector other that DGROUP the results will be unpredictable.

 Some of the available DOS functions are not supported or only partially
 supported in the X and P memory models, refer to the entry for int86()
 for more information.

Return Value: Returns the value in AX after the system call.

See Also: DOS package, bdos, intdos, intdosx, int86, int86x

BIOS Package
The BIOS package allows access to routines in the IBM PC and PS/2 ROM
BIOS. These routines require an IBM compatible BIOS in order to work
correctly. The routines in the BIOS package can be recognized by the
prefix _bios and require the inclusion of the header file bios.h which
contains the relevant function prototypes and manifest constants.

The BIOS package consists of the following functions:

_bios_disk         BIOS disk functions (0x13)
_bios_equiplist    BIOS equipment list function (0x11)
_bios_keybrd       BIOS keyboard functions (0x16)
_bios_memsize      BIOS memory size function (0x12)
_bios_printer      BIOS printer functions (0x17)
_bios_serialcom    BIOS serial port functions (0x14)
_bios_timeofday    BIOS time of day functions (0x1a)

These functions are specific to the IBM PC and PS/2 series of personal
computers and are not portable to other system architectures. They are
not included in the ANSI C standard.

 The majority of these functions are not available under OS/2. The
 exception is the widely used function _bios_keybrd, which is provided
 to increase the portability of existing code.

_bios_disk
Note - This function is not available when using the DOSX extender
       (X memory model) or OS/2.

Usage:
#include <bios.h>
int _bios_disk(unsigned service, struct diskinfo_t *info);

Description:
_bios_disk is a direct interface to the bios disk control interrupt 0x13.
Six services are available on a basic IBM PC. They are selected by the
value given to service as follows:

Service          Operation

0 (reset)        Causes a hard reset of the floppy disk controller. This
                 is useful after an error has occurred. For this service
                 the info parameter is ignored.

1 (status)       Obtains the status of the last disk operation. For this
                 service the info parameter is ignored.

2 (read)         Reads one or more disk sectors into the memory buffer
                 pointed to by buffer in the diskinfo_t structure. This
                 service requires that all the fields in the diskinfo_t
                 structure, pointed to by info, are correctly set up.

3 (write)        Writes one or more disk sectors with data from the memory
                 buffer pointed to by buffer in the diskinfo_t structure.
                 This service requires that all the fields in the
                 diskinfo_t structure, pointed to by info, are correctly
                 set up.

4 (verify)       Verifies one or more disk sectors to ensure that it exists
                 and is readable. It also does a CRC (cyclic redundancy
                 check). This service requires that all the fields in the
                 diskinfo_t structure, pointed to by info, are correctly
                 set up.

5 (format)       Formats the track specified in the head and track fields
                 of the diskinfo_t structure pointed to by info. Only one
                 track can be formatted in each call. The buffer field
                 contains a set of sector markers, the format of which
                 depends on the type of disk drive. Refer to the IBM
                 Technical Reference Manual for more information on
                 marker formats.

The format of struct diskinfo_t is as follows:

struct diskinfo_t {
    unsigned drive;         /* drive number         */
    unsigned head;          /* head number          */
    unsigned track;         /* track number         */
    unsigned sector;        /* start sector no.     */
    unsigned nsectors;      /* sectors to process   */
    void far *buffer;       /* memory buffer to use */
    };

Example:
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int status;
    struct diskinfo_t disk;

    if ((status = _bios_disk(1,&disk)) != 0)
        printf("Last disk operation had error %d\n", status);
    else
        printf("Last disk operation completed OK\n"
    );
    return EXIT_SUCCESS;
}

Return Value: The value returned depends of the service requested.
              The reset and format services do not return meaningful
              values. The read, write and verify services return the
              number of sectors processed in the low byte, and the
              high byte is 0. The status service and, if an error has
              occurred, the read, write or verify service, places a code
              in the high byte of the return value.

              The status codes are as follows:

              0x01    Invalid request / bad command
              0x02    Address mark not found
              0x04    Sector not found
              0x05    Reset failure
              0x07    Drive parameter activity failure
              0x09    DMA overrun
              0x0a    Bad sector flag detected
              0x10    Data read (ECC) error
              0x11    Corrected data read (ECC) error
              0x20    Controller failure
              0x40    Seek error
              0x80    Disk timed out / not responding
              0xaa    Drive not ready
              0xbb    Undefined error
              0xcc    Write fault
              0xe0    Status error

See Also: BIOS package, _bios_keybrd, _bios_memsize, _bios_printer,
          _bios_serialcom

_bios_equiplist
Note - This function is not available when using OS/2.

Usage:
#include <bios.h>
int _bios_equiplist(void);

Description:
The function _bios_equiplist executes a BIOS interrupt 0x11, the
equipment determination routine.

Example:
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned equipment;

    equipment = _bios_equiplist();
    if (equipment & 0x0c)
        printf("Game adaptor installed\n");
    else
        printf("No Game adaptor installed\n");
    return EXIT_SUCCESS;
}

Return Value: An integer containing the following information as a bit
              pattern:

    Bit No      Meaning
         
    15,14       the number of printers attached
    13          not used
    12          1 if a game adaptor is attached
    11,10,9     the number of serial (RS232) ports
    8           not used
    7,6         the number of diskette drives (maximum 4)
    5,4         the initial video mode:
                  00    not used
                  01    40x25 color
                  10    80x25 color
                  11    monochrome
    3,2         planar ram size (11 = 64k which is normal)
    1           not used
    0           set if there are any diskette drives

See Also: BIOS package, _bios_keybrd, _bios_memsize, _bios_printer,
          _bios_serialcom, _bios_disk

_bios_keybrd bioskey
Usage:
#include <bios.h>
int _bios_keybrd(int flag);
int bioskey(int flag);

Description:
These names refer to the same function. The two spellings are for
compatibility with other compilers. bioskey passes flag to the BIOS
interrupt 0x14 (20) - the keyboard interrupt. The values for flag are:

    0   Read the next key value from the keyboard input buffer.
        Wait for one if there are not any available.
    1   Determine if any keys are in the keyboard input buffer.
    2   Read the status of the shift keys.

Example:
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int key,shift;
    int lastshift = 0;
    while (1)
    {
        shift = bioskey(2);
        /* If shift status changes */
        if (shift != lastshift)
            printf("shift = 0x%02x\n",shift);
        /* If a key is available */
        if (bioskey(1))
        {
            /* Read the key */
            key = _bios_keybrd(0);
            if ((key & 0xFF) == 'q')
                break;
            printf("key = 0x%04x\n",key);
        }
        lastshift = shift;
    }
    return EXIT_SUCCESS;
}

Return Value:
If flag is 0, the value returned is the key value. The ASCII value of the
key is returned in the low byte, and the scan code in the high byte. If
the low byte is 0, then the key value is not an ASCII key (it might be an
arrow or function key). If flag is 1, 0 is returned if there are no keys
in the input buffer, otherwise the next key value is returned. The key
value is not removed from the input buffer, and is still available to be
read. If flag is 2, the value returned is the state of the shift keys
encoded into the bits as follows:

    0x01    Right shift key is down
    0x02    Left shift key is down
    0x04    Ctrl key is down
    0x08    Alt key is down
    0x10    Scroll Lock is toggled
    0x20    Num Lock is toggled
    0x40    Caps Lock is toggled
    0x80    Ins is toggled

See Also: BIOS Package

_bios_memsize
Note - This function is not available when using OS/2.

Usage:
#include <bios.h>
int _bios_memsize(void);

Description:
The function _bios_memsize executes a BIOS interrupt 0x12, which is the
memory size determination routine.

Example:
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("The memory size of this system is %dK\n", _bios_memsize());
    return EXIT_SUCCESS;
}

Return Value: Returns the maximum number of contiguous 1K memory blocks
              which are present, as an integer.

See Also: BIOS package, _bios_equiplist

_bios_printer
Note - This function is not available when using OS/2.

Usage:
#include  <bios.h>
int _bios_printer(unsigned service, unsigned printer, unsigned data);

Description:
The function _bios_printer executes a BIOS interrupt 0x17, which is the
printer interface routine. The service argument determines which of three
possible operations to perform:

0                Write the low order byte of data to the printer which was
                 specified in the printer argument.

1                Intialize the selected printer. The data argument is
                 ignored.

2                Returns the current printer status. The data argument is
                 ignored.

Example:
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned i, data = 36;
    unsigned status;

    printf("place printer offline and press return\n");
    getchar();
    status = _bios_printer(2,0,data);
    printf("status with printer offline: %x\n\n\n",status);
    printf("press return to initialize printer\n");
    getchar();
    status = _bios_printer(1,0,data);
    printf("status after printer initialized:%x\n\n\n",status);
    printf("press return to print\n");
    getchar();
    for (i = 0; i > 10; i++)
        _bios_printer(0,0,data);
    status = _bios_printer(0,0,'\n');
    printf("status after printing %d %c's: %x\n\n\n",i,data,status);
    return EXIT_SUCCESS;
}

Return Value: The low byte of the return value, for all three services,
              contains the printer status thus:

    0x01    Printer timed out
    0x02    Not used
    0x04    Not used
    0x08    I/O error
    0x10    Printer selected
    0x20    Out of paper
    0x40    Acknowledge
    0x80    Printer not busy

See Also: BIOS package, _bios_equiplist

_bios_serialcom
Note-This function is not available when using OS/2.

Usage:
#include <bios.h>
int _bios_serialcom(unsigned service, unsigned port, unsigned data);

Description:
This function uses the BIOS to provide a number of serial RS232
operations. The IBM BIOS only allows polled operation of the serial
ports, not interrupt operation. The port argument is the number of the
serial port to address. This is set to 0 for COM1 and 1 for COM2.

There are four services provided:


0 (inititialize) Set up the serial port as specified in the data
                 argument (see below).

1 (send)         Transmit the data character through the selected serial
                 port

2 (receive)      Accepts an input character through the selected serial
                 port.

3 (status)       Return the current status of the selected serial port.

The data argument for the initialize service is created by oring together
one value from each of the following categories.

Baud Rate

    Rate    Value
       
    110        0
    150       32
    300       64
    600       96
    1200     128
    2400     160
    4800     192
    9600     224

Data Word Length

    Word Length     Value
         
    7 data bits       2
    8 data bits       3

Stop Bits

    No of bits  Value
      
       1          0
       2          4

Parity

    Parity  Value
      
    none      0
    odd       8
    even     24

Example:
#include <stdio.h>
#include <bios.h>
#include <stdlib.h>

int main()
{
    unsigned com1_status;

    com1_status = _bios_serialcom(3,0,0);
    printf("COM1 status: %x\n",com1_status);
    return EXIT_SUCCESS;
}

Return Value: A 16 bit integer whose high byte contains status bits.
              The low byte will vary according to the service requested.

The high byte status bits are as follows:

    Bit     Meaning when set
         
    15      Timed out
    14      Transmitter Shift register empty
    13      Transmitter Holding register empty
    12      Break detected
    11      Framing Error
    10      Parity Error
     9      Overrun Error
     8      Data Ready

If the service requested is send, then bit 15 will be set if data could
not be sent.

If the service requested is recieve, then the byte read will be returned
in the low byte, If an error occurred at least one bit in the high byte
will be set, to indicate the source of the error.

If the service requested is either initialize or status, additional
status information will be returned in the low byte:

    Bit     Meaning when set
         
     7      Data Carrier Detect (DCD) state
     6      Ring Indicator (RI) state
     5      Data Set Ready (DSR) state
     4      Clear To Send (CTS) state
     3      Change in DCD
     2      Change in RI
     1      Change in DSR
     0      Change in CTS

See Also: BIOS package

_bios_timeofday
Note-This function is not available when using OS/2.

Usage:
#include <bios.h>
int _bios_timeofday(unsigned mode, long *btime);

Description:
_bios_timeofday provides an interface to the IBM BIOS time of day
functions, interrupt 0x1a (26). The argument mode determines whether the
time is to be read (mode = 0) or set (mode = 1). If the time is to be
read, the current BIOS time (in clock ticks since midnight) is placed in
the long integer pointed to by btime, otherwise the BIOS time of day
counter is set to the value of that long. There are approximately 18.2
clock ticks per second.

Example:
#include <stdio.h>
#include <bios.h>
#include <stdlib.h>

int main()
{
    unsigned hours, minutes;
    long btime;

    _bios_timeofday(0,&btime);
    btime = (btime*10)/182;
    minutes = btime/60;
    hours = minutes/60;
    minutes %= 60;
    printf("The time is %2d:%2d hours\n",hours,minutes);
    return EXIT_SUCCESS;
}

Return Value: If mode is 0 the function returns 1 if the system clock has
              passed midnight since the last time it was read otherwise it
              returns 0. If mode is 1, no meaningful value is returned.

See Also: BIOS package

bsearch
Usage:
#include <stdlib.h>
void *bsearch(const void *key,const void *base, size_t num,
              size_t width,int (*cmp)(const void *elem1,
              const void *elem2));
ANSI

Description:
bsearch performs a binary search of a sorted array of num elements, which
is pointed to by base, for an element which matches key. The contents of
the array must have been previously sorted into ascending order. Each
item of the array is width bytes. The typedef size_t is the unsigned
integer data type that results from the use of the sizeof operator. The
function used in the search is *cmp. This function must be supplied by
the programmer and must be declared as taking C linkage. The cmp function
takes two arguments as pointers to the element in the array. The *cmp
function must return one of the following values:

        Value   Meaning
           
        < 0     elem1 is less than elem2
        = 0     elem1 and elem2 match
        > 0     elem1 is greater then elem2

Note that the standard library function strcmp is a suitable compare
function (cmp) for C style strings.

Example:
#include <stdio.h>
#include <stdlib.h>

#define SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
int array[] = {1254,3427,1111,3901,6677,0101};

#ifdef __cplusplus
extern "C"
#endif

int intcmp(int *p1, int *p2)
{
        return(*p1 - *p2);
}

int main()
{
    int *pointer;

    int key = 3901;
    pointer = (int *)bsearch(&key,array,SIZE(array), sizeof(int),intcmp);
    if (pointer) {
       printf("[%d] is in array\n",key);
    }
    else {
       printf("[%d] is not in array\n",key);
    }
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the matching element, or NULL if not
              found.

calloc
Usage:
#include <stdlib.h>
void *calloc(size_t numelems, size_t sizelem);
ANSI

Description:
Allocates a block of memory that is numelems *sizelem bytes in size in
the program heap. The memory is cleared (i.e. all bytes are initialized
to zero) and a pointer to it is returned. If there is an error (e.g.
insufficient memory), NULL is returned. If either numelems or sizelem is
0, NULL is returned. If, under MS-DOS, a block of memory larger than 64K
is required, the X memory model should be used.

Memory is dynamically allocated from the heap at run time, and must be
freed explicitly if the space is required again within the program.

Example:
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#define num 50

/* compile with a large data model */
int main()
{
    long *buffer;
    buffer = calloc(num,sizeof(long));
    if(!buffer)
        {
            fprintf(stderr,"Calloc failed\n");
            abort();
        }
    printf("Memory allocated at offset: %x\p",buffer);
    free(buffer);

    return EXIT_SUCCESS;
}

Return Value: A pointer to the allocated memory is returned on success,
              otherwise a NULL pointer is returned.

See Also: free, malloc, realloc, farcalloc

ceil
Usage:
#include <math.h>
double ceil(double x);
ANSI

Description:
ceil returns a double value representing the smallest integer that is
greater than or equal to x.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x = 5.3,result;
    result = ceil(x);
    printf("The ceil of %f is %f\n",x,result);
    return EXIT_SUCCESS;
}

Return Value: Returns the double value of the smallest integer not less
              than x.

See Also: floor, fmod

chdir
Usage:
#include <direct.h>
int chdir(char *path);

Description:
chdir is a system call that changes the current directory to the
directory specified in the path argument. path must be a valid directory.
It is possible to specify a drive in the path argument, in which case the
current directory on that drive is changed, but the current drive is not
changed.

Example:
#include <direct.h>
#include <stdio.h>
#include <stdlib.h>

char *path = "\temp";
int main()
{
    int result;
    result = chdir(path);
    if (result != 0) {
        printf("Couldn't change directory\n");
        return EXIT_FAILURE;
    } else
        printf("Directory changed to %s\n",path);

    return EXIT_SUCCESS;
}

Return Value: Returns a 0 upon success otherwise a -1 and errno is set.

See Also: mkdir, rmdir

_chkstack
Usage:
#include <dos.h>
size_t _chkstack(void);

Description:
_chkstack determines if the stack has grown larger than the memory
allocated for it and if so, aborts the program with a stack overflow
message. This function should be called in recursive functions or other
functions that might use a lot of stack space. Alternatively, stack
checking can be inserted in the code automatically at compilation both
from within the environment and by using the -s switch in the ZTC command
line.

 In the X and P memory models, the 80386 segment protection mechanism
 automatically aborts the program if stack space grows into the heap so
 this function is not implemented.

Example:
#include <dos.h>

/* do_tree is a recursive func */

do_tree(struct tree *t)
{
#ifdef __ZTC__      /* defined if Zortech C / C++ */
    _chkstack();
#endif

    /* ...more code...  */

    do_tree(t->left);
    do_tree(t->right);
}

Return Value: Returns the number of bytes left on the stack, if the stack
              has not overflowed.

chmod
Usage:
#include <io.h>
#include <sys\stat.h>
int chmod (char *pathname, int pmode);

Description:
chmod is used to change the permission on a file specified by pathname to
permissions pmode. The user must have write permission for the file. The
following values are valid for pmode:

        S_IREAD         read
        S_IWRITE        write

Note that write permission implies that files may be deleted.

Example:
#include <io.h>
#include <sys\stat.h>
#include <stdlib.h>

char *pathname = "\temp"

int main()
{
    int result;
    result=chmod (pathname, S_IREAD|S_IWRITE|S_EXECUTE);
    if (result !=0) {
        printf ("Can't change permissions on file %s\n",pathname);
        return EXIT_FAILURE;
    } else
        printf ("Permissions changed on file %s\n",pathname);
    return EXIT_SUCCESS;
}

Return Value: Returns 0 upon success, otherwise -1 and errno is set.

See Also: mknod

chsize
Usage:
#include <io.h>
int chsize(int fd,long posn);

Description:
The chsize function will truncate or extend an open file. The argument fd
is the handle of the file to truncate or extend and posn is the new size.
If the specified position is shorter than the existing file, the file
will be truncated. If the specified position is longer than the existing
file, the file will be extended. Note that the new contents of extended
files are undefined.

Example:
#include <io.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    int fd;
    FILE *fp;
    char *fname[2] = {"file1","file2"};
    long sizes[2]  = {10000L, 20000L};

    fd = open(fname[0], O_WRONLY);
    fp = fopen(fname[1], "wb");
    chsize(fd, sizes[0]);
    chsize(fileno(fp), sizes[1]);

    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise -1.

See Also: filesize, filelength

clearerr
Usage:
#include <stdio.h>
void clearerr(FILE *fp);
ANSI

Description:
Clears error and EOF (end-of-file) flags associated with the stream fp.
Once the error flag on a stream is set, any operation carried out on that
stream will return an error status unless a call is made to clearerr.
Note the EOF flag is cleared with each input from the stream.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *stream;
    char *string = "Sample data";

    stream = fopen("file.dat","r");
    fprintf(stream,"%s\n",string);
    if(ferror(stream))
        {
            fprintf(stderr,"Write error to file.dat\n");
            clearerr(stream);
            fclose(stream);
            return EXIT_FAILURE;
        }
    printf("No error writing to file\n");
    fclose(stream);
    return EXIT_SUCCESS;
}

See Also: feof, ferror

clock

Usage:
#include <time.h>
long clock(void)

Description:
Determines the processor time used by the calling process at the time
clock is executed. IBM PCs have granularities of 1/18 sec. Other MS DOS
machines have only 1 sec granularity, although the time is always
returned in 1/100ths of a second.

The typedef clock_t is the long data integer type that results from the
use of clock, and represents system clock ticks.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    clock_t process;
    process = clock()/CLOCKS_PER_SEC;
    printf("Processor time in seconds %ld",process);
    return EXIT_SUCCESS;
}

Return Value: Returns an approximation of the processor time used thus
              far by the calling program. Division of the return value of
              clock by the value of the CLOCK_PER_SEC macro yields the
              time in seconds. If the processor time used is not available
              or its value cannot be represented, the function returns -1.

See Also: Time package,  asctime,  ctime,  difftime,  localtime

close
Usage:
#include <io.h>
int close(int fd);

Description:
Closes file associated with file descriptor handle fd, freeing the file
descriptor for use by another file. close does not write a Ctrl-Z (EOF)
character at the end of the file.

Example:
#include <io.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int fd,result;

    fd = open("temp",O_RDONLY);
    if(fd < 0 )
        {
            fprintf(stderr,"Can't open temp\n");
            abort();
        }
    result = close(fd);
    printf("Result code from close is %d\n",result);
    return EXIT_SUCCESS;
}

Return Value: close returns 0 if successful, or -1 and errno is set.

See Also: open, unlink

Control-C Handling
It is always difficult to handle the Ctrl-C and Ctrl-Break interrupts
properly under MS-DOS. They can cause your program to abort when you
least expect it, with disastrous results. Add to this the difficulty of
supporting interrupt handlers on DOS extended platforms and under
UNIX, and you have a major portability issue all centering around a
trivial problem.

The controlc_ functions provide a solution to this problem. They are
portable across all of the platforms Zortech supports. This code will
work under DOS, Rational Systems DOS16RM, Phar Lap & DOS386 and our
own 286 and 386 DOS extended platforms. They also work under OS/2 and
UNIX.

These functions utilize the following global variable:

    void (* _far _cdecl _controlc_handler)(void);

To use them, install a pointer to your control c/break handler in
_controlc_handler, and then call controlc_open() to activate it.

Example:
void _far _cdecl myhandler(void)
{
    controlc_occurred = 1;
    // don't call any functions here that might call DOS
    // because this is an interrupt service routine
    // and DOS is not reentrant.
}

void main(void)
{
    // notify your custom handler
    _controlc_handler = myhandler;

    // install control C/control BREAK handler
   controlc_open();

    // remove control C/control BREAK handler
    controlc_close();
}

controlc_close
Usage:
#include <controlc.h>
int _cdecl controlc_close(void);

Description:
Removes a user supplied control c/break handler. The handler should have
previously been installed by controlc_open().

See Also: Critical Error Handling

controlc_open
Usage:
#include <controlc.h>
int _cdecl controlc_open(void);

Description:
Installs a user supplied control c/break handler. A pointer to the
handler should have been previously installed in the global variable
_controlc_handler. The handler must be a far function that has void
arguments and returns a void. It should be declared with C linkage
(_cdecl).

See Also: Critical Error Handling

cos
Usage:
#include <math.h>
double cos(double x);
ANSI

Description:
The function cos calculates the cosine of the floating point argument x
where x is in radians.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double value = 2.5556,result;
    result = cos(value);
    printf("The cosine of %f is %f\n",value,result);
    return EXIT_SUCCESS;
}

Return Value: cos returns the cosine of x. Zero is returned on error and
              errno is set. Error handling can be modified with matherr.

See Also: acos, asin, atan, atan2, acosh, matherr, sin, sinh, tan, tanh

cosh
Usage:
#include <math.h>
double cosh(double x);
ANSI

Description:
Calculates the hyperbolic cosine of x.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double value = 2.5556, hycos;
    hycos = cosh(value);
    printf("Hyperbolic cosine of %f = %f\n",value,hycos);
    return EXIT_SUCCESS;
}

Return Value: cosh returns the hyperbolic cosine of x. HUGE_VAL is
              returned on overflow, 0 on any other error and errno
              is set. Error handling can be modified with matherr.

See Also: acos, asin, atan, atan2, acos, matherr, sin, sinh, tan, tanh

cputype
Usage:
#include <dos.h>
int cputype(void);

Description:
Reports the type of Intel CPU fitted.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    char *type[5] =
        {"8088/8086","80186","80286","80386","80486"};

    printf("The cpu is an %s\n",type[cputype()]);
    return EXIT_SUCCESS;
}

Return Value: An integer indicating the type of CPU fitted:
              0   8088/8086/V20
              1   80186
              2   80286
              3   80386
              4   80486

creat
Usage:
#include <io.h>
#include <sys\stat.h>
int creat(char *name, int pmode);

Description:
The system call creat either creates a new file or opens and truncates an
existing file. The permission setting, pmode, sets the new file s
reading, writing and execution permission after the file is closed for
the first time. pmode takes one or both of the following values defined
in stat.h:

        S_IREAD         read permission, owner
        S_IWRITE        write permission, owner

When two or more constants are required, they should be joined with the
bitwise OR operator. Note that creat will open the file with read/write
permission regardless of the setting of pmode. The pmode will only take
effect after the file has been closed for the first time. Under MS-DOS it
is not possible to give write-only permission, and a write-only pmode is
ignored.

Example:
#include <io.h>
#include <sys\stat.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int fp;
    fp = creat ("file.dat", S_IREAD | S_IWRITE);
    if (fp == -1) {
        printf("Cannot create file.dat\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: creat returns a -1 if an error occurred and sets errno
              to one of the following (defined in errno.h):

EACCES           Permission to access the file or a directory on the path
                 prefix has been denied.

EAGAIN           The specified file exists, and has a locking or sharing
                 violation.

EMFILE           Too many open files.

ENOENT           A path argument points to a null path name. The file or
                 path name can not be found.

creat will return with an error and errno set to EACCES if an attempt is
made to truncate an existing file with read-only permission. In a similar
way to open(), close(), etc., creat returns a file handle if the file was
created.

See Also: dos_creat, close, fopen, open

Critical Error Handling
Critical errors can occur under MS-DOS during attempts to access floppy
disk drives or while using a parallel printer. They can cause the Abort,
Retry, Ignore, Fail message to appear across your beautiful windowed
environment at the most inopportune moments. Normally you have to
write and debug a critical error handler for MS-DOS, and for each DOS
extended platform you want to support.

The cerror_ functions provide a solution to this problem. They are
portable across all the platforms that Zortech supports. This code will
work under DOS, Rational Systems DOS16RM, Phar Lap s DOS386 and our
own 286 and 386 DOS extended platforms. They also work under OS/2 and
UNIX.

These functions utilize the following global variable:

    int (* _far _cdecl _cerror_handler)(int *ax,int *di);

To use them, install a pointer to your handler in  _cerror_handler, and
then call cerror_open() to activate it.

Example:
int _far _cdecl myhandler (int *ax,int *di)
{
    // display critical error message
    // and set *ax to user response
    // don't call any functions that could call DOS
    // because this is and interrupt service routine
    // and DOS is not reentrant
}

void main(void)
{
    // notify your custom handler
    _cerror_handler = myhandler;

    // install critical error handler
   cerror_open();

    // remove critical error handler
    cerror_close();
}

cerror_close
Usage:
#include <cerror.h>
int _cdecl cerror_close(void);

Description:
Removes a user supplied critical handler. The handler should have
previously been installed by cerror_open().

See Also: Control-C Handling

cerror_open
Usage:
#include <cerror.h>
int _cdecl cerror_open(void);

Description:
Installs a user supplied critical handler. A pointer to the handler
should have been previously installed in the global variable
_cerror_handler. The handler must be a far function that takes two int
arguments and returns an int. It should be declared with C linkage
(_cdecl).

See Also: Control-C Handling

ctime
Usage:
#include <time.h>
char *ctime(time_t *ntime);
ANSI

Description:
Converts the calender time (type time_t) pointed to by ntime to local
time in the form of an ASCII string. It is equivalent to
asctime(localtime(ntime));.The time_t value ntime is normally obtained by
a call to the time function, obtaining time elapsed since 00:00:00 GMT on
January 1, 1970.

Example:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

time_t ntime;

int main()
{
    time(&ntime);
    printf("The current time is %s\n",ctime(&ntime));
    return EXIT_SUCCESS;
}

Return Value: Returns pointer to a static ASCII string of 26 characters
              of the form: DDD MMM dd hh:mm:ss YYYY\n\0

              where:

              DDD         =   day of the week
              MMM         =   month
              dd          =   day of the month
              hh:mm:ss    =   hour:minutes:seconds
              YYY         =   the year

              The string will be overwritten by each call to ctime.

See Also: Time package, asctime, clock, difftime, localtime, time

difftime
Usage:
#include <time.h>
double difftime (time_t time2, time_t time1);
ANSI

Description:
The difftime macro subtracts time1 from time2, that is, calculates the
time elapsed between time1 and time2. The value is calculated in seconds
elapsed. The arguments are normally obtained by two calls to the time
function.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    register int delay;
    time_t start, finish;
    time(&start);
    for (delay = 0; delay < 1000; delay++)
        printf("%d \n", delay);
    time (&finish);
    printf("The delay lasted %.0f seconds",
        difftime(finish, start));
    return EXIT_SUCCESS;
}

Return Value: Returns the difference between time1 and time2 in seconds.

See Also: Time package, asctime, clock, ctime, gmtime, localtime, mktime,
          time

Display Package
The Display package provides fast screen character I/O for the PC and
true compatibles. The functions comprising the Display package are
recognizable by the prefix disp_; the header file disp.h must be included
when using these functions. This section contains an overview of the
package and its use. For more details on each function refer to the
individual entry for that function.

Compatibility

These routines normally write directly into screen memory thereby gaining
their speed, and are mostly written in assembly language. They are
suitable for use in text modes only. Although they may work in graphics
modes their behavior with respect to display attributes will be
different, many of the functions will not work correctly, and for these
reasons such use is not recommended. If mixed text and graphics are
required, the functions contained in the Flash Graphics package should be
used instead.

These routines will not work on machines that do not have an IBM-PC
compatible display or BIOS. For machines that have an IBM compatible
BIOS, but a display which is not totally IBM compatible, the function
disp_usebios is provided to force the Display package to do all screen
access through the BIOS. This option will considerably slow its
operation.

 The Display package will work correctly with both the ZPM and DOSX
 extenders. It will also work correctly under OS/2.

Display Modes

The IBM PC supports several different types of display adaptor:
monochrome, medium resolution color (CGA and MCGA) and high resolution
color (EGA and VGA). Each of these has, in turn, a number of supported
screen modes. A full list of the supported display modes can be found
within the description of the disp_setmode function which follows
shortly. The current video adaptor and screen mode is ascertained by the
function disp_open, which must be called to initialize the Display
package. It is possible for the programmer to discover the current
display mode via a call to the disp_getmode function. In text modes the
IBM PC supports 80 column monochrome and 40 and 80 column color displays,
each with 25 lines. In addition the EGA and VGA adaptors can be
configured to use the medium resolution character set of the CGA adaptor,
which allows a 43 line (50 in the case of VGA) display. This latter is
not a real display mode since it is in fact obtained using the standard
80 column color mode call, but with special code to set up the character
set, and modify the number of lines. For this reason there are two
special functions in the Display package to handle 43 line mode,
disp_set43 and disp_reset43. All of the mode setting functions need to be
called before the Display package is set up (with disp_open) in order to
work correctly. After the display functions are no longer required, a
call to disp_close will restore the initial cursor type and position, and
terminate the Display package.

Cursor Size and Position

The Display package contains a function disp_setcursortype which allows
the programmer to alter the shape of the hardware text cursor. This
manipulation of cursor shape is restricted by the design of the hardware
to being able to specify the scan lines within the character box at which
the cursor will start and stop. A scan line is one pixel in height. There
are 8 scan lines to a character in CGA modes and 43/50 line mode, and 14
in EGA, VGA and monochome modes. Normally the BIOS carries out an
automatic conversion in EGA/VGA modes which allows the start and end
lines to be specified in the same way as for the CGA modes. Thus it is
only normally necessary to consider whether the display is color or
monochrome when setting the cursor type. Three macros are defined in
disp.h which allow the specification of the cursor type to be made
without reference to the display type. They are:

DISP_CURSORBLOCK        a full block cursor
DISP_CURSORHALF         a half block cursor
DISP_CURSORUL           an underline cursor

For information on their use refer to the description for
disp_setcursortype. It is possible to remove the cursor from the display
using the function disp_hidecursor, and then restore it with the
complementary function disp_showcursor, These functions are useful for
temporarily removing the cursor from the screen when displaying help
messages or menus. Note that these functions can be nested, if
disp_hidecursor has been called twice then two calls to disp_showcursor
will be required before the cursor will be displayed.

Cursor positioning within the Display package is carried out with the
function disp_move. Care should be taken when mixing Display package
functions with normal I/O functions such as printf,gets or C++ streams.
The Display package does not update the hardware cursor position when
writing to the display screen, and it is therefore essential that
disp_flush be called prior to the use of any of the normal C functions
which either write to the display, or obtain input from the user, and
before the use of any of the C++ stream functions which do likewise.


Display Attributes

The Display package allows display attributes to be modified. This allows
inverse video, bright and blinking to be used on both monochrome and
color displays. In addition separate foreground and background colors can
be specified on color displays and underline can be used on monochrome
displays. Three functions are provided for display attribute control. A
general function disp_setattr, and two specific functions disp_startstand
and disp_endstand. The latter turn reverse video on and off for
subsequent disp output operations, while the former allows more general
attribute control.

There are a number of macros defined in disp.h for use with the
disp_setattr function. They are as follows:

DISP_NORMAL             monochrome:
                        normal video
                        color:
                        white text on a black background

DISP_NONDISPLAY         monochrome:
                        invisible text
                        color:
                        invisible text on a black background

DISP_REVERSEVIDEO       monochrome:
                        inverse video
                        color:
                        black text on a white background

DISP_UNDERLINE          monochrome:
                        underlined text
                        color:
                        blue text on a black background

For more information see the relevant function descriptions.

Input and Output Functions

The Display package has a full complement of output functions, disp_putc,
disp_puts and disp_printf. These functions output at the current position
set by disp_move. This may not be the same location as the hardware
cursor unless you have previously called disp_usebios to force output to
go through the BIOS. If you require the position of the hardware cursor
to be updated to reflect the position of the next Display package output,
you must call disp_flush to update the position. All output using these
functions will use the current attribute as set by disp_setattr. If no
call to disp_setattr has been made, the default attribute is DISP_NORMAL.

In addition to these output functions there are two further functions
disp_peekw and disp_pokew. These functions allow direct access to the
video display. The disp_peekw function reads a combined character and
attribute code from the specified display coordinates as an unsigned
short. The attribute is returned in the high byte and the character in
the low byte. The character can be obtained by casting the returned value
to a char or by value&0xff. The attribute can be obtained using value>>8.
The disp_pokew function places the supplied combined character and
attribute, again as an unsigned short, at the requested display
coordinates. The combined character and attribute is obtained using the
following expression:

    attribute*256+character

Finally there are the functions disp_eeol and disp_eeop which erase to
the end of the current line, or to the end of the screen, respectively.
These functions use the currently set attribute, and it should again be
remembered that they erase from the current print position and not
necessarily from the position of the hardware cursor. A convenient method
of clearing the display screen completely is to use a disp_move(0,0)
followed by a disp_eeop().

The reason that the hardware cursor is not set to the current print
position is that to do so would considerably slow down output if a BIOS
call to move the hardware cursor were to be issued after each character
is written. Thus, the hardware cursor is only updated when disp_flush is
called.

Box Functions

The Display package provides four functions for manipulating rectangular
areas (boxes) of the display screen. These functions together allow the
development of high performance windowing or menu systems. The
disp_peekbox and disp_pokebox functions allow the contents of rectangular
areas of the screen to be read into or written from a user provided
buffer. These functions allow a portion of the display to be temporarily
saved in a buffer, and restored intact later. The disp_box function uses
the IBM box drawing characters to draw a border around a rectangular area
of screen. The function disp_fillbox allows a section of the screen to be
filled with a particular character and attribute combination.

Global Variables

A number of global variables are initialized when the Display package is
opened with a call to the disp_open function described below. The current
status of these globals can be tested in your program. These globals,
listed below, should be treated as read only.

Globals declared in disp.h:

unsigned char disp_mono       0 if color and 1 if monochrome.
unsigned char disp_snowycga   !=0 if snowy IBM CGA.
unsigned char disp_mode       Current display mode. See disp_setmode().
unsigned char disp_inited     !=0 if Display package open.
unsigned char disp_ega        !=0 if IBM EGA or VGA.
unsigned disp_base            Segment of video display RAM
                              (MDA = 0B000) (Color = 0B800)

Globals not declared in disp.h (extern declaration required):

int disp_activepage           currently active display page.
int disp_numrows              No. of display rows.
int disp_numcols              No. of display columns.
int disp_cursorrow            Row of cursor position.
int disp_cursorcol            Col. of cursor position.
int disp_cursortype           current cursor type.
                              See disp_setcursortype()

The following is an example of the use of some of the Display package
functions. The normal procedure in using the Display package is as
follows:

1. Set the display mode via a call to disp_mode or disp_set43 if the
current mode is not desired.

2. Call disp_open to open the Display package.

3. Set up the display attributes required using disp_setattr.

4. Set up the cursor type, if required, using disp_setcursortype.

5. Use disp_printf etc.

6. Before getting user input (gets, getche) or using a standard C library
function which writes to stdin (printf, putc, puts) if this is not
redirected, call disp_flush to update the cursor position.

7. Close the Display package with a call to disp_close.

For further explanation of individual functions, see their respective
descriptions.

Example:
#include <disp.h>
#include <conio.h>
#include <stdlib.h>

char *string = "Blinking Example String";
int cursor = ((6*256)+11);

int main()
{
    char ch;

    disp_open();

    disp_startstand();
    disp_printf("String displayed after call to ");
    diap_printf("disp_startstand\n");
    disp_endstand();

    disp_setattr(DISP_BLINK | DISP_NORMAL);
    disp_printf("%s\n",string);
    disp_setattr(DISP_INTENSITY | DISP_NORMAL);
    disp_printf("Attribute set to High Intensity\n");
    disp_setattr(DISP_NORMAL);

    disp_usebios();
    disp_printf("String displayed using BIOS\n");

    disp_printf("Change cursor size, Press any key: ");
    disp_setcursortype(cursor);
    disp_flush();
    ch = getch();

    disp_close();
    return EXIT_SUCCESS;
}

Refer to the chapter Other C Tools for a helpful example of the use of the
Display package for producing pop up menus.

disp_box
Usage:
#include <disp.h>
void disp_box (int type, int attr, unsigned trow, unsigned lcol,
               unsigned brow, unsigned rcol)

Description:
Draws a box of border type with attribute attr starting at top left trow,
lcol and finishing at bottom right brow, rcol.

Values for type are:

        0   Double Line Border
        1   Single Line Border
        2   Solid Border
        3   Double Horizontal/Single Vertical Line Border
        4   Single Horizontal/Double Vertical Line Border

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_box(1,DISP_NORMAL,5,10,15,60);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_fillbox, disp_peekbox, disp_pokebox

disp_close
Usage:
#include <disp.h>
void disp_close(void);

Description:
Flushes output and terminates use of the Display package. Restores the
cursor position, and type, to that in effect when the package was opened.

Example:
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(10,0);
    disp_setcursortype(DISP_CURSORHALF);
    disp_printf("Press a key to restore cursor\n");
    getch();

    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_open

disp_eeol
Usage:
#include <disp.h>
void disp_eeol(void);

Description:
Erases to the end of the current line from the current ouput position,
including the character at that position. The current output position may
not be the same as the current cursor position, unless output has been
forced to go through the BIOS by a call to disp_usebios, or disp_flush
has been called to explicitly update the cursor position.

Example:
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_printf("Press a key to erase this line\n");
    getch();
    disp_move(0,0);
    disp_eeol();
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_eeop

disp_eeop
Usage:
#include <disp.h>
void disp_eeop(void);

Description:
Erases from the current output position to the end of the screen. Uses
the currently set attribute. The current output position may not be the
same as the current cursor position,unless output has been forced to go
through the BIOS by a call to disp_usebios, or disp_flush has been called
to explicitly update the cursor position.

Example:
/* clears the screen */
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_eeol, disp_flush, disp_setattr

disp_endstand
Usage:
#include <disp.h>
void disp_endstand(void);

Description:
Ends the reverse video mode. This should be called after disp_startstand,
see that function for more details.

Example:
See disp_startstand

See Also: Display package, disp_startstand

disp_fillbox
Usage:
#include <disp.h>
void disp_fillbox (unsigned attrchar, unsigned trow, unsigned lcol,
                   unsigned brow, unsigned rcol);

Description:
Fills the box which starts at top left trow,lcol and ends at bottom right
brow,rcol with the specified character and attribute attrchar. The
attribute should be in the high byte of the unsigned attrchar, and the
character in the low byte. Use:

    attrchar = attribute*256 + character.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    unsigned chatt;

    chatt = DISP_NORMAL*256+171;
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_fillbox(chatt,5,20,10,60);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_box

disp_flush
Usage:
#include <disp.h>
void disp_flush(void);

Description:
Flushes output, moves the hardware cursor so that it coincides with the
Display package output position. This is necessary when the screen must
be up-to-date, such as when input is requested from the user.

Example:
#include <stdio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    char name[21];

    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("Enter your name ");
    disp_printf("(maximum 20 characters)");
    disp_flush();
    gets(name);
    disp_printf("\nThank you, %s.\n",name);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package

disp_getattr
Usage:
#include <disp.h>
int disp_getattr(void);

Description:
Returns the current display attribute used by the display package.

Example:
#include <ctype.h>
#include <disp.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    int att;
    if(argc!=2)
    {
        printf("Usage : PROG -R|Anotherflag\n
        printf("-R\t\Enters Reverse Video\n");
        printf("\tOther flags leave display alone\n");
        exit(EXIT_FAILURE);
    }
    disp_open();
    if( 'R' == toupper(argv[1][1]))
        disp_setattr(DISP_REVERSEVIDEO);
    if((att=disp_getattr())==DISP_REVERSEVIDEO)
        disp_printf("Attribute is reverse video.\n");
    else
        disp_printf
        ("No reverse video: attribute is: 0x%x\n",att);

    disp_flush();
    disp_close();
    return EXIT_SUCCESS;
}

Return Value:
Returns the current display attribute. The following attributes are
predefined in disp.h.

   DISP_REVERSEVIDEO,  DISP_NORMAL
   DISP_UNDERLINE,     DISP_NONDISPLAY

Information can also be obtained regarding the color attributes on a
color display. This is contained in the low byte. The high nibble of this
byte contains the background color and the low nibble the foreground
color. Thus a value of 0x17 indicates that the display will print white
text on a blue background.

Possible color settings for an IBM compatible color adaptor are:

        0           black
        1           blue
        2           green
        3           cyan
        4           red
        5           magenta
        6           brown
        7           white

See Also: Display package, disp_setattr

disp_getmode
Usage:
#include <disp.h>
int disp_getmode(void);

Description:
Returns the current video mode. This function can be used without opening
the Display package.

Example:
#include <disp.h>
#include <stdlib.h>

int main() {
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("Current video mode = %d\n",disp_getmode());
    disp_close();
    return EXIT_SUCCESS;
}

Return Value

disp_getmode returns the current video mode as follows:

    Mode    Description                     Availability
             
     0       40 x 25 B/W Alpha              CGA/EGA/VGA
     1       40 x 25 color Alpha            CGA/EGA/VGA
     2       80 x 25 B/W Alpha              CGA/EGA/VGA
     3       80 x 25 color Alpha            CGA/EGA/VGA
     4      320 x 200 color graphics        CGA/EGA/VGA
     5      320 x 200 B/W graphics          CGA/EGA/VGA
     6      640 x 200 B/W graphics          CGA/EGA/VGA
     7       80 x 25 B/W Alpha              MDA /EGA/VGA (mono display)
    13      320 x 200 16 color graphics     EGA/VGA
    14      640 x 200 16 color graphics     EGA/VGA
    15      640 x 350 4 color graphics      EGA /VGA (mono display)
    16      640 x 350 16 color graphics     EGA/VGA

See Also: Display package, disp_setmode

disp_hidecursor
Usage:
#include <disp.h>
void disp_hidecursor(void);

Description:
Hides the hardware cursor via a call to the BIOS. A call to
disp_showcursor is required to redisplay it. Multiple calls to
disp_hidecursor are nested such that an equal number of calls to
disp_showcursor are required before the cursor is restored.

Example:
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("Press any key to hide the cursor\n");
    disp_flush();
    getch();
    disp_hidecursor();
    disp_printf("Press any key to show the cursor\n");
    disp_flush();
    getch();
    disp_showcursor();
    disp_printf("Press any key to exit");
    disp_flush();
    getch();
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_showcursor

disp_move
Usage:
#include <disp.h>
void disp_move(int row,int col);

Description:
Moves the Display package output position to the row and column
specified. The home position is 0,0 which is the upper left corner of the
display. Does not update the hardware cursor position unless disp_usebios
has been called previously to force output to go through the BIOS. To
explicitly update the hardware cursor, to ensure that it reflects the
current Display package output position, use disp_flush.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_move(5,10);
    disp_printf("hello there\n");
    disp_close();
    return EXIT_SUCCESS;
}

disp_open
Usage:
#include <disp.h>
void disp_open(void);

Description:
Initializes the Display package. The type of display and the screen
memory address are determined during this call. All globals are
initialized. This function must be called before any of the Display
package functions are used with the exception of disp_setmode,
disp_set43, or disp_reset43, which must be called before disp_open.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_printf("The base screen address is %5x",disp_base);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_close, disp_flush

disp_peekbox
Usage:
#include <disp.h>
void disp_peekbox(unsigned *save, unsigned trow, unsigned lcol,
                  unsigned brow, unsigned rcol)

Description:
Stores a rectangular area of the screen defined by top left trow, lcol
and bottom right brow, rcol in the user supplied buffer save which should
point to an unsigned integer array large enough to hold the area being
saved. This is calculated as follows:

    size = ((brow-trow+1) * (rcol-lcol+1)) * sizeof(unsigned short)

Example:
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    unsigned buf[20*5];

    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_box(0,0x70,0,0,4,19);
    disp_peekbox(buf,0,0,4,19);
    disp_move(0,0);
    disp_eeop();
    disp_puts("hello world");
    disp_flush();
    getch();
    disp_pokebox(buf,0,0,4,19);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package,  disp_pokebox,  disp_box,  disp_fillbox,
          disp_peekw,  disp_pokew

disp_peekw
Usage:
#include <disp.h>
unsigned disp_peekw(int row,int col);

Description:
Reads a combined attribute/character from video display at position
row, col. The components can be separated out as follows:

    character = charatt & 0xff;
and
    attribute = charatt >> 8;

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    unsigned chatt;

    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_move(4,4);
    disp_puts("hello world ");
    chatt = disp_peekw(4,4);
    disp_printf("Char at 4,4 is %c with attr %2x",chatt&0xff,chatt>>8);
    disp_close();
    return EXIT_SUCCESS;
}

Return Value: The combined character and attribute as an unsigned integer.
              The attribute is returned in the high byte, and the
              character in the low byte.

See Also: Display package, disp_pokew, disp_peekbox, disp_pokebox

disp_pokebox
Usage:
#include <disp.h>
void disp_pokebox(unsigned *save, unsigned trow, unsigned lcol,
                  unsigned brow, unsigned rcol)

Description:
Restores a rectangular area of the screen defined by top left trow, tcol
and bottom right brow, rcol from the buffer save which could have been
saved previously by a call to disp_peekbox.

Example:
See disp_peekbox

See Also: Display package,  disp_peekbox,  disp_box,  disp_fillbox,
          disp_pokew,  disp_peekw

disp_pokew
Usage:
#include <disp.h>
void disp_pokew(int row,int col,int attrchar);

Description:
Pokes an attribute and character into a specified row and column. The
character and attribute are passed as a combined value in an unsigned
integer (the form in which they are returned by disp_peekw). Use

    attrchar = attribute*256 + character

Example:
#include <disp.h>
#include <stdlib.h>

int main() {
    unsigned chatt;
    chatt = DISP_REVERSEVIDEO*256+'a';

    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_pokew(4,4,chatt);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_peekw, disp_pokebox, disp_peekbox

disp_printf
Usage:
#include <disp.h>
void disp_printf(char *format,...);

Description:
The formatted print routine for writing directly to the screen. For more
information on print formatting see the function descriptions for printf
and fprintf.

Example:
See disp_peekw

See Also: Display package, disp_puts, printf

disp_putc
Usage:
#include <disp.h>
void disp_putc(int c);

Description:
Writes the character c to the current Display package output location
using the character attribute set by disp_setattr. Handles tabs, carriage
returns and backspaces, etc. correctly.

Example:
#include <disp.h>
#include <stdlib.h>

int main() {
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_move(4,10);
    disp_putc('a');
    disp_putc('\t');
    disp_putc('b');
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_puts, disp_pokew, putc

disp_puts
Usage:
#include <disp.h>
void disp_puts(const char * p);

Description:
Writes the string pointed at by p to the current Display package output
location using the character attribute set by disp_setattr. Handles tabs,
carriage returns and backspaces, etc. correctly. Unlike puts it does not
write a newline at the end of the string.

Example:
#include <disp.h>
#include <stdlib.h>

char *first =
   "disp_puts needs a newline at the end, ";
char * second =
   "otherwise output continues on the same line.\n";

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_move(4,10);
    disp_puts(first);
    disp_puts(second);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_putc, disp_pokew, puts

disp_reset43
Usage:
#include <disp.h>
void disp_reset43(void);

Description:
Resets display from 80x43 EGA or 80x50 VGA text mode to 80x25 mode.

Example:
See disp_set43

See Also: Display package, disp_set43, disp_setmode, disp_getmode,
          disp_open

disp_scroll
Usage:
#include <disp.h>
void disp_scroll(int lines, unsigned ulrow, unsigned ulcol,
                 unsigned lrrow, unsigned lrcol, unsigned attr);

Description:
Scrolls the screen up:
    lines   no. of lines to scroll (lines < 0 scrolls area down)
    ulrow   upper left row of display area
    ulcol   upper left column of display area
    lrrow   lower right row of display area
    lrcol   lower right column of display area
    attr    video attribute to use on uncovered areas.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_scroll(disp_numrows,0,0,disp_numrows-1,disp_numcols/2,DISP_NORMAL);
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_box, disp_fillbox

disp_set43
Usage:
#include <disp.h>
void disp_set43(void);

Description:
This function sets the display mode to 80x43 EGA text mode (80x50 on a
VGA). This function should not be used while Display package is open.
An EGA or VGA display adaptor and compatible display are needed for this
to work. The actual resulting number of lines is stored in disp_numrows.

Example:
#include <stdio.h>
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main() {
    disp_set43();
    disp_open();
    disp_printf("The display should be in 43 line mode\n");
    disp_printf("Press a key when ready\n");
    disp_flush();
    getch();
    disp_close();
    disp_reset43();
    printf("Back to the original screen mode\n");
    return EXIT_SUCCESS;
}

See Also: Display package, disp_reset43, disp_setmode, disp_getmode

disp_setattr
Usage:
#include <disp.h>
void disp_setattr(int attr);

Description:
Sets the display attribute for characters written by disp_putc and
disp_printf. Below is a list of the predefined attributes to be found in
the disp.h file.

   DISP_REVERSEVIDEO,  DISP_NORMAL,
   DISP_UNDERLINE,     DISP_NONDISPLAY

It is possible to use this function to set the color attributes for use
with a color display. The easiest way to do so is by their entry as a one
byte hexadecimal number, where the high nibble holds the background color
and the low nibble the foreground color. Thus the call disp_setattr(0x17)
will set up white text on a blue background. Possible color settings for
an IBM compatible color adaptor are:

            0       black
            1       blue
            2       green
            3       cyan
            4       red
            5       magenta
            6       brown
            7       white

The following attribute bits can be ORed in:

    DISP_INTENSITY, DISP_BLINK

Example:
#include <disp.h>
#include <stdlib.h>
int main() {
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("This is normal video\n");
    disp_setattr(DISP_NORMAL|DISP_INTENSITY);
    disp_printf("This is bright\n");
    disp_setattr(DISP_REVERSEVIDEO);
    disp_printf("and this is inverse video\n");
    if (disp_getmode() == 3) {
        disp_setattr(0x17);
        disp_printf("This is white on blue...\n");
    }
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_setmode, disp_getmode

disp_setcursortype
Usage:
#include <disp.h>
void disp_setcursortype(int startline*256 + endline);

Description:
disp_setcursortype can be used to modify the appearance of the hardware
cursor. The cursor consists of a series of horizontal lines corresponding
to the lines of horizontal pixels in the character matrix. The monochrome
and color systems have different size character matrices. There are also
differences between the various color display adaptors. In the latter
case, however, an internal compensation is carried out which allows all
color adaptors to be specified using an 8x8 matrix. Monochrome systems
use a 14x9 matrix. A BIOS call is used to set the cursor size, arguments
expected are the starting and ending lines for the cursor.

The DOS default cursor types are:

    Type        Start   End     Use
              
    Monochrome   11     12      ((11*256)+12)
    Color         6      7      ((6*256)+7)

There are three values defined in disp.h which can be used to set
standard cursor types:

    DISP_CURSORBLOCK    a full bock cursor
    DISP_CURSORHALF     a half block cursor
    DISP_CURSORUL       an underline cursor

Example:
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("Press any key for a block cursor\n");
    disp_flush();
    getch();
    disp_setcursortype(DISP_CURSORBLOCK);
    disp_printf("Press any key for a half cursor\n");
    disp_flush();
    getch();
    disp_setcursortype(DISP_CURSORHALF);
    disp_printf("Press any key to exit");
    disp_flush();
    getch();
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_hidecursor, disp_showcursor, disp_flush

disp_setmode
Usage:
#include <disp.h>
void disp_setmode(unsigned char mode);

Description:
Sets the video mode. If the current video mode is not required, a call to
this function must be made before the call to disp_open. See disp_getmode
for details of the available modes.

Example:
#include <stdio.h>
#include <conio.h>
#include <disp.h>
#include <stdlib.h>

int main()
{
    if (disp_getmode() == 7)
        printf("Can't change mode on a mono display\n");
    else {
        disp_setmode(1);        /* 40x25 color */
        disp_open();
        disp_printf("This should be in 40 column color.\n");
        disp_printf("Press a key to exit\n");
        getch();
        disp_close();
    }
    return EXIT_SUCCESS;
}

See Also: Display package, disp_getmode, disp_set43, disp_reset43

disp_showcursor
Usage:
#include <disp.h>
void disp_showcursor(void);

Description:
Restores the hardware cursor to the screen after it has been hidden with
a call to disp_hidecursor. Multiple calls to disp_hidecursor are nested
such that an equal number of calls to disp_showcursor are required before
the cursor is restored.

Example:
See disp_hidecursor

See Also: Display package, disp_hidecursor, disp_setcursortype

disp_startstand
Usage:
#include <disp.h>
void disp_startstand(void);

Description:
Causes all characters printed after this call to be displayed in reverse
video mode. The reverse video mode is turned off using the disp_endstand
function call.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_printf("This is normal video\n");
    disp_startstand();
    disp_printf("This is after disp_startstand\n");
    disp_endstand();
    disp_printf("and this is after disp_endstand\n");
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_endstand, disp_setattr

disp_usebios
Usage:
#include <disp.h>
void disp_usebios(void);

Description:
Sets up the Display package to write characters to the screen using the
BIOS, instead of writing directly to the display. This increases
portability while reducing speed. This should be called after disp_open.
When output is forced through the BIOS the hardware cursor will always
reflect the Display package's current output position. This function
should not be used under OS/2.

Example:
#include <disp.h>
#include <stdlib.h>

int main()
{
    disp_open();
    disp_move(0,0);
    disp_eeop();
    disp_puts("This writes directly to the display");
    disp_usebios();
    disp_puts("This example writes through the BIOS");
    disp_close();
    return EXIT_SUCCESS;
}

See Also: Display package, disp_flush

div
Usage:
#include <stdlib.h>
div_t div(int numerator, int denominator);
ANSI

Description:
div divides the numerator by denominator, returning the quotient and the
remainder. The div_t type is defined in stdlib.h as follows:

    typedef struct { int quot, rem; } div_t;

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    div_t answ;
    int ina,inb;
    puts("Enter two integers:");
    scanf("%d %d",&ina,&inb);
    answ = div(ina,inb);
    printf("The quotient is %d, and the remainder ");
    printf("is %d\n",answ.quot,answ.rem);
    return EXIT_SUCCESS;
}

Return Value: The div function returns a structure type div_t
              whose elements are quot (the quotient) and rem (the
              remainder).

See Also: ldiv

DOS Package
The DOS package is a collection of useful functions which are designed
specifically for IBM PC compatible machines operating under MS or PC
DOS, although some of these functions are also provided under OS/2. DOS
Package functions have the prefix dos_, and should not be used if you plan
to port your code to other hardware or another operating system.

 Some of the available dos_ functions are not supported or only
 partially supported in the X memory model, refer to the entry for each
 function for more information.

The DOS package functions can be split conveniently into four groups.
Those concerned with disk or file access, those concerned with the system
time and date, those concerned with memory allocation and various
miscellaneous functions.

Disk and File Functions

There a variety of functions involved with disk and file operations which go
directly through the MS-DOS software interrupts. The first of these are
dos_abs_disk_read and dos_abs_disk_write. These functions provide a
way of directly reading and writing logical disk sectors to and from the
disk. One possible use for these routines would be in a diskcopy type
utility. dos_getdrive and dos_setdrive provide a way for the
programmer to ascertain the current drive number, and to change the
current drive. dos_getdiskfreespace can be used to find out the amount
of free space that is available on a disk. dos_getftime and dos_setftime
allow the file date and time stamps to be read and modified. Finally
dos_getfileattr and dos_setfileattr can be used to read or modify a
file's attribute bits.

System Date/Time Functions

There are four functions associated with the DOS system time and date.
These are dos_gettime and dos_settime which allow the system time to
be read and set, and dos_getdate and dos_setdate which do the same for
the system date.

Memory Allocation Functions

Four memory allocation functions are provided as part of the DOS package.
dos_alloc and dos_calloc request memory from the heap in a similar
way to malloc and calloc. These functions are direct calls to MS-DOS and
do not go through the normal allocation management system. dos_free is
provided to free memory allocated by dos_alloc and dos_calloc. The final
function, dos_setblock, carries out a similar function to realloc,
allowing the size of an allocated memory block to be changed.

Miscellaneous Functions

The rest of the functions provide an interface to various miscellaneous
facilities provided by DOS. dos_exterr obtains the extended error
information provided by MS-DOS 2.11 and later. The functions
dos_get_ctrl_break and dos_set_ctrl_break allow the DOS control
break status to be tested or changed. dos_get_verify and dos_set
verify do the same for the DOS verify status.

dos_abs_disk_read
Note-This function is not available under the DOSX extender.

Usage:
#include <dos.h>
int dos_abs_disk_read (int drive, int num_sec,
                       int start_sec, char *buffer):

Description:
Transfer control directly to BIOS to perform the disk read. The drive is
a 0 for A:, 1 for B: and so on up to 25. The number of sectors to read is
specified in num_sec. start_sec defines the first sector for operation.
The final argument, buffer, is the destination memory address for the
operation, it must be large enough to hold the requested sectors. This
function will work correctly under MS-DOS 4.x.

Example:
/* Reads in logical sector 1 from drive a: and    */
/* does a hex and ascii dump of it to the display */
#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include <stdlib.h>

char buffer[512];

int main()
{
    unsigned i, j;
    unsigned char *p = (unsigned char *) buffer;

    i = dos_abs_disk_read(0,1,1,buffer);
    if (i)
        {
        printf("Disk error: DOS code %x BIOS code %x\n",i%256,i/256);
        exit(EXIT_FAILURE);
        }

    printf("logical sector 1, drive A\n\n\n");

    for (j = 0; j < 512; j += 8, p += 16)
        {
        for (i = 0; i < 16; i++)
            printf("%02x ",p[i]);
        printf("    ");
        for (i = 0; i < 16; i++)
            if (isprint(p[i]))
                printf("%c",p[i]);
            else
                printf(".");
        if (j && (j%128 == 0))
            {
            printf("\n:Press any key:\n%c",0x07);
            getchar();
            }
        else
            printf("\n");
        }
    return EXIT_SUCCESS;
}

Return Value

Returns a 0 on success. A non-zero return value indicates an error. The
lower byte will contain the DOS error code. The higher byte will contain
the specific BIOS error. These BIOS errors are detailed below:

    0x01    bad command
    0x02    bad address mark
    0x03    write protect error
    0x04    sector not found
    0x08    DMA (direct memory access) failure
    0x10    data error (bad CRC)
    0x20    controller failure
    0x40    seek operation failed
    0x80    device failed to respond

See Also: DOS package, dos_abs_disk_write

dos_abs_disk_write
Note-This function is not available under the DOSX extender.

Usage:
#include <dos.h>
int dos_abs_disk_write(int drive,int num_sec,
                       int start_sec,char *buffer):

Description:
Transfer control directly to BIOS to perform the disk write. The drive is
a 0 for A:, 1 for B: and so on up to 25. The number of sectors to write
is specified in num_sec. start_sec defines the first sector for
operation. Buffer is the source memory address for the operation. This
function will work correctly under MS-DOS 4.x.

 Writing to a disk using this function could cause irretrievable loss of
 data, and may damage the file structure of the disk. For this reason no
 example is given. You should only use this function if you are fully
 conversant with the organization of MS-DOS disks and their associated
 file structures.

Return Value: Returns a 0 on success. A non-zero return value indicates
              an error. The lower byte will contain the DOS error code.
              The higher byte will contain the specific BIOS error. See
              dos_abs_disk_read for details of these error codes.

See Also: DOS package, dos_abs_disk_read

dos_alloc
Usage:
#include <dos.h>
unsigned dos_alloc(unsigned para):

Description:
Allocates memory from the heap by a direct call to MS-DOS. The argument
para contains the number of paragraphs required. Use:

        (bytes_required+15)/16

Memory allocated with dos_alloc should be freed using dos_free only.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

unsigned newseg;

int main()
{
    if ((newseg = dos_alloc(20)) == 0)
        {
        printf("dos_alloc failed\n");
        exit(EXIT_FAILURE);
        }
    else
        {
        printf("Memory allocated successfully\n");
        }
    if (dos_free(newseg) == -1)
        printf("Unable to free memory\n");
    else
        printf("Memory freed successfully\n");
    return EXIT_SUCCESS;
}

Return Value: If successful dos_alloc returns the segment of the allocated
              block, otherwise zero is returned and _doserrno is set to
              the DOS error number.

See Also: DOS package, dos_calloc, dos_free, dos_setblock

dos_calloc
Usage:
#include <dos.h>
unsigned dos_calloc(unsigned para):

Description:
Allocates memory from the heap by a direct call to MS-DOS. If successful,
the allocated memory is cleared (all bytes zero). The argument para
contains the number of paragraphs required. Use:

        (bytes_required+15)/16

Memory allocated with dos_calloc should be freed using dos_free only.

Example:
See that for dos_alloc.

Return Value: If successful dos_calloc returns the segment of the allocated
              block, otherwise zero is returned and _doserrno is set to
              the DOS error number.

See Also: DOS package, dos_alloc, dos_free, dos_setblock

dos_creat
Usage:
#include <dos.h>
int dos_creat(char *name,unsigned attribute):

Description:
Create a file in a DOS environment as opposed to a UNIX type environment
(there is no "write-only" option as is found in UNIX). The attribute byte
is the same as described in the DOS Technical Reference Manual. Here are
the attributes defined in dos.h:

    FA_RDONLY   0x01    Read Only
    FA_HIDDEN   0x02    Hidden file
    FA_SYSTEM   0x04    System file
    FA_LABEL    0x08    Volume label
    FA_DIREC    0x10    Sub-directory
    FA_ARCH     0x20    Archive bit

Example:
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

int main()
{
    int handle;

    if((handle = dos_creat("temp.fil",FA_ARCH)) == -1)
        perror("Unable to create file");
    else
        printf("File created successfully\n");
    return EXIT_SUCCESS;
}

Return Value: Returns a DOS handle if the file was successfully created
              otherwise a -1 and errno is set.

dos_exterr dosexterr
Usage:
#include <dos.h>
int dos_exterr(struct DOSERROR *err):
int dosexterr(struct DOSERROR *err):

Description:
These functions are identical, both names are used to increase
compatibility with other compilers.

The function dos_exterr obtains the DOS extended error information which
is returned from DOS function call 0x59 (89). The information is placed
in the structure which is pointed to by err. The format of the DOSERROR
structure is defined in dos.h and is as follows:

struct DOSERROR
{
    int exterror;
    char eclass;
    char action;
    char locus;
};

If a NULL pointer is passed to dos_exterr , the function will return
immediately with the extended error number.

 The function dos_exterr is only available with MS-DOS 3.x and above

Example:
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int fd;
    struct DOSERROR p;
    if ((fd = open("temp.fil",O_RDONLY,0)) == -1)
        {
        dos_exterr(&p);
        printf("exterr = %d\n",p.exterror);
        printf("class = %d\n",p.class);
        printf("action = %d\n",p.action);
        printf("locus = %d\n",p.locus);
        perror("File open error");
        return EXIT_FAILURE;
        }
    return EXIT_SUCCESS;
}

Return Value: Returns the DOS extended error number. A value of 0 means
              that no error occurred in the previous operation.

See Also: Dos package

dos_findfirst
Usage:
#include <dos.h>
int dos_findfirst(char *name,int attr,struct FIND *b1);

Description:
This is a recursive version of the library findfirst() call. The primary
difference between this routine and findfirst() is that it allows
recursion through the use of different FIND structures for each occasion
the dos_findfirst() function is called. The arguments are:

    name    File name to locate. Usually contains wildcards.
    attr    Attribute mask to use.
    b1      FIND structure in which to place the result.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main() {
    struct FIND ffblk;

    if (0 == dos_findfirst("*.*", 0xff, &ffblk))
        do {
            puts(ffblk.name);
        } while (0 == dos_findnext(&ffblk));
    return EXIT_SUCCESS;
}

Return Value: 0 if file is found, else non-zero

See Also: dos_findnext

dos_findnext
Usage:
#include <dos.h>
int dos_findnext(struct FIND *b1);

Description:
This is a recursive version of the library findnext() call. The primary
difference between this routine and findnext() is that it allows
recursion through the use of different FIND structures for each occasion
the findfirst function is called. The argument b1 is the FIND structure
returned by the corresponding dos_findfirst call.

Example:
See dos_findfirst

Return Value: 0 if file is found, else non-zero

See Also: dos_findfirst

dos_free
Usage:
#include <dos.h>
int dos_free(unsigned):

Description:
Frees (releases back to the operating system) memory which has been
previously allocated with dos_alloc or dos_calloc. The argument is the
segment address of the memory to be freed.

Example:
See the example for dos_alloc.

Return Value: 0 if the memory was sucessfully freed, otherwise -1.

See Also: Dos package, dos_alloc, dos_calloc, dos_setblock

dos_get_ctrl_break
Usage:
#include <dos.h>
int dos_get_ctrl_break(void):

Description:
Returns the state of the DOS control break status. Returns a non-zero
value if BREAK checking is on and a zero value if BREAK checking is off.
For additional information, see the BREAK command in your DOS Reference
Manual.

Return Value: Return a non-zero value if the status is on and a zero
              if the status is off.

dos_getdate
Usage:
#include <dos.h>
void dos_getdate(struct dos_date_t *date):

Description:
Obtains the current system date via a call to DOS function 0x2a (42) and
places it in the structure pointed to by date. The format of this
structure is as follows:

struct dos_date_t
{
    char    day;            /* day of month(1-31)     */
    char    month;          /* month (1-12)           */
    int     year;           /* year (1980-2099)       */
    char    dayofweek;      /* day of week (0=Sunday) */
}

Example:
See dos_setdate

See Also: DOS package, dos_setdate, dos_settime dos_gettime

dos_getdiskfreespace
Usage:
#include <dos.h>
long dos_getdiskfreespace(int drive):

Description:
Returns a long integer of available disk space. Drive is an integer value
where 0 = default, 1 = A:, 2 = B:, 3 = C: and so on.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    printf("Free space on default drive is %ld bytes\n",
            dos_getdiskfreespace(0));
    return EXIT_SUCCESS;
}

Return Value: Returns a long integer of available disk space.

dos_getdrive
Usage:
#include <dos.h>
void dos_getdrive(unsigned *driveptr):

Description:
This function obtains the identity of the currently logged drive and
stores it in the unsigned integer pointed to by driveptr. The drive is
reported as a integer number where 1 = A:, 2 = B:, 3 = C: and so on.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    unsigned driveno;

    dos_getdrive(&driveno);
    printf("The current drive is %c:",driveno-1+'a');
    return EXIT_SUCCESS;
}

See Also: DOS package, dos_setdrive

dos_getfileattr
Usage:
#include <dos.h>
int dos_getfileattr (char *filepath, unsigned *att):

Description:
Gets the current file attributes of the named file and places them in the
unsigned integer pointed to by att. The char pointer filepath references
a standard DOS path and filename as a null terminated string. Individual
file attributes can be checked by anding them with the appropriate masks.
The following macros are defined in dos.h and can be used for that
purpose:

    FA_RDONLY   read only
    FA_HIDDEN   hidden
    FA_SYSTEM   system
    FA_ARCH     archive

 dos_getfileattr is not available for directories or the volume label.

Example:
See dos_setfileattr

Return Value: 0 if succesful otherwise the DOS error code.

See Also: DOS package, dos_setfileattr

dos_getftime
Usage:
#include <dos.h>
int dos_getftime(int fd, unsigned *date, unsigned *time):

Description:
Obtains the time and date of the file belonging to the file descriptor fd
and places it in the unsigned integers pointed to by the arguments date
and time. The format of these arguments is the same as those which are
used by the dos_setftime function and is as follows:

date:
    bits 0 to 4     day of month (0-31)
    bits 5 to 8     month (0-12)
    bits 9 to 15    year (relative to 1980)
time:
    bits 0 to 4     number of 2 second increments (0-29)
    bits 5 to 10    minutes (0-59)
    bits 11 to 15   hours (0-23)

Example:
See dos_setftime

Return Value: 0 if successful, otherwise sets errno and returns the DOS
              error code.

See Also: DOS package, dos_setftime

dos_gettime
Usage:
#include <dos.h>
void dos_gettime(struct dos_time_t *time):

Description:
Obtains the current system time via a call to DOS function 0x2c (44) and
places it in the structure pointed to by time. The format of this
structure  is as follows:

struct dos_time_t
{
    char    hour;           /* hours (0-23)       */
    char    minute          /* minutes (0-59)     */
    char    second;         /* seconds (0-59)     */
    char    hsecond;        /* seconds/100 (0-99) */
}

Example:
See dos_settime

See Also: DOS package, dos_settime, dos_setdate, dos_getdate

dos_get_verify
Usage:
#include <dos.h>
int dos_get_verify(void):

Description:
Returns the state of the DOS verify status. This function will return a
non-zero value if VERIFY is on and a zero if the VERIFY is off. For
additional information, see the VERIFY command in your DOS Technical
Reference Manual.

Return Value: Return a non-zero value if the status is on and a zero
              if the status is off.

dos_open
Usage:
#include <io.h>
int dos_open (char *pathname,int rwmode);

Description:
Opens the file specified by pathname. rwmode selects the mode in which
the  file is opened. The values for rwmode are to be found in dos.h and
are:

    O_RDONLY    read
    O_WRONLY    write

This function is implemented as a direct hook to DOS. Other values can be
passed to DOS (see your DOS manual for more information) but values
which are undefined to DOS should never be passed via dos_open.

Example:
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <stdlib.h>

int main()

{
    char *fname;
    unsigned int mode;
    int fd;
    mode = O_RDONLY;
    fname = "file.dat";
    fd = dos_open(fname,mode,0);
    if(fd == -1)
        perror("Error opening file");
    else {
        printf("\nfile: %s opened for reading\n", fname);
        close(fd);
    }
    mode = O_WRONLY;
    fname = "CON";
    fd = dos_open(fname,mode,0);
    if(fd < 0)
        printf("\nError opening console for write:%s\n", fname);
    else {
        printf("\nfile: %s opened for write\n",fname);
        close(fd);
    }
    mode = O_WRONLY | O_CREAT;
    fname = "file.dat";
    fd = dos_open(fname,mode);
    if(fd == -1) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }
    else {
        printf("\nfile: %s opened for output\n", fname);
        close(fd);
    }
    return EXIT_SUCCESS;
}

Return Value: Returns the file descriptor (fd) if successful, -1 if an
              error occurred. errno is set upon error.

See Also: close, creat, dos_creat, fopen, open

dos_setblock
Usage:
#include <dos.h>
unsigned dos_setblock(unsigned newsize, unsigned seg):

Description:
Attempts to modify the size of a memory block previously allocated with
dos_alloc or dos_calloc. The newsize argument is the new number of
paragraphs requested, seg is the segment address of the allocated memory.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned newseg;

    if ((newseg = dos_alloc(10)) == 0) {
        printf("dos_alloc failed\n");
        exit(EXIT_FAILURE);
    }
    else {
        printf("Memory allocated successfully\n");
    }

    newseg = dos_setblock(20,newseg);

    if (_doserrno) {
        printf("dos_setblock failed: ");
        printf("only %ud available\n",newseg);
        exit(EXIT_FAILURE);
    }
    else {
        printf("Memory block successfully expanded\n");
    }

    if (dos_free(newseg)    == -1)
        printf("Unable to free memory\n");
    else
        printf("Memory freed successfully\n");
}

Return Value: If successful the segment address of the allocated memory
              is returned, otherwise _doserrno is set and the maximum size
              that the block could be expanded to is returned, in which
              case the block is not altered.

See Also: DOS package, dos_alloc, dos_calloc, dos_free

dos_set_ctrl_break
Usage:
#include <dos.h>
void dos_set_ctrl_break(int on_off);

Description:
Turns the control break checking on or off. A non-zero value for the
on/off  argument turns control break checking on and a zero value turns
off  control break checking. This function has the same effect as the
BREAK  command does for the DOS command processor.

dos_setdate
Usage:
#include <dos.h>
int dos_setdate(struct dos_date_t *date):

Description:
Sets the current date via a call to DOS function 0x2b (43) to the values
passed in the structure pointed to by date. The format of this structure
is as follows:

struct dos_date_t
{
    char    day;        /* day of month(1-31)       */
    char    month;      /* month (1-12)             */
    int     year;       /* year (1980-2099)         */
    char    dayofweek;  /* day of week (0 = Sunday) */
}

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    struct dos_date_t date;
    int oy;

    dos_getdate (&date);
    printf ("Date is %02d/%02d/%d (day of week %d)\n",
            date.month, date.day, date.year, date.dayofweek);

    oy = date.year;
    date.year = 1991;
    dos_setdate(&date);
    dos_getdate(&date);
    printf("\nDate is %02d/%02d/%d (day of week %d)\n",
           date.month, date.day, date.year, date.dayofweek);

    date.year = oy;
    dos_setdate(&date);
    dos_getdate(&date);
    printf("\nDate is %02d/%02d/%d (day of week %d)\n",
           date.month, date.day, date.year, date.dayofweek);
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise returns non zero if the date
              passed was invalid.

See Also: DOS package, dos_getdate, dos_settime, dos_gettime

dos_setdrive
Usage:
#include <dos.h>
void dos_setdrive(unsigned drive, unsigned *no_of_drives):

Description:
The function dos_setdrive changes the currently logged drive to that
requested in the drive argument. This argument is supplied as an
unsigned integer where 1 = A:, 2 = B:, 3 = C: and so on. The second
argument is a pointer to an unsigned integer into which the total number
of logical drives in the system is placed.

 The term logical drives refers to all block transfer devices in the
 system. This includes diskette (floppy disk) drives, ram disks, and hard
 disks including those which have been partitioned into separate drives.
 A system fitted with a single diskette drive will return a value of 2 in
 no_of_drives. This is because a single diskette drive can be accessed as
 either of two logical drives, A or B.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    unsigned numdrives;

    dos_setdrive(1,&numdrives);
    printf("Total drives in the system is %d\n", numdrives);
    printf("Current drive is now a: \n");
    return EXIT_SUCCESS;
}

See Also: DOS package, dos_getdrive

dos_setfileattr
Usage:
#include <dos.h>
int dos_setfileattr(char *filepath, unsigned att):

Description:
Sets the current file attributes of the named file to those passed in the
unsigned integer att. The char pointer filepath references a standard
DOS path and filename as a null terminated string. Individual file
attributes can be set by oring att with the appropriate masks. The
following macros are defined in dos.h and can be used for that purpose:

    FA_NORMAL   no attributes set
    FA_RDONLY   read only
    FA_HIDDEN   hidden
    FA_SYSTEM   system
    FA_ARCH     archive

 dos_setfileattr is not available for directories or the volume label.

Example:
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int fd;
    unsigned attribute;

    printf("Creating temporary file\n");
    fd = dos_creat("temp.fil",FA_RDONLY);
    if (fd == -1)
        {
        perror("Error opening file");
        exit(EXIT_FAILURE);
        }
    dos_getfileattr("temp.fil",&attribute);

    if (attribute & FA_RDONLY)
        printf("temp.fil is read only\n");
    else
        printf("temp.fil is not read only\n");

    if (attribute & FA_ARCH)
        printf("temp.fil has its archive bit set \n");
    dos_setfileattr("temp.fil",FA_NORMAL);
    dos_getfileattr("temp.fil",&attribute);

    if (attribute & FA_RDONLY)
        printf("temp.fil is read only\n");
    else
        printf("temp.fil is not read only\n");

    if (attribute & FA_ARCH)
        printf("temp.fil has its archive bit set \n");

    if (unlink("temp.fil") == 0)
        printf("\nTemporary file deleted OK\n");
    else {
        perror("Error deleting file");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: 0 if succesful otherwise the DOS error code

See Also: DOS package, dos_getfileattr

dos_setftime
Usage:
#include <dos.h>
int dos_setftime(int fd, unsigned date, unsigned time);

Description:
Sets the time and date of the file attatched to the file descriptor fd
to those specified in the arguments date and time. The format of these
arguments is the same as those which are obtained by the use of the
dos_getftime function.

date:
        bits 0 to 4     day of month (0-31)
        bits 5 to 8     month (0-12)
        bits 9 to 15    year (relative to 1980)
time:
        bits 0 to 4     no of 2 second increments (0-29)
        bits 5 to 10    minutes (0-59)
        bits 11 to 15   hours (0-23)

Example:
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int fd, d,m,y,h,mi,s;
    unsigned date, time;

    printf("Creating temporary file\n");
    fd = dos_creat("temp.fil",FA_RDONLY);
    if (fd == -1)
        {
        perror("Error opening file");
        exit(EXIT_FAILURE);
        }
    dos_getftime(fd,&date,&time);
    d = date & 0b11111;
    m = (date >> 5)  & 0b1111;
    y = ((date >> 9) & 0b1111111) + 1980;
    s = (time & 0b11111)*2;
    mi = (time >> 5)  & 0b111111;
    h = (time >> 11) & 0b11111;
    close(fd);
    printf("temp.fil date = %02d/%02d/%02d\n",m,d,y);
    printf("         time = %02d:%02d:%02d\n",h,mi,s);
    if (unlink("temp.fil") == 0)
        printf("\nTemporary file successfully deleted\n");
    else {
        perror("Error deleting file:");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise returns the DOS error code.

See Also: DOS package, dos_getftime

dos_settime
Usage:
#include <dos.h>
int dos_settime(struct dos_time_t *time);

Description:
Sets the current system via a call to DOS function 0x2d (45) to the
values passed in the structure pointed to by time. The format of this
structure is as follows:

struct dos_time_t
{
    char    hour;           /* hours (0-23)       */
    char    minute;         /* minutes (0-59)     */
    char    second;         /* seconds (0-59)     */
    char    hsecond;        /* seconds/100 (0-99) */
}

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    struct dos_time_t time;
    char oh;

    dos_gettime(&time);
    printf("Time is %02d:%02d:%02d:%02d\n",
            time.hour, time.minute, time.second, time.hsecond);

    oh = time.hour;
    time.hour = 4;
    dos_settime(&time);
    dos_gettime(&time);
    printf("Time is %02d:%02d:%02d:%02d\n",
            time.hour, time.minute, time.second, time.hsecond);

    time.hour = oh;
    dos_settime(&time);
    dos_gettime(&time);
    printf("Time is %02d:%02d:%02d:%02d\n",
            time.hour, time.minute, time.second, time.hsecond);
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise returns the DOS error code if
              the time passed was invalid.

See Also: DOS package, dos_settime, dos_setdate dos_getdate

dos_set_verify
Usage:
#include <dos.h>
void dos_set_verify(int on_off);

Description:
Sets automatic read-after-write verification on (1) or off (0). This
function has the same effect as the MS-DOS commands VERIFY ON and
VERIFY OFF.

dup dup2
Usage:
#include <io.h>
int dup(int fd);
int dup2(int fd1, int fd2);

Description:
The functions dup and dup2 allow more than one file handle to be
associated with a currently open file. Once associated, any of the file
handles can be used to carry out operations on the file. All such file
handles use the same file pointer. The access mode for the file is
unchanged.

The function dup creates a new file handle and associates it with the
file already connected to fd.

The function dup2 associates fd2 with fd1 so that it refers to the file
already connected to that handle.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

const int stdout_h = 1;

int main() {
    int oldout, newout;
    oldout = dup(stdout_h);
    if (oldout == -1) {
        perror("dup failed");
        return EXIT_FAILURE;
    }
    newout = open("temp.fil");
    if (dup2(newout,stdout_h) == -1) {
        perror("dup2 failed");
        return EXIT_FAILURE;
    }
    fprintf(stdout,"This goes to the file temp.fil\n");
    fflush(stdout);
    fprintf(oldout,"This goes to stdout\n");
    if (dup2(stdout_h,oldout) == -1) {
        perror("Can't restore stdout");
        return EXIT_FAILURE;
    }
    fprintf(stdout,"This goes to stdout\n");
    return EXIT_SUCCESS;
}

Return Value: dup returns the new file handle, otherwise -1 if an error
              occurred. dup2 returns 0 if successful, otherwise -1.
              Both functions set errno if an error occurs.

See Also: close, creat, open

ecvt
Usage:
#include <stdlib.h>
char *ecvt(double val,int ndig,int *pdecpt,int *psign);

Description:
Converts the double value val into a string and returns a pointer to that
string. The number of digits to be created is given by ndig. The digit
string is rounded if the actual number of digits exceeds ndig. The string
is padded with 0 s if ndig is greater than the actual number of digits.
As only digits are stored in the string, the position of the decimal
point relative to the left of the first digit in the string is stored in
the integer pointed to by *pdecpt. If *pdecpt is negative, the decimal
point is positioned that many places to the left of the string. Into
*psign is stored 0 if val >= 0, else a non-zero value.

 The string is written into a statically allocated area, shared with
 fcvt and printf, which is reused at each call.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *buffer;
    int dec, sign;

    buffer = ecvt(98.69138432, 5, &dec, &sign);
    printf("buffer = \"%s\", decimal = %d, sign = %d\n",
            buffer,dec,sign);
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the string of digits, which is
              overwritten by each call to ecvt, fcvt or printf.

See Also: fcvt, sprintf

The EMM Package
The EMM package is provided as an alternative to the __handle pointer
system for the programmer who requires more control of the use of
expanded memory by an application. The EMM package can be utilized at the
same time as the __handle system but the two should be kept separate. The
following discussion will be useful to programmers whichever system they
intend to use.

The current implementation only uses the facilities of EMS 3.2 to ensure
the widest possible compatibility. Applications written using the EMM
package or the __handle pointer system are therefore compatible with
expanded memory managers for both EMS 3.2 and the newer EMS 4.0, as well
as with the EMS facilities within MS-DOS 4.x.

What is an Expanded Memory System?

Expanded memory is a system for real mode MS-DOS which gives access to up
to 8 Mb (EMS 3.2) of bank switched memory. It is not required when using
the ZPM or DOSX extenders. Blocks of the expanded memory are overlaid on
a region of conventional memory, known as a page frame, and swapped in
and out of the normal addressing space, as needed. When a block of
expanded memory is swapped into the page frame it can be used to store
and retrieve data just as if it were conventional memory. Data stored
within the blocks is retained even when they are not swapped in.

An expanded memory system normally consists of two components, an
expansion board containing extra memory as well as some special control
chips, and an MS-DOS device driver known as the Expanded Memory Manager
(EMM). However, there are a number of other methods of implementing
expanded memory. Some software only systems are designed to emulate
expanded memory in the 16 Mb address space of 80286 based computers
(known as extended memory). There are also systems that emulate expanded
memory using hard disk storage. These software only systems do not
support some of the facilities available in the hardware based
implementations. For example, data aliasing, that is the mapping of the
same expanded memory page to more than one physical page, cannot be
supported. Another system which has appeared, also uses extended memory
as expanded memory, except that the facility is built into the hardware
of the computer, this type can sometimes support data aliasing. Finally
the 80386 chip has the ability to manage expanded memory built in, and
most 80386 based systems are designed to allow this.

How Expanded Memory Works

An expanded memory system normally sets aside a page frame in the
nominally "unused" area of 8086 address space which lies between the top
of the video display memory (768K) and the 1 Mb address limit. In version
3.2 of the EMS this area has a fixed length of 64 kb and is arranged to
start at a segment boundary. Different board manufacturers use different
absolute addresses for the start of their page frames, but this address
is always fixed at start up either by board switches or by the device
driver command line. (EMS version 4.0 allows the page frame to be any
length between 64 kb and 176 kb and allows for the start of the page
frame to be changed by software during program execution.)

It should be noted that although the memory addresses between 768 kb and
1 Mb are normally unused in most systems, certain hardware add ons such
as network boards, or specialist display boards may use this address
space and clash with EMS boards. It is sometimes possible to alleviate
this situation by relocating the page frame, provided there is a
sufficiently large (64 kb for EMS 3.2) free area in the 768 kb to 1 Mb
address space that is unused.

The page frame is normally split up into 16 kb blocks, known as physical
pages. Thus a 64 kb page frame consists of 4 physical pages. Access to
expanded memory is then achieved via the Expanded Memory Manager, by the
use of hardware registers in the expanded memory board or a software
simulation of these registers. These registers are used to "map" 16 kb
blocks of expanded memory into the address space of the available
physical pages. The 16 kb expanded memory page can then be accessed by
the microprocessor reading and writing to memory addresses which are
contained within that physical page.

Taking the example of an Expanded Memory Manager which uses a 64 kb page
frame starting at the hex address 1e00:0000 (in segment:offset notation).
The EMM might be asked to map the first 16 kb block of expanded memory
(this is known as a logical page) into the first physical page in the
page frame. The net result of this is that the 1st logical page of
expanded memory now has the effective address of 1e00:0000 through
1e00:3fff. The application can then store and retrieve data from this
block of expanded memory, as if it were any other block of memory.
However, if the application program then requests the memory manager to
map a different block of expanded memory into this physical page, any
data stored to the previous page will no longer be found. The data is not
lost, however, because any read or write operations are now affecting a
totally different block of memory, which can be used independently of the
first block. The application could for instance then ask for the original
1st logical page to be mapped back not into the first physical page in
the page frame, but into the second physical page at memory addresses
1e00:4000 through 1e00:7fff. Any data previously stored in this page of
expanded memory can then be retrieved using a memory address which is 16
Kb higher than that to which it was originally written.

Obviously, with a 64 kb page frame it is possible to have more than one
page of expanded memory mapped into the microprocessor's address space at
any one time. The term used to describe the relationship between physical
pages within the page frame and the logical pages which are using the
address space of those physical pages (mapped in) is known as the mapping
context. The mapping context is maintained for you by the Expanded Memory
Manager once you have established it with the appropriate expanded memory
function calls and it modifies this context when requested to by further
function calls as your application progresses. EMS version 3.2 allows a
maximum of 8 Mb of expanded memory to be utilized whereas version 4.0
allows up to 32 Mb (2048 logical pages) to be made available to
applications or the operating system.

As mentioned previously, applications gain access to expanded memory
through the Expanded Memory Manager. This is an MS-DOS device driver
which is normally supplied with the expanded memory hardware, or with the
computer if the expanded memory hardware is built in. The usual way of
installing such a device driver is to place it in the config.sys file.

The EMM installs itself onto one of the 8086 interrupt vectors, interrupt
0x67 and this vector provides the application software with access to the
Expanded Memory Manager via the 8086 instruction int. From the point of
view of the programmer therefore, access to the EMM can be achieved
through the standard library functions int86 and int86x. This requires
the programmer to know exactly the register format required by the
Expanded Memory Manager for each EMS function and also involves a speed
penalty since int86 and int86x are general purpose functions designed to
cope with a wide variety of different situations. Obviously, where memory
access to data is concerned, any loss of speed can have a detrimental
effect on the performance of an application. For these reasons the
pre-written access functions provided in the EMM package are all hand
coded in assembler.

If you are using the EMM functions, it is important to note that when the
program exits, EMM pages that are allocated are not automatically freed,
in the same way regular allocated memory is. It is therefore important to
find all routes by which the program can be terminated, and add in a call
to free up and terminate use of EMM pages. The ways a program can
terminate are:

1. Return from main().

2. Calling exit().

3. Calling _exit(), _assert(), abort() or raise(SIGABRT).

4. Ctrl-C or Ctrl-Break.

5. Heap corruption or floating point not loaded errors from the runtime
library.

Case 4 can only be handled by intercepting the control break interrupt
(0x23). Case 5 is a program crash anyway.

The symptoms of not freeing up EMM memory are that programs run later
will not find any available EMM pages to allocate. This will persist
until a program is run that frees up EMM, or the system is rebooted. If
you are using EMM via handles, this is already taken care of by the
runtime library. Cases 1 and 2 are handled by setting up a static
destructor. Case 4 is done by chaining into the control break interrupt.
Case 3 is not dealt with.

The following outline shows how a typical application might use expanded
memory:

1. The application tests whether an Expanded Memory Manager is installed.

2. It determines whether there are enough expanded memory pages available
for the application's purposes.

3. The EMM is requested to allocate the required number of expanded
memory (logical) pages to the application. The EMM supplies the
application with a unique EMM handle, which the application uses to refer
to its allocated pages.

4. The base address of the various physical pages is obtained from the
EMM so that the application knows which memory addresses to use to access
the expanded memory.

5. Some of the expanded memory (logical) pages are mapped into the
physical pages within the page frame.

6. Data is written to and read from these logical pages, just as though
it were being written to or read from conventional memory.

7. Steps 5 and 6 are repeated as necessary by the application.

8. When the application is finished using expanded memory, it returns the
expanded memory pages to the EMM pool before exiting (otherwise other
applications will be unable to use this memory).

9. The application terminates.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <emm.h>

#define HANDLES 4

/* chkout: make sure an EMM supervisor is installed. */
void chkout(void)
{
    int i, version;
    float ver_no;

    if (emm_init()) {
        printf("Unable to initiate EMS driver\n");
        exit(EXIT_FAILURE);
    }

    version = emm_getversion();
    ver_no = version/16+version%16/10.0;

    printf("EMS driver detected, version %1.1f\n",ver_no);

    printf("\tlogical page\t\tsegment\n");
    for (i = 0;i < 4;i++) {
        printf("\t%d\t\t\t%lp\n",i,emm_physpage(i));
    }
    printf("\n");
}

/* check that allocation worked */
void check_aloc(void)
{
    int i, noh;
    struct emm_handle_s *hp;

    noh = emm_gethandlecount();

    if ((hp = calloc(noh, sizeof(struct emm_handle_s))) == NULL) {
        printf("Insufficient Memory:function check_aloc\n");
        exit(EXIT_FAILURE);
    }

    emm_gethandlespages(hp);

    printf("\thandle no.\t\tpages\n");
    for (i = 0; i < noh; i++) {
        printf("\t%d\t\t\t%d\n",hp[i].handle,hp[i].pages);
    }
    printf("\n");
}

use_emm(unsigned h, int logical)
{
    char message[128], *s;
    char far *src, far *dst;

    src = emm_physpage(0);
    dst = emm_physpage(1);
    printf("Writing string to physical page 0 at %lp\n", src);
    sprintf(message,"Hello, from physical page 1 at %lp", dst);

    emm_maphandle(h,logical,0);
    s = message;
    while (*s)
        *src++ = *s++;
    printf("Reading String from EMM buffer:\n");

    emm_maphandle(h,logical,1);
    s = message;
    while (*s)
        *s++ = *dst++;
    printf("Handle %d message ='%s'.\n",h,message);
}

int main()
{
    unsigned i, usedp, thandle[HANDLES];

    chkout() ;
    printf("No. of active handles is %d \n", emm_gethandlecount());

    for (i=0;i<HANDLES;i++) {
        /* Take half of what is available */
        usedp = (emm_getunalloc()+1)>>1;
        thandle[i] = emm_allocpages(usedp);
        printf("%d pages allocated to handle %d\n", usedp, thandle[i]);
    }
    printf("No. of active handles is %d \n", emm_gethandlecount());
    printf("Total size is %d pages\n",emm_gettotal());
    printf("Free size is %d pages\n",emm_getunalloc());

    check_aloc();
    use_emm(thandle[0],0);

    for (i=0;i<HANDLES;i++) {
        emm_deallocpages(thandle[i]);
        printf("[%d] H=%d freed\n",i,thandle[i]);
    }
    printf("Total size is %d pages\n",emm_gettotal());
    printf("Free size is %d pages\n",emm_getunalloc());
    printf("Done with EMM test.\n");
    emm_term();
    return EXIT_SUCCESS;
}

emm_allocpages
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h >
int emm_allocpages(unsigned no_pages);

Description:
This routine requests the expanded memory manager to allocate the
required number of expanded memory (logical) 16Kb pages. The number of
pages to be allocated should not exceed the number of free pages
remaining, otherwise an error will occur. Use emm_getunalloc to check the
number of free pages available.

Return Value: emm_allocpages returns a unique handle allocated by the
              Expanded Memory Manager. If there are no handles available,
              a fatal error will occur.

See Also: emm_getunalloc, emm_deallocpages

emm_deallocpages
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_deallocpages(handle);

Description:
This routine requests the Expanded Memory Manager to free (deallocate)
the expanded memory pages associated with the EMM handle handle.

See Also: emm_allocpages, emm_term

emm_gethandlecount
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
int emm_gethandlecount(void);

Description:
This routine asks the Expanded Memory Manager how many EMM handles are
currently active. The operating system is allocated handle 0, and this
handle is always active. Thus the minimum number of active handles is 1.

Return Value: Returns the number of active handles (minimum 1).

See Also: emm_gethandlespages

emm_gethandlespages
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
int emm_gethandlespages(struct emm_handle_s *p);

Description:
This routine returns the number of pages currently allocated to each of
the active EMM handles. It is passed a pointer to an array of structures
of type emm_handle_s (defined in emm.h).

Return Value: It returns zero if successful, otherwise non-zero.

See Also: emm_gethandlecount

emm_getpagemap
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_getpagemap(void *pmptr);

Description:
This routine requests the Expanded Memory Manager to store the current
page mapping context, into a buffer supplied by the calling function. No
EMM handle is required (unlike emm_savepagemap). The size of the buffer
needed to store this information can be obtained from emm_getpagemapsize.

See Also: emm_setpagemap, emm_getpagemapsize, emm_savepagemap

emm_getpagemapsize
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
unsigned emm_getpagemapsize(void);

Description:
This routine is used to obtain the size of the buffer needed by the
functions emm_getpagemap, emm_setpagemap and emm_getsetpagemap.

Return Value: The size of the buffer required.

See Also: emm_setpagemap, emm_setgetpagemap, emm_getpagemap

emm_getsetpagemap
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_getsetpagemap(void *dst, void *src);

Description:
This routine requests the Expanded Memory Manager to store the current
page mapping context, into the buffer dst supplied by the calling
function and then to set the mapping context using the new values
provided in the buffer src. This is the equivalent of doing an
emm_getpagemap(dst) followed by an emm_setpagemap(src). No EMM handle is
required (unlike emm_savepagemap). The size of the buffer needed to store
this information can be obtained from emm_getpagemapsize.

See Also: emm_setpagemap , emm_getpagemapsize, emm_getpagemap

emm_gettotal
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
unsigned emm_gettotal(void);

Description:
This routine obtains the total number of 16Kb logical pages of expanded
memory which are present. Some of these pages may already be allocated.
Use emm_getunalloc to get the number of free (unallocated) pages.

Return Value: Returns the total number of 16Kb logical pages which are
              present.

See Also: emm_getunalloc

emm_getunalloc
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
unsigned emm_getunalloc(void);

Description:
This routine obtains the number of 16Kb logical pages of expanded memory
which are currently free and available for allocation. Use this to find
out how many pages are available before calling emm_allocpages.

Return Value: Returns the number of free (unallocated) pages.

See Also: emm_gettotal, emm_allocpages

emm_getversion
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
int emm_getversion(void);

Description:
Obtains the version number of the Expanded Memory Manager software.

Return Value: Returns the version number of the Expanded Memory Manager
              as two hexadecimal digits in the form 0x32 where 3 is the
              major version and 2 the minor.

See Also: emm_init

emm_init
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
int emm_init(void);

Description:
This routine tests for the presence of the EMM driver as recommended in
the Expanded Memory Specification. The technique of tracing through the
interrupt vector to find the name of the device driver is adopted since
it can be safely used by interrupt handlers and memory resident software.

Return Value: Returns zero if an Expanded Memory Manager is installed or
              non-zero if one is not installed, or is not operating
              correctly.

See Also: emm_term

emm_maphandle
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_maphandle(int handle, unsigned logical, unsigned physical);

Description:
This routine requests the Expanded Memory Manager to map the logical
page, logical, which belongs to handle onto the specified physical page
in the EMM page frame.

See Also: emm_allocpages

emm_physpage
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void far *emm_physpage(int page);

Description:
This routine gets the address of the start of the specified EMM page.
page should be in the range 0 to 3.

Return Value: A far pointer to the base address of page, or a NULL pointer
              if an error occurred.

emm_restorepagemap
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_restorepagemap(int handle);

Description:
This routine requests the Expanded Memory Manager to restore a mapping
context for the specified handle which has been saved previously with
emm_savepagemap. Only one mapping context can be saved and restored for
each handle.

See Also: emm_savepagemap

emm_savepagemap
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_savepagemap(int handle);

Description:
This routine requests the Expanded Memory Manager to save the current
logical/physical page mapping context for the specified handle. The
context is restored using emm_restorepagemap. Only one such context can
be saved for each handle. There are a limited number of such contexts
that can be saved, and therefore any application should strive to require
no more than 1. This function will generate a fatal error if there is no
space to save the mapping context.

See Also: emm_restorepagemap

emm_setpagemap
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_setpagemap(void *pmptr);

Description:
This routine requests the Expanded Memory Manager to load a new page
mapping context from a buffer supplied by the calling function. No EMM
handle is required (unlike emm_restorepagemap).

See Also: emm_setpagemap , emm_getpagemapsize, emm_savepagemap,
          emm_getsetpagemap

emm_term
Note-This function is not available under OS/2 or the ZPM or DOSX
extenders.

Usage:
#include <emm.h>
void emm_term(void);

Description:
This routine terminates the use of the EMM package.

See Also: emm_init, emm_deallocpages

_exec_instancehandleget _exec_showget _exec_showreset _exec_showset

Usage:
#include <windows.h>
HANDLE _exec_instancehandleget(void);
ushort _exec_showget(void)
void _exec_showreset(void)
void _exec_showset(void)

Description:
These functions are only available under Microsoft Windows. They are used
when spawning a child process under Windows.

_exec_instancehandleget is used to obtain the instance handle of a
spawned process. _exec_handleset sets the SHOW parameter to be used when
spawning programs under Windows. _exec_showget returns the current value
of the SHOW parameter. _exec_showreset sets the show parameter back to
SW_SHOW.

Return Value: _exec_instancehandleget returns the instance handle of the
              spawned process, or 0 if there is none available.

              _exec_showget returns the current setting of the SHOW
              parameter that will be used when spawning programs.

See Also:     spawn, system

execl execv execle execlp execvp execve
Usage:
#include <process.h>
#include <errno.h>  /* for error checking only */
int execl(const char *path,const char *arglist,...)
int execv(const char *path,const char *argv)
int execlp(const char *file,const char *arglist,...)
int execvp(const char *file,const char *argv)

Description:
The exec functions load and execute new child processes. When the call is
successful, the child process is placed in the memory previously occupied
by the calling process. Sufficient memory must be available for loading
and executing the child process. All of the functions in this family use
the same exec function the letter(s) at the end determine the specific
variation:

    Letter              Variation
         
      p                 Uses the PATH environment variable to
                        find the file to be executed.

      l                 Command line arguments are passed
     (lower case L)     individually to the exec function.

      v                 Command line arguments are passed to
                        the exec function as an array of pointers.

Example:
#include <errno.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
    char *args[4];
    int result;
    args[0] = "arg0";
    args[1] = "arg1";
    args[2] = "arg2";
    args[3] = NULL;

    switch (argv[1][0])
    {
        case '1':
            execl("myprog","arg0","arg1","arg2",NULL);
            break;
        case '2':
            execlp("myprog","arg0","arg1","arg2",NULL);
            break;
        case '3':
            execv("myprog",args);
            break;
        case '4':
            execvp("myprog",args);
            break;
        default:
        printf("Enter a number between 1 and 4 on "
                                        "the command line\n");
    }
    printf("Process myprog not exececuted.\n");
    return EXIT_FAILURE;
}

Return Value

The exec functions do not normally return to the calling process. If an
exec function returns, an error has occurred and the return value is -1.
In this case errno is set to one of the following values:

E2BIG            The argument list exceeds the system limit.

EACCES           The specified file has a locking or sharing violation

ENOENT           The file or path name not found.

ENOMEM           Not enough memory is available to execute the child
                 process or the available memory has been corrupted.

_exit
Usage:
#include <process.h>
#include <stdlib.h>
void _exit(int exitstatus);

Description:
_exit closes all output files and returns to the operating system with an
exit status given by exitstatus. It does not call the static destructors
or flush the buffers, but immediately returns to the operating system.
exit is preferred over _exit for C++ programs.

exitstatus is normally EXIT_SUCCESS to indicate a normal end of program
and EXIT_FAILURE to indicate an error. Only the lower order byte of
exitstatus is returned to the parent process. The exit status can be
referenced by the name ERRORLEVEL in batch files and the spawn return
values.

Example:
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
FILE *fp;
if(argc > 1)
    {
        fp = fopen(argv[1],"r");
        if(fp == NULL)
        {
            fprintf(stderr,"Can't open file \"%s\"\n", argv[1]);
            _exit(EXIT_FAILURE);
        }
    }
else
    {
        fprintf(stderr,"No file specified\n");
        _exit(EXIT_FAILURE);
    }
}

See Also: abort, exit, spawn

exit
Usage:
#include <stdlib.h>
void exit(int exitstatus);
ANSI

Description:
exit calls functions logged by atexit, all static destructors (for C++
programs), flushes all output buffers, closes all output files and
returns to the operating system with an exit status given by exitstatus.
exit is the preferred function for C++ programs.

exitstatus is normally a EXIT_SUCCESS to indicate a normal end of program
and EXIT_FAILURE to indicate an error. Only the lower order byte of
exitstatus is returned to the parent process. The exit status can be
referenced by the spawn return values.

Example:
#include <stdlib.h>
#include <stdio.h>

int main (int argc, char *argv[])
{
    FILE *fp;

    if (argc > 1) {
        fp = fopen(argv[1],"r");
        if (fp == NULL) {
            fprintf(stderr,"Can't open \"%s\"\n", argv[1]);
            exit(EXIT_FAILURE);
        }
    }
    else {
        fprintf(stderr,"No file specified\n");
        exit(EXIT_FAILURE);
    }
    return (EXIT_SUCCESS);
}

See Also: abort, _exit, spawn

exit_popstate exit_pushstate
Usage:
#include <exitstat.h>
int exit_popstate(int a);
void exitpushstate(void)

Description:
These functions push and pop the program exit frame so that exit and
atexit return points can be intercepted and controlled. This is useful in
Microsoft Windows programming and for turning a stand-alone program in to
a subroutine. A maximum of 16 states can be saved.

exit_pushstate will set the integer variable passed to it by reference
to the return state + 1, sent via any exit() statement encountered before
a matching exit_popstate has been reached. If an exit() is encountered,
an exit_popstate is automatically executed and should not be performed
again. The atexit() function list contains no functions after an
exit_pushstate is performed, even if there had been previous calls to
atexit(). These functions will be returned to the atexit() function list
when a matching exit_popstate or an exit() is reached.

Example 1:
/* example usage: */

int  a;

if (exit_pushstate(a) == 0)
{
    sub();              // your functions that may call exit
    exit_popstate();
                        // only call if exit_pushstate returns 0
} else {
    --a;                // a == return value now,
}                       // exit_pushstate always returns exit
                        // value + 1
    ...

void sub()
{
    ...
    exit(2);            // rather than exit program,
}                       // this will 'call up' to exit_pushstate
                        // and then drop down to the else case
                        // with a == 3

Example 2: atexit chaining
/* example usage: */

void goodbye_world(void)
{
    printf("goodbye\n");
}

void hello_world(void)
{
    printf("hello\n");
}

void foo(void)
{
    int  a;

    atexit(goodbye_world);
    if (exit_pushstate(a) == 0) {
        atexit(hello_world);
        sub();                  // your functions that may call exit
        exit_popstate();        // only call if exit_pushstate returns 0
    } else {
        --a;                    // a == return value now,
    }                           // exit_pushstate always returns
                                // exit value + 1
exit(1);                        // this exit will exit the program
                                // entirely but before the exit occurs
                                // goodbye_world will be executed
}

void sub()
{
    ...
    exit(2);                    // rather than exit program,
}                               // this will 'call up' to
                                // exit_pushstate
                                // and then drop down to the
                                // else case with a == 3
                                // before the call up occurs
                                // however, the hello_world
                                // function will be executed

Return Value: exit_pushstate will set the integer variable passed to it
              by reference to the return state + 1, sent via any exit()
              statement encountered before a matching exit_popstate has
              been  reached.

exp
Usage:
#include <math.h>
double exp (double x);
ANSI

Description:
exp generates the natural exponent of the argument x.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double dnum, xpnt;
    dnum = 3.1415926;
    xpnt = exp(dnum);
    printf("The exp(%f) = %f\n",dnum,xpnt);
    return EXIT_SUCCESS;
}

Return Value: Returns the real exponential function e to the x.
              If overflow, errno is set to ERANGE and HUGE_VAL is
              returned. If underflow, exp returns 0 and does not set
              errno. The function matherr can be used to modify the
              behavior on error.

See Also: log, pow, sqrt

fabs
Usage:
#include <math.h>
double fabs(double x);
ANSI

Description:
Returns the absolute value of the floating point argument x.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double numbr, absval;
    numbr = -1.0;
    absval = fabs(numbr);
    printf("The fabs of (%f) is %f\n",numbr,absval);
    return EXIT_SUCCESS;
}

Return Value: Returns the absolute value of its double argument.

See Also: abs, labs

The Far Package
The Far package is a set of memory allocation functions that allow access
to the far heap, these functions are direct hooks into DOS and are much
slower than malloc, etc. They can also prevent the heap from expanding
fully in S, M, T models, so you should not use _okbigbuf = 0 in your
program.

The advantages of these functions are that they give access to the whole
of the available RAM in all memory models and memory blocks larger than
64k can be allocated.

It is necessary to use far pointers to access memory blocks allocated
with the far... functions. Use huge pointers for blocks larger than 64k.

See Also: Functions with the prefix far.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
char far *memblock;
long allocate = 65000;
    printf("%lu bytes memory free\n",farcoreleft());
    memblock = farmalloc(allocate);
    if(memblock == NULL) {
        printf("failed to allocate memory-block\n");
        exit(EXIT_FAILURE);
    }
    printf("%lu bytes allocated, ",allocate);
    printf("%lu bytes memory free\n",farcoreleft());
    allocate /= 2;
    memblock = farrealloc(memblock, allocate);
    printf("memory now reallocated to %lu bytes,", allocate);
    printf("%lu bytes memory free\n",farcoreleft());
    farfree(memblock);
    printf("memory-block now freed, ");
    printf("%lu bytes memory free\n",farcoreleft());
    return EXIT_SUCCESS;
}

farcalloc
Note-This function is not implemented for the X and P memory models.

Usage:
#include <dos.h>
void far *farcalloc(unsigned long numelems, unsigned long size);

Description:
farcalloc allocates memory from the far heap for an array containing
numelems elements, each size bytes long.

This function is very similar to calloc. In the small and medium memory
models calloc allocates memory within the near heap, whereas farcalloc
allocates memory in the far heap. In the large memory model, both
functions allocate memory from the far heap.

Return Value: farcalloc returns a far pointer to the allocated memory
              block, or NULL if not enough space exists.

See Also: calloc, farcoreleft, farfree, farmalloc, farrealloc, free,
          malloc, realloc

farcoreleft
Note-This function is not implemented for the X and P memory models.

Usage:
#include <dos.h>
long farcoreleft(void);

Description:
farcoreleft returns the size of largest contiguous block of unused memory
in the far heap.

Return Value: farcoreleft returns the largest contiguous block of memory
              in the far heap which has not been used, between the highest
              allocated block and the end of memory. This is the amount of
              memory still available for use by farmalloc or farcalloc.

See Also: calloc, farcalloc, farfree, farmalloc, farrealloc, free,
          malloc, realloc

farfree
Note-This function is not implemented for the X and P memory models.

Usage:
#include <dos.h>
void farfree(void far *memblock);

Description:
farfree releases a memblock of previously allocated far memory pointed to
by the far pointer memblock. The memblock argument must point to a memory
block previously allocated by farcalloc, farmalloc or farrealloc.

See Also: calloc, farcalloc, farcoreleft, farmalloc, farrealloc, free,
          malloc, realloc

farmalloc
Note-This function is not implemented for the X and P memory models.

Usage:
#include <dos.h>
void far *farmalloc(unsigned long sizebytes);

Description:
farmalloc allocates a memory block sizebytes long from the far heap.

Return Value: farmalloc returns a far pointer to the allocated memblock,
              or NULL if not enough space exists.

See Also: calloc, farcalloc, farcoreleft, farfree, farrealloc, free,
          malloc, realloc

farrealloc
Note-This function is not implemented for the X and P memory models.

Usage:
#include <dos.h>
void far *farrealloc(void far *memblock, unsigned long newsize);

Description:
farrealloc adjusts the size of a previously allocated memblock to newsize.

Return Value: farrealloc returns the address of the reallocated memblock.
              This may be different from the original memory block.

See Also: calloc, farcalloc, farcoreleft, farfree, farmalloc, free,
          malloc, realloc

fclose
Usage:
#include <stdio.h>
int fclose(FILE *fp);
ANSI

Description:
fclose closes the file associated with the stream fp. Any data in the
output buffer for fp is flushed (written to the file) before closing.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fp = fopen("file.dta","r");
    if (fp == NULL) {
        printf("Datafile not opened\n");
        return EXIT_FAILURE;
    }
    else {
        fclose(fp);
        printf("File file.dta closed using fclose\n");
    }
    return EXIT_SUCCESS;
}

Return Value: fclose returns 0 if the stream successfully closed.
              A -1 is returned on error.

See Also: close, fopen, freopen

fcloseall
Usage:
#include <stdio.h>
int fcloseall();

Description:
fcloseall closes all open streams/files except stdin and stdout. Any data
in the I/O buffers is flushed before closing.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x;
    FILE *fp1, *fp2;
    fp1 = fopen("file1.dta","r");
    if (fp1 == NULL)
        {
        printf("Datafile not opened\n");
        exit(EXIT_FAILURE);
        }
    fp2 = fopen("file2.dta","r");
    if (fp2 == NULL)
        {
        printf("Datafile not opened\n");
        exit(EXIT_FAILURE);
        }
    x = fcloseall();
    printf("fcloseall closed %d streams\n",x);
    return EXIT_SUCCESS;
}

Return Value: fcloseall returns the number of streams closed.

See Also: close, fclose, fopen, freopen

fcvt
Usage:
#include <process.h>
char *fcvt (double val, int nfrac, int *pdecpt, int *psign);

Description:
Converts the double value into a string and returns a pointer to that
string. nfrac specifies the number of digits that appear after the
decimal point. The digit string is rounded. The position of the decimal
point relative to the left of the first digit in the string is stored in
*pdecpt. If *pdecpt is negative, the decimal point is positioned that
many places to the left of the string. Into *psign is stored 0 if val >=
0, else a non-zero value. The string is written into a statically
allocated area, shared with ecvt and printf, which is reused at each
call.

Example:
#include <stdio.h>
#include <process.h>
#include <stdlib.h>

int main()
{
    char *buffer;
    int dec, sign;
    buffer = fcvt(98.69138432, 5, &dec, &sign);
    printf("buffer = \"%s\", decimal = %d, sign = %d\n",
           buffer, dec, sign);
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to a static string of digits which is
              overwritten by each call to ecvt, fcvt or printf.

See Also: ecvt, sprintf

fdopen
Usage:
#include <io.h>
FILE *fdopen(int fd, char *mode);

Description:
This function allows the buffering of a file which has already been
opened as an unbuffered file using open(). The handle of the already
opened file is passed as the first argument and the file mode as the
second. If the specified mode is an append mode, the file pointer is
positioned at the end of the file, otherwise the file pointer is
positioned at the beginning of the file. If the specified mode is
a write mode, the file is truncated.

Note-No checking is done to assure that the mode of the buffered file is
compatible with the rwmode of the unbuffered file. Incompatibility of
file modes will give undefined results.

Example:
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int fd;
    FILE *fp;
    char line[81];

    if ((fd = open("stdio.h", O_RDONLY)) == -1) {
        printf("Can't open stdio.h\n");
        return EXIT_FAILURE;
    }
    if ((fp = fdopen(fd, "r")) == NULL) {
        printf("Can't fdopen stdio.h\n");
        return EXIT_FAILURE;
    }
    fgets(line, 80, fp);
    printf("The first line of stdio.h is:\n%s\n",line);
    return EXIT_SUCCESS;
}

Return Value: A FILE pointer to opened file

See Also: open, fopen

feof
Usage:
#include <stdio.h>
int feof(FILE *fp);
ANSI

Description:
feof determines if the stream fp is at the end of file. After the EOF
indicator is set no further read operations are allowed.

Example:
#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE 128
char buffer[BUFSIZE];

int main()
{
    FILE *fp;
    fp = fopen ("file.dat", "r");
        {
            while ( !feof(fp) )
                fgets(buffer, BUFSIZE, fp);
        }
    printf("Done reading file, EOF found\n",buffer);
    return EXIT_SUCCESS;
}

Return Value: Non-zero (EOF flag set) if current position is end. No read
              operations are allowed after the flag is set. The flag is
              cleared if rewind, fseek or file is closed. 0 if the flag
              is clear.

See Also: clearerr, ferror

ferror
Usage:
#include <stdio.h>
int ferror(FILE *fp);
ANSI

Description:
ferror checks the error flag on the stream fp. The error flag remains set
until a clearerr, rewind or fseek is issued or the stream is closed. No
read or write operations can be carried out until this flag is cleared.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    if ( (c = fgetc(stdin)) == EOF)
        if (ferror(stdin))
            {
                fprintf(stderr,"Read error\n");
                clearerr(stdin);
                return EXIT_FAILURE;
            }
    printf("No error\n");
    return EXIT_SUCCESS;
}

Return Value: Returns non-zero if the error flag is set, otherwise it
              returns a zero.

See Also: clearerr, feof

fflush
Usage:
#include <stdio.h>
int fflush(FILE *fp);
ANSI

Description:
Flushes the buffer associated with stream fp. If the file is opened for
writing, the buffer is written. If the file is opened for reading, the
buffer is cleared.

The fflush function may be used to force the data in the file buffer to
be written to the file before the buffer becomes full. Similarly data
read from a file is input a buffer full at a time. Only after every
character has been processed does another file access occur. The fflush
function may be used to clear the buffer and thus force the next read
operation to occur.

Example:
#include <stdio.h>
#include <stdlib.h>

FILE *fp;

int main()
{
    if((fp = fopen("file.dat","w"))==NULL)
         return EXIT_FAILURE;
    fflush(fp); /* flush buffer to disk to protect   */
                /* data before performing operations */
                /* that may cause system crash       */
    return EXIT_SUCCESS;
}

Return Value: fflush returns a 0 if the buffer was successfully flushed.
              EOF is returned if an error occurred.

See Also: fclose, flushall

Flash Graphics
Flash Graphics is a set of graphics routines for the IBM PC (and
compatibles) to interface to the Zortech C and C++ compilers. They are
optimized for speed and size with most of the code being written in
assembly language. Support is provided for the following display types:
Hercules, EGA (color and the monochrome modes), CGA, VGA, the IBM 8514A
and the Toshiba 3100. Specific support is provided for the high
resolution modes of some display adaptors.

The initialization routine recognizes most graphics boards and
automatically configures for the graphics board available. A manual over-
ride is possible through either an environment variable or at compile
time. There are two libraries available, which will work correctly with
all supported memory models. One is a debug library that does range
checking on most variables passed to the functions. If an error is
detected then fg_assert is called with an error message. This is to
provide some help in finding difficult to locate program bugs. There is a
small penalty paid in both size and speed with this library and so a
non-debug version is available for use with fully debugged code.

The Files fg.h and readme.fg
The header file fg.h must be included in any modules using these
functions and variables. Some of the function calls are macros and will
result in unresolved externals if the header file is not used.

Previous versions of Flash Graphics used different header files for each
operating system, causing considerable confusion. This has now been
changed so that there is only one header file for all operating systems.
It is recommended that all previously compiled Flash Graphics programs
should be recompiled with the current fg.h header file.

Zortech is committed to the continuing improvement of the Flash Graphics
package. Of necessity this means that at times the software supplied is
more up to date than the documentation. Therefore, treat any information
in the file readme.fg contained in the readme directory as authoritative.
However, there are a number of functions defined in the header file, fg.h
that are not documented. If a function is not documented either in the
manual or in the file readme.fg, then do not use it! Such functions are
liable to change, or could cause unexpected results.

Definition of Basic Coordinate System
FG uses a right-handed coordinate system with its origin at the bottom
left of the drawing area. The origin is taken as x = 0, y = 0, where x
and y are pixel coordinates.

Variable Types Defined
fg_coord_t       Type for an individual coordinate variable.

fg_box_t         Type for coordinate box. There are four coordinate
                 variables in the box, FG_X1, FG_Y1, FG_X2, FG_Y2. Boxes
                 must be normalized before being passed to the graphics
                 functions. A normalized box is one whose FG_X1
                 coordinate is less than or equal to the FG_X2 coordinate
                 and FG_Y1 coordinate is less than or equal to the FG_Y2
                 coordinate. In other words, the first point of a box is
                 always the lower left corner and the second is always
                 the upper right corner.

fg_pbox_t        Pointer to a box.

fg_const_pbox_t  Pointer to a box that will never be changed.

fg_line_t        The type for a line. Lines use the same constants for
                 indexes that boxes do, but have no need to be normalized
                 before being passed to the functions.

fg_color_t       The type for a color.

fg_pline_t       Pointer to a line.

fg_const_pline_t Pointer to a line that will never be changed.

fg_handle_t      A "handle" for a saved area of the screen. See fg_save and
                 fg_restore .

Constants Defined by FG
Constants are indicated by upper case names. These are defined in the
header file fg.h. They should always be referred to by the name and never
the value that the macro in the header file expands to. They are subject
to change in future versions of the graphics package.

Graphics Display Adaptors
Important-Not all the display types are supported under OS/2. See later
for details.

Values returned from fg_init (see description of fg_init for more
information). The global fg_display is set to the same value. fg_init
will attempt to determine which graphics device is connected. This can be
overridden at run time by using the environment variable FG_DISPLAY and
setting it to one of the values below. E.g FG_DISPLAY=HERCFULL

NULL             All graphics are routed to bit bucket

CGAHIRES         IBM CGA in 640 x 200 x 2 color mode

CGAMEDRES        IBM CGA in 320x200 x 4 color mode

EGACOLOR         IBM EGA with regular color display in 640 x 200 x 16
                 color mode

EGAECD           IBM EGA with enhanced color display in 640 x 350 x 16
                 color mode

EGALOWRES        IBM EGA with enhanced color display in 320 x 200 x 16
                 color mode

EGAMONO          IBM EGA with IBM monochrome monitor in 640 x 350 x 4
                 color mode

EVGAHIRES        Everex EVGA board in 800 x 600 x 16 color mode.

HERCFULL         Hercules monochrome in 2 display pages x 2 color mode

HERCHALF         Hercules monochrome in 1 display page x 2 colors

HERC             Hercules monochrome, fg_init to determine whether 1 or 2
                 pages

ORCHIDPROHIRES   Orchid ProDesigner VGA in 800 x 600 x 16 color mode

PARADISEHIRES    Paradise VGA in 800 x 600 x 16 color mode

TOSHIBA          Toshiba 3100 in 640 x 400 x 2 color mode

TRIDENTHIRES     Trident VGA in 800 x 600 x 16 color mode

VEGAVGAHIRES     Video 7 Vega VGA board in 800 x 600 x 16 color mode

VESA6A           VESA mode 0x6A, 800 x 600 x 16 color mode

VESA2            VESA mode 0x102, 800 x 600 x 16 color mode

VGA11            IBM VGA in 640 x 480 x 2 color mode (0x11)

VGA12            IBM VGA in 640 x 480 x 16 color mode (0x12)

VGA13            IBM VGA in mode 320 x 200 x 256 color mode (0x13)

8514A            IBM 8514A display adaptor.

Box and Line Indexes FG_X1, FG_Y1, FG_X2, FG_Y2
Used as indexes into boxes and lines, as in fg.displaybox. [FG_X1] refers
to the x coordinate of the left side of the display.

 The relationship of the FG_X? and FG_Y? indexes to the coordinates of a
 box or line within Flash Graphics is based on an origin at bottom left
 of the display context. These constants should be used to put data into
 the fg_box and line arrays rather than the absolute values to avoid
 problems with display adapters that may use a different coordinate
 system.
Masks
Mask constants are passed to nearly all functions to indicate the bits on
which to perform the desired operations. The mask only has utility on
boards that support more than two colors. For boards like the EGA which
supports 16 simultaneous colors in the high resolution mode there are 4
bits in the mask that may be utilized by the programmer in some fashion.
Whatever the board, the significant mask bits are always packed into the
low order bits.

In most cases the application will want to write to all the bit planes.
Using a value of ~0 will ensure this. Controlling which bit planes the
functions operate on is useful for:

1. If you have 2 planes (2bits/pixel), you can draw a different image on
each plane. By then changing the color map, the planes can be
independently turned on or off, creating an animation effect.

2. The cursor could be written to its own plane, thus making it
independent of the other graphics.

Writing Modes
One of the following is passed to nearly all functions to indicate the
type of operation to perform on the screen.

FG_MODE_XOR     Mode value for XORing colors on to the screen.
FG_MODE_SET     Mode value for setting colors on to the screen.

Types of Lines
One of the following values is passed to the line drawing functions to
indicate the type of line to draw.

FG_LINE_SOLID
FG_LINE_LONG_DASH
FG_LINE_MEDIUM_DOTTED
FG_LINE_DASH_DOTTED
FG_LINE_MEDIUM_DASHED
FG_LINE_DASH_W_2_DOTS
FG_LINE_SHORT_DASH
FG_LINE_DENSE_DOTTED
FG_LINE_SPARSE_DOTTED
FG_LINE_USER_DEFINED

The last of these line types, FG_LINE_USER_DEFINED, is undefined by
Flash Graphics and can be defined by the application program with
fg_setlinepattern.

The value FG_LINE_MAX is the maximum number of line types defined at one
time.

Available Colors
This is the value that must be passed to functions as arguments for the
color of lines, dots, boxes, etc. Due to the variety of graphics boards
supported no one board supplies all the following colors. Some supply
only two, Flash Graphics is defined such that there will always be at
least two of the same colors available on all boards supported.

These values are the defaults. If you change the palette (color map), the
names will no longer match the colors that they provide. If a color is
not available, it will expand to -1. These values are not valid before
fg_init is called.

FG_BLACK              Available on all systems
FG_BLUE
FG_GREEN
FG_CYAN
FG_BLUE_GREEN         Blue-green - same as cyan.
FG_RED
FG_MAGENTA
FG_PURPLE             Purple - same as magenta
FG_YELLOW
FG_WHITE              Available on all systems
FG_GRAY
FG_LIGHT_BLUE
FG_LIGHT_GREEN
FG_LIGHT_CYAN
FG_LIGHT_BLUE_GREEN   Light blue-green = light cyan
FG_LIGHT_RED
FG_LIGHT_MAGENTA
FG_BROWN
FG_LIGHT_WHITE
FG_HIGHLIGHT          Normally an intense white. This is always
                      available but may be the same as FG_WHITE
FG_BLINK              Blinking white

Public Structure
A predefined structure contains information useful to the application
program. The structure is fg, the various members are defined below.
Values of these members are garbage until fg_init is called. They are
garbage after fg_term() is called. The values (except fg.activepage and
fg.displaypage) never change between fg_init and fg_term- none of them
must ever be modified by the application.

fg.displaybox
Type:
fg_box_t fg.displaybox;

Description:
The bounding box of the display. (fg.displaybox [FG_X1],
fg.displaybox [FG_Y1]) is the coordinate of the lower left corner
of the display. (fg.displaybox [FG_X2], fg.displaybox [FG_Y2]) is the
coordinate of the upper right corner of the display.

fg.charbox
Type:
fg_box_t fg.charbox;

Description:
The bounding box of a character. (fg.charbox [FG_X1], fg.charbox
[FG_Y1]) is (0, 0). (fg.charbox [FG_X2], fg.charbox [FG_Y2]) is the
coordinate of the upper right corner of the bounding box of the character.

fg.ncolormap
Type:
long int fg.ncolormap;

Description:
The number of entries in the color map. Example values would be 64 for
the EGA board with an Enhanced Color Display, 2 for the Hercules board
and 262144 for the VGA in mode 0x13.

fg.nsimulcolor
Type:
int fg.nsimulcolor;

Description:
The number of simultaneous colors possible, 2 raised to the nth power,
where n is bits per pixel.

Example:
For the EGA board with an Enhanced Color Display this is 16 (4 bits per
pixel). For the Hercules board this is 2 (1 bit per pixel). The number of bits
per pixel is equivalent to the number of bit planes.

fg.pixelx fg.pixely
Type:
int fg.pixelx, fg.pixely;

Description:
The typical width and height of pixels in micrometers. Since the actual
monitor being used is impossible to determine with software, these
numbers are for a typical monitor used with this graphics board.

fg.numpages
Type:
int fg.numpages;

Description:
Number of display pages, referred to by 0 through (fg.numpages -1).

Example:
The EGA board with 256k of RAM installed will have 2 different pages of
graphics available which are referred to by the page numbers 0 and 1.

fg.display
Type:
int fg.display;

Description:
The type of graphics display board attached to the computer. This variable
is set to one of the constants FG_NULL, FG_EGAECD, FG_HERCFULL,
etc. as described in the constants section.

fg.activepage
Type:
unsigned fg.activepage;

Description:
Current active page to which all graphics commands are directed. The
active page is changed by the function fg.setactivepage.

fg.displaypage
Type:
unsigned fg.displaypage;

Description:
The current page being displayed on the monitor. The display page is
changed by the function fg_setdisplaypage.

fg.version
Type:
unsigned fg.version;

Description:
Contains the compile date and time of the library. If you encounter
problems with Flash Graphics please report the value of fg.version along
with the problem.

fg.msm
Type:
unsigned fg.msm;

Description:
Reports on whether the mouse functions can be used. It will be zero if no
Microsoft mouse driver is present, or the code has not been linked in. It is
non-zero if the code and driver are present.

Optional User-supplied Functions
The user of the FG module can supply alternatives to the following
functions although default versions are supplied in the libraries. The
functions themselves are described later.

fg_assert
fg_lineclip

Supported Modes
A function, fg_get_type(), has been provided to determine the type of
display present. See the individual entry for this function for details.
Currently the following modes are supported under OS/2:

    CGAHIRES        EGACOLOR
    EGAMONO         EGAECD
    VGA11           VGA12

Other modes will be added from time to time. Please refer to the file
readme.fg for up to date information on supported display modes.

Here is a complete list of boards and modes currently supported by Flash
Graphics. Again, refer to the readme.fg file for up to date information
on OS/2 support.

Hercules mono
1 or 2 display pages 720x348x2 colors.

CGA
320x200x4 colors (mode 0x03).
640x200x2 colors (mode 0x06).

IBM EGA color display
320x200x16 colors (mode 0x0D).
640x200x16 colors (mode 0x0E).

IBM EGA TTL mono monitor
640x350x4 colors (mode 0x0F).

IBM EGA enhanced color display
640x350x16 colors (mode 0x10).

IBM VGA
640x480x1 color (mode 0x11).
640x200x2 colors (mode 0x06).
640x200x2 colors (mode 0x06).
320x200x256 colors (mode 0x13).

Orchid ProDesigner multi-freq monitor
800x600x16 colors (mode 0x29).

Paradise VGA Plus multi-freq monitor
800x600x16 colors (mode 0x58).

Video 7 VEGA VGA multi-freq monitor
800x600x16 colors (mode 0x62).

VESA (multi vendor) multi-freq monitor
800x600x16 colors (mode 0x6A).
800x600x16 colors (mode 0x102).

Everex EVGA multi-freq monitor
800x600x16 colors (mode 0x70).

Toshiba T/J-3100
640x400x2 colors, note T and J.
No autodetect

Trident VGA
800x600x16 colors.

IBM 8514A
Resolution and colors 8514 dependent.

Due to the way the data is arranged in the new library, some of the old
tricks to limit code size do not work. For example, previously if you did
not call fg_init_all() but instead called fg_init_herc() you would cut
your code size by about 15 kb. This no longer works. Get round it by
creating your own function fg_init_all(), which achieves the same
results. For example:

#include <fg.h>

main ()
    {
        if (fg_init() != FG_NULL)
        {
            . . .
            fg_term();
            return 0;
        }
    else
        return 1;
    }

int fg_init_all(void)
    {
        return fg_init_herc();
    }

The above "trick" cuts the code size by about 17 kb, at the loss of
EGA/VGA etc. Of course you must make sure that a Hercules board is really
present or you will probably crash the computer. This can be achieved by
brute force like requiring users to inform the system that they have a
Hercules (or EGA, VGA, whatever) available. Alternatively call
fg_get_type() which returns the type of graphics board available. For
example, replace the fg_init_all() with the following:

int fg_init_all(void)
{
    switch (fg_get_type()) {
        case HERCHALF:
        case HERCFULL: return fg_init_herc();
                       break;
        default: return FG_NULL;
    }
}

Fonts and Flash Graphics
The extended character set (0x80 through 0xff) is available with
fg_putc() and fg_puts() for all graphics boards except the CGA. On the
CGA, characters in this range are silently ignored.

It is also now possible to define your own fonts. This is achieved by
using the following typedef.

typedef struct fg_font
{
    const char _far *fontptr;   /* First 128 characters  */
    const char _far *fontptr2;  /* Second 128 characters */
    fg_box_t charbox;
} fg_font_t;

To save DGROUP data segment space declare the tables _far (optional):

char _far  my_4x4_font_table[]=
{
    0x80,0x40,0x20,0x10,    /* char 0 == '\'   */
    0x10,0x20,0x40,0x80,    /* char 1 == '/'   */
    .   .   .
    .   .   .
    0x00,0x00,0x00,0xf0     /* char 127 == '_' */
};

The font table is used by fg_drawmatrix() to output the characters. Each
character entry must be in form compatible for fg_drawmatrix(). The first
font table is assumed to be 128 characters long, the characters 129
through 256 are assumed to be in the second font table. The second table
is optional. If it is set to (char _far *) 0 then any attempted output of
characters in the range 128 through 255 is ignored. The font tables need
not be 128 characters long, but outputting characters beyond the range of
the table will most likely result in segment faults under UNIX, DOS 386
and OS/2, and garbage output under DOS. You can make your own font tables
or request pointers to them from your graphics board (if available), see
your graphics board programmer s manual for details.

There are two functions supplied to enable the selection of fonts,
fg_get_font() and fg_set_font().

fg_font_t my_4x4_font =
{
    my_4x4_font_table,
    (char _far *)0,
    0, 0, 3, 3
};

void foo(void)
{
    fg_font_t default_font;
    /* Save current font if we want to restore it later */
    fg_get_font(&default_font);

    fg_set_font(&my_4x4_font);      /* Install new font */
    .  .  .
    fg_set_font(&default_font);     /* Restore original */

    return;
}

A sample character and icon designer, ICONDRAW, is supplied on the
distribution disks.

Mouse Support
When using Flash Graphics with a mouse it is not often appreciated that
the mouse cursor is drawn by the mouse driver. Most drivers have support
for the standard graphics adapters supplied by IBM, such as CGA, EGA,
VGA. Some may even have support for Hercules. Most, however, do not
support the high resolution 800x600 modes supported by Flash Graphics.
Your mouse will most likely disappear (but still report its position when
queried) when you put the graphics board into one of these modes.

Previously it has been necessary for the programmer to build his own
mouse support using either fg_drawmatrix or fg_drawline. However, mouse
support has now been added to the Flash Graphics libraries. It should
work with any mouse that has a suitable mouse driver. The mouse will work
with all graphics modes supported by Flash Graphics, even Hercules and
Super VGA modes.

The mouse support is implemented in such a way that the code is not
linked in if you do not call any of the following functions:

    fg_msm_getpress()       fg_msm_getrelease()
    fg_msm_getstatus()      fg_msm_setarea()
    fg_msm_setcurpos()      fg_msm_setcursor()
    fg_msm_setratio()

If you do not want the mouse support you can save about 1100 bytes total
in code and data space.

A global variable, fg.msm, has been supplied to report on whether the
mouse functions can be run. It will be zero if no mouse driver is
present, or the code has not been linked in. It is non-zero if the code
and driver are present.

The following defines can be tested to check on the status of the mouse
buttons. They represent the bits that will be set on pressing that
button.

    FG_MSM_LEFT FG_MSM_RIGHT    FG_MSM_MIDDLE

These are also used by fg_msm_getpress() and fg_msm_getrelease().

Example Code:
See the file fgdemo.c on the distribution disks for examples of how to use
the Flash Graphics mouse interface.

fg_adjustxy
Usage:
#include <fg.h>

void far fg_adjustxy (int rot, int n, fg_coord_t far *px,
                      fg_coord_t far *py, fg_const_pbox_t box);

Description:
The x or y coordinate for the next character (or object bounded by box)
is calculated depending on the rotation rot, which must be one of the
constants FG_ROT0, FG_ROT90, FG_ROT180 or FG_ROT270. *px and *py are
pointers to the coordinates of the starting location of first character
in the string and are adjusted to be where the next character (object)
would go. The argument n is the number of chars or objects already
output. This function is most useful with fg_drawmatrix and fg_puts.

Example:
{
    static char test_string[] = "This is a test.";
    fg_coord_t x, y;
    . . .
    x = fg.displaybox[FG_X1] + fg.displaybox[FG_X2];
    x -= sizeof(test_string) * (fg.charbox[FG_X2] + 1);
    x /= 2;
    y = (fg.displaybox[FG_Y1] + fg.displaybox[FG_Y2])/2;

    fg_puts(FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, x, y,
            test_string, fg.displaybox);

    fg_adjustxy(FG_ROT0, sizeof(test_string) - 1, &x, &y, fg.charbox);
    /* x and y now are located at the  */
    /* end of the string "test string" */
}

fg_assert
Usage:
#include <fg.h>
void far fg_assert(char far *string_p, char far *file_p,
                   unsigned int line);

Description:
fg_assert is called when a program bug is detected (debug library only)
such as a coordinate that is out of range and was not clipped. The
default function prints an error message to stderr and then exits to the
operating system.

The programmer can provide their own replacement for this function. If
this is done, it should print out the message pointed to by string_p, the
source file name at file_p and the source file line number line. It must
not return, it is strongly suggested that it exit the program.

fg_blit
Usage:
#include <fg.h>
void far fg_blit(fg_const_pbox_t src_box, fg_coord_t x,
                 fg_coord_t y, int dstpage, int srcpage);

Description:
Do a blit of a rectangle of pixels from one area of the screen to
another. The argument src_box defines the source rectangle of pixels.
Box src_box must be enclosed by fg.displaybox both before the start of
the blit and after the translation to the new coordinates. The arguments
x and y give the coordinates of the lower left corner of the destination
of the box src_box. The page the pixels are to be moved to is given by
dstpage and the page they are to be read from by srcpage.

No clipping is done. Overlapping source and destination locations will be
handled such that the pixel to be read is not destroyed by a previous
write. This function can also be used as a "page copy" function with the
proper src_box(fg.displaybox) and destination coordinate (0,0).

Example:
/* copy screen from oldpage to page */
fg_blit(fg.displaybox, 0, 0, page, oldpage);

fg_box_area
Usage:
#include <fg.h>
long int far fg_box_area(fg_const_pbox_t b)

Description:
Returns the number of pixels in a box. This is very useful for
calculating the storage requirements for fg_readbox.

Example:
{
fg_color_t *color_p;
fg_box_t read_box;
read_box [FG_X1] = 10;
read_box [FG_Y1] = 0;
read_box [FG_X2] = 100;
read_box [FG_Y2] = 100;
color_p = malloc(sizeof(fg_color_t) * fg_box_area(read_box));
assert(color_p != NULL);
fg_readbox(read_box, color_p);
    . . .
}

fg_box_cpy
Usage:
#include <fg.h>
pbox_t far fg_box_cpy(fg_pbox_t to, fg_const_pbox_t from);

Description:
Copy the box from to the box to.

Example:
fg_box_cpy(destination_box, source_box);

Return Value: Pointer to the box to.

fg_box_enclose
Usage:
#include <fg.h>
fg_coord_t far fg_box_enclose(fg_const_pbox_t b1, fg_const_pbox_t b2);

Description:
Returns nonzero if a box completely encloses another.

Example:
void fg_c_readbox(fg_const_pbox_t b, fg_color_t *p)
{
fg_coord_t  y, x;

assert(p && b);
assert(fg_box_enclose(fg.displaybox,b));

for (y = b[FG_Y1]; y < b[FG_Y2]; y++)
    for (x = b[FG_X1]; x < b[FG_X2]; x++)
        *p++ = fg_readdot(x,y);
}

fg_box_height
Usage:
#include <fg.h>
fg_coord_t far fg_box_height(fg_const_pbox_t b);

Description:
Returns the height of the box in pixels.

Example:
void status_line(char *status_string)
{
fg_box_t status_box;

fg_box_cpy(status_box, fg.displaybox);
status_box [FG_Y1] = fg.displaybox [FG_Y2] - fg_box_height(fg.charbox);

/* Clear the old string. */
fg_fillbox(FG_BLACK, FG_MODE_SET, ~0, status_box);
fg_puts(FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, 0, status_box[FG_Y1],
        status_string, status_box);
}

fg_box_width
Usage:
#include <fg.h>
fg_coord_t far fg_box_width(fg_const_pbox_t b)

Description:
Returns the height of the box in pixels.

Example:
#include <stdio.h>
#include <fg.h>

void label_graph (char *label_string) {
   fg_box_t label_box;
   size_t len = strlen (label_string);

   fg_box_cpy (label_box, fg.charbox);

   label_box [FG_X1] = (fg_box_width(fg.displaybox) -
                       len * fg_box_width(fg.charbox))/2;
   label_box [FG_X2] = (fg_box_width(fg.displaybox) +
                       len * fg_box_width(fg.charbox))/2;

   /* Clear a space for it. */

   fg_fillbox (FG_BLACK, FG_MODE_SET, ~0, label_box);
   fg_puts (FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, label_box[FG_X1],
            label_box [FG_Y1], label_string, label_box);
}

fg_coord_midpoint
Usage:
#include <fg.h>
fg_coord_t far fg_coord_midpoint(fg_coord_t a, fg_coord_t b);

Description:
Returns the midpoint of two points on the same axis.

Example:
fg_coord_t x_center, y_center;

x_center = fg_coord_midpoint(fg.displaybox [FG_X2],
                             fg.displaybox [FG_X1]);
y_center = fg_coord_midpoint(fg.displaybox [FG_Y2],
                             fg.displaybox [FG_Y1]);
fg_drawdot(FG_WHITE, FG_MODE_SET, ~0, x_center, y_center);

fg_drawarc
Usage:
#include <fg.h>
void far fg_drawarc(fg_color_t color, int mode, int mask,
                    fg_coord_t x, fg_coord_t y, fg_coord_t radius,
                    int startangle, int endangle,
                    fg_const_pbox_t clipbox);

Description:
Draw a circular arc counter-clockwise from startangle to endangle.

Input:
x,y         Center of circle
radius      Radius of circle
clipbox     Bounding box of the arc.
startangle  Value from 0-3600 (10ths of a degree)
endangle    Value from 0-3600 (10ths of a degree)

To draw a complete circle, use 0, 3600 for the start and end angles.
Note that a zero radius or zero angular distance arc will be drawn as one
pixel. 0 degrees is to the right, such that an arc drawn from 0 to 900
will be in the upper right quadrant of the circle described by "radius".
Although the units for the start and end angles are in 10ths of a degree,
there is a maximum error of about 3 degrees for some angles.

The arc is circular in pixel units. On most displays it will appear as an
ellipse due to the difference in dimensions in the x and y directions of
each pixel (the aspect ratio). If a circular appearance is required use
fg_drawellipse with the appropriate scaling for the x and y radii
calculated with the use of fg.pixelx and fg.pixely.

Example:
fg_drawarc(FG_WHITE, FG_MODE_XOR, ~0, fg.displaybox [FG_X2]/2,
           fg.displaybox [FG_Y2] + 10, fg.displaybox [FG_Y2]/2,
           1800, 3600, fg.displaybox);
/*
        This will result in the lower half of a circle being
        drawn with it's center above the top of the screen
*/

fg_drawbox
Usage:
#include <fg.h>
void far fg_drawbox(fg_color_t color, int mode, int mask,
                    int line_type, fg_const_pbox_t box,
                    fg_const_pbox_t clipbox);

Description:
Draw the outline of a box on the display screen and clip it to the box
clipbox. The box to be drawn must be normalized, i.e. the first
coordinate pair must be the lower left corner and the second pair must be
the upper right corner.

Example:
{
    fg_box_t box_to_draw;
    box_to_draw [FG_X1] = -10;
    box_to_draw [FG_Y1] = 0;
    box_to_draw [FG_X2] = 20;
    box_to_draw [FG_Y2] = 30;

    fg_drawbox(FG_WHITE, FG_MODE_SET, ~0, FG_LINE_DENSE_DOTTED,
               box_to_draw, fg.displaybox);
}

All sides of the box will be drawn but the left side will be at x coordinate
0 instead of -10.

fg_drawdot
Usage:
#include <fg.h>
void far fg_drawdot(fg_color_t color, int mode, int mask,
                    fg_coord_t x, fg_coord_t y);

Description:
Draw dot at x,y. The coordinates (x, y) must be within fg.displaybox.

Example:
fg_drawdot(FG_WHITE, FG_MODE_SET, ~0, 0, 0);

fg_drawellipse
Usage:
#include <fg.h>
void far fg_drawellipse,(fg_color_t color, int mode, int mask,
                         fg_coord_t x, fg_coord_t y, fg_coord_t xradius,
                         fg_coord_t yradius, int startangle, int endangle,
                         fg_const_pbox_t clipbox);

Description:
Draw an elliptical arc counter-clockwise from startangle to endangle.

Input

x, y                Center of ellipse
xradius,yradius     Ellipse radii
clipbox             Bounding box for the ellipse.
startangle          Value from 0..3600 (10ths of a degree)
endangle            Value from 0..3600 (10ths of a degree)

To draw a complete ellipse, use 0 and 3600 for start and end angles
respectively.

Note that a zero radius or zero angular distance arc will be drawn as one
pixel.

See Also: fg_drawarc

fg_drawline fg_drawlinep
Usage:
#include <fg.h>
void far fg_drawline(fg_color_t color, int mode, int mask,
                     int line_type, fg_const_pline_t line);
void fg_drawlinep(fg_color_t color, int mode, int mask,
                     int line_type, fg_const_pline_t line);

Description:
Draws a line from (x1,y1) to (x2,y2) using the indicated line type,
color, mode and mask. The line must have been previously clipped to
fg.displaybox.

fg_drawlinep differs from fg_drawline in that the end points of the line
will be drawn regardless of the line type.

Example:
{
fg_line_t line_to_draw;
/* A line from the upper left corner to the lower */
/* right corner of the display.                   */
    line_to_draw [FG_X1] = fg.displaybox [FG_X2];
    line_to_draw [FG_Y1] = fg.displaybox [FG_Y1];
    line_to_draw [FG_X2] = fg.displaybox [FG_X1];
    line_to_draw [FG_Y2] = fg.displaybox [FG_Y2];
    fg_drawline(FG_WHITE, FG_MODE_SET, ~0,
        FG_LINE_SOLID, line_to_draw);
}

fg_drawlineclip
Usage:
#include <fg.h>
void far fg_drawlineclip(fg_color_t color, int mode, int mask,
                         int line_type, fg_const_pline_t line,
                         fg_const_pbox_t clipbox);

Description:
Clip the line to clipbox and draw the remainder. The function fg_lineclip
is used to do the clipping. If the results are not satisfactory the
programmer may supply an alternate clipping function with the same name
(see fg_lineclip). See the description for fg_drawline for more
information on the input parameters.

fg_drawmatrix
Usage:
#include <fg.h>
void far fg_drawmatrix(fg_color_t color, int mode, int mask,
                       int rotation, fg_coord_t x, fg_coord_t y,
                       const char *p, fg_const_pbox_t b,
                       fg_const_pbox_t clipbox);

Description:
Draw matrix of dots fg_box_width(b) by fg_box_height(b). The matrix is
drawn from top to bottom; the first row pointed to by p corresponds to
the top row displayed. Only the bits that are 1s are output to the
display. This is so that icons can be overlaid across what is already on
screen. If a different result is desired you can do a fg_fillbox prior to
calling this routine.

color,mode,mask  The color, mode and mask to use for the matrix.

rotation         FG_ROTx about x,y where x,y is the lower left corner of
                 where matrix is to be written.

p                Pointer to data to be written, which is an array
                 fg_matrix_size(b) bytes long. Bit 0 of the byte
                 corresponds to the rightmost pixel, bit 7 to the
                 leftmost.

b                Enclosing box. b[FG_X1] = b[FG_Y1] = 0.

clipbox          The clipping rectangle.

Example:
{
static fg_box_t bat_mouse_box = {0,0,26,11};
static char bat_mouse_cursor[48] =
 {
 /*
   This is drawn with the X's set to WHITE, blanks are unchanged.
 */
    0x00,0x0a,0x00,0x00,    /*            X X           */
    0x00,0x0e,0x00,0x00,    /*            XXX           */
    0x02,0x15,0x08,0x00,    /*        X  X X X  X       */
    0x07,0x9f,0x3c,0x00,    /*      XXXX XXXXX XXXX     */
    0x0f,0xff,0xfe,0x00,    /*    XXXXXXXXXXXXXXXXXXX   */
    0x1f,0xff,0xff,0x00,    /*  XXXXXXXXXXXXXXXXXXXXX   */
    0x3f,0xff,0xff,0x80,    /* XXXXXXXXXXXXXXXXXXXXXXX  */
    0x7f,0xff,0xff,0xc0,    /* XXXXXXXXXXXXXXXXXXXXXXXX */
    0xc7,0x3b,0x9c,0x60,    /*  XX  XXX XXX XXX XXX XX  */
    0x82,0x11,0x08,0x20,    /*    X   X  X   X  X  X    */
    0x00,0x11,0x00,0x00,    /*           X   X          */
    0x00,0x2a,0x80,0x00     /*         X X   X X        */
    };
    fg_drawmatrix(FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, 0, 0,
                  bat_mouse_cursor, bat_mouse_box,  fg.displaybox);
}

fg_drawpolygon
Usage:
#include <fg.h>
void far fg_drawpolygon(fg_color_t color, int mode, int mask,
                        int line_type, unsigned int vertices,
                        const fg_coord_t far *polygon,
                        fg_const_pbox_t clipbox),

Description:
Draw a polygon. The line_type is the same as for fg_drawline. The integer
vertices is the number of corners in the polygon. The pointer to
coordinates polygon is the array of coordinate pairs that make up the
polygon. The last coordinate pair in the polygon must be equal to the
first pair to make a closed figure.

Example:
void big_open_triangle(void)
{
fg_coord_t poly[8];

poly [0] = 0;
poly [1] = 0;
poly [2] = fg.displaybox [FG_X2];
poly [3] = fg.displaybox [FG_Y2];
poly [4] = fg.displaybox [FG_X2];
poly [5] = 0;
poly [6] = 0;
poly [7] = 0;
fg_drawpolygon(FG_LIGHT_WHITE, FG_MODE_SET, ~0, FG_LINE_SOLID,
               3, poly, fg.displaybox);
}

fg_drawthickline
Usage:
#include <fg.h>
void far fg_drawthickline(fg_color_t color, int mode, int mask,
                          int line_type, fg_const_pline_t line,
                          fg_const_pbox_t clip, int thickness);

Description:
Draw thick line. Line is drawn as if the "pen" is a square that is
thickness pixels wide on a side. See fg_drawlineclip for a description of
the other parameters and a (similar) example.

See Also: fg_drawlineclip

fg_fill
Usage:
#include <fg.h>
void far fg_fill(fg_coord_t x, fg_coord_t y, fg_color_t fillcolor,
                 fg_color_t boundary);

Description:
fg_fill does a boundary fill. It starts at (x,y) and draws pixels with
fillcolor in the left, right, up and down directions until pixels with
color boundary are encountered.

fg_fill is recursive in nature, and for complex fills it requires an
arbitrarily large amount of memory to store the recursion data. fg_fill
does dynamic memory allocation as required, so it does not suffer from
stack overflows or require the amount of memory needed to be specified in
advance. If it does run out of memory it will simply terminate without
completing the fill.

Example:
/*
    fill an area in green, as bounded by white starting
    at coords 100,100
*/
fg_fill(100, 100, FG_GREEN, FG_WHITE);

fg_fillbox
Usage:
#include <fg.h>
void far fg_fillbox(fg_color_t color, int mode, int mask,
                    fg_const_pbox_t box);

Description:
Set box to color. Box b must be already clipped. This function can be
used to clear the screen if box is equal to fg.displaybox.

Example:
/* clear the screen */
fg_fillbox(FG_BLACK, MODE_SET, ~0, fg.displaybox);

fg_filloutline
Usage:
#include <fg.h>
void far fg_filloutline(fg_color_t color, int mode, int mask,
                        const fg_coord_t far *out_line,
                        fg_coord_t far *buffer,
                        unsigned int point_pairs,
                        int fill_side, fg_const_pbox_t clipbox),

Description:
A more general version of fg_fillpolygon. Fill the outline of points with
a solid color. Y coordinates between adjacent points must not differ by
more than 1 pixel. The buffer will contain random information upon
return. The out_line has pixels of coordinate pairs. The buffer must, in
the worst case, be as large as out_line plus an extra point pair for each
local minimum and each local maximum in the Y direction.

The end point must be equal to the beginning point. fill_side is one of
FG_FILL_ON_RIGHT or FG_FILL_ON_LEFT. This is the side that must be filled
with the color color as the array out_line is traversed from small
indices to large indices.

Example:
See fg_getfillside

See Also: fg_getfillside, fg_fillpolygon, fg_linepixels, fg_traverseline.

fg_fillpolygon
Usage:
#include <fg.h>
int far fg_fillpolygon(fg_color_t color, int mode, int mask,
                       unsigned int vertices, const fg_coord_t *polygon,
                       fg_const_pbox_t clipbox)

Description:
Fill a polygon. This requires the allocation of memory and if memory is
exhausted will return 0. Returns non-zero if successful. Figure may be
concave as well as convex, undefined (but relatively benign) results will
occur with sides that cross.

Example:
void big_triangle(void)
{
    fg_coord_t poly[8];

    poly [0] = 0;
    poly [1] = 0;
    poly [2] = fg.displaybox [FG_X2];
    poly [3] = fg.displaybox [FG_Y2];
    poly [4] = fg.displaybox [FG_X2];
    poly [5] = 0;
    poly [6] = 0;
    poly [7] = 0;

    fg_fillpolygon(FG_LIGHT_WHITE, FG_MODE_SET, ~0, 3, poly,
                   fg.displaybox);
}

fg_getfillside
Usage:
#include <fg.h>
int fg_getfillside(const fg_coord_t *pt_pairs, unsigned int vertices)

Description:
Figure out which side of the polygon/outline, as it is traversed, the
fill is  on. Return FG_FILL_ON_RIGHT or FG_FILL_ON_LEFT. The algorithm
may  fail if line segments cross each other or are colinear. The last
point pair in  the array pt_pairs must be equal to the first. May be
used with  fg_filloutline to fill arbitrary shapes.

Example:
fill_users_outline()
{
    fg_coord_t *p, *buf;
    unsigned int point_pairs;
    char *s;

    point_pairs = get_users_outline(&p)

    if (point_pairs 0)
    {
        unsigned int buffer_size;
        int side = fg_getfillside(p, point_pairs)

        if (side == FG_FILL_ON_RIGHT)
            s = "Filling on the right side";
        else
        {
            assert(side == FG_FILL_ON_LEFT);
            s = "Filling on the left side.";
        }

        buffer_size = get_outline_buff_size(p, point_pairs);
        buf = malloc(buffer_size);
        if (buf)
        {
            fg_filloutline(FG_WHITE, FG_MODE_SET, ~0, p,
                 buf, point_pairs, side, fg.displaybox);
            free(buf);
        }
        else
            s = "Insufficient memory.";
    }
    else
        s = "No outline obtained.";

    fg_puts(FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, 0, 0, s,
            fg.displaybox);
}

fg_flush
Usage:
#include <fg.h>
void far fg_flush(void);

Description:
Flush any pending output to display. Wait until the display is
up-to-date.  This should be called before any user input is expected to
ensure that the  screen is up-to-date.

Example:
int console_char;

fg_flush();
console_char = getch();

fg_getcolormap
 This function was made obsolete with the support of VGA mode 0x13.
 It still exists for the EGA and other modes of the VGA for backwards
 compatibility but it may not be supported in future releases. Use
 fg_setpalette for all new programs.

Usage:
#include <fg.h>
void far fg_getcolormap(fg_color_t *color_array, int max_entries)

Description:
Get values of the current color map (inverse of fg_setcolormap). Input:
max_entries Max number of entries to write into  color_array[]. The
actual number of  entries written is the lesser of  fg.nsimulcolor or
max_entries. Output: color_array    Array of colors. The values are
between 0  and fg.ncolormap - 1.

Example:
{
    fg_color_t color_array [16];
    fg_getcolormap(color_array, 16);
}

See Also: fg_setcolormap, fg_setpalette

fg_get_font
Usage:
void fg_get_font(fg_font_t *dest_p);

Description:
Obtain the current font in use. If you wish to restore the default font
after  setting a new one, you must first save it. Otherwise you must
re-initialize  the graphics package.

fg_get_type
Usage:
int fg_get_type(void)

Description:
Returns the type of display present.

Return Value: The FG_XXXX display type present.

fg_init
Usage:
#include <fg.h>
int far fg_init(void);

Description:
Initialize the graphics variables and put the crt in graphics mode. If
the fg  graphics package has never been initialized fg_init will search
the  environment for "FG_DISPLAY" and use the board and mode specified by
that environment string. If the "FG_DISPLAY" is not found an attempt is
made to identify the current graphics hardware available and initialize
it  to the highest resolution available (maximum number of pixels which
may  not be the maximum number of colors). It returns fg_display which is
non-zero if the initialization was successful.

If the graphics package is closed down using fg_term, and then reopened
using fg_init, the previously set graphics mode is restored. This is
useful  if the program has called a specific initialization routine (such
as  fg_init_vga13) at the beginning of the program and later wants to
temporarily switch to text mode without the additional overhead of
remembering the specific initialization routine was that was previously
called.

Example:
This is useful if you need to temporarily switch to text mode

int status = 0;

fputs("EGA found. Monochrome (M) or Color Display (C)?", stdout);
fflush(stdout);

switch (getc(stdin))
{
case 'M':
case 'm':
    status = fg_init_egamono();
    break;
case 'c':
case 'C':
    status = fg_init_egaecd();
    break;
default:
    status = 0;
}

if (status == 0)
    return;

        /* MORE CODE */

fg_term();
system("dir");
fg_init();

        /* MORE CODE */

fg_term();

fg_init_null - fg_init_8514a
 Not all of this group of functions are currently supported under
 OS/2. Please refer to the readme.fg file for more information.

Usage:
#include <fg.h>

Function Prototype                      Setting

int far fg_init_all(void);
int far fg_init_cga(void)               CGAHIRES
int far fg_init_cgamedres(void)         CGAMEDRES
int far fg_init_egacolor(void);         EGACOLOR
int far fg_init_egaecd(void);           EGAECD
int far fg_init_egamono(void);          EGAMONO
int far fg_init_egalowres(void);        EGALOWRES
int far fg_init_evgahires(void);        EVGAHIRES
int far fg_init_herc(void);             HERC or HERCFULL
int far fg_init_null(void);
int far fg_init_orchidprohires(void);   ORCHIDPROHIRE
int far fg_init_paradisehires(void);    PARADISEHIRES
int far fg_init_toshiba(void);          TOSHIBA
int far fg_init_tridenthires(void);     TRIDENTHIRES
int far fg_init_vegavgahires(void);     VEGAVGAHIRES
int far fg_init_vesa6a(void);           VESA6A
int far fg_init_vesa2(void);            VESA2
int far fg_init_vga11(void);            VGA11
int far fg_init_vga12(void);            VGA12
int far fg_init_vga13(void);            VGA13
int far fg_init_8514a(void)             8514A

Description:
Initialize Graphics Display Device. If not already in graphics mode save
current mode of display device, so it can be restored by fg_term. Put
display device into its graphics mode. Set the current display page to
page  0. Store the characteristics of the display device into the global
variables. On output fg.display is set to the return value, fg.activepage
and  fg_displaypage are set to 0. Page 0 is set to FG_BLACK.

Return Value: FG_XXXX Display type that was opened. FG_NULL (0) if failure.

fg_init_all()    will attempt to determine the type of display graphics
                 that is available and  open that display device. The
                 environment variable FG_DISPLAY=XXXXX will  override.
                 The environment variable override will be primarily
                 useful for  non-standard clone boards, or for boards
                 that emulate multiple boards.  fg_init_all is obsolete
                 but still exists for backward compatibility, use
                 fg_init for new programs. fg_init_all may not exist in
                 future releases.

fg_init_cga()    will assume that the graphics device is a CGA board and
                 put it in 640 x  200 x 2 color mode (mode 0x6).

fg_init_cgamedres() will assume that the graphics device is a CGA board
                 and put it in 320 x  200 x 4 color mode (mode 0x4).

fg_init_egacolor() will assume that the graphics device is a EGA board
                 with a IBM color  monitor (not enhanced color monitor)
                 and put it into 640 x 200 x 16 color  mode (mode 0xE).

fg_init_egaecd() will assume that the graphics device is a EGA board
                 with a enhanced color  monitor and put it into 640 x 350
                 x 16 color mode (mode 0x10).

fg_init_egamono() will assume that the graphics device is a EGA board
                 with a IBM  monochrome monitor and put it into 640 x 350
                 x 4 color mode (mode 0xF).

fg_init_egalowres() will assume that the graphics device is a EGA board
                 with a IBM color  monitor and put it into 320 x 200 x 16
                 color mode (mode 0xD).

fg_init_evgahires() will assume that the graphics device is a Everex
                 EVGA board with a  multifrequency monitor and put it
                 into 800 x 600 x 16 color mode (mode  0x70).

fg_init_herc()   will assume that the graphics device is a Hercules
                 board. It will determine  if there are 1 or 2 pages
                 available and put it into 720 x 348 x 2 color mode.

fg_init_null()   is the bit-bucket graphics device. It always returns
                 FG_NULL.

fg_init_orchidprohires() will assume the the graphics device is a
                 Orchid Prodesigner VGA board  and put it into 800 x 600
                 x 16 color mode (mode 0x29).

fg_init_paradisehires() will assume that the graphics device is a
                 Paradise VGA board and put it  into 800 x 600 x 16 color
                 mode (mode 0x58).

fg_init_toshiba() will assume that the graphics device is a Toshiba
                 3100 and put it into 640  x 400 x 2 color mode (mode
                 0x74).

fg_init_tridenthires() will assume that the graphics device is a
                 Trident VGA board and put it  into 800 x 600 x 16 color
                 mode (mode 0x5B).

fg_init_vegavgahires() will assume that the graphics device is a Video
                 7 VEGA VGA board and  put it into 800 x 600 x 16 color
                 mode (mode 0x62).

fg_init_vesa6a() will assume that the graphics device is a VESA
                 compatible VGA board and  put it into 800 x 600 x 16
                 color mode (mode 0x6A).

fg_init_vesa2()  will assume that the graphics device is a VESA
                 compatible VGA board and put it into 800 x 600 x 16
                 color mode (mode 0x102).

fg_init_vga11()  will assume that the graphics device is a VGA board and
                 put it into 640 x 480 x 2 color mode (mode 0x11).

fg_init_vga12()  will assume that the graphics device is a VGA board and
                 put it into 640 x 480 x 16 color mode (mode 0x12).

fg_init_vga13()  will assume that the graphics device is a VGA board and
                 put it into 320 x 200 x 256 color mode (mode 0x13).

fg_init_8514a()  will assume that the graphics device is an IBM 8514A
                 and put it into graphics mode.

 The first attempt to use the graphics device MUST be one of the
 fg_init_xxx() functions.

As new devices are implemented, corresponding functions will be named
and available.

Example:
if (fg_init() == FG_NULL)
    {
        fputs ("Unable to open graphics device.\n", stderr);
        exit(EXIT_FAILURE);
    }
}

fg_lineclip
Usage:
#include <fg.h>
int far fg_lineclip(fg_const_pbox_t clip, fg_const_pline_t
                    line_in, fg_pline_t line_out);

Description:
clip        The clipping box for the line line_in.
line_in     The line that is to be tested against the clipping box.
line_out    The output line that is a clipped version of line_in.

Clipping is an area prone to problems with roundoff and disconcerting
behavior. If the programmer is not satisfied with the performance of the
functions that call this routine (fg_drawlineclip, fg_drawbox, and
fg_drawthickline) the programmer may supply an alternative
implementation.

Return Value: Returns non-zero if one or more pixels of the line line_out
              lie inside the clipping box clip. Returns zero otherwise.

fg_line_cpy
Usage:
#include <fg.h>
fg_pline_t far fg_line_cpy(fg_pline_t to, fg_const_pline_t from);

Description:
Copy the line from to the line to. Return to.

Example:
fg_line_cpy(destination_line, source_line);

fg_line_horiz
Usage:
#include <fg.h>
int far fg_line_horiz(fg_const_pline_t line);

Description:
Tests whether the supplied line is horizontal.

Return Value: Returns nonzero if horizontal.

fg_linepixels
Usage:
#include <fg.h>
unsigned int far fg_linepixels(fg_const_pline_t line);

Description:
Returns the total number of pixels in a line. The line need not be
confined to fg.displaybox. A useful function for obtaining the buffer
size for fg_filloutline.

fg_line_vert
Usage:
#include <fg.h>
int far fg_line_vert(fg_const_pline_t line);

Description:
Tests whether the supplied line is vertical.

Return Value: Returns nonzero if vertical.

fg_line_zerolength
Usage:
#include <fg.h>
int far fg_line_zerolength(fg_const_pline_t line);

Description:
Tests whether the supplied line is actually a point (has zero length).

Return Value: Returns nonzero if line is 0 length.

fg_make_line
Usage:
#include <fg.h>
void far fg_make_line(fg_pline_t line, fg_coord_t x1, fg_coord_t y1,
                      fg_coord_t x2, fg_coord_t y2);

Description:
Make a line from the individual coordinates. Saves typing FG_X2, FG_Y2
etc.

Example:
fg_line_t line;
fg_make_line(line, 0, 0, 100, 100);
   . . .

fg_matrix_size
Usage:
#include <fg.h>
size_t far fg_matrix_size(fg_const_pbox_t box);

Description:
Determines the number of bytes that will be required to store a matrix.
This value can then be used to allocate suficient memory.

Example:
char *make_user_icon(fg_pbox_t icon_box)
{
    char *icon_matrix;

    get_user_icon_box(icon_box);
    icon_matrix = calloc(fg_matrix_size(icon_box), 1);

    if (icon_matrix)
        get_user_icon(icon_matrix, icon_box);

    /* Caller must free storage used for icon_matrix. */
    return icon_matrix;
}

Return Value: Returns the number of bytes to allocate for the matrix.

fg_msm_getpress
Usage:
#include <fg.h>
unsigned int fg_msm_getpress(unsigned *but_num,
                             fg_coord_t *last_x, fg_coord_t *last_y);

Description:
Get the number of presses of a button since the last call. On input
*but_num has the button to be queried (FG_MSM_LEFT, FG_MSM_RIGHT,
FG_MSM_MIDDLE), on output it has the number of times it has been pressed
since the last call.  *last_x and *last_y contain the coordinate at which
the button was last pressed.

Return Value: Returns the current status of all the buttons.

fg_msm_getrelease
Usage:
#include <fg.h>
unsigned int fg_msm_getrelease(unsigned *but_num,
                               fg_coord_t  *last_x, fg_coord_t *last_y);

Description:
Get the number of releases of a button since the last call. On input
*but_num has the button to be queried (FG_MSM_LEFT, FG_MSM_RIGHT,
FG_MSM_MIDDLE), on output it has the number of times it has been pressed
since the last call.  *last_x and *last_y contain the coordinate at which
the button was last released.

Return Value: Returns the current status of all the buttons.

fg_msm_getstatus
Usage:
#include <fg.h>
unsigned int fg_msm_getstatus(fg_coord_t *x_p, fg_coord_t*y_p);

Description:
Get the current button press status

Return Value: Updates the x and y coordinates, and returns the state of
              all the buttons as a bit pattern. See msm_getstatus.

fg_msm_hidecursor
Usage:
#include <fg.h>
void fg_msm_hidecursor(void);

Description:
Hides the cursor. At init time it is hidden. These calls are nestable.
If you call hidecursor 5 times you must call fg_msm_showcursor 5 times
to make it visible again. You should never call fg_msm_showcursor() more
than one level deep, if you do, you will have mouse tracks on your
screen. You may call fg_msm_hidecursor() 128 deep. fg_flush() must be
called to make the mouse cursor visible. All fg_ functions (except of
course fg_flush(), and some fg_msm_XXX functions) call fg_msm_hidecursor()
before outputting to or reading from the screen and fg_msm_showcursor()
afterwards. This prevents you from trashing the cursor and/or your
graphics output. The cursor will not be visible again until the number
of fg_msm_showcursor()calls is one greater than the number of
fg_msm_hidecursor() calls and fg_flush() is called.

Return Value: None

fg_msm_motion
Usage:
#include <fg.h>
void fg_msm_motion(unsigned char a);

Description:
Change the motion algorithm. 0 is linear, 1 is non-linear. Default is
non-linear. All other values reserved.

Return Value: None

fg_msm_setarea
Usage:
#include <fg.h>
void fg_msm_setarea(fg_const_pbox_t);

Description:
Set the minimum and maximum horizontal and vertical positions. Mouse
motion will be restricted and clipped to this box. At fg_init() this is
set to fg.displaybox.

fg_msm_setcurpos
Usage:
#include <fg.h>
void fg_msm_setcurpos(fg_coord_t x, fg_coord_t y);

Description:
Set the position of the cursor to a known location. At fg_init() time it
is 0,0.

Return Value: None

fg_msm_setcursor
Usage:
#include <fg.h>
void fg_msm_setcursor(fg_msm_cursor_t cursor);

Description:
typedef struct fg_msm_cursor
    {
        char far *matrix;
        fg_box_t box;
        fg_coord_t hot_x, hot_y;
    } fg_msm_cursor_t;

Set the type of cursor to use. The default is an arrow. matrix must
remain in scope for as long as that cursor type is to be used. The cursor
is implemented with fg_drawmatrix(). The other parameters are copied. The
matrix and bounding box must satisfy the fg_drawmatrix specifications.
The hot spot is specified relative to the lower left corner of the
matrix. This is the coordinate reported by the various mouse functions.
It is always drawn in XOR mode with FG_HIGHLIGHT color, with FG_ROT0
rotation, clipped to the area defined by fg_msm_setarea(). If you do not
care for this method or color you can change it by supplying your own
output function (see fg_msm_setoutput()). The coordinates passed to your
function will always be within the area defined by fg_msm_setarea()
however.

Return Value: None

fg_msm_setoutput
Usage:
#include <fg.h>
void fg_msm_setoutput(void (*cdecl _far func_p)(fg_coord_t x,
                                                fg_coord_t y))

Description:
Change the output function to use for outputting the cursor. The
programmer supplies a function that must display the cursor on all odd
calls (1st, 3rd, 5th, etc) and remove it on all even calls (2nd, 4th,
6th).

Return Value: None

fg_msm_setratio
Usage:
#include <fg.h>
void fg_msm_setratio(unsigned ratiox,unsigned ratioy);

Description:
Set the mickey to pixel ratio for mouse motion. Specify the number of
mickeys per 8 pixels, range is 1 to 32767. The default setting is 8 and
16.

Return Value: None

fg_msm_showcursor
Usage:
#include <fg.h>
void fg_msm_showcursor(void);

Description:
Shows the cursor. At init time it is hidden. These calls are nestable.
If you call fg_msm_hidecursor 5 times you must call fg_msm_showcursor 5
times to make it visible again. You should never call fg_msm_showcursor()
more than one level deep, if you do, you will have mouse tracks on your
screen. You may call fg_msm_hidecursor() 128 deep. fg_flush() must be
called to make the mouse cursor visible. All fg_ functions (except of
course fg_flush(), and some fg_msm_XXXX functions) call
fg_msm_hidecursor() before outputting to or reading from the screen and
fg_msm_showcursor() afterwards. This prevents you from trashing the
cursor and/or your graphics output. The cursor will not be visible again
until the number of fg_msm_showcursor() calls is one greater than the
number of fg_msm_hidecursor() calls and fg_flush() is called.

Return Value: None

fg_pt_inbox
Usage:
#include <fg.h>
int far fg_pt_inbox(fg_const_pbox_t box, fg_coord_t x, fg_coord_t y);

Description:
Tests whether point is contained within the bounds of box.

Return Value: Returns nonzero if point is in box.

fg_putc
Usage:
#include <fg.h>
void far fg_putc(fg_color_t color, int mode, int mask, int rotation,
                 fg_coord_t x, fg_coord_t y, int put_char,
                 fg_const_pbox_t clip_box);

Description:
Send character to screen using rotation, color, mask and mode.The
coordinates x and y gives the position of lower left corner of the
character (about which point the character rotates). The character pixels
are clipped to clipbox.

Example:
fg_putc (FG_WHITE, FG_MODE_SET, ~0, FG_ROT270, 100, 100, 'Z',
         fg.displaybox);

fg_puts
Usage:
#include <fg.h>
void far fg_puts(fg_color_t color, int mode, int mask, int rotation,
                 coord_t x, coord_t y, char *out_string,
                 fg_const_pbox_t clip);

Description:
Output a string to the graphics device. Use the specified color, mode,
mask and rotation. The starting point of the lower left corner of the
first character is at x, y. The string to output is out_string. The
string will be clipped to the box clip.

Example:
fg_puts (FG_WHITE, FG_MODE_SET, ~0, FG_ROT0, 0, 0, "Hello, world!",
         fg.displaybox);

fg_readbox
Usage:
#include <fg.h>
void char far fg_readbox(fg_const_pbox_t b, fg_color_t far *p);

Description:
Read box b (inclusive) pixels off of the screen and store into the
fg_color_t array pointed to by p. The color of each pixel is written into
each element. The number of bytes required is sizeof(fg_color_t) *
fg_box_area(b) Rows are written first, in order of increasing y (this
means starting at the lower left corner).

Example:
{
    fg_color_t *color_p;
    fg_box_t read_box;
    read_box [FG_X1] = 10;
    read_box [FG_Y1] = 0;
    read_box [FG_X2] = 100;
    read_box [FG_Y2] = 100;
    color_p = malloc(sizeof(fg_color_t) * fg_box_area(read_box));
    assert(color_p != NULL);
    fg_readbox(read_box, color_p);
    . . .
    /* Need not be the same box, but must be the same size */
    read_box [FG_X1] += 20;
    read_box [FG_X2] += 20;
    read_box [FG_Y1] += 30;
    read_box [FG_Y2] += 30;
    fg_writebox(read_box, color_p);
}

fg_readdot
Usage:
#include <fg.h>
fg_color_t far fg_readdot(fg_coord_t x, fg_coord_t y);

Description:
Read the dot at x,y.

Example:
{
   fg_color_t dot_color;
   dot_color = fg_readdot(0, 0);
}

Return Value: Returns the color at x,y. These coordinates must be within
              fg.displaybox.

fg_restore
Usage:
#include <fg.h>
void far fg_restore (fg_handle_t handle);

Description:
Restore an area to the screen that was saved by fg_save. On input, handle
should contain the value returned by fg_save. On output, handle is no
longer valid. It may not be used on subsequent calls to fg_restore.

Example:
See fg_save.

See Also: fg_save
fg_save
Usage:
#include <fg.h>
fg_handle_t far fg_save(fg_const_pbox_t box);

Description:
Save an area on the screen. This area can be restored using fg_restore .
fg_save and fg_restore are primarily useful to support pop-in areas on
the screen. Note that areas saved can only be restored to the same
location (or the same location on another page if the active page was
changed).

Example:
{
    fg_box_t save_box;
    fg_handle_t save_handle;
    save_box [FG_X1] = save_box [FG_Y1] = 0;
    save_box [FG_X1] = save_box [FG_Y1] = 100;
    save_handle = fg_save(save_box);
    assert(save_handle != NULL);
    . . .
    fg_restore(save_handle);
}

Return Value: Returns an fg_handle_t, the handle to be used with
              fg_restore, otherwise NULL  (Failed, probably out of memory).

fg_setactivepage
Usage:
#include <fg.h>
void far fg_setactivepage(unsigned int pagenum);

Description:
Change active page to pagenum. The active page is the page that all the
fg_xxxx routines draw to. It is not necessarily the one that is being
displayed. pagenum must be less than fg.numpages. fg.activepage is set to
pagenum.

Example:
fg_setactivepage(1);

See Also: fg_setdisplaypage

fg_setcolormap
Usage:
#include <fg.h>
void far fg_setcolormap (fg_color_t far carray[], int max);

Description:
Set all the colors for the color map. The color map is not modifiable if
fg.ncolormap == fg.nsimulcolor.

 Note: This function was made obsolete with the support of VGA mode 0x13.
 It still exists for the EGA and other modes of the VGA for backwards
 compatibility but it may not be supported in future releases. Use
 fg_setpalette for all new programs.

carray           Array of colors, dimension is fg.nsimulcolor. The values
                 are between 0 and fg.ncolormap-1.

max              Max number of entries to read from color_array[]. The
                 actual number of entries read is the lesser of
                 fg.nsimulcolor or max).

fg_setcolornum
Usage:
#include <fg.h>
int far fg_setcolornum(old,new);

Description:
Change the definition of an FG_COLOR. As in

      fg_setcolornum(FG_WHITE, 3);

If 3 actually produces green then whenever your program subsequently uses
FG_WHITE, green will be the actual color output to the screen.

Example:
    . . .
    if (fg_init() == FG_NULL)
    {
        fputs("Unable to initialize graphics.", stderr);
        return 0;
    }
/*
        If this board only has 2 colors map the red, green and
        blue colors used throughout the program to black and
        white.
*/
    if (fg.nsimulcolor == 2)
    {
        fg_setcolornum(FG_BLUE, FG_WHITE);
        fg_setcolornum(FG_RED, FG_WHITE);
        fg_setcolornum(FG_GREEN, FG_BLACK);
    }
/*
        Code originally intended to require red green and blue
        will now have black and white functionality (dependent on
        the use of the colors).
*/
    . . .

fg_setdisplaypage
Usage:
#include <fg.h>
void far fg_setdisplaypage(unsigned pagenum);

Description:
Change display page to pagenum. The display page is the page that the
user sees on the screen. pagenum must be less than fg.numpages.
fg.displaypage is set to pagenum.

Example:
fg_setactivepage(0);

See Also: fg_setactivepage

fg_setenv_variable
Usage:
#include <fg.h>
void far fg_setenv_variable(const char *new_string)

Description:
Change the environment variable that fg_init looks for to that pointed to
by new_string. The environment variable can be changed from FG_DISPLAY to
any string less than or equal to 39 characters (plus a terminating '\0').

fg_set_font
Usage:
#include <fg.h>
void fg_set_font(const fg_font_t *newfont_p);

Description:
Set the font to use for further characters to be this one.

Return Value: None

fg_setlinepattern
Usage:
#include <fg.h>
void far fg_setlinepattern(int line_type,int pattern);

Description:
Set the pattern for a line.

line_type        Value between 0 and FG_LINE_MAX-1. Subsequent uses
                 of this value will use this line pattern.

pattern          16 bits defining the line pattern. The pattern starts
                 at bit 15, goes down to bit 0, and then repeats. If
                 fg_drawlinep is to always generate a dot at the
                 beginning of a line, bit 15 must be a 1.

Example:
/* A very, very sparse dotted line. */
fg_setlinepattern(FG_LINE_USER_DEFINED, 0x8000);

fg_setpalette
Usage:
#include <fg.h>
void far fg_setpalette(fg_color_t color_num, fg_color_t red,
                       fg_color_t green, fg_color_t blue);

Description:
Set the palette for display adaptors where fg.nsimulcolor is not equal to
fg.ncolormap.

Set the palette for the VGA/EGA. color_num is a number from 0 to
fg.nsimulcolor that is desired to have the specified red, green, and blue
intensities. The range of  red ,  green , and  blue  is from 0 to 255.
For graphics boards that have only 16 shades of red, green and blue the
range of 0 to 255 is divided evenly among the colors available. For
example the EGA has a total palette of 64, there are 4 different
intensities for each of the 3 colors (cube root of 64). Therefore for red
in the range of 0 to 63 will be the same as 0, 64 to 127 is the same as
64, 128 to 191 is the same as 128, and 192 to 255 is the same as 192.

All pixels that use the color color_num now have the relative proportion
of red, green, and blue specified. This applies to pixels presently on
the screen drawn with color_num as well as subsequent pixels drawn with
that color.

Example:
/* Initialize the vga palette for mode 0x13. */
void init_vga13_palette(void)
{
    int color_num, gray, red, green, blue;

    color_num = 0;

    /* Set the gray scale. */
    for (gray = 0; color_num < 40; gray += 6)
        fg_setpalette(color_num++, gray, gray, gray);

    for (red = 0; red < 256; red += 51)
    {
        for (green = 0; green < 256; green += 51)
        {
            for (blue = 0; blue < 256; blue += 51)
                fg_setpalette(color_num++, red, green,
            blue);
        }
    }
}

fg_term
Usage:
#include <fg.h>
void far fg_term(void);

Description:
Close display device. Display is returned to the state it was in before
the call to fg_init. Do nothing if fg_init was never called, or fg_term
was already called without another intervening fg_init. This is so that
panic-and-abort routines can reset back to text mode, without regard to
whether the display is in graphics mode or not.

Example:
fg_term();          /* Back to text mode. */

 Note: Exit from the program automatically calls fg_term as does
 Ctrl-Break. If this is not desired it is possible to bypass this
 feature by creating your own function and assigning it to fg.term_p
 (fg_term function pointer) after fg_init has been called. Your function
 must return (not exit) but need not call the previous function assigned
 to fg.term_p.

Example using fg_term_p:
#include <fg.h>
#include <stdlib.h>

int stay_in_graphics = 1;

#ifdef __cplusplus
extern "C"  {
#endif

void (far *old_fg_term) (void);
void far alt_fg_term(void)
{
    if (stay_in_graphics)
        return;
    (*old_fg_term)();
}

#ifdef __cplusplus
                }
#endif

int main(int argc, char *argv[])
{
    fg_init();
    old_fg_term = fg.term_p;
    fg.term_p = alt_fg_term;
    . . .
    return EXIT_SUCCESS;
}

fg_traverseline
Usage:
#include <fg.h>
void far fg_traverseline(int line_type, fg_const_pline_t line,
                         fg_coord_t far *pt_pair_buff);

Description:
Fills an array with x, y points that traverse a line. Useful with
fg_filloutline. The point pairs are put in the buffer pt_pair_buff
which must be supplied by the user. The worst case size (solid line)
requirements for the buffer can be obtained with the aid of a call to
fg_linepixels.

Example:
unsigned int get_line_points(fg_coord_t *buff, fg_const_pline_t line)
{
    unsigned int buff_size = fg_linepixels(line);
    buff = malloc(buff_size * 2 * sizeof(fg_coord_t));
    if (buff)
        fg_traverseline(FG_LINE_SOLID, line, buff);
    else
        buff_size = 0;
    return buff_size;
}

fg_writebox
Usage:
#include <fg.h>
void far fg_writebox(fg_const_pbox_t box, fg_color_t *p);

Description:
Inverse of fg_readbox. Writes the pixels to the screen. The argument box
is the bounding box of where the data is to be written. p is a pointer to
an array of colors, one color for each pixel in the bounding box box.

Example:
See fg_readbox

See Also: fg_readbox

fgetc
Usage:
#include <stdio.h>
int fgetc(FILE *fp);
ANSI

Description:
fgetc reads and returns the next character from the stream fp. The
character is returned as an integer in the range of 0 to 255.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int ch;
    fputs("Enter data terminated by Ctrl-Z: ",stdout);
    while((ch = fgetc(stdin)) != EOF) fputc(ch,stdout);
    return EXIT_SUCCESS;
}

Return Value: Returns the character just read on success, or EOF if
              end-of-file or a read error is encountered. Note that the
              return value should always be assigned to a variable of
              type int, or an error cannot be detected.

See Also: fputc, putchar, getc, getchar, getche, getch.

fgetpos
Usage:
#include <stdio.h>
int fgetpos(FILE *fp, fpos_t pos);

Description:
The function fgetpos gets the current position of the stream fp. The
position is stored in pos. The format of fpos_t is internal, the value
in pos can be used to reset the position of the stream pointer later
using fsetpos.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fpos_t pos;
    char dump[64];

    fp = fopen("temp.fil","rb");
    fread(dump,1,64,fp);

    /* Save current position */
    if (fgetpos(fp,pos) != 0) {
        perror("fgetpos failed");
        return EXIT_FAILURE;
    }
    fread(dump,1,64,fp);

    /* back to previous position */
    if (fsetpos(fp,pos) != 0) {
        perror("fsetpos failed");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise non-zero and errno is set.

See Also: fsetpos

fgets
Usage:
#include <stdio.h>
char *fgets(char *str,int n,FILE *fp);
ANSI

Description:
Reads characters from stream fp into the string pointed to by str. The
integer argument n indicates the maximum number of characters that the
buffer str can store. Reading stops when a newline is read, end-of-file
is encountered, a read error occurs, or n-1 characters were read.
Newlines are included in the string. The string read is terminated
with a 0.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buffer[255];
    int buflen;
    char *result;
    buflen = 255;
    fputs("Enter line of data\n",stdout);
    result = fgets(buffer,buflen,stdin);
    if(!result)
        printf("\nEOF or ERROR\n");
    else
        fputs(buffer,stdout);
    return EXIT_SUCCESS;
}

Return Value: String str if successful. If no characters have been read
              into str and a read error or EOF is encountered, NULL is
              returned and the string pointed to by str is unchanged.
              If a read error occurs, NULL is returned and str contains
              garbage.

See Also: fputs, gets, puts

filelength
Usage:
#include <io.h>
long filelength(int fd);

Description:
filelength returns the length in bytes of the file associated with the
file descriptor fd. The fd argument must point to a file which is already
open. The filelength function differs from filesize in that it is used on
a file that is already open.

Example:
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, *argv[])
{
    int fd;
    long l;

    if (argc < 2) {
        printf("Usage: fl 'filename'\n");
        exit(EXIT_FAILURE);
    }

    fd = open(argv[1],O_RDONLY,0);
    if (fd == -1) {
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }
    l = filelength(fd);

    printf("File %s is %ld bytes long\n",argv[1],l);

    if (close(fd) == -1) {
        perror("Error closing file");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: filelength returns the length of the file in bytes as
              a long integer. The current read/write position within the
              file is unaltered.

See Also: filesize

fileno
Usage:
#include <stdio.h>
int fileno(FILE *fp);

Description:
fileno returns the file descriptor associated with stream fp. The fp
argument must point to a file which is already open.

The fileno function converts a file pointer to a file descriptor for use
with the low-level file functions such as close, read and write. Mixing
of high and low level functions is not recommended.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int fd;
    fd = fileno(stderr);
    printf("The file handle for stderr is %d\n",fd);
    fd = fileno(stdaux);
    printf("The file handle for stdaux is %d\n",fd);
    fd = fileno(stdprn);
    printf("The file handle for stdprn is %d\n",fd);
    return EXIT_SUCCESS;
}

Return Value: fileno returns the file descriptor. There is no error
              return.

See Also: fopen, freopen

filesize
Usage:
#include <io.h>
long filesize(char *filename);

Description:
filesize determines the size of a file in bytes. The filename must be an
existing file that is not currently open.

Example:
#include <io.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    long size;

    size = filesize ("file.dat");
    printf("The filesize of file.dat is %ld \n",size);
    return EXIT_SUCCESS;
}

Return Value: The length of the file in bytes is returned upon success,
              otherwise a -1L is returned and errno is set.

See Also: stat, fstat

findfirst
Usage:
#include <dos.h>
struct FIND *findfirst(char *pathname,int attribute);

Description:
The system calls findfirst and findnext are used to find files matching
a file description possibly containing wild cards (i.e.  *  or  ? ). The
wild cards can be in the file name or extension, but not the path. The
attribute argument is the file attribute of the files to be found.

More than one attribute bit can be passed in the findfirst call. The
attribute bits are defined in dos.h and are:

        Attribute       Bit Mask
               
        FA_RDONLY       0x01
        FA_HIDDEN       0x02
        FA_SYSTEM       0x04
        FA_LABEL        0x08
        FA_DIREC        0x10
        FA_ARCH         0x20

A value of 0 for the attribute will find all normal files. A pointer to a
static structure (defined in dos.h) is returned upon success, otherwise a
NULL is returned.

Example:
See findnext.

Return Value: A pointer to a static struct FIND as defined in dos.h is
              returned on success. A NULL pointer indicates the end of
              filename matches or an error (such as no matching files).

findnext
Usage:
#include <dos.h>
struct FIND *findnext(void);

Description:
The system calls findfirst and findnext are used to find files matching
a file description possibly containing wild cards (i.e.  *  or  ? ). The
wild cards can be in the file name or extension, but not the path. The
attribute argument is the file attribute of the files to be found. The
attribute bits are defined in dos.h (see findfirst)

A value of 0 for the attribute will find all normal files. A pointer to a
static structure (defined in dos.h) is returned upon success, otherwise a
NULL is returned. The pointer to the returned structure is static, so if
the information is needed after a call to findnext, then the structure
must be copied to another buffer. The system call findnext gets the next
match of the file name specified in the preceding findfirst call.
findnext must be called only after a findfirst call.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    struct FIND *p;
    printf("Directory listing of *.*\n");
    p = findfirst("*.*",0);
    while(p)
        {
            printf(" %s\n",p->name);
            p = findnext();
        }
    return EXIT_SUCCESS;
}

Return Value: A pointer to a static struct FIND as defined in dos.h is
              returned on success. A NULL pointer indicates the end of
              filename matches or an error.

floor
Usage:
#include <math.h>
double floor (double x);
ANSI

Description:
floor returns the largest integer (as a double-precision number)
not greater than x.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double d;
    d = floor(4.8);
    printf("The floor of 4.8 is %f\n",d);
    d = floor(-4.2);
    printf("The floor of -4.2 is %f\n",d);
    return EXIT_SUCCESS;
}

Return Value: floor returns the double result.

See Also: ceil, fmod

flushall
Usage:
#include <stdio.h>
int flushall(void);

Description:
flushall flushes the I/O buffers for all open streams. Output buffers
are written to their associated files and input buffers are cleared. All
streams remain open after a call to flushall. Any read operation reads
new data into the buffers.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int totalflushed;
    totalflushed = flushall();
    return EXIT_SUCCESS;
}

Return Value: flushall returns the number of open streams.

See Also: fflush

fmod
Usage:
#include <math.h>
double fmod (double x,double y);
ANSI

Description:
fmod is used to obtain the floating point remainder of two numbers. It
returns x if x is zero, or the number F with the same sign as x, such
that x = L * y + F for some integer L, and |F| < |Y|.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x, y, d;
    x = 5.0;
    y = 3.0;
    d = fmod(x, y);
    printf("fmod (%.2f, %.2f) is %f",x,y,d);
    return EXIT_SUCCESS;
}

Return Value: fmod returns the floating point remainder.

See Also: ceil, floor, modf

fopen
Usage:
#include <stdio.h>
FILE *fopen(char *name,char *mode);
ANSI

Description:
fopen opens a file. name gives the filename to be opened. mode is a
character string indicating how the file is to be opened. Possible
values for mode are:

"r"              for reading

"w"              for writing (truncates any existing file with the same
                 name)

"a"              for appending (if file exists then open for writing at
                 end of file, else create the file)

"r+"             for reading and writing

"w+"             for reading and writing (if file exists then truncate
                 it, else create it)

"a+"             for reading and writing (if file exists, position at end
                 of file, else create it)

In addition, a b may be appended to the mode string to indicate that the
file is to be opened in binary mode (the default is text mode). If a file
is opened for reading and writing, only reads or only writes can be done
at any one time. To switch from reading to writing, or vice versa, an
fseek must be performed on the stream, unless during input an EOF was
read.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fp = fopen("file.dat","r");
    printf("Open text file\n");
    if(fp) fclose(fp);
    fp = fopen("file.dat","a+");
    printf("ASCII update file\n");
    if(fp) fclose(fp);
    return EXIT_SUCCESS;
}

Return Value: fopen returns a FILE pointer to an open file.
              A NULL pointer value indicates an error.

See Also: fclose, freopen, open

FP_OFF FP_SEG
Usage:
#include <dos.h>
unsigned FP_OFF(int far *fpointer);
unsigned FP_SEG(void far *fpointer);

Description:
FP_OFF and FP_SEG are used to split far pointers into their offset and
segment parts. These functions are implemented as macros.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char far *p;
    unsigned int segment, offset;
    p = MK_FP(0xb000,0);
    segment = FP_SEG(p);
    offset  = FP_OFF(p);
    printf("The mono video segment:offset ");
    printf("is at %04x:%04x \n", segment,offset);
    return EXIT_SUCCESS;
}

Return Value: FP_SEG returns the 16-bit segment value of the far pointer.
              FP_OFF returns the 32-bit offset of the far pointer.

See Also: MK_FP

fprintf
Usage:
#include <stdio.h>
int fprintf (FILE *fp, const char *format, ...);
ANSI

Description:
fprintf, printf and sprintf are the formatted print routines.
fprintf writes its characters to the file stream fp.

Arguments are interpreted according to the zero terminated format string.
The format string is a sequence of characters with embedded conversion
commands. Characters that are not part of the conversion command are
output. Conversion commands consist of:

    '%'{flag}[field_width]['.' precision]['l' or 'L']conversion_char

where a % always signifies the beginning of a conversion command. To
print a (%) use (%%).


Flag Characters

-                Means left justify the conversion.

+                Means that signed conversions always start with a + or -.

Space            means that for positive conversions, the conversion will
                 start with a space. The + flag overrides the space flag.

#                For x or X conversions, if the result is non-zero then
                 a 0x or 0X will be added to the front of it. For o
                 conversions, a leading 0 will be added. For floating
                 conversions (e, E, f, g, G), a decimal point will always
                 appear. If it is g or G, then trailing 0 s will not be
                 truncated.


field_width

Decimal integer controlling the minimum number of characters printed. If
the actual number of characters is less than the field_width, it is
padded with blanks. If the field_width digit string begins with a 0, it
is padded with a 0.

If the field_width is the character *, the actual field_width value is
taken from the next int arg. If the field_width is negative, it is
treated as if the - flag were given and the absolute value of the
field_width is used. If there are more characters than allowed for by the
field_width, then the width is expanded appropriately.

precision

.                Followed by a digit string specifying the precision of
                 the conversion. If no digits appear after the ".", then
                 the precision is taken as 0. For integral conversions,
                 this is the minimum number of digits. For g and G, the
                 precision gives the maximum number of significant digits.
                 For e, E, and f, it is the number of digits appearing
                 after the decimal point. For s, it is the maximum number
                 of characters in a string. If the precision starts with
                 a 0, then the conversion is 0 padded.

l                Lower case L. If a o, u, x, X, i, d  or b conversion
                 character is specified, then the argument is taken to be
                 a long, except for a p conversion, when the argument is
                 taken to be a far pointer. For all other conversion
                 characters, it is ignored.

L                This flag is ignored.

conversion_char

One of the characters b,d, i, o, u, x, X, f, e, E, g, G, c, s, p, n, %.
Other characters cause undefined behavior.

b,d,i,o,u,x,X    The argument is an integer and it is converted to a
                 string of digits according to the conversion character.
                 b is unsigned binary, o is unsigned octal, u is unsigned
                 decimal, x and X are unsigned hex, i and d are signed
                 decimal. For x, lower-case hex letters are used. For X,
                 upper-case ones are used. If no precision is specified,
                 it defaults to one. If there are fewer digits than
                 precision, leading spaces are placed before the digits.
                 If the argument is 0 and the precision is 0, no
                 characters are printed.

c                The least significant byte of the integer argument is
                 printed as a character.

e,E              The argument is a double. It is printed using scientifc
                 notation, ([-]d.dddddde+- dd). There is one digit before
                 the decimal point and precision digits after. The
                 precision defaults to 6. If the precision is 0, the
                 decimal point is not written. E is used for the exponent
                 instead of e if the E conversion character was specified.
                 A minimum of two digits will appear in the exponent.

f                The argument is a double. It is converted to a decimal
                 string of the form [-]dd.dddd. The number of digits
                 after the decimal point is given by the precision, which
                 defaults to 6. If the precision is 0, no fractional
                 digits or decimal points appear.

g,G              The argument is a double. It is printed using f or e (or E
                 if G was specified) format, depending on the value of
                 the argument. e will be used if the exponent is <-3 or >
                 the precision. The precision gives the number of
                 significant digits; it defaults to 6. The decimal point
                 appears if followed by a digit; trailing 0 s are
                 truncated.

n                The argument is a pointer to an int, into which is
                 written the number of characters printed so far. No
                 characters are generated or converted by this.

p                The argument is a pointer which is printed as
                 segment:offset for far pointers or as xxxx for near
                 pointers.

s                The argument is a pointer to a string. The characters
                 are printed until a 0 is encountered or the number of
                 characters specified in precision are printed. The
                 terminating 0 is not printed. The precision defaults to
                 32767.

%                The % character is printed.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *msg = "Integer formats are: ";
    int in = 10;

    fprintf(stdout, "%sHex: 0%x Dec: %d Oct: %o Bin: %b\n",
            msg, in, in, in, in);
    return EXIT_SUCCESS;
}

Return Value: Returns the number of characters written or a negative
              value on error.

See Also: printf, scanf, sprintf, vprintf, vsprintf, vfprintf

fputc
Usage:
#include <stdio.h>
int fputc(int c,FILE *fp);
ANSI

Description:
fputc writes the character c to the stream fp.

Example:
#include <stdio.h>
#include <stdlib.h>

FILE *fp;

int main()
{
    char *line = "This is an example ";
    fp = stdout;
    while (*line)
        fputc (*line++, fp);
    return EXIT_SUCCESS;
}

Return Value: fputc returns the last character output to the stream.
              An EOF is returned on error.

See Also: fgetc, getc, getchar

fputs
Usage:
#include <stdio.h>
int fputs(const char *s,FILE *fp);
ANSI

Description:
fputs writes the string s (excluding the terminating 0) to the stream fp.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    if (fputs ("Hello World\n", stdout) == EOF) {
        fprintf(stderr, "Output error\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: Returns non-negative if successful, EOF if a write error
              occurred.

See Also: fgets, gets, puts

fread
Usage:
#include <stdio.h>
size_t fread (const void *p,size_t sizelem,size_t n,FILE *fp);
ANSI

Description:
Reads n elements from stream fp into the array that p points to.
sizelem is the number of bytes in each element.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *dest;
    int size = 1;
    int number = 256, numread;
    FILE *fp;

    if((fp = fopen("file.dat","r")) == NULL)
        return EXIT_FAILURE;
    dest = calloc(256,1);
    numread = fread(dest,size,number,fp);
    printf("Total read %d\n",numread);
    fprintf(stdout,"Data read\n %s",dest);
    free(dest);
    return EXIT_SUCCESS;
}

Return Value: fread returns the number of complete elements actually read.
              If an error or an end of file is encountered, it will return
              less than n.

See Also: fwrite, read

free
Usage:
#include <stdlib.h>
void free(void *p);
ANSI

Description:
free releases memory pointed to by p. p must have been allocated using
calloc, malloc, or realloc. p can be NULL, in which case free does
nothing

 Caution - do not free data items more than once or refer to data
 after it has been freed.

If free detects that the heap has become corrupted it will abort the
program with an error messsage: Heap is corrupted!

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *p;
    if((p = malloc(1000)) == NULL) {
        printf("Unable to allocate memory\n");
        return EXIT_FAILURE;
    }
    free(p);
    return EXIT_SUCCESS;
}

See Also: calloc, malloc, realloc

freopen
Usage:
#include <stdio.h>
FILE *freopen(const char *name,const char *mode,FILE *fp);
ANSI

Description:
Closes file indicated by fp. Errors while closing the file are ignored.
Open a new file and associate the stream fp with it. name and mode have
the same meaning as in fopen.

Example:
#include <stdio.h>
#include <stdlib.h>

FILE *fp;

int main()
{
    fp = freopen("file.dat", "w+", stdout);
    if(fp == NULL) {
        fprintf(stderr,"error on freopen\n");
        return EXIT_FAILURE;
    }
    else
        fprintf(fp,"This data will go to file.dat\n");
    return EXIT_SUCCESS;
}

Return Value: freopen returns fp if successful, otherwise a NULL.

See Also: fclose, fopen, open

frexp
Usage:
#include <math.h>
double frexp(double value,int *eptr);
ANSI

Description:
Splits the double value into x and e such that (value == x*(2e) and
x > 0.5 and x <= 1.0). e is stored in *eptr and x is returned. If value
is 0.0, then both x and e are 0.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double d1, d2;
    int i;
    d2 = 15.3;
    d1 = frexp(d2, &i);
    printf("d1 = %f si = %d\n",d1,i);
    return EXIT_SUCCESS;
}

Return Value: frexp returns the mantissa x.

See Also: ldexp, modf

fscanf
Usage:
#include <stdio.h>
int fscanf (FILE *fp, const char *format, ...);
ANSI

Description:
Reads characters from the input stream fp. Characters read are converted
according to the format string and the values created are stored through
the argument pointers.

 Note that the arguments are pointers to where values are to be stored.

The format string consists of:

1. Spaces, tabs and newlines which cause input to be skipped up to the
next character which is not a whitespace.

2. Other characters, except for % which are matched against the input.

3. A conversion specification, which is as follows:

    '%' ['*'] [field-width] [precision] conv_char

This specifies how input characters are to be converted and assigned
through the corresponding argument pointers. Conversion continues until a
conflicting input character is encountered or the field_width is reached.

*  is an assignment suppression flag. It causes the conversion to be
performed but the result is ignored. There is no corresponding argument
pointer for this.

If there are less argument pointers than conversion specification the
results are unpredictable. If there are extra argument pointers the
excess ones are ignored.

field_width is a sequence of decimal digits specifying the maximum number
of characters in the field.

precision

L, l             If l is used with one of the (b, d, i, o, u, or x)
                 conversion characters, then it indicates that the
                 argument is a pointer to a long rather than a pointer
                 to an int. The l or L flag, when used with the e or f
                 conversion character, means that the argument is a
                 pointer to a double rather than a pointer to a float.

h                Argument is a pointer to a short. Conversion Characters:
                 conv_char The conversion characters are:

b                A binary number is expected, the argument pointer must be
                 a pointer to an int.

d                An integer is expected, the argument pointer must be a
                 pointer to an int. e, E, f, g, GA floating point
                 number is expected. The format of the number is the same
                 as in C. The argument pointer must be a pointer to a
                 float (double if l or L is used).

i                An integer is expected. If it starts with a 0, it is
                 taken to be octal. If it starts with 0x or 0X, it is
                 hexadecimal. The argument pointer must be a pointer to
                 an int.

o                An octal number is expected. The argument pointer must
                 be a pointer to an int.

p                A hexadecimal integer is expected. The argument pointer
                 must be a pointer to a pointer.

u                An unsigned integer is expected, the argument pointer
                 must be a pointer to an unsigned.

n                Through the argument pointer is stored an integer
                 specifying the number of characters read up to this
                 point by this call to fscanf.

[                A string is expected. Between the [ and a closing ] will
                 be the characters acceptable to the string. If the [ is
                 immediately followed by a ^ (caret) the acceptable
                 characters for the string are all those except the ones
                 between the ^ and the ]. The argument pointer must be a
                 pointer to a string. A 0 is appended to the string.

s                A string is expected. The argument pointer must be a
                 pointer to a string. The input field extends until a
                 space or newline is read, which is not part of the
                 field. A 0 is appended to the string.

c                A character is expected. The argument pointer must be a
                 pointer to a character. If a field_width is specified,
                 then that many characters are read and the argument
                 pointer must point to a character array large enough to
                 hold the result.

%                Match the input with a %.

The conversion characters e, g and x may be in capitals, with no
difference in meaning. Other conversion characters will cause unexpected
results. Conflicting characters are left unread in the input stream.
There is no direct way to determine if suppressed assignments or literal
matches succeeded, unless %n is used.

Example:
#include <stdio.h>

char fst[10], *lst = "     ";
int ttl;

int main()
{
    int rt;
    rt = fscanf(stdin, "%s %s %d", fst, lst, &ttl);
    printf("Values read %s %s %d\n", fst, lst, ttl);
    return rt == 3;
}

Return Value: The number of assigned input items excluding any assignment
              suppressed conversions is returned. If the end of file is
              encountered before any assignments are done or before any
              conflicts occur, an EOF is returned. fscanf() normally
              returns when it reaches the end of the format string.

See Also: printf, scanf, sscanf

fseek
Usage:
#include <stdio.h>
#include <io.h>
int fseek(FILE *fp,long offset,int origin);

ANSI

Description:
Sets the file position associated with the stream fp. offset is the
signed offset in bytes relative to that specified by origin. Values for
origin are defined in io.h:

        SEEK_SET        beginning of file
        SEEK_CUR        current position
        SEEK_END        end of file

If the file is opened in text mode, offset can only be a value returned
by ftell and origin can only be SEEK_SET, or offset must be 0. If an
ungetc was done immediately before an fseek, the ungetc is undone. If the
file was opened in read/write mode (see fopen), following the fseek
either reading or writing may be performed.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fp = fopen("file.dat","r+");
    fseek(fp, 0L,SEEK_END);     /* Move to end of file   */
    fseek(fp, 0L,SEEK_SET);     /* Move to start of file */
    fseek(fp, 200L,SEEK_SET);   /* Move to offset 200    */
    return EXIT_SUCCESS;
}

Return Value: fseek returns 0 if the pointer was successfully moved.
              fseek returns !=0 if an error occurred.

See Also: ftell, lseek

fsetpos
Usage:
#include <stdio.h>
int fsetpos (FILE *fp, fpos_t pos);

Description:
The function fsetpos restores the position of the stream fp as previously
saved in pos by a call to fgetpos. The format of fpos_t is internal.

Example:
See fgetpos

Return Value: 0 if successful, otherwise non-zero and errno is set.

See Also: fgetpos

fstat
Usage:
#include <sys\stat.h>
int fstat(int fd,struct stat *buf);

Description:
fstat function gets information about an open file fd and stores it
in the structure that buf points to. The structure stat contains the
following fields:

st_dev          Drive number of disk containing file fd or,
                value of fd if fd is a device.
st_mode         Bit mask containing mode information on the open file.
                S_IFCHR     Set if fd refers to a device
                S_IFREG     Set if fd refers to an ordinary file
                S_IREAD     Set if file is open for reading.
                S_IWRITE    Set if file is open for writing.
st_nlink        Number of links (always 1)
st_rdev         Same as st_dev
st_size         Size of open file in bytes
st_atime        Time last modified
st_mtime        as above
st_ctime        as above
st_ino          Always 0.
st_uid          Always 0.
st_gid          Always 0.

Example:
#include <dos.h>
#include <sys\stat.h>
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>

struct stat buf;
int fh, result;

int main()
{
    fh = open("file.dat",O_RDONLY);
    result = fstat(fh,&buf);
    if(result != 0) {
        printf("Bad file handle\n");
        return EXIT_FAILURE;
    } else {
        printf("File size : %ld\n",buf.st_size);
        printf("Drive number : %d\n",buf.st_dev);
        printf("Time modified : %s",
        ctime(&buf.st_mtime));
    }
    return EXIT_SUCCESS;
}

Return Value: fstat returns a value of 0 if file information is successfully
              obtained. If a value of -1 is returned errno is set to EBADF
              indicating a bad file handle.

See Also: stat, findfirst, findnext, isatty

ftell
Usage:
#include <stdio.h>
long ftell(FILE *fp);
ANSI

Description:
ftell returns the current position in the file associated with the
stream fp. If the file is opened in text mode, the returned value may
not accurately reflect the number of bytes actually read or written.

Example:
#include <stdio.h>
#include <stdlib.h>

FILE *fp;

int main()
{
    long position;

    fp = fopen("file.dat","a");
    fprintf(fp,"Sample data string\n");
    position = ftell(fp);   /* get file position */
    printf("Position of file pointer: %ld\n",position);
    fclose(fp);
    return EXIT_SUCCESS;
}

Return Value: ftell returns the current file position. A -1L is returned
              if an error occurred and errno is set.

See Also: fseek, isatty

fwrite
Usage:
#include <stdio.h>
size_t fwrite (const void *buffer, size_t sizelem, size_t n, FILE *fp);
ANSI

Description:
The function fwrite writes n elements of sizelem bytes each pointed to
by buffer to the stream fp.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *buffer;
    unsigned sizelem,n;
    FILE *fp;
    int wrtn;
    buffer = calloc(255,1);
    sizelem = 1;
    n = 255;
    fp = fopen("file.dat","a");
    strcpy(buffer,"\nSample data\n");
    wrtn = fwrite(buffer,sizelem,n,fp);
    free(buffer);
    return EXIT_SUCCESS;
}

Return Value: The function fwrite returns the number of complete elements
              actually written which may be less than n if an error
              occurred.

See Also: fread, write

getc
Usage:
#include <stdio.h>
int getc(FILE *fp);
ANSI

Description:
getc obtains one character from the stream fp. Input is buffered and
therefore a carriage return is required before the character is returned.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    printf("Input a character then press return: ");
    c = getc(stdin);
    printf("%c is an example of getc\n", c);
    return EXIT_SUCCESS;
}

Return Value: Returns the next character read. getc returns a value of
              EOF on error.

See Also: fgetc, getch, getchar, getche, putc, putchar, ungetc

getch
Usage:
#include <conio.h>
int getch(void);

Description:
getch obtains a character from stdin. Input is unbuffered and, therefore,
this routine will return as soon as a character is available without
waiting for a carriage return. The character is not echoed to stdout.
getch bypasses the normal buffering done by getchar and getc. ungetc
cannot be used with getch.

Example:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    printf("Press a function key and then a character");
    c = getch();
    printf("\nCharacter [%c] is an example of getch",c);
    return EXIT_SUCCESS;
}

Return Value: Returns the next character read. getch never returns an
              error.

See Also: fgetc, getc, getchar, getche, putc, putchar, ungetc

getchar
Usage:
#include <stdio.h>
int getchar(void);
ANSI

Description:
getchar obtains a character from the stream stdin.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    printf("Input a character then press return: ");
    c = getchar();
    printf("%c is an example of getchar\n", c);
    return EXIT_SUCCESS;
}

Return Value: Returns the next character read. getchar returns a value of
              EOF on error.

See Also: fgetc, getc, getch, getche, putc, putchar, ungetc

getche
Usage:
#include <conio.h>
int getche(void);

Description:
getche obtains a character from stdin with echo. This routine will return
as soon as a character is available and not await a carriage return.
getche is the same as getch except that the character is echoed to
stdout. Like getch it bypasses the normal buffering done by getchar and
getc. ungetc cannot be used with getche.

Example:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    printf("Input a character: ");
    c = getche();
    printf(" Is an example of getche\n");
    return EXIT_SUCCESS;
}

Return Value: Returns the next character read. getche never returns an
              error.

See Also: fgetc, getc, getch, getchar, putc, putchar, ungetc

getcwd
Usage:
#include <direct.h>
char *getcwd (char *buffer, int length);

Description:
Stores the drive and path name of the current directory in buffer. If
buffer is NULL, getcwd will malloc enough bytes to hold the path
including the terminating 0. At least length bytes will be allocated.

Example:
#include <direct.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *buff;
    if((buff = getcwd(NULL,0)) == NULL) {
        perror("getcwd error");
        return EXIT_FAILURE;
    } else
        printf("%s",buff);
    return EXIT_SUCCESS;
}

Return Value: Returns buffer on success. A return value of NULL indicates
              an error and errno is set to ENOMEM - out of memory.

See Also: chdir, mkdir, rmdir

getDS
Usage:
#include <io.h>
int getDS(void);

Description:
getDS returns the value of the data segment register.

 In the X and P memory models, getDS returns the actual value in the DS
 register. This will be the protected mode segment selector. This is not
 the base address of DGROUP.  You should use __X386_get_abs_addr() to
 find DGROUP.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    unsigned int data_seg;
    data_seg = getDS();
    printf("The current contents of DS are %x\n", data_seg);
    return EXIT_SUCCESS;
}

Return Value: The current value in the data segment register DS
              is returned.

See Also: segread

getenv
Usage:
#include <stdlib.h>
char *getenv(const char *name);
ANSI

Description:
getenv searches the environment list for a string of the form
"NAME=value" and returns a pointer to the value string, if such
a string is present. The NAME string should be capitalized.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *path;
    path = getenv("PATH");
    printf("PATH = %s\n", path);
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the value string of an environment
              variable. A return value of NULL indicates the name was not
              found in the environment.

gets
Usage:
#include <stdio.h>
char *gets(char *str);
ANSI

Description:
Read characters from stdin into the string str until a newline is read
or an end-of-file is encountered. Newlines are not written to the string.
The string is terminated with a 0. str must be large enough to hold the
resulting string.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buffer[125];
    printf ("Type in a string: ");
    gets (buffer);
    printf ("The string typed was: %s\n", buffer);
    return EXIT_SUCCESS;
}

Return Value: Returns str if successful. A NULL is returned if an
              end-of-file is encountered and no characters have been
              written to str, or if a read error occurs.

See Also: fgets, puts

The Handle Package
The Handle package is a set of functions which allow the programmer
dynamically to allocate and use handle memory. Currently the Handle
package supports EMS (LIMS) memory. Handle memory is manipulated by
means of a special pointer type, the __handle pointer.The programmer
can use calls to handle_malloc, handle_calloc, handle_realloc and
handle_free to allocate memory from handle memory in a similar fashion
to the standard memory allocation routines.

The handle allocation functions return a __handle pointer which can,
with a few restrictions, be used in the same way as any other pointer.
A special function, handle_strdup, is provided to make a copy of a string
in handle space. Handle pointers can be used in most situations that a
far data pointer could be used, for instance as function arguments in the
compact and large memory models. A __handle pointer should be assigned to
a normal far pointer before being passed to a formatted print routine.
Handle memory cannot currently be used for code.

The use of handle memory can be "locked out" by #defining NO_HANDLE
before including handle.h, in which case any use of handle pointers and
functions defaults to normal pointers and memory allocation routines.

 If there is no handle (EMS) memory present in the host system the
 Handle package acts as if NO_HANDLE were defined. This also occurs
 under OS/2 and when the Z, X or P memory models are used. For more
 information on __handle pointers please refer to the chapter The Handle
 Pointer Type in the Compiler Reference.

Example:
#include <stdio.h>
#include <handle.h>
#include <stdlib.h>

/* C and L models ONLY */

int main()
{
    char __handle *hptr;
    char __handle *cptr;
    char *p;

    hptr = handle_malloc(256);

    if (handle_ishandle(hptr) == 0)
        sprintf(hptr,"This string is in normal memory");
    else
        sprintf(hptr,"This string is in handle memory");

    p = hptr;
    printf("%s - handle pointer is %p\n",p,hptr);

    cptr = handle_strdup(hptr);
    p = cptr;
    printf("%s - this time from %p\n",p,cptr);

    handle_free(hptr);
    handle_free(cptr);
    printf("All Handles freed\n");
    return EXIT_SUCCESS;
}

handle_calloc
Usage:
#include <handle.h>
void __handle *handle_calloc (unsigned size);

Description:
Allocate and clear a block of data, size bytes long, from handle memory.

Return Value: A __handle pointer to the allocated memory.

See Also: calloc, handle_malloc, handle_free

handle_free
Usage:
#include <handle.h>
void handle_free(void __handle *hptr);

Description:
Free the memory pointed to by the __handle pointer hptr, that was
previously allocated by handle_malloc or handle_calloc.

See Also: handle_malloc, handle_calloc

handle_ishandle
Usage:
#include <handle.h>
int handle_ishandle (void __handle *hptr);

Description:
Tests whether hptr is a true __handle pointer or a far pointer. If there
is no handle memory present __handle pointers default to being normal
pointers.

Implemented as a macro in handle.h.

Return Value: 1 if hptr is a __handle pointer otherwise 0.

See Also: handle_malloc, handle_calloc

handle_malloc
Usage:
#include <handle.h>
void __handle *handle_malloc (unsigned size);

Description:
Allocate a block of memory of size bytes from handle space.

Return Value: A __handle pointer to the allocated memory.

See Also: malloc, handle_calloc, handle_free

handle_realloc
Usage:
#include <handle.h>
void __handle *handle_realloc (void __handle *hptr, unsigned nbytes);

Description:
Reallocates (changes the size of) a block of memory that was allocated by
handle_malloc or handle_calloc.

Return Value: A __handle pointer to the reallocated data block.

See Also: realloc, handle_malloc, handle_calloc

handle_strdup
Usage:
#include <handle.h>
char __handle *handle_strdup (char __handle *hptr);

Description:
Uses handle_malloc to allocate a block of memory in handle space, and
then makes a copy of the string pointed to by the __handle pointer hptr
in the allocated memory.

Return Value: A __handle pointer to the duplicated string.

See Also: handle_malloc, strdup

hypot
Usage:
#include <math.h>
double hypot (double x, double y);

Description:
Calculates the length of the hypotenuse of a right-angled triangle with
sides of length x and y. The hypotenuse is the value obtained by taking
the square root of the sums of the squares of x and y (sqrt(x*x+y*y)).

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x,y;
    printf("Enter floating point x: ");
    scanf("%lf",&x);
    printf("Enter floating point y: ");
    fflush(stdin);
    scanf("%lf",&y);
    printf("The hypotenuse of [%lf, %lf] is ",x,y);
    printf("[%lf]\n",hypot(x,y));
    return EXIT_SUCCESS;
}

Return Value: The hypotenuse of a right-angled triangle with sides x and y.

index
 The function index has been removed from the libraries. The function
 was identical to strchr which is ANSI C, use that instead.

inp inpw
Note - These function are not available under OS/2.

Usage:
#include <dos.h>
int inp (int port_address);
int inpw (port_address);

Description:
This is a C interface to the hardware ports using the in 80x86 I/O
instructions.

inp reads a byte from the specified port.
inpw reads a word from the specified port.

The compiler will generate inline code for these. The real library
functions can be called if #undef inpw and #undef inp are inserted
in the source file after #include <dos.h>.

Return Value: The value read from the port is returned.

Example:
/* This function will turn off the MDA cursor */
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int porta, portb, bytea, byteb;

int main()
{
    char result;
    porta = 0x3b4;
    portb = 0x3b5;
    bytea = 10;
    byteb = 32;
    result = inpw (porta);
    printf("The value from port %#x is %x hex\n", porta, result);
    outp (porta, bytea);
    outp (portb, byteb);
    return EXIT_SUCCESS;
}

/* File 2 - This function will turn on the MDA cursor */
#include <dos.h>
#include <stdlib.h>

int porta, portb, bytea, byteb;

int main()
{
    porta = 0x3b4;
    portb = 0x3b5;
    bytea = 10;
    byteb = 11;
    outp (porta, bytea);
    outp (portb, byteb);
    return EXIT_SUCCESS;
}

See Also: outp, outpw

int86 intreal
Note - These functions are not available under OS/2.

Usage:
#include <dos.h>  /* register structures */
int int86 (int intnum, union REGS *regsin, union REGS *regsout);
int intreal (int intnum, union REGS *regsin, union REGS *regsout);

Description:
int86() performs a software interrupt where:

intnum   is the interrupt number (0..255).
regsin   is a pointer to a structure containing the values of the
         registers AX, BX, CX, DX, SI and DI to be passed to the
         interrupt.
regsout  is a pointer to a structure into which the return values
         of the registers will be written.

The REGS structure is defined in dos.h. Consult your system hardware and
software manuals to determine what the interrupt numbers are and what
they do on your machine.

 intreal() is only available in the X and P memory models. See below
 for an explanation.

Special Consideration for the X and P Memory Models

In the X and P memory models, the functions bdos(), bdosx(), int86(),
int86x(), intdos(), and intdosx() employ some filtering of parameters
sent to the real mode interrupt. For example if DOS function 40h (write)
is detected, the source buffer is copied to a buffer in conventional
memory (dos-buffer) and a pointer to dos-buffer is passed to DOS since
DOS could not properly use the buffer located in extended memory. If the
information passed is larger than DOS-buffer, there are multiple calls
to DOS to transfer all information, which may be much larger than 64k.

Where pointers are passed to these functions, they are assumed to contain
protected mode addresses. The filtering routine used for these functions
assumes that all far pointers passed in registers to DOS have a segment
address of DGROUP. If you use int86x() to execute int 21h and specify
selectors other than DGROUP, the results will be unpredictable. It is
possible to bypass this filtering by using the function int_real()
instead of int86(). This function bypasses all protected mode filtering
in both the Phar Lap and DOSX extenders and executes the interrupt in
real mode.  It can be used to retrieve real mode segment values from the
BIOS or from DOS if desired.

Under the X memory model, not all DOS calls are supported in the
filtering process. DOS calls (listed in hex) that are completely
supported include:

0 - 9
b, d, e, 19
2a - 2e
30, 33, 36
39 - 43
45 - 47
4c - 4f
54 - 58
5b - 5c
62 (returns protected mode selector, not real mode segment)
63
66 - 68

Partial support:

c    (AL = 0, AH not supported)
1a   (DTA set to a location in conventional memory)
2f   (Get DTA returns protected mode address of DTA in conventional
      memory)
44   (Subfunctions 2, 3, 4, 5, c and d are not supported)
59   (Information at ES:DI not available)
5a   (Information at ds:dx is not available)

Functions not supported:

a
f - 17
1b - 1c
21 - 29
2f
31
35
38
48 - 4b
5e - 5f
65

Some of the functions which are not currently supported will be supported
in future versions of the DOSX 386 memory model. Refer to your Phar Lap
documentation for information about supported DOS functions in the P
memory model.

Example:
/*
  These functions accept input from the keyboard and write
  the string to the screen via BIOS
*/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXKEY 19
#define BEEP printf("\007")

void print(void);
void biosprt(void);
char buf[MAXKEY],*ptr;
int colm = 30,i;
union REGS r;

int main() {
    system("cls");
    printf("Enter a 20 character string\n\n\n");
    gets(buf);
    if (strlen(buf)  > 20)
        printf("String to long, truncating\n");
    print();
    BEEP;
    return EXIT_SUCCESS;
}

void print() {
    r.h.ah = 0x02;
    r.h.bh = 0;
    r.h.dh = 12;
    r.h.dl = colm;
    int86(0x10,&r,&r);
    for (ptr = buf, i=0; i <= MAXKEY; (biosprt()), i++, ptr++)
       ;
}

void biosprt() {
    r.h.ah = 0x09;
    r.h.al = *ptr;
    r.x.cx = 1;
    r.h.bl = 0x0f;
    r.h.bh = 0;
    int86 (0x10, &r, &r);

    r.h.ah = 0x02;
    r.h.bh = 0;
    r.h.dh = 12;
    r.h.dl = ++colm;
    int86 (0x10, &r, &r);
}

Return Value: int86 returns the value in the AX register at the completion
              of the interrupt. The state of the carry flag can be
              determined from x.cflag in regsout. Do not use int86 for
              interrupts 0x25 or 0x26. Use dos_abs_disk_read / write for
              those.

See Also: int86x, intdos, bdos

int86x intrealx
Note - These functions are not available under OS/2.

Usage:
#include <dos.h>  /* register structures */
int int86x (int intnum, union REGS *regsin, union REGS *regsout,
            struct SREGS *segregs);
int intrealx (int intnum, union REGS *regsin, union REGS *regsout,
            struct SREGS *segregs);

Description:
int86x() performs a software interrupt where:

intnum   is the interrupt number (0 through 255).
regsin   is a pointer to a structure containing the values of the
         registers AX, BX, CX, DX, SI and DI to be passed to the
         interrupt.

segregs  is a pointer to a structure containing the values of the
         segment registers to be passed to the interrupt. It is also
         used to return the values in the segment registers after the
         interrupt has completed.
regsout  is a pointer to a structure into which the return values of the
         registers will be written.

The REGS and SREGS structures are defined in dos.h. Consult your system
hardware and software manuals to determine what the interrupt numbers are
and what they do on your machine.

 intrealx() is only available in the X and P memory models. See below
 for an explanation.

Under the X and P memory models int86() and int86x() carry out some
filtering of parameters sent to the real mode interrupt. This filtering
allows data stored in extended memory to be passed to the DOS function so
that, for instance, much larger buffers than normal can be used with the
DOS disk functions. Where pointers are passed to int86(), they are
assumed to contain protected mode addresses. The filtering routine used
for these functions assumes that all far pointers passed in registers to
DOS have a segment address of DGROUP. If you use int86x() and specify a
selector other that DGROUP the results will be unpredictable.. It is
possible to bypass this filtering by using the function int_real(x)
instead of int86x(). This function bypasses all protected mode filtering
in both the Phar Lap and DOSX extenders and executes the interrupt in
real mode.  It can be used to retrieve real mode segment values from the
BIOS or from DOS if desired.

 Some of the available DOS functions are not supported or only partially
 supported in the X and P memory models. Refer to the entry for int86()
 for more information.

Return Value: int86x returns the value in the AX register at the
              completion of the interrupt. The state of the carry flag
              can be determined from x.cflag in regsout. Do not use
              int86x for interrupts 0x25 or 0x26. Use dos_abs_disk_read /
              write for those.

See Also: int86, intdos, bdos

intdos
Note - This function is not available under OS/2.

Usage:
#include <dos.h> /* register structures */
int intdos (union REGS *regsin, union REGS *regsout);

Description:
This function performs a MS-DOS system call (int 0x21). Consult an
MS-DOS manual for specific function and calling conventions.

regsin   is a pointer to a structure containing the values of the
         registers AX, BX, CX, DX, SI and DI to be passed to the
         interrupt.
regsout  is a pointer to a structure into which the return values of the
         registers will be written.

The state of the carry flag can be determined from x.cflag in regsout.
The union REGS is defined in dos.h

Under the X and P memory models intdos() and intdosx() carry out some
filtering of parameters sent to the real mode interrupt. This enables
MS-DOS functions running in real mode to access data stored in extended
memory.

 Some of the available DOS functions are not supported or only partially
 supported in the X and P memory models. Refer to the entry for int86()
 for more information.

Return Value: The value that was in AX at the end of the interrupt.

See Also: int86, int86x, intdosx, bdos

intdosx
Note-This function is not available under OS/2.

Usage:
#include <dos.h> /* register structures */
int intdosx (union REGS *regsin, union REGS *regsout,
             struct SREGS *segregs);

Description:
This function performs a MS-DOS system call (int 0x21). Consult an
MS-DOS manual for specific function and calling conventions.

regsin    is a pointer to a structure containing the values of the
          registers AX, BX, CX, DX, SI and DI to be passed to the
          interrupt.
regsout   is a pointer to a structure into which the return values of the
          registers will be written.

The state of the carry flag can be determined from x.cflag in regsout.
The segregs structure contains the segment register values passed to the
interrupt for the intdosx. It is also used to return their values after
the interrupt has been processed. The union REGS and struct SREGS are
defined in dos.h.

Under the X and P memory models intdos() and intdosx() carry out some
filtering of parameters sent to the real mode interrupt. This filtering
allows data stored in extended memory to be passed to the DOS function so
that, for instance, much larger buffers than normal can be used with the
DOS disk functions. Where pointers are passed to intdosx(), they are
assumed to contain protected mode addresses. The filtering routine used
for these functions assumes that all far pointers passed in registers to
DOS have a segment address of DGROUP. If you use intdosx() and specify a
selector other that DGROUP the results will be unpredictable.

 Some of the available DOS functions are not supported or only partially
 supported in the X and P memory models. Refer to the entry for int86()
 for more information.

Example:
#include <dos.h>
#include <stdlib.h>

union REGS inregs, outregs;
struct SREGS segregs;

int main()
{
    char far *string = "Print this string$";
    inregs.h.ah = 9;
    inregs.x.dx = FP_OFF(string);
    segregs.ds = FP_SEG(string);
    intdosx(&inregs,&outregs,&segregs);
    return EXIT_SUCCESS;
}

Return Value: The value that was in AX at the end of the interrupt.

See Also: int86, int86x, bdos

The Interrupt Package
The Interrupt package is designed to be a general purpose 80x86 interrupt
handling package. New interrupt handlers can be defined for each vector.
The function handling the interrupt controls whether the interrupt is
chained to the previous interrupt vector or not.

Zortech C++ has support for interrupt service routines in a different way
to most other C and C++ compilers. It is done with library functions
instead of a keyword. The advantage is that the library will create a
stack for the interrupt service routine of a specified size, and the
stack will conform to the constraints of the memory model used.

 These functions are not available under OS/2.

There are several rules that must be followed when handling interrupts
in C++. They are:

1. No DOS calls or BIOS calls may be made during the handling of the
interrupt, if the interrupt could occur when DOS or BIOS is executing.
This is because DOS and BIOS are not re-entrant. Beware of functions
like new and malloc which use DOS calls internally.

2. Do not let the interrupt handler, or any function called by it, use
more than the allocated stack space. If the handler is intended to be re-
entrant, use a stacksize of zero to int_intercept so that a local stack
is not created and the normal program stack is used instead.

3. Do not call any function that is not re-entrant, for example be
careful in your use of global variables. (Unpredictable results will
occur.)

4. Do not perform any I/O from within the interrupt handler, this is
especially true for high level file I/O.

5. When using variables set by interrupt handlers, declare the variables
to be volatile.

6. Turn off stack overflow checking for the handler.

 WARNING: Intercepting interrupts is an advanced technique and requires
 a good understanding of DOS and the IBM family of PCs to use it
 successfully.

Example:
#include <int.h>
#include <stdio.h>
#include <stdlib.h>

volatile int ctrl_c_count = 0;

#ifdef __cplusplus
extern "C"
#endif

int do_ctrl_c (struct INT_DATA *pd)
{
     ++ctrl_c_count;
     return 1;
}

int main()
{
    int_intercept (0x23, do_ctrl_c, 256); /* set handler */
    while (ctrl_c_count < 3)
       printf ("Number of Ctrl Cs is %d\n", ctrl_c_count);
    int_restore (0x23);                   /* reset old handler */
    return EXIT_SUCCESS;
}

int_gen
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
void int_gen(int intno)

Description:
The function int_gen is used to generate a standard Intel 80x86
interrupt, where intno is the interrupt to generate. The function is
actually implemented inline in the header file int.h as asm(0xCD,i).

Example:
#include <int.h>
#include <stdlib.h>

int main()
{
    int_gen (5);        /* print-screen interrupt */
    return EXIT_SUCCESS;
}

See Also: The int_ functions.

int_getvector
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
void int_getvector (unsigned vector, unsigned *poffset,
                    unsigned *psegment);

Description:
int_getvector obtains the contents of the specified interrupt vector,
splits it into its segment and offset components and stores each in the
unsigned integers pointed to by poffset and psegment.

int_intercept
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
int int_intercept (unsigned vector, int (*funcptr)(struct INT_DATA *pd),
                   unsigned stacksize);

Description:
int_intercept links a standard C function to an interrupt vector for
handling the interrupt when the interrupt occurs. The funcptr is a
pointer to the C function that will handle the interrupt. This function
must be declared as taking C linkage. The vector argument defines which
interrupt vector the function will be attached to (0..255). The stacksize
argument is the number of bytes of memory allocated for the stack within
the interrupt handler. stacksize should be a minimum of 256 bytes, except
that if stacksize is 0, no stack is allocated, and the program stack is
used. This is essential for interrupt routines that are required to be
re-entrant, such as serial handlers for example.

If a zero value is returned from the interrupt handler (*funcptr)() then
the previous interrupt vector for this vector is called else a return
from interrupt is performed.

Values in registers can be read/written through the pointer (pd) to the
INT_DATA struct which is passed to (*funcptr)().

Return Value: The value returned from int_intercept indicates success or
              failure. A zero is returned on success otherwise -1.

int_off
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
void int_off(void);

Description:
int_off will turn off the interrupts via a CLI (clear interrupt flag)
instruction.

int_on
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
void int_on (void);

Description:
int_on will turn the interrupts on via an STI (set interrupt flag)
instruction.

int_prev
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
long int_prev (struct INT_DATA *idp)

Description:
The function int_prev can be used to call the standard interrupt handler
from within a user-handler which has been installed using int_intercept.
The parameter *ipd can be used to pass register values into the routine.
On exit it contains the register values at the end oawthe standard
interrupt handler.

Return Value: A long containing the values in the DX and AX registers
              at the end of the called routine.

See Also: The int_ functions.

int_restore
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
int int_restore (unsigned vector);

Description:
int_restore will unlink the first interrupt handler which was hooked into
the specified vector via int_intercept. This function must not be called
unless an interrupt handler was linked to the vector using int_intercept.

int_restore is the complement to the int_intercept function.

Return Value: The value returned from int_restore indicates success or
              failure. A zero is returned on success otherwise -1.

int_setvector
 Note - This function is not available under OS/2.

Usage:
#include <int.h>
void int_setvector (unsigned vector, unsigned offset, unsigned segment);

Description:
int_setvector installs the address of a user routine supplied in offset
and segment in the specified interrupt vector.

isatty
Usage:
#include <io.h>
int isatty (int fd);

Description:
isatty determines if the handle fd is associated with a terminal,
printer, or a serial port.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    if (isatty (fileno(stdin)))
        printf ("stdin is connected to keyboard\n");
    else
        printf ("stdin is connected to a file\n");
    return EXIT_SUCCESS;
}

Return Value: The function isatty returns a non-zero value if the device
              is a terminal, console, etc. and a zero if not (like a disk
              file).

See Also: fstat

The isxxxx Macros (ANSI)
Usage:
#include <ctype.h>
int isalnum (int c);
int isalpha (int c);
int isascii (int c);
int iscntrl (int c);
int isdigit (int c);
int isgraph (int c);
int islower (int c);
int isprint (int c);
int ispunct (int c);
int isspace (int c);
int isupper (int c);
int isxdigit (int c);

Description:
isalnum          Determines if a character is not a symbol, i.e. is
                 alphanumeric by table lookup. Only values of c between
                 -1 and 255 are valid. This macro is also implemented as
                 a function in the library.

isalpha          Determines if c is a letter by table lookup. Only values
                 of c between -1 and 255 are valid. This macro is also
                 implemented as a function in the library.

isascii          Determines if c is between 0 and 127. This macro is also
                 implemented as a function in the library.

iscntrl          Determines if c is a control character (0 to 0x1F), or
                 c == 0x7F by table lookup. Only values of c between -1
                 and 255 are valid. This macro is also implemented as a
                 function in the library.

isdigit          Determines if the character is a digit by table lookup.
                 Only values of c between -1 and 255 are valid. This
                 macro is also implemented as a function in the library.

isgraph          Determines if c is a printing character (excluding the
                 space) by table lookup. Only values of c between -1 and
                 255 are valid. This macro is also implemented as a
                 function in the library.

islower          Determines if character is lower case by table lookup.
                 Only values of c between -1 and 255 are valid. This
                 macro is also implemented as a function in the library.

isprint          Determines if c is a printing character (including the
                 space) by table lookup. Only values of c between -1 and
                 255 are valid. This macro is also implemented as a
                 function in the library.

ispunct          Determines if c is a punctuation character by table
                 lookup. Only values of c between -1 and 255 are valid.
                 This macro is also implemented as a function in the
                 library.

isspace          Determines if character is "white space", that is, a tab,
                 line feed, vertical tab, form feed, return or space by
                 table lookup. Only values of c between -1 and 255 are
                 valid. This macro is also implemented as a function in
                 the library.

isupper          Determines if c is an upper-case character by table
                 lookup. Only values of c between -1 and 255 are valid.
                 This macro is also implemented as a function in the
                 library.

isxdigit         Determines if c is one of the characters 0 to 9, A to F
                 or a to f by table lookup. Only values of c between -1
                 and 255 are valid. This macro is also implemented as a
                 function in the library.

Example:
#include <ctype.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main()
{
    int i;
    char *ans[2] = { "not ", "" };
    for (i = -1; i < 255; i++) {
        printf ("\n\n\nThe value %02x is :\n");
        printf ("%salphanumeric\n", ans[(isalnum(i) != 0)]);
        printf ("%sa letter\n", ans[(isalpha(i) != 0)]);
        printf ("%sascii\n", ans[(isascii(i) != 0)]);
        printf ("%sa control\n", ans[(iscntrl(i) != 0)]);
        printf ("%sa digit\n", ans[(isdigit(i) != 0)]);
        printf ("%sprintable/not a space\n", ans[(isgraph(i) != 0)]);
        printf ("%slower case\n", ans[(islower(i) != 0)]);
        printf ("%sprintable\n", ans[(isprint(i) != 0)]);
        printf ("%sa punctuator\n", ans[(ispunct(i) != 0)]);
        printf ("%swhite space\n", ans[(isspace(i) != 0)]);
        printf ("%supper case\n", ans[(isupper(i) != 0)]);
        printf ("%sa hexadecimal digit\n", ans[(isxdigit(i) != 0)]);
        printf ("* Press a key for the next value *\n");
        getch();
        }
    return EXIT_SUCCESS;
}

Return Value:
    isalnum     Returns non-zero if c is a letter or a digit.
    isalpha     Returns non-zero if c is a letter.
    isascii     Returns non-zero if c is between 0 and 127.
    iscntrl     Returns non-zero if c is a control character
                (0 to 0x1F), or c == 0x7F.
    isdigit     Returns non-zero for the digits 0 to 9.
    isgraph     Returns non-zero if c is a printing character
                (excluding the space).
    islower     Returns non-zero if c is a lower-case character.
    isprint     Returns non-zero if c is a printing character
                (including the space).
    ispunct     Returns non-zero if c is a punctuation character.
    isspace     Returns non-zero for tabs, linefeeds, vertical tabs,
                form feeds, carriage returns and spaces.
    isupper     Returns non-zero if c is an upper-case character.
    isxdigit    Returns non-zero if c is one of the characters 0 to 9,
                A to F or a to f.

itoa
Usage:
#include <stdlib.h>
char *itoa (int value, char *str, int radix);

Description:
itoa converts value to a null terminated string using a radix. The radix
specifies the base and must be in the range between 2 and 36. If value is
negative and the radix is 10, the first character of the stored string is
-'. The result is stored into the string pointed to by str, which must be
large enough to hold the result.

Example:
#include <stdlib.h>
#include <stdio.h>

int main()
{
    char buffer[10];
    int value = 67;
    char *ptr;
    ptr = itoa(value,buffer,2);
    printf("The number %d equals binary = \"%s\"\n",value,buffer);
    ptr = itoa(value,buffer,8);
    printf("The number %d equals octal = \"%s\"\n",value,buffer);
    ptr = itoa(value,buffer,16);
    printf("The number %d equals hex = \"%s\"\n",value,buffer);
    return EXIT_SUCCESS;
}

Return Value: itoa returns str. There is no error return.

See Also: ltoa

kbhit
Usage:
#include <conio.h>
int kbhit (void);

Description:
The kbhit function checks if a keyboard key has been pressed.

Example:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main()
{
    printf ("Hit any character key when ready\n");
    while (!kbhit())
        { ; }
    printf ("\nThe key pressed was (%c)\n", getch());
    return EXIT_SUCCESS;
}

Return Value: Returns non-zero if key pressed, otherwise it returns 0.

See Also: getch, getche

labs
Usage:
#include <stdlib.h>
long labs(long i);
ANSI

Description:
The labs function returns the absolute value of a long integer.

Example:
#include <stdlib.h>
#include <stdio.h>

int main()
{
    long lng,result;
    lng = -314159L;
    result = labs(lng);
    printf ("The absolute value of (%ld) is (%ld)\n", lng, result);
    return EXIT_SUCCESS;
}

Return Value: Returns the absolute value of a long integer.

See Also: abs

ldexp
Usage:
#include <math.h>
double ldexp (double x, int exp);
ANSI

Description:
The function ldexp multiplies a floating point number by an integral
power of two.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x, y;
    int exp;
    x = 1.5;
    exp = 5;
    y = ldexp (x, exp);
    printf ("The ldexp (%f exp %d) = %f\n", x, exp, y);
    return EXIT_SUCCESS;
}

Return Value: ldexp returns x* 2 raised to the power exp.

See Also: exp, frexp, log, log10, modf

ldiv
Usage:
#include <stdlib.h>
ldiv_t ldiv (long int numerator, long int denominator)
ANSI

Description:
The ldiv function divides the numerator by the denominator, returning
the quotient and remainder. If the denominator is 0 the program will
terminate with an error message. The arguments and the returned values
are all type long.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    long numer, denom;
    ldiv_t result;

    numer = 3;
    denom = 2;
    printf ("The numerator is %ld ", numer);
    printf ("and the denominator is %ld\n", denom);
    result = ldiv (numer, denom);
    printf ("The quotient is %ld \n", result.quot);
    printf ("The remainder is %ld \n", result.rem);
    return EXIT_SUCCESS;
}

Return Value: ldiv returns a structure of type ldiv_t, containing both
              quotient and remainder.

See Also: div

localeconv
Usage:
#include <locale.h>
struct lconv * localeconv (void);

Description:
localeconv returns a pointer to a filled in struct lconv which contains
information specific to a particular locale.

struct lconv looks like this:

struct lconv {
    char *decimal_point;
    char *thousands_sep;
    char *int_curr_symbol;
    char *currency_symbol;
    char *mon_decimal_point;
    char *mon_thousands_sep;
    char *negative_sign;
    char frac_digits;
    char p_cs_precedes;
    char p_sep_by_space;
    char n_sc_precedes;
    char n_sep_by_space;
    char n_sign_posn;
    char lc[6];
};

decimal_point     The decimal point character for non- monetary usage.
thousands_sep     The separator to be used in non-monetary usage to the
                  left of the decimal point.
int_curr_symbol   The international currency symbol used in the locale.
currency_symbol   The local currency symbol.
mon_decimal_point The decimal point character for monetary usage.
mon_thousands_sep The separator to be used in monetary usage to the left
                  of the decimal point.
negative_sign     A string to indicate a negative monetary quantity.
frac_digits       The number of digits to display to the right of the
                  decimal point for a monetary quantity.
p_cs_precedes     1 if currency_symbol is a prefix, 0 if currency_symbol
                  is a suffix for positive monetary quantities.
p_sep_by_space    1 if currency_symbol is separated by a space from a
                  positive monetary quantity, 0 if there is no space.
n_cs_precedes     1 if currency_symbol is a prefix, 0 if currency_symbol
                  is a suffix for a negative monetary quantity.
n_sep_by_space    1 if currency_value is separated by a space from a
                  negative monetary quantity, 0 if there is no space.
n_sign_posn       A value that indicates how to position negative_sign
                  for a negative monetary quantity.
lc[6]             The current state of the locale. LC_XXX forms the index
                  of this array. Its values are from _LOCALE enumeration
                  in locale.h.

Example:
See setlocale

Return Value: A pointer to a struct lconv. The values contained within
              the structure should be regarded as read only.

See Also: setlocale

localtime
Usage:
#include <time.h>
struct tm *localtime (time_t *stime);
ANSI

Description:
localtime converts a time stored as a time_t value to the structure tm.
The time_t value stime is the seconds elapsed since 00:00:00 GMT on
January 1, 1970. This value can be obtained from the function time.
localtime makes corrections for time zones and possible daylight savings
time. The fields of the structure tm are:

struct tm {
    tm_sec,         /* seconds 0..59                 */
    tm_min,         /* minutes 0..59                 */
    tm_hour,        /* hour of day 0..23             */
    tm_mday,        /* day of month 1..31            */
    tm_mon,         /* month 0..11                   */
    tm_year,        /* years since 1900              */
    tm_wday,        /* day of week, 0..6 (Sun..Sat)  */
    tm_yday,        /* day of year, 0..365           */
    tm_isdst;       /* >0 if daylight savings time   */
                    /* ==0 if not DST, <0 don't know */
};

Return Value: localtime returns a pointer to a static structure tm
              which is overwritten by each call to localtime().

Example:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct tm *t;
    time_t ltime;

    time (&ltime);
    t = localtime (&ltime);
    printf ("The date is %d-%d-%d\n", t->tm_mday, t->tm_mon+1,
             t->tm_year);
    return EXIT_SUCCESS;
}

See Also: time, asctime, ctime, mktime

locking
Usage:
#include <sys\locking.h>
#include <io.h>
int locking (int fd, int mode, long size);

Description:
The locking function locks or unlocks a section of the file associated
with the file handle fd. This operation is used for record locking in
files that are shared by multiple applications in a multi-tasking or
network environment. Locking a section of the file prevents other
applications from reading or writing that section while it is being
updated. The section is then unlocked to allow other applications to read
and write to it. The file is locked from the current position of the file
pointer for the next size bytes. The mode argument specifies which of
several locking functions is to be applied:

LK_LOCK, LK_RLCK Locks the specified number of bytes. If they cannot be
                 locked it will retry after 1 second. This is repeated
                 until 10 attempts have failed at which point the
                 function will return an error.

LK_NBLCK, LK_NBRLCK Locks the specified number of bytes. If they cannot
                 be locked, returns an error.

LK_UNLCK         Unlocks the specified number of bytes. The file pointer
                 and size must have exactly the same values as when the
                 section was locked.

Multiple regions of a file can be locked, but no regions may overlap.
No more than one region can be unlocked with one call to locking.

Example:
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys\locking.h>
#include <sys\types.h>

int main()
{
    int fd;

    if ((fd = open("temp.fil",O_RDONLY)) == -1)
        {
        perror("Error opening file");
        exit(EXIT_FAILURE);
        }

    lseek (fd, 0L, SEEK_SET);
    if ((locking(fd, LK_NBLCK, 20)) == -1)
        {
        perror("Locking operation failed");
        exit(EXIT_FAILURE);
        }
    else
        {
        printf("Locking operation successful\n");
        lseek (fd, 0L, SEEK_SET);
        locking (fd, LK_UNLCK, 20);
        }
    close (fd);
    return EXIT_SUCCESS;
}

Return Value: Returns 0 if successful, otherwise -1 if an error occurred
              and errno is set.

See Also: creat, open

log
Usage:
#include <math.h>
double log (double x);
ANSI

Description:
log returns the natural logarithm of x. The value of x must be > 0.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char **argv)
{
    double d, result;
    d = atof (argv[1]);
    result = log(d);
    printf("The log of %.2f is %f\n", d, result);
    return EXIT_SUCCESS;
}

Return Value: The log function returns the logarithm result or domain
              error if x < 0, range error if x == 0.

See Also: exp, log10, pow, sqrt

log10
Usage:
#include <math.h>
double log10(double x);
ANSI

Description:
log10 returns the logarithm base ten of x. (x must be > 0).

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    double d, result;
    d = atof (argv[1]);
    result = log10 (d);
    printf ("The log10 of %.2f is %f\n", d, result);
    return EXIT_SUCCESS;
}

Return Value: The log10 function returns the logarithm result or domain
              error if x < 0, range error if  x == 0.

See Also: exp, log, pow, sqrt

longjmp setjmp
Usage:
#include <setjmp.h>
void longjmp (jmp_buf env, int value);
ANSI
int setjmp (jmp_buf env);
ANSI

Description:
These functions allow a goto between functions. They are good for
dealing with errors or interrupts encountered in low-level subroutines
of a program.

setjmp saves the stack environment in the variable env for later use by
longjmp.

longjmp restores the environment previously saved by setjmp in jmp_buf
and is pointed to by envp. The return value is that of setjmp.

 NOTE: The environment must have been previously saved using setjmp by
 a function that is currently active, and which is the same function or
 a parent of the function containing the call to longjmp.

After completion of longjmp, program execution continues just as if the
corresponding call to setjmp had just returned with value. The value will
never be 0. If value is passed as 0, the value 1 will be returned.

Return Value: setjmp returns a 0. There is no return value for longjmp.

Example:
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>

void docall (void);
jmp_buf environment;
int error_val = -1;

int main()
{
    int error_code;
    error_code = setjmp (environment);
    if (error_code != 0)
        {
            printf ("Longjmp called\n");
            exit (EXIT_FAILURE);
        }
    printf ("Setjmp called\n");
    docall ();
    return EXIT_SUCCESS;
}

void docall (void)
{
    longjmp (environment, error_val);
}

_lrotl _lrotr
Usage:
#include <stdlib.h>
unsigned long _lrotl (unsigned long val, int shift);
unsigned long _lrotr (unsigned long val, int shift);

Description:
The functions _lrotl and _lrotr carry out a binary rotation of the
supplied unsigned long, value, by shift bits.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned long value = 0x01234567;

    printf ("_lrotl(value,4) = 0x%8.81x\n", _lrotl(value,4));
    printf ("_lrotr(value,12) = 0x%8.81x\n", _lrotr(value,12));
    return EXIT_SUCCESS;
}

Return Value: Both of these functions return the rotated value as an
              unsigned long. There is no error return.

See Also: _rotl, _rotr

lseek
Usage:
#include <io.h>
long lseek (int fd, long offset, int mode);

Description:
lseek changes the read/write pointer for a file given by file descriptor
fd. Values for mode are:

SEEK_SET    The pointer is moved to offset bytes from the beginning of
            the file.
SEEK_CUR    Moved to the current location plus offset.
SEEK_END    Moved to the end of the file plus the offset.

Example:
#include <stdio.h>
#include <io.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    int fp;
    long offset, lpos;
    fp = open ("file.dat", O_RDWR);
    if (fp <  0) return;
    offset = 0L;
    lpos = lseek (fp, offset, SEEK_SET);
    printf ("Current position of seek = %ld\n", lpos);
    offset = 10L;
    lpos = lseek (fp, offset, SEEK_CUR);
    printf ("Current position of seek = %ld\n", lpos);
    offset = 50L;
    lpos = lseek (fp, offset, SEEK_END);
    printf ("Current position of seek = %ld\n", lpos);
    close (fp);
    return EXIT_SUCCESS;
}

Return Value: lseek returns the offset in bytes of the new position from
              the beginning of the file. A -1 is returned on error, and
              errno is set.

See Also: fseek

ltoa
Usage:
#include <stdlib.h>
char *ltoa (long number, char *string, int radix);

Description:
The ltoa() function converts a long integer into a null terminated string
using a radix. The radix specifies the base and must be in the range 2
through 36, using the numbers 0 to 9 and letters A to Z for the digits 0
through 35. Attempts to use any other number base will cause ltoa() to
ignore the number base argument and convert to decimal. Also note that
all conversions for bases other than 10 are unsigned. The arguments are:

number   the number to convert
string   the buffer in which to build the string
radix    the number base to use (range: 2 through 36)

Example:
#include <stdio.h>
#include <stdlib>

int main()
{
    char numbuf[20];

    puts (ltoa (123456L, numbuf, 10)); /* prints 123456   */
    puts (ltoa (-1L, numbuf, 0));      /* prints -1       */
    puts (ltoa (-1L, numbuf, 16));     /* prints FFFFFFFF */
    return EXIT_SUCCESS;
}

Return Value: A pointer to the converted string

See Also: itoa

malloc
Usage:
#include <stdlib.h>
void *malloc (size_t numbytes);
ANSI

Description:
malloc allocates a block of memory that is numbytes in size. If numbytes
is 0, NULL is returned.

Example:
#include <stdlib.h>
#include <stdio.h>
#define NUM_INTS 7623

int main()
{
   int *memblock;

    memblock = malloc (NUM_INTS*sizeof(int));
    if (memblock == NULL) {
        printf ("Insufficient memory\n");
        return EXIT_FAILURE;
    }
    else
        printf ("Memory allocated\n");
    free (memblock);
    return EXIT_SUCCESS;
}

Return Value: Pointer to the memory block allocated. NULL is returned if
              not enough memory is available, or if numbytes is 0.

See Also: calloc, free, realloc, farmalloc

matherr
Usage:
#include <math.h>
int matherr (struct exception *e);

Description:
matherr is called by functions in the math library when errors are
detected. Users may use the library supplied matherr function or define
their own procedures for handling errors by including a function named
matherr in their programs. matherr must be of the form described above.

A pointer to the exception structure will be passed to the user supplied
matherr function when errors occur. The structure is defined in math.h
and matherr is available in the library source for an example.

Return Value: A zero returned from matherr means the error was handled
              correctly, a one returned means the error could not be
              handled.

Example:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    printf ("log(-1) = %e\n", log(-1));
    return EXIT_SUCCESS;
}

int matherr (x)
struct exception *x;
{
    if (x->type == DOMAIN) {
       if (strcmp(x->name,"log") == 0) {
          x->retval = log(-(x->arg1));
          return(1);
       }
    }
    return(0);
}

The Memory Package
This is a set of ANSI C functions for manipulating memory buffers.
They are very closely related to the functions in the String package
but do not expect a buffer to be null terminated.

Memory package functions expect their pointer arguments to match the
memory model in use. Do not use explicit near or far pointers unless
this is the case.

The Memory package can be split into three functional groups and some
miscellaneous function, as follows:

Copying Functions

Two functions are provided for copying blocks of memory, memcpy and
memmove. These are generally equivalent except that memcpy cannot
handle overlapping moves. memmove can do this, but is slower in
operation.

Comparison Functions

Two comparison functions are provided which allow blocks of memory to be
compared, memcmp and memicmp. The difference here is that memcmp treats
upper and lower case as distinct whereas memicmp does not.

Search Functions

A single function memchr locates the first occurrence of a byte in a
memory block.

Miscellaneous Functions

The function memset is used to set a block of memory to a known value.
This could be used to clear all bytes in the block to zero, for instance.

Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char srccpy[] = "Sample string 2\n";

int main()
{
    char buffer[50];
    char buffer2[50];
    char *result;
    int reslt;

    strcpy (buffer2, "Sample String\n");
    printf ("memcpy function in progress\n");
    memcpy (buffer, buffer2, 15);
    printf ("memchr function in progress\n");
    result = memchr (buffer, 't', 50);
    if (result != NULL)
        printf ("Character (t) found at (%d)\n", result - buffer +1);
    else
        printf ("Error - (t) not found\n");
    printf ("memcmp function in progress\n");
    reslt = memcmp (buffer, buffer2, 50);
    printf ("The result of memcmp is: %s\n", reslt);
    printf ("memicmp function in progress\n");
    reslt = memicmp (buffer, buffer2, 50);
    printf ("The result of memicmp is: %s\n", reslt);
    printf ("buffer before memmove: %s", buffer);
    result = memmove(buffer,srccpy,sizeof(srccpy));
    printf ("buffer after memmove: %s", buffer);
    printf ("buffer before memset: %s", buffer);
    result = memset (buffer, 'x', 6);
    printf ("buffer after memset: %s", buffer);
    return EXIT_SUCCESS;
}

See Also: movedata, peek, poke, The String Package

memchr
Usage:
#include <string.h>
void *memchr (const void *buf1, int c, size_t count);
ANSI

Description:
memchr searches in the buffer, buf, for a byte with the value of c. The
search continues for count bytes or until a value of c is encountered.

Example:
See The Memory package

Return Value: memchr returns a pointer to the location of c in buf if
              found, otherwise a NULL.

See Also: memcpy, memcmp, memset, strcmp, strcat, strset, strchr

memcmp
Usage:
#include <string.h>
int memcmp (void *buf1, const void *buf2, size_t count);
ANSI

Description:
memcmp compares each successive byte pointed to by pointer buf1 with the
corresponding byte pointed to by buf2 until they do not have the same
value or until the number of bytes specified in count have been compared.
memcmp returns an integer less than, equal to, or greater than zero,
depending on whether the last byte compared in the buffer pointed to by
buf1 is less than, equal to, or greater than the corresponding byte
pointed to by buf2.

Example:
See The Memory package

Return Value: memcmp returns a value which is (< 0) if buf1 is less than
              buf2, (=0) if buf1 equals buf2 and (> 0)if buf1 is greater
              than buf2.

See Also: memicmp, memchr, memcpy, memset, strcmp, strcat, strset, strchr

memcpy
Usage:
#include <string.h>
void *memcpy (void *buf1, const void *buf2, size_t count);
ANSI

Description:
memcpy copies the number of characters specified in count from buf2 to
buf1. buf1 is returned. memcpy is faster than memmove, but cannot handle
overlapping moves.

Example:
See The Memory package

Return Value: memcpy returns buf1.

See Also: memchr, memcmp, memmove, memset, strcmp, strcat, strset, strchr

memicmp
Usage:
#include <string.h>
int memicmp (const void *buf1, const void *buf2, size_t count);
ANSI

Description:
The function memicmp compares the first count characters from buf1
with those in buf2 on a byte for byte basis, without reference to the
case of the letters being compared. Uppercase and lowercase letters are
considered to be equivalent. All uppercase (capital) letters in both buf1
and buf2 are converted to lowercase before the comparison is done. This
function is identical to memcmp except that case is ignored.

Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buffer1[50];
    char buffer2[50];
    int result;

    strcpy (buffer1, "Sample String\n");
    strcpy (buffer2, "sample 2 String\n");
    printf ("memicmp function in progress\n");
    result = memicmp (buffer1, buffer2, 50);
    printf ("The result of memicmp is: %d\n", result);
    return EXIT_SUCCESS;
}

Return Value: memicmp returns an integer value which depends on the
              relationship of buf1 to buf2, as follows:
              < 0   buf1 less than buf2
              = 0   buf1 identical to buf2
              > 0   buf1 greater than buf2

See Also: memcmp, memchr, memcpy, memset

memmove
Usage:
#include <string.h>
void *memmove (void *buf1, const void *buf2, size_t count);
ANSI

Description:
memmove copies the number of characters specified in count from buf2 to
buf1. buf1 is returned.  memmove, slower than memcpy, can handle
overlapping moves.

Example:
See The Memory package

Return Value: memmove returns buf1.

See Also: memcpy, strcmp, strcat, strset, strchr

memset
Usage:
#include <string.h>
void *memset (void *buf, int val, size_t count);
ANSI

Description:
memset sets the first count characters pointed to by buf to the value
specified by val. It returns buf.

Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char buffer[20] = "Test string\n";

int main()
{
    printf ("buffer before memset: %s", buffer);
    memset (buffer, 'z', 8);
    printf ("buffer after memset: %s", buffer);
    return EXIT_SUCCESS;
}

Return Value: memset returns buf.

See Also: mem..., strcmp, strcat, strset, strchr

mkdir
Usage:
#include <direct.h>
int mkdir (char *pathname);

Description:
mkdir creates a new directory as specified by the pathname argument. If
pathname contains more than one directory component, then only the last
component may be new. All preceding components must refer to existing
directories.

Example:
#include <stdio.h>
#include <direct.h>
#include <stdlib.h>

int main()
{
    int result;
    result = mkdir("\temp");
    if(result == 0)
        printf("Directory \temp created\n");
    else {
        printf("Could not create directory \temp\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: Returns a 0 if the directory was created successfully.
              A -1 is returned if an error occurred, and errno is set.

See Also: rmdir, chdir

MK_FP
Usage:
#include <dos.h>
void far *MK_FP(unsigned seg, unsigned off);

Description:
Converts the unsigned segment and offset values to a far pointer.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char far *p;
    unsigned int segment = 0xb800, offset = 0;

    p = MK_FP (segment, offset);
    printf ("The CGA video buffer is at %lp\n", p);
    return EXIT_SUCCESS;
}

Return Value: MK_FP returns a far pointer.

See Also: FP_SEG, FP_OFF

mktime
Usage:
#include <time.h>
time_t mktime (struct tm *ntime);
ANSI

Description:
Converts from struct tm to time_t.

Example:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct tm ntime;
    time_t set;

    time(&set);
    ntime = *localtime(&set);
    printf("Seconds since 1 Jan 1970 is %ld\n", mktime(&ntime));
    printf("The time is %s\n", asctime(&ntime));
    return EXIT_SUCCESS;
}

Return Value: Time in seconds since 00:00:00 GMT on January 1, 1970 based
              on struct tm returned by localtime.

See Also: asctime, ctime, localtime, time

modf
Usage:
#include <math.h>
double modf (double x, double *ptr);
ANSI

Description:
modf returns the signed fractional value of x. The signed integral part
of x is stored at the location pointed to by ptr.

Example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double x, y, n;
    x = -41.56789;
    y = modf (x, &n);
    printf("modf(%f) = fractional: %f\n and integer: %f", x, y, n);
    return EXIT_SUCCESS;
}

Return Value: The function modf returns the signed fractional portion
              of x.

See Also: frexp, ldexp

movedata
Usage:
#include <string.h>
void movedata (unsigned srcseg, unsigned srcoff, unsigned dstseg,
               unsigned dstoff, size_t numbytes);

Description:
Copies numbytes bytes from the source address specified by segment srcseg
and offset srcoff to the destination address specified by segment dstseg
and offset dstoff.

This function is used to move data between segments. For normal intra-
segment movement of data memcpy or memmove are used instead.

 movedata does not handle overlapping moves correctly.

See Also: FP_OFF, FP_SEG, memcpy, memmove

msleep
Usage:
#include <time.h>
void msleep (long milliseconds);

Description:
Suspends execution of the program for the specified number of
milliseconds. The granularity depends on the operating system.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    printf ("Going to sleep for 10 seconds\n");
    msleep (10000);
    printf ("OK, back again now\n");
    return EXIT_SUCCESS;
}

See Also: sleep, usleep

The Mouse Package
The Mouse package is a C interface to the Microsoft mouse. Its use
requires a Microsoft compatible mouse driver to be installed. This
package is best used in conjunction with the mouse programming manual.

Converting Mouse Coordinates to Display Coordinates

The mouse coordinate system is left-handed for both text and graphics
modes, with 0,0 being the upper left corner.

Note that The Display package uses a left-handed coordinate system, but
Flash Graphics uses a right-handed system where 0,0 is the lower left
hand corner. Also note that the mouse coordinates in text mode are not in
character coordinates.

To convert from Flash Graphics coordinates to mouse coordinates use:

    mouse_x = fg_x;
    mouse_y = fg_displaybox[FG_Y2] - fg_y;

To convert from display (character) coordinates to mouse coordinates use:

    if (40 column mode)
        mouse_x = display_x * 16;
    else
        mouse_x = display_x * 8;
    mouse_y = display_y * 8;

The mouse driver sometimes gets the number of screen rows wrong in text
mode, so the recommended method of initializing the mouse if the display
package is also used is:

    disp_open();            /* initialize display */
    msm_init();             /* initialize mouse   */

    /* Mouse driver sometimes gets the number of screen rows wrong,
       so here we force it to whatever disp_open() discovered.
    */
    msm_setareay (0, (disp_numrows - 1) * 8);
    msm_showcursor();       /* mouse cursor on*/

Using the Mouse Package

The Mouse Package contains a large number of functions which fall
naturally into categories. By discussing these categories in turn, a
reasonable knowledge can be obtained of how these functions fit together
in developing a mouse driven application.

Initializing the Mouse Driver

There are two complementary functions provided within the Mouse package
which are concerned with initializing and closing down the mouse driver.
These are msm_init and msm_term.

The function msm_init attempts to initialize the mouse driver. This
function is required to be executed before any of the other mouse
functions can be used. If there is no mouse driver installed it will
return 0, otherwise it returns 1. A number of operations are carried out
by this function, including setting of the default cursor shape. For more
details look at the individual listing for msm_init.

The function msm_term closes down the mouse driver and cleans up the
display by removing the mouse cursor. Once msm_term has been called a
further msm_init is required to restart the mouse package.

Mouse Cursor Positioning

Three functions are involved with mouse positioning. The functions
msm_setareax and msm_setareay are used to restrict mouse cursor movements
to a particular rectangle, normally the screen coordinates. msm_init
normally sets these to reflect the screen size, but as mentioned above,
it sometimes gets them wrong due to a fault with the mouse driver.

The function msm_setcurpos is used to position the mouse cursor at an
arbitrary position on the screen.


Mouse Cursor Shape and Size

Two functions are concerned with the shape and size of the mouse cursor.
They are msm_setgraphcur, which sets the graphics cursor shape, and
msm_settextcur, which does the same for the text cursor. The graphics
cursor is the most flexible, since it is bit mapped on a 16 by 16 matrix.
The text cursor can only be used as a valid character and attribute
combination. A zero character with a blinking attribute mask allows a
flashing see-through block cursor to be used.

Controlling the Display of the Mouse Cursor

The three functions msm_hidecursor, msm_showcursor and msm_condoff
provide control over whether the mouse cursor is shown on the screen or
not. The mouse cursor must be hidden when writing to or updating the
screen, otherwise there is a risk of screen corruption.

The first two functions turn the mouse cursor off and on unconditionally.
These functions are normally used to bracket an instruction which updates
the display. Because there is a time penalty involved, it is best to
enclose a series of updates if possible, rather than each individual
update. The function msm_condoff will turn off the cursor only when it is
in a specified area of the screen. This is useful for an area of the
screen that is being continually updated, although any call to
msm_showcursor will disable this automatic hiding facility.

Adjusting Mouse Response

Two functions are used to modifying the response of the mouse to
movement. The function msm_setratio sets the sensitivity of the mouse.
Higher values mean that the mouse must be moved further to get the same
relative cursor movement. Generally, the higher the screen resolution,
the lower this ratio needs to be.

The second function is msm_setthreshold. This is used to set the
threshold speed for mouse movement. This threshold is where the
mouse/cursor ratio is temporarily halved so that the mouse appears to
move twice as quickly. This is used to provide fast movement of the mouse
cursor when a user wants to go to a menu for example, without sacrificing
precision when working on detail.

Testing for Mouse Events and Movement

Five functions are concerned with detecting mouse events, such as button
presses and mouse movement. One, msm_readcounters, is used to detect
motion, It reports how far the mouse has moved since the last call, and
in what direction. The movement is in mouse units (mickeys) and must be
converted into pixels with the aid of the mickey/pixel ratio as used by
msm_setratio.

The status function, msm_getstatus, returns the current cursor position
in pixels, and the current state of the mouse buttons, i.e. whether they
were up or down at the time the call was made.

There are two complementary event counting functions, msm_getpress and
msm_getrelease. These functions count the number of times the specified
button has been pressed (for msm_getpress) or released (for
msm_getrelease) since the last time the function was called. They also
indicate the cursor position when the last event was recorded. They are
often used in the situation where it is necessary to determine whether
the user is clicking a mouse button or attempting a drag. For example a
routine would be written using these functions to test a button. When a
button press is detected, the function waits a fixed interval for a
release. If it does not get one it assumes a drag is in progress.

The final function concerned with mouse events is msm_signal. This is
very different to the other functions discussed, in that it is not an
event monitoring function, but is used to install a user routine as a
handler which is then called whenever a mouse event occurs. This facility
allows mouse events to be handled asynchronously. When a mouse event
occurs, information is passed to the user s function detailing the event
that caused the signal, the current button status and the position of the
mouse cursor.

Light Pen Emulation

The final two functions msm_lightpenon and msm_lightpenoff, are involved
in making the mouse cursor emulate a light pen. When light pen emulation
is on (the default), movement of the mouse, and left and right buttons
being simultaneously pressed are reflected in the appropriate settings in
the light pen registers of the IBM PC BIOS.

Example:
#include <stdio.h>
#include <msmouse.h>
#include <stdlib.h>

int main()
{
    if (msm_init() == -1) {
       printf ("Mouse initialization succeeded\n");
       msm_showcursor();
       while (1) {
          int status;
          unsigned x, y;
          status = msm_getstatus (&x, &y);
          if (status & LEFT_BUTTON) {
             msm_hidecursor();
             printf("x = %u, y = %u\n", x, y);
             msm_showcursor();
          }
          if (status & RIGHT_BUTTON)
             break;
       }
       msm_term();
    } else {
       printf ("Mouse initialization failed\n");
       return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

msm_condoff
Usage:
#include <msmouse.h>
void msm_condoff (unsigned upperx, unsigned uppery,
                  unsigned lowerx, unsigned lowery);

Description:
Conditional off. The parameters define a rectangular region on the
screen. When the mouse is in that region, the mouse cursor is hidden.
This is useful if a portion of the screen is to be updated. A call to
msm_showcursor() will undo this and turn the mouse cursor back on.

See Also: msm_showcursor, msm_hidecursor

msm_getpress
Usage:
#include <msmouse.h>
int msm_getpress (unsigned *count, unsigned *curposx, unsigned *curposy);

Description:
Get button press information. On entering the routine count should point
to an integer designating which button we require information about
(0 = left button, 1 = right button, 2 = middle button). The function
places the number of times that the button has been pressed since the
last call to msm_getpress into count and the mouse position at the last
press into curposx and curposy. Values can be in the range 0 to 32767.

Return Value: It returns the state of all of the buttons as a bit pattern.
              Bit 0:  left button (1 == down, 0 == up)
              Bit 1:   right button
              Bit 2:  middle button
              All other bits should be ignored.

See Also: msm_getrelease

msm_getrelease
Usage:
#include <msmouse.h>
int msm_getrelease(unsigned *count,unsigned *curposx,unsigned *curposy);

Description:
Get button release information. On entering the routine count should
point to an integer designating which button we require information about
(0 = left button, 1 = right button, 2 = middle button). The function
places the number of times that the button has been released since the
last call to msm_getrelease into count and the mouse position at the
release press into curposx and curposy. Values can be in the range 0 to
32767.

Return Value: It returns the state of all of the buttons as a bit pattern.
              Bit 0:  left button (1 == down, 0 == up)
              Bit 1:  right button
              Bit 2:  middle button
              All other bits should be ignored.

See Also: msm_getpress

msm_getstatus
Usage:
#include <msmouse.h>
int msm_getstatus (unsigned *curposx, unsigned *curposy);

Description:
Get status. Places the current cursor position in the variables pointed
to by curposx and curposy.

Return Value: Returns the status of the mouse buttons as a bit pattern.
              Bit 0:  left button (1 == down, 0 == up)
              Bit 1:  right button
              Bit 2:  middle button
              All other bits should be ignored.

msm_hidecursor
Usage:
#include <msmouse.h>
void msm_hidecursor (void);

Description:
Hide cursor. Decrements the cursor flag. Complement to msm_showcursor().

See Also: msm_condoff, msm_showcursor

msm_init
Usage:
#include <msmouse.h>
int msm_init (void);

Description:
Initializes the mouse driver. This function turns off all mouse
interrupts and turns on light pen emulation, it is required before any
other mouse functions are used.

If in graphics mode the cursor is set to be an arrow, if in text mode,
it is set to be inverse video. The cursor is positioned in the middle of
screen, the cursor display is turned off and the min/max cursor position
is set to the full screen dimensions. Finally, the mickey/pixel ratio is
set to1/1 in the x direction and 2/1 in the y direction.

Return Value: Returns -1 if successful, otherwise 0 if initialization
              failed. Failure may indicate no mouse driver is present.

See Also: msm_term

msm_lightpenoff
Usage:
#include <msmouse.h>
void msm_lightpenoff (void);

Description:
Turns light pen emulation mode off.

Return Value: None.

See Also: msm_lightpenon

msm_lightpenon
Usage:
#include <msmouse.h>
void msm_lightpenon (void);

Description:
Turns light pen emulation mode on. The mouse emulates a light pen,that
is, the "pen" is off the screen when the left and right buttons are up,
and the "pen" is down when both buttons are down.

Return Value: None.

See Also: msm_lightpenoff

msm_readcounters
Usage:
#include <msmouse.h>
void msm_readcounters (int *countx, int *county);

Description:
This function reads the mouse motion counters in mickeys. A mickey is
1/200 of an inch.

Return Value: On returning the variables pointed to by countx and county
              contain the mickey count since the last call, values can
              range from -32768 to 32767.

msm_setareax
Usage:
#include <msmouse.h>
void msm_setareax (unsigned minx, unsigned maxx);

Description:
Set minimum and maximum horizontal position. If maxx < minx, the values
are exchanged. The mouse horizontal motion will be restricted to be
within these values.

msm_setareay
Usage:
#include <msmouse.h>
void msm_setareay (unsigned miny, unsigned maxy);

Description:
Set minimum and maximum vertical position. If maxy < miny, the values
are exchanged. The mouse vertical motion will be restricted to be within
these values.

msm_setcurpos
Usage:
#include <msmouse.h>
void msm_setcurpos (unsigned curposx, unsigned curposy);

Description:
Set the cursor position. The upper left corner of the screen is 0,0.
The values for curposx and curposy must be within the screen.

msm_setgraphcur
Usage:
#include <msmouse.h>
void msm_setgraphcur (int hotx, int hoty, int *pmasks);

Description:
Set the graphics cursor block. On entry to the function hotx and hoty
should point to the location of the  hot spot  of cursor. Values must be
in the range -16 through 16. Location 0,0 is the upper left corner of the
cursor with positive values extending right and down. The variable pmasks
should point to an array of 32 words which contain bit masks defining the
cursor. The first 16 words define the mask, that is, which bits of the
background  shine  through the cursor. A 1 means shine through, a 0 means
not. The second 16 words define the bitmap of the cursor, 1 being on and
0 being off. The cursor is 16*16, the first word forms the top row, bit
15 forms the left-most column.

msm_setratio
Usage:
#include <msmouse.h>
void msm_setratio (unsigned ratiox, unsigned ratioy);

Description:
Sets the mickey/pixel ratio (the sensitivity of the mouse). Higher values
mean less cursor movement for corresponding mouse movement. The default
values are 8,16. The values for ratiox and ratioy must be in the range 1
to 32767.

msm_settextcur
Usage:
#include <msmouse.h>
void msm_settextcur (int select, int scanstart, int scanstop);

Description:
Set the text cursor. On entry to the function select is used to indicate
whether or not to use a hardware cursor. If select is 1, then the
hardware text cursor is used, if 0, then an attribute cursor is used. The
parameters scanstart, scanstop have different uses depending on the value
in select. If select is 1, then these values form the starting and ending
scan lines of the hardware text cursor. If select is 0, then these values
form the screen mask and cursor mask, respectively, for the attribute
cursor.

msm_setthreshhold
Usage:
#include <msmouse.h>
void msm_setthreshhold (unsigned speed);

Description:
Sets the double speed threshold, i.e. the speed at which the mickey/pixel
ratio is temporarily halved so that the mouse apparently moves faster.
Speed is in mickeys/second. The default is 64.

msm_showcursor
Usage:
#include <msmouse.h>
void msm_showcursor(void);

Description:
Show cursor. That is, increment the cursor flag. If the cursor flag is 0,
then the cursor is displayed. Since msm_init() sets the value of the
cursor flag to -1, msm_showcursor() must be called after msm_init() in
order for the cursor to appear. Note that showcursor and hidecursor can
be nested.That is, if n hidecursors were done, then n showcursors must be
done in order to show the cursor. Generally, the point is to remove the
cursor before any screen I/O is done, and then restore the cursor.

See Also: msm_condoff, msm_hidecursor

msm_signal
Usage:
#include <msmouse.h>
void msm_signal (unsigned mask, void(*func) (unsigned mask,
                 unsigned state, unsigned curposx, unsigned curposy),
                 void *stack);

Description:
Sets up a user-defined subroutine input mask. Used to set a function to
be called whenever there is input available from the mouse. On input mask
defines when to call the user function (1 means yes):

Bit 0:           mouse moved
Bit 1:           left button is pressed
Bit 2:           left button is released
Bit 3:           right button is pressed
Bit 4:           right button is released
Bit 5:           middle button is pressed
Bit 6:           middle button is released

Other bits are not used. The parameter func is a pointer to the
application-defined interrupt service routine to call whenever a mouse
button is pressed or released, or the mouse moves, according to the bits
in mask. The parameter stack contains the value to set stack pointer to
when func is called. Should point just past end of an area that is at
least 256 bytes long. When func is called, it is passed the following:

mask               Event that occurred is indicated with the bit set as
                   defined above.

state              If button event, this is the button number of the
                   button that changed (0 = left, 1 = right, 2 = middle).

curposx, curposy   Current mouse position.

msm_term
 Should be called before exiting

Usage:
#include <msmouse.h>
void msm_term (void);

Description:
Terminates the mouse driver. This should be called before the program is
exited if the mouse was used.

See Also: msm_init

open
Usage:
#include <io.h>
int open (char *file, int oflag [,int pmode]);

Description:
This function opens a file for reading, writing or appending to.
The function arguments are:

int fd           Handle of opened file or ERROR

char *file       Name of file to open

int oflag        Operations allowed - one or more of:
                   O_APPEND   position file pointer to end
                   O_CREAT    create file if it does not exist
                   O_EXCL     used with O_CREAT, returns an error
                              if file already exists
                   O_RDONLY   open file for reading only
                   O_RDWR     open file for reading and writing
                   O_TRUNC    truncates an existing file
                   O_WRONLY   opens file for writing only

int pmode       Optional permission mode - one or more of:
                   S_IWRITE   used with O_CREAT, permit writing
                   S_IREAD    used with O_CREAT, permit reading

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int fd;
    if (ERROR == (fd = open("file.ext",O_CREAT | O_RDWR, S_IWRITE))) {
        printf ("Can't open file.ext");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: A file handle to the opened file, else -1 and errno is set.

See Also: sopen

outp outpw
 Note - This function is not available under OS/2.

Usage:
#include <dos.h>
void outp (int port_address, int value);
void outpw (int port_address, int value);

Description:
outp and outpw are C interfaces to the hardware I/O ports using the
"out" 80x86 instructions.

outp writes the least significant byte of value to the specified port.
outpw writes the word value to the specified port.

The compiler generates inline code for outp and outpw.

Example:
See the example for inp, inpw.

See Also: inp, inpw, outpw

The Page Package
The Page package is a set of functions which allow the programmer to
create and manipulate a heap (a block of memory set aside for dynamic
allocation). The heap is created by passing the function page_initialize
the address and size of the block of memory that is to become the heap.
The programmer can then use calls to page_malloc, page_calloc,
page_realloc and page_free to allocate memory from this heap in a
similar fashion to the standard memory allocation routines.

All these functions require a far pointer to the page heap as an argument
so that they know which heap to act on. The page allocation functions
return the offset of the allocated block within the page heap rather than
a pointer. The macro page_toptr can be used to obtain a far pointer to a
location in the heap.

Example:
#include <stdio.h>
#include <io.h>
#include <page.h>
#include <stdlib.h>

/* For Small Data Models only */

#define HEAPSIZE 0x4000

static char buffer[HEAPSIZE];
/* a 16K static buffer */

int main()
{
    unsigned maxsize, offset;
    char far *baseptr;
    int far *fp, i;

    baseptr = MK_FP(getDS(),buffer);
    maxsize = page_initialize(baseptr,0x4000);
    printf("The maximum allocatable size");
    printf(" is %04x bytes\n",maxsize);

    if ((offset = page_malloc(baseptr,0x800)) == 0)
        printf("Page_malloc failed\n ");
    else
        printf("Allocated 0x800 bytes successfully\n");

    fp = page_toptr(baseptr,offset);
    for (i = 0; i < 255; i++)
        fp[i] = i;
    printf("fp[50] = %d\n",*(fp+50));

    if ((offset = page_realloc(baseptr,offset,0x1000))==0)
        printf("Page_realloc failed\n ");
    else
        printf("Re-allocated to 0x1000 bytes\n");

    fp = page_toptr(baseptr,offset);
    printf("fp[75] = %d\n",*(fp+75));

    maxsize = page_maxfree(baseptr);
    printf("Maximum free block remaining");
    printf(" is %04x bytes\n",maxsize);

    if (page_free(baseptr,offset) == -1)
        printf("Page_free failed\n");
    else
        printf("Page freed successfully\n");
    return EXIT_SUCCESS;
}

page_calloc
Usage:
#include <page.h>
unsigned page_calloc (void far *baseptr, unsigned size);

Description:
Allocate and clear a block of data, size bytes long, from the page heap
pointed to by baseptr.

Return Value: The offset of the allocated data within baseptr if
              successful, otherwise zero.

See Also: calloc, page_malloc, page_free

page_free
Usage:
#include <page.h>
int page_free (void far *baseptr, unsigned p);

Description:
Free the memory at offset p in the page heap pointed to by baseptr,
that was allocated by page_malloc or page_calloc.

Return Value: Returns 0 on success or -1 if an error occurred (baseptr is
              bad, or memory is corrupted).

See Also: page_malloc, page_calloc

page_initialize
Usage:
#include <page.h>
unsigned page_initialize (void far *baseptr, unsigned pagesize);

Description:
Initialize the memory allocation system for the block of memory pointed
to by baseptr which is of size, pagesize. Turns the buffer at baseptr
into a page heap.

Return Value: The size of the largest allocatable block in baseptr.

page_malloc
Usage:
#include <page.h>
unsigned page_malloc (void far *baseptr, unsigned size);

Description:
Allocate a block of data of size bytes from the page heap pointed to by
baseptr.

Return Value: The offset of the allocated data within baseptr, otherwise
              zero.

See Also: malloc, page_calloc, page_free

page_maxfree
Usage:
#include <page.h>
unsigned page_maxfree (void far *baseptr);

Description:
Determine size of largest free block in the page heap pointed to by
baseptr.

Return Value: The size of the largest free block.

page_realloc
Usage:
#include <page.h>
unsigned page_realloc (void far *baseptr, unsigned p, unsigned nbytes)

Description:
Reallocates (changes the size of) a block of memory that was allocated
by page_malloc or page_calloc.

Return Value: The offset of the reallocated data block from baseptr,
              otherwise zero.

See Also: realloc, page_malloc, page_calloc

page_size
Usage:
#include <page.h>
unsigned page_size (void far *baseptr, unsigned p);

Description:
Returns the number of bytes allocated for the block of memory at
offset p that was allocated by page_malloc, page_calloc or page_realloc.
Implemented as a macro in page.h.

Return Value: The number of bytes in the block.

page_toptr
Usage:
#include <page.h>
void far * near page_toptr (void far *baseptr, unsigned p);

Description:
Converts a pointer to a page heap, and an offset into it of p, into a
void * pointer. Implemented as a macro in page.h.

Return Value: A far pointer to the position in the page corresponding
              to the offset p.

pclose
Usage:
#include <process.h>
int pclose (FILE *fp)

Description:
Close this pipe. Wait for the child process to terminate.

Return Value: The termination/exit status of the child process.

peek
Usage:
#include <dos.h>
void peek (unsigned seg, unsigned offset, void *buf, int numbytes);

Description:
Moves numbytes from the memory specified by seg:offset to the buffer
pointed to by buf.

Example:
/* this program will accept as command line arguments
   ON or OFF - to turn numlock on or off.
*/

#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
    char state1, state2;
    int i;

    for (i = 0; i < argc; i++)
        {
            strupr(argv[i]);
        }
    if ((strcmp(argv[1],"ON") == 0))
        {
            printf("Numlock is on\n");
            peek (0, 0x417, &state1, 1);
            state1 |= 0x20;
            poke (0, 0x417, &state1, 1);
        }
    else
        if ((strcmp(argv[1],"OFF") == 0 ))
            {
             printf("Numlock is off\n");
             peek (0, 0x417, &state1, 1);
             state1 &= ~0x20;
             poke (0, 0x417, &state1, 1);
            }
        else
            {
             printf("\nEnter ON or OFF as a command);
             printf(" line argument\n");
             exit (EXIT_FAILURE);
            }
    return EXIT_SUCCESS;
}

See Also: poke

perror
Usage:
#include <stdlib.h>
void perror (char *msg);
ANSI

Description:
Displays a message on the standard output describing the last error that
occurred in a system call or library function call. The argument msg is
printed first, then a colon, followed by the error description.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    char *string = "Error message";

    if ((fp = fopen("file.dat","r")) == NULL) {
        perror (string);
        return EXIT_FAILURE;
    } else
        printf ("File open for reading\n");
    fclose (fp);
    return EXIT_SUCCESS;
}

See Also: strerror

poke
Usage:
#include <dos.h>
void poke (unsigned seg, unsigned offset, void *buf, int numbytes);

Description:
Moves numbytes from the buffer pointed to by buf, to the memory
specified by seg:offset.

See Also: peek

Example:
See the example for peek.

poly
Usage:
#include <math.h>
double poly (double x, int deg, double coeff[]);

Description:
poly evaluates a polynomial of the form:

(...(coeff[deg]*x + coeff[deg-1]) * x + ...) * x + coeff[0].

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

double coeff[4];

int main()
{
    double x = 1.2, y;

    coeff[0] = 0.0;
    coeff[1] = 1.0;
    coeff[2] = 2.0;
    coeff[3] = 3.0;
    y = poly (x, 3, coeff);
    printf("The polynomial is %f\n", y);
    return EXIT_SUCCESS;
}

Return Value: The double result is returned.

pow
Usage:
#include <math.h>
double pow (double x, double y);
ANSI

Description:
pow returns the value of x to the y power .

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x = 3, y = 2, result;
    result = pow(x,y);
    printf("%.2f to the power of %.2f is: %.2f\n", x, y, result);
    return EXIT_SUCCESS;
}

Return Value: The double result is returned or a DOMAIN error if x == 0
              and y <= 0, or x <= 0 and y is not an integer.

See Also: exp, log, sqrt

printf
Usage:
#include <stdio.h>
int printf (const char *format,...);
ANSI

Description:
printf is the formatted print routine, it writes its characters to stdout.
Arguments are interpreted according to the zero terminated format string.
The format string is a sequence of characters with embedded conversion
commands. Characters that are not part of the conversion command are
output. For a full list of the conversion commands refer to the entry for
fprintf.

Example:
See fprintf

Return Value: Returns the number of characters written. If an output
              error occurred, then a negative integer is returned.

See Also: fprintf, scanf, sprintf, vprintf, vsprintf, vfprintf

putc
Usage:
#include <stdio.h>
int putc (int c, FILE *fp);
ANSI

Description:
putc writes the character c to the stream fp.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *string = "This is an example of putc()";
    int i, ch;
    for (i=0; (i<28) && ((ch = putc(string[i],stdout)) != EOF); i++);
    return EXIT_SUCCESS;
}

Return Value: The character just written is returned. An EOF is returned
              if an error occurs.

See Also: fputc, getc, getchar, putchar

putchar
Usage:
#include <stdio.h>
int putchar (int c);
ANSI

Description:
putchar writes the character c to the standard output stream, stdout
(usually the screen).

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *string = "This is an example of putchar()";
    int i, ch;
    for (i=0; (i<32) && ((ch = putchar(string[i])) != EOF); i++);
    return EXIT_SUCCESS;
}

Return Value: The character just written is returned. An EOF is returned
              when an error occurs.

See Also: fputc, getc, getchar, putc

putenv
Usage:
#include <stdlib.h>
char *environ[];
int putenv (char *newdef);

Description:
The putenv() function complements the getenv() function in the standard
library. Passed a string, newdef, of the form "ENVAR=STUFF", it will set
the environment variable ENVAR to the value STUFF. Note that this does
not set the master environment and that the value set will be lost upon
program termination! It is, however, useful for passing arguments in
environment variables to spawned programs. Please note:

1. Since the environment table must be allowed to grow to accommodate
added variables, this implementation does not allow modified environments
to be passed to executed programs or those spawned using the P_OVERLAY
mode.

2. When putenv() is called with an argument of the form "ENVAR=", if
ENVAR exists in the current environment, it will be deleted.

3. The library getenv() function may be used to access environment
variables set using putenv().

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    if (putenv("envar=new stuff")) {
        puts("can't modify environment");
        return EXIT_FAILURE;
    } else
        spawnlp(P_WAIT, "prog", "prog", "arg", NULL);
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, else -1

See Also: getenv

puts
Usage:
#include <stdio.h>
int puts (const char *s);
ANSI

Description:
puts writes the string s to stdout (without the terminating 0), then
writes a newline to stdout.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *string = "Display this string using puts,";
    char *string2 = "Puts inserts a newline character.";
    puts (string); puts (string2);
    return EXIT_SUCCESS;
}

Return Value: Returns a positive value if successful, otherwise EOF.

See Also: fprintf, fputs, gets, printf

qsort
Usage:
include <stdlib.h>

void qsort (void *base,size_t int nel, size_t size,
            int compar (const void *, const void *));
ANSI

Description:
qsort is an implementation of the quick-sort algorithm. It sorts a table
of elements.

base             Points to the element at the base of the table.
nel              The number of elements in the table.
size             The size in bytes of one table element.
compar           The name of the comparison function, which is called
                 with  two arguments that point to the elements being
                 compared. The function  compar must be written by the
                 programmer and must return an integer that is less than,
                 equal to, or greater than zero according to a comparison
                 of the first argument to the second. compar should be
                 declared as taking  C linkage.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXL 10
unsigned char *line[MAXL];

#ifdef __cplusplus
extern "C"
#endif

comp (char **a, char **b)
{
    return strcmp (*a, *b);
}

int main()
{
    int j, k;
    unsigned char buffer[82];
    printf ("Enter 10 lines of data\n");
    for (j = 0; j < MAXL; ++j)
        {
            printf ("Line: %d\n", j+1);
            if (!fgets((char *)buffer, 80, stdin))
                break;
            line[j] = malloc (strlen((char *)buffer)+1);
            strcpy((char *)line[j], (char *)buffer);
        }

    printf ("\n\n\nSort ten lines from stdin:\n");
    qsort (line, j, sizeof(unsigned char *), comp);

    for (k = 0; k < j; ++k)
        printf ("Line: %d %s\n", k+1, line[k]);
    return EXIT_SUCCESS;
}

raise
Usage:
#include <signal.h>
int raise (int sig);
ANSI

Description:
raise issues a signal to the executing program. The signal type, sig,
is discussed in the signal description. When the signal is raised by the
raise function call, the current signal-handling routine will be called.
See signal for a complete description.

Example:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
#endif

void div_zero (int val)
{
    printf ("Divide by zero detected!\n");
    exit (EXIT_SUCCESS);
}

int main()
{
    float numerator = 3.0, denominator = 0.0;

    if (signal (SIGFPE, div_zero) == SIG_ERR)
        {
            printf ("Could not set SIGFPE!\n");
            abort();
        }
    if (denominator == 0)
        raise (SIGFPE);
    else
        printf ("The result of the division is %f\n",
                numerator / denominator);
    return EXIT_SUCCESS;
}

Return Value: Returns 0 if successful, otherwise returns a non-zero value.

See Also: signal

rand
Usage:
#include <stdlib.h>
int rand (void);
ANSI

Description:
rand returns a random number in the range 0 to 32767. srand seeds the
random number generator. See srand for description.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    for (i = 0; i < 20; i++)
        printf ("i: %d rand(): %d\n", i, rand());
    return EXIT_SUCCESS;
}

Return Value: An integer containing the random number.

See Also: srand

read
Usage:
#include <io.h>
int read (unsigned fd, void *buffer, size_t len);

Description:
The system call read gets the next block of characters from the file
associated with the file descriptor fd. The number of bytes read into the
buffer is specified with the len parameter. The transfer is untranslated.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <stdlib.h>

#define BYTECOUNT 255

int main()
{
    char *buffer;
    int fd, numread, count;
    if ((fd = open ("file.dat", O_RDONLY)) == -1) {
        perror ("Open failed on file file.dat");
        exit (EXIT_FAILURE);
    }
    buffer = malloc(BYTECOUNT+1);
    for (count = 0; count <  BYTECOUNT; count++)
        buffer[count] = '\0';
    numread = read (fd, buffer, BYTECOUNT);
    printf("\nNumber of characters read %d\n", numread);
    close (fd);
    free (buffer);
    return EXIT_SUCCESS;
}

Return Value: Returns the number of characters actually read, which may
              be less than length if end-of-file was encountered. If a
              read error occurs, then a -1 is returned and errno is set.

See Also: fread, open, write

realloc
Usage:
#include <stdlib.h>
void *realloc (void *ptr, size_t size);
ANSI

Description:
realloc changes the size of a previously allocated memory block pointed
to by ptr. The size of the block after the call to realloc is specified
by size. If size is 0, ptr is free'd and NULL is returned. If ptr is
NULL, then size is malloc'd and the result is returned. If there is
insufficient room to expand the current block a new block will be
allocated and the current block released. Existing data will be copied
into the new block.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *ptr;
    ptr = realloc (NULL, 20*sizeof(char));
    strcpy (ptr, "This is part one, ");
    ptr = realloc (ptr, 100*sizeof(char));
    strcat (ptr, "This is part two.");
    printf ("\%s\n",ptr);
    realloc (ptr, 0);
    return EXIT_SUCCESS;
}

Return Value: A pointer to the reallocated memory block is returned. If
              there is insufficient memory for the realloc, NULL is
              returned (but ptr is not free'd).

See Also: calloc, free, malloc

remove
Usage:
#include <io.h>
int remove (const char *filename);

Description:
remove deletes the file specified by the string filename.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int value;
    char buffer[13];
    char *result;

    printf("Input file to remove: ");
    result = gets(buffer);
    value = remove(result);
    if(value == 0)
        printf("Erased [%s] from disk\n",result);
    else {
        printf("Unable to erase [%s]\n",result);
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: Returns 0 if the file was successfully deleted or -1 if an
              error occurred and errno is set.

See Also: unlink

rename
Usage:
#include <stdio.h>
int rename (const char *oldname, const char *newname);
ANSI

Description:
Changes the name of a file from oldname to newname. Both oldname and
newname may contain drive and path names but both names must refer to
the same drive.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int return_code;
    char *oldname, *newname;

    oldname = "data.fil";
    newname = "file.dat";
    return_code = rename (oldname, newname);
    printf("\n%s %s renamed to %s\n", oldname,
           return_code == 0 ? "was" : "was not", newname);
    return EXIT_SUCCESS;
}

Return Value: rename returns a 0 if the file name was successfully changed
              and non-zero if it was not and errno is set.

response_expand
Usage:
#include <dos.h>
int _pascal response_expand (int *argc, char ***argv)

Description:
The function response_expand expands an argument list read in from a
response file. The response file should be passed in the form @filename.
Any existing command line arguments are preserved. Response files can be
nested.

response_expand will also expand command line arguments based on
environment variables rather than response file names.

Example:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    int i;
    response_expand (&argc, &argv);
    for (i = 1; i < argc; i++)
        printf("Arg %d is %s\n", i, argv[i])
    return EXIT_SUCCESS;
}

Return Value: 0 if successful, otherwise non-zero, in which case argc and
              argv are unchanged.

rewind
Usage:
#include <stdio.h>
void rewind (FILE *fp);
ANSI

Description:
rewind repositions the file pointer associated with a stream to the
beginning of the file. This is equivalent to using fseek(fp,0L,SEEK_SET),
with the error flag for fp also cleared.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    char *string = "String one, example string";
    char string2[30] = "xxxxxxxxxxxxxx";

    fp = fopen("file.dat","w+");
    fprintf(fp,"%s",string);
    rewind(fp);
    fscanf(fp,"%s",string2);
    printf("The value read back is: %s\n",string2);
    return EXIT_SUCCESS;
}

See Also: fseek

rmdir
Usage:
#include <direct.h>
int rmdir (char *pathname);

Description:
rmdir deletes the directory specified by the pathname argument. The
directory must be empty and cannot be the root directory or the current
working directory. All the intermediate directories must also exist.

Example:
#include <stdio.h>
#include <direct.h>
#include <stdlib.h>

int main()
{
    int result;
    result = rmdir("\temp");
    if(result == 0)
        printf("Directory \temp removed\n");
    else {
        printf("Could not remove directory \temp\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: The function rmdir returns a 0 if the directory was deleted.
              A return value of -1 indicates an error and errno is set.

See Also: mkdir, chdir

_rotl _rotr
Usage:
#include <stdlib.h>
unsigned int _rotl (unsigned int val, int shift);
unsigned int _rotr (unsigned int val, int shift);

Description:
The functions _rotl and _rotr carry out a binary rotation of the supplied
unsigned integer, val, by shift bits.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned int value = 0x01234;

    printf("_rotl(value,4) = 0x%4.4x\n", _rotl(value,4));
    printf("_rotr(value,8) = 0x%4.4x\n", _rotr(value,8));
    return EXIT_SUCCESS;
}

Return Value: Both of these functions return the rotated value as an
              unsigned int. There is no error return.

See Also: _lrotl, _lrotr

sbrk
Usage:
#include <stdlib.h>
void *sbrk (unsigned int count);

Description:
sbrk attempts to enlarge the data segment by the number of bytes
specified in count. A pointer to the added memory is returned on success,
else -1 if error.

For T, S and M models if the variable _okbigbuf was not defined, then
all available memory up to 64k is allocated during program start-up and
sbrk will always fail (return a -1). If in the program _okbigbuf is
defined and initialized to 0, then only the memory required by a program
is allocated to the heap and sbrk will be usable..

 sbrk() is an integral part of calloc(), malloc(), and realloc().
 Applications should avoid using it.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>

extern _okbigbuf = 0;
void *sbrk (int);

int main()
{
    unsigned int count = 100;
    char *ptr;
    ptr = sbrk(count);
    if (ptr == (char *) -1L)
        {

            perror("No available space for sbrk\n");
            return EXIT_FAILURE;
        }
    strcpy (ptr, "String of data:");
    strcat (ptr, " another string added\n");
    fputs (ptr, stdout);
    return EXIT_SUCCESS;
}

Return Value: sbrk returns a -1 if there was not enough memory to satisfy
              the request and errno is set. Otherwise, a pointer to the
              memory block is returned.

See Also: calloc, free, malloc, realloc

scanf
Usage:
#include <stdio.h>
int scanf (char *format, ...);
ANSI

Description:
scanf is a formatted input routine which obtains its input from stdin.
Apart from the format string, the arguments must be pointers to where
values are stored. For details of the format and usage of this function
refer to the entry for fscanf.

Example:
#include <stdio.h>
#include <stdlib.h>

int main() {
    unsigned int result, val;
    printf ("Enter a decimal integer: ");
    result = scanf("%i", &val);
    printf ("The decimal number [%d]", val);
    printf (" is [%4x] hexadecimal\n", val);
    return EXIT_SUCCESS;
}

Return Value: The number of assigned input items excluding any assignment
              suppressed conversions is returned. If the end of file is
              encountered before any assignments are done or before any
              conflicts occur, an EOF is returned. scanf() normally returns
              when it reaches the end of the format string.

See Also: printf, fscanf, sscanf

segread
Usage:
#include <dos.h>  /* register structures */
void segread (struct SREGS *segregs);

Description:
Reads segment register values and puts them in SREGS.

 In the X and P memory models, this function returns protected mode
 segment selectors, not real mode segment values.

Example:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

struct SREGS segregs;
unsigned code_seg, data_seg, stack_seg, extra_seg;

int main()
{
    segread(&segregs);
    code_seg = segregs.cs;
    stack_seg = segregs.ss;
    data_seg = segregs.ds;
    extra_seg = segregs.es;
    printf ("\nSegment registers currently contain:\n");
    printf ("\nCS: %4x\nDS: %4x\nSS: %4x\nES: %4x\n",
            code_seg, data_seg, stack_seg, extra_seg);
    return EXIT_SUCCESS;
}

See Also: intdosx, int86x, getDS

setbuf
Usage:
#include <stdio.h>
void setbuf (FILE *stream, char *buffer);
ANSI

Description:
The setbuf function sets the buffering system for bytes read or written
to a stream. If the buffer argument is NULL, the stream is unbuffered.
If buffer is not NULL, it is taken to be a pointer to the buffer which is
to be used for subsequent read and write calls. buffaw must point to a
character array of size BUFSIZ (defined in stdio.h). The user specified
buffer is used then instead of the default system-allocated I/O buffer.

Example:
#include <stdio.h>
#include <stdlib.h>

char buffer[BUFSIZ];
FILE *fp;

int main()
{
    fp = fopen("file.dat","r");
    setbuf(fp,buffer);
    printf("Stream has been set to buffer\n");
    return EXIT_SUCCESS;
}

See Also: setvbuf

setjmp
Usage:
#include <setjmp.h>
int setjmp (jmp_buf env);
ANSI

Description:
Coupled with longjmp, setjmp allows a goto between functions. They are
good for dealing with errors or interrupts encountered in low-level
subroutines of a program. See longjmp for more information.

Return Value: setjmp returns a 0.

Example:
See longjmp

See Also: longjmp

setlocale
Usage:
#include <locale.h>
char * setlocale (int category, const char * locale);
ANSI

Description:
setlocale is used to change locale dependent behavior or to check on its
current settings. category can be one of six predefined constants.
Zortech C++ supports the minimal ANSI C definition and therefore only
those described below have any effect.

LC_ALL           Specifies the entire locale.
LC_COLLATE
LC_CTYPE
LC_MONETARY      Specifies monetary formatting characteristics.
LC_NUMERIC       Specifies the character to be used for decimal point
                 and other nonmonetary formatting behavior.
LC_TIME

The following locales are recognized.

C                The minimal default locale.
USA              This is predefined in locale.h as the "native"
                 locale. Calling setlocale(LC_ALL,"") will select this.
Italy
Netherlands
Norway
Switzerland
UK
Japan
Korea
China

Information as to the current locale can be obtained by a call to
setlocale with a NULL second argument. This will return the current
locale for the category selected.

Having set the locale, a call to localeconv will obtain a pointer to a
filled in struct lconv with the specific locale values. See localeconv
for details.

Example:
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * countries[] =
{
    "USA",
    "ITALY",
    "NORWAY",
     NULL
};

int main()
{
    char * loc, *currency;
    int i;
    struct lconv * lcptr;
    int money = 100; /* Something to display */
/*
    setlocale can be called with a NULL locale to check on
    its current setting
*/
    loc = setlocale (LC_ALL, NULL);
    printf("The default locale is the \"%s\" locale\n", loc);

    for (i = 0; countries[i]; i++)
    {
        loc = setlocale (LC_MONETARY, countries[i]);
        lcptr = localeconv();
        currency = malloc (strlen(lcptr ->currency_symbol)+1);
        strcpy (currency, lcptr->currency_symbol);
        if (loc)
            printf ("Monetary figure for %s locale: %s%d\n", loc,
                    currency, money);
        free (currency);
    }
    return EXIT_SUCCESS;
}

Return Value: A pointer containing the currently selected locale for the
              category specified. A NULL is returned if the locale
              specified is not supported.

See Also: localeconv

setvbuf
Usage:
#include <stdio.h>
int setvbuf (FILE *fp,char *buf, int mode, size_t size);
ANSI

Description:
setvbuf specifies the type and size of a buffer to be used for a stream.
In addition to the function parameters the following global variable
affects the behaviour of this function: _okbigbuf.

This is used only in the T, S and M memory models under MS-DOS and the S
and M memory models under OS/2, and controls how buffers are allocated
when buf is NULL. It is statically initialized to 0 or 1 by the
programmer (the default definition in the library sets it to 1). If
_okbigbuf is 1 and the memory model is T, S or M: setvbuf tries to
allocate a buffer outside of the data segment. If that fails, and
size <= BUFSIZ, then setvbuf tries to allocate a buffer within the data
segment.

A buffer that is outside the data segment is marked by setting _IOBIGBUF
in fp->_flags . If _okbigbuf is 0 or the memory model is C or L: setvbuf
tries to allocate a buffer within the data segment. A buffer allocated by
setvbuf is flagged by _IOMYBUF being set in fp->_flags.

The function parameters are:

fp               Stream pointer that is already opened, but before any
                 reads or writes have been done to the stream.

buf              Pointer to buffer, or NULL. If NULL, then setvbuf uses
                 malloc or faralloc to try to allocate a buffer of size
                 bytes. If buf is not NULL, it points to a buffer that
                 setvbuf will cause to be associated with the stream fp.

mode             Is one of:
                 _IONBF  No buffering. The buf and size parameters are
                         ignored. Unbuffered I/O means that: data written
                         is immediately passed on to DOS. When data is
                         read, exactly enough is read.
                 _IOLBF  Do line buffering. The actual I/O is performed
                         when a newline is read or written.
                 _IOFBF  Full buffering. Data is read a full buffer at a
                         time. Data is written only when the
                         buffer is full.

size             If buf is NULL, then size is the number of bytes to
                 allocate for the buffer. If buf is not NULL, then size
                 must be the number of bytes in the buffer points to.

Example:
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
    FILE *fp;
    static char buf[100];

    /* Make stdprn unbuffered */
    setvbuf (stdprn, NULL, _IONBF, 0);
    fprintf (stdprn,"unbuffered\n");

    if (argc == 2)          /* if an argument */
        fp = fopen(argv[1],"w");
    else
        fp = stdout;        /* use standard output */

    if (setvbuf (fp, buf, _IOLBF, sizeof(buf))) {
        printf ("setvbuf failed\n");
        return EXIT_FAILURE;
    }
    else
    {
        fprintf (fp, "This is going to fp\n");
        fclose (fp);
    }
    return EXIT_SUCCESS;
}

Return Value: If success, the various fields that fp points to are updated
              to show the buffer and 0 is returned. If there is insufficient
              memory for the buffer or the mode parameter is invalid,
              a non-zero result is returned

See Also: setbuf

signal
Usage:
#include <signal.h>
void (*signal (int sig, void (*handler)(int)))(int)
ANSI

Description:
signal allows a program to define how signals from the operating system
are to be handled. The sig argument must be one of these constants:

SIGABRT          Abnormal termination
SIGFPE           Floating point error
SIGILL           Illegal instruction
SIGINT           Interrupt
SIGSEGV          Segment violation
SIGTERM          Terminate (CTRL+C)

The macros below are special values for func:

SIG_DFL          Handled in the default manner.
SIG_IGN          Ignored the signal.

signal sets the response. func should be declared with C linkage.

When a signal happens, first the behavior for the signal is reset to
SIG_DFL, then the function for that signal is called and sig is passed
to it.

Example:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

/* our signal handler function */

void cdecl ctrl_break (int val)
{
    signal (SIGTERM, SIG_IGN);
    printf ("Press any key to terminate: ");
    getch();
    exit (EXIT_SUCCESS);
}

int main()
{
    if (signal (SIGTERM, ctrl_break) == SIG_ERR)
        {
            perror ("Could not set SIGTERM!");
            abort();
        }
    raise (SIGTERM);
    return EXIT_SUCCESS;
}

Return Value: signal returns the previous value of func. A return value
              of SIG_ERR indicates an error and errno is set.

See Also: raise

sin
Usage:
#include <math.h>
double sin (double x);
ANSI

Description:
sin returns the sine of x where x is in radians.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x = 4.3, d;
    d = sin(x);
    printf ("The sine of (%f) is (%f)\n", x, d);
    d = sinh(x);
    printf ("The hyperbolic sine of (%f) is (%f)\n", x, d);
    return EXIT_SUCCESS;
}

Return Value: Returns the sine of the argument x.

sinh
Usage:
#include <math.h>
double sinh (double x);
ANSI

Description:
sinh returns the hyperbolic sine of x.

Example:
See the example for sin.

Return Value: Returns the hyperbolic sine of the argument x.

sleep
Usage:
#include <time.h>
void sleep (time_t seconds);

Description:
Suspends execution of the program for the specified number of seconds.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    printf ("Going to sleep for 10 seconds\n");
    sleep (10);
    printf ("OK, back again now\n");
    return EXIT_SUCCESS;
}

See Also: msleep, usleep

sopen
Usage:
#include <io.h>
int sopen (char *file, int oflag, int shflag [,int pmode]);

Description:
This function is comparable to the standard library open() function but
prepares an opened file for DOS sharing. Note that attempting to use
sopen() with DOS 2.x will result in an error. The DOS utility SHARE
should be installed if files are to be opened in shared mode.

char *file       Name of file to open

int oflag        Operations allowed - one or more of:
                 O_APPEND   position file pointer to end
                 O_CREAT    create file if it doesn't exist
                 O_EXCL     used with O_CREAT, returns an error
                            if file already exists
                 O_RDONLY   open file for reading only
                 O_RDWR     open file for reading and writing
                 O_TRUNC    truncates an existing file
                 O_WRONLY   opens file for writing only

int shflag   Type of sharing allowed - one of:
                 SH_COMPAT  sets compatibility mode
                 SH_DENYRW  denies read and write access
                 SH_DENYWR  denies write access
                 SH_DENYRD  denies read access
                 SH_DENYNO  permits read and write access

int pmode    optional permission mode - one or more of:
                 S_IWRITE   used with O_CREAT, permit writing
                 S_IREAD    used with O_CREAT, permit reading

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int fd;

    if (ERROR == (fd = sopen("file.ext", O_CREAT | O_RDWR,
                             SH_COMPAT, S_IWRITE))) {
        printf ("Can't open file.ext");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: A file handle to the opened file is returned, otherwise -1
              and errno is set.

See Also: open

The Sound Package
The sound package consists of a set of three functions which allow the
programmer to manipulate the IBM PC s built-in speaker.

The functions are:

    sound_beep
    sound_click
    sound_tone

These functions will only work on machines that are hardware and software
compatible with the IBM PC.

sound_beep
Usage:
#include <sound.h>
void sound_beep (int freq):

Description:
sound_beep causes the speaker to sound a beep. Any frequency in Hertz can
be approximated by multiplying by a conversion factor of 1.331 and using
this value for freq.

Example:
See sound_tone.

See Also: sound_click, sound_tone

sound_click
Usage:
#include <sound.h>
void sound_click():

Description:
sound_click causes the speaker to click.

Example:
See sound_tone.

See Also: sound_beep, sound_tone

sound_tone
Usage:
#include <sound.h>
void sound_tone (int cycles, int uptime, int dntime):

Description:
sound_tone plays tones. The number of cycles and the cycle times are
specified.

Example:
#include <stdio.h>
#include <sound.h>
#include <stdlib.h>

int main()
{
    int cycles = 5000, uptime = 50, dntime = 50, freq = 1331;
    printf ("Sound using sound_click\n");
    sound_click();
    printf ("Press any key: ");
    getch();
    printf ("\nSound using sound_tone\n");
    sound_tone (cycles, uptime, dntime);
    printf ("Press any key: ");
    getch();
    printf ("\nSound using sound_beep\n");
    sound_beep (freq);
    getch();
    return EXIT_SUCCESS;
}

See Also: sound_click, sound_beep

spawnl spawnlp spawnv spawnvp
Usage:
#include <process.h>
int spawnl (int mode, char *pathname, char *arg0,*arg1,...,*argn, NULL);
int spawnlp (int mode,char *filename, char *arg0,*arg1,...,*argn, NULL);
int spawnv (int mode, char *pathname, char *argv[]);
int spawnvp (int mode, char *filename, char *argv[]);

Description:
The spawn system calls load and execute a new child process. The current
process may or may not continue to execute asynchronously. Creating a new
subprocess requires memory to be available for the child process to
execute in addition to that used by the current program.

The mode argument determines whether or not the child process is to run
asynchronously. It is currently only used under OS/2, and allows
multitasking between the parent and child processes. Values for mode are:

EXEC_SYNC        Run synchronously. The parent process waits for the
                 child process to terminate before continuing.

EXEC_ASYNC       Run asynchronously. The parent and child processes
                 execute in parallel.

EXEC_ASYNCRESULT Run asynchronously. The parent and child processes
                 execute in parallel. The termination code of the child
                 process can be recovered using the OS/2 API function
                 DosCwait().

EXEC_BACKGROUND  Run asynchronously. The parent and child processes
                 execute in parallel, but the child process is detached
                 from the screen group of its parent process. The
                 detached process executes in the background and may not
                 use screen output (except VioPopUp()) or the keyboard
                 or mouse subsystems.

EXEC_TRACE       Execute under conditions for tracing. Used by debuggers
                 to debug the child process.

The filename argument specifies the program to execute. For spawnlp and
spawnvp only, if the filename does not have a path and it is not in the
current directory then the environment variable PATH is used to determine
which directories are searched for the file. The string pointed to by
argv[0] should be the name of the program that is to run. The command
line passed to the spawned program is made up of the character strings in
the spawn call, the first being arg1, second arg2, etc. The combined
length of these strings must not exceed 128 characters. The argv argument
used in the spawnv and spawnvp is an array of character pointers. The
last pointer in argv must be NULL to indicate the end of the list.

The spawn functions can be used under Microsoft Windows.  They use
LoadModule to run the spawned process. If this fails an attempt is made
to spawn a normal MS-DOS process. If a Windows application is spawned,
the instance handle can be obtained using _exec_instancehandleget(). It
is possible to specify how the spawned program is to be shown using the
functions _exec_showset(), _exec_showget() and _exec_showreset(). Refer
to the entries for those functions for more information.

Example:
#include <stdio.h>
#include <process.h>
#include <stdlib.h>

int main()
{
    char *args[4];

    args[0] = "ztc1";
    args[1] = "stuff";
    args[2] = "morestuff";
    args[3] = NULL;
    if (spawnv(0, "ZTC1.EXE", args) == -1) {
        fprintf (stderr, "exec failed!\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value

The return value indicates the exit status of the spawned program.
A value of 0 indicates that the spawned program executed successfully.
A positive value indicates that the spawned program executed, but was
aborted or ended in error, the value returned is the exit status of the
child process. A negative value indicates that the spawned program did
not execute, and errno is set.

 Under Microsoft Windows spawn returns the negated error code returned
 from LoadModule for compatibility with the C runtime library. The
 following error codes may be encountered:

   -2    File not found
   -3    Path not found
  -11    Invalid .exe file (for Windows)
  -13    Dos 4.0 application
  -14    Unknown .exe type (may be DOS extended)

See Also: abort, exit, exec, system

sprintf
Usage:
#include <stdio.h>
int sprintf (char *buffer, const char *format, ...);
ANSI

Description:
sprintf is a formatted print routine that writes its characters to the
memory buffer specified by buffer. Arguments are interpreted according
to the zero terminated format string. The format string is a sequence of
characters with embedded conversion commands. Characters that are not
part of the conversion command are output. For a full list of the
conversion commands refer to the entry for fprintf.

Return Value: Returns the number of characters written. If an error
              occurred, then a negative value is returned.

See Also: fprintf, printf, scanf, vprintf, vsprintf, vfprintf

sqrt
Usage:
#include <math.h>
double sqrt (double x);
ANSI

Description:
sqrt returns the square root of x. If x is negative then a DOMAIN error
occurs.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x;
    for(x = 1.0; x <= 20.0; ++x)
        printf ("The square root of %.4f is %.4f\n", x, sqrt(x));
    return EXIT_SUCCESS;
}

Return Value: sqrt returns the double result.

See Also: exp, log, pow

srand
Usage:
#include <stdlib.h>
void srand (unsigned seed);
ANSI

Description:
srand initializes the random number generator rand() with a seed number.
If srand() is never called, then the default is as if srand(1) was
called.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    srand (9);
    for (i = 0;i < 20;i++)
        printf("i: %d rand(): %d\n", i, rand());
    return EXIT_SUCCESS;
}

See Also: rand

sscanf
Usage:
#include <stdio.h>
int sscanf (char *buffer, const char *format, ...);
ANSI

Description:
sscanf is a formatted input routine which  reads from the specified
buffer using the specified format. The additional arguments must be
pointers to where the values are to be stored.

For details of the format and usage refer to the entry for fscanf.

Example:
#include <stdio.h>
#include <stdlib.h>

char *string = "1.24...";
char str[8];
float fp;
int i;

int main()
{
    sscanf(string,"%s", str);
    sscanf(string,"%f", &fp);
    sscanf(string,"%d", &i);
    printf("String : %s\n", str);
    printf("Float : %f\n", fp);
    printf("Integer: %d\n", i);
    return EXIT_SUCCESS;
}

Return Value: The number of assigned input items excluding any assignment
              suppressed conversions is returned. If the end of file is
              encountered before any assignments are done or before any
              conflicts occur, an EOF is returned. sscanf() normally
              returns when it reaches the end of the format string.

See Also: printf, fscanf, scanf

The StdIO Package
The StdIO package supports and controls output to stdout and stderr under
Microsoft Windows. Its use allows programs to modify the behavior of the
standard output streams and direct their output to user defined windows.
Similar facilities are available from C++. See the WinC documentation for
more information.


Functions available are:

StdIOSet

void _pascal StdIOSet (class StdIOC *, HWND);

Attaches the output stream to the window handle. You should normally
use the macros StdOutSet or StdErrSet.

StdIOGet

ushort _pascal StdIOGet (class StdIOC *);

Returns the window handle attached to the output stream.

StdIORelease

void _pascal StdIORelease (class StdIOC *);

Unattaches the output stream from the window handle.

StdioHookSet

void _pascal StdIOHookSet (class StdIOC *, Hook_t);

Installs a function of type Hook_t that is called with the output stream.
This is how WinC builds the scrollable list of  the input from the
program. The hook function is call BufferOutput in INC.CPP.
StdIOHookSet(StdOutW,NULL) deinstalls the hook.

StdIOHookGet

Hook_t _pascal StdIOHookGet (class StdIOC *);

Returns a pointer to the function that is being used as a hook. If NULL
then no hook is installed.

StdIOClear

void _pascal StdIOClear (class StdIOC *);

Causes the window to be cleared and the cursor to be homed.

StdIO macros

Macros available are:

void   _pascal StdOutSet(HWND)
void   _pascal StdErrSet(HWND)
ushort _pascal StdOutGet(void)
ushort _pascal StdErrGet(void)
void   _pascal StdOutRelease(void)
void   _pascal StdErrRelease(void
void   _pascal StdOutHooSet(Hook_t)
void   _pascal StdErrHookSet(Hook_t)
Hook_t _pascal StdOutHookGet()
Hook_t _pascal StdErrHookGet()
void   _pascal StdOutClear(void)
void   _pascal StdErrClear(void)

stat
Usage:
#include <sys\stat.h>
int stat (char *path, struct stat *buf);

Description:
stat gets information about a file or directory specified by path and
stores it in the structure that buf points to.

The structure stat contains the following fields:

st_dev       Drive number of disk containing file fd or value of fd
             if fd is a device.
st_mode      Bit mask containing mode information on the open file.
                 S_IFCHR    Set if fd refers to a device
                 S_IFREG    Set if fd refers to an ordinary file
                 S_IREAD    Set if file is open for reading
                 S_IWRITE   Set if file is open for writing
st_nlink     Total number of links (always 1).
st_rdev      Same as st_dev.
st_size      Size of open file in bytes.
st_atime     Time last modified.
st_mtime     As above.
st_ctime     As above.
st_ino       Always 0.
st_uid       Always 0.
st_gid       Always 0.

Example:
#include <stdio.h>
#include <time.h>
#include <sys\stat.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *date;
    int ret;

    struct stat buf;
    if((ret = stat("file.dat",&buf))!=0)
        {
            fprintf(stderr,"stat failure error %d",ret);
            exit(EXIT_FAILURE);
        }
    date = asctime(localtime(&buf.st_ctime));
    printf("\n %s\n",date);
    printf("\n %d mode\n",buf.st_mode);
    printf("\n %ld size\n",buf.st_size);
    return EXIT_SUCCESS;
}

Return Value: stat returns 0 if the status information is retrieved. On
              error the function returns -1 and errno is set.

See Also: fstat, filesize

strerror
Usage:
#include <string.h>
char *strerror (int errornum);
ANSI

Description:
Maps errornum to an error message string and returns a pointer to that
string.

Example:
#include <stdio.h>
#include <errno.h>
#include <io.h>
#include <dos.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    int fp;

    errno = 0;
    if ((fp = open("file", O_RDONLY)) == -1)
        {
            printf (strerror(errno));
        }
    close (fp);
    return EXIT_SUCCESS;
}

Return Value: strerror returns a pointer to the error message string.

See Also: perror

strftime
Usage:
#include <time.h>
size_t strftime (char *s, size_t max, const char *format,
                 const struct tm *timeptr);
ANSI

Description:
The strftime function inserts characters into the array pointed to by s
following instructions in the format string. The format should be a
multibyte character sequence, beginning and ending in its initial shift
state. The format string consists of zero or more conversion
specifications as well as ordinary multibyte characters. A conversion
specification consists of a % character followed by a character that
determines the conversion to be applied. All ordinary multibyte
characters (including the terminating null character) are copied
unchanged into the array. However, no more than max characters are placed
into the array. Each conversion specification is replaced by appropriate
characters as described in the following list. The appropriate characters
are determined by the program s locale and by the values contained in the
structure pointed to by timeptr.

%a  is replaced by the locale s abbreviated weekday name.
%A  is replaced by the locale s full weekday name.
%b  is replaced by the locale s abbreviated month name.
%B  is replaced by the locale s full month name.
%c  is replaced by the locales appropriate date and time representation.
%d  is replaced by the day of the month as a decimal number (01-31).
%H  is replaced by the hour (24-hour clock) as a decimal number (00-23).
%I  is replaced by the hour (12-hour clock) as a decimal number (00-12).
%J  is replaced by the day of the year as a decimal number (001-366).
%m  is replaced by the month as a decimal number (01-12).
%M  is replaced by the minute as a decimal number (00-59).
%P  is replaced by the locale s equivalent of either AM or PM
%S  is replaced by the second as a decimal number (00-60).
%U  is replaced by the week number of the year, with Sunday
    taken as the first day of the week, as a decimal number (00-53).
%w  is replaced by the weekday as a decimal number (0(Sunday)-6).
%W  is replaced by the week number of the year, with Monday
    taken as the first day of the week, as a decimal number (00-53).
%x  is replaced by the locale s appropriate date representation.
%X  is replaced by the locale s appropriate time representation.
%y  is replaced by the year (without century) as a decimal number
    (00-99).
%Y  is replaced by the year (with century) as a decimal number.
%Z  is replaced by the time zone name or by no characters if no time
    zone is determinable.
%%  is replaced by %

 The strftime function should not be used to copy between objects that
 overlap, it does not handle overlapping moves correctly.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main() {
    char buf[80];
    struct tm *tp;
    time_t newtime;

    time (&newtime);
    tp = localtime (&newtime);
    strftime (buf, sizeof(buf), "%A, %B %d", tp);
    puts (buf);
    return EXIT_SUCCESS;
}

Return Value: strftime returns the number of characters placed in the
              array pointed to by s, not including the terminating null
              character. If the total number of resulting characters,
              including the terminating null character is greater than
              max, zero is returned, and the contents of the array will
              be invalid.

See Also: asctime, ctime, gmtime, localtime, mktime, time

The String Package
The String package is a set of standard functions for manipulating null
(0) terminated strings. Most of the functions within the package are
ANSI, but there are a number of additional functions provided. Many of
these functions are closely related to functions in the Memory package.

The package can be split into 5 functional groups and a number of
miscellaneous functions. They are organized as follow:

Copying Functions

These are functions that allow strings to be copied. Functions that fall
into this category are:

strcpy
stpcpy
strdup
strncpy

Concatenation Functions

These are string concatenation functions which mirror the copying
functions. Concatenation means that the source string is appended to the
destination string instead of being copied over it. Functions that fall
into this category are:

strcat
strncat

Comparison Functions

These functions allow strings to be compared with other strings, or
parts of other strings. Functions that fall into this category are:

strcmp
strcmpl
strncmp
strncmpl
strnicmp

Conversion Functions

These functions convert the contents of a string into a different
representation. Functions that fall into this category are:

strlwr
strupr

Search Functions

These functions search a string for a given character or sequence of
characters. Functions that fall into this category are:

strchr
strcspn
strpbrk
strrchr
strspn
strstr
strtok

Miscellaneous Functions

Finally we have some miscellaneous string functions which do not fit into
any other category:

strlen
strnset
strrev
strset

stpcpy
Usage:
#include <string.h>
char *stpcpy (char *s1, char *s2);

Description:
The stpcpy function copies the string pointed to by s2 into the buffer
pointed to by s1. It is similar to the normal library strcpy() function
except that it returns a pointer to the end of the copied string. This
is useful when concatenating strings.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char s1[8] = "Eu", *s2 = "re", *s3 = "ka";
    stpcpy (stpcpy (stpcpy (s1, s2), s3), "!");
    puts (s1);       /* prints "Eureka!" */
    return EXIT_SUCCESS;
}

Return Value: A pointer to the end of the copied string

See Also: strcpy

strcat
Usage:
#include <string.h>
char *strcat (char *string1, const char *string2);
ANSI

Description:
Appends a copy of string2 onto the end of string1. The application code
is responsible for ensuring that there is enough space in the string to
hold the result.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = " 1 Example string ";
char string2[50] = " 2 Example string ";

int main()
{
    printf("strcat example [%s]\n", strcat (string1, string2));
    return EXIT_SUCCESS;
}

Return Value: Returns pointer to first string.

strchr
Usage:
#include <string.h>
char *strchr (const char *string, int ch);
ANSI

Description:
Finds the first occurrence of the character ch in string. It returns a
pointer to character ch. strchr is identical to the function index.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = " 1 Example string ";

int main()
{
    printf("\nstrchr example [%s]\n", strchr(string1,'2'));
    return EXIT_SUCCESS;
}

Return Value: Pointer to character ch. A NULL pointer is returned if not
              found.

See Also: index, memchr

strcmp strcmpl
Usage:
#include <string.h>
int strcmp (const char *string1, const char *string2);
int strcmpl (const char *string1, const char *string2);
ANSI

Description:
strcmp and strcmpl compare two strings, character by character.
strcmp is case sensitive whereas strcmpl is not.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = "Example string ";
char string2[50] = "Example String ";

int main() {
    printf("\nstrcmp example [%d]\n", strcmp (string1, string2));
    printf("\nstrcmpl example [%d]\n", strcmpl (string1, string2));
    return EXIT_SUCCESS;
}

Return Value: < 0  if string1 is less than string2
              = 0  if string1 is equal to string2
              > 0  if string1 is greater than string2

See Also: memcmp

strcpy
Usage:
#include <string.h>
char *strcpy (char *string1, const char *string2);
ANSI

Description:
strcpy copies string2 into the object pointed to by string1 including
the terminating null '\0'. It returns string1.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = " 1 Example string ";
char buffer[50] = " Rubbish - string ";

int main()
{
    printf("\nstrcpy example [%s]\n", strcpy (buffer, string1));
    return EXIT_SUCCESS;
}

Return Value: Returns the new string pointed to by string1.

strcspn
Usage:
#include <string.h>
size_t strcspn (const char *string1, const char string2);
ANSI

Description:
strcspn searches string1 for the first occurrence of a character in
string2.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = " 1 Example string ";

int main()
{
    printf("\nstrcspn example [%d]\n", strcspn (string1, "s"));
    return EXIT_SUCCESS;
}

Return Value: It returns the length of the initial segment of string1
              that consists of characters in string2 not found. If no
              character appears in string2, then the total length of
              string1 not counting the null  \0  terminator is returned.

strdup
Usage:
#include <string.h>
char *strdup (const char *string);

Description:
strdup allocates memory with a call to malloc, copies the string into it
and returns a pointer to the malloced string.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string1[50] = " 1 Example string ";

int main()
{
    printf("\nstrdup example [%s]\n", strdup (string1));
    return EXIT_SUCCESS;
}

Return Value: Returns NULL if memory cannot be allocated.

strlen
Usage:
#include <string.h>
size_t strlen (const char *string);
ANSI

Description:
Returns the length of the string excluding the terminating '\0'.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string = "Example string";
size_t result;

int main()
{
    result = strlen (string);
    printf ("The length of string: [%s] is [%d]\n", string, result);
    return EXIT_SUCCESS;
}

Return Value: Returns the length of the string.

strlwr
Usage:
#include <string.h>
char *strlwr (char *string);

Description:
Converts any upper case characters in the string to lower case.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string = "Mixed Case String";

int main()
{
    printf("strlwr Example [%s]\n", strlwr(string));
    return EXIT_SUCCESS;
}

Return Value: Returns string.

See Also: strupr

strncat
Usage:
#include <string.h>
char *strncat (char *string1, const char *string2, size_t n);
ANSI

Description:
Appends the lesser of n or strlen(string2) characters of string2 onto
the end of string1 and adds a terminating null '\0'. It is the user's
responsibility to ensure there is enough space in string1 to hold the
result.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string[50] = " Example string";
char *string2 = " Add this string";

int main()
{
    printf("strncat Example [%s]\n", strncat (string, string2, 50));
    return EXIT_SUCCESS;
}

Return Value: It returns string1.

See Also: strcat

strncmp
Usage:
#include <string.h>
int strncmp (const char *string1, const char *string2, size_t n):
ANSI

Description:
Compares n characters of string2 to string1. The comparison stops after
n characters or the end of string1.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string[50] = " Example string";
char *string2 = " Add this string";

int main() {
    printf("\nstrncmp Example [%d]\n", strncmp (string, string2, 10));
    return EXIT_SUCCESS;
}

Return Value: strncmp returns an integer:
              < 0   if string1 is less then string2
              = 0   if string1 is equal to string2
              > 0   if string1 is greater than string2

strncmpl strnicmp
Usage:
#include <string.h>
int strncmpl (char *str1, char *str2, int n);
int strnicmp (char *str1, char *str2, int n);

Description:
This function is a case-insensitive version of strncmp(). The first N
characters of each string are compared. If either string is less than N
characters long, the comparison is terminated and the return value
represents the results of the comparison up until the termination. The
returned value is zero for a successful match, or else a positive or
negative number representing the difference in the mismatching
characters. strncmpl is implemented as a macro in string.h. strnicmp is
provided for compatibility with other compilers.

Example:
#include <string.h>
#include <stdlib.h>

int main()
{
    r = strncmpl("abc","ABCD",3); /* returns   0 */
    r = strncmpl("abc","ABCD",6); /* returns   0 */
    r = strncmpl("abc","ABCX",6); /* returns   0 */
    r = strncmpl("abcx","ABC",6); /* returns   0 */
    r = strnicmp("abc","ABX",2);  /* returns   0 */
    r = strnicmp("abc","ABX",3);  /* returns -21 */
    r = strnicmp("abx","ABC",6);  /* returns  21 */
    return EXIT_SUCCESS;
}

Return Value: 0 if first n bytes match, else positive if str1 > str2 or
              negative if str1 < str2.

See Also: strncmp

strncpy
Usage:
#include <string.h>
char *strncpy (char *string1, const char *string2, size_t n):
ANSI

Description:
Copies the first n characters of string2 into string1. If string2 is
longer than string1, the result will not be null  \0' terminated. If
string2 is less than n characters, string1 will be padded to n with
null characters.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string2 = " Add this string";
char buffer[50];

int main()
{
    printf("\nstrncpy Example[%s]\n", strncpy (buffer, string2, 10));
    return EXIT_SUCCESS;
}

Return Value: It returns string1.

strnset
Usage:
#include <string.h>
char *strnset (char *string, int ch, size_t n);

Description:
Sets at most n characters of string to ch.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string2 = "Example string";

int main()
{
    printf("\nstrnset Example [%s]\n", strnset (string2, 'x', 9));
    return EXIT_SUCCESS;
}

Return Value: It returns string.

strpbrk
Usage:
#include <string.h>
char *strpbrk (const char *string1, const char *string2);
ANSI

Description:
Finds the first occurrence in string1 of any character from string2.
The terminating '\0' is not included in the search.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string2 = "Example string";

int main()
{
    printf("\nstrnset Example [%s]\n", strnset (string2,'x',8));
    printf("\nstrpbrk Example [%s]\n", strpbrk (string2,"s"));
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the first occurrence in string1 of any
              character from string2, or NULL if no character from string2
              exists in string1.

strrchr
Usage:
#include <string.h>
char *strrchr (const char *string, int ch);
ANSI

Description:
strrchr finds the last occurrence of character ch in string.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string[50] = "Example string";

int main()
{
    printf ("strrchr Example [%s]\n", strrchr (string,'i'));
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the occurrence of  ch in string.
              strrchr returns a NULL pointer if the character ch is not
              found.

strrev
Usage:
#include <string.h>
char *strrev (char *string);

Description:
strrev reverses the order of characters in string leaving a terminating
'\0' at the end.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char string[50] = "Example string";

int main()
{
    printf("\nstrrev Example [%s]\n", strrev(string));
    return EXIT_SUCCESS;
}

Return Value: Returns string.

strset
Usage:
#include <string.h>
char *strset (char *string, int ch);

Description:
strset sets all the characters in string to ch except the terminating
'\0'.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string = " This string";

int main()
{
    printf("\nstrset Example [%s]\n", strset(string,' '));
    return EXIT_SUCCESS;
}

Return Value: Returns string.

See Also: strnset

strspn
Usage:
#include <string.h>
size_t strspn (const char *string1, const char *string2);
ANSI

Description:
Returns the length of the initial segment of string1 which consists
entirely of characters found in string2.

Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char *string = "Example";
char *cmp = "aEx";

int main()
{
    int result;
    printf("Length of string in [%s] ",string);
    printf("containing [%s] characters\n",cmp);
    printf("strspn is [%d]\n",strspn(string,cmp));
    return EXIT_SUCCESS;
}

strstr
Usage:
#include <string.h>
char *strstr (const char *string1, const char *string2);
ANSI

Description:
Returns a pointer to the first occurrence of string2 within string1.

Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char *string = " Example string";
char *cmp = "str";

int main()
{
    printf("strstr Example [%s]\n", strstr(string,cmp));
    return EXIT_SUCCESS;
}

Return Value: strstr returns NULL if no occurrence was found. If string2
              is of 0 length, returns string1.

strtod
Usage:
#include <stdlib.h>
double strtod (char *nptr, char **endptr);
ANSI

Description:
strtod converts the ASCII string pointed to by nptr to a double precision
value. It will recognize white space then an optionally signed string of
digits containing an optional decimal point. It will stop reading the
string at the first character that doesn t represent a part of the
number. A pointer to that character will be stored in the object endptr
if endptr is not NULL.

Example:
See strtoul

Return Value: If correct values would cause an overflow, plus or minus
              HUGE_VAL is returned according to the sign and errno is set
              to ERANGE. If an unrecognized character is encountered
              before a legal character, zero is returned. If underflow
              then 0 is returned and errno is set to ERANGE.

See Also: atof, scanf

strtok
Usage:
#include <string.h>
char * strtok (char * string1, const char * string2);
ANSI

Description:
strtok parses string1 into tokens delimited by characters in string2. It
returns a pointer to the first character in string1 that is not one of
the delimiting characters, and writes a '\0' at the position of the next
delimiter following this. As an internal record is stored of the current
position within the string a subsequent call of strtok with a NULL value
for string1 will continue parsing from the position reached in the
previous call. string2 may change between calls.

Example:
/*
    Program that parses a string into individual words.
    These are then stored in an array and printed
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static char str[] = " \n\t\rfirst\n\tsecond\v\t third";

int main()
{
    char *token;
    char ** numbers;
    int i, dimension=0;
    numbers = malloc (++dimension * sizeof(char *));
/*
    token points at the first character in str not to be
    found in the second argument to strtok (the delimiter
    string). str is then parsed and a null written at the
    next delimiter found.
*/
    token = strtok (str,"\n \t\r\v");
    for (i=0; token;)
    {
        tokenlist = (char **) realloc (tokenlist, ++dimension *
                                       sizeof(char *));
        tokenlist[i] = malloc (strlen(token) + 1);
        strcpy (tokenlist[i], token);
        tokenlist[++i] = 0;
/*
        strtok remembers where it is in the string. The next
        call continues the parsing of the string. The delimiter
        string can be different between calls if desired
*/
        token = strtok(NULL,"\n \t\r\v");
    }
    for (i=0; tokenlist[i]; i++)
        printf("%s\n", tokenlist[i]);
    return EXIT_SUCCESS;
}

Return Value: Returns a pointer to the next token in string1.

strtol
Usage:
#include <stdlib.h>
long strtol (char *nptr, char **endptr, int base);
ANSI

Description:
strtol converts the ASCII string pointed to by nptr to a long integer
value. It will recognize white space then an optionally signed string of
digits. It will stop reading the string at the first character that
doesnt represent a part of the number. A pointer to that character will
be stored in the object endptr if endptr is not NULL.

If base is zero the first character after the optional sign will
determine the base of the conversion. If the first character is 0 and the
second character is not x or X, then the string is interpreted as octal.
If the first character is 0 and the second character is x or X it will be
interpreted as a hexadecimal integer.

If the first character is 1 through 9 the string is interpreted as
decimal integer. The upper or lower case letters A to Z are assigned the
values 10 through 35. Only letters with values less than the base are
permitted. If the base is not 0, the base must be between 2 and 36.

Example:
See strtoul

Return Value: If correct values would cause an overflow then LONG_MAX or
              LONG_MIN is returned according to the sign and errno is set
              to ERANGE. If an unrecognized character is encountered before
              a legal character, zero is returned.

See Also: atoi, atol, strtoul, scanf

strtoul
Usage:
#include <stdlib.h>
unsigned long int strtoul (const char *nptr, char **endptr, int base);
ANSI

Description:
Converts the ASCII string pointed to by nptr to a unsigned long decimal.
It will recognize white space then an optionally signed string of digits.
It will stop reading the string at the first character that doesn't
represent a part of the number. A pointer to that character will be
stored in the object endptr if endptr is not NULL.

If base is zero the first character after the optional sign will
determine the base of the conversion. If the first character is 0 and
the second character is not x or X, then the string is interpreted as
octal. If the first character is 0 and the second character is x or X it
will be interpreted as a hexadecimal integer. If the first character is
1 through 9 the string is interpreted as decimal integer.

The upper or lower case letters A to Z are assigned the values 10 through
35. Only letters with values less than the base are permitted. If the
base is not 0, the base must be between 2 and 36.

Return Value: If correct values would cause overflow ULONG_MAX is returned
              according to the sign and errno is set to ERANGE. If an
              unrecognized character is encountered before a legal
              character, zero is returned.

Example:
#include <stdio.h>
#include <stdlib.h>

char *string, *string2;

int main()
{
    unsigned long result;
    long result1;
    double result2;
    int base;

    string = "3.1415926Stop here";
    result2 = strtod (string, &string2);
    printf ("String [%s] strtod = [%f]\n", string, result2);
    base = 8;
    string = "1011013";
    result1 = strtol (string, &string2, base);
    printf("String [%s] strtol [%ld] (base 8)\n", string, result1);
    base = 2;
    string = "1011013";
    result = strtoul (string, &string2, base);
    printf ("String [%s] strtoul [%ld] (base 2)\n", string, result);
    return EXIT_SUCCESS;
}

See Also: atoi, atol, strtol, scanf

strupr
Usage:
#include <string.h>
char *strupr (char *string);

Description:
Converts any lowercase characters in string to uppercase.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string = "Mixed Case String";

int main()
{
    printf ("strupr Example [%s]\n", strupr(string));
    return EXIT_SUCCESS;
}

Return Value: Returns string.

See Also: strlwr, toupper

swab
Usage:
#include <string.h>
void swab (char *source, char *destination, int n);

Description:
Copies n bytes from source swapping each pair of adjacent bytes. The
converted string is stored at destination. The integer n should be even
as pairs of characters are swapped.

Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *string1 = "badcfehgjilknm";
char *string2 = "..............";

int main()
{
    swab (string1, string2, 14);
    printf ("string1 [%s] string2 [%s]\n", string1, string2);
    return EXIT_SUCCESS;
}

The Swap package
The Swap package allows programs that use the spawn() or system()
functions to temporarily remove themselves from memory so that the
spawned program can execute with the maximum possible memory available.
It does this by swapping the programs memory image out to a temporary
disk file. In order to use the Swap package, the appropriate _swapx.obj
file must be linked with your program, normally as the first object in
the linker command line.

 The Swap package is for real mode MS-DOS applications only and
 supports the C (compact), L (Large) and V (Virtual) memory models.
 Use the object files _swapc.obj, _swapl.obj and _swapv.obj
 respectively.

The position of the _SWAPX module in the executable determines how much
of the program will be "swapped out" to disk. For example, if _SWAPX is
the first object file in the linker's parameter list, then the entire
executable will be swapped to disk, with the exception of the Swap
kernel required to control windowing, piping, and reloading. You can get
Swap to leave more of the program in memory by positioning it in the
linker object file list after the object files you want to remain in
memory. For instance, your programs critical error handler or some other
interrupt service routine. Any interrupt service routine left in memory
and active while the rest of the program is "swapped out" must not
access any global data as this is likely to have been "swapped out" with
the rest of the program.

 Swap has default settings that enable it to be used in an application
 without changes to the source code. Additional facilities are available
 to the programmer if required.

Additional Facilities

Swap has the ability to capture program output through stdout and
redirect it to a file or a screen area (window) of specific dimensions.
The  function swap_pipe() controls capture to a file, while swap_window()
controls capture to a window. Both facilities can be used simultaneously,
output can be displayed in a window and captured to a file at the same
time. It is also possible to control the amount of memory allocated to
the  child process, to enable and disable Swap under program control and
to  control the location of the swap file. Access to these facilities are
described  in the function descriptions that follow.

Swap Defaults

The default settings for Swap are:

1.  Swapping is ON
2.  Windowing is OFF
3.  Piping is OFF
4.  Free paragraphs is OFF
5.  Swaps to the directory specified by the TEMP or TMP environment
    variable, or to the current directory if TEMP or TMP is not defined.

Constants Defined by swap.h

The header file swap.h prototypes the Swap functions. It also contains
definitions of error return codes that can be tested by applications
which  use Swap.

SWAP_FREEMEMERROR the primary memory block allocated for the program.

SWAP_NOVMSPACE   disk drive to write the image of the program. Generally
                 occurs when the user has defined TEMP or TMP to point a
                 small RAM drive.

If the latter error is obtained while spawning a child process, the
application can use swap_tempcheckoff() to prevent use of the TEMP path
and reinvoke the command so that the current working directory is used
instead.

The following functions constitute the Swap package:

swap_clearkeyboardoff
swap_clearkeyboardon
swap_freeparagraphs
swap_freeparagraphsoff
swap_freeparagraphson
swap_isclearkeyboardon
swap_isfreeparagraphson
swap_ison
swap_ispipeon
swap_istempcheckon
swap_istrapcbreakon
swap_iswindowon
swap_off
swap_on
swap_pipe
swap_pipeoff
swap_pipeon
swap_tempcheckoff
swap_tempcheckon
swap_trapcbreakoff
swap_trapcbreakon
swap_window
swap_windowoff
swap_windowon

swap_clearkeyboardoff swap_clearkeyboardon
Usage:
#include <swap.h>
void swap_clearkeyboardoff (void)
void swap_clearkeyboardon (void)

Description:
These functions turn the clear keyboard feature of Swap on or off. When
on, Swap will clear the keyboard buffer before returning from a spawned
process. The default is on.

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate the feature.

See Also: spawn, system

swap_freeparagraphs
Usage:
#include <swap.h>
void swap_freeparagraphs (unsigned int para);

Description:
The argument para is the number of 16 byte paragraphs of memory that
Swap is to make available for the spawned process. Swap normally frees
all the memory it can, but if you are running a program that will only
require  a only a small amount of memory then the use of this function
will allow  Swap to execute faster. Note that each kilobyte of memory
consists of 64 paragraphs. This call is for speed enhancement only. A
call to this function will implicitely turn on the "free paragraphs"
feature. It can be turned off again by calling swap_freeparagraphsoff().

If the number of paragraphs specified is greater than Swap can free,
Swap will free all it can and continue to spawn the process.

See Also: spawn, system

swap_freeparagraphsoff swap_freeparagraphson
Usage:
#include <swap.h>
void swap_freeparagraphsoff (void);
void swap_freeparagraphson (void);

Description:
These functions turn the "free paragraph" feature of Swap on or off.
When on, Swap will free only the specified amount of memory when spawning
a child process. The  number of paragraphs to be freed must have been
specified previously by a call to the function swap_freeparagraphs(), in
which case it is only required if a call to swap_freeparagraphsoff() has
been made in the interim.

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate the feature.

See Also: spawn, system

swap_isclearkeyboardon swap_isfreeparagraphson swap_ison
swap_ispipeon swap_istempcheckon swap_istrapcbreakon swap_iswindowon
Usage:
#include <swap.h>
int swap_isclearkeyboardon (void);
int swap_isfreeparagraphson (void);
int swap_ison (void);
int swap_ispipeon (void);
int swap_istempcheckon (void);
int swap_istrapcbreakon (void);
int swap_iswindowon (void);

Description:
These functions return the status of the flags concerned with the
configurable features available when using Swap. Refer to the
descriptions of the corresponding control functions for further
information.

Return Value: A non-zero, positve return value indicates that the feature
              is turned on.

See Also: spawn, system

swap_off swap_on
Usage:
#include <swap.h>
void swap_off (void);
void swap_on (void);

Description:
These functions turn Swap on or off. When off, calls to spawn() or
system() will behave as normal. The default is on.

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate swapping.

See Also: spawn, system

swap_pipe
Usage:
#include <swap.h>
void swap_pipe (const char *file);

Description:
This function specifies a file into which Swap will place a copy of the
output from the spawned  program. This facility only works for output
sent via stdout or stderr.

Output to the pipe file can be suspended by a call to swap_pipeoff().

See Also: spawn, system

swap_pipeoff swap_pipeon
Usage:
#include <swap.h>
void swap_pipeoff (void);
void swap_pipeon (void);

Description:
These functions turn the Swap "pipe output to file" facility on or off.
When on, all output from the program that goes through stdout or stderr
will be piped to the pipe file. The pipe file must have been previously
specified with a call to swap_pipe(), in which case it is only required
if a call has been made to swap_pipeoff() in the interim.

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate the pipe.

See Also: spawn, system

swap_tempcheckoff swap_tempcheckon
Usage:
#include <swap.h>
void swap_tempcheckoff (void);
void swap_tempcheckon (void);

Description:
By default Swap will save its memory image file in the directory pointed
to by the TEMP or TMP environment variable if there is one, or in the
current working directory if there is not. These functions turn this
behavior on or off. When off, the swap file will always be stored in the
current working directory. The default is on.

The ability to disable checking of TEMP or TMP is useful in the case
where the environment variable points to a RAM disk or other specialized
memory that you do not want to be used for the memory image of the
program being swapped.

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate checking of TEMP or TMP.

See Also: spawn, system

swap_trapcbreakoff swap_trapcbreakon
Usage:
#include <swap.h>
void swap_trapcbreakoff (void);
void swap_trapcbreakon (void);

Description:
These functions allow the Control-C trapping carried out by Swap to be
turned on or off. When on, Control-C and Control-Break are trapped by
Swap and ignored. The default is on.

 If you want the spawned program to react to Control-C or Control-Break
 you should install a Control-C handler yourself using the Control_C
 functions and turn Swap's handler off by calling the function
 swap_trapcbreakoff().

See Also: spawn, system

swap_window
Usage:
#include <swap.h>
void swap_window (int col, int lin, int x, int y);

Description:
This function specifies a screen area (window) that Swap is to use to
display output from the spawned  program. This facility only works for
output sent via stdout or stderr. The parameters are:

col              The left column of the window
row              The top row of the window
x                The width of the window in columns
y                The depth of the window in rows

Output to the window is scrolled and wrapped appropriately. It can be
suspended by a call to swap_windowoff().

See Also: spawn, system

swap_windowoff swap_windowon
Usage:
#include <swap.h>
void swap_windowoff (void);
void swap_windowon (void);

Description:
These functions turn the Swap "window program output" facility on or off.
When on, all output from the program that goes through stdout or stderr
will be sent to a specified screen area (window). The window must have
been previously defined  with a call to swap_window(), in which case
swap_windowon() is only required if a previous call has been made to
swap_windowoff().

 These function calls can be nested. If two calls are made to the off
 function, two calls will also be needed to the on function in order to
 reactivate the feature.

See Also: spawn, system

system
Usage:
#include <stdlib.h>
int system (const char *string);
ANSI

Description:
system causes string to be passed to the operating system command
processor as if the string had been typed in at the console. The
current program waits until the command is executed then resumes.

There is no way to determine the exit status of programs run using
system.Use one of the spawn functions if an exit status is required.

 System cannot be used to set environment variables.

Example:
#include <stdlib.h>

int main()
{
    system("set >>path.log");
    system("cat path.log");
    system("rm path.log");
    system("ls /w");
    return EXIT_SUCCESS;
}

Return Value: If there was not enough available memory to execute the
              process, then -1 is returned, else a 0 is returned.

See Also: exec, spawn

The Tab_size Package
The purpose of the Tab_size package is to provide a common API for all
programs that use tabs, so that tab width can be modified by the user
and all of the programs in the system can know about this. These
functions use a global system variable that is initialized to 8 (the
UNIX standard tab size) at run-time. This size can be manipulated with
tab_sizeset() and retrieved with tab_sizeget(). tab_sizegetenv() will
check the environment for TAB or TABS and return the value of the
environment variable if found, or 0 if neither of them is defined.
tab_putenv() will define the environment variable TAB= to the specified
tab size and will undefine TABS if it is present.

 These changes only affect spawned programs. No modifications are made
 to the user's original environment.

The Tab_size package limits legal tab sizes to the range 2 to 32.

tab_sizeget
Usage:
#include <tabsize.h>
unsigned short tab_sizeget (void);

Description:
This function is used to obtain the current setting of the global tab
size.

Example:
#include <stdio.h>
#include <tabsize.h>
#include <stdlib.h>

int main()
{
    unsigned short tabsize;
    tabsize = tab_sizeget();
    printf("The tab size is %d\n",tabsize);
    return EXIT_SUCCESS;
}

Return Value: Returns the current global tab size..

tab_sizegetenv
Usage:
#include <tabsize.h>
unsigned short tab_sizegetenv (void);

Description:
Obtains the value of the TAB environment variable. If there is no TAB
environment variable it will return the value of the TABS environment
variable. If neither environment variable exists it will return 0.

Example:
#include <stdio.h>
#include <tabsize.h>
#include <stdlib.h>

int main()
{
    unsigned short tab;
    tab = tab_sizegetenv();
    if (tab)
        printf("The value of TAB is %d\n",tab);
    else
        printf("TAB or TABS not defined.\n");
    return EXIT_SUCCESS;
}

Return Value: The value of TAB or TABS, if they exist, otherwise 0.

tab_sizeputenv
Usage:
#include <tabsize.h>
void tab_sizeputenv (unsigned short newtabsize);

Description:
Defines the environment variable TAB with a value equal to the specified
tab size. It will undefine the environment variable TABS if it is
present.

Example:
#include <stdio.h>
#include <tabsize.h>
#include <stdlib.h>

int main()
{
    unsigned short tab;
    tab_sizeputenv(4);
    tab = tab_sizegetenv();
    printf("The value of TAB is %d\n",tab);
    return EXIT_SUCCESS;
}

tab_sizeset
Usage:
#include <tabsize.h>
void tab_sizeset (unsigned short newtabsize)

Description:
This function is used to change the global tab size.

Example:
#include <stdio.h>
#include <tabsize.h>
#include <stdlib.h>

int main()
{
    unsigned short tabsize;

    tabsize = tab_sizeget();
    printf("The tab size was %d\n",tabsize);
    tab_sizeset(tabsize + 2);
    tabsize = tab_sizeget();
    printf("The tab size is now %d\n",tabsize);
    return EXIT_SUCCESS;
}

tan
Usage:
#include <math.h>
double tan (double x);
ANSI

Description:
Return the tangent x, where x is measured in radians.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double d = .45987;
    printf("The tangent of .45987 is [%f]\n", tan(d));
    return EXIT_SUCCESS;
}

Return Value: Returns the tangent of x.

tanh
Usage:
#include <math.h>
double tanh (double x);
ANSI

Description:
Return the hyperbolic tangent of x. x is measured in radians.

Example:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double d = .495;
    printf("The hyperbolic tan of .495 is [%f]\n", tanh(d));
    return EXIT_SUCCESS;
}

Return Value: Returns hyperbolic tangent of x.

tempnam
Usage:
#include <stdio.h>
char *tempnam (const char *dir, const char *prefix);
ANSI

Description:
The tempnam function generates a unique temporary file name that is both
valid, and not the same as, the name of any existing file.

The tempnam is similar to tmpnam, except that the string to be returned
is always malloc'ed. The dir argument is the directory in which to create
the temporary file. The prefix argument is a 5 character prefix string
which will be used for the start of the temporary filename.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *name;

    if ((name = tempnam(NULL,"abcde")) != NULL)
        printf("Temporary file %s created",name);
    else {
        printf("Unable to create temporary file");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: A malloc'ed string containing the temporary file name. If
              tempnam is unable to open the temporary file for any reason
              a NULL pointer is returned.

See Also: tmpnam

Time Package
Zortech C++ contains an ANSI compatible package of time functions for
obtaining and displaying system times. These functions require the
inclusion of the time.h header file.

The relevant contents of this header file is as follows:

#define CLOCKS_PER_SEC ((clock_t) 100)

typedef long clock_t;

#ifndef __TYPES_H
typedef long time_t;
#endif

/* Structure to contain broken-down time */
struct tm
{
    int tm_sec,   /* seconds 0..59                 */
    tm_min,       /* minutes 0..59                 */
    tm_hour,      /* hour of day 0..23             */
    tm_mday,      /* day of month 1..31            */
    tm_mon,       /* month 0..11                   */
    tm_year,      /* years since 1900              */
    tm_wday,      /* day of week, 0..6 (Sun..Sat)  */
    tm_yday,      /* day of year, 0..365           */
    tm_isdst;     /*  > 0 if daylight savings time */
                  /* == 0 if not DST               */
                  /*  0 < if don't know            */
};

clock_t clock (void);
double difftime (time_t,time_t);
time_t mktime (struct tm *);
time_t time (time_t *);
char * asctime (const struct tm *);
char * ctime (const time_t *);
struct tm * gmtime (const time_t *);
struct tm * localtime (const time_t *);
size_t strftime (char *,size_t,const char *,const struct tm *);

#define difftime(t1,t2) ((double)((time_t)(t1)-(time_t)(t2)))

/* non-ANSI stuff */

#define TIMEOFFSET 315558000 /* Unix time - DOS time */
#define CLK_TCK    CLOCKS_PER_SEC

void sleep (time_t);
void usleep (unsigned long);
void msleep (unsigned long);

The clock function returns an approximation of the processor time used
by the calling program up to the time the clock function was called.
clock always returns the time in units of 1/100th of a second, even
though on the IBM PC the smallest measurable unit is in fact 1/18th of a
second. If the value returned by clock is divided by the CLOCKS_PER_SEC
macro it will yield the time in seconds. The clock function is useful
for elapsed time calculations.

The xxxtime functions depend on the operation of the function time. This
gets the operating system time, if available, and converts it into the
number of seconds elapsed since 00:00:00 GMT on January 1, 1970. The
result of this function is returned as a data type time_t, which is
defined as a long either in time.h or types.h. This figure is then used
as a basis for difftime, ctime, gmtime and localtime.

The difftime function is different in purpose from the other three
functions. It simply returns the difference in seconds between two
time_t values obtained by calls to time.

The functions gmtime and localtime take a time_t value obtained from a
call to time, and convert it into a different representation, as a
struct tm. This contains the time value broken down into seconds,
minutes, hours, days, weeks and so on. The function gmtime converts the
value with respect to Greenwich Mean Time whereas localtime carries out
any required corrections for time zone and daylight saving time where
such information is available.

The struct tm values obtained from gmtime and localtime are themselves
used as the input to a further set of time functions, mktime, asctime
and strftime. The function mktime is simply the reverse of gmtime and
localtime in that it takes a struct tm representation of the system time,
and converts it back to a time_t representation as seconds since
00:00:00 GMT on January 1, 1970.

The function asctime has a different purpose. It takes the struct tm
value and converts it into a ascii string, which can be printed,
displayed or manipulated. The string is 26 characters long and consists
of 3 characters representing the day of the week e.g. MON, followed by a
space and then three representing the month e.g. MAR, another space and
then two digits representing the day in the month. After a further space,
the next 8 characters display the time in hours, minutes and seconds with
colon separators. There is one further space followed by four digits for
the year, a newline and the null character to mark the end of the string.
A typical string would be

 "MON MAR 7 12:21:35 1989\n"

To bring these functions together, a normal course of action to undertake,
if the system time is required in a displayable format, would be:

1.  create a variable of type time_t.
2.  create a pointer to struct tm.
3.  create a pointer to char.
4.  call time with the address of this variable.
5.  call localtime passing it the value from time as argument, and
    assigning the return value to the struct tm pointer.
6.  call asctime passing it the struct tm pointer and assigning its
    return value to the char pointer.
7.  print the char pointer.

The ctime function allows you to combine phases 5 and 6 above, in that it
takes a time_t value obtained by a call to time, and returns a pointer to
a printable string directly. It is exactly equivalent to the localtime,
asctime sequence above.

 It is important to appreciate that both the gmtime/localtime functions
 and the asctime/ctime functions return a pointer to a static data
 object, in the first case a struct tm , and in the second case a null
 terminated string. These data objects are reused each time one of these
 functions is called, and any previous contents are overwritten.
 Therefore it is the programmer s responsibility to ensure, should one
 of these values need to be retained, that a copy is made of the object
 in question.

The final three functions defined in time.h, sleep, usleep and msleep,
are not strictly part of the time package. Refer to their entries for a
description of these functions.

time
Usage:
#include <time.h>
time_t time (time_t *timeptr);
ANSI

Description:
The time function returns the current time in seconds elapsed since
00:00:00 GMT on January 1, 1970 and stores that value in *timeptr if
timeptr is not NULL.

Example:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    time_t ntime;
    time(&ntime);
    printf("The time is: %s\n", ctime(&ntime));
    return EXIT_SUCCESS;
}

Return Value: time returns the number of seconds since 00:00:00 GMT on
              January 1, 1970.

See Also: ctime, asctime, localtime, mktime

tmpnam
Usage:
#include <stdio.h>
char *tmpnam (const char *s);
ANSI

Description:
The tmpnam function generates a unique temporary file name that is both
valid, and not the same as, the name of any existing file.

The tmpnam function generates a different string each time it is called,
up a to a maximum which is defined by the macro TMP_MAX, found in
stdio.h. If tmpnam is called more than TMP_MAX times the generated names
cannot be guaranteed to be unique. The argument passed to tmpnam can be
either a pointer to a buffer, which should be large enough to hold the
file name, or a NULL pointer.

Example:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *name;

    if ((name = tmpnam(NULL)) != NULL)
        printf("Temporary file %s created",name);
    else {
        printf("Unable to create temporary file");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Return Value: If the argument passed to tmpnam is a pointer to a buffer,
              the temporary file name is placed in this buffer, and the
              return value is a pointer to this buffer. If the argument
              to tmpnam is a NULL pointer, the file name is placed in a
              static data area, overwritten at each call to tmpnam, and
              a pointer to this static data buffer is returned.

toascii
Usage:
#include <ctype.h>
int toascii (int c);

Description:
toascii converts c to a character by taking any integer value and
discarding all but the low order seven bits making up an ASCII character.
If c is already a valid character, then it is returned unchanged.

Implemented as a macro in ctype.h, toascii is also included as a function
within the library. Undefining the macros, or not including ctype.h, will
cause the library functions to be used.

Example:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Make ASCII character [%c]\n", toascii(0x0e));
    return EXIT_SUCCESS;
}

Return Value: Returns the low 7 bits of c.

tolower toupper
Usage:
#include <ctype.h>
int tolower (int c);
int toupper (int c);
Both ANSI

Description:
tolower    converts any integer value c in the range of A - Z to
           lower case.

toupper    converts any integer value c in the range of a - z to
           upper case.

These are implemented as macros in ctype.h, and are also included as
functions within the library. Undefining the macros, or not including
ctype.h, will cause the library functions to be used.

Example:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Lowercase character [%c]\n", tolower(0x4d));
    return EXIT_SUCCESS;
}

Return Value:
tolower    returns c, converted to lower case if it was upper case,
           otherwise c is returned unchanged.

toupper    returns c, converted to upper case if it was lower case,
           otherwise c is returned unchanged.

The TSR Package
This is an MS-DOS specific package of functions for creating memory
resident programs.

 These functions are not available under the Z, X or P memory models or
 when compilng for OS/2.

tsr_install
 Note - This function is not available under OS/2 or when using the Z,
 X or P memory models.

Usage:
#include <tsr.h>
int tsr_install (int flag);

Description:
Causes the program to terminate but stay resident. Installs the TSR
interrupt handlers and sets up the hotkey. If flag is TIMESLICE, popmain
is called on the timer interrupt, a maximum of 18.2 times a second. If
flag is POPONLY, popmain is activated only when the hotkey is pressed.
The value TSR_DEBUG can be ored with flag so that the TSR is installed
with debugging mode turned on.

Return Value: Returns 1 if it cannot install because another copy
              is already installed. If the function is successful
              it does not return.

See Also: tsr_uninstall

tsr_service
 Note - This function is not available under OS/2 or when using the Z,
 X or P memory models.

Usage:
#include <tsr.h>
void tsr_service (void);

Description:
Causes an int 0x28 to be issued, allowing other TSRs a chance to execute
while the current TSR is active.

tsr_uninstall
 Note - This function is not available under OS/2 or when using the Z,
 X or P memory models.

Usage:
#include <tsr.h>
int tsr_uninstall(void)

Description:
If called from an active TSR (i.e. one that has not yet tried to become
resident), attempts to un-install a previously installed version of the
TSR program. If called from an active TSR, it will attempt to un-install
itself.

Return Value:  0   Success
               2   Cannot remove, program is not loaded
               3   Cannot remove, another TSR is installed on top of this
                   program

ungetc
Usage:
#include <stdio.h>
int ungetc (int c, FILE *fp);
ANSI

Description:
Puts character c back into the input stream fp, where it is read by the
next input operation on the stream. If an fseek is done between an
ungetc and the next read, then the ungotten character is lost. Only one
character may be put back between reads. EOF cannot be ungotten.

Example:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

int main()
{
    char ch;
    FILE *stream;
    stream = fopen ("file.dat","r");
    while ((ch = fgetc(stream)) != EOF)
        if (isspace(ch)) break;
    ungetc (ch, stream);
    ch = fgetc (stream);
    fclose (stream);
    return EXIT_SUCCESS;
}

Return Value: ungetc returns c if successful and returns an EOF if the
              character cannot be pushed back.

See Also: getc, getchar, putc, putchar

unlink
Usage:
#include <io.h>
int unlink (const char *filename);

Description:
unlink deletes the file specified by the string filename.

Example:
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

int main()
{
    int value;
    char buffer[13];
    char *result;

    printf("Input file to remove: ");
    result = gets(buffer);
    value = unlink(result);
    if(value == 0) {
        printf("Erased [%s] from disk\n",result);
        return EXIT_SUCCESS;
    } else {
        printf("Unable to erase [%s]\n",result);
        return EXIT_FAILURE;
    }
}

Return Value: Returns 0 if the file was successfully deleted or -1 if an
              error occurred and errno is set.

usleep
Usage:
#include <time.h>
void usleep (long microseconds);

Description:
Suspends execution of the program for the specified number of
microseconds. The granularity depends on the operating system.

Example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    printf ("Going to sleep for 10 seconds\n");
    usleep (10000000);
    printf ("OK, back again now\n");
    return EXIT_SUCCESS;
}

See Also: sleep, msleep

utime
Usage:
#include <time.h>
int utime (char *path, time_t times[]);

Description:
utime changes the modified time associated with the file specified by the
path argument. The argument times contains the new time to be applied to
the file. The times array should contain the last access time and a last
modified time, respectively. If the times argument is NULL, then the
current time will be used.

Example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main (int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf (stderr,"Usage: utime [file.name]\n");
        abort();
    }
    if (utime(argv[1],NULL) == -1)
    {
        fprintf (stderr,"Could not update file [%s]\n", argv[1]);
        abort();
    }
    return EXIT_SUCCESS;
}

Return Value: utime returns a 0 on success and a -1 if an error occurred
              and errno is set.

See Also: time, stat, fstat

va_arg va_end va_start
Usage:
#include <stdarg.h>
type va_arg (va_list arg_ptr, type);
void va_end (va_list arg_ptr);
void va_start (va_list arg_ptr, prev_parm);
All ANSI

Description:
These macros are used to maintain a list of arguments to be accessed
within functions that accept a variable number of arguments (e.g. the
vprintf function).

va_list is a type of variable argument list defined in stdarg.h,
together with the three macros, this allows variable argument lists to
be processed by a function when it does not know the number of arguments
being passed. The va_list array holds information required by va_arg and
va_end. When a called function takes a variable argument list, it
declares a variable of type va_list.

va_start is first called to initialize the argument list, for which the
parameter arg_ptr points to the first argument in the va_list. The other
parameter prev_parm is the parameter preceding the first argument. After
a call to va_start, a call to va_arg will evaluate data type from the
location pointed to by arg_ptr and increment arg_ptr.

va_end resets arg_ptr to NULL.

Example:
See vfprintf.

Return Value: va_arg returns the current argument.
              va_start and va_end evaluate to void.

vprintf vfprintf vsprintf
Usage:
#include <stdio.h>
#include <stdarg.h>
int vfprintf (FILE *stream, const char *format, va_list arg_ptr);
int vprintf (const char *format, va_list arg_ptr);
int vsprintf (char *buffer, const char *format, va_list arg_ptr);
All ANSI

Description:
These functions are all similar to their counterparts printf(), fprintf()
and sprintf() except the data is taken from the va_list arg_ptr. See
fprintf for a description of the format commands.

Example:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

varprint (char *format, ...)
{
    va_list arg_ptr;
    va_start (arg_ptr, format);
    vprintf (format, arg_ptr);
    va_end (arg_ptr);
}

int main()
{
    char *string = "STRING";
    int hnum = 0xb000;
    varprint ("Call with a %s parm and a %x hex parm\n", string, hnum);
    varprint ("Or with no parms\n");
    return EXIT_SUCCESS;
}

Return Value: The number of characters written if successful, or
              a negative number on error.

See Also: fprintf, printf, sprintf

write
Usage:
#include <io.h>
int write (int fd, void *buffer, size_t length);

Description:
Write length bytes from buffer to the file specified by the file
descriptor fd. This is a binary-only operation and is not buffered.

Example:
#include <io.h>
#include <string.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>

int main()
{
    unsigned int fd;
    char *buffer = "Write this data to file";
    unsigned int count;
    int nwritten;

    count = strlen (buffer);
    fd = open ("file.dat", O_WRONLY);
    if (fd == -1) {
            fputs ("Unable to open file",stdout);
            return EXIT_FAILURE;
    }
    nwritten = write (fd, buffer, count);
    printf ("\nWRITE:\n%u bytes written to file\n", nwritten);
    close (fd);
    return EXIT_SUCCESS;
}

Return Value: write returns the number of actual bytes written or a -1 if
              an error occurred and errno is set.

_X386_mk_protected_ptr
Usage:
#include <dosx.h>
void far *_X386_mk_protected_ptr (unsigned base_addr)

Description:
This function is implemented for the X memory model only. It returns a
protected mode far pointer that can be used to access the memory at
base_addr. A maximum of 8 protected mode pointers can exist at any time,
unused, previously allocated ones can be freed with
_X386_free_protected_ptr().

Return Value: A protected mode far pointer.

_X386_free_protected_ptr
Usage:
#include <dosx.h>
void _X386_free_protected_ptr (void far *)

Description:
This function is implemented for the X memory model only. It frees a
protected mode far pointer that has been previously allocated with
_x386_mk_protected_ptr(). A maximum of 8 protected mode pointers can
exist at any time, unused.

_X386_get_abs_addr
Usage:
#include <dos.h>
unsigned _X386_get_abs_addr (unsigned seg, unsigned off)

Description:
This function is implemented for the X memory model only. This returns a
32 bit address relative to zero with a protected mode segment selector
and a 32 bit offset for inputs. This can be used to find the starting
address of DGROUP as follows:

dgroup_address = _X386_get_abs_addr(getDS(),0);

Return Value: A 32 protected mode address relative to zero.

ZPMExtAvail
Usage:
#include <zpmapi.h>
long ZPMExtAvail();

Description:
This function is implemented for the Z memory model only. It returns
the number of bytes of extended memory available for allocation. Due to
fragmentation, there is no guarantee that you can obtain a single
allocation of the number of bytes returned by this function.

 Because the function is run with interrupts enabled, real time
 applications should not call it from an external interrupt handler.

Example:
/* This example prints the number of bytes of */
 * extended memory that are free.
*/
printf( %ld bytes of extended memory are free", ZPMExtAvail());

Return Value: See description

See Also: ZPMLowAvail

ZPMLowAlloc
Usage:
#include <zpmapi.h>
void far *ZPMLowAlloc (unsigned size);

Description:
This function is implemented for the Z memory model only. It allocates a
data segment in low memory. The argument size in the call to ZPMLowAlloc
specifies the size in bytes of the data segment being allocated. Since a
value of 64 kb is too large for an unsigned variable, specify a size of 0
to allocate a 64 kb segment. (This is incompatible with the C library
malloc function, which will allocate a block of zero bytes.) ZPMLowAlloc
is similar to DOS int 21h, function 48h.

 Because the function is run with interrupts enabled, real time
 applications should not call it from an external interrupt handler.

Example:
/*
    The first function below calls ZPMLowAlloc to allocate a 32 Kb
    data segment in low memory. The pointer returned by the call is
    stored in low_data_ptr. The function prints out the result of the
    call to ZPMLowAlloc and returns low_data_ptr.

    The second function in the example calls ZPMLowFree to free the
    segment pointed to by low_data_ptr. After this call, the function
    prints a message to indicate whether or not the memory was freed.
*/
char far *alloc_low_dat()
{
    char far *low_data_ptr;

    low_data_ptr = ZPMLowAlloc (32 * 1024);
    if (low_data_ptr)
       printf("Segment allocate");
    else
       printf("Error: Cannot allocate segment.");
    return(low_data_ptr);
}
    . . .

void free_low_data (char far *low_data_ptr)
{
    if (ZPMLowFree(low_data_ptr))
       printf("Segment freed");
    else
       printf("Error: Cannot free segment");
}

Return Value: A pointer to the allocated data segment, or a null pointer
              if an error occurred. A new selector is assigned for the
              selector portion of the pointer.

See Also: ZPMLowFree

ZPMLowAvail
Usage:
#include <zpmapi.h>
long ZPMLowAvail();

Description:
This function is implemented for the Z memory model only. It returns the
total available bytes of DOS managed memory. Because of fragmentation,
there is no guarantee that the number of bytes returned by this function
can be allocated in a single allocation.

Example:
/* This line of code prints out the number of bytes of DOS memory
   that are available.
*/
printf ( %ld bytes of low memory are available.", ZPMLowAvail());

Return Value: See description

See Also: ZPMExtAvail

ZPMLowFree
Usage:
#include <zpmapi.h>
int ZPMLowFree (void far *pm_ptr);

Description:
This function is implemented for the Z memory model only. Ii frees the
protected mode segment in low memory specified by pm_ptr and cancels the
selector. This is equivalent to DOS function 49h but is easier to access.

 Because the function is run with interrupts enabled, real time
 applications should not call it from an external interrupt handler.

Example:
See the example for ZPMLowAlloc.

Return Value: Returns nonzero if successful, zero if unsuccessful.

See Also: ZPMLowAlloc

ZPMProtectedPtr
Usage:
#include <zpmapi.h>
void far *ZPMProtectedPtr (void far *rm_ptr, unsigned size);

Description:
This function is implemented for the Z memory model only. It creates a
protected mode pointer from a real mode pointer. The protected mode data
pointer created by this function points to a segment of size bytes. Since
a value of 64K is too large for an unsigned variable, use 0 to specify
64K for size. The offset of pm_ptr is always 0. The base physical address
of the segment of pm_ptr is the absolute address of rm_ptr, which is
segment(rm_ptr) * 16 + offset(rm_ptr).

 Because the function is run with interrupts enabled, real time
 applications should not call it from an external interrupt handler.

Example:
/*
    The function below returns a protected mode pointer temp_ptr
    from the real mode pointer real_pnt passed to it. The protected
    mode pointer points to a segment of 200 bytes. The function
    notifies the user if it can't allocate the selector.
*/
#include <zpmapi.h)

void far * protected_ptr (void * far real_ptr)
{
    void * far temp_ptr = ZPMProtectedPtr (real_ptr, 200);
    if (!temp_ptr) printf ("Error: Could not allocate selector.");
    return (temp_ptr);
}

Return Value: The protected mode pointer, or null if the pointer can not
              be allocated. A new selector is allocated for the selector
              portion of the pointer.

See Also: ZPMRealPtr

ZPMRealPtr
Usage:
#include <zpmapi.h>
void far *ZPMRealPtr (void far *pm_ptr);

Description:
This function is implemented for the Z memory model only. It creates a
real mode pointer from a protected mode pointer. The pm_ptr argument is
the protected mode pointer to be converted. Note that if the real mode
pointer points to 0:0, the returned value is the same as an error value.

Example:
/*
    The function below is passed the protected mode pointer protpnt
    and calls ZPMRealPtr to convert it to a real mode pointer. The
    return value is stored in realpnt. If ZPMRealPtr returns a null
    pointer, an error message is printed. The sample function then
    returns realpnt.
*/
char far *sample (char far *protpnt)
{
    char far *realpnt;
    realpnt = ZPMRealPtr (protpnt));
    if (!realpnt)
        printf ("Error: can't convert to a real mode pointer");
    return (realpnt);
}

Return Value: The real mode pointer, or null if pm_ptr is in extended
              memory (and not accessible in real mode).

See Also: ZPMProtectedPtr

A. FURTHER READING
Appendix A - Further Reading
C++ Language Definition
Ellis, Margaret and Stroustrup, Bjarne. The Annotated C++ Reference
Manual, Addison-Wesley, 1990, ISBN 0-201-51459-1.

Stroustrup, Bjarne. The C++ Programming Language, Addison-Wesley,
1986, ISBN 0-201-12078-X.

Stroustrup, Bjarne. C++ Release 2.0 documentation, AT&T Bell
Laboratories, 1989. Obtainable from the AT&T Customer Information
Center, telephone (800)432-6600:
---Release Notes (307-090)
---Product Reference (307-146)
---Library Manual (307-145)
---Selected Readings (307-144)

Stroustrup, Bjarne. C++ Release 2.1 documentation, AT&T Bell
Laboratories, 1989.
Books Exclusively on C++
C++ at Work '89, Conference Proceedings, JPAM Inc, 1989

Dewhurst, Stephen C. and Stark, Kathy T. Programming in C++, Prentice
Hall, 1989, ISBN 0-13-723156-3.

Gorlen, Keith E., Orlow, Sanford M. and Plexico, S. Perry. Data
Abstraction and Object-Oriented Programming in C++, John Wiley & Sons,
1990, ISBN 0-471-92346-X.

Hansen, Tony L. The C++ Answer Book, Addison-Wesley, ISBN 0-201-11497-6.

Lippman, Stanley B. C++ Primer, Addison-Wesley, 1989, ISBN 0-201-16487-6.

OOPSLA 1988 Conference Proceedings, ACM Press (11 West 42nd Street,
New York, NY  10036).

Pohl, Ira. C++ for C Programmers, Benjamin/Cummings Publishing, 1989,
ISBN 0-8053-0910-1.

Ladd, Scott Robert, C++ Techniques and Applications, M&T Books, 1990

Weiskamp, Keith and Flamig, Brian. The Complete C++ Primer, Acedemic
Press, 1989.

Proceedings of the 1987, 1988 and 1990 C++ Conferences, USENIX
Association (PO Box 2299, Berkeley, CA 94710).
Object-oriented Programming (not specific to C++)
Abelson, Harold and Sussman, Jay. Structure and Interpretation of
Computer Programs, McGraw-Hill Book Company (MIT Press), 1987,
ISBN 0-262-01077-1.

Booch, Grady. Software Engineering with Ada, Benjamin Cummings, 1986,
ISBN 0-8053-0604-8.

Cox, Brad J. Object Oriented Programming: an Evolutionary Approach,
Addison-Wesley, 1987, ISBN 0-201-10393-1.

Meyer, Bertrand. Object-Oriented Software Construction, Prentice Hall
International, 1988, ISBN 0-13-629049-3.
Programming for Microsoft Windows
Petzold, Charles. Programming Windows, Second Edition, Microsoft Press,
1990, ISBN 1-55615-2467.
Programming for OS/2
The Microsoft OS/2 Programmer's Reference, Volumes I to IV, Microsoft
Press, 1989, ISBN 1-55615-220-5

Iacobucci, Ed, OS/2 Programmers Guide, Osborne McGraw-Hill, 1989,
ISBN 0-07-881300-X.

Duncan, Ray, Advanced OS/2 Programming, 1989, Microsoft Press, ISBN
1-55615-045-8.

Petzold, Charles, Programming the OS/2 Presentation Manager, 1989,
Microsoft Press, ISBN 1-55615-170-5.
Magazines
The C++ Report: the International Newsletter for C++ Programmers,
JPAM, SIGS Publications Group (310 Madison Ave., Suite 503, New York,
NY 10017, (212) 972-7055).

The Journal of Object-Oriented Programming, SIGS Publications Group
(310 Madison Ave., Suite 503, New York, NY 10017, (212) 972-7055).
Training
The C++ Video Course, Zortech Ltd, 1989. VHS format for NSTC or PAL.

Appendix B - Technical Support
Zortech operates two technical support services: one for the U.S.A. and
the Americas and one for the U.K. and Europe. Whichever you use, Zortech
staff will be pleased to deal with your problems.

It will help our technical support staff if you adopt the following
procedure before calling.

1. Check the manual!

2. Attempt to isolate a suspected bug to a trivial example. A good method
is to remove half of the code and try again, repeating the process until
the problem is isolated to a half dozen lines. Often this procedure can
suggest a fix or work-around.

3. Have the version numbers of the software you are using ready to hand.
(To find the version of the compiler you are using, compile a file with
the -v switch, or run ZTC1, etc. with no arguments.)

4. If the problem is not urgent, report it by mail with a disk or
listing, or by fax.

Technical Support Centers are:

U.S.A. and the Americas

Zortech Inc., Technical Support
4-C Gill Street
Woburn
MA 01801
U.S.A.
Hotline:    (617) 937-0696
Fax:        (617) 643-7969
BBS:        (206) 822-6907

United Kingdom and Europe

Zortech Ltd., Technical Support
58-60 Beresford Street
Woolwich
London-SE18 6BG
England
Hotline:    081-316 7777
Fax:        081-316 4138
BBS:        081-855 3286

Zortech also has a support conference on BIX. Just type "join zortech"
at the main prompt.

Zortech also has number of email addresses:

ztc-list@zortech.com            General requests and discussion
ztc-list-request@zortech.com    Requests to be added to ztc-list
ztc-bugs@zortech.com            For short bug reports

