/******************************************************************

    $Header$

    Module: Generics

    Author: Jeff Lait

    Copyright 1995 Ytinasin.

    Description: Contains all generic Ytinasin functions

 ******************************************************************/

/******************************************************************

  Revision Record

    Rev Date        Auth    Changes
    === ====        ====    =======

    0.0 21/12/95    jml     created this header
    0.1 13/08/97    jml     Hacked for uC++.

 ******************************************************************/

/******************************************************************
 * INCLUDES:
 ******************************************************************/
#include <uC++.h>
#include <uIOStream.h>
#include <uIOManip.h>
#include <uSemaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include "ugeneric.h"

#include <memory.h>

#include <fcntl.h>
#include <malloc.h>
#include <ctype.h>
#include <string.h> 

/******************************************************************
 * DEFINES:
 ******************************************************************/
#define ASSERT


/******************************************************************
 * GLOBAL VARIABLES:
 ******************************************************************/

// Threadsafes old library calls.
uSemaphore glbDiskLock(1);

/******************************************************************
 * LOCAL FUNCTION PROTOTYPES
 ******************************************************************/
void CRASH(int num, char *text);

#ifdef CPU_X86
// Triggers debugger, allows recovery.
extern void Int3();
#pragma aux Int3 =              \
        "int 3";
#else
void Int3()
{
}
#endif

/******************************************************************
 * LOCAL VARIABLES:
 ******************************************************************/
void (*error)(int num, char *text) = CRASH;


/********************************************************************
 * ReadOpen
 *      Opens a file for reading, using file *.
 ********************************************************************/
FILE *ReadOpenFP(char *fname) 
{
    FILE *fp;

#ifdef CPU_X86
    // Watcom kludge:
    _fmode = O_BINARY;
#endif

    fp = fopen(fname, "r");
    if (!fp) 
    {
            char s[90];

            sprintf(s, "Failed on opening %s\n", fname);
            error(ERR_FILEOPEN, s);
    }
    return(fp);
    }

/******************************************************************
 * FileSize
 *      Gets file size.
 *  NB: Resets file pointer
 ******************************************************************/
int FileSize(FILE *fp)
{
    int result;

    assert(fp);
    fseek(fp, 0, SEEK_END);
    result = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    return result;
}

/********************************************************************
 * WriteOpen
 *      Opens a file for writing, using FILE *.
 ********************************************************************/
FILE *WriteOpenFP(char *fname) 
{
    FILE *fp;

#ifdef CPU_X86
    _fmode = O_BINARY;
#endif

    fp = fopen(fname, "w");
    if (!fp) {
        char s[90];

        sprintf(s, "Failed on creating/truncating %s\n", fname);
        error(ERR_FILEOPEN, s);
        }
    return(fp);
    }

/********************************************************************
 * GetMem
 *      Retrieves a pointer to new memory.  Handles errors.
 * (Albeit, not well :>)
 ********************************************************************/
char *OptGetMem(int length) 
{
    char *temp;

    temp = new char [length];
    if (temp == NULL) {
        char s[90];
        sprintf(s, "Failure to allocate %d bytes\n", length);
        error(ERR_MALLOC, s);
        }
    return(temp);
    }


void OptFreeMem(char *p)
{
    delete [] p;
    }


/********************************************************************
 * SetErrorHandler
 *      Changes the default error handler.  The new one should
 *  crash the program (Ie: not return..)
 ********************************************************************/
void SetErrorHandler(void (*callback)(int num, char *text))
{
    error = callback;
    }

/******************************************************************
 * _assert
 *  Default assert behaviour.
 ******************************************************************/
void _assert(int expr, char *file, int line)
{
    if( !expr )
    {
        uCerr << uAcquire << "Assertion Failed\nFile " << file << ", Line " << line <<
                endl << uRelease;
        Int3();
        error(ERR_ASSERT, "Failed Assertion\n");
    }
}

/********************************************************************
 * Default error handler
 ********************************************************************/
void CRASH(int num, char *text)
{
    printf("Error #%d: %s\n", num, text);
    Int3();             /* Eases debugging (x86 only) */
    int foo = 4 / 0;	/* Trigger an exception... */
    printf("%d\n", foo);
    uExit(num);
    }

/******************************************************************
 * ourstrdup
 * This makes a lot more sense with the non-concurrent debug memory
 * manager....
 ******************************************************************/
char *ourstrdup(char *s)
{
    char *temp;

    temp = GetMem(strlen(s) +2);
    strcpy(temp, s);
    return(temp);
    }
