added linux support
authorDavid Anderson <dvander@alliedmods.net>
Thu Jan 25 20:08:00 2007 +0000 (2007-01-25)
changeset 353492a8d0d5f59
parent 352 2c01ab1a8933
child 354 3c8e2a6ab04a
added linux support
sourcepawn/compiler/Makefile
sourcepawn/compiler/amx.h
sourcepawn/compiler/binreloc.c
sourcepawn/compiler/binreloc.h
sourcepawn/compiler/getch.h
sourcepawn/compiler/sclinux.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/sourcepawn/compiler/Makefile	Thu Jan 25 20:08:00 2007 +0000
     1.3 @@ -0,0 +1,65 @@
     1.4 +#(C)2004-2007 SourceMod Development Team
     1.5 +# Makefile written by David "BAILOPAN" Anderson
     1.6 +
     1.7 +SMSDK = ../..
     1.8 +
     1.9 +### EDIT BELOW FOR OTHER PROJECTS ###
    1.10 +
    1.11 +OPT_C_FLAGS = -O3 -funroll-loops -s -pipe -fno-strict-aliasing -fomit-frame-pointer 
    1.12 +OPT_CPP_FLAGS = 
    1.13 +DEBUG_C_FLAGS = -g -ggdb3
    1.14 +CPP = gcc-4.1
    1.15 +BINARY = spcomp
    1.16 +
    1.17 +OBJECTS = libpawnc.c lstring.c memfile.c pawncc.c sc1.c sc2.c sc3.c sc4.c sc5.c \
    1.18 +	  sc6.c sc7.c scexpand.c sci18n.c sclist.c scmemfil.c scstate.c sctracker.c \
    1.19 +	  scvars.c sp_file.c binreloc.c zlib/adler32.c zlib/crc32.c zlib/deflate.c \
    1.20 +	  zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c \
    1.21 +	  zlib/trees.c zlib/uncompr.c zlib/zutil.c zlib/compress.c
    1.22 +
    1.23 +LINK = -lgcc -static-libgcc
    1.24 +
    1.25 +INCLUDE = -I. -I$(SMSDK)/public/sourcepawn
    1.26 +
    1.27 +GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
    1.28 +
    1.29 +ifeq "$(GCC_VERSION)" "4"
    1.30 +	OPT_CPP_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
    1.31 +endif	
    1.32 +
    1.33 +ifeq "$(DEBUG)" "true"
    1.34 +	BIN_DIR = Debug
    1.35 +	CFLAGS = $(DEBUG_C_FLAGS)
    1.36 +else
    1.37 +	BIN_DIR = Release
    1.38 +	CFLAGS = $(OPT_C_FLAGS)
    1.39 +	CPPFLAGS += $(OPT_CPP_FLAGS)
    1.40 +endif
    1.41 +
    1.42 +CFLAGS += -DLINUX -DNDEBUG -DHAVE_STDINT_H -DAMX_ANSIONLY 
    1.43 +CPPFLAGS += -Wno-deprecated -fno-exceptions -fno-rtti
    1.44 +
    1.45 +OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
    1.46 +OBJ_LINUX := $(OBJECTS:%.c=$(BIN_DIR)/%.o)
    1.47 +
    1.48 +$(BIN_DIR)/%.o: %.cpp
    1.49 +	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
    1.50 +
    1.51 +$(BIN_DIR)/%.o: %.c
    1.52 +	$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
    1.53 +
    1.54 +all:
    1.55 +	mkdir -p $(BIN_DIR)/zlib
    1.56 +	$(MAKE) spcomp
    1.57 +
    1.58 +spcomp: $(OBJ_LINUX)
    1.59 +	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) $(OBJ_LINUX) $(LINK) -ldl -lm -o$(BIN_DIR)/$(BINARY)
    1.60 +
    1.61 +default: all
    1.62 +
    1.63 +clean:
    1.64 +	rm -rf Release/*.o
    1.65 +	rm -rf Release/$(BINARY)
    1.66 +	rm -rf Debug/*.o
    1.67 +	rm -rf Debug/$(BINARY)
    1.68 +
     2.1 --- a/sourcepawn/compiler/amx.h	Thu Jan 25 10:07:35 2007 +0000
     2.2 +++ b/sourcepawn/compiler/amx.h	Thu Jan 25 20:08:00 2007 +0000
     2.3 @@ -36,7 +36,9 @@
     2.4  
     2.5  #if defined __GNUC__
     2.6    #include <stdint.h>
     2.7 -  #define HAVE_STDINT_H
     2.8 +  #if !defined HAVE_STDINT_H
     2.9 +    #define HAVE_STDINT_H
    2.10 +  #endif
    2.11  #elif !defined HAVE_STDINT_H
    2.12    #if defined __LCC__ || defined __DMC__ || defined LINUX || (defined __WATCOMC__ && __WATCOMC__ >= 1200)
    2.13      #if defined HAVE_INTTYPES_H
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/sourcepawn/compiler/binreloc.c	Thu Jan 25 20:08:00 2007 +0000
     3.3 @@ -0,0 +1,766 @@
     3.4 +/*
     3.5 + * BinReloc - a library for creating relocatable executables
     3.6 + * Written by: Hongli Lai <[email protected]>
     3.7 + * http://autopackage.org/
     3.8 + *
     3.9 + * This source code is public domain. You can relicense this code
    3.10 + * under whatever license you want.
    3.11 + *
    3.12 + * See http://autopackage.org/docs/binreloc/ for
    3.13 + * more information and how to use this.
    3.14 + */
    3.15 +
    3.16 +#ifndef __BINRELOC_C__
    3.17 +#define __BINRELOC_C__
    3.18 +
    3.19 +#ifdef ENABLE_BINRELOC
    3.20 +	#include <sys/types.h>
    3.21 +	#include <sys/stat.h>
    3.22 +	#include <unistd.h>
    3.23 +#endif /* ENABLE_BINRELOC */
    3.24 +#include <stdio.h>
    3.25 +#include <stdlib.h>
    3.26 +#include <limits.h>
    3.27 +#include <string.h>
    3.28 +#include "binreloc.h"
    3.29 +
    3.30 +#ifdef __cplusplus
    3.31 +extern "C" {
    3.32 +#endif /* __cplusplus */
    3.33 +
    3.34 +
    3.35 +
    3.36 +/** @internal
    3.37 + * Find the canonical filename of the executable. Returns the filename
    3.38 + * (which must be freed) or NULL on error. If the parameter 'error' is
    3.39 + * not NULL, the error code will be stored there, if an error occured.
    3.40 + */
    3.41 +static char *
    3.42 +_br_find_exe (BrInitError *error)
    3.43 +{
    3.44 +#ifndef ENABLE_BINRELOC
    3.45 +	if (error)
    3.46 +		*error = BR_INIT_ERROR_DISABLED;
    3.47 +	return NULL;
    3.48 +#else
    3.49 +	char *path, *path2, *line, *result;
    3.50 +	size_t buf_size;
    3.51 +	ssize_t size;
    3.52 +	struct stat stat_buf;
    3.53 +	FILE *f;
    3.54 +
    3.55 +	/* Read from /proc/self/exe (symlink) */
    3.56 +	if (sizeof (path) > SSIZE_MAX)
    3.57 +		buf_size = SSIZE_MAX - 1;
    3.58 +	else
    3.59 +		buf_size = PATH_MAX - 1;
    3.60 +	path = (char *) malloc (buf_size);
    3.61 +	if (path == NULL) {
    3.62 +		/* Cannot allocate memory. */
    3.63 +		if (error)
    3.64 +			*error = BR_INIT_ERROR_NOMEM;
    3.65 +		return NULL;
    3.66 +	}
    3.67 +	path2 = (char *) malloc (buf_size);
    3.68 +	if (path2 == NULL) {
    3.69 +		/* Cannot allocate memory. */
    3.70 +		if (error)
    3.71 +			*error = BR_INIT_ERROR_NOMEM;
    3.72 +		free (path);
    3.73 +		return NULL;
    3.74 +	}
    3.75 +
    3.76 +	strncpy (path2, "/proc/self/exe", buf_size - 1);
    3.77 +
    3.78 +	while (1) {
    3.79 +		int i;
    3.80 +
    3.81 +		size = readlink (path2, path, buf_size - 1);
    3.82 +		if (size == -1) {
    3.83 +			/* Error. */
    3.84 +			free (path2);
    3.85 +			break;
    3.86 +		}
    3.87 +
    3.88 +		/* readlink() success. */
    3.89 +		path[size] = '\0';
    3.90 +
    3.91 +		/* Check whether the symlink's target is also a symlink.
    3.92 +		 * We want to get the final target. */
    3.93 +		i = stat (path, &stat_buf);
    3.94 +		if (i == -1) {
    3.95 +			/* Error. */
    3.96 +			free (path2);
    3.97 +			break;
    3.98 +		}
    3.99 +
   3.100 +		/* stat() success. */
   3.101 +		if (!S_ISLNK (stat_buf.st_mode)) {
   3.102 +			/* path is not a symlink. Done. */
   3.103 +			free (path2);
   3.104 +			return path;
   3.105 +		}
   3.106 +
   3.107 +		/* path is a symlink. Continue loop and resolve this. */
   3.108 +		strncpy (path, path2, buf_size - 1);
   3.109 +	}
   3.110 +
   3.111 +
   3.112 +	/* readlink() or stat() failed; this can happen when the program is
   3.113 +	 * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
   3.114 +
   3.115 +	buf_size = PATH_MAX + 128;
   3.116 +	line = (char *) realloc (path, buf_size);
   3.117 +	if (line == NULL) {
   3.118 +		/* Cannot allocate memory. */
   3.119 +		free (path);
   3.120 +		if (error)
   3.121 +			*error = BR_INIT_ERROR_NOMEM;
   3.122 +		return NULL;
   3.123 +	}
   3.124 +
   3.125 +	f = fopen ("/proc/self/maps", "r");
   3.126 +	if (f == NULL) {
   3.127 +		free (line);
   3.128 +		if (error)
   3.129 +			*error = BR_INIT_ERROR_OPEN_MAPS;
   3.130 +		return NULL;
   3.131 +	}
   3.132 +
   3.133 +	/* The first entry should be the executable name. */
   3.134 +	result = fgets (line, (int) buf_size, f);
   3.135 +	if (result == NULL) {
   3.136 +		fclose (f);
   3.137 +		free (line);
   3.138 +		if (error)
   3.139 +			*error = BR_INIT_ERROR_READ_MAPS;
   3.140 +		return NULL;
   3.141 +	}
   3.142 +
   3.143 +	/* Get rid of newline character. */
   3.144 +	buf_size = strlen (line);
   3.145 +	if (buf_size <= 0) {
   3.146 +		/* Huh? An empty string? */
   3.147 +		fclose (f);
   3.148 +		free (line);
   3.149 +		if (error)
   3.150 +			*error = BR_INIT_ERROR_INVALID_MAPS;
   3.151 +		return NULL;
   3.152 +	}
   3.153 +	if (line[buf_size - 1] == 10)
   3.154 +		line[buf_size - 1] = 0;
   3.155 +
   3.156 +	/* Extract the filename; it is always an absolute path. */
   3.157 +	path = strchr (line, '/');
   3.158 +
   3.159 +	/* Sanity check. */
   3.160 +	if (strstr (line, " r-xp ") == NULL || path == NULL) {
   3.161 +		fclose (f);
   3.162 +		free (line);
   3.163 +		if (error)
   3.164 +			*error = BR_INIT_ERROR_INVALID_MAPS;
   3.165 +		return NULL;
   3.166 +	}
   3.167 +
   3.168 +	path = strdup (path);
   3.169 +	free (line);
   3.170 +	fclose (f);
   3.171 +	return path;
   3.172 +#endif /* ENABLE_BINRELOC */
   3.173 +}
   3.174 +
   3.175 +
   3.176 +/** @internal
   3.177 + * Find the canonical filename of the executable which owns symbol.
   3.178 + * Returns a filename which must be freed, or NULL on error.
   3.179 + */
   3.180 +static char *
   3.181 +_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
   3.182 +{
   3.183 +#ifndef ENABLE_BINRELOC
   3.184 +	if (error)
   3.185 +		*error = BR_INIT_ERROR_DISABLED;
   3.186 +	return (char *) NULL;
   3.187 +#else
   3.188 +	#define SIZE PATH_MAX + 100
   3.189 +	FILE *f;
   3.190 +	size_t address_string_len;
   3.191 +	char *address_string, line[SIZE], *found;
   3.192 +
   3.193 +	if (symbol == NULL)
   3.194 +		return (char *) NULL;
   3.195 +
   3.196 +	f = fopen ("/proc/self/maps", "r");
   3.197 +	if (f == NULL)
   3.198 +		return (char *) NULL;
   3.199 +
   3.200 +	address_string_len = 4;
   3.201 +	address_string = (char *) malloc (address_string_len);
   3.202 +	found = (char *) NULL;
   3.203 +
   3.204 +	while (!feof (f)) {
   3.205 +		char *start_addr, *end_addr, *end_addr_end, *file;
   3.206 +		void *start_addr_p, *end_addr_p;
   3.207 +		size_t len;
   3.208 +
   3.209 +		if (fgets (line, SIZE, f) == NULL)
   3.210 +			break;
   3.211 +
   3.212 +		/* Sanity check. */
   3.213 +		if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
   3.214 +			continue;
   3.215 +
   3.216 +		/* Parse line. */
   3.217 +		start_addr = line;
   3.218 +		end_addr = strchr (line, '-');
   3.219 +		file = strchr (line, '/');
   3.220 +
   3.221 +		/* More sanity check. */
   3.222 +		if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
   3.223 +			continue;
   3.224 +
   3.225 +		end_addr[0] = '\0';
   3.226 +		end_addr++;
   3.227 +		end_addr_end = strchr (end_addr, ' ');
   3.228 +		if (end_addr_end == NULL)
   3.229 +			continue;
   3.230 +
   3.231 +		end_addr_end[0] = '\0';
   3.232 +		len = strlen (file);
   3.233 +		if (len == 0)
   3.234 +			continue;
   3.235 +		if (file[len - 1] == '\n')
   3.236 +			file[len - 1] = '\0';
   3.237 +
   3.238 +		/* Get rid of "(deleted)" from the filename. */
   3.239 +		len = strlen (file);
   3.240 +		if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
   3.241 +			file[len - 10] = '\0';
   3.242 +
   3.243 +		/* I don't know whether this can happen but better safe than sorry. */
   3.244 +		len = strlen (start_addr);
   3.245 +		if (len != strlen (end_addr))
   3.246 +			continue;
   3.247 +
   3.248 +
   3.249 +		/* Transform the addresses into a string in the form of 0xdeadbeef,
   3.250 +		 * then transform that into a pointer. */
   3.251 +		if (address_string_len < len + 3) {
   3.252 +			address_string_len = len + 3;
   3.253 +			address_string = (char *) realloc (address_string, address_string_len);
   3.254 +		}
   3.255 +
   3.256 +		memcpy (address_string, "0x", 2);
   3.257 +		memcpy (address_string + 2, start_addr, len);
   3.258 +		address_string[2 + len] = '\0';
   3.259 +		sscanf (address_string, "%p", &start_addr_p);
   3.260 +
   3.261 +		memcpy (address_string, "0x", 2);
   3.262 +		memcpy (address_string + 2, end_addr, len);
   3.263 +		address_string[2 + len] = '\0';
   3.264 +		sscanf (address_string, "%p", &end_addr_p);
   3.265 +
   3.266 +
   3.267 +		if (symbol >= start_addr_p && symbol < end_addr_p) {
   3.268 +			found = file;
   3.269 +			break;
   3.270 +		}
   3.271 +	}
   3.272 +
   3.273 +	free (address_string);
   3.274 +	fclose (f);
   3.275 +
   3.276 +	if (found == NULL)
   3.277 +		return (char *) NULL;
   3.278 +	else
   3.279 +		return strdup (found);
   3.280 +#endif /* ENABLE_BINRELOC */
   3.281 +}
   3.282 +
   3.283 +
   3.284 +#ifndef BINRELOC_RUNNING_DOXYGEN
   3.285 +	#undef NULL
   3.286 +	#define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
   3.287 +#endif
   3.288 +
   3.289 +static char *exe = (char *) NULL;
   3.290 +
   3.291 +
   3.292 +/** Initialize the BinReloc library (for applications).
   3.293 + *
   3.294 + * This function must be called before using any other BinReloc functions.
   3.295 + * It attempts to locate the application's canonical filename.
   3.296 + *
   3.297 + * @note If you want to use BinReloc for a library, then you should call
   3.298 + *       br_init_lib() instead.
   3.299 + *
   3.300 + * @param error  If BinReloc failed to initialize, then the error code will
   3.301 + *               be stored in this variable. Set to NULL if you want to
   3.302 + *               ignore this. See #BrInitError for a list of error codes.
   3.303 + *
   3.304 + * @returns 1 on success, 0 if BinReloc failed to initialize.
   3.305 + */
   3.306 +int
   3.307 +br_init (BrInitError *error)
   3.308 +{
   3.309 +	exe = _br_find_exe (error);
   3.310 +	return exe != NULL;
   3.311 +}
   3.312 +
   3.313 +
   3.314 +/** Initialize the BinReloc library (for libraries).
   3.315 + *
   3.316 + * This function must be called before using any other BinReloc functions.
   3.317 + * It attempts to locate the calling library's canonical filename.
   3.318 + *
   3.319 + * @note The BinReloc source code MUST be included in your library, or this
   3.320 + *       function won't work correctly.
   3.321 + *
   3.322 + * @param error  If BinReloc failed to initialize, then the error code will
   3.323 + *               be stored in this variable. Set to NULL if you want to
   3.324 + *               ignore this. See #BrInitError for a list of error codes.
   3.325 + *
   3.326 + * @returns 1 on success, 0 if a filename cannot be found.
   3.327 + */
   3.328 +int
   3.329 +br_init_lib (BrInitError *error)
   3.330 +{
   3.331 +	exe = _br_find_exe_for_symbol ((const void *) "", error);
   3.332 +	return exe != NULL;
   3.333 +}
   3.334 +
   3.335 +
   3.336 +/** Find the canonical filename of the current application.
   3.337 + *
   3.338 + * @param default_exe  A default filename which will be used as fallback.
   3.339 + * @returns A string containing the application's canonical filename,
   3.340 + *          which must be freed when no longer necessary. If BinReloc is
   3.341 + *          not initialized, or if br_init() failed, then a copy of
   3.342 + *          default_exe will be returned. If default_exe is NULL, then
   3.343 + *          NULL will be returned.
   3.344 + */
   3.345 +char *
   3.346 +br_find_exe (const char *default_exe)
   3.347 +{
   3.348 +	if (exe == (char *) NULL) {
   3.349 +		/* BinReloc is not initialized. */
   3.350 +		if (default_exe != (const char *) NULL)
   3.351 +			return strdup (default_exe);
   3.352 +		else
   3.353 +			return (char *) NULL;
   3.354 +	}
   3.355 +	return strdup (exe);
   3.356 +}
   3.357 +
   3.358 +
   3.359 +/** Locate the directory in which the current application is installed.
   3.360 + *
   3.361 + * The prefix is generated by the following pseudo-code evaluation:
   3.362 + * \code
   3.363 + * dirname(exename)
   3.364 + * \endcode
   3.365 + *
   3.366 + * @param default_dir  A default directory which will used as fallback.
   3.367 + * @return A string containing the directory, which must be freed when no
   3.368 + *         longer necessary. If BinReloc is not initialized, or if the
   3.369 + *         initialization function failed, then a copy of default_dir
   3.370 + *         will be returned. If default_dir is NULL, then NULL will be
   3.371 + *         returned.
   3.372 + */
   3.373 +char *
   3.374 +br_find_exe_dir (const char *default_dir)
   3.375 +{
   3.376 +	if (exe == NULL) {
   3.377 +		/* BinReloc not initialized. */
   3.378 +		if (default_dir != NULL)
   3.379 +			return strdup (default_dir);
   3.380 +		else
   3.381 +			return NULL;
   3.382 +	}
   3.383 +
   3.384 +	return br_dirname (exe);
   3.385 +}
   3.386 +
   3.387 +
   3.388 +/** Locate the prefix in which the current application is installed.
   3.389 + *
   3.390 + * The prefix is generated by the following pseudo-code evaluation:
   3.391 + * \code
   3.392 + * dirname(dirname(exename))
   3.393 + * \endcode
   3.394 + *
   3.395 + * @param default_prefix  A default prefix which will used as fallback.
   3.396 + * @return A string containing the prefix, which must be freed when no
   3.397 + *         longer necessary. If BinReloc is not initialized, or if
   3.398 + *         the initialization function failed, then a copy of default_prefix
   3.399 + *         will be returned. If default_prefix is NULL, then NULL will be returned.
   3.400 + */
   3.401 +char *
   3.402 +br_find_prefix (const char *default_prefix)
   3.403 +{
   3.404 +	char *dir1, *dir2;
   3.405 +
   3.406 +	if (exe == (char *) NULL) {
   3.407 +		/* BinReloc not initialized. */
   3.408 +		if (default_prefix != (const char *) NULL)
   3.409 +			return strdup (default_prefix);
   3.410 +		else
   3.411 +			return (char *) NULL;
   3.412 +	}
   3.413 +
   3.414 +	dir1 = br_dirname (exe);
   3.415 +	dir2 = br_dirname (dir1);
   3.416 +	free (dir1);
   3.417 +	return dir2;
   3.418 +}
   3.419 +
   3.420 +
   3.421 +/** Locate the application's binary folder.
   3.422 + *
   3.423 + * The path is generated by the following pseudo-code evaluation:
   3.424 + * \code
   3.425 + * prefix + "/bin"
   3.426 + * \endcode
   3.427 + *
   3.428 + * @param default_bin_dir  A default path which will used as fallback.
   3.429 + * @return A string containing the bin folder's path, which must be freed when
   3.430 + *         no longer necessary. If BinReloc is not initialized, or if
   3.431 + *         the initialization function failed, then a copy of default_bin_dir will
   3.432 + *         be returned. If default_bin_dir is NULL, then NULL will be returned.
   3.433 + */
   3.434 +char *
   3.435 +br_find_bin_dir (const char *default_bin_dir)
   3.436 +{
   3.437 +	char *prefix, *dir;
   3.438 +
   3.439 +	prefix = br_find_prefix ((const char *) NULL);
   3.440 +	if (prefix == (char *) NULL) {
   3.441 +		/* BinReloc not initialized. */
   3.442 +		if (default_bin_dir != (const char *) NULL)
   3.443 +			return strdup (default_bin_dir);
   3.444 +		else
   3.445 +			return (char *) NULL;
   3.446 +	}
   3.447 +
   3.448 +	dir = br_build_path (prefix, "bin");
   3.449 +	free (prefix);
   3.450 +	return dir;
   3.451 +}
   3.452 +
   3.453 +
   3.454 +/** Locate the application's superuser binary folder.
   3.455 + *
   3.456 + * The path is generated by the following pseudo-code evaluation:
   3.457 + * \code
   3.458 + * prefix + "/sbin"
   3.459 + * \endcode
   3.460 + *
   3.461 + * @param default_sbin_dir  A default path which will used as fallback.
   3.462 + * @return A string containing the sbin folder's path, which must be freed when
   3.463 + *         no longer necessary. If BinReloc is not initialized, or if the
   3.464 + *         initialization function failed, then a copy of default_sbin_dir will
   3.465 + *         be returned. If default_bin_dir is NULL, then NULL will be returned.
   3.466 + */
   3.467 +char *
   3.468 +br_find_sbin_dir (const char *default_sbin_dir)
   3.469 +{
   3.470 +	char *prefix, *dir;
   3.471 +
   3.472 +	prefix = br_find_prefix ((const char *) NULL);
   3.473 +	if (prefix == (char *) NULL) {
   3.474 +		/* BinReloc not initialized. */
   3.475 +		if (default_sbin_dir != (const char *) NULL)
   3.476 +			return strdup (default_sbin_dir);
   3.477 +		else
   3.478 +			return (char *) NULL;
   3.479 +	}
   3.480 +
   3.481 +	dir = br_build_path (prefix, "sbin");
   3.482 +	free (prefix);
   3.483 +	return dir;
   3.484 +}
   3.485 +
   3.486 +
   3.487 +/** Locate the application's data folder.
   3.488 + *
   3.489 + * The path is generated by the following pseudo-code evaluation:
   3.490 + * \code
   3.491 + * prefix + "/share"
   3.492 + * \endcode
   3.493 + *
   3.494 + * @param default_data_dir  A default path which will used as fallback.
   3.495 + * @return A string containing the data folder's path, which must be freed when
   3.496 + *         no longer necessary. If BinReloc is not initialized, or if the
   3.497 + *         initialization function failed, then a copy of default_data_dir
   3.498 + *         will be returned. If default_data_dir is NULL, then NULL will be
   3.499 + *         returned.
   3.500 + */
   3.501 +char *
   3.502 +br_find_data_dir (const char *default_data_dir)
   3.503 +{
   3.504 +	char *prefix, *dir;
   3.505 +
   3.506 +	prefix = br_find_prefix ((const char *) NULL);
   3.507 +	if (prefix == (char *) NULL) {
   3.508 +		/* BinReloc not initialized. */
   3.509 +		if (default_data_dir != (const char *) NULL)
   3.510 +			return strdup (default_data_dir);
   3.511 +		else
   3.512 +			return (char *) NULL;
   3.513 +	}
   3.514 +
   3.515 +	dir = br_build_path (prefix, "share");
   3.516 +	free (prefix);
   3.517 +	return dir;
   3.518 +}
   3.519 +
   3.520 +
   3.521 +/** Locate the application's localization folder.
   3.522 + *
   3.523 + * The path is generated by the following pseudo-code evaluation:
   3.524 + * \code
   3.525 + * prefix + "/share/locale"
   3.526 + * \endcode
   3.527 + *
   3.528 + * @param default_locale_dir  A default path which will used as fallback.
   3.529 + * @return A string containing the localization folder's path, which must be freed when
   3.530 + *         no longer necessary. If BinReloc is not initialized, or if the
   3.531 + *         initialization function failed, then a copy of default_locale_dir will be returned.
   3.532 + *         If default_locale_dir is NULL, then NULL will be returned.
   3.533 + */
   3.534 +char *
   3.535 +br_find_locale_dir (const char *default_locale_dir)
   3.536 +{
   3.537 +	char *data_dir, *dir;
   3.538 +
   3.539 +	data_dir = br_find_data_dir ((const char *) NULL);
   3.540 +	if (data_dir == (char *) NULL) {
   3.541 +		/* BinReloc not initialized. */
   3.542 +		if (default_locale_dir != (const char *) NULL)
   3.543 +			return strdup (default_locale_dir);
   3.544 +		else
   3.545 +			return (char *) NULL;
   3.546 +	}
   3.547 +
   3.548 +	dir = br_build_path (data_dir, "locale");
   3.549 +	free (data_dir);
   3.550 +	return dir;
   3.551 +}
   3.552 +
   3.553 +
   3.554 +/** Locate the application's library folder.
   3.555 + *
   3.556 + * The path is generated by the following pseudo-code evaluation:
   3.557 + * \code
   3.558 + * prefix + "/lib"
   3.559 + * \endcode
   3.560 + *
   3.561 + * @param default_lib_dir  A default path which will used as fallback.
   3.562 + * @return A string containing the library folder's path, which must be freed when
   3.563 + *         no longer necessary. If BinReloc is not initialized, or if the initialization
   3.564 + *         function failed, then a copy of default_lib_dir will be returned.
   3.565 + *         If default_lib_dir is NULL, then NULL will be returned.
   3.566 + */
   3.567 +char *
   3.568 +br_find_lib_dir (const char *default_lib_dir)
   3.569 +{
   3.570 +	char *prefix, *dir;
   3.571 +
   3.572 +	prefix = br_find_prefix ((const char *) NULL);
   3.573 +	if (prefix == (char *) NULL) {
   3.574 +		/* BinReloc not initialized. */
   3.575 +		if (default_lib_dir != (const char *) NULL)
   3.576 +			return strdup (default_lib_dir);
   3.577 +		else
   3.578 +			return (char *) NULL;
   3.579 +	}
   3.580 +
   3.581 +	dir = br_build_path (prefix, "lib");
   3.582 +	free (prefix);
   3.583 +	return dir;
   3.584 +}
   3.585 +
   3.586 +
   3.587 +/** Locate the application's libexec folder.
   3.588 + *
   3.589 + * The path is generated by the following pseudo-code evaluation:
   3.590 + * \code
   3.591 + * prefix + "/libexec"
   3.592 + * \endcode
   3.593 + *
   3.594 + * @param default_libexec_dir  A default path which will used as fallback.
   3.595 + * @return A string containing the libexec folder's path, which must be freed when
   3.596 + *         no longer necessary. If BinReloc is not initialized, or if the initialization
   3.597 + *         function failed, then a copy of default_libexec_dir will be returned.
   3.598 + *         If default_libexec_dir is NULL, then NULL will be returned.
   3.599 + */
   3.600 +char *
   3.601 +br_find_libexec_dir (const char *default_libexec_dir)
   3.602 +{
   3.603 +	char *prefix, *dir;
   3.604 +
   3.605 +	prefix = br_find_prefix ((const char *) NULL);
   3.606 +	if (prefix == (char *) NULL) {
   3.607 +		/* BinReloc not initialized. */
   3.608 +		if (default_libexec_dir != (const char *) NULL)
   3.609 +			return strdup (default_libexec_dir);
   3.610 +		else
   3.611 +			return (char *) NULL;
   3.612 +	}
   3.613 +
   3.614 +	dir = br_build_path (prefix, "libexec");
   3.615 +	free (prefix);
   3.616 +	return dir;
   3.617 +}
   3.618 +
   3.619 +
   3.620 +/** Locate the application's configuration files folder.
   3.621 + *
   3.622 + * The path is generated by the following pseudo-code evaluation:
   3.623 + * \code
   3.624 + * prefix + "/etc"
   3.625 + * \endcode
   3.626 + *
   3.627 + * @param default_etc_dir  A default path which will used as fallback.
   3.628 + * @return A string containing the etc folder's path, which must be freed when
   3.629 + *         no longer necessary. If BinReloc is not initialized, or if the initialization
   3.630 + *         function failed, then a copy of default_etc_dir will be returned.
   3.631 + *         If default_etc_dir is NULL, then NULL will be returned.
   3.632 + */
   3.633 +char *
   3.634 +br_find_etc_dir (const char *default_etc_dir)
   3.635 +{
   3.636 +	char *prefix, *dir;
   3.637 +
   3.638 +	prefix = br_find_prefix ((const char *) NULL);
   3.639 +	if (prefix == (char *) NULL) {
   3.640 +		/* BinReloc not initialized. */
   3.641 +		if (default_etc_dir != (const char *) NULL)
   3.642 +			return strdup (default_etc_dir);
   3.643 +		else
   3.644 +			return (char *) NULL;
   3.645 +	}
   3.646 +
   3.647 +	dir = br_build_path (prefix, "etc");
   3.648 +	free (prefix);
   3.649 +	return dir;
   3.650 +}
   3.651 +
   3.652 +
   3.653 +/***********************
   3.654 + * Utility functions
   3.655 + ***********************/
   3.656 +
   3.657 +/** Concatenate str1 and str2 to a newly allocated string.
   3.658 + *
   3.659 + * @param str1 A string.
   3.660 + * @param str2 Another string.
   3.661 + * @returns A newly-allocated string. This string should be freed when no longer needed.
   3.662 + */
   3.663 +char *
   3.664 +br_strcat (const char *str1, const char *str2)
   3.665 +{
   3.666 +	char *result;
   3.667 +	size_t len1, len2;
   3.668 +
   3.669 +	if (str1 == NULL)
   3.670 +		str1 = "";
   3.671 +	if (str2 == NULL)
   3.672 +		str2 = "";
   3.673 +
   3.674 +	len1 = strlen (str1);
   3.675 +	len2 = strlen (str2);
   3.676 +
   3.677 +	result = (char *) malloc (len1 + len2 + 1);
   3.678 +	memcpy (result, str1, len1);
   3.679 +	memcpy (result + len1, str2, len2);
   3.680 +	result[len1 + len2] = '\0';
   3.681 +
   3.682 +	return result;
   3.683 +}
   3.684 +
   3.685 +
   3.686 +char *
   3.687 +br_build_path (const char *dir, const char *file)
   3.688 +{
   3.689 +	char *dir2, *result;
   3.690 +	size_t len;
   3.691 +	int must_free = 0;
   3.692 +
   3.693 +	len = strlen (dir);
   3.694 +	if (len > 0 && dir[len - 1] != '/') {
   3.695 +		dir2 = br_strcat (dir, "/");
   3.696 +		must_free = 1;
   3.697 +	} else
   3.698 +		dir2 = (char *) dir;
   3.699 +
   3.700 +	result = br_strcat (dir2, file);
   3.701 +	if (must_free)
   3.702 +		free (dir2);
   3.703 +	return result;
   3.704 +}
   3.705 +
   3.706 +
   3.707 +/* Emulates glibc's strndup() */
   3.708 +static char *
   3.709 +br_strndup (const char *str, size_t size)
   3.710 +{
   3.711 +	char *result = (char *) NULL;
   3.712 +	size_t len;
   3.713 +
   3.714 +	if (str == (const char *) NULL)
   3.715 +		return (char *) NULL;
   3.716 +
   3.717 +	len = strlen (str);
   3.718 +	if (len == 0)
   3.719 +		return strdup ("");
   3.720 +	if (size > len)
   3.721 +		size = len;
   3.722 +
   3.723 +	result = (char *) malloc (len + 1);
   3.724 +	memcpy (result, str, size);
   3.725 +	result[size] = '\0';
   3.726 +	return result;
   3.727 +}
   3.728 +
   3.729 +
   3.730 +/** Extracts the directory component of a path.
   3.731 + *
   3.732 + * Similar to g_dirname() or the dirname commandline application.
   3.733 + *
   3.734 + * Example:
   3.735 + * \code
   3.736 + * br_dirname ("/usr/local/foobar");  --> Returns: "/usr/local"
   3.737 + * \endcode
   3.738 + *
   3.739 + * @param path  A path.
   3.740 + * @returns     A directory name. This string should be freed when no longer needed.
   3.741 + */
   3.742 +char *
   3.743 +br_dirname (const char *path)
   3.744 +{
   3.745 +	char *end, *result;
   3.746 +
   3.747 +	if (path == (const char *) NULL)
   3.748 +		return (char *) NULL;
   3.749 +
   3.750 +	end = strrchr (path, '/');
   3.751 +	if (end == (const char *) NULL)
   3.752 +		return strdup (".");
   3.753 +
   3.754 +	while (end > path && *end == '/')
   3.755 +		end--;
   3.756 +	result = br_strndup (path, end - path + 1);
   3.757 +	if (result[0] == 0) {
   3.758 +		free (result);
   3.759 +		return strdup ("/");
   3.760 +	} else
   3.761 +		return result;
   3.762 +}
   3.763 +
   3.764 +
   3.765 +#ifdef __cplusplus
   3.766 +}
   3.767 +#endif /* __cplusplus */
   3.768 +
   3.769 +#endif /* __BINRELOC_C__ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/sourcepawn/compiler/binreloc.h	Thu Jan 25 20:08:00 2007 +0000
     4.3 @@ -0,0 +1,80 @@
     4.4 +/*
     4.5 + * BinReloc - a library for creating relocatable executables
     4.6 + * Written by: Hongli Lai <[email protected]>
     4.7 + * http://autopackage.org/
     4.8 + *
     4.9 + * This source code is public domain. You can relicense this code
    4.10 + * under whatever license you want.
    4.11 + *
    4.12 + * See http://autopackage.org/docs/binreloc/ for
    4.13 + * more information and how to use this.
    4.14 + */
    4.15 +
    4.16 +#ifndef __BINRELOC_H__
    4.17 +#define __BINRELOC_H__
    4.18 +
    4.19 +#ifdef __cplusplus
    4.20 +extern "C" {
    4.21 +#endif /* __cplusplus */
    4.22 +
    4.23 +
    4.24 +/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
    4.25 +typedef enum {
    4.26 +	/** Cannot allocate memory. */
    4.27 +	BR_INIT_ERROR_NOMEM,
    4.28 +	/** Unable to open /proc/self/maps; see errno for details. */
    4.29 +	BR_INIT_ERROR_OPEN_MAPS,
    4.30 +	/** Unable to read from /proc/self/maps; see errno for details. */
    4.31 +	BR_INIT_ERROR_READ_MAPS,
    4.32 +	/** The file format of /proc/self/maps is invalid; kernel bug? */
    4.33 +	BR_INIT_ERROR_INVALID_MAPS,
    4.34 +	/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
    4.35 +	BR_INIT_ERROR_DISABLED
    4.36 +} BrInitError;
    4.37 +
    4.38 +
    4.39 +#ifndef BINRELOC_RUNNING_DOXYGEN
    4.40 +/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
    4.41 +	#define br_init             SbCJ22537442193159_br_init
    4.42 +	#define br_init_lib         SbCJ22537442193159_br_init_lib
    4.43 +	#define br_find_exe         SbCJ22537442193159_br_find_exe
    4.44 +	#define br_find_exe_dir     SbCJ22537442193159_br_find_exe_dir
    4.45 +	#define br_find_prefix      SbCJ22537442193159_br_find_prefix
    4.46 +	#define br_find_bin_dir     SbCJ22537442193159_br_find_bin_dir
    4.47 +	#define br_find_sbin_dir    SbCJ22537442193159_br_find_sbin_dir
    4.48 +	#define br_find_data_dir    SbCJ22537442193159_br_find_data_dir
    4.49 +	#define br_find_locale_dir  SbCJ22537442193159_br_find_locale_dir
    4.50 +	#define br_find_lib_dir     SbCJ22537442193159_br_find_lib_dir
    4.51 +	#define br_find_libexec_dir SbCJ22537442193159_br_find_libexec_dir
    4.52 +	#define br_find_etc_dir     SbCJ22537442193159_br_find_etc_dir
    4.53 +	#define br_strcat           SbCJ22537442193159_br_strcat
    4.54 +	#define br_build_path       SbCJ22537442193159_br_build_path
    4.55 +	#define br_dirname          SbCJ22537442193159_br_dirname
    4.56 +
    4.57 +
    4.58 +#endif
    4.59 +int   br_init             (BrInitError *error);
    4.60 +int   br_init_lib         (BrInitError *error);
    4.61 +
    4.62 +char *br_find_exe         (const char *default_exe);
    4.63 +char *br_find_exe_dir     (const char *default_dir);
    4.64 +char *br_find_prefix      (const char *default_prefix);
    4.65 +char *br_find_bin_dir     (const char *default_bin_dir);
    4.66 +char *br_find_sbin_dir    (const char *default_sbin_dir);
    4.67 +char *br_find_data_dir    (const char *default_data_dir);
    4.68 +char *br_find_locale_dir  (const char *default_locale_dir);
    4.69 +char *br_find_lib_dir     (const char *default_lib_dir);
    4.70 +char *br_find_libexec_dir (const char *default_libexec_dir);
    4.71 +char *br_find_etc_dir     (const char *default_etc_dir);
    4.72 +
    4.73 +/* Utility functions */
    4.74 +char *br_strcat  (const char *str1, const char *str2);
    4.75 +char *br_build_path (const char *dir, const char *file);
    4.76 +char *br_dirname (const char *path);
    4.77 +
    4.78 +
    4.79 +#ifdef __cplusplus
    4.80 +}
    4.81 +#endif /* __cplusplus */
    4.82 +
    4.83 +#endif /* __BINRELOC_H__ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/sourcepawn/compiler/getch.h	Thu Jan 25 20:08:00 2007 +0000
     5.3 @@ -0,0 +1,15 @@
     5.4 +/* Extremely inefficient but portable POSIX getch(), see getch.c */
     5.5 +#ifndef GETCH_H
     5.6 +#define GETCH_H
     5.7 +
     5.8 +#if defined __cplusplus
     5.9 +  extern "C" {
    5.10 +#endif
    5.11 +int getch(void);
    5.12 +int kbhit(void);
    5.13 +
    5.14 +#if defined __cplusplus
    5.15 +}
    5.16 +#endif
    5.17 +
    5.18 +#endif /* GETCH_H */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/sourcepawn/compiler/sclinux.h	Thu Jan 25 20:08:00 2007 +0000
     6.3 @@ -0,0 +1,47 @@
     6.4 +/*
     6.5 + * Things needed to compile under linux.
     6.6 + *
     6.7 + * Should be reworked totally to use GNU's 'configure'
     6.8 + */
     6.9 +#ifndef SCLINUX_H
    6.10 +#define SCLINUX_H
    6.11 +
    6.12 +/* getchar() is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the
    6.13 + * controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling 
    6.14 + * terminal tty's in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must 
    6.15 + * be put back correctly when the function ends. See GETCH.C for an implementation.
    6.16 + *
    6.17 + * For interactive use of SRUN/SDBG if would be much better to use GNU's readline package: the user would be able to 
    6.18 + * have a complete emacs/vi like line editing system.
    6.19 + */
    6.20 +#include "getch.h"
    6.21 +
    6.22 +#define	stricmp(a,b)    strcasecmp(a,b)
    6.23 +#define	strnicmp(a,b,c) strncasecmp(a,b,c)
    6.24 +
    6.25 +/*
    6.26 + * WinWorld wants '\'. Unices do not.
    6.27 + */
    6.28 +#define	DIRECTORY_SEP_CHAR      '/'
    6.29 +#define	DIRECTORY_SEP_STR       "/"
    6.30 +
    6.31 +/*
    6.32 + * SC assumes that a computer is Little Endian unless told otherwise. It uses
    6.33 + * (and defines) the macros BYTE_ORDER and BIG_ENDIAN.
    6.34 + * For Linux, we must overrule these settings with those defined in glibc.
    6.35 + */
    6.36 +#if !defined __BYTE_ORDER
    6.37 +# include <stdlib.h>
    6.38 +#endif
    6.39 +
    6.40 +#if defined __OpenBSD__ || defined __FreeBSD__
    6.41 +# define __BYTE_ORDER    BYTE_ORDER
    6.42 +# define __LITTLE_ENDIAN LITTLE_ENDIAN
    6.43 +# define __BIG_ENDIAN    BIG_ENDIAN
    6.44 +#endif
    6.45 +
    6.46 +#if !defined __BYTE_ORDER
    6.47 +# error	"Can't figure computer byte order (__BYTE_ORDER macro not found)"
    6.48 +#endif
    6.49 +
    6.50 +#endif /* SCLINUX_H */