/**************************************************************************
 *{@C
 *	Copyright:	1988-2020 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;
}
