/**************************************************************************
 *{@C
 *      Copyright:      1988-2024 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UT_ErrInit.c
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    This file contains functions to translate error
 *                      messages supplied by the operating system into
 *                      error codes that are understood by the error and
 *                      signal handling functions.
 *
 *      Additional documentation:
 *                      None.
 *
 *      Exported functions:
 *                      UT_ErrInit
 *                      UT_ErrFromOs
 *
 **************************************************************************/

#include <stdio.h>
#include <errno.h>

#include "UT_Compat.h"

#include "UT_Error.h"
#include "UT_ErrPrivate.h"
#include "UT_ErrTexts.h"

UT_ErrBase UT_ErrList;

/***************************************************************************
 *[@e
 *      Name:           UT_ErrInit
 *
 *      Usage:          Initialize the error management library.
 *
 *      Synopsis:       void UT_ErrInit (void)
 *
 *      Description:    Initialize the error management library.
 *
 *      Return value:   None.
 *
 *      See also:
 *
 ***************************************************************************/

void UT_ErrInit (void)
{
    if (UT_ErrInitialized) {
        return;
    }

    UT_ErrInitialized = UT_True;
    UT_ErrSupply (UT_ErrTexts,
                sizeof (UT_ErrTexts) / sizeof (char *),
                &UT_ErrList);
    UT_ErrSetNum (UT_ErrNone, "");

    return;
}

/***************************************************************************
 *[@e
 *      Name:           UT_ErrFromOs
 *
 *      Usage:          Translate error messages from the operating system
 *                      into error numbers for UT_ErrSetNum.
 *                      returns an error code indicating what went wrong.
 *
 *      Synopsis:       Int32 UT_ErrFromOs (void)
 *
 *      Description:    Translate error messages from the operating system
 *                      into error codes for UT_ErrSetNum.
 *                      When a program executes an operating system related
 *                      function (a system call or a standard library
 *                      function) and that function fails, a call to
 *                      UT_ErrFromOs returns an error code indicating what
 *                      went wrong.
 *
 *      Return value:   The error code number.
 *
 *      See also:
 *
 ***************************************************************************/

Int32 UT_ErrFromOs (void)
{
    if (!UT_ErrInitialized) {
        UT_ErrInit ();
    }

    switch (errno) {
        case EPERM:
            return UT_ErrNotOwner;
        case ENOENT:
            return UT_ErrNoFile;
        case ESRCH:
            return UT_ErrNoProcess;
        case EINTR:
            return UT_ErrIntr;
        case EIO:
            return UT_ErrIoErr;
        case ENODEV:
        case ENXIO:
            return UT_ErrNoDev;
        case E2BIG:
            return UT_ErrTooBig;
        case ENOEXEC:
            return UT_ErrExec;
        case EBADF:
            return UT_ErrBadFile;
        case ECHILD:
            return UT_ErrChild;
        case EAGAIN:
            return UT_ErrAgain;
        case ENOMEM:
            return UT_ErrNoMem;
        case EACCES:
            return UT_ErrPermission;
        case EFAULT:
            return UT_ErrAddress;
        #if !defined (CC_IS_MSC) && !defined (mingw)
        case ENOTBLK:
            return UT_ErrNoBlock;
        #endif
        case EBUSY:
            return UT_ErrBusy;
        case EEXIST:
            return UT_ErrExists;
        case EXDEV:
            return UT_ErrXdevive;
        case ENOTDIR:
            return UT_ErrNotDir;
        case EISDIR:
            return UT_ErrIsDir;
        case EINVAL:
            return UT_ErrInvalid;
        case ENFILE:
            return UT_ErrNumFiles;
        case EMFILE:
            return UT_ErrOpenFiles;
        case ENOTTY:
            return UT_ErrNoTty;
        #if !defined (CC_IS_MSC) && !defined (mingw)
        case ETXTBSY:
            return UT_ErrTextBusy;
        #endif
        case EFBIG:
            return UT_ErrFileTooBig;
        case ENOSPC:
            return UT_ErrFsFull;
        case ESPIPE:
            return UT_ErrSeekPipe;
        case EROFS:
            return UT_ErrFsReadonly;
        case EMLINK:
            return UT_ErrNumLinks;
        case EPIPE:
            return UT_ErrPipe;
        case EDOM:
            return UT_ErrDomain;
        case ERANGE:
            return UT_ErrRange;

        #if defined (OS_IS_BSD_UNIX)
        /* Identical to EAGAIN in Darwin */
        #if ! defined (Darwin)
            case EWOULDBLOCK:
                return UT_ErrWouldBlock;
        #endif
        case EINPROGRESS:
            return UT_ErrInProgress;
        case EALREADY:
            return UT_ErrAlready;
        case ENOTSOCK:
            return UT_ErrNotSock;
        case EDESTADDRREQ:
            return UT_ErrDestAddrReq;
        case EMSGSIZE:
            return UT_ErrMsgSize;
        case EPROTOTYPE:
            return UT_ErrPrototype;
        case ENOPROTOOPT:
            return UT_ErrNoProtoOpt;
        case EPROTONOSUPPORT:
            return UT_ErrProtNoSupp;
        case ESOCKTNOSUPPORT:
            return UT_ErrSockNoSupp;
        case EOPNOTSUPP:
            return UT_ErrOpNoSupp;
        case EPFNOSUPPORT:
            return UT_ErrPfNoSupp;
        case EAFNOSUPPORT:
            return UT_ErrAfNoSupp;
        case EADDRINUSE:
            return UT_ErrAddrInUse;
        case EADDRNOTAVAIL:
            return UT_ErrAddrNotAvail;
        case ENETDOWN:
            return UT_ErrNetDown;
        case ENETUNREACH:
            return UT_ErrNetUnreach;
        case ENETRESET:
            return UT_ErrNetReset;
        case ECONNABORTED:
            return UT_ErrConnAbort;
        case ECONNRESET:
            return UT_ErrConnReset;
        case ENOBUFS:
            return UT_ErrNoBufs;
        case EISCONN:
            return UT_ErrIsConn;
        case ENOTCONN:
            return UT_ErrNotConn;
        case ESHUTDOWN:
            return UT_ErrShutdown;
        case ETIMEDOUT:
            return UT_ErrTimedOut;
        case ECONNREFUSED:
            return UT_ErrConnRefused;
        case ELOOP:
            return UT_ErrLoop;
        case ENAMETOOLONG:
            return UT_ErrNameTooLong;
        case ENOTEMPTY:
            return UT_ErrNotEmpty;
        #endif /* OS_IS_BSD_UNIX */

    }
    return UT_ErrUnknown;
}
