diff dwcompat.c @ 1594:6baf177f335c

Rename compat.c/h dwcompat.c/h and configure option to --with-dwcompat. There are several other projects that include compat.c and compat.h... To avoid conflicts make sure the header and source files match the library.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 23 Feb 2012 12:44:15 +0000
parents compat.c@007ed833ac79
children 71e0a3ad07f7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwcompat.c	Thu Feb 23 12:44:15 2012 +0000
@@ -0,0 +1,833 @@
+/* $Id$ */
+
+#include "dwcompat.h"
+#include "dw.h"
+#if defined(__OS2__) || defined(__WIN32__)
+#include <share.h>
+#endif
+
+#if defined(__UNIX__) || defined(__MAC__)
+#if defined(__FreeBSD__) || defined(__MAC__)
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#elif defined(__sun__)
+#include <sys/mnttab.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/statvfs.h>
+#else
+#include <mntent.h>
+#include <sys/vfs.h>
+#endif
+#endif
+#include <time.h>
+#include <errno.h>
+
+#if defined(__UNIX__) || defined(__MAC__)
+void msleep(long period)
+{
+#ifdef __sun__
+	/* usleep() isn't threadsafe on Solaris */
+	struct timespec req;
+
+	req.tv_sec = 0;
+	if(period >= 1000)
+	{
+		req.tv_sec = (int)(period / 1000);
+		period -= (req.tv_sec * 1000);
+	}
+	req.tv_nsec = period * 10000000;
+	
+	nanosleep(&req, NULL);
+#else
+	usleep((int)(period * 1000));
+#endif
+}
+#endif
+
+int API makedir(char *path)
+{
+#if defined(__IBMC__) || defined(__WATCOMC__) || (defined(__WIN32__) && !defined(__CYGWIN32__))
+	return mkdir(path);
+#else
+	return mkdir(path,S_IRWXU);
+#endif
+}
+
+char * API vargs(char *buf, int len, char *format, ...)
+{
+	va_list args;
+
+	va_start(args, format);
+#ifdef HAVE_VSNPRINTF
+	vsnprintf(buf, len, format, args);
+#else
+	len = len;
+	vsprintf(buf, format, args);
+#endif
+	va_end(args);
+
+	return buf;
+}
+
+long double API drivefree(int drive)
+{
+#if defined(__EMX__) || defined(__OS2__)
+	ULONG   aulFSInfoBuf[40] = {0};
+	APIRET  rc               = NO_ERROR;
+
+	DosError(FERR_DISABLEHARDERR);
+	rc = DosQueryFSInfo(drive,
+						FSIL_ALLOC,
+						(PVOID)aulFSInfoBuf,
+						sizeof(aulFSInfoBuf));
+
+	DosError(FERR_ENABLEHARDERR);
+	if (rc != NO_ERROR)
+		return 0;
+
+	return (long double)((double)aulFSInfoBuf[3] * (double)aulFSInfoBuf[1] * (double)aulFSInfoBuf[4]);
+#elif defined(__WIN32__) || defined(WINNT)
+	char buffer[10] = "C:\\";
+	DWORD spc, bps, fc, tc;
+
+	buffer[0] = drive + 'A' - 1;
+
+	if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0)
+		return 0;
+
+	return (long double)((double)spc*(double)bps*(double)fc);
+#elif defined(__FreeBSD__) || defined(__MAC__)
+	struct statfs *fsp;
+	int entries, index = 1;
+
+	entries = getmntinfo (&fsp, MNT_NOWAIT);
+
+	for (; entries-- > 0; fsp++)
+	{
+		if(index == drive)
+			return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail);
+		index++;
+	}
+	return 0;
+#elif defined(__sun__)
+	FILE *fp = fopen("/etc/mnttab", "r");
+	struct mnttab mnt;
+	struct statvfs sfs;
+	int index = 1;
+
+	if(fp)
+	{
+		while((getmntent(fp, &mnt) == 0))
+		{
+			if(index == drive)
+			{
+				long double size = 0;
+
+				if(mnt.mnt_mountp)
+				{
+					if(!statvfs(mnt.mnt_mountp, &sfs))
+					{
+						size = (long double)((double)sfs.f_bsize * (double)sfs.f_bavail);
+					}
+				}
+				fclose(fp);
+				return size;
+			}
+			index++;          
+		}
+		fclose(fp);
+	}
+	return 0;
+#else
+	FILE *fp = setmntent(MOUNTED, "r");
+	struct mntent mnt;
+	struct statfs sfs;
+	char buffer[1024];
+	int index = 1;
+
+	if(fp)
+	{
+		while(getmntent_r(fp, &mnt, buffer, sizeof(buffer)))
+		{
+			if(index == drive)
+			{
+				long double size = 0;
+
+				if(mnt.mnt_dir)
+				{
+					if(!statfs(mnt.mnt_dir, &sfs))
+					{
+						size = (long double)((double)sfs.f_bsize * (double)sfs.f_bavail);
+					}
+				}
+				endmntent(fp);
+				return size;
+			}
+			index++;          
+		}
+		endmntent(fp);
+	}
+	return 0;
+#endif
+}
+
+long double API drivesize(int drive)
+{
+#if defined(__EMX__) || defined(__OS2__)
+	ULONG   aulFSInfoBuf[40] = {0};
+	APIRET  rc               = NO_ERROR;
+
+	DosError(FERR_DISABLEHARDERR);
+	rc = DosQueryFSInfo(drive,
+						FSIL_ALLOC,
+						(PVOID)aulFSInfoBuf,
+						sizeof(aulFSInfoBuf));
+
+	DosError(FERR_ENABLEHARDERR);
+	if (rc != NO_ERROR)
+		return 0;
+
+	return (long double)((double)aulFSInfoBuf[2] * (double)aulFSInfoBuf[1] * (double)aulFSInfoBuf[4]);
+#elif defined(__WIN32__) || defined(WINNT)
+	char buffer[10] = "C:\\";
+	DWORD spc, bps, fc, tc;
+
+	buffer[0] = drive + 'A' - 1;
+
+	if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0)
+		return 0;
+
+	return (long double)((double)spc*(double)bps*(double)tc);
+#elif defined(__FreeBSD__) || defined(__MAC__)
+	struct statfs *fsp;
+	int entries, index = 1;
+
+	entries = getmntinfo (&fsp, MNT_NOWAIT);
+
+	for (; entries-- > 0; fsp++)
+	{
+		if(index == drive)
+			return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks);
+		index++;
+	}
+	return 0;
+#elif defined(__sun__)
+	FILE *fp = fopen("/etc/mnttab", "r");
+	struct mnttab mnt;
+	struct statvfs sfs;
+	int index = 1;
+
+	if(fp)
+	{
+		while(getmntent(fp, &mnt) == 0)
+		{
+			if(index == drive)
+			{
+				long double size = 0;
+
+				if(mnt.mnt_mountp)
+				{
+					if(!statvfs(mnt.mnt_mountp, &sfs))
+					{
+						size = (long double)((double)sfs.f_bsize * (double)sfs.f_blocks);
+					}
+				}
+				fclose(fp);
+				return size;
+			}
+			index++;          
+		}
+		fclose(fp);
+	}
+	return 0;
+#else
+	FILE *fp = setmntent(MOUNTED, "r");
+	struct mntent mnt;
+	char buffer[1024];
+	struct statfs sfs;
+	int index = 1;
+
+	if(fp)
+	{
+		while(getmntent_r(fp, &mnt, buffer, sizeof(buffer)))
+		{
+			if(index == drive)
+			{
+				long double size = 0;
+
+				if(mnt.mnt_dir)
+				{
+					if(!statfs(mnt.mnt_dir, &sfs))
+					{
+						size = (long double)((double)sfs.f_bsize * (double)sfs.f_blocks);
+					}
+				}
+				endmntent(fp);
+				return size;
+			}
+			index++;          
+		}
+		endmntent(fp);
+	}
+	return 0;
+#endif
+}
+
+int API isdrive(int drive)
+{
+#if defined(__EMX__) || defined(__OS2__)
+	APIRET  rc               = NO_ERROR;
+	FSINFO  volinfo;
+
+	DosError(FERR_DISABLEHARDERR);
+	rc = DosQueryFSInfo(drive,
+			    FSIL_VOLSER,
+			    (PVOID)&volinfo,
+			    sizeof(FSINFO));
+
+	DosError(FERR_ENABLEHARDERR);
+	if (rc == NO_ERROR)
+		return 1;
+
+#elif defined(__WIN32__) || defined(WINNT)
+	char buffer[10] = "C:\\", volname[100];
+	DWORD spc, bps, fc;
+
+	buffer[0] = drive + 'A' - 1;
+
+	if(GetVolumeInformation(buffer, volname, 100, &spc, &bps, &fc, NULL, 0) != 0)
+		return 1;
+#elif defined(__FreeBSD__) || defined(__MAC__)
+	struct statfs *fsp;
+	int entries, index = 1;
+
+	entries = getmntinfo (&fsp, MNT_NOWAIT);
+
+	for (; entries-- > 0; fsp++)
+	{
+		if(index == drive && fsp->f_blocks)
+			return 1;
+		index++;
+	}
+	return 0;
+#elif defined(__sun__)
+	FILE *fp = fopen("/etc/mnttab", "r");
+	struct mnttab mnt;
+	struct statvfs sfs;
+	int index = 1;
+
+	if(fp)
+	{
+		while(getmntent(fp, &mnt) == 0)
+		{
+			if(index == drive)
+			{
+				fclose(fp);
+				if(mnt.mnt_mountp)
+				{
+					if(!statvfs(mnt.mnt_mountp, &sfs) && sfs.f_blocks)
+						return 1;
+				}
+				return 0;
+			}
+			index++;          
+		}
+		fclose(fp);
+	}
+#else
+	FILE *fp = setmntent(MOUNTED, "r");
+	struct mntent mnt;
+	char buffer[1024];
+	struct statfs sfs;
+	int index = 1;
+
+	if(fp)
+	{
+		while(getmntent_r(fp, &mnt, buffer, sizeof(buffer)))
+		{
+			if(index == drive)
+			{
+				endmntent(fp);
+				if(mnt.mnt_dir)
+				{
+					if(!statfs(mnt.mnt_dir, &sfs) && sfs.f_blocks)
+					{
+						return 1;
+					}
+				}
+				return 0;
+			}
+			index++;          
+		}
+		endmntent(fp);
+	}
+#endif
+	return 0;
+}
+
+void API getfsname(int drive, char *buf, int len)
+{
+#if defined(__UNIX__) || defined(__MAC__) 
+#if defined(__FreeBSD__) || defined(__MAC__)
+	struct statfs *fsp;
+	int entries, index = 1;
+
+	strncpy(buf, "Unknown", len);
+
+	entries = getmntinfo (&fsp, MNT_NOWAIT);
+
+	for (; entries-- > 0; fsp++)
+	{
+		if(index == drive)
+			strncpy(buf, fsp->f_mntonname, len);
+		index++;
+	}
+#elif defined(__sun__)
+	FILE *fp = fopen("/etc/mnttab", "r");
+	struct mnttab mnt;
+	int index = 1;
+
+	strncpy(buf, "Unknown", len);
+
+	if(fp)
+	{
+		while(getmntent(fp, &mnt) == 0)
+		{
+			if(index == drive && mnt.mnt_mountp)
+				strncpy(buf, mnt.mnt_mountp, len);
+			index++;          
+		}
+		fclose(fp);
+	}
+#else
+	FILE *fp = setmntent(MOUNTED, "r");
+	struct mntent mnt;
+	char buffer[1024];
+	int index = 1;
+
+	strncpy(buf, "Unknown", len);
+
+	if(fp)
+	{
+		while(getmntent_r(fp, &mnt, buffer, sizeof(buffer)))
+		{
+			if(index == drive && mnt.mnt_dir)
+				strncpy(buf, mnt.mnt_dir, len);
+			index++;          
+		}
+		endmntent(fp);
+	}
+#endif
+#elif defined(__OS2__)
+	/* No snprintf() on OS/2 ??? */
+	len = len;
+	sprintf(buf, "Drive %c",  (char)drive + 'A' - 1);
+#else
+	_snprintf(buf, len, "Drive %c",  (char)drive + 'A' - 1);
+#endif
+}
+
+void API setfileinfo(char *filename, char *url, char *logfile)
+{
+	time_t		ltime;
+	struct tm	*tm;
+    char buffer[200], timebuf[200];
+#ifdef __OS2__
+	const unsigned fea2listsize = 6000;
+	char *pData;
+	EAOP2 eaop2;
+	PFEA2 pFEA2;
+#else
+	FILE *urlfile;
+#endif
+
+	ltime = time(NULL);
+
+	tm = localtime(&ltime);
+
+	strftime(timebuf, 200, "%c", tm);
+
+	sprintf(buffer, "%s %s", url, timebuf);
+
+#ifdef __OS2__
+	logfile = logfile;
+	eaop2.fpGEA2List = 0;
+	eaop2.fpFEA2List = (PFEA2LIST)malloc(fea2listsize);
+	pFEA2 = &eaop2.fpFEA2List->list[0];
+
+	pFEA2->fEA = 0;
+    /* .COMMENTS is 9 characters long */
+	pFEA2->cbName = 9;
+
+	/* space for the type and length field. */
+	pFEA2->cbValue = strlen(buffer)+2*sizeof(USHORT);
+
+	strcpy(pFEA2->szName, ".COMMENTS");
+	pData = pFEA2->szName+pFEA2->cbName+1;
+	/* data begins at first byte after the name */
+
+	*(USHORT*)pData = EAT_ASCII;             /* type */
+	*((USHORT*)pData+1) = strlen(buffer);  /* length */
+	strcpy(pData+2*sizeof(USHORT), buffer);/* content */
+
+	pFEA2->oNextEntryOffset = 0;
+
+	eaop2.fpFEA2List->cbList = ((PCHAR)pData+2*sizeof(USHORT)+
+									 pFEA2->cbValue)-((PCHAR)eaop2.fpFEA2List);
+
+	DosSetPathInfo((PSZ)filename,
+						FIL_QUERYEASIZE,
+						&eaop2,
+						sizeof(eaop2),
+						0);
+
+	free((void *)eaop2.fpFEA2List);
+#else
+
+	if((urlfile = fopen(logfile, "a"))!=NULL)
+	{
+		fprintf(urlfile, "%s\n", buffer);
+		fclose(urlfile);
+	}
+#endif
+}
+
+#if defined(__OS2__) || defined(__WIN32__)
+typedef struct _fsinfo {
+	FILE *fp;
+	int fd;
+} FSInfo;
+
+FSInfo *FSIRoot = NULL;
+
+#define FSI_MAX 100
+#endif
+
+/* Sharable fopen() and fclose() calls. */
+FILE * API fsopen(char *path, char *modes)
+{
+#if (defined(__OS2__) && !defined(__WATCOMC__)) || defined(__WIN32__)
+	int z;
+
+	if(!FSIRoot)
+		FSIRoot = calloc(sizeof(struct _fsinfo), FSI_MAX);
+
+	for(z=0;z<FSI_MAX;z++)
+	{
+		if(FSIRoot[z].fd < 1)
+		{
+			int s, sopenmode = 0, wrmode = 0;
+
+			/* Check the flags passed */
+			for(s=0;s<3;s++)
+			{
+				if(modes[s] == 'b')
+					sopenmode |= O_BINARY;
+				if(modes[s] == 'r')
+					wrmode |= O_RDONLY;
+				if(modes[s] == 'w')
+					wrmode |= O_WRONLY;
+				if(modes[s] == 'a')
+					sopenmode |= O_APPEND;
+				if(modes[s] == 't')
+					sopenmode |= O_TEXT;
+			}
+
+			/* Check the read/write request */
+			if((wrmode & O_RDONLY) && (wrmode & O_WRONLY))
+				sopenmode |= O_RDWR;
+			else
+				sopenmode |= wrmode;
+			FSIRoot[z].fd = _sopen(path, sopenmode, SH_DENYNO, S_IREAD|S_IWRITE);
+			if(FSIRoot[z].fd > 0)
+			{
+				FSIRoot[z].fp = fdopen(FSIRoot[z].fd, modes);
+
+				return FSIRoot[z].fp;
+			}
+		}
+	}
+	return NULL;
+#else
+	return fopen(path, modes);
+#endif
+}
+
+int API fsclose(FILE *fp)
+{
+#if defined(__OS2__) || defined(__WIN32__)
+	if(FSIRoot)
+	{
+
+		int z;
+		for(z=0;z<FSI_MAX;z++)
+		{
+			if(fp == FSIRoot[z].fp)
+			{
+				int ret = fclose(fp);
+				close(FSIRoot[z].fd);
+				FSIRoot[z].fd = 0;
+				FSIRoot[z].fp = NULL;
+				return ret;
+			}
+		}
+	}
+#endif
+	return fclose(fp);
+}
+
+char * API fsgets(char *str, int size, FILE *stream)
+{
+	return fgets(str, size, stream);
+}
+
+int API fsseek(FILE *stream, long offset, int whence)
+{
+	return fseek(stream, offset, whence);
+}
+
+void API nice_strformat(char *dest, long double val, int dec)
+{
+	char formatbuf[10];
+	char format = 0;
+	double printval;
+
+	/* 1024 ^ 3 = Gigabytes */
+	if(val >= 1073741824L)
+	{
+		printval = val/(1073741824L);
+		format = 'G';
+	}
+	/* 1024 ^ 2 = Megabytes */
+	else if(val >= 1048576)
+	{
+		printval = val/(1048576);
+		format = 'M';
+	}
+	/* 1024 = Kilobytes */
+	else if(val > 1024)
+	{
+		printval = val/1024;
+		format = 'K';
+	}
+	else
+		printval = val;
+
+	/* Generate the format string */
+	sprintf(formatbuf, "%%.%df%c", dec, format);
+	/* Create the pretty value */
+	sprintf(dest, formatbuf, printval);
+}
+
+/* Update the current working directory based on the
+ * path of the executable being executed.
+ */
+void API initdir(int argc, char *argv[])
+{
+	if(argc > 0)
+	{
+		char *tmpdir = strdup(argv[0]);
+		int z, len = (int)strlen(argv[0]);
+
+		for(z=len;z > -1;z--)
+		{
+			if(tmpdir[z] == '/')
+			{
+				tmpdir[z+1] = 0;
+				setpath(tmpdir);
+				free(tmpdir);
+				return;
+			}
+		}
+		free(tmpdir);
+	}
+}
+
+/*
+ * Sets	the current directory (and drive) information.
+ * Parameters:
+ *	 path: A buffer	containing the new path.
+ * Returns:
+ *	 -1 on error.
+ */
+int API setpath(char *path)
+{
+#if defined(__OS2__) || defined(__WIN32__)
+	if(strlen(path)	> 2)
+	{
+		if(path[1] == ':')
+		{
+			char drive = toupper(path[0]);
+			_chdrive((drive - 'A')+1);
+		}
+	}
+#endif
+	return chdir(path);
+}
+
+static int locale_number = -1, locale_count = 0;
+static char **locale_text = NULL;
+
+void _compat_free_locale(void)
+{
+	if(locale_text)
+	{
+		int z;
+
+		for(z=0;z<locale_count;z++)
+		{
+			if(locale_text[z])
+				free(locale_text[z]);
+		}
+		free(locale_text);
+		locale_text = NULL;
+	}
+}
+
+int _stripcrlf(char *buf)
+{
+	int z, len = (int)strlen(buf);
+
+	for(z=0;z<len;z++)
+	{
+		if(buf[z] == '\r' || buf[z] == '\n')
+		{
+			buf[z] = 0;
+			return 1;
+		}
+	}
+	return 1;
+}
+
+#ifdef __WIN32__
+#define LOCALE_CHARACTERS 62
+static char locale_table[LOCALE_CHARACTERS * 2] = {
+	0xc0, 0xb7, 0xc1, 0xb5, 0xc2, 0xb6, 0xc3, 0xc7, 0xc4, 0x8e, 0xc5, 0x8f,
+	0xc6, 0x92, 0xc7, 0x80, 0xc8, 0xd4, 0xc9, 0x90, 0xcb, 0xd3, 0xcc, 0xde,
+	0xcd, 0xd6, 0xce, 0xd7, 0xcf, 0xd8, 0xd0, 0xd1, 0xd1, 0xa5, 0xd2, 0xe3,
+	0xd3, 0xe0, 0xd4, 0xe2, 0xd5, 0xe5, 0xd6, 0x99, 0xd8, 0x9d, 0xd9, 0xeb,
+	0xda, 0xe9, 0xdb, 0xea, 0xdc, 0x9a, 0xde, 0xed, 0xde, 0xe8, 0xdf, 0xe1,
+	0xe0, 0x85, 0xe1, 0xa0, 0xe2, 0x83, 0xe3, 0xc6, 0xe4, 0x84, 0xe5, 0x86,
+	0xe6, 0x91, 0xe7, 0x87, 0xe8, 0x8a, 0xe9, 0x82, 0xea, 0x88, 0xeb, 0x89,
+	0xec, 0x8d, 0xed, 0xa1, 0xee, 0x8c, 0xef, 0x8b, 0xf0, 0xd0, 0xf1, 0xa4,
+	0xf2, 0x95, 0xf3, 0xa3, 0xf4, 0x93, 0xf5, 0xe4, 0xf6, 0x94, 0xf7, 0xf6,
+	0xf8, 0x9b, 0xf9, 0x97, 0xfa, 0xa3, 0xfb, 0x96, 0xfc, 0x81, 0xfd, 0xec,
+    0xfe, 0xe7, 0xff, 0x9e
+
+};
+
+char locale_convert(int codepage, char c)
+{
+	int z;
+
+	for(z=0;z<LOCALE_CHARACTERS;z++)
+	{
+		if(locale_table[(z*2)+1] == c)
+			return locale_table[z*2];
+	}
+	return c;
+}
+#endif
+
+/* Initialize the locale engine
+ * Returns: TRUE on success, FALSE on failure.
+ */
+int API locale_init(char *filename, int my_locale)
+{
+	FILE *fp = fopen(filename, FOPEN_READ_TEXT);
+	static char text[1025];
+	int count = 0;
+
+	_compat_free_locale();
+
+	if(fp)
+	{
+		if(fgets(text, 1024, fp) && strncasecmp(text, "MESSAGES=", 9) == 0 && (count = atoi(&text[9])) > 0)
+		{
+			int current = -1;
+
+			locale_text = calloc(count, sizeof(char *));
+
+			while(!feof(fp))
+			{
+				if(fgets(text, 1024, fp) && _stripcrlf(text) &&
+				   strncasecmp(text, "LOCALE=", 7) == 0)
+				{
+					if(current > -1)
+					{
+						fclose(fp);
+						locale_count = count;
+						locale_number = my_locale;
+						return 1;
+					}
+					if(atoi(&text[7]) == my_locale)
+						current = 0;
+				}
+				else if(current > -1 && current < count)
+				{
+					/* Use defaults on blank lines */
+					if(text[0])
+					{
+						int x = 0, z, len = (int)strlen(text);
+
+						locale_text[current] = calloc(1, len + 1);
+
+						for(z=0;z<len;z++)
+						{
+							if(text[z] == '\\' && (text[z+1] == 'r' || text[z+1] == 'n'
+							   || text[z+1] == '\"'  || text[z+1] == '\''))
+							{
+								switch(text[z+1])
+								{
+								case 'r':
+									locale_text[current][x] = '\r';
+                                    break;
+								case 'n':
+									locale_text[current][x] = '\n';
+                                    break;
+								case '\"':
+									locale_text[current][x] = '\"';
+                                    break;
+								case '\'':
+									locale_text[current][x] = '\'';
+                                    break;
+								}
+								x++;
+								z++;
+							}
+							else
+							{
+#ifdef __WIN32__
+								locale_text[current][x] = locale_convert(1252, text[z]);
+#else
+								locale_text[current][x] = text[z];
+#endif
+								x++;
+							}
+						}
+					}
+					current++;
+				}
+			}
+		}
+		fclose(fp);
+	}
+	if(locale_text && count)
+	{
+		locale_count = count;
+		locale_number = my_locale;
+		return 1;
+	}
+	return 0;
+}
+
+/* Retrieve a localized string if available */
+char * API locale_string(char *default_text, int message)
+{
+	if(locale_number > -1 && message < locale_count && message > -1 && locale_text[message])
+		return locale_text[message];
+	return default_text;
+}
+