852 lines
16 KiB
C
852 lines
16 KiB
C
|
/*
|
||
|
PLIB - A Suite of Portable Game Libraries
|
||
|
Copyright (C) 1998,2002 Steve Baker
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public
|
||
|
License along with this library; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
||
|
For further information visit http://plib.sourceforge.net
|
||
|
|
||
|
$Id: ul.h 2131 2008-03-11 02:23:50Z sjbaker $
|
||
|
*/
|
||
|
|
||
|
//
|
||
|
// UL - utility library
|
||
|
//
|
||
|
// Contains:
|
||
|
// - necessary system includes
|
||
|
// - basic types
|
||
|
// - error message routines
|
||
|
// - high performance clocks
|
||
|
// - ulList
|
||
|
// - ulLinkedList
|
||
|
// - more to come (endian support, version ID)
|
||
|
//
|
||
|
|
||
|
#ifndef _INCLUDED_UL_H_
|
||
|
#define _INCLUDED_UL_H_
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
/**********************\
|
||
|
* *
|
||
|
* Determine OS type *
|
||
|
* *
|
||
|
\**********************/
|
||
|
|
||
|
#if defined(__CYGWIN__)
|
||
|
|
||
|
#define UL_WIN32 1
|
||
|
#define UL_CYGWIN 1 /* Windoze AND Cygwin. */
|
||
|
|
||
|
#elif defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER)
|
||
|
|
||
|
#define UL_WIN32 1
|
||
|
#define UL_MSVC 1 /* Windoze AND MSVC. */
|
||
|
|
||
|
#elif defined(__BEOS__)
|
||
|
|
||
|
#define UL_BEOS 1
|
||
|
|
||
|
#elif defined( macintosh )
|
||
|
|
||
|
#define UL_MACINTOSH 1
|
||
|
|
||
|
#elif defined(__APPLE__)
|
||
|
|
||
|
#define UL_MAC_OSX 1
|
||
|
|
||
|
#elif defined(__linux__)
|
||
|
|
||
|
#define UL_LINUX 1
|
||
|
|
||
|
#elif defined(__sgi)
|
||
|
|
||
|
#define UL_IRIX 1
|
||
|
|
||
|
#elif defined(_AIX)
|
||
|
|
||
|
#define UL_AIX 1
|
||
|
|
||
|
#elif defined(SOLARIS) || defined(sun)
|
||
|
|
||
|
#define UL_SOLARIS 1
|
||
|
|
||
|
#elif defined(hpux)
|
||
|
|
||
|
#define UL_HPUX 1
|
||
|
|
||
|
#elif (defined(__unix__) || defined(unix)) && !defined(USG)
|
||
|
|
||
|
#define UL_BSD 1
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*
|
||
|
Add specialised includes/defines...
|
||
|
*/
|
||
|
|
||
|
#ifdef UL_WIN32
|
||
|
#define WIN32_LEAN_AND_MEAN
|
||
|
#include <windows.h>
|
||
|
#include <mmsystem.h>
|
||
|
#include <regstr.h>
|
||
|
#define UL_WGL 1
|
||
|
#endif
|
||
|
|
||
|
#ifdef UL_CYGWIN
|
||
|
#include <unistd.h>
|
||
|
#define UL_WGL 1
|
||
|
#endif
|
||
|
|
||
|
#ifdef UL_BEOS
|
||
|
#include <be/kernel/image.h>
|
||
|
#define UL_GLX 1
|
||
|
#endif
|
||
|
|
||
|
#ifdef UL_MACINTOSH
|
||
|
#include <CodeFragments.h>
|
||
|
#include <unistd.h>
|
||
|
#define UL_AGL 1
|
||
|
#endif
|
||
|
|
||
|
#ifdef UL_MAC_OSX
|
||
|
#include <unistd.h>
|
||
|
#define UL_CGL 1
|
||
|
#endif
|
||
|
|
||
|
#if defined(UL_LINUX) || defined(UL_BSD) || defined(UL_IRIX) || defined(UL_SOLARIS) || defined(UL_AIX)
|
||
|
#include <unistd.h>
|
||
|
#include <dlfcn.h>
|
||
|
#include <fcntl.h>
|
||
|
#define UL_GLX 1
|
||
|
#endif
|
||
|
|
||
|
#if defined(UL_BSD)
|
||
|
#include <sys/param.h>
|
||
|
#define UL_GLX 1
|
||
|
#endif
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <limits.h>
|
||
|
#include <math.h>
|
||
|
#include <float.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
/* PLIB version macros */
|
||
|
|
||
|
#define PLIB_MAJOR_VERSION 1
|
||
|
#define PLIB_MINOR_VERSION 8
|
||
|
#define PLIB_TINY_VERSION 5
|
||
|
|
||
|
#define PLIB_VERSION (PLIB_MAJOR_VERSION*100 \
|
||
|
+PLIB_MINOR_VERSION*10 \
|
||
|
+PLIB_TINY_VERSION)
|
||
|
|
||
|
/* SGI machines seem to suffer from a lack of FLT_EPSILON so... */
|
||
|
|
||
|
#ifndef FLT_EPSILON
|
||
|
#define FLT_EPSILON 1.19209290e-07f
|
||
|
#endif
|
||
|
|
||
|
#ifndef DBL_EPSILON
|
||
|
#define DBL_EPSILON 1.19209290e-07f
|
||
|
#endif
|
||
|
|
||
|
#ifndef TRUE
|
||
|
#define TRUE 1
|
||
|
#define FALSE 0
|
||
|
#endif
|
||
|
|
||
|
/* SUNWspro 4.2 and earlier need bool to be defined */
|
||
|
|
||
|
#if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
|
||
|
typedef int bool ;
|
||
|
const int true = 1 ;
|
||
|
const int false = 0 ;
|
||
|
#endif
|
||
|
|
||
|
/* Let's define our own "min" and "max" so that different operating systems
|
||
|
* don't complain
|
||
|
*/
|
||
|
#define ulMax(a,b) ((a)>(b)?(a):(b))
|
||
|
#define ulMin(a,b) ((a)<(b)?(a):(b))
|
||
|
|
||
|
|
||
|
/*
|
||
|
Basic Types
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*
|
||
|
High precision clocks.
|
||
|
*/
|
||
|
|
||
|
class ulClock
|
||
|
{
|
||
|
double start ;
|
||
|
double now ;
|
||
|
double delta ;
|
||
|
double last_time ;
|
||
|
double max_delta ;
|
||
|
|
||
|
#ifdef UL_WIN32
|
||
|
static double res ;
|
||
|
static int perf_timer ;
|
||
|
void initPerformanceTimer () ;
|
||
|
#endif
|
||
|
|
||
|
double getRawTime () const ;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulClock () { reset () ; }
|
||
|
|
||
|
void reset ()
|
||
|
{
|
||
|
#ifdef UL_WIN32
|
||
|
initPerformanceTimer () ;
|
||
|
#endif
|
||
|
start = getRawTime () ;
|
||
|
now = 0.0 ;
|
||
|
max_delta = 0.2 ;
|
||
|
delta = 0.0000001 ; /* Faked so stoopid programs won't div0 */
|
||
|
last_time = 0.0 ;
|
||
|
}
|
||
|
|
||
|
void setMaxDelta ( double maxDelta ) { max_delta = maxDelta ; }
|
||
|
double getMaxDelta () const { return max_delta ; }
|
||
|
void update () ;
|
||
|
double getAbsTime () const { return now ; }
|
||
|
double getDeltaTime () const { return delta ; }
|
||
|
double getFrameRate () const { return 1.0 / delta ; }
|
||
|
} ;
|
||
|
|
||
|
|
||
|
inline void ulSleep ( int seconds )
|
||
|
{
|
||
|
if ( seconds >= 0 )
|
||
|
{
|
||
|
#ifdef UL_WIN32
|
||
|
Sleep ( 1000 * seconds ) ;
|
||
|
#else
|
||
|
sleep ( seconds ) ;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
inline void ulMilliSecondSleep ( int milliseconds )
|
||
|
{
|
||
|
if ( milliseconds >= 0 )
|
||
|
{
|
||
|
#ifdef UL_WIN32
|
||
|
Sleep ( milliseconds ) ;
|
||
|
#else
|
||
|
usleep ( milliseconds * 1000 ) ;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
This is extern C to enable 'configure.in' to
|
||
|
find it with a C-coded probe.
|
||
|
*/
|
||
|
|
||
|
extern "C" void ulInit () ;
|
||
|
|
||
|
/*
|
||
|
Error handler.
|
||
|
*/
|
||
|
|
||
|
enum ulSeverity
|
||
|
{
|
||
|
UL_DEBUG, // Messages that can safely be ignored.
|
||
|
UL_WARNING, // Messages that are important.
|
||
|
UL_FATAL, // Errors that we cannot recover from.
|
||
|
UL_MAX_SEVERITY
|
||
|
} ;
|
||
|
|
||
|
|
||
|
typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ;
|
||
|
|
||
|
void ulSetError ( enum ulSeverity severity, const char *fmt, ... ) ;
|
||
|
char* ulGetError ( void ) ;
|
||
|
void ulClearError ( void ) ;
|
||
|
ulErrorCallback ulGetErrorCallback ( void ) ;
|
||
|
void ulSetErrorCallback ( ulErrorCallback cb ) ;
|
||
|
|
||
|
/*
|
||
|
Directory Reading
|
||
|
*/
|
||
|
|
||
|
#define UL_NAME_MAX 256
|
||
|
typedef struct _ulDir ulDir ;
|
||
|
struct ulDirEnt
|
||
|
{
|
||
|
char d_name [ UL_NAME_MAX+1 ];
|
||
|
bool d_isdir ;
|
||
|
} ;
|
||
|
|
||
|
int ulIsAbsolutePathName ( const char *pathname ) ;
|
||
|
char *ulGetCWD ( char *result, int maxlength ) ;
|
||
|
|
||
|
ulDir* ulOpenDir ( const char* dirname ) ;
|
||
|
ulDirEnt* ulReadDir ( ulDir* dir ) ;
|
||
|
void ulCloseDir ( ulDir* dir ) ;
|
||
|
|
||
|
// file handling
|
||
|
|
||
|
char* ulMakePath( char* path, const char* dir, const char* fname );
|
||
|
|
||
|
bool ulFileExists ( const char *fileName ) ;
|
||
|
|
||
|
void ulFindFile( char *filenameOutput, const char *path,
|
||
|
const char * tfnameInput, const char *sAPOM ) ;
|
||
|
|
||
|
|
||
|
/*
|
||
|
Endian handling
|
||
|
*/
|
||
|
|
||
|
static const int _ulEndianTest = 1;
|
||
|
#define ulIsLittleEndian (*((char *) &_ulEndianTest ) != 0)
|
||
|
#define ulIsBigEndian (*((char *) &_ulEndianTest ) == 0)
|
||
|
|
||
|
inline void ulEndianSwap(unsigned int *x)
|
||
|
{
|
||
|
*x = (( *x >> 24 ) & 0x000000FF ) |
|
||
|
(( *x >> 8 ) & 0x0000FF00 ) |
|
||
|
(( *x << 8 ) & 0x00FF0000 ) |
|
||
|
(( *x << 24 ) & 0xFF000000 ) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
inline void ulEndianSwap(unsigned short *x)
|
||
|
{
|
||
|
*x = (( *x >> 8 ) & 0x00FF ) |
|
||
|
(( *x << 8 ) & 0xFF00 ) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
inline void ulEndianSwap(float *x) { ulEndianSwap((unsigned int *)x); }
|
||
|
inline void ulEndianSwap(int *x) { ulEndianSwap((unsigned int *)x); }
|
||
|
inline void ulEndianSwap(short *x) { ulEndianSwap((unsigned short *)x); }
|
||
|
|
||
|
|
||
|
inline unsigned short ulEndianLittle16(unsigned short x) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline unsigned int ulEndianLittle32(unsigned int x) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline float ulEndianLittleFloat(float x) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianLittleArray16(unsigned short *x, int length) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianLittleArray32(unsigned int *x, int length) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianLittleArrayFloat(float *x, int length) {
|
||
|
if (ulIsLittleEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianBigArray16(unsigned short *x, int length) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianBigArray32(unsigned int *x, int length) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void ulEndianBigArrayFloat(float *x, int length) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return;
|
||
|
} else {
|
||
|
for (int i = 0; i < length; i++) {
|
||
|
ulEndianSwap(x++);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline unsigned short ulEndianBig16(unsigned short x) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline unsigned int ulEndianBig32(unsigned int x) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline float ulEndianBigFloat(float x) {
|
||
|
if (ulIsBigEndian) {
|
||
|
return x;
|
||
|
} else {
|
||
|
ulEndianSwap(&x);
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline unsigned short ulEndianReadLittle16(FILE *f) {
|
||
|
unsigned short x;
|
||
|
fread(&x, 2, 1, f);
|
||
|
return ulEndianLittle16(x);
|
||
|
}
|
||
|
|
||
|
inline unsigned int ulEndianReadLittle32(FILE *f) {
|
||
|
unsigned int x;
|
||
|
fread(&x, 4, 1, f);
|
||
|
return ulEndianLittle32(x);
|
||
|
}
|
||
|
|
||
|
inline float ulEndianReadLittleFloat(FILE *f) {
|
||
|
float x;
|
||
|
fread(&x, 4, 1, f);
|
||
|
return ulEndianLittleFloat(x);
|
||
|
}
|
||
|
|
||
|
inline unsigned short ulEndianReadBig16(FILE *f) {
|
||
|
unsigned short x;
|
||
|
fread(&x, 2, 1, f);
|
||
|
return ulEndianBig16(x);
|
||
|
}
|
||
|
|
||
|
inline unsigned int ulEndianReadBig32(FILE *f) {
|
||
|
unsigned int x;
|
||
|
fread(&x, 4, 1, f);
|
||
|
return ulEndianBig32(x);
|
||
|
}
|
||
|
|
||
|
inline float ulEndianReadBigFloat(FILE *f) {
|
||
|
float x;
|
||
|
fread(&x, 4, 1, f);
|
||
|
return ulEndianBigFloat(x);
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteLittle16(FILE *f, unsigned short x) {
|
||
|
x = ulEndianLittle16(x);
|
||
|
return fwrite( &x, 2, 1, f );
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteLittle32(FILE *f, unsigned int x) {
|
||
|
x = ulEndianLittle32(x);
|
||
|
return fwrite( &x, 4, 1, f );
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteLittleFloat(FILE *f, float x) {
|
||
|
x = ulEndianLittleFloat(x);
|
||
|
return fwrite( &x, 4, 1, f );
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteBig16(FILE *f, unsigned short x) {
|
||
|
x = ulEndianBig16(x);
|
||
|
return fwrite( &x, 2, 1, f );
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteBig32(FILE *f, unsigned int x) {
|
||
|
x = ulEndianBig32(x);
|
||
|
return fwrite( &x, 4, 1, f );
|
||
|
}
|
||
|
|
||
|
inline size_t ulEndianWriteBigFloat(FILE *f, float x) {
|
||
|
x = ulEndianBigFloat(x);
|
||
|
return fwrite( &x, 4, 1, f );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
Windoze/BEOS code based on contribution from Sean L. Palmer
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifdef UL_WIN32
|
||
|
|
||
|
class ulDynamicLibrary
|
||
|
{
|
||
|
HMODULE handle ;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulDynamicLibrary ( const char *libname )
|
||
|
{
|
||
|
char dllname[1024];
|
||
|
strcpy ( dllname, libname ) ;
|
||
|
strcat ( dllname, ".dll" ) ;
|
||
|
handle = (HMODULE) LoadLibrary ( dllname ) ;
|
||
|
}
|
||
|
|
||
|
void *getFuncAddress ( const char *funcname )
|
||
|
{
|
||
|
return (void *) GetProcAddress ( handle, funcname ) ; //lint !e611
|
||
|
}
|
||
|
|
||
|
~ulDynamicLibrary ()
|
||
|
{
|
||
|
if ( handle != NULL )
|
||
|
FreeLibrary ( handle ) ;
|
||
|
}
|
||
|
} ;
|
||
|
|
||
|
#elif defined (UL_MACINTOSH)
|
||
|
|
||
|
class ulDynamicLibrary
|
||
|
{
|
||
|
CFragConnectionID connection;
|
||
|
OSStatus error;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulDynamicLibrary ( const char *libname )
|
||
|
{
|
||
|
Str63 pstr;
|
||
|
int sz;
|
||
|
|
||
|
sz = strlen (libname);
|
||
|
|
||
|
if (sz < 64) {
|
||
|
|
||
|
pstr[0] = sz;
|
||
|
memcpy (pstr+1, libname, sz);
|
||
|
|
||
|
error = GetSharedLibrary (pstr, kPowerPCCFragArch, kReferenceCFrag,
|
||
|
&connection, NULL, NULL);
|
||
|
}
|
||
|
else
|
||
|
error = 1;
|
||
|
}
|
||
|
|
||
|
~ulDynamicLibrary ()
|
||
|
{
|
||
|
if ( ! error )
|
||
|
CloseConnection (&connection);
|
||
|
}
|
||
|
|
||
|
void* getFuncAddress ( const char *funcname )
|
||
|
{
|
||
|
if ( ! error ) {
|
||
|
|
||
|
char* addr;
|
||
|
Str255 sym;
|
||
|
int sz;
|
||
|
|
||
|
sz = strlen (funcname);
|
||
|
if (sz < 256) {
|
||
|
|
||
|
sym[0] = sz;
|
||
|
memcpy (sym+1, funcname, sz);
|
||
|
|
||
|
error = FindSymbol (connection, sym, &addr, 0);
|
||
|
if ( ! error )
|
||
|
return addr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#elif defined (UL_MAC_OSX)
|
||
|
|
||
|
|
||
|
class ulDynamicLibrary
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulDynamicLibrary ( const char *libname )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
~ulDynamicLibrary ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void* getFuncAddress ( const char *funcname )
|
||
|
{
|
||
|
ulSetError ( UL_WARNING, "ulDynamicLibrary unsuppored on Mac OS X" );
|
||
|
return NULL;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#elif defined (__BEOS__)
|
||
|
|
||
|
class ulDynamicLibrary
|
||
|
{
|
||
|
image_id *handle ;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulDynamicLibrary ( const char *libname )
|
||
|
{
|
||
|
char addonname[1024] ;
|
||
|
strcpy ( addonname, libname ) ;
|
||
|
strcat ( addonname, ".so" ) ;
|
||
|
handle = new image_id ;
|
||
|
|
||
|
*handle = load_add_on ( addonname ) ;
|
||
|
|
||
|
if ( *handle == B_ERROR )
|
||
|
{
|
||
|
delete handle ;
|
||
|
handle = NULL ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void *getFuncAddress ( const char *funcname )
|
||
|
{
|
||
|
void *sym = NULL ;
|
||
|
|
||
|
if ( handle &&
|
||
|
get_image_symbol ( handle, "funcname",
|
||
|
B_SYMBOL_TYPE_TEXT, &sym ) == B_NO_ERROR )
|
||
|
return sym ;
|
||
|
|
||
|
return NULL ;
|
||
|
}
|
||
|
|
||
|
~ulDynamicLibrary ()
|
||
|
{
|
||
|
if ( handle != NULL )
|
||
|
unload_add_on ( handle ) ;
|
||
|
|
||
|
delete handle ;
|
||
|
}
|
||
|
} ;
|
||
|
|
||
|
# else
|
||
|
|
||
|
/*
|
||
|
Linux/UNIX
|
||
|
*/
|
||
|
|
||
|
class ulDynamicLibrary
|
||
|
{
|
||
|
void *handle ;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulDynamicLibrary ( const char *libname )
|
||
|
{
|
||
|
char dsoname [ 1024 ] ;
|
||
|
strcpy ( dsoname, libname ) ;
|
||
|
strcat ( dsoname, ".so" ) ;
|
||
|
handle = (void *) dlopen ( dsoname, RTLD_NOW | RTLD_GLOBAL ) ;
|
||
|
|
||
|
if ( handle == NULL )
|
||
|
ulSetError ( UL_WARNING, "ulDynamicLibrary: %s\n", dlerror() ) ;
|
||
|
}
|
||
|
|
||
|
void *getFuncAddress ( const char *funcname )
|
||
|
{
|
||
|
return (handle==NULL) ? NULL : dlsym ( handle, funcname ) ;
|
||
|
}
|
||
|
|
||
|
~ulDynamicLibrary ()
|
||
|
{
|
||
|
if ( handle != NULL )
|
||
|
dlclose ( handle ) ;
|
||
|
}
|
||
|
} ;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
class ulList
|
||
|
{
|
||
|
protected:
|
||
|
unsigned int total ; /* The total number of entities in the list */
|
||
|
unsigned int limit ; /* The current limit on number of entities */
|
||
|
unsigned int next ; /* The next entity when we are doing getNext ops */
|
||
|
|
||
|
void **entity_list ; /* The list. */
|
||
|
|
||
|
void sizeChk (void) ;
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulList ( int init_max = 1 ) ;
|
||
|
virtual ~ulList (void) ;
|
||
|
|
||
|
void *getEntity ( unsigned int n )
|
||
|
{
|
||
|
next = n + 1 ;
|
||
|
return ( n >= total ) ? (void *) NULL : entity_list [ n ] ;
|
||
|
}
|
||
|
|
||
|
virtual void addEntity ( void *entity ) ;
|
||
|
virtual void addEntityBefore ( int n, void *entity ) ;
|
||
|
virtual void removeEntity ( unsigned int n ) ;
|
||
|
|
||
|
void removeAllEntities () ;
|
||
|
|
||
|
void removeEntity ( void *entity )
|
||
|
{
|
||
|
removeEntity ( searchForEntity ( entity ) ) ;
|
||
|
}
|
||
|
|
||
|
virtual void replaceEntity ( unsigned int n, void *new_entity ) ;
|
||
|
|
||
|
void replaceEntity ( void *old_entity, void *new_entity )
|
||
|
{
|
||
|
replaceEntity ( searchForEntity ( old_entity ), new_entity ) ;
|
||
|
}
|
||
|
|
||
|
void *getNextEntity (void) { return getEntity ( next ) ; }
|
||
|
|
||
|
int getNumEntities (void) const { return total ; }
|
||
|
int searchForEntity ( void *entity ) const ;
|
||
|
} ;
|
||
|
|
||
|
|
||
|
typedef bool (*ulIterateFunc)( const void *data, void *user_data ) ;
|
||
|
typedef int (*ulCompareFunc)( const void *data1, const void *data2 ) ;
|
||
|
|
||
|
/*
|
||
|
Linked list.
|
||
|
*/
|
||
|
|
||
|
class ulListNode ;
|
||
|
|
||
|
class ulLinkedList
|
||
|
{
|
||
|
protected:
|
||
|
|
||
|
ulListNode *head ;
|
||
|
ulListNode *tail ;
|
||
|
|
||
|
int nnodes ;
|
||
|
bool sorted ;
|
||
|
|
||
|
void unlinkNode ( ulListNode *prev, ulListNode *node ) ;
|
||
|
|
||
|
bool isValidPosition ( int pos ) const
|
||
|
{
|
||
|
if ( ( pos < 0 ) || ( pos >= nnodes ) )
|
||
|
{
|
||
|
ulSetError ( UL_WARNING, "ulLinkedList: Invalid 'pos' %u", pos ) ;
|
||
|
return false ;
|
||
|
}
|
||
|
return true ;
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
|
||
|
ulLinkedList ()
|
||
|
{
|
||
|
head = tail = NULL ;
|
||
|
nnodes = 0 ;
|
||
|
sorted = true ;
|
||
|
}
|
||
|
|
||
|
~ulLinkedList () { empty () ; }
|
||
|
|
||
|
int getNumNodes ( void ) const { return nnodes ; }
|
||
|
bool isSorted ( void ) const { return sorted ; }
|
||
|
|
||
|
int getNodePosition ( void *data ) const ;
|
||
|
|
||
|
void insertNode ( void *data, int pos ) ;
|
||
|
void prependNode ( void *data ) { insertNode ( data, 0 ) ; }
|
||
|
void appendNode ( void *data ) ;
|
||
|
|
||
|
int insertSorted ( void *data, ulCompareFunc comparefn ) ;
|
||
|
|
||
|
void removeNode ( void *data ) ;
|
||
|
void * removeNode ( int pos ) ;
|
||
|
|
||
|
void * getNodeData ( int pos ) const ;
|
||
|
|
||
|
void * forEach ( ulIterateFunc fn, void *user_data = NULL ) const ;
|
||
|
|
||
|
void empty ( ulIterateFunc destroyfn = NULL, void *user_data = NULL ) ;
|
||
|
} ;
|
||
|
|
||
|
|
||
|
extern char *ulStrDup ( const char *s ) ;
|
||
|
extern int ulStrNEqual ( const char *s1, const char *s2, int len );
|
||
|
extern int ulStrEqual ( const char *s1, const char *s2 );
|
||
|
|
||
|
//lint -restore
|
||
|
|
||
|
#endif
|
||
|
|