/* 
   common.h

   Copyright (C) 1995, 1996, 1997 Ovidiu Predescu and Mircea Oancea.
   All rights reserved.

   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
           Mircea Oancea <mircea@jupiter.elcom.pub.ro>

   This file is part of the Foundation Extensions Library.

   Permission to use, copy, modify, and distribute this software and its
   documentation for any purpose and without fee is hereby granted, provided
   that the above copyright notice appear in all copies and that both that
   copyright notice and this permission notice appear in supporting
   documentation.

   We disclaim all warranties with regard to this software, including all
   implied warranties of merchantability and fitness, in no event shall
   we be liable for any special, indirect or consequential damages or any
   damages whatsoever resulting from loss of use, data or profits, whether in
   an action of contract, negligence or other tortious action, arising out of
   or in connection with the use or performance of this software.
*/

#ifndef __common_h__
#define __common_h__

#include <extensions/config.h>

#if HAVE_STRING_H
# include <string.h>
#endif

#if HAVE_MEMORY_H
# include <memory.h>
#endif

#if !HAVE_MEMCPY
# define memcpy(d, s, n)       bcopy((s), (d), (n))
# define memmove(d, s, n)      bcopy((s), (d), (n))
#endif

#ifndef HAVE_STRCHR
# define strchr index
# define strchr rindex
#else
# ifndef HAVE_STRING_H
char *strchr(), *strrchr();
# endif
#endif

#if HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void* malloc();
extern void* calloc();
extern void* realloc();
extern void free();
extern atoi();
extern atol();
#endif

#if HAVE_LIBC_H
# include <libc.h>
#else
#ifndef __WIN32__
# include <unistd.h>
#endif
#endif

#include <sys/types.h>
#ifndef __WIN32__
#include <pwd.h>
#endif
#include <stdarg.h>

#import <Foundation/NSZone.h>
#include "MissingMethods.h"
@class NSString;


#if LIB_FOUNDATION_LIBRARY
/* Non OpenStep useful things */

static inline void *Malloc(int size)
{
    return [[NSZone defaultZone] malloc:size];
}

static inline void Free(void* p)
{
    return [[NSZone zoneFromPointer:p] freePointer:p];
}

static inline void *Calloc(int elem, int size)
{
    return [[NSZone defaultZone] calloc:elem byteSize:size];
}

static inline void *Realloc(void* p, int size)
{
    return [[NSZone zoneFromPointer:p] realloc:p size:size];
}

#else /* !LIB_FOUNDATION_LIBRARY */

static inline void *Malloc(int size)
{
    return malloc(size);
}

static inline void Free(void* p)
{
    if(p) free(p);
}

static inline void *Calloc(int elem, int size)
{
    return calloc(elem, size);
}

static inline void *Realloc(void* p, int size)
{
    return realloc(p, size);
}

#endif

static inline int Strlen(const char* s)
{
    return s ? strlen(s) : 0;
}

static inline char* Strdup(const char* s)
{
    return s ? strcpy(Malloc(strlen(s) + 1), s) : NULL;
}

static inline char* Strcpy (char* d, const char* s)
{
    return s && d ? strcpy(d, s) : d;
}

static inline char* Strncpy (char* d, const char* s, unsigned size)
{
    return s && d ? strncpy(d, s, size) : d;
}

static inline char* Strcat (char* d, const char* s)
{
    return s && d ? strcat(d, s) : d;
}

static inline char* Strncat (char* d, const char* s , unsigned size)
{
    return s && d ? strncat(d, s , size) : d;
}

static inline char* Strtok (char* s, const char* tok)
{
    return tok ? strtok(s, tok) : NULL;
}

static inline int Strcmp(const char* p, const char* q)
{
    if(!p) {
        if(!q)
            return 0;
        else return -1;
    }
    else {
        if(!q)
            return 1;
        else return strcmp(p, q);
    }
}

static inline int Strncmp(const char* p, const char* q, unsigned size)
{
    if(!p) {
        if(!q)
            return 0;
        else return -1;
    }
    else {
        if(!q)
            return 1;
        else return strncmp(p, q, size);
    }
}

static inline int Strcasecmp(const char* p, const char* q)
{
    if(!p) {
	if(!q)
	    return 0;
	else return -1;
    }
    else {
	if(!q)
	    return 1;
	else 
	    return strcasecmp((char*)p, (char*)q);
    }
}

static inline int Strncasecmp(const char *p, const char *q, unsigned size)
{
    if(!p) {
	if(!q)
	    return 0;
	else return -1;
    }
    else {
	if(!q)
	    return 1;
	else 
	    return strncasecmp((char*)p, (char*)q, size);
    }
}

static inline char* Strstr (const char* str, const char* sub)
{
    return str && sub ? strstr(str, sub) : 0;
}

static inline char* Strnchr (const char* str, int c, unsigned n)
{
    return (str && c && n > 0) ?
	(({for( ; (str = strchr(str, c)) && str && --n; str++);}), (char *)str)
      : NULL;
}

static inline char* Strchr (const char* str, int c)
{
    return str ? strchr(str, c) : NULL;
}

static inline char* Strrchr (const char* str, int c)
{
    return str ? strrchr(str, c) : NULL;
}

static inline char* Strpbrk (const char* str, const char* str2)
{
    return (str && str2) ? strpbrk(str, str2) : NULL;
}

static inline int Atoi(const char* str)
{
    return str ? atoi(str) : 0;
}

static inline long Atol(const char *str)
{
    return str ? atol(str) : 0;
}

#ifndef MAX
#define MAX(a, b) \
    ({typedef _ta = (a), _tb = (b);   \
	_ta _a = (a); _tb _b = (b);     \
	_a > _b ? _a : _b; })
#endif

#ifndef MIN
#define MIN(a, b) \
    ({typedef _ta = (a), _tb = (b);   \
	_ta _a = (a); _tb _b = (b);     \
	_a < _b ? _a : _b; })
#endif /* LIB_FOUNDATION_LIBRARY */

#endif /* __common_h__ */
