/*  Copyright (C) 1993   Marc Stern  (internet: stern@mble.philips.be)  */

#ifndef __Tools_H
#define __Tools_H

#include "c2cpp.h"
#include <stdio.h>
#include <io.h>
#include <dos.h>


/* for Microsoft (or other than Borland) */

#ifndef MK_FP
#define MK_FP( seg, ofs )   (void far *)( (unsigned long)((void far *)(seg)) + (unsigned long)((void near *)(ofs)) )

struct  fcb {
    char    fcb_drive;      /* 0 = default, 1 = A, 2 = B */
    char    fcb_name[8];    /* File name */
    char    fcb_ext[3];     /* File extension */
    short   fcb_curblk;     /* Current block number */
    short   fcb_recsize;    /* Logical record size in bytes */
    long    fcb_filsize;    /* File size in bytes */
    short   fcb_date;       /* Date file was last written */
    char    fcb_resv[10];   /* Reserved for DOS */
    char    fcb_currec;     /* Current record in block */
    long    fcb_random;     /* Random record number */
};

struct  xfcb    {
    char        xfcb_flag;    /* Contains 0xff to indicate xfcb */
    char        xfcb_resv[5];  /* Reserved for DOS */
    char        xfcb_attr;     /* Search attribute */
    struct  fcb xfcb_fcb;      /* The standard fcb */
};

#endif


            
typedef unsigned char BYTE;


/***
 *  Function    :  HIBYTE/LOWBYTE
 *
 *  Description :  Extract high/low byte of an integer
 *
 *  Parameters  :  in   int x
 *
 *  Side-effects:  Macro, so be careful.
 *
 *  Return      :  none
 ***/

#define HIBYTE( x ) ( (unsigned int)(x) >> 8 )
#define LOWBYTE( x) ( (unsigned char)(x) )


/***
 *  Function    :  CAST
 *
 *  Description :  Cast any object to any type.
 *
 *  Parameters  :  in     new_type      any type
 *                 in     object        any variable
 *
 *  Side-effects:  Macro, so be careful.
 *
 *  Return      :  none
 ***/

#define CAST( new_type, object ) ( *((new_type *)&object) )
     

/***
 *  Function    :  SWAP
 *
 *  Description :  Swap two arguments of any type.
 *
 *  Parameters  :  in/out   x      any type argument
 *                 in/out   y      any type argument
 *
 *  Side-effects:  Macro, so be careful.
 *
 *  Return      :  none
 ***/

#define SWAP( x, y )        ( (x) ^= (y) ^= (x) ^= (y) )


/***
 *  Function    :  fileexist
 *
 *  Description :  Test if a filename exist
 *
 *  Parameters  :  in   char *filename
 *
 *  Return      :  0 or 1
 ***/

#define fileexist( filename )   ( ! access(filename, 0) )


/***
 *  Function    :  ICA_get/put
 *
 *  Description :  Intra-application Communications Area get/put
 *                 a 16 bytes data
 *
 *  Parameters  :  in   void *ptr   pointer to a 16 bytes data
 *
 *  Return      :  none
 ***/

#define ICA_get( ptr )   ( memcpy(ptr, MK_FP(0x0040, 0x00F0), 16) )
#define ICA_put( ptr )   ( memcpy(MK_FP(0x0040, 0x00F0), ptr, 16) )



/***
 *  Function    :  getkey
 *
 *  Description :  Return a 2-bytes key pressed.
 *
 *  Parameters  :  none
 *
 *  Decisions   :  extended characters are added to 256.
 *
 *  Return code :  code of key pressed.
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int getkey( void );


/***
 *  Function    :  ungetkey
 *
 *  Description :  Puts a 2-bytes key into the keyboard buffer
 *
 *  Parameters  :  in    int key           key to be buffered
 *
 *  Decisions   :  extended characters are added to 256.
 *
 *  Return code :  none
 *
 *  Warning     :  May not work if a keyboard buffer extender is used.
 *                 Does not handle the case of buffer full.
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN void ungetkey( int key );



/***
 *  Function    :  fnreduce
 *
 *  Description :  Transforms a filename into a full reduced filename.
 *
 *  Parameters  :  in/out   char *filename    input/reduced filename
 *
 *  Decisions   :  Translate into uppercase
 *                  '/' are tranlated into '\\'
 *
 *  Return      :  pointer to result
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN char *fnreduce( char *filename );


/***
 *  Function    :  getpgmpath
 *
 *  Description :  Transforms a filename into a full pathname
 *                 relative to program directory.
 *
 *  Parameters  :  in/out   char *filename    input filename
 *
 *  Return      :  pointer to filename    
 *
 *  Precond     :  Global variable extern char **_argv must be defined
 *                 and assign to argv in main( int argc, char *argv[] )
 *                 Built-in in Borland
 *                 Built-in in Microsoft (uses _pgmptr)
 *
 *  OS/Compiler :  MS-DOS version >= 3.0
 ***/

EXTERN char *getpgmpath( char *filename );


/***
 *  Function    :  gettmppath
 *
 *  Description :  Transforms a filename into a full pathname
 *                 relative to temporary directory.
 *
 *  Decisions   :  Temporary directory is first searched
 *                 into environment variable 'TEMP',
 *                 after into environment variable 'TMP'.
 *                 If none are defined, program directory
 *                 is assumed.
 *
 *  Parameters  :  in/out  char *filename    filename
 *
 *  Return      :  pointer to filename
 *
 *  Precond     :  Global variable extern char **_argv must be defined
 *                 and assign to argv in main( int argc, char *argv[] )
 *                 Built-in in Borland
 *
 *  OS/Compiler :  MS-DOS version >= 3.0
 ***/

EXTERN char *gettmppath( char *filename );


/***
 *  Function    :  truename
 *
 *  Description :  Transforms a filename into a full reduced filename.
 *                 Resolves all SUBST's, JOIN's, network names,...
 *
 *  Parameters  :  in/out   char *filename    input/reduced filename
 *
 *  Warning     :   - Valid only for DOS >= 2.0
 *                  - Trailing '\' is not removed
 *
 *  Return      :  0      OK
 *                 2  Invalid syntax
 *                 3  Invalid drive or path
 *
 *  OS/Compiler :  MS-DOS version >= 2.0
 ***/

EXTERN int truename( char *filename );


/***
 *  Function    :  exthandles
 *
 *  Description :  Allows MS-DOS program to open 255 handles
 *
 *  Parameters  :  none
 *
 *  Return      :  none
 *
 *  OS/Compiler :  MS-DOS version >= 3.30
 ***/

EXTERN void exthandles( void );



/***
 *  Function    :  getdensity
 *
 *  Description :  Return the density of a floppy drive.
 *
 *  Parameters  :  in    int drive         0 = A:, 1 = B:
 *
 *  Return      :  density in Kb (360, 720, 1200, 1440)
 *                 0 if invalid drive or drive not ready
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int getdensity( int drive );


/***
 *
 *  Function    :  is_drive_ready
 *
 *  Description :  Return if a floppy drive is ready or not.
 *
 *  Parameters  :  in    int drive         0 = A:, 1 = B:, ...
 *
 *  Return      :  0 if not ready (or invalid)
 *                 1 if ready
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int is_drive_ready( int drive );



/***
 *
 *  Function    :  geterrorlevel
 *
 *  Description :  Return errorlevel code from previous command executed
 *                 by top COMMAND.COM
 *
 *  Parameters  :  none
 *
 *  Return      :  errorlevel
 *                 -1 If MS-DOS version not supported
 *
 *  Warning     :  This function is only valid with COMMAND.COM from
 *                 MS-DOS 3.20, 3.21, 3.30, 4.0, 4.01, 5.0 & NDOS 6.0.
 */

EXTERN int geterrorlevel( void );



/***
 *  Function    :  getdiskfree
 *
 *  Description :  Return the number of bytes free of a disk.
 *
 *  Parameters  :  in    int disk         0 = A:, 1 = B:, ...
 *
 *  Return      :  number of bytes free
 *                 -1 if invalid drive
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN long getdiskfree( int disk );


/***
 *  Function    :  setcwd
 *
 *  Description :  Change to specified directory accross disks
 *
 *  Parameters  :  in    char *dir    input directory name
 *
 *  Return      :  0      OK
 *                 other  Invalid syntax, drive or path
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int setcwd( const char *dir );


/***
 *  Function    :  getsetup
 *
 *  Description :  Read paramaters in setup file.
 *
 *  Parameters  :  in    FILE *file        input file
 *                 in    char *format      "keyword1=format keyword2=format"
 *                 out   pointer list
 *
 *  Decisions   :  Expected format is a list of lines of the form
 *
 *	       	                  <keyword>=<value>
 *
 *                 - All letters are treated (and returned) as uppercases.
 *                 - Blanks and tabs are skipped.
 *
 *                 - <value> can be enclosed between double quotes
 *	       	     to preserve lowercases and blanks.
 *
 * 	       	   - 2 consecutive double quotes allow to keep
 *                   a double quote in <value>.
 *
 *                 - A number sign (#) in first column forces the line
 *                   to be ignored.
 *
 *                 - The input formats in parameter 'format' are C standard
 *                   ones ( %d, %s, %f,...).
 *
 *                 - Special format added: "%b" will translate
 *                   True/False, Yes/No, On/Off, 1/0 into integer 1/0
 *
 *                 - Special format added: "%S" will result into copying
 *                   all the input line (with spaces in it if any).
 *                   It will not be processed by scanf-like processing.
 *
 *  Return      :  number of found parameters
 *                 -1     syntax error
 *                 -2     file error
 *
 *  Precond     :  Input file must be opened with read access.
 *
 *  OS/Compiler :  All
 */

EXTERN int getsetup( FILE *file, const char *format, ... );


/***
 *  Function    :  load_options
 *
 *  Description :  Load options from a file.
 *
 *  Parameters  :  out  void * options     ptr to variable containing options
 *                 in   size_t size        size of data to read
 *
 *  Decisions   :  The file has the same name as the program
 *                 with extension .OPT and is searched in
 *                 current directory, then in program directory.
 *                 If option file is not found, options are not modified.
 *
 *  Return      :  number of bytes read
 *                 -1 if file was not found
 *
 *  Precond     :  Global variable extern char **_argv must be defined
 *                 and assign to argv in main( int argc, char *argv[] )
 *                 Built-in in Borland
 *
 *  OS/Compiler :  MS-DOS version >= 3.0
 ***/

EXTERN int load_options( void *options, size_t size );

/***   To not specify the size   ***/
#define Opt_load( opt )     load_options( (opt), sizeof(*(opt)) )




/***
 *  Function    :  save_options
 *
 *  Description :  Save options in a file.
 *
 *  Parameters  :  in  void * options     ptr to variable containing options
 *                 in  size_t size        size of data to read
 *
 *  Decisions   :  If options were previously loaded, this file is used.
 *                 Otherwise, the file has the same name as the program
 *                 with extension .OPT and is located in program directory.
 *
 *  Return      :  number of bytes written
 *                 -1 if file not opened
 *
 *  Precond     :  Global variable extern char **_argv must be defined
 *                 and assign to argv in main( int argc, char *argv[] )
 *                 Built-in in Borland
 *
 *  OS/Compiler :  MS-DOS version >= 3.0
 ***/

EXTERN int save_options( const void *options, size_t size );

/***   To not specify the size   ***/
#define Opt_save( opt )     save_options( (opt), sizeof(*(opt)) )


/***
 *
 *  Function    :  load_cfg
 *
 *  Description :  Load configuration from a file.
 *
 *  Parameters :   in   char * name        filename
 *                 out  void * config      ptr to variable containing configuration
 *                 in   size_t size        size of data to read
 *
 *  Decisions   :  The file has the same name as the parameter 'name'
 *                 but with extension .CFG
 *                 If configuration file is not found, config is unchanged.
 *
 *  Return     :   number of bytes read
 *                 -1 if file was not found
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int load_cfg( const char *name, void *config, size_t bsize );

/***   To not specify the size   ***/
#define Cfg_load( name, cfg )   load_cfg( (name), (cfg), sizeof(*(cfg)) )



/***
 *
 *  Function    :  save_cfg
 *
 *  Description :  Save a configuration into a file.
 *
 *  Parameters  :  in   char * name        filename
 *                 in   void * config      ptr to variable containing configuration
 *                 in   size_t size        size of data to write
 *
 *  Decisions   :  The file has the same name as the parameter 'name'
 *                 but with extension .CFG
 *
 *  Return      :  number of bytes written
 *                 -1 if file was not found
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN int save_cfg( const char *name, const void *config, size_t bsize );

/***   To not specify the size   ***/
#define Cfg_save( name, cfg )   save_cfg( (name), (cfg), sizeof(*(cfg)) )



/***
 *  Function    :  filencopy
 *
 *  Description :  Copy n characters from a file on another.
 *
 *  Parameters  :  in   int            target    target file descriptor
 *                 in   int            source    source file descriptor
 *                 in   unsigned long  length    number of bytes to copy
 *
 *  Precond     :  The two files must be opened.
 *
 *  Decisions   :  The copy can stop when eof is reached.
 *
 *  Warning     :  no rewind is performed on either file!!!
 *
 *  Return      :  0 if OK
 *                 errno if error
 *
 *  OS/Compiler :  All
 ***/

EXTERN int filencopy( int source, int target, unsigned long length );

/* maximum size */
#define filecopy( source, target )    filencopy( source, target, 0xFFFFFFFF )


/***
 *  Function    :  Filencopy
 *
 *  Description :  Copy n characters from a file on another.
 *
 *  Parameters  :  in   char *         source    source filename
 *                 in   char *         target    target filename
 *                 in   unsigned long  length    number of bytes to copy
 *
 *  Decisions   :  The copy can stop when eof is reached.
 *
 *  Return      :  0 if OK
 *                 errno if error
 *
 *  OS/Compiler :  All
 ***/

EXTERN int Filencopy( const char *source, const char *target, unsigned long length );

/* maximum size */
#define Filecopy( source, target )    Filencopy( source, target, 0xFFFFFFFF )




/***
 *  Function    :  Filecat
 *
 *  Description :  Concatenate two files on another.
 *
 *  Parameters  :  in   char *     newpath     result filename
 *                 in   char *     path1       target filename
 *                 in   char *     path2       source filename
 *
 *  Return      :  0 if OK
 *                 errno if error
 *
 *  OS/Compiler :  All
 ***/

EXTERN int Filecat( const char *newpath, const char *path1, const char *path2 );


/***
 *  Function    :  filetrunc
 *
 *  Description :  Truncate a file to a specified length.
 *
 *  Parameters  :  in   int            fd        file descriptor
 *                 in   unsigned long  length    number of bytes to copy
 *
 *  Precond     :  The file must be opened with writing permission
 *
 *  Warning     :  no rewind is performed on the file!!!
 *
 *  Return      :  0 if OK
 *                 errno if error
 *
 *  OS/Compiler :  All
 ***/

EXTERN int filetrunc( int fd, unsigned long length );




/***
 *  Function    :  Filetrunc
 *
 *  Description :  Truncate a file to a specified length.
 *
 *  Parameters  :  in   char *         path      file descriptor
 *                 in   unsigned long  length    number of bytes to copy
 *
 *  Return      :  0 if OK
 *                 errno if error
 *
 *  OS/Compiler :  All
 ***/

EXTERN int Filetrunc( const char *path, int length );




/***
 *  Functions   :  filedel
 *
 *  Description :  Like 'unlink' but allows wildcards
 *
 *  Parameters  :  in   char *  filename   pathname with/without wildcards
 *
 *  Return      :  none
 *
 *  OS/Compiler :  MS-DOS
 ***/

EXTERN void filedel( const char *filename );



/***
 *  Function    :  getPasswd
 *
 *  Description :  Input a password (echoes '*')
 *
 *  Parameters  :  in  char *passwd    string to store password
 *
 *  Decisions   :  Echoes '*' in place of characters.
 *                  Backspace and left arrow can be used to erase characters
 *                  Characters must be in the range 32 - 254
 *
 *  Return      :  pointer to password
 *
 *  OS/Compiler :  MS-DOS & Turbo-C
 ***/

EXTERN char *getPasswd( char *passwd );



/***
 *  Function    :  vollabel
 *
 *  Description :  Get/Set disk volume label
 *
 *  Parameters  :  in       int drive         0 = A:, 1 = B:, ...
 *                 in/out   char *vol         volume label
 *
 *  Decisions   :  - If *vol = '\0', it is filled with disk volume label.
 *                 - Otherwise, vol is copied onto disk volume label.
 *
 *  Return      :   0 if OK
 *                 -1 if error
 ***/

EXTERN int vollabel( int drive, char *vol );


#if ! defined(__TURBOC__)
/*  void sound ( short frequency, long duration )
 *
 *  Makes the PC speaker emit a sound at `frequency' Herz for approximately
 *  `duration' milliseconds.
 */
EXTERN void sound ( short frequency, long duration );
#endif

/***
 *
 *  Function beep :   Emit a beep.
 *
 ***/
EXTERN void beep( void );

/***
 *
 *  Function buzzer:   Emit a buzzer sound.
 *
 ***/
EXTERN void buzzer( void );


#endif
