Remove Pawn support

0.6.3
Koncord 7 years ago
parent bef53749ed
commit 685a80887b

@ -7,7 +7,6 @@ if(UNIX) #temporarily disabled for non-unix
endif(NOT (${CMAKE_CXX_COMPILER} MATCHES "aarch64" OR ${CMAKE_CXX_COMPILER} MATCHES "arm"))
endif(UNIX)
option(BUILD_WITH_PAWN "Enable Pawn language" OFF)
option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF)
if(ENABLE_BREAKPAD)
@ -22,25 +21,6 @@ if(ENABLE_BREAKPAD)
include_directories(${CMAKE_SOURCE_DIR}/extern/breakpad/src ${Breakpad_Headers})
endif(ENABLE_BREAKPAD)
if(BUILD_WITH_PAWN)
add_subdirectory(amx)
#set(Pawn_ROOT ${CMAKE_SOURCE_DIR}/external/pawn/)
set(Pawn_INCLUDES ${Pawn_ROOT}/include)
set(Pawn_LIBRARY ${Pawn_ROOT}/lib/libamx.a)
set(PawnScript_Sources
Script/LangPawn/LangPAWN.cpp
Script/LangPawn/PawnFunc.cpp)
set(PawnScript_Headers ${Pawn_INCLUDES}
Script/LangPawn/LangPAWN.hpp
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_PAWN -DPAWN_CELL_SIZE=64")
#include_directories(${Pawn_INCLUDES})
include_directories("./amx/linux")
endif(BUILD_WITH_PAWN)
option(BUILD_WITH_LUA "Enable Terra/Lua language" ON)
option(FORCE_LUA "Use Lua instead Terra" OFF)
if(BUILD_WITH_LUA)
@ -93,7 +73,6 @@ set(SERVER
Script/Functions/Timer.cpp
Script/API/TimerAPI.cpp Script/API/PublicFnAPI.cpp
${PawnScript_Sources}
${LuaScript_Sources}
${NativeScript_Sources}
@ -103,7 +82,6 @@ set(SERVER_HEADER
Script/Types.hpp Script/Script.hpp Script/SystemInterface.hpp
Script/ScriptFunction.hpp Script/Platform.hpp Script/Language.hpp
Script/ScriptFunctions.hpp Script/API/TimerAPI.hpp Script/API/PublicFnAPI.hpp
${PawnScript_Headers}
${LuaScript_Headers}
${NativeScript_Headers}
${CallFF_INCLUDES}
@ -194,7 +172,6 @@ target_link_libraries(tes3mp-server
components
${Terra_LIBRARY}
${LUA_LIBRARIES}
${Pawn_LIBRARY}
${Breakpad_Library}
${CallFF_LIBRARY}
)

@ -25,14 +25,6 @@ Public::Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, c
publics.emplace(name, this);
}
#if defined(ENABLE_PAWN)
Public::Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def): ScriptFunction(_public, amx, ret_type, def)
{
publics.emplace(name, this);
}
#endif
boost::any Public::Call(const std::string &name, const std::vector<boost::any> &args)
{
auto it = publics.find(name);
@ -67,21 +59,6 @@ bool Public::IsLua(const std::string &name)
#endif
}
bool Public::IsPAWN(const std::string &name)
{
#if !defined(ENABLE_PAWN)
return false;
#else
auto it = publics.find(name);
if (it == publics.end())
throw runtime_error("Public with name \"" + name + "\" does not exist");
return it->second->script_type == SCRIPT_PAWN;
#endif
}
void Public::DeleteAll()
{
for (auto it = publics.begin(); it != publics.end(); it++)

@ -17,9 +17,6 @@ private:
static std::unordered_map<std::string, Public *> publics;
Public(ScriptFunc _public, const std::string &name, char ret_type, const std::string &def);
#if defined(ENABLE_PAWN)
Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def);
#endif
#if defined(ENABLE_LUA)
Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, char ret_type, const std::string &def);
#endif
@ -33,7 +30,6 @@ public:
static const std::string& GetDefinition(const std::string& name);
static bool IsPAWN(const std::string &name);
static bool IsLua(const std::string &name);
static void DeleteAll();

@ -17,14 +17,6 @@ Timer::Timer(ScriptFunc callback, long msec, const std::string& def, std::vector
end = true;
}
#if defined(ENABLE_PAWN)
Timer::Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string &def, std::vector<boost::any> args): ScriptFunction(callback, amx, 'v', def)
{
targetMsec = msec;
this->args = args;
end = true;
}
#endif
#if defined(ENABLE_LUA)
Timer::Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args): ScriptFunction(callback, lua, 'v', def)
{
@ -77,30 +69,6 @@ void Timer::Start()
int TimerAPI::pointer = 0;
std::unordered_map<int, Timer* > TimerAPI::timers;
#if defined(ENABLE_PAWN)
int TimerAPI::CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const string& def, std::vector<boost::any> args)
{
int id = -1;
for (auto timer : timers)
{
if (timer.second != nullptr)
continue;
timer.second = new Timer(amx, callback, msec, def, args);
id = timer.first;
}
if (id == -1)
{
timers[pointer] = new Timer(amx, callback, msec, def, args);
id = pointer;
pointer++;
}
return id;
}
#endif
#if defined(ENABLE_LUA)
int TimerAPI::CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args)
{

@ -22,9 +22,6 @@ namespace mwmp
public:
Timer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args);
#if defined(ENABLE_PAWN)
Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
#endif
#if defined(ENABLE_LUA)
Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
#endif
@ -45,9 +42,6 @@ namespace mwmp
class TimerAPI
{
public:
#if defined(ENABLE_PAWN)
static int CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
#endif
#if defined(ENABLE_LUA)
static int CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
#endif

@ -4,6 +4,7 @@
#include <apps/openmw-mp/Networking.hpp>
#include <apps/openmw-mp/Player.hpp>
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
#include <fstream>
#include "Worldstate.hpp"

@ -1,458 +0,0 @@
//
// Created by koncord on 08.05.16.
//
#include "LangPAWN.hpp"
#include <amxmodules.h>
#include <amxaux.h>
#include "Script.hpp"
using namespace std;
typedef long NetworkID;
static vector<vector<char>> strings;
static vector<pair<cell*, double>> floats;
static pair<cell*, NetworkID*> data = {nullptr, nullptr};
void free_strings() noexcept {
strings.clear();
}
void free_floats() noexcept {
for (const auto& value : floats)
*value.first = amx_ftoc(value.second);
floats.clear();
}
void free_data(unsigned int size) noexcept {
if (data.first && data.second)
for (unsigned int i = 0; i < size; ++i)
data.first[i] = data.second[i];
data.first = nullptr;
data.second = nullptr;
}
void after_call() noexcept {
free_strings();
free_floats();
}
template<typename R>
void after_call(const R&) noexcept {
free_strings();
free_floats();
}
template<>
void after_call(const unsigned int& result) noexcept {
free_strings();
free_floats();
free_data(result);
}
template<typename R, unsigned int I, unsigned int F>
struct PAWN_extract_ {
inline static R PAWN_extract(AMX*&&, const cell*&& params) noexcept {
return static_cast<R>(forward<const cell*>(params)[I]);
}
};
template<unsigned int I, unsigned int F>
struct PAWN_extract_<void*, I, F>
{
inline static void* PAWN_extract(AMX *&&amx, const cell *&&params) noexcept
{
return amx_Address(amx, forward<const cell *>(params)[I]); // fixme: I'm not sure in this fix
}
};
template<unsigned int I, unsigned int F>
struct PAWN_extract_<double, I, F> {
inline static double PAWN_extract(AMX*&&, const cell*&& params) noexcept {
return amx_ctof(forward<const cell*>(params)[I]);
}
};
template<unsigned int I, unsigned int F>
struct PAWN_extract_<const char*, I, F> {
inline static const char* PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
int len;
cell* source;
source = amx_Address(amx, params[I]);
amx_StrLen(source, &len);
strings.emplace_back(len + 1);
char* value = &strings.back()[0];
amx_GetString(value, source, 0, UNLIMITED);
return value;
}
};
template<unsigned int I, unsigned int F>
struct PAWN_extract_<double*, I, F> {
inline static double* PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
floats.emplace_back(amx_Address(amx, params[I]), 0.00);
return &floats.back().second;
}
};
template<unsigned int I, unsigned int F>
struct PAWN_extract_<NetworkID**, I, F> {
inline static NetworkID** PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
static_assert(F_.func.numargs == I, "NetworkID** must be the last parameter");
data.first = amx_Address(amx, params[I]);
return &data.second;
}
};
template<unsigned int I, unsigned int F>
struct PAWN_dispatch_ {
template<typename R, typename... Args>
inline static R PAWN_dispatch(AMX*&& amx, const cell*&& params, Args&&... args) noexcept {
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
auto arg = PAWN_extract_<typename CharType<F_.func.types[I - 1]>::type, I, F>::PAWN_extract(forward<AMX*>(amx), forward<const cell*>(params));
return PAWN_dispatch_<I - 1, F>::template PAWN_dispatch<R>(
forward<AMX*>(amx),
forward<const cell*>(params),
arg,
forward<Args>(args)...);
}
};
template<unsigned int F>
struct PAWN_dispatch_<0, F> {
template<typename R, typename... Args>
inline static R PAWN_dispatch(AMX*&&, const cell*&&, Args&&... args) noexcept {
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
return reinterpret_cast<FunctionEllipsis<R>>(F_.func.addr)(forward<Args>(args)...);
}
};
template<unsigned int I>
static typename enable_if<ScriptFunctions::functions[I].func.ret == 'v', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<void>(forward<AMX*>(amx), forward<const cell*>(params));
after_call();
return 1;
}
template<unsigned int I>
static typename enable_if<ScriptFunctions::functions[I].func.ret == 'f', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
double value = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<double>(forward<AMX*>(amx), forward<const cell*>(params));
after_call();
return amx_ftoc(value);
}
template<unsigned int I>
static typename enable_if<ScriptFunctions::functions[I].func.ret == 's', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
const char* value = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<const char*>(forward<AMX*>(amx), forward<const cell*>(params));
after_call();
if (value) {
cell* dest = amx_Address(amx, params[ScriptFunctions::functions[I].func.numargs + 1]);
amx_SetString(dest, value, 1, 0, strlen(value) + 1);
return 1;
}
return 0;
}
template<unsigned int I>
static typename enable_if<ScriptFunctions::functions[I].func.ret != 'v' && ScriptFunctions::functions[I].func.ret != 'f' && ScriptFunctions::functions[I].func.ret != 's', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
auto result = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<typename CharType<ScriptFunctions::functions[I].func.ret>::type>(forward<AMX*>(amx), forward<const cell*>(params));
after_call(result);
return result;
}
template<unsigned int I> struct F_ { static constexpr AMX_NATIVE_INFO F{ScriptFunctions::functions[I].name, wrapper<I>}; };
template<> struct F_<0> { static constexpr AMX_NATIVE_INFO F{"CreateTimer", LangPAWN::CreateTimer}; };
template<> struct F_<1> { static constexpr AMX_NATIVE_INFO F{"CreateTimerEx", LangPAWN::CreateTimerEx}; };
template<> struct F_<2> { static constexpr AMX_NATIVE_INFO F{"MakePublic", LangPAWN::MakePublic}; };
template<> struct F_<3> { static constexpr AMX_NATIVE_INFO F{"CallPublic", LangPAWN::CallPublic}; };
void LangPAWN::LoadProgram(const char *filename)
{
int err = aux_LoadProgram(amx, filename, 0);
if (err != AMX_ERR_NONE)
throw runtime_error("PAWN script " + string(filename) + " error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\"");
amx_CoreInit(amx);
amx_ConsoleInit(amx);
amx_FloatInit(amx);
amx_TimeInit(amx);
amx_StringInit(amx);
amx_FileInit(amx);
constexpr auto functions_n = sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]);
amx_Register(amx, functions(IndicesFor<functions_n>{}), functions_n); // TODO: throw if error
}
int LangPAWN::FreeProgram()
{
int err = aux_FreeProgram(amx);
delete amx;
return err;
}
bool LangPAWN::IsCallbackPresent(const char *name)
{
int idx;
return (amx_FindPublic(amx, name, &idx) == AMX_ERR_NONE);
}
boost::any LangPAWN::Call(const char *name, const char *argl, int buf, ...)
{
va_list args;
va_start(args, buf);
cell ret = 0;
vector<pair<cell *, char *>> strings;
try
{
int idx = 0;
int err = 0;
err = amx_FindPublic(amx, name, &idx);
if (err != AMX_ERR_NONE)
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
unsigned int len = strlen(argl);
vector<cell> args_amx;
for (unsigned int i = 0; i < len; ++i)
{
switch (argl[i])
{
case 'i':
args_amx.emplace_back(va_arg(args, unsigned
int));
break;
case 'q':
args_amx.emplace_back(va_arg(args, signed
int));
break;
case 'l':
args_amx.emplace_back(va_arg(args, unsigned
long
long));
break;
case 'w':
args_amx.emplace_back(va_arg(args, signed
long
long));
break;
case 'f':
{
double value = va_arg(args, double);
args_amx.emplace_back(amx_ftoc(value));
break;
}
case 'p':
args_amx.emplace_back(reinterpret_cast<uintptr_t>(va_arg(args, void*)));
break;
case 's':
args_amx.emplace_back(reinterpret_cast<uintptr_t>(va_arg(args, char*)));
break;
default:
throw runtime_error("PAWN call: Unknown argument identifier " + argl[i]);
}
}
for (unsigned int i = len; i; --i)
{
switch (argl[i - 1])
{
case 's':
{
char *string = reinterpret_cast<char *>(static_cast<unsigned int>(args_amx[i - 1]));
cell *store;
amx_PushString(amx, &store, string, 1, 0);
strings.emplace_back(store, string);
break;
}
default:
amx_Push(amx, args_amx[i - 1]);
break;
}
}
err = amx_Exec(amx, &ret, idx);
if (err != AMX_ERR_NONE)
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
if (buf != 0)
for (const auto &str : strings)
amx_GetString(str.second, str.first, 0, strlen(str.second) + 1);
if (!strings.empty())
amx_Release(amx, strings[0].first);
}
catch (...)
{
va_end(args);
if (!strings.empty())
amx_Release(amx, strings[0].first);
throw;
}
return boost::any(ret);
}
boost::any LangPAWN::Call(const char *name, const char *argl, const std::vector<boost::any> &args)
{
cell ret = 0;
cell *str = nullptr;
try
{
int idx = 0;
int err = 0;
err = amx_FindPublic(amx, name, &idx);
if (err != AMX_ERR_NONE)
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
for (intptr_t i = strlen(argl) - 1; i >= 0; i--)
{
switch (argl[i])
{
case 'i':
{
cell value = (cell) boost::any_cast<unsigned int>(args.at(i));
amx_Push(amx, value);
break;
}
case 'q':
{
cell value = (cell) boost::any_cast<signed int>(args.at(i));
amx_Push(amx, value);
break;
}
case 'l':
{
cell value = (cell) boost::any_cast<unsigned long long>(args.at(i));
amx_Push(amx, value);
break;
}
case 'w':
{
cell value = (cell) boost::any_cast<signed long long>(args.at(i));
amx_Push(amx, value);
break;
}
case 'f':
{
double value = boost::any_cast<double>(args.at(i));
amx_Push(amx, amx_ftoc(value));
break;
}
case 'p':
{
cell value = (cell) boost::any_cast<void *>(args.at(i));
amx_Push(amx, value);
break;
}
case 's':
{
string string_ = boost::any_cast<string>(args.at(i));
cell *store;
amx_PushString(amx, &store, string_.c_str(), 1, 0);
if (!str)
str = store;
break;
}
default:
throw runtime_error("PAWN call: Unknown argument identifier " + argl[i]);
}
}
err = amx_Exec(amx, &ret, idx);
if (err != AMX_ERR_NONE)
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
if (str)
amx_Release(amx, str);
}
catch (...)
{
if (str)
amx_Release(amx, str);
throw;
}
return ret;
}
template<size_t... Indices>
inline AMX_NATIVE_INFO *LangPAWN::functions(indices<Indices...>)
{
static AMX_NATIVE_INFO functions_[sizeof...(Indices)]{
F_<Indices>::F...
};
static_assert(
sizeof(functions_) / sizeof(functions_[0]) == sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]),
"Not all functions have been mapped to PAWN");
return functions_;
}
lib_t LangPAWN::GetInterface()
{
return reinterpret_cast<lib_t>(amx);
}
LangPAWN::LangPAWN()
{
//throw std::runtime_error("Pawn is no longer supported, use Terra/Lua!");
amx = new AMX();
}
LangPAWN::LangPAWN(AMX *amx)
{
this->amx = amx;
}
LangPAWN::~LangPAWN()
{
}

@ -1,46 +0,0 @@
//
// Created by koncord on 08.05.16.
//
#ifndef PLUGINSYSTEM3_LANGPAWN_HPP
#define PLUGINSYSTEM3_LANGPAWN_HPP
#include "Language.hpp"
#include <amx.h>
class LangPAWN: public Language
{
private:
template<std::size_t... Is>
struct indices {};
template<std::size_t N, std::size_t... Is>
struct build_indices : build_indices<N-1, N-1, Is...> {};
template<std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};
template<std::size_t N>
using IndicesFor = build_indices<N>;
public:
virtual lib_t GetInterface() override;
template<std::size_t... Indices>
static AMX_NATIVE_INFO* functions(indices<Indices...>);
AMX *amx;
public:
LangPAWN();
LangPAWN(AMX *amx);
~LangPAWN();
static cell MakePublic(AMX *amx, const cell *params) noexcept;
static cell CallPublic(AMX *amx, const cell *params) noexcept;
static cell CreateTimer(AMX *amx, const cell *params) noexcept;
static cell CreateTimerEx(AMX *amx, const cell *params) noexcept;
virtual void LoadProgram(const char *filename) override;
virtual int FreeProgram() override;
virtual bool IsCallbackPresent(const char *name) override;
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
};
#endif //PLUGINSYSTEM3_LANGPAWN_HPP

@ -1,154 +0,0 @@
//
// Created by koncord on 09.05.16.
//
#include <API/PublicFnAPI.hpp>
#include "LangPAWN.hpp"
#include "API/TimerAPI.hpp"
using namespace std;
cell LangPAWN::MakePublic(AMX *amx, const cell *params) noexcept
{
int len;
cell* source;
source = amx_Address(amx, params[1]);
amx_StrLen(source, &len);
vector<char> real;
real.reserve(len + 1);
amx_GetString(&real[0], source, 0, UNLIMITED);
source = amx_Address(amx, params[2]);
amx_StrLen(source, &len);
vector<char> name;
name.reserve(len + 1);
amx_GetString(&name[0], source, 0, UNLIMITED);
cell *ret_addr = amx_Address(amx, params[3]);
char ret_type = static_cast<char>(*reinterpret_cast<cell*>(&ret_addr));
source = amx_Address(amx, params[4]);
amx_StrLen(source, &len);
vector<char> def;
def.reserve(len + 1);
amx_GetString(&def[0], source, 0, UNLIMITED);
Public::MakePublic(&real[0], amx, &name[0], ret_type, &def[0]);
return 1;
}
cell LangPAWN::CallPublic(AMX *amx, const cell *params) noexcept
{
int len;
cell* source;
source = amx_Address(amx, params[1]);
amx_StrLen(source, &len);
vector<char> name;
name.reserve(len + 1);
amx_GetString(&name[0], source, 0, UNLIMITED);
string def;
try
{
def = Public::GetDefinition(&name[0]);
}
catch (...) { return 0; }
vector<boost::any> args;
unsigned int count = (params[0] / sizeof(cell)) - 1;
if (count != def.length())
throw runtime_error("Script call: Number of arguments does not match definition");
for (unsigned int i = 0; i < count; ++i)
{
cell* data = amx_Address(amx, params[i + 2]);
switch (def[i])
{
case 'i':
{
args.emplace_back((unsigned int) *data);
break;
}
case 'q':
{
args.emplace_back((signed int) *data);
break;
}
case 'l':
{
args.emplace_back((unsigned long long) *data);
break;
}
case 'w':
{
args.emplace_back((signed long long) *data);
break;
}
case 'f':
{
args.emplace_back((double) amx_ctof(*data));
break;
}
case 'p':
{
args.emplace_back((void*) data);
break;
}
case 's':
{
amx_StrLen(data, &len);
vector<char> str;
str.reserve(len + 1);
amx_GetString(&str[0], data, 0, UNLIMITED);
args.emplace_back(string(&str[0]).c_str());
break;
}
default:
throw runtime_error("PAWN call: Unknown argument identifier " + def[i]);
}
}
boost::any result = Public::Call(&name[0], args);
if (result.empty())
return 0;
cell ret = 0;
if (result.type().hash_code() == typeid(signed int).hash_code())
ret = boost::any_cast<signed int>(result);
else if (result.type().hash_code() == typeid(unsigned int).hash_code())
ret = boost::any_cast<unsigned int>(result);
else if (result.type().hash_code() == typeid(double).hash_code())
ret = amx_ftoc(result);
return ret;
}
cell LangPAWN::CreateTimer(AMX *amx, const cell *params) noexcept
{
}
cell LangPAWN::CreateTimerEx(AMX *amx, const cell *params) noexcept
{
}

@ -5,9 +5,6 @@
#include "Script.hpp"
#include "LangNative/LangNative.hpp"
#if defined (ENABLE_PAWN)
#include "LangPawn/LangPAWN.hpp"
#endif
#if defined (ENABLE_LUA)
#include "LangLua/LangLua.hpp"
#endif
@ -34,13 +31,6 @@ Script::Script(const char *path)
script_type = SCRIPT_CPP;
lang = new LangNative();
}
#if defined (ENABLE_PAWN)
else if (strstr(path, ".amx"))
{
lang = new LangPAWN();
script_type = SCRIPT_PAWN;
}
#endif
#if defined (ENABLE_LUA)
else if (strstr(path, ".lua") || strstr(path, ".t"))
{

@ -24,7 +24,6 @@ private:
enum
{
SCRIPT_CPP,
SCRIPT_PAWN,
SCRIPT_LUA
};
@ -93,13 +92,6 @@ public:
if (script->script_type == SCRIPT_CPP)
result = reinterpret_cast<FunctionEllipsis<CallBackReturn<I>>>(callback)(std::forward<Args>(args)...);
#if defined (ENABLE_PAWN)
else if (script->script_type == SCRIPT_PAWN)
{
boost::any any = script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
result = reinterpret_cast<CallBackReturn<I>> ((int)boost::any_cast<int64_t>(any)); // TODO: WTF?! int?!
}
#endif
#if defined (ENABLE_LUA)
else if (script->script_type == SCRIPT_LUA)
{
@ -133,10 +125,6 @@ public:
if (script->script_type == SCRIPT_CPP)
reinterpret_cast<FunctionEllipsis<CallBackReturn<I>>>(callback)(std::forward<Args>(args)...);
#if defined (ENABLE_PAWN)
else if (script->script_type == SCRIPT_PAWN)
script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
#endif
#if defined (ENABLE_LUA)
else if (script->script_type == SCRIPT_LUA)
script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);

@ -14,10 +14,6 @@
#include "LangLua/LangLua.hpp"
#endif
#if defined (ENABLE_PAWN)
#include "LangPawn/LangPAWN.hpp"
#endif
using namespace std;
ScriptFunction::ScriptFunction(ScriptFunc fCpp,char ret_type, const string &def) :
@ -33,24 +29,9 @@ ScriptFunction::ScriptFunction(const ScriptFuncLua &fLua, lua_State *lua, char r
}
#endif
#if defined (ENABLE_PAWN)
ScriptFunction::ScriptFunction(const ScriptFuncPAWN &fPawn, AMX *amx, char ret_type, const string &def) :
fPawn({amx, fPawn}), def(def), ret_type(ret_type), script_type(SCRIPT_PAWN)
{
}
#endif
ScriptFunction::~ScriptFunction()
{
#if defined (ENABLE_PAWN)
if (script_type == SCRIPT_PAWN)
fPawn.name.~ScriptFuncPAWN();
#if defined (ENABLE_LUA)
else
#endif
#endif
#if defined (ENABLE_LUA)
if (script_type == SCRIPT_LUA)
fLua.name.~ScriptFuncLua();
@ -63,37 +44,6 @@ boost::any ScriptFunction::Call(const vector<boost::any> &args)
if (def.length() != args.size())
throw runtime_error("Script call: Number of arguments does not match definition");
#if defined (ENABLE_PAWN)
if (script_type == SCRIPT_PAWN)
{
LangPAWN langPawn(fPawn.amx);
boost::any any = langPawn.Call(fPawn.name.c_str(), def.c_str(), args);
result = boost::any();
cell ret = boost::any_cast<cell>(any);
switch (ret_type)
{
case 'i':
result = static_cast<unsigned int>(ret);
break;
case 'q':
result = static_cast<signed int>(ret);
break;
case 's':
throw runtime_error("Pawn call: the Pawn does not supported strings in public functions");
case 'f':
result = static_cast<double>(amx_ctof(ret));
break;
case 'v':
result = boost::any();
break;
default:
throw runtime_error("Pawn call: Unknown return type" + ret_type);
}
}
#endif
#if defined (ENABLE_LUA)
else if (script_type == SCRIPT_LUA)
{

@ -12,14 +12,7 @@
#include "LangLua/LangLua.hpp"
#endif
#if defined (ENABLE_PAWN)
#include <amx.h>
#endif
typedef unsigned long long(*ScriptFunc)();
#if defined (ENABLE_PAWN)
typedef std::string ScriptFuncPAWN;
#endif
#if defined (ENABLE_LUA)
typedef std::string ScriptFuncLua;
#endif
@ -30,13 +23,6 @@ protected:
union
{
ScriptFunc fCpp;
#if defined (ENABLE_PAWN)
struct
{
AMX *amx;
ScriptFuncPAWN name;
} fPawn;
#endif
#if defined (ENABLE_LUA)
struct
{
@ -53,16 +39,12 @@ protected:
enum
{
SCRIPT_CPP,
SCRIPT_PAWN,
SCRIPT_LUA
};
ScriptFunction(ScriptFunc fCpp, char ret_type, const std::string &def);
#if defined (ENABLE_LUA)
ScriptFunction(const ScriptFuncLua &fPawn, lua_State *lua, char ret_type, const std::string &def);
#endif
#if defined (ENABLE_PAWN)
ScriptFunction(const ScriptFuncPAWN &fPawn, AMX *amx, char ret_type, const std::string &def);
#endif
virtual ~ScriptFunction();

@ -24,7 +24,6 @@
#include <Script/Functions/Stats.hpp>
#include <Script/Functions/Worldstate.hpp>
#include <RakNetTypes.h>
//#include <amx/amx.h>
#include <tuple>
#include <apps/openmw-mp/Player.hpp>
#include "ScriptFunction.hpp"

@ -1,23 +0,0 @@
include_directories(./linux)
add_definitions(-DPAWN_CELL_SIZE=64)
set(source_amx
amxexec_gcc.c
amxfile.c
fpattern.c
minIni.c
amxcons.c
amxcore.c
amxstring.c
amxtime.c
amxfloat.c
amxaux.c
amx.c
linux/binreloc.c
linux/getch.c
)
source_group(amx FILES ${source_amx})
add_library(amx STATIC ${source_amx} )

File diff suppressed because it is too large Load Diff

@ -1,545 +0,0 @@
/* Pawn Abstract Machine (for the Pawn language)
*
* Copyright (c) ITB CompuPhase, 1997-2015
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: amx.h 5181 2015-01-21 09:44:28Z thiadmer $
*/
#ifndef AMX_H_INCLUDED
#define AMX_H_INCLUDED
#include <stdlib.h> /* for size_t */
#include <limits.h>
#if (defined __linux || defined __linux__) && !defined __LINUX__
#define __LINUX__
#endif
#if defined FREEBSD && !defined __FreeBSD__
#define __FreeBSD__
#endif
#if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
#include <sclinux.h>
#endif
#if defined __GNUC__
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#endif
#if !defined HAVE_STDINT_H
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) \
|| defined __GNUC__ || defined __LCC__ || defined __DMC__ \
|| (defined __WATCOMC__ && __WATCOMC__ >= 1200)
#define HAVE_STDINT_H 1
#endif
#endif
#if !defined HAVE_INTTYPES_H
#if defined __FreeBSD__ || defined __APPLE__
#define HAVE_INTTYPES_H 1
#endif
#endif
#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#if defined __MACH__
#include <ppc/types.h>
#endif
typedef short int int16_t;
typedef unsigned short int uint16_t;
#if defined SN_TARGET_PS2
typedef int int32_t;
typedef unsigned int uint32_t;
#else
typedef long int int32_t;
typedef unsigned long int uint32_t;
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#define HAVE_I64
#endif
#if !defined _INTPTR_T_DEFINED
#if defined _LP64 || defined WIN64 || defined _WIN64
typedef __int64 intptr_t;
#else
typedef int32_t intptr_t;
#endif
#endif
#endif
#if defined _LP64 || defined WIN64 || defined _WIN64
#if !defined __64BIT__
#define __64BIT__
#endif
#endif
#if !defined HAVE_ALLOCA_H
#if defined __GNUC__ || defined __LCC__ || defined __DMC__ || defined __ARMCC_VERSION
#define HAVE_ALLOCA_H 1
#elif defined __WATCOMC__ && __WATCOMC__ >= 1200
#define HAVE_ALLOCA_H 1
#endif
#endif
#if defined HAVE_ALLOCA_H && HAVE_ALLOCA_H
#include <alloca.h>
#elif defined __BORLANDC__
#include <malloc.h>
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
#if !defined alloca
#define alloca(n) _alloca(n)
#endif
#endif
#if !defined assert_static
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112) || GCC_VERSION >= 40600
#define assert_static(test) _Static_assert(test, "assert")
#else
/* see "Compile-Time Assertions" by Greg Miller,
* (with modifications to port it to C)
*/
#define _ASSERT_STATIC_SYMBOL_INNER(line) __ASSERT_STATIC_ ## line
#define _ASSERT_STATIC_SYMBOL(line) _ASSERT_STATIC_SYMBOL_INNER(line)
#define assert_static(test) \
do { \
typedef char _ASSERT_STATIC_SYMBOL(__LINE__)[ ((test) ? 1 : -1) ]; \
} while (0)
#endif
#endif
#if defined __cplusplus
extern "C" {
#endif
#if defined PAWN_DLL
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL __stdcall
#endif
#if !defined AMXAPI
#define AMXAPI __stdcall
#endif
#if !defined AMXEXPORT
#define AMXEXPORT __declspec(dllexport)
#endif
#endif
/* calling convention for native functions */
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL
#endif
/* calling convention for all interface functions and callback functions */
#if !defined AMXAPI
#if defined STDECL
#define AMXAPI __stdcall
#elif defined CDECL
#define AMXAPI __cdecl
#elif defined GCC_HASCLASSVISIBILITY
#define AMXAPI __attribute__((visibility("default")))
#else
#define AMXAPI
#endif
#endif
#if !defined AMXEXPORT
#define AMXEXPORT
#endif
/* File format version (in CUR_FILE_VERSION)
* 0 original version
* 1 opcodes JUMP.pri, SWITCH and CASETBL
* 2 compressed files
* 3 public variables
* 4 opcodes SWAP.pri/alt and PUSHADDR
* 5 tagnames table
* 6 reformatted header
* 7 name table, opcodes SYMTAG & SYSREQ.D
* 8 opcode BREAK, renewed debug interface
* 9 macro opcodes
* 10 position-independent code, overlays, packed instructions
* 11 relocating instructions for the native interface, reorganized instruction set
* MIN_FILE_VERSION is the lowest file version number that the current AMX
* implementation supports. If the AMX file header gets new fields, this number
* often needs to be incremented. MIN_AMX_VERSION is the lowest AMX version that
* is needed to support the current file version. When there are new opcodes,
* this number needs to be incremented.
* The file version supported by the JIT may run behind MIN_AMX_VERSION. So
* there is an extra constant for it: MAX_FILE_VER_JIT.
*/
#define CUR_FILE_VERSION 11 /* current file version; also the current AMX version */
#define MIN_FILE_VERSION 11 /* lowest supported file format version for the current AMX version */
#define MIN_AMX_VERSION 11 /* minimum AMX version needed to support the current file format */
#define MAX_FILE_VER_JIT 11 /* file version supported by the JIT */
#define MIN_AMX_VER_JIT 11 /* AMX version supported by the JIT */
#if !defined PAWN_CELL_SIZE
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
#endif
#if PAWN_CELL_SIZE==16
typedef uint16_t ucell;
typedef int16_t cell;
#elif PAWN_CELL_SIZE==32
typedef uint32_t ucell;
typedef int32_t cell;
#elif PAWN_CELL_SIZE==64
typedef uint64_t ucell;
typedef int64_t cell;
#define HAVE_I64
#else
#error Unsupported cell size (PAWN_CELL_SIZE)
#endif
#define UNPACKEDMAX (((cell)1 << (sizeof(cell)-1)*8) - 1)
#define UNLIMITED (~1u >> 1)
struct tagAMX;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, const cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
cell *result, const cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
typedef int (AMXAPI *AMX_OVERLAY)(struct tagAMX *amx, int index);
typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX *, cell *, int));
#if !defined _FAR
#define _FAR
#endif
#if defined _MSC_VER
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */
#pragma warning(disable:4127) /* "conditional expression is constant" (needed for static_assert) */
#pragma warning(disable:4996) /* POSIX name is deprecated */
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
#define AMX_NO_ALIGN
#endif
#if defined __GNUC__
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif
#if !defined AMX_NO_ALIGN
#if defined __LINUX__ || defined __FreeBSD__ || defined __APPLE__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#if defined __TURBOC__
#pragma option -a- /* "pack" pragma for older Borland compilers */
#endif
#endif
#endif
typedef struct tagAMX_NATIVE_INFO {
const char _FAR *name;
AMX_NATIVE func;
} PACKED AMX_NATIVE_INFO;
#if !defined AMX_USERNUM
#define AMX_USERNUM 4
#endif
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
#define sNAMEMAX 31 /* maximum name length of symbol name */
typedef struct tagFUNCSTUB {
uint32_t address;
uint32_t nameofs;
} PACKED AMX_FUNCSTUB;
typedef struct tagOVERLAYINFO {
int32_t offset; /* offset relative to the start of the code block */
int32_t size; /* size in bytes */
} PACKED AMX_OVERLAYINFO;
/* The AMX structure is the internal structure for many functions. Not all
* fields are valid at all times; many fields are cached in local variables.
*/
typedef struct tagAMX {
unsigned char _FAR *base; /* points to the AMX header, perhaps followed by P-code and data */
unsigned char _FAR *code; /* points to P-code block, possibly in ROM or in an overlay pool */
unsigned char _FAR *data; /* points to separate data+stack+heap, may be NULL */
AMX_CALLBACK callback; /* native function callback */
AMX_DEBUG debug; /* debug callback */
AMX_OVERLAY overlay; /* overlay reader callback */
/* for external functions a few registers must be accessible from the outside */
cell cip; /* instruction pointer: relative to base + amxhdr->cod */
cell frm; /* stack frame base: relative to base + amxhdr->dat */
cell hea; /* top of the heap: relative to base + amxhdr->dat */
cell hlw; /* bottom of the heap: relative to base + amxhdr->dat */
cell stk; /* stack pointer: relative to base + amxhdr->dat */
cell stp; /* top of the stack: relative to base + amxhdr->dat */
int flags; /* current status, see amx_Flags() */
/* user data */
#if AMX_USERNUM > 0
long usertags[AMX_USERNUM];
void _FAR *userdata[AMX_USERNUM];
#endif
/* native functions can raise an error */
int error;
/* passing parameters requires a "count" field */
int paramcount;
/* the sleep opcode needs to store the full AMX status */
cell pri;
cell alt;
cell reset_stk;
cell reset_hea;
/* extra fields for increased performance */
cell sysreq_d; /* relocated address/value for the SYSREQ.D opcode */
/* fields for overlay support and JIT support */
int ovl_index; /* current overlay index */
long codesize; /* size of the overlay, or estimated memory footprint of the native code */
#if defined AMX_JIT
/* support variables for the JIT */
int reloc_size; /* required temporary buffer for relocations */
#endif
} PACKED AMX;
/* The AMX_HEADER structure is both the memory format as the file format. The
* structure is used internaly.
*/
typedef struct tagAMX_HEADER {
int32_t size; /* size of the "file" */
uint16_t magic; /* signature */
char file_version; /* file format version */
char amx_version; /* required version of the AMX */
int16_t flags;
int16_t defsize; /* size of a definition record */
int32_t cod; /* initial value of COD - code block */
int32_t dat; /* initial value of DAT - data block */
int32_t hea; /* initial value of HEA - start of the heap */
int32_t stp; /* initial value of STP - stack top */
int32_t cip; /* initial value of CIP - the instruction pointer */
int32_t publics; /* offset to the "public functions" table */
int32_t natives; /* offset to the "native functions" table */
int32_t libraries; /* offset to the table of libraries */
int32_t pubvars; /* offset to the "public variables" table */
int32_t tags; /* offset to the "public tagnames" table */
int32_t nametable; /* offset to the name table */
int32_t overlays; /* offset to the overlay table */
} PACKED AMX_HEADER;
#define AMX_MAGIC_16 0xf1e2
#define AMX_MAGIC_32 0xf1e0
#define AMX_MAGIC_64 0xf1e1
#if PAWN_CELL_SIZE==16
#define AMX_MAGIC AMX_MAGIC_16
#elif PAWN_CELL_SIZE==32
#define AMX_MAGIC AMX_MAGIC_32
#elif PAWN_CELL_SIZE==64
#define AMX_MAGIC AMX_MAGIC_64
#endif
enum {
AMX_ERR_NONE,
/* reserve the first 15 error codes for exit codes of the abstract machine */
AMX_ERR_EXIT, /* forced exit */
AMX_ERR_ASSERT, /* assertion failed */
AMX_ERR_STACKERR, /* stack/heap collision */
AMX_ERR_BOUNDS, /* index out of bounds */
AMX_ERR_MEMACCESS, /* invalid memory access */
AMX_ERR_INVINSTR, /* invalid instruction */
AMX_ERR_STACKLOW, /* stack underflow */
AMX_ERR_HEAPLOW, /* heap underflow */
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
AMX_ERR_NATIVE, /* native function failed */
AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_INVSTATE, /* no implementation for this state, no fall-back */
AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
AMX_ERR_NOTFOUND, /* function not found */
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
AMX_ERR_DEBUG, /* debugger cannot run */
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
AMX_ERR_PARAMS, /* parameter error */
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
AMX_ERR_OVERLAY, /* overlays are unsupported (JIT) or uninitialized */
};
#define AMX_FLAG_OVERLAY 0x01 /* all function calls use overlays */
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
#define AMX_FLAG_NOCHECKS 0x04 /* no array bounds checking; no BREAK opcodes */
#define AMX_FLAG_SLEEP 0x08 /* script uses the sleep instruction (possible re-entry or power-down mode) */
#define AMX_FLAG_CRYPT 0x10 /* file is encrypted */
#define AMX_FLAG_DSEG_INIT 0x20 /* data section is explicitly initialized */
#define AMX_FLAG_SYSREQN 0x800 /* script uses new (optimized) version of SYSREQ opcode */
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
#define AMX_FLAG_VERIFY 0x4000 /* busy verifying P-code */
#define AMX_FLAG_INIT 0x8000 /* AMX has been initialized */
#define AMX_EXEC_MAIN (-1) /* start at program entry point */
#define AMX_EXEC_CONT (-2) /* continue from last address */
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
/* for native functions that use floating point parameters, the following
* two macros are convenient for casting a "cell" into a "float" type _without_
* changing the bit pattern
*/
#if PAWN_CELL_SIZE==32
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
#elif PAWN_CELL_SIZE==64
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
#else
// amx_ftoc() and amx_ctof() cannot be used
#endif
/* when a pointer cannot be stored in a cell, cells that hold relocated
* addresses need to be expanded
*/
#if defined __64BIT__ && PAWN_CELL_SIZE<64
#define CELLMASK (((int64_t)1 << PAWN_CELL_SIZE) - 1)
#define amx_Address(amx,addr) \
(cell*)(((int64_t)((amx)->data ? (amx)->data : (amx)->code) & ~CELLMASK) | ((int64_t)(addr) & CELLMASK))
#elif defined __32BIT__ && PAWN_CELL_SIZE<32
#define CELLMASK ((1L << PAWN_CELL_SIZE) - 1)
#define amx_Address(amx,addr) \
(cell*)(((int32_t)((amx)->data ? (amx)->data : (amx)->code) & ~CELLMASK) | ((int32_t)(addr) & CELLMASK))
#else
#define amx_Address(amx,addr) ((void)(amx),(cell*)(addr))
#endif
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
/* C99: use variable-length arrays */
#define amx_StrParam_Type(amx,param,result,type) \
int result##_length_; \
amx_StrLen(amx_Address(amx,param),&result##_length_); \
char result##_vla_[(result##_length_+1)*sizeof(*(result))]; \
(result)=(type)result##_vla_; \
amx_GetString((char*)(result),amx_Address(amx,param), \
sizeof(*(result))>1,result##_length_+1)
#define amx_StrParam(amx,param,result) \
amx_StrParam_Type(amx,param,result,void*)
#else
/* macro using alloca() */
#define amx_StrParam_Type(amx,param,result,type) \
do { \
int result##_length_; \
amx_StrLen(amx_Address(amx,param),&result##_length_); \
if (result##_length_>0 && \
((result)=(type)alloca((result##_length_+1)*sizeof(*(result))))!=NULL) \
amx_GetString((char*)(result),amx_Address(amx,param), \
sizeof(*(result))>1,result##_length_+1); \
else (result) = NULL; \
} while (0)
#define amx_StrParam(amx,param,result) \
amx_StrParam_Type(amx,param,result,void*)
#endif
uint16_t * AMXAPI amx_Align16(uint16_t *v);
uint32_t * AMXAPI amx_Align32(uint32_t *v);
#if defined _I64_MAX || defined INT64_MAX || defined HAVE_I64
uint64_t * AMXAPI amx_Align64(uint64_t *v);
#endif
int AMXAPI amx_Allot(AMX *amx, int cells, cell **address);
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, const cell *params);
int AMXAPI amx_Cleanup(AMX *amx);
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
int AMXAPI amx_FindPublic(AMX *amx, const char *name, int *index);
int AMXAPI amx_FindPubVar(AMX *amx, const char *name, cell **address);
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
int AMXAPI amx_GetNative(AMX *amx, int index, char *name);
int AMXAPI amx_GetPublic(AMX *amx, int index, char *name, ucell *address);
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *name, cell **address);
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
int AMXAPI amx_Init(AMX *amx, void *program);
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
int AMXAPI amx_NameLength(AMX *amx, int *length);
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
int AMXAPI amx_NumNatives(AMX *amx, int *number);
int AMXAPI amx_NumPublics(AMX *amx, int *number);
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
int AMXAPI amx_NumTags(AMX *amx, int *number);
int AMXAPI amx_Push(AMX *amx, cell value);
int AMXAPI amx_PushAddress(AMX *amx, cell *address);
int AMXAPI amx_PushArray(AMX *amx, cell **address, const cell array[], int numcells);
int AMXAPI amx_PushString(AMX *amx, cell **address, const char *string, int pack, int use_wchar);
int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_Release(AMX *amx, cell *address);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
int AMXAPI amx_StrLen(const cell *cstring, int *length);
int AMXAPI amx_UTF8Check(const char *string, int *length);
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
#if PAWN_CELL_SIZE==16
void amx_Swap16(uint16_t *v);
#endif
#if PAWN_CELL_SIZE==32
void amx_Swap32(uint32_t *v);
#endif
#if PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined INT64_MAX || defined HAVE_I64)
void amx_Swap64(uint64_t *v);
#endif
#if PAWN_CELL_SIZE==16
#define amx_AlignCell(v) amx_Align16((uint16_t*)(v))
#define amx_SwapCell(v) amx_Swap16((uint16_t*)(v))
#elif PAWN_CELL_SIZE==32
#define amx_AlignCell(v) amx_Align32((uint32_t*)(v))
#define amx_SwapCell(v) amx_Swap32((uint32_t*)(v))
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined INT64_MAX || defined HAVE_I64)
#define amx_AlignCell(v) amx_Align64((uint64_t*)(v))
#define amx_SwapCell(v) amx_Swap64((uint64_t*)(v))
#else
#error Unsupported cell size
#endif
#define amx_RegisterFunc(amx, name, func) \
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
#if !defined AMX_NO_ALIGN
#if defined __LINUX__ || defined __FreeBSD__ || defined __APPLE__
#pragma pack() /* reset default packing */
#elif defined MACOS && defined __MWERKS__
#pragma options align=reset
#else
#pragma pack(pop) /* reset previous packing */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* AMX_H_INCLUDED */

@ -1,164 +0,0 @@
/* Support routines for the Pawn Abstract Machine
*
* Copyright (c) ITB CompuPhase, 2003-2011
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: amxaux.c 4523 2011-06-21 15:03:47Z thiadmer $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "amx.h"
#include "amxaux.h"
size_t AMXAPI aux_ProgramSize(const char *filename)
{
FILE *fp;
AMX_HEADER hdr;
if ((fp=fopen(filename,"rb")) == NULL)
return 0;
fread(&hdr, sizeof hdr, 1, fp);
fclose(fp);
amx_Align16(&hdr.magic);
amx_Align32((uint32_t *)&hdr.stp);
return (hdr.magic==AMX_MAGIC) ? (size_t)hdr.stp : 0;
}
int AMXAPI aux_LoadProgram(AMX *amx, const char *filename, void *memblock)
{
FILE *fp;
AMX_HEADER hdr;
int result, didalloc;
/* open the file, read and check the header */
if ((fp = fopen(filename, "rb")) == NULL)
return AMX_ERR_NOTFOUND;
fread(&hdr, sizeof hdr, 1, fp);
amx_Align16(&hdr.magic);
amx_Align32((uint32_t *)&hdr.size);
amx_Align32((uint32_t *)&hdr.stp);
if (hdr.magic != AMX_MAGIC) {
fclose(fp);
return AMX_ERR_FORMAT;
} /* if */
/* allocate the memblock if it is NULL */
didalloc = 0;
if (memblock == NULL) {
if ((memblock = malloc(hdr.stp)) == NULL) {
fclose(fp);
return AMX_ERR_MEMORY;
} /* if */
didalloc = 1;
/* after amx_Init(), amx->base points to the memory block */
} /* if */
/* read in the file */
rewind(fp);
fread(memblock, 1, (size_t)hdr.size, fp);
fclose(fp);
/* initialize the abstract machine */
memset(amx, 0, sizeof *amx);
result = amx_Init(amx, memblock);
/* free the memory block on error, if it was allocated here */
if (result != AMX_ERR_NONE && didalloc) {
free(memblock);
amx->base = NULL; /* avoid a double free */
} /* if */
return result;
}
int AMXAPI aux_FreeProgram(AMX *amx)
{
if (amx->base!=NULL) {
amx_Cleanup(amx);
free(amx->base);
memset(amx, 0, sizeof(AMX));
} /* if */
return AMX_ERR_NONE;
}
char * AMXAPI aux_StrError(int errnum)
{
static char *messages[] = {
/* AMX_ERR_NONE */ "(none)",
/* AMX_ERR_EXIT */ "Forced exit",
/* AMX_ERR_ASSERT */ "Assertion failed",
/* AMX_ERR_STACKERR */ "Stack/heap collision (insufficient stack size)",
/* AMX_ERR_BOUNDS */ "Array index out of bounds",
/* AMX_ERR_MEMACCESS */ "Invalid memory access",
/* AMX_ERR_INVINSTR */ "Invalid instruction",
/* AMX_ERR_STACKLOW */ "Stack underflow",
/* AMX_ERR_HEAPLOW */ "Heap underflow",
/* AMX_ERR_CALLBACK */ "No (valid) native function callback",
/* AMX_ERR_NATIVE */ "Native function failed",
/* AMX_ERR_DIVIDE */ "Divide by zero",
/* AMX_ERR_SLEEP */ "(sleep mode)",
/* AMX_ERR_INVSTATE */ "Invalid state",
/* 14 */ "(reserved)",
/* 15 */ "(reserved)",
/* AMX_ERR_MEMORY */ "Out of memory",
/* AMX_ERR_FORMAT */ "Invalid/unsupported P-code file format",
/* AMX_ERR_VERSION */ "File is for a newer version of the AMX",
/* AMX_ERR_NOTFOUND */ "File or function is not found",
/* AMX_ERR_INDEX */ "Invalid index parameter (bad entry point)",
/* AMX_ERR_DEBUG */ "Debugger cannot run",
/* AMX_ERR_INIT */ "AMX not initialized (or doubly initialized)",
/* AMX_ERR_USERDATA */ "Unable to set user data field (table full)",
/* AMX_ERR_INIT_JIT */ "Cannot initialize the JIT",
/* AMX_ERR_PARAMS */ "Parameter error",
/* AMX_ERR_DOMAIN */ "Domain error, expression result does not fit in range",
/* AMX_ERR_GENERAL */ "General error (unknown or unspecific error)",
/* AMX_ERR_OVERLAY */ "Overlays are unsupported (JIT) or uninitialized",
};
if (errnum < 0 || errnum >= sizeof messages / sizeof messages[0])
return "(unknown)";
return messages[errnum];
}
int AMXAPI aux_GetSection(const AMX *amx, int section, cell **start, size_t *size)
{
AMX_HEADER *hdr;
if (amx == NULL || start == NULL || size == NULL)
return AMX_ERR_PARAMS;
hdr = (AMX_HEADER*)amx->base;
switch(section) {
case CODE_SECTION:
*start = (cell *)(amx->base + hdr->cod);
*size = hdr->dat - hdr->cod;
break;
case DATA_SECTION:
*start = (cell *)(amx->data);
*size = hdr->hea - hdr->dat;
break;
case HEAP_SECTION:
*start = (cell *)(amx->data + hdr->hea);
*size = amx->hea - hdr->hea;
break;
case STACK_SECTION:
*start = (cell *)(amx->data + amx->stk);
*size = amx->stp - amx->stk;
break;
default:
return AMX_ERR_PARAMS;
} /* switch */
return AMX_ERR_NONE;
}

@ -1,50 +0,0 @@
/* Support routines for the Pawn Abstract Machine
*
* Copyright (c) ITB CompuPhase, 2003-2011
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: amxaux.h 4523 2011-06-21 15:03:47Z thiadmer $
*/
#ifndef AMXAUX_H_INCLUDED
#define AMXAUX_H_INCLUDED
#include "amx.h"
#ifdef __cplusplus
extern "C" {
#endif
/* loading and freeing programs */
size_t AMXAPI aux_ProgramSize(const char *filename);
int AMXAPI aux_LoadProgram(AMX *amx, const char *filename, void *memblock);
int AMXAPI aux_FreeProgram(AMX *amx);
/* a readable error message from an error code */
char * AMXAPI aux_StrError(int errnum);
enum {
CODE_SECTION,
DATA_SECTION,
HEAP_SECTION,
STACK_SECTION,
/* ----- */
NUM_SECTIONS
};
int AMXAPI aux_GetSection(const AMX *amx, int section, cell **start, size_t *size);
#ifdef __cplusplus
}
#endif
#endif /* AMXAUX_H_INCLUDED */

File diff suppressed because it is too large Load Diff

@ -1,18 +0,0 @@
#ifndef AMXCONS_H_INCLUDED
#ifndef AMXCONS_H_INCLUDED
#define AMXCONS_H_INCLUDED
typedef struct tagFMTINFO {
const cell *params;
int numparams;
int skip; /* number of characters to skip from the beginning */
int length; /* number of characters to print */
/* helper functions */
int (*f_putstr)(void *dest,const TCHAR *);
int (*f_putchar)(void *dest,TCHAR);
void *user; /* user data */
} AMX_FMTINFO;
int amx_printstring(AMX *amx,cell *cstr,AMX_FMTINFO *info);
#endif /* AMXCONS_H_INCLUDED */

@ -1,500 +0,0 @@
/* Core module for the Pawn AMX
*
* Copyright (c) ITB CompuPhase, 1997-2012
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: amxcore.c 4708 2012-05-18 12:52:49Z $
*/
#if defined _UNICODE || defined __UNICODE__ || defined UNICODE
# if !defined UNICODE /* for Windows */
# define UNICODE
# endif
# if !defined _UNICODE /* for C library */
# define _UNICODE
# endif
#endif
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include "osdefs.h"
#if defined __ECOS__
/* eCos puts include files in cyg/package_name */
#include <cyg/pawn/amx.h>
#define stricmp(a,b) strcasecmp(a,b)
#else
#include "amx.h"
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
#include <windows.h>
#endif
/* A few compilers do not provide the ANSI C standard "time" functions */
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE && !defined __ICC430__
#include <time.h>
#endif
#if defined _UNICODE
# include <tchar.h>
#elif !defined __T
typedef char TCHAR;
# define __T(string) string
# define _tcschr strchr
# define _tcscpy strcpy
# define _tcsdup strdup
# define _tcslen strlen
#endif
#define CHARBITS (8*sizeof(char))
typedef unsigned char uchar;
#if !defined AMX_NOPROPLIST
typedef struct _property_list {
struct _property_list *next;
cell id;
char *name;
cell value;
} proplist;
static proplist proproot = { NULL, 0, NULL, 0 };
static proplist *list_additem(proplist *root)
{
proplist *item;
assert(root!=NULL);
if ((item=(proplist *)malloc(sizeof(proplist)))==NULL)
return NULL;
item->name=NULL;
item->id=0;
item->value=0;
item->next=root->next;
root->next=item;
return item;
}
static void list_delete(proplist *pred,proplist *item)
{
assert(pred!=NULL);
assert(item!=NULL);
pred->next=item->next;
assert(item->name!=NULL);
free(item->name);
free(item);
}
static void list_setitem(proplist *item,cell id,char *name,cell value)
{
char *ptr;
assert(item!=NULL);
if ((ptr=(char *)malloc(strlen(name)+1))==NULL)
return;
if (item->name!=NULL)
free(item->name);
strcpy(ptr,name);
item->name=ptr;
item->id=id;
item->value=value;
}
static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
proplist **pred)
{
proplist *item=root->next;
proplist *prev=root;
/* check whether to find by name or by value */
assert(name!=NULL);
if (strlen(name)>0) {
/* find by name */
while (item!=NULL && (item->id!=id || stricmp(item->name,name)!=0)) {
prev=item;
item=item->next;
} /* while */
} else {
/* find by value */
while (item!=NULL && (item->id!=id || item->value!=value)) {
prev=item;
item=item->next;
} /* while */
} /* if */
if (pred!=NULL)
*pred=prev;
return item;
}
#endif
static cell AMX_NATIVE_CALL numargs(AMX *amx,const cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell bytes;
(void)params;
hdr=(AMX_HEADER *)amx->base;
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
/* the number of bytes is on the stack, at "frm + 2*cell" */
bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
/* the number of arguments is the number of bytes divided
* by the size of a cell */
return bytes/sizeof(cell);
}
static cell AMX_NATIVE_CALL getarg(AMX *amx,const cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell value;
hdr=(AMX_HEADER *)amx->base;
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
/* get the base value */
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
/* adjust the address in "value" in case of an array access */
value+=params[2]*sizeof(cell);
/* get the value indirectly */
value= * (cell *)(data+(int)value);
return value;
}
static cell AMX_NATIVE_CALL setarg(AMX *amx,const cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell value;
hdr=(AMX_HEADER *)amx->base;
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
/* get the base value */
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
/* adjust the address in "value" in case of an array access */
value+=params[2]*sizeof(cell);
/* verify the address */
if (value<0 || value>=amx->hea && value<amx->stk)
return 0;
/* set the value indirectly */
* (cell *)(data+(int)value) = params[3];
return 1;
}
static cell AMX_NATIVE_CALL heapspace(AMX *amx,const cell *params)
{
(void)params;
return amx->stk - amx->hea;
}
static cell AMX_NATIVE_CALL funcidx(AMX *amx,const cell *params)
{
char name[64];
cell *cstr;
int index,err;
cstr=amx_Address(amx,params[1]);
amx_GetString(name,cstr,0,sizeof name);
err=amx_FindPublic(amx,name,&index);
if (err!=AMX_ERR_NONE)
index=-1; /* this is not considered a fatal error */
return index;
}
void amx_swapcell(cell *pc)
{
union {
cell c;
#if PAWN_CELL_SIZE==16
uchar b[2];
#elif PAWN_CELL_SIZE==32
uchar b[4];
#elif PAWN_CELL_SIZE==64
uchar b[8];
#else
#error Unsupported cell size
#endif
} value;
uchar t;
assert(pc!=NULL);
value.c = *pc;
#if PAWN_CELL_SIZE==16
t = value.b[0];
value.b[0] = value.b[1];
value.b[1] = t;
#elif PAWN_CELL_SIZE==32
t = value.b[0];
value.b[0] = value.b[3];
value.b[3] = t;
t = value.b[1];
value.b[1] = value.b[2];
value.b[2] = t;
#elif PAWN_CELL_SIZE==64
t = value.b[0];
value.b[0] = value.b[7];
value.b[7] = t;
t = value.b[1];
value.b[1] = value.b[6];
value.b[6] = t;
t = value.b[2];
value.b[2] = value.b[5];
value.b[5] = t;
t = value.b[3];
value.b[3] = value.b[4];
value.b[4] = t;
#else
#error Unsupported cell size
#endif
*pc = value.c;
}
static cell AMX_NATIVE_CALL swapchars(AMX *amx,const cell *params)
{
cell c;
(void)amx;
assert((size_t)params[0]==sizeof(cell));
c=params[1];
amx_swapcell(&c);
return c;
}
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,const cell *params)
{
(void)amx;
#if defined __WIN32__ || defined _WIN32 || defined WIN32
return (cell)CharLower((LPTSTR)params[1]);
#elif defined _Windows
return (cell)AnsiLower((LPSTR)params[1]);
#else
if ((unsigned)(params[1]-'A')<26u)
return params[1]+'a'-'A';
return params[1];
#endif
}
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,const cell *params)
{
(void)amx;
#if defined __WIN32__ || defined _WIN32 || defined WIN32
return (cell)CharUpper((LPTSTR)params[1]);
#elif defined _Windows
return (cell)AnsiUpper((LPSTR)params[1]);
#else
if ((unsigned)(params[1]-'a')<26u)
return params[1]+'A'-'a';
return params[1];
#endif
}
static cell AMX_NATIVE_CALL core_min(AMX *amx,const cell *params)
{
(void)amx;
return params[1] <= params[2] ? params[1] : params[2];
}
static cell AMX_NATIVE_CALL core_max(AMX *amx,const cell *params)
{
(void)amx;
return params[1] >= params[2] ? params[1] : params[2];
}
static cell AMX_NATIVE_CALL core_clamp(AMX *amx,const cell *params)
{
cell value = params[1];
if (params[2] > params[3]) /* minimum value > maximum value ! */
amx_RaiseError(amx,AMX_ERR_NATIVE);
if (value < params[2])
value = params[2];
else if (value > params[3])
value = params[3];
return value;
}
#if !defined AMX_NOPROPLIST
static char *MakePackedString(cell *cptr)
{
int len;
char *dest;
amx_StrLen(cptr,&len);
dest=(char *)malloc(len+sizeof(cell));
amx_GetString(dest,cptr,0,len+sizeof(cell));
return dest;
}
/* getproperty(id=0, const name[]="", value=cellmin, string[]="", size=sizeof string) */
static cell AMX_NATIVE_CALL getproperty(AMX *amx,const cell *params)
{
cell *cstr;
char *name;
proplist *item;
(void)amx;
cstr=amx_Address(amx,params[2]);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
/* if list_finditem() found the value, store the name */
if (item!=NULL && item->value==params[3] && strlen(name)==0) {
cstr=amx_Address(amx,params[4]);
amx_SetString(cstr,item->name,1,0,params[5]);
} /* if */
free(name);
return (item!=NULL) ? item->value : 0;
}
/* setproperty(id=0, const name[]="", value=cellmin, const string[]="") */
static cell AMX_NATIVE_CALL setproperty(AMX *amx,const cell *params)
{
cell prev=0;
cell *cstr;
char *name;
proplist *item;
cstr=amx_Address(amx,params[2]);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
if (item==NULL)
item=list_additem(&proproot);
if (item==NULL) {
amx_RaiseError(amx,AMX_ERR_MEMORY);
} else {
prev=item->value;
if (strlen(name)==0) {
free(name);
cstr=amx_Address(amx,params[4]);
name=MakePackedString(cstr);
} /* if */
list_setitem(item,params[1],name,params[3]);
} /* if */
free(name);
return prev;
}
/* deleteproperty(id=0, const name[]="", value=cellmin) */
static cell AMX_NATIVE_CALL delproperty(AMX *amx,const cell *params)
{
cell prev=0;
cell *cstr;
char *name;
proplist *item,*pred;
(void)amx;
cstr=amx_Address(amx,params[2]);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],&pred);
if (item!=NULL) {
prev=item->value;
list_delete(pred,item);
} /* if */
free(name);
return prev;
}
/* existproperty(id=0, const name[]="", value=cellmin) */
static cell AMX_NATIVE_CALL existproperty(AMX *amx,const cell *params)
{
cell *cstr;
char *name;
proplist *item;
(void)amx;
cstr=amx_Address(amx,params[2]);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
free(name);
return (item!=NULL);
}
#endif
#if !defined AMX_NORANDOM
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
* generator" that has been extended to 31-bits (the standard C version returns
* only 15-bits).
*/
#define INITIAL_SEED 0xcaa938dbL
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
#define IL_RMULT 1103515245L
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_random(AMX *amx,const cell *params)
{
unsigned long lo, hi, ll, lh, hh, hl;
unsigned long result;
/* one-time initialization (or, mostly one-time) */
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE && !defined __ICC430__
if (IL_StandardRandom_seed == INITIAL_SEED)
IL_StandardRandom_seed=(unsigned long)time(NULL);
#endif
(void)amx;
lo = IL_StandardRandom_seed & 0xffff;
hi = IL_StandardRandom_seed >> 16;
IL_StandardRandom_seed = IL_StandardRandom_seed * IL_RMULT + 12345;
ll = lo * (IL_RMULT & 0xffff);
lh = lo * (IL_RMULT >> 16 );
hl = hi * (IL_RMULT & 0xffff);
hh = hi * (IL_RMULT >> 16 );
result = ((ll + 12345) >> 16) + lh + hl + (hh << 16);
result &= ~LONG_MIN; /* remove sign bit */
if (params[1]!=0)
result %= params[1];
return (cell)result;
}
#endif
#if defined __cplusplus
extern "C"
#endif
const AMX_NATIVE_INFO core_Natives[] = {
{ "numargs", numargs },
{ "getarg", getarg },
{ "setarg", setarg },
{ "heapspace", heapspace },
{ "funcidx", funcidx },
{ "swapchars", swapchars },
{ "tolower", core_tolower },
{ "toupper", core_toupper },
{ "min", core_min },
{ "max", core_max },
{ "clamp", core_clamp },
#if !defined AMX_NORANDOM
{ "random", core_random },
#endif
#if !defined AMX_NOPROPLIST
{ "getproperty", getproperty },
{ "setproperty", setproperty },
{ "deleteproperty",delproperty },
{ "existproperty", existproperty },
#endif
{ NULL, NULL } /* terminator */
};
int AMXEXPORT AMXAPI amx_CoreInit(AMX *amx)
{
return amx_Register(amx, core_Natives, -1);
}
int AMXEXPORT AMXAPI amx_CoreCleanup(AMX *amx)
{
(void)amx;
#if !defined AMX_NOPROPLIST
while (proproot.next!=NULL)
list_delete(&proproot,proproot.next);
#endif
return AMX_ERR_NONE;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,379 +0,0 @@
/* Float arithmetic for the Pawn Abstract Machine
*
* Copyright (c) Artran, Inc. 1999
* Written by Greg Garner (gmg@artran.com)
* This file may be freely used. No warranties of any kind.
*
* CHANGES -
* 2002-08-27: Basic conversion of source from C++ to C by Adam D. Moss
* <adam@gimp.org> <aspirin@icculus.org>
* 2003-08-29: Removal of the dynamic memory allocation and replacing two
* type conversion functions by macros, by Thiadmer Riemersma
* 2003-09-22: Moved the type conversion macros to AMX.H, and simplifications
* of some routines, by Thiadmer Riemersma
* 2003-11-24: A few more native functions (geometry), plus minor modifications,
* mostly to be compatible with dynamically loadable extension
* modules, by Thiadmer Riemersma
* 2004-01-09: Adaptions for 64-bit cells (using "double precision"), by
* Thiadmer Riemersma
*/
#include <stdlib.h> /* for atof() */
#include <stdio.h> /* for NULL */
#include <assert.h>
#include <math.h>
#include "amx.h"
/*
#if defined __BORLANDC__
#pragma resource "amxFloat.res"
#endif
*/
#if PAWN_CELL_SIZE==32
#define REAL float
#elif PAWN_CELL_SIZE==64
#define REAL double
#else
#error Unsupported cell size
#endif
#define PI 3.1415926535897932384626433832795
/******************************************************************/
static cell AMX_NATIVE_CALL n_float(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = integer value to convert to a float
*/
REAL fValue;
(void)amx;
/* Convert to a float. Calls the compilers long to float conversion. */
fValue = (REAL) params[1];
/* Return the cell. */
return amx_ftoc(fValue);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_strfloat(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = virtual string address to convert to a float
*/
char szSource[60];
cell *pString;
REAL fNum;
int nLen;
(void)amx;
/* They should have sent us 1 cell. */
assert(params[0]/sizeof(cell)==1);
/* Get the real address of the string. */
pString=amx_Address(amx,params[1]);
/* Find out how long the string is in characters. */
amx_StrLen(pString, &nLen);
if (nLen == 0 || nLen >= sizeof szSource)
return 0;
/* Now convert the Pawn string into a C type null terminated string */
amx_GetString(szSource, pString, 0, sizeof szSource);
/* Now convert this to a float. */
fNum = (REAL)atof(szSource);
return amx_ftoc(fNum);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatmul(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1
* params[2] = float operand 2
*/
REAL fRes = amx_ctof(params[1]) * amx_ctof(params[2]);
(void)amx;
return amx_ftoc(fRes);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatdiv(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float dividend (top)
* params[2] = float divisor (bottom)
*/
REAL fRes = amx_ctof(params[1]) / amx_ctof(params[2]);
(void)amx;
return amx_ftoc(fRes);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatadd(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1
* params[2] = float operand 2
*/
REAL fRes = amx_ctof(params[1]) + amx_ctof(params[2]);
(void)amx;
return amx_ftoc(fRes);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatsub(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1
* params[2] = float operand 2
*/
REAL fRes = amx_ctof(params[1]) - amx_ctof(params[2]);
(void)amx;
return amx_ftoc(fRes);
}
/******************************************************************/
/* Return fractional part of float */
static cell AMX_NATIVE_CALL n_floatfract(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand
*/
REAL fA = amx_ctof(params[1]);
fA = fA - (REAL)(floor((double)fA));
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
/* Return integer part of float, rounded */
static cell AMX_NATIVE_CALL n_floatround(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand
* params[2] = Type of rounding (integer)
*/
REAL fA = amx_ctof(params[1]);
(void)amx;
switch (params[2])
{
case 1: /* round downwards */
fA = (REAL)(floor((double)fA));
break;
case 2: /* round upwards */
fA = (REAL)(ceil((double)fA));
break;
case 3: /* round towards zero (truncate) */
if ( fA>=0.0 )
fA = (REAL)(floor((double)fA));
else
fA = (REAL)(ceil((double)fA));
break;
default: /* standard, round to nearest */
fA = (REAL)(floor((double)fA+.5));
break;
}
return (cell)fA;
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatcmp(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1
* params[2] = float operand 2
*/
REAL fA, fB;
(void)amx;
fA = amx_ctof(params[1]);
fB = amx_ctof(params[2]);
if (fA == fB)
return 0;
else if (fA>fB)
return 1;
else
return -1;
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatsqroot(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand
*/
REAL fA = amx_ctof(params[1]);
fA = (REAL)sqrt(fA);
if (fA < 0)
return amx_RaiseError(amx, AMX_ERR_DOMAIN);
return amx_ftoc(fA);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatpower(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1 (base)
* params[2] = float operand 2 (exponent)
*/
REAL fA = amx_ctof(params[1]);
REAL fB = amx_ctof(params[2]);
fA = (REAL)pow(fA, fB);
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatlog(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1 (value)
* params[2] = float operand 2 (base)
*/
REAL fValue = amx_ctof(params[1]);
REAL fBase = amx_ctof(params[2]);
(void)amx;
if (fValue <= 0.0 || fBase <= 0)
return amx_RaiseError(amx, AMX_ERR_DOMAIN);
if (fBase == 10.0) // ??? epsilon
fValue = (REAL)log10(fValue);
else
fValue = (REAL)(log(fValue) / log(fBase));
return amx_ftoc(fValue);
}
static REAL ToRadians(REAL angle, int radix)
{
switch (radix)
{
case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
return (REAL)(angle * PI / 180.0);
case 2: /* grades, centesimal system */
return (REAL)(angle * PI / 200.0);
default: /* assume already radian */
return angle;
} /* switch */
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatsin(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1 (angle)
* params[2] = float operand 2 (radix)
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = (float)sin(fA);
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatcos(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1 (angle)
* params[2] = float operand 2 (radix)
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = (float)cos(fA);
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floattan(AMX *amx,const cell *params)
{
/*
* params[0] = number of bytes
* params[1] = float operand 1 (angle)
* params[2] = float operand 2 (radix)
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = (float)tan(fA);
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
static cell AMX_NATIVE_CALL n_floatabs(AMX *amx,const cell *params)
{
REAL fA = amx_ctof(params[1]);
fA = (fA >= 0) ? fA : -fA;
(void)amx;
return amx_ftoc(fA);
}
/******************************************************************/
/* return the integer part of a real value, truncated
/* Return integer part of float, truncated (same as floatround
* with mode 3)
*/
static cell AMX_NATIVE_CALL n_floatint(AMX *amx,const cell *params)
{
REAL fA = amx_ctof(params[1]);
if ( fA>=0.0 )
fA = (REAL)(floor((double)fA));
else
fA = (REAL)(ceil((double)fA));
(void)amx;
return (cell)fA;
}
#if defined __cplusplus
extern "C"
#endif
const AMX_NATIVE_INFO float_Natives[] = {
{ "float", n_float },
{ "strfloat", n_strfloat },
{ "floatmul", n_floatmul },
{ "floatdiv", n_floatdiv },
{ "floatadd", n_floatadd },
{ "floatsub", n_floatsub },
{ "floatfract", n_floatfract },
{ "floatround", n_floatround },
{ "floatcmp", n_floatcmp },
{ "floatsqroot", n_floatsqroot},
{ "floatpower", n_floatpower },
{ "floatlog", n_floatlog },
{ "floatsin", n_floatsin },
{ "floatcos", n_floatcos },
{ "floattan", n_floattan },
{ "floatabs", n_floatabs },
{ "floatint", n_floatint }, // also add user-defined operator "="
{ NULL, NULL } /* terminator */
};
int AMXEXPORT AMXAPI amx_FloatInit(AMX *amx)
{
return amx_Register(amx,float_Natives,-1);
}
int AMXEXPORT AMXAPI amx_FloatCleanup(AMX *amx)
{
(void)amx;
return AMX_ERR_NONE;
}

File diff suppressed because it is too large Load Diff

@ -1,480 +0,0 @@
/* Date/time module for the Pawn Abstract Machine
*
* Copyright (c) ITB CompuPhase, 2001-2013
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: amxtime.c 4983 2013-10-21 07:32:57Z $
*/
#include <time.h>
#include <assert.h>
#include "amx.h"
#if defined __WIN32__ || defined _WIN32 || defined _Windows
#include <windows.h>
#include <mmsystem.h>
#endif
#define CELLMIN (-1 << (8*sizeof(cell) - 1))
#define SECONDS_PER_MINUTE 60
#define SECONDS_PER_HOUR 3600
#define SECONDS_PER_DAY 86400
#define SECONDS_PER_YEAR 31556952 /* based on 365.2425 days per year */
#if !defined CLOCKS_PER_SEC
#define CLOCKS_PER_SEC CLK_TCK
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32
static int timerset = 0;
/* timeGetTime() is more accurate on WindowsNT if timeBeginPeriod(1) is set */
#define INIT_TIMER() \
if (!timerset) { \
timeBeginPeriod(1); \
timerset=1; \
}
#else
#define INIT_TIMER()
#endif
static unsigned long timestamp;
static unsigned long timelimit;
static int timerepeat;
static const unsigned char monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static int wrap(int value, int min, int max)
{
if (value<min)
value=max;
else if (value>max)
value=min;
return value;
}
static unsigned long gettimestamp(void)
{
unsigned long value;
#if defined __WIN32__ || defined _WIN32 || defined WIN32
value=timeGetTime(); /* this value is already in milliseconds */
#elif defined __linux || defined __linux__ || defined __LINUX__ || defined __APPLE__
struct timeval tv;
gettimeofday(&tv, NULL);
value = ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
#else
value=clock();
#if CLOCKS_PER_SEC<1000
/* convert to milliseconds */
value=(cell)((1000L * value) / CLOCKS_PER_SEC);
#elif CLOCKS_PER_SEC>1000
/* convert to milliseconds */
value=(cell)(value/(CLOCKS_PER_SEC/1000));
#endif
#endif
return value;
}
void stamp2datetime(unsigned long sec1970,
int *year, int *month, int *day,
int *hour, int *minute, int *second)
{
int days, seconds;
/* find the year */
assert(year!=NULL);
for (*year = 1970; ; *year += 1) {
days = 365 + ((*year & 0x03) == 0); /* clumsy "leap-year" routine, fails for 2100 */
seconds = days * SECONDS_PER_DAY;
if ((unsigned long)seconds > sec1970)
break;
sec1970 -= seconds;
} /* if */
/* find the month */
assert(month!=NULL);
for (*month = 1; ; *month += 1) {
days = monthdays[*month - 1];
seconds = days * SECONDS_PER_DAY;
if ((unsigned long)seconds > sec1970)
break;
sec1970 -= seconds;
} /* if */
/* find the day */
assert(day!=NULL);
for (*day = 1; sec1970 >= SECONDS_PER_DAY; *day += 1)
sec1970 -= SECONDS_PER_DAY;
/* find the hour */
assert(hour!=NULL);
for (*hour = 0; sec1970 >= SECONDS_PER_HOUR; *hour += 1)
sec1970 -= SECONDS_PER_HOUR;
/* find the minute */
assert(minute!=NULL);
for (*minute = 0; sec1970 >= SECONDS_PER_MINUTE; *minute += 1)
sec1970 -= SECONDS_PER_MINUTE;
/* remainder is the number of seconds */
assert(second!=NULL);
*second = (int)sec1970;
}
static void settime(cell hour,cell minute,cell second)
{
#if defined __WIN32__ || defined _WIN32 || defined WIN32
SYSTEMTIME systim;
GetLocalTime(&systim);
if (hour!=CELLMIN)
systim.wHour=(WORD)wrap((int)hour,0,23);
if (minute!=CELLMIN)
systim.wMinute=(WORD)wrap((int)minute,0,59);
if (second!=CELLMIN)
systim.wSecond=(WORD)wrap((int)second,0,59);
SetLocalTime(&systim);
#else
/* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
* must have "root" permission to call stime(); many POSIX systems will
* have settimeofday() instead
*/
time_t sec1970;
struct tm gtm;
#if defined __APPLE__ /* also valid for other POSIX systems */
struct timeval tv;
#endif
time(&sec1970);
gtm=*localtime(&sec1970);
if (hour!=CELLMIN)
gtm.tm_hour=wrap((int)hour,0,23);
if (minute!=CELLMIN)
gtm.tm_min=wrap((int)minute,0,59);
if (second!=CELLMIN)
gtm.tm_sec=wrap((int)second,0,59);
sec1970=mktime(&gtm);
#if defined __APPLE__ /* also valid for other POSIX systems */
tv.tv_sec = sec1970;
tv.tv_usec = 0;
settimeofday(&tv, 0);
#else
stime(&sec1970);
#endif
#endif
}
static void setdate(cell year,cell month,cell day)
{
int maxday;
#if defined __WIN32__ || defined _WIN32 || defined WIN32
SYSTEMTIME systim;
GetLocalTime(&systim);
if (year!=CELLMIN)
systim.wYear=(WORD)wrap((int)year,1970,2099);
if (month!=CELLMIN)
systim.wMonth=(WORD)wrap((int)month,1,12);
maxday=monthdays[systim.wMonth - 1];
if (systim.wMonth==2 && ((systim.wYear % 4)==0 && ((systim.wYear % 100)!=0 || (systim.wYear % 400)==0)))
maxday++;
if (day!=CELLMIN)
systim.wDay=(WORD)wrap((int)day,1,maxday);
SetLocalTime(&systim);
#else
/* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
* must have "root" permission to call stime(); many POSIX systems will
* have settimeofday() instead
*/
time_t sec1970;
struct tm gtm;
#if defined __APPLE__ /* also valid for other POSIX systems */
struct timeval tv;
#endif
time(&sec1970);
gtm=*localtime(&sec1970);
if (year!=CELLMIN)
gtm.tm_year=year-1900;
if (month!=CELLMIN)
gtm.tm_mon=month-1;
if (day!=CELLMIN)
gtm.tm_mday=day;
sec1970=mktime(&gtm);
#if defined __APPLE__ /* also valid for other POSIX systems */
tv.tv_sec = sec1970;
tv.tv_usec = 0;
settimeofday(&tv, 0);
#else
stime(&sec1970);
#endif
#endif
}
/* settime(hour, minute, second)
* Always returns 0
*/
static cell AMX_NATIVE_CALL n_settime(AMX *amx, const cell *params)
{
(void)amx;
settime(params[1],params[2],params[3]);
return 0;
}
/* gettime(&hour, &minute, &second)
* The return value is the number of seconds since 1 January 1970 (Unix system
* time).
*/
static cell AMX_NATIVE_CALL n_gettime(AMX *amx, const cell *params)
{
time_t sec1970;
struct tm gtm;
cell *cptr;
assert(params[0]==(int)(3*sizeof(cell)));
time(&sec1970);
/* on DOS/Windows, the timezone is usually not set for the C run-time
* library; in that case gmtime() and localtime() return the same value
*/
gtm=*localtime(&sec1970);
cptr=amx_Address(amx,params[1]);
*cptr=gtm.tm_hour;
cptr=amx_Address(amx,params[2]);
*cptr=gtm.tm_min;
cptr=amx_Address(amx,params[3]);
*cptr=gtm.tm_sec;
/* the time() function returns the number of seconds since January 1 1970
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
*/
return (cell)sec1970;
}
/* setdate(year, month, day)
* Always returns 0
*/
static cell AMX_NATIVE_CALL n_setdate(AMX *amx, const cell *params)
{
(void)amx;
setdate(params[1],params[2],params[3]);
return 0;
}
/* getdate(&year, &month, &day)
* The return value is the number of days since the start of the year. January
* 1 is day 1 of the year.
*/
static cell AMX_NATIVE_CALL n_getdate(AMX *amx, const cell *params)
{
time_t sec1970;
struct tm gtm;
cell *cptr;
assert(params[0]==(int)(3*sizeof(cell)));
time(&sec1970);
gtm=*localtime(&sec1970);
cptr=amx_Address(amx,params[1]);
*cptr=gtm.tm_year+1900;
cptr=amx_Address(amx,params[2]);
*cptr=gtm.tm_mon+1;
cptr=amx_Address(amx,params[3]);
*cptr=gtm.tm_mday;
return gtm.tm_yday+1;
}
/* tickcount(&granularity)
* Returns the number of milliseconds since start-up. For a 32-bit cell, this
* count overflows after approximately 24 days of continuous operation.
*/
static cell AMX_NATIVE_CALL n_tickcount(AMX *amx, const cell *params)
{
cell *cptr;
assert(params[0]==(int)sizeof(cell));
INIT_TIMER();
cptr=amx_Address(amx,params[1]);
#if defined __WIN32__ || defined _WIN32 || defined WIN32
*cptr=1000; /* granularity = 1 ms */
#else
*cptr=(cell)CLOCKS_PER_SEC; /* in Unix/Linux, this is often 100 */
#endif
return gettimestamp() & 0x7fffffff;
}
/* delay(milliseconds)
* Pauses for (at least) the requested number of milliseconds.
*/
static cell AMX_NATIVE_CALL n_delay(AMX *amx, const cell *params)
{
unsigned long stamp;
(void)amx;
assert(params[0]==(int)sizeof(cell));
INIT_TIMER();
stamp=gettimestamp();
while (gettimestamp()-stamp < (unsigned long)params[1])
/* nothing */;
return 0;
}
/* settimer(milliseconds, bool: singleshot = false)
* Sets the delay until the @timer() callback is called. The timer may either
* be single-shot or repetitive.
*/
static cell AMX_NATIVE_CALL n_settimer(AMX *amx, const cell *params)
{
(void)amx;
assert(params[0]==(int)(2*sizeof(cell)));
timestamp=gettimestamp();
timelimit=params[1];
timerepeat=(int)(params[2]==0);
return 0;
}
/* bool: gettimer(&milliseconds, bool: &singleshot = false)
* Retrieves the timer set with settimer(); returns true if a timer
* was set up, or false otherwise.
*/
static cell AMX_NATIVE_CALL n_gettimer(AMX *amx, const cell *params)
{
cell *cptr;
assert(params[0]==(int)(2*sizeof(cell)));
cptr=amx_Address(amx,params[1]);
*cptr=timelimit;
cptr=amx_Address(amx,params[2]);
*cptr=timerepeat;
return timelimit>0;
}
/* settimestamp(seconds1970) sets the date and time from a single parameter: the
* number of seconds since 1 January 1970.
*/
static cell AMX_NATIVE_CALL n_settimestamp(AMX *amx, const cell *params)
{
#if defined __WIN32__ || defined _WIN32 || defined WIN32
int year, month, day, hour, minute, second;
stamp2datetime(params[1],
&year, &month, &day,
&hour, &minute, &second);
setdate(year, month, day);
settime(hour, minute, second);
#else
/* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
* must have "root" permission to call stime(); many POSIX systems will
* have settimeofday() instead
*/
#if defined __APPLE__ /* also valid for other POSIX systems */
struct timeval tv;
tv.tv_sec = params[1];
tv.tv_usec = 0;
settimeofday(&tv, 0);
#else
time_t sec1970=(time_t)params[1];
stime(&sec1970);
#endif
#endif
(void)amx;
return 0;
}
/* cvttimestamp(seconds1970, &year, &month, &day, &hour, &minute, &second)
*/
static cell AMX_NATIVE_CALL n_cvttimestamp(AMX *amx, const cell *params)
{
int year, month, day, hour, minute, second;
(void)amx;
stamp2datetime(params[1],
&year, &month, &day,
&hour, &minute, &second);
return 0;
}
#if !defined AMXTIME_NOIDLE
static AMX_IDLE PrevIdle = NULL;
static int idxTimer = -1;
static int AMXAPI amx_TimeIdle(AMX *amx, int AMXAPI Exec(AMX *, cell *, int))
{
int err=0;
assert(idxTimer >= 0);
if (PrevIdle != NULL)
PrevIdle(amx, Exec);
if (timelimit>0 && (gettimestamp()-timestamp)>=timelimit) {
if (timerepeat)
timestamp+=timelimit;
else
timelimit=0; /* do not repeat single-shot timer */
err = Exec(amx, NULL, idxTimer);
while (err == AMX_ERR_SLEEP)
err = Exec(amx, NULL, AMX_EXEC_CONT);
} /* if */
return err;
}
#endif
#if defined __cplusplus
extern "C"
#endif
const AMX_NATIVE_INFO time_Natives[] = {
{ "gettime", n_gettime },
{ "settime", n_settime },
{ "getdate", n_getdate },
{ "setdate", n_setdate },
{ "tickcount", n_tickcount },
{ "settimer", n_settimer },
{ "gettimer", n_gettimer },
{ "delay", n_delay },
{ "settimestamp", n_settimestamp },
{ "cvttimestamp", n_cvttimestamp },
{ NULL, NULL } /* terminator */
};
int AMXEXPORT AMXAPI amx_TimeInit(AMX *amx)
{
#if !defined AMXTIME_NOIDLE
/* see whether there is a @timer() function */
if (amx_FindPublic(amx,"@timer",&idxTimer) == AMX_ERR_NONE) {
if (amx_GetUserData(amx, AMX_USERTAG('I','d','l','e'), (void**)&PrevIdle) != AMX_ERR_NONE)
PrevIdle = NULL;
amx_SetUserData(amx, AMX_USERTAG('I','d','l','e'), amx_TimeIdle);
} /* if */
#endif
return amx_Register(amx, time_Natives, -1);
}
int AMXEXPORT AMXAPI amx_TimeCleanup(AMX *amx)
{
(void)amx;
#if !defined AMXTIME_NOIDLE
PrevIdle = NULL;
#endif
return AMX_ERR_NONE;
}

File diff suppressed because it is too large Load Diff

@ -1,184 +0,0 @@
/******************************************************************************
* fpattern.h
* Functions for matching filename patterns to filenames.
*
* Usage
* Filename patterns are composed of regular (printable) characters which
* may comprise a filename as well as special pattern matching characters:
*
* . Matches a period (.).
* Note that a period in a filename is not treated any
* differently than any other character.
*
* ? Any.
* Matches any single character except '/' or '\'.
*
* * Closure.
* Matches zero or more occurences of any characters other
* than '/' or '\'.
* Leading '*' characters are allowed.
*
* SUB Substitute (^Z); optionally supported.
* Similar to '*', this matches zero or more occurences of
* any characters other than '/', '\', or '.'.
* Leading '^Z' characters are allowed.
*
* [ab] Set.
* Matches the single character 'a' or 'b'.
* If the dash '-' character is to be included, it must
* immediately follow the opening bracket '['.
* If the closing bracket ']' character is to be included,
* it must be preceded by a quote '`'.
*
* [a-z] Range.
* Matches a single character in the range 'a' to 'z'.
* Ranges and sets may be combined within the same set of
* brackets.
*
* [!R] Exclusive range.
* Matches a single character not in the range 'R'.
* If range 'R' includes the dash '-' character, the dash
* must immediately follow the caret '!'.
*
* ! Not; optionally supported.
* Makes the following pattern (up to the next '/') match
* any filename except those what it would normally match.
*
* / Path separator (UNIX and DOS).
* Matches a '/' or '\' pathname (directory) separator.
* Multiple separators are treated like a single
* separator.
* A leading separator indicates an absolute pathname.
*
* \ Path separator (DOS).
* Same as the '/' character.
* Note that this character must be escaped if used within
* string constants ("\\").
*
* \ Quote (UNIX).
* Makes the next character a regular (nonspecial)
* character.
* Note that to match the quote character itself, it must
* be quoted.
* Note that this character must be escaped if used within
* string constants ("\\").
*
* ` Quote (DOS).
* Makes the next character a regular (nonspecial)
* character.
* Note that to match the quote character itself, it must
* be quoted.
*
* Upper and lower case alphabetic characters are considered identical,
* i.e., 'a' and 'A' match each other.
* (What constitutes a lowercase letter depends on the current locale
* settings.)
*
* Spaces and control characters are treated as normal characters.
*
* Examples
* The following patterns in the left column will match the filenames in
* the middle column and will not match filenames in the right column:
*
* Pattern Will Match Will Not Match
* ------- ---------- --------------
* a a (only) (anything else)
* a. a. (only) (anything else)
* a?c abc, acc, arc, a.c a, ac, abbc
* a*c ac, abc, abbc, acc, a.c a, ab, acb, bac
* a* a, ab, abb, a., a.b b, ba
* * a, ab, abb, a., .foo, a.foo (nothing)
* *. a., ab., abb., a.foo. a, ab, a.foo, .foo
* *.* a., a.b, ah.bc.foo a
* ^Z a, ab, abb a., .foo, a.foo
* ^Z. a., ab., abb. a, .foo, a.foo
* ^Z.* a, a., .foo, a.foo ab, abb
* *2.c 2.c, 12.c, foo2.c, foo.12.c 2x.c
* a[b-z]c abc, acc, azc (only) (anything else)
* [ab0-9]x ax, bx, 0x, 9x zx
* a[-.]b a-b, a.b (only) (anything else)
* a[!a-z]b a0b, a.b, a@b aab, azb, aa0b
* a[!-b]x a0x, a+x, acx a-x, abx, axxx
* a[-!b]x a-x, a!x, abx (only) (anything else)
* a[`]]x a]x (only) (anything else)
* a``x a`x (only) (anything else)
* oh`! oh! (only) (anything else)
* is`?it is?it (only) (anything else)
* !a?c a, ac, ab, abb, acb, a.foo abc, a.c, azc
*
* History
* 1.00 1997-01-03 David Tribble.
* First cut.
* 1.01 1997-01-03 David Tribble.
* Added '^Z' pattern character.
* Added fpattern_matchn().
* 1.02 1997-01-26 David Tribble.
* Changed range negation character from '^' to '!', ala Unix.
* 1.03 1997-08-02 David Tribble.
* Added 'FPAT_XXX' macro constants.
*
* Limitations
* This code is copyrighted by the author, but permission is hereby
* granted for its unlimited use provided that the original copyright
* and authorship notices are retained intact.
*
* Other queries can be sent to:
* dtribble@technologist.com
* david.tribble@beasys.com
* dtribble@flash.net
*
* Copyright <EFBFBD>1997 by David R. Tribble, all rights reserved.
*/
#ifndef fpattern_h
#define fpattern_h 1
#ifdef __cplusplus
extern "C"
{
#endif
/* Options */
//#define FPAT_DELIM /* handle path delimiters in a special way */
//#define FPAT_SUBCLOS /* support alternative closure */
//#define FPAT_NOT_ENABLED /* !pattern is enabled */
#define FPAT_MSET_ENABLED /* multi-set/range is enabled */
/* Manifest constants */
#define FPAT_QUOTE '`' /* Quotes a special char */
#define FPAT_DEL '/' /* Path delimiter (used only when FPAT_DELIM is true) */
#define FPAT_DEL2 '\\' /* Path delimiter (used only when FPAT_DELIM is true) */
#define FPAT_DOT '.' /* Dot char */
#define FPAT_NOT '!' /* Exclusion (also used for sets) */
#define FPAT_ANY '?' /* Any one char */
#define FPAT_CLOS '*' /* Zero or more chars */
#define FPAT_CLOSP '\x1A' /* Zero or more nondelimiters (used only when FPAT_SUBCLOS is true) */
#define FPAT_SET_L '[' /* Set/range open bracket */
#define FPAT_SET_R ']' /* Set/range close bracket */
#define FPAT_MSET_L '{' /* Multi-set/range open bracket */
#define FPAT_MSET_R '}' /* Multi-set/range close bracket*/
#define FPAT_SET_THRU '-' /* Set range of chars */
#define FPAT_INVALID 0 /* invalid pattern */
#define FPAT_CLOSED 1 /* valid pattern */
#define FPAT_OPEN 2 /* valid pattern */
/* Public functions */
extern int fpattern_isvalid(const char *pat);
extern int fpattern_match(const char *pat, const char *fname, int flength, int keepcase);
extern int fpattern_matchn(const char *pat, const char *fname, int flength, int keepcase);
extern int fpattern_matchcount(const char *pat, const char *fname, int flength, int minlength, int keepcase);
#ifdef __cplusplus
}
#endif
#endif /* fpattern_h */

@ -1,778 +0,0 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#ifndef __BINRELOC_C__
#define __BINRELOC_C__
#ifdef ENABLE_BINRELOC
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif /* ENABLE_BINRELOC */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "binreloc.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** @internal
* Find the canonical filename of the executable. Returns the filename
* (which must be freed) or NULL on error. If the parameter 'error' is
* not NULL, the error code will be stored there, if an error occured.
*/
static char *
_br_find_exe(BrInitError *error)
{
#ifndef ENABLE_BINRELOC
if (error)
*error = BR_INIT_ERROR_DISABLED;
return NULL;
#else
char *path, *path2, *line, *result;
size_t buf_size;
ssize_t size;
struct stat stat_buf;
FILE *f;
/* Read from /proc/self/exe (symlink) */
if (sizeof (path) > SSIZE_MAX)
buf_size = SSIZE_MAX - 1;
else
buf_size = PATH_MAX - 1;
path = (char *) malloc (buf_size);
if (path == NULL) {
/* Cannot allocate memory. */
if (error)
*error = BR_INIT_ERROR_NOMEM;
return NULL;
}
path2 = (char *) malloc (buf_size);
if (path2 == NULL) {
/* Cannot allocate memory. */
if (error)
*error = BR_INIT_ERROR_NOMEM;
free (path);
return NULL;
}
strncpy (path2, "/proc/self/exe", buf_size - 1);
while (1) {
int i;
size = readlink (path2, path, buf_size - 1);
if (size == -1) {
/* Error. */
free (path2);
break;
}
/* readlink() success. */
path[size] = '\0';
/* Check whether the symlink's target is also a symlink.
* We want to get the final target. */
i = stat (path, &stat_buf);
if (i == -1) {
/* Error. */
free (path2);
break;
}
/* stat() success. */
if (!S_ISLNK (stat_buf.st_mode)) {
/* path is not a symlink. Done. */
free (path2);
return path;
}
/* path is a symlink. Continue loop and resolve this. */
strncpy (path, path2, buf_size - 1);
}
/* readlink() or stat() failed; this can happen when the program is
* running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
buf_size = PATH_MAX + 128;
line = (char *) realloc (path, buf_size);
if (line == NULL) {
/* Cannot allocate memory. */
free (path);
if (error)
*error = BR_INIT_ERROR_NOMEM;
return NULL;
}
f = fopen ("/proc/self/maps", "r");
if (f == NULL) {
free (line);
if (error)
*error = BR_INIT_ERROR_OPEN_MAPS;
return NULL;
}
/* The first entry should be the executable name. */
result = fgets (line, (int) buf_size, f);
if (result == NULL) {
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_READ_MAPS;
return NULL;
}
/* Get rid of newline character. */
buf_size = strlen (line);
if (buf_size <= 0) {
/* Huh? An empty string? */
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_INVALID_MAPS;
return NULL;
}
if (line[buf_size - 1] == 10)
line[buf_size - 1] = 0;
/* Extract the filename; it is always an absolute path. */
path = strchr (line, '/');
/* Sanity check. */
if (strstr (line, " r-xp ") == NULL || path == NULL) {
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_INVALID_MAPS;
return NULL;
}
path = strdup (path);
free (line);
fclose (f);
return path;
#endif /* ENABLE_BINRELOC */
}
/** @internal
* Find the canonical filename of the executable which owns symbol.
* Returns a filename which must be freed, or NULL on error.
*/
static char *
_br_find_exe_for_symbol(const void *symbol, BrInitError *error)
{
#ifndef ENABLE_BINRELOC
if (error)
*error = BR_INIT_ERROR_DISABLED;
return (char *) NULL;
#else
#define SIZE PATH_MAX + 100
FILE *f;
size_t address_string_len;
char *address_string, line[SIZE], *found;
if (symbol == NULL)
return (char *) NULL;
f = fopen ("/proc/self/maps", "r");
if (f == NULL)
return (char *) NULL;
address_string_len = 4;
address_string = (char *) malloc (address_string_len);
found = (char *) NULL;
while (!feof (f)) {
char *start_addr, *end_addr, *end_addr_end, *file;
void *start_addr_p, *end_addr_p;
size_t len;
if (fgets (line, SIZE, f) == NULL)
break;
/* Sanity check. */
if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
continue;
/* Parse line. */
start_addr = line;
end_addr = strchr (line, '-');
file = strchr (line, '/');
/* More sanity check. */
if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
continue;
end_addr[0] = '\0';
end_addr++;
end_addr_end = strchr (end_addr, ' ');
if (end_addr_end == NULL)
continue;
end_addr_end[0] = '\0';
len = strlen (file);
if (len == 0)
continue;
if (file[len - 1] == '\n')
file[len - 1] = '\0';
/* Get rid of "(deleted)" from the filename. */
len = strlen (file);
if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
file[len - 10] = '\0';
/* I don't know whether this can happen but better safe than sorry. */
len = strlen (start_addr);
if (len != strlen (end_addr))
continue;
/* Transform the addresses into a string in the form of 0xdeadbeef,
* then transform that into a pointer. */
if (address_string_len < len + 3) {
address_string_len = len + 3;
address_string = (char *) realloc (address_string, address_string_len);
}
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, start_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &start_addr_p);
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, end_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &end_addr_p);
if (symbol >= start_addr_p && symbol < end_addr_p) {
found = file;
break;
}
}
free (address_string);
fclose (f);
if (found == NULL)
return (char *) NULL;
else
return strdup (found);
#endif /* ENABLE_BINRELOC */
}
#ifndef BINRELOC_RUNNING_DOXYGEN
#undef NULL
#define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
#endif
static char *exe = (char *) NULL;
/** Initialize the BinReloc library (for applications).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the application's canonical filename.
*
* @note If you want to use BinReloc for a library, then you should call
* br_init_lib() instead.
*
* @param error If BinReloc failed to initialize, then the error code will
* be stored in this variable. Set to NULL if you want to
* ignore this. See #BrInitError for a list of error codes.
*
* @returns 1 on success, 0 if BinReloc failed to initialize.
*/
int
br_init(BrInitError *error)
{
exe = _br_find_exe(error);
return exe != NULL;
}
/** Initialize the BinReloc library (for libraries).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the calling library's canonical filename.
*
* @note The BinReloc source code MUST be included in your library, or this
* function won't work correctly.
*
* @param error If BinReloc failed to initialize, then the error code will
* be stored in this variable. Set to NULL if you want to
* ignore this. See #BrInitError for a list of error codes.
*
* @returns 1 on success, 0 if a filename cannot be found.
*/
int
br_init_lib(BrInitError *error)
{
exe = _br_find_exe_for_symbol((const void *) "", error);
return exe != NULL;
}
/** Find the canonical filename of the current application.
*
* @param default_exe A default filename which will be used as fallback.
* @returns A string containing the application's canonical filename,
* which must be freed when no longer necessary. If BinReloc is
* not initialized, or if br_init() failed, then a copy of
* default_exe will be returned. If default_exe is NULL, then
* NULL will be returned.
*/
char *
br_find_exe(const char *default_exe)
{
if (exe == (char *) NULL)
{
/* BinReloc is not initialized. */
if (default_exe != (const char *) NULL)
return strdup(default_exe);
else
return (char *) NULL;
}
return strdup(exe);
}
/** Locate the directory in which the current application is installed.
*
* The prefix is generated by the following pseudo-code evaluation:
* \code
* dirname(exename)
* \endcode
*
* @param default_dir A default directory which will used as fallback.
* @return A string containing the directory, which must be freed when no
* longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_dir
* will be returned. If default_dir is NULL, then NULL will be
* returned.
*/
char *
br_find_exe_dir(const char *default_dir)
{
if (exe == NULL)
{
/* BinReloc not initialized. */
if (default_dir != NULL)
return strdup(default_dir);
else
return NULL;
}
return br_dirname(exe);
}
/** Locate the prefix in which the current application is installed.
*
* The prefix is generated by the following pseudo-code evaluation:
* \code
* dirname(dirname(exename))
* \endcode
*
* @param default_prefix A default prefix which will used as fallback.
* @return A string containing the prefix, which must be freed when no
* longer necessary. If BinReloc is not initialized, or if
* the initialization function failed, then a copy of default_prefix
* will be returned. If default_prefix is NULL, then NULL will be returned.
*/
char *
br_find_prefix(const char *default_prefix)
{
char *dir1, *dir2;
if (exe == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_prefix != (const char *) NULL)
return strdup(default_prefix);
else
return (char *) NULL;
}
dir1 = br_dirname(exe);
dir2 = br_dirname(dir1);
free(dir1);
return dir2;
}
/** Locate the application's binary folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/bin"
* \endcode
*
* @param default_bin_dir A default path which will used as fallback.
* @return A string containing the bin folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if
* the initialization function failed, then a copy of default_bin_dir will
* be returned. If default_bin_dir is NULL, then NULL will be returned.
*/
char *
br_find_bin_dir(const char *default_bin_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_bin_dir != (const char *) NULL)
return strdup(default_bin_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "bin");
free(prefix);
return dir;
}
/** Locate the application's superuser binary folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/sbin"
* \endcode
*
* @param default_sbin_dir A default path which will used as fallback.
* @return A string containing the sbin folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_sbin_dir will
* be returned. If default_bin_dir is NULL, then NULL will be returned.
*/
char *
br_find_sbin_dir(const char *default_sbin_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_sbin_dir != (const char *) NULL)
return strdup(default_sbin_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "sbin");
free(prefix);
return dir;
}
/** Locate the application's data folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/share"
* \endcode
*
* @param default_data_dir A default path which will used as fallback.
* @return A string containing the data folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_data_dir
* will be returned. If default_data_dir is NULL, then NULL will be
* returned.
*/
char *
br_find_data_dir(const char *default_data_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_data_dir != (const char *) NULL)
return strdup(default_data_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "share");
free(prefix);
return dir;
}
/** Locate the application's localization folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/share/locale"
* \endcode
*
* @param default_locale_dir A default path which will used as fallback.
* @return A string containing the localization folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_locale_dir will be returned.
* If default_locale_dir is NULL, then NULL will be returned.
*/
char *
br_find_locale_dir(const char *default_locale_dir)
{
char *data_dir, *dir;
data_dir = br_find_data_dir((const char *) NULL);
if (data_dir == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_locale_dir != (const char *) NULL)
return strdup(default_locale_dir);
else
return (char *) NULL;
}
dir = br_build_path(data_dir, "locale");
free(data_dir);
return dir;
}
/** Locate the application's library folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/lib"
* \endcode
*
* @param default_lib_dir A default path which will used as fallback.
* @return A string containing the library folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_lib_dir will be returned.
* If default_lib_dir is NULL, then NULL will be returned.
*/
char *
br_find_lib_dir(const char *default_lib_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_lib_dir != (const char *) NULL)
return strdup(default_lib_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "lib");
free(prefix);
return dir;
}
/** Locate the application's libexec folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/libexec"
* \endcode
*
* @param default_libexec_dir A default path which will used as fallback.
* @return A string containing the libexec folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_libexec_dir will be returned.
* If default_libexec_dir is NULL, then NULL will be returned.
*/
char *
br_find_libexec_dir(const char *default_libexec_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_libexec_dir != (const char *) NULL)
return strdup(default_libexec_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "libexec");
free(prefix);
return dir;
}
/** Locate the application's configuration files folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/etc"
* \endcode
*
* @param default_etc_dir A default path which will used as fallback.
* @return A string containing the etc folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_etc_dir will be returned.
* If default_etc_dir is NULL, then NULL will be returned.
*/
char *
br_find_etc_dir(const char *default_etc_dir)
{
char *prefix, *dir;
prefix = br_find_prefix((const char *) NULL);
if (prefix == (char *) NULL)
{
/* BinReloc not initialized. */
if (default_etc_dir != (const char *) NULL)
return strdup(default_etc_dir);
else
return (char *) NULL;
}
dir = br_build_path(prefix, "etc");
free(prefix);
return dir;
}
/***********************
* Utility functions
***********************/
/** Concatenate str1 and str2 to a newly allocated string.
*
* @param str1 A string.
* @param str2 Another string.
* @returns A newly-allocated string. This string should be freed when no longer needed.
*/
char *
br_strcat(const char *str1, const char *str2)
{
char *result;
size_t len1, len2;
if (str1 == NULL)
str1 = "";
if (str2 == NULL)
str2 = "";
len1 = strlen(str1);
len2 = strlen(str2);
result = (char *) malloc(len1 + len2 + 1);
memcpy(result, str1, len1);
memcpy(result + len1, str2, len2);
result[len1 + len2] = '\0';
return result;
}
char *
br_build_path(const char *dir, const char *file)
{
char *dir2, *result;
size_t len;
int must_free = 0;
len = strlen(dir);
if (len > 0 && dir[len - 1] != '/')
{
dir2 = br_strcat(dir, "/");
must_free = 1;
} else
dir2 = (char *) dir;
result = br_strcat(dir2, file);
if (must_free)
free(dir2);
return result;
}
/* Emulates glibc's strndup() */
static char *
br_strndup(const char *str, size_t size)
{
char *result = (char *) NULL;
size_t len;
if (str == (const char *) NULL)
return (char *) NULL;
len = strlen(str);
if (len == 0)
return strdup("");
if (size > len)
size = len;
result = (char *) malloc(len + 1);
memcpy(result, str, size);
result[size] = '\0';
return result;
}
/** Extracts the directory component of a path.
*
* Similar to g_dirname() or the dirname commandline application.
*
* Example:
* \code
* br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
* \endcode
*
* @param path A path.
* @returns A directory name. This string should be freed when no longer needed.
*/
char *
br_dirname(const char *path)
{
char *end, *result;
if (path == (const char *) NULL)
return (char *) NULL;
end = strrchr(path, '/');
if (end == (const char *) NULL)
return strdup(".");
while (end > path && *end == '/')
end--;
result = br_strndup(path, end - path + 1);
if (result[0] == 0)
{
free(result);
return strdup("/");
} else
return result;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BINRELOC_C__ */

@ -1,80 +0,0 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#ifndef __BINRELOC_H__
#define __BINRELOC_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
typedef enum {
/** Cannot allocate memory. */
BR_INIT_ERROR_NOMEM,
/** Unable to open /proc/self/maps; see errno for details. */
BR_INIT_ERROR_OPEN_MAPS,
/** Unable to read from /proc/self/maps; see errno for details. */
BR_INIT_ERROR_READ_MAPS,
/** The file format of /proc/self/maps is invalid; kernel bug? */
BR_INIT_ERROR_INVALID_MAPS,
/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
BR_INIT_ERROR_DISABLED
} BrInitError;
#ifndef BINRELOC_RUNNING_DOXYGEN
/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
#define br_init SbCJ22537442193159_br_init
#define br_init_lib SbCJ22537442193159_br_init_lib
#define br_find_exe SbCJ22537442193159_br_find_exe
#define br_find_exe_dir SbCJ22537442193159_br_find_exe_dir
#define br_find_prefix SbCJ22537442193159_br_find_prefix
#define br_find_bin_dir SbCJ22537442193159_br_find_bin_dir
#define br_find_sbin_dir SbCJ22537442193159_br_find_sbin_dir
#define br_find_data_dir SbCJ22537442193159_br_find_data_dir
#define br_find_locale_dir SbCJ22537442193159_br_find_locale_dir
#define br_find_lib_dir SbCJ22537442193159_br_find_lib_dir
#define br_find_libexec_dir SbCJ22537442193159_br_find_libexec_dir
#define br_find_etc_dir SbCJ22537442193159_br_find_etc_dir
#define br_strcat SbCJ22537442193159_br_strcat
#define br_build_path SbCJ22537442193159_br_build_path
#define br_dirname SbCJ22537442193159_br_dirname
#endif
int br_init (BrInitError *error);
int br_init_lib (BrInitError *error);
char *br_find_exe (const char *default_exe);
char *br_find_exe_dir (const char *default_dir);
char *br_find_prefix (const char *default_prefix);
char *br_find_bin_dir (const char *default_bin_dir);
char *br_find_sbin_dir (const char *default_sbin_dir);
char *br_find_data_dir (const char *default_data_dir);
char *br_find_locale_dir (const char *default_locale_dir);
char *br_find_lib_dir (const char *default_lib_dir);
char *br_find_libexec_dir (const char *default_libexec_dir);
char *br_find_etc_dir (const char *default_etc_dir);
/* Utility functions */
char *br_strcat (const char *str1, const char *str2);
char *br_build_path (const char *dir, const char *file);
char *br_dirname (const char *path);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BINRELOC_H__ */

@ -1,104 +0,0 @@
/* Extremely inefficient but portable POSIX getch() */
#include <stdio.h>
#include <string.h>
#include <termios.h> /* for tcgetattr() and tcsetattr() */
#include <unistd.h> /* for read() */
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include "getch.h"
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
int
getch (void)
{
struct termios save_termios;
struct termios ios;
unsigned char b;
int c = 0;
if (!isatty (STDIN_FILENO))
return EOF;
if (tcgetattr (STDIN_FILENO, &save_termios) < 0)
return EOF;
ios = save_termios;
ios.c_lflag &= ~(ICANON | ECHO | ISIG);
ios.c_cc[VMIN] = 1; /* read() will return with one char */
ios.c_cc[VTIME] = 0; /* read() blocks forever */
if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0)
return EOF;
if (read (STDIN_FILENO, &b, 1) == 1)
c = (int)(0xff & b);
else
c = EOF;
tcsetattr (STDIN_FILENO, TCSANOW, &save_termios);
return c;
}
int
kbhit (void)
{
struct termios save_termios;
struct termios ios;
fd_set inp;
struct timeval timeout = {0, 0};
int result;
if (!isatty (STDIN_FILENO))
return 0;
if (tcgetattr (STDIN_FILENO, &save_termios) < 0)
return 0;
ios = save_termios;
ios.c_lflag &= ~(ICANON | ECHO | ISIG);
ios.c_cc[VMIN] = 1; /* read() will return with one char */
ios.c_cc[VTIME] = 0; /* read() blocks forever */
if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0)
return 0;
/* set up select() args */
FD_ZERO(&inp);
FD_SET(STDIN_FILENO, &inp);
result = select (STDIN_FILENO+1, &inp, NULL, NULL, &timeout) == 1;
tcsetattr (STDIN_FILENO, TCSANOW, &save_termios);
return result;
}
#if defined TEST_GETCH
int
main ()
{
int i;
char c[4];
printf("Enter %d keys to continue: ", sizeof c - 1);
fflush (stdout);
memset(c, 0, sizeof c);
for (i=0; i<sizeof c - 1; i++)
c[i] = getch ();
printf("Your input: [%s]\n", c);
printf("Now hit any key to abort: ");
while (!kbhit())
printf(".");
return 0;
}
#endif

@ -1,15 +0,0 @@
/* Extremely inefficient but portable POSIX getch(), see getch.c */
#ifndef GETCH_H
#define GETCH_H
#if defined __cplusplus
extern "C" {
#endif
int getch(void);
int kbhit(void);
#if defined __cplusplus
}
#endif
#endif /* GETCH_H */

@ -1,49 +0,0 @@
/*
* Things needed to compile under linux.
*
* Should be reworked totally to use GNU's 'configure'
*/
#ifndef SCLINUX_H
#define SCLINUX_H
/* getchar() is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the
* controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling
* terminal tty's in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must
* be put back correctly when the function ends. See GETCH.C for an implementation.
*
* For interactive use of PawnRun/PawnDbg if would be much better to use GNU's readline package: the user would be able to
* have a complete emacs/vi like line editing system.
*/
#if !defined getch && !defined kbhit
#include "getch.h"
#endif
#define stricmp(a,b) strcasecmp(a,b)
#define strnicmp(a,b,c) strncasecmp(a,b,c)
/*
* WinWorld wants '\'. Unices do not.
*/
#define DIRECTORY_SEP_CHAR '/'
#define DIRECTORY_SEP_STR "/"
/*
* SC assumes that a computer is Little Endian unless told otherwise. It uses
* (and defines) the macros BYTE_ORDER and BIG_ENDIAN.
* For Linux, we must overrule these settings with those defined in glibc.
*/
#if !defined __BYTE_ORDER
# include <stdlib.h>
#endif
#if defined __OpenBSD__ || defined __FreeBSD__ || defined __APPLE__
# define __BYTE_ORDER BYTE_ORDER
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __BIG_ENDIAN BIG_ENDIAN
#endif
#if !defined __BYTE_ORDER
# error "Can't figure computer byte order (__BYTE_ORDER macro not found)"
#endif
#endif /* SCLINUX_H */

@ -1,31 +0,0 @@
/* Glue functions for the minIni library, based on the C/C++ stdio library
*
* Or better said: this file contains macros that maps the function interface
* used by minIni to the standard C/C++ file I/O functions.
*
* By CompuPhase, 2008-2014
* This "glue file" is in the public domain. It is distributed without
* warranties or conditions of any kind, either express or implied.
*/
/* map required file I/O types and functions to the standard C library */
#include <stdio.h>
#define INI_FILETYPE FILE*
#define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL)
#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL)
#define ini_openrewrite(filename,file) ((*(file) = fopen((filename),"r+b")) != NULL)
#define ini_close(file) (fclose(*(file)) == 0)
#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL)
#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0)
#define ini_rename(source,dest) (rename((source), (dest)) == 0)
#define ini_remove(filename) (remove(filename) == 0)
#define INI_FILEPOS long int
#define ini_tell(file,pos) (*(pos) = ftell(*(file)))
#define ini_seek(file,pos) (fseek(*(file), *(pos), SEEK_SET) == 0)
/* for floating-point support, define additional types and functions */
#define INI_REAL float
#define ini_ftoa(string,value) sprintf((string),"%f",(value))
#define ini_atof(string) (INI_REAL)strtod((string),NULL)

@ -1,877 +0,0 @@
/* minIni - Multi-Platform INI file parser, suitable for embedded systems
*
* These routines are in part based on the article "Multiplatform .INI Files"
* by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal.
*
* Copyright (c) CompuPhase, 2008-2015
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: minIni.c 5181 2015-01-21 09:44:28Z thiadmer $
*/
#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined INI_ANSIONLY
# if !defined UNICODE /* for Windows */
# define UNICODE
# endif
# if !defined _UNICODE /* for C library */
# define _UNICODE
# endif
#endif
#define MININI_IMPLEMENTATION
#include "minIni.h"
#if defined NDEBUG
#define assert(e)
#else
#include <assert.h>
#endif
#if !defined __T || defined INI_ANSIONLY
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define TCHAR char
#define __T(s) s
#define _tcscat strcat
#define _tcschr strchr
#define _tcscmp strcmp
#define _tcscpy strcpy
#define _tcsicmp stricmp
#define _tcslen strlen
#define _tcsncmp strncmp
#define _tcsnicmp strnicmp
#define _tcsrchr strrchr
#define _tcstol strtol
#define _tcstod strtod
#define _totupper toupper
#define _stprintf sprintf
#define _tfgets fgets
#define _tfputs fputs
#define _tfopen fopen
#define _tremove remove
#define _trename rename
#endif
#if defined __linux || defined __linux__
#define __LINUX__
#elif defined FREEBSD && !defined __FreeBSD__
#define __FreeBSD__
#elif defined(_MSC_VER)
#pragma warning(disable: 4996) /* for Microsoft Visual C/C++ */
#endif
#if !defined strnicmp && !defined PORTABLE_STRNICMP
#if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
#define strnicmp strncasecmp
#endif
#endif
#if !defined _totupper
#define _totupper toupper
#endif
#if !defined INI_LINETERM
#if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
#define INI_LINETERM __T("\n")
#else
#define INI_LINETERM __T("\r\n")
#endif
#endif
#if !defined INI_FILETYPE
#error Missing definition for INI_FILETYPE.
#endif
#if !defined sizearray
#define sizearray(a) (sizeof(a) / sizeof((a)[0]))
#endif
enum quote_option {
QUOTE_NONE,
QUOTE_ENQUOTE,
QUOTE_DEQUOTE,
};
#if defined PORTABLE_STRNICMP
int strnicmp(const TCHAR *s1, const TCHAR *s2, size_t n)
{
register int c1, c2;
while (n-- != 0 && (*s1 || *s2)) {
c1 = *s1++;
if ('a' <= c1 && c1 <= 'z')
c1 += ('A' - 'a');
c2 = *s2++;
if ('a' <= c2 && c2 <= 'z')
c2 += ('A' - 'a');
if (c1 != c2)
return c1 - c2;
} /* while */
return 0;
}
#endif /* PORTABLE_STRNICMP */
static TCHAR *skipleading(const TCHAR *str)
{
assert(str != NULL);
while ('\0' < *str && *str <= ' ')
str++;
return (TCHAR *)str;
}
static TCHAR *skiptrailing(const TCHAR *str, const TCHAR *base)
{
assert(str != NULL);
assert(base != NULL);
while (str > base && '\0' < *(str-1) && *(str-1) <= ' ')
str--;
return (TCHAR *)str;
}
static TCHAR *striptrailing(TCHAR *str)
{
TCHAR *ptr = skiptrailing(_tcschr(str, '\0'), str);
assert(ptr != NULL);
*ptr = '\0';
return str;
}
static TCHAR *save_strncpy(TCHAR *dest, const TCHAR *source, size_t maxlen, enum quote_option option)
{
size_t d, s;
assert(maxlen>0);
assert(dest <= source || dest >= source + maxlen);
if (option == QUOTE_ENQUOTE && maxlen < 3)
option = QUOTE_NONE; /* cannot store two quotes and a terminating zero in less than 3 characters */
switch (option) {
case QUOTE_NONE:
for (d = 0; d < maxlen - 1 && source[d] != '\0'; d++)
dest[d] = source[d];
assert(d < maxlen);
dest[d] = '\0';
break;
case QUOTE_ENQUOTE:
d = 0;
dest[d++] = '"';
for (s = 0; source[s] != '\0' && d < maxlen - 2; s++, d++) {
if (source[s] == '"') {
if (d >= maxlen - 3)
break; /* no space to store the escape character plus the one that follows it */
dest[d++] = '\\';
} /* if */
dest[d] = source[s];
} /* for */
dest[d++] = '"';
dest[d] = '\0';
break;
case QUOTE_DEQUOTE:
for (d = s = 0; source[s] != '\0' && d < maxlen - 1; s++, d++) {
if ((source[s] == '"' || source[s] == '\\') && source[s + 1] == '"')
s++;
dest[d] = source[s];
} /* for */
dest[d] = '\0';
break;
default:
assert(0);
} /* switch */
return dest;
}
static TCHAR *cleanstring(TCHAR *string, enum quote_option *quotes)
{
int isstring;
TCHAR *ep;
assert(string != NULL);
assert(quotes != NULL);
/* Remove a trailing comment */
isstring = 0;
for (ep = string; *ep != '\0' && ((*ep != ';' && *ep != '#') || isstring); ep++) {
if (*ep == '"') {
if (*(ep + 1) == '"')
ep++; /* skip "" (both quotes) */
else
isstring = !isstring; /* single quote, toggle isstring */
} else if (*ep == '\\' && *(ep + 1) == '"') {
ep++; /* skip \" (both quotes */
} /* if */
} /* for */
assert(ep != NULL && (*ep == '\0' || *ep == ';' || *ep == '#'));
*ep = '\0'; /* terminate at a comment */
striptrailing(string);
/* Remove double quotes surrounding a value */
*quotes = QUOTE_NONE;
if (*string == '"' && (ep = _tcschr(string, '\0')) != NULL && *(ep - 1) == '"') {
string++;
*--ep = '\0';
*quotes = QUOTE_DEQUOTE; /* this is a string, so remove escaped characters */
} /* if */
return string;
}
static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key,
int idxSection, int idxKey, TCHAR *Buffer, int BufferSize,
INI_FILEPOS *mark)
{
TCHAR *sp, *ep;
int len, idx;
enum quote_option quotes;
TCHAR LocalBuffer[INI_BUFFERSIZE];
assert(fp != NULL);
/* Move through file 1 line at a time until a section is matched or EOF. If
* parameter Section is NULL, only look at keys above the first section. If
* idxSection is postive, copy the relevant section name.
*/
len = (Section != NULL) ? (int)_tcslen(Section) : 0;
if (len > 0 || idxSection >= 0) {
idx = -1;
do {
if (!ini_read(LocalBuffer, INI_BUFFERSIZE, fp))
return 0;
sp = skipleading(LocalBuffer);
ep = _tcschr(sp, ']');
} while (*sp != '[' || ep == NULL || (((int)(ep-sp-1) != len || _tcsnicmp(sp+1,Section,len) != 0) && ++idx != idxSection));
if (idxSection >= 0) {
if (idx == idxSection) {
assert(ep != NULL);
assert(*ep == ']');
*ep = '\0';
save_strncpy(Buffer, sp + 1, BufferSize, QUOTE_NONE);
return 1;
} /* if */
return 0; /* no more section found */
} /* if */
} /* if */
/* Now that the section has been found, find the entry.
* Stop searching upon leaving the section's area.
*/
assert(Key != NULL || idxKey >= 0);
len = (Key != NULL) ? (int)_tcslen(Key) : 0;
idx = -1;
do {
if (mark != NULL)
ini_tell(fp, mark); /* optionally keep the mark to the start of the line */
if (!ini_read(LocalBuffer,INI_BUFFERSIZE,fp) || *(sp = skipleading(LocalBuffer)) == '[')
return 0;
sp = skipleading(LocalBuffer);
ep = _tcschr(sp, '='); /* Parse out the equal sign */
if (ep == NULL)
ep = _tcschr(sp, ':');
} while (*sp == ';' || *sp == '#' || ep == NULL
|| ((len == 0 || (int)(skiptrailing(ep,sp)-sp) != len || _tcsnicmp(sp,Key,len) != 0) && ++idx != idxKey));
if (idxKey >= 0) {
if (idx == idxKey) {
assert(ep != NULL);
assert(*ep == '=' || *ep == ':');
*ep = '\0';
striptrailing(sp);
save_strncpy(Buffer, sp, BufferSize, QUOTE_NONE);
return 1;
} /* if */
return 0; /* no more key found (in this section) */
} /* if */
/* Copy up to BufferSize chars to buffer */
assert(ep != NULL);
assert(*ep == '=' || *ep == ':');
sp = skipleading(ep + 1);
sp = cleanstring(sp, &quotes); /* Remove a trailing comment */
save_strncpy(Buffer, sp, BufferSize, quotes);
return 1;
}
/** ini_gets()
* \param Section the name of the section to search for
* \param Key the name of the entry to find the value of
* \param DefValue default string in the event of a failed read
* \param Buffer a pointer to the buffer to copy into
* \param BufferSize the maximum number of characters to copy
* \param Filename the name and full path of the .ini file to read from
*
* \return the number of characters copied into the supplied buffer
*/
int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue,
TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
INI_FILETYPE fp;
int ok = 0;
if (Buffer == NULL || BufferSize <= 0 || Key == NULL)
return 0;
if (ini_openread(Filename, &fp)) {
ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize, NULL);
(void)ini_close(&fp);
} /* if */
if (!ok)
save_strncpy(Buffer, (DefValue != NULL) ? DefValue : __T(""), BufferSize, QUOTE_NONE);
return (int)_tcslen(Buffer);
}
/** ini_getl()
* \param Section the name of the section to search for
* \param Key the name of the entry to find the value of
* \param DefValue the default value in the event of a failed read
* \param Filename the name of the .ini file to read from
*
* \return the value located at Key
*/
long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename)
{
TCHAR LocalBuffer[64];
int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename);
return (len == 0) ? DefValue
: ((len >= 2 && _totupper((int)LocalBuffer[1]) == 'X') ? _tcstol(LocalBuffer, NULL, 16)
: _tcstol(LocalBuffer, NULL, 10));
}
#if defined INI_REAL
/** ini_getf()
* \param Section the name of the section to search for
* \param Key the name of the entry to find the value of
* \param DefValue the default value in the event of a failed read
* \param Filename the name of the .ini file to read from
*
* \return the value located at Key
*/
INI_REAL ini_getf(const TCHAR *Section, const TCHAR *Key, INI_REAL DefValue, const TCHAR *Filename)
{
TCHAR LocalBuffer[64];
int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename);
return (len == 0) ? DefValue : ini_atof(LocalBuffer);
}
#endif
/** ini_getbool()
* \param Section the name of the section to search for
* \param Key the name of the entry to find the value of
* \param DefValue default value in the event of a failed read; it should
* zero (0) or one (1).
* \param Buffer a pointer to the buffer to copy into
* \param BufferSize the maximum number of characters to copy
* \param Filename the name and full path of the .ini file to read from
*
* A true boolean is found if one of the following is matched:
* - A string starting with 'y' or 'Y'
* - A string starting with 't' or 'T'
* - A string starting with '1'
*
* A false boolean is found if one of the following is matched:
* - A string starting with 'n' or 'N'
* - A string starting with 'f' or 'F'
* - A string starting with '0'
*
* \return the true/false flag as interpreted at Key
*/
int ini_getbool(const TCHAR *Section, const TCHAR *Key, int DefValue, const TCHAR *Filename)
{
TCHAR LocalBuffer[2] = __T("");
int ret;
ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename);
LocalBuffer[0] = (TCHAR)_totupper((int)LocalBuffer[0]);
if (LocalBuffer[0] == 'Y' || LocalBuffer[0] == '1' || LocalBuffer[0] == 'T')
ret = 1;
else if (LocalBuffer[0] == 'N' || LocalBuffer[0] == '0' || LocalBuffer[0] == 'F')
ret = 0;
else
ret = DefValue;
return(ret);
}
/** ini_getsection()
* \param idx the zero-based sequence number of the section to return
* \param Buffer a pointer to the buffer to copy into
* \param BufferSize the maximum number of characters to copy
* \param Filename the name and full path of the .ini file to read from
*
* \return the number of characters copied into the supplied buffer
*/
int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
INI_FILETYPE fp;
int ok = 0;
if (Buffer == NULL || BufferSize <= 0 || idx < 0)
return 0;
if (ini_openread(Filename, &fp)) {
ok = getkeystring(&fp, NULL, NULL, idx, -1, Buffer, BufferSize, NULL);
(void)ini_close(&fp);
} /* if */
if (!ok)
*Buffer = '\0';
return (int)_tcslen(Buffer);
}
/** ini_getkey()
* \param Section the name of the section to browse through, or NULL to
* browse through the keys outside any section
* \param idx the zero-based sequence number of the key to return
* \param Buffer a pointer to the buffer to copy into
* \param BufferSize the maximum number of characters to copy
* \param Filename the name and full path of the .ini file to read from
*
* \return the number of characters copied into the supplied buffer
*/
int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
INI_FILETYPE fp;
int ok = 0;
if (Buffer == NULL || BufferSize <= 0 || idx < 0)
return 0;
if (ini_openread(Filename, &fp)) {
ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize, NULL);
(void)ini_close(&fp);
} /* if */
if (!ok)
*Buffer = '\0';
return (int)_tcslen(Buffer);
}
#if !defined INI_NOBROWSE
/** ini_browse()
* \param Callback a pointer to a function that will be called for every
* setting in the INI file.
* \param UserData arbitrary data, which the function passes on the the
* \c Callback function
* \param Filename the name and full path of the .ini file to read from
*
* \return 1 on success, 0 on failure (INI file not found)
*
* \note The \c Callback function must return 1 to continue
* browsing through the INI file, or 0 to stop. Even when the
* callback stops the browsing, this function will return 1
* (for success).
*/
int ini_browse(INI_CALLBACK Callback, const void *UserData, const TCHAR *Filename)
{
TCHAR LocalBuffer[INI_BUFFERSIZE];
int lenSec, lenKey;
enum quote_option quotes;
INI_FILETYPE fp;
if (Callback == NULL)
return 0;
if (!ini_openread(Filename, &fp))
return 0;
LocalBuffer[0] = '\0'; /* copy an empty section in the buffer */
lenSec = (int)_tcslen(LocalBuffer) + 1;
for ( ;; ) {
TCHAR *sp, *ep;
if (!ini_read(LocalBuffer + lenSec, INI_BUFFERSIZE - lenSec, &fp))
break;
sp = skipleading(LocalBuffer + lenSec);
/* ignore empty strings and comments */
if (*sp == '\0' || *sp == ';' || *sp == '#')
continue;
/* see whether we reached a new section */
ep = _tcschr(sp, ']');
if (*sp == '[' && ep != NULL) {
*ep = '\0';
save_strncpy(LocalBuffer, sp + 1, INI_BUFFERSIZE, QUOTE_NONE);
lenSec = (int)_tcslen(LocalBuffer) + 1;
continue;
} /* if */
/* not a new section, test for a key/value pair */
ep = _tcschr(sp, '='); /* test for the equal sign or colon */
if (ep == NULL)
ep = _tcschr(sp, ':');
if (ep == NULL)
continue; /* invalid line, ignore */
*ep++ = '\0'; /* split the key from the value */
striptrailing(sp);
save_strncpy(LocalBuffer + lenSec, sp, INI_BUFFERSIZE - lenSec, QUOTE_NONE);
lenKey = (int)_tcslen(LocalBuffer + lenSec) + 1;
/* clean up the value */
sp = skipleading(ep);
sp = cleanstring(sp, &quotes); /* Remove a trailing comment */
save_strncpy(LocalBuffer + lenSec + lenKey, sp, INI_BUFFERSIZE - lenSec - lenKey, quotes);
/* call the callback */
if (!Callback(LocalBuffer, LocalBuffer + lenSec, LocalBuffer + lenSec + lenKey, UserData))
break;
} /* for */
(void)ini_close(&fp);
return 1;
}
#endif /* INI_NOBROWSE */
#if ! defined INI_READONLY
static void ini_tempname(TCHAR *dest, const TCHAR *source, int maxlength)
{
TCHAR *p;
save_strncpy(dest, source, maxlength, QUOTE_NONE);
p = _tcsrchr(dest, '\0');
assert(p != NULL);
*(p - 1) = '~';
}
static enum quote_option check_enquote(const TCHAR *Value)
{
const TCHAR *p;
/* run through the value, if it has trailing spaces, or '"', ';' or '#'
* characters, enquote it
*/
assert(Value != NULL);
for (p = Value; *p != '\0' && *p != '"' && *p != ';' && *p != '#'; p++)
/* nothing */;
return (*p != '\0' || (p > Value && *(p - 1) == ' ')) ? QUOTE_ENQUOTE : QUOTE_NONE;
}
static void writesection(TCHAR *LocalBuffer, const TCHAR *Section, INI_FILETYPE *fp)
{
if (Section != NULL && _tcslen(Section) > 0) {
TCHAR *p;
LocalBuffer[0] = '[';
save_strncpy(LocalBuffer + 1, Section, INI_BUFFERSIZE - 4, QUOTE_NONE); /* -1 for '[', -1 for ']', -2 for '\r\n' */
p = _tcsrchr(LocalBuffer, '\0');
assert(p != NULL);
*p++ = ']';
_tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */
if (fp != NULL)
(void)ini_write(LocalBuffer, fp);
} /* if */
}
static void writekey(TCHAR *LocalBuffer, const TCHAR *Key, const TCHAR *Value, INI_FILETYPE *fp)
{
TCHAR *p;
enum quote_option option = check_enquote(Value);
save_strncpy(LocalBuffer, Key, INI_BUFFERSIZE - 3, QUOTE_NONE); /* -1 for '=', -2 for '\r\n' */
p = _tcsrchr(LocalBuffer, '\0');
assert(p != NULL);
*p++ = '=';
save_strncpy(p, Value, INI_BUFFERSIZE - (p - LocalBuffer) - 2, option); /* -2 for '\r\n' */
p = _tcsrchr(LocalBuffer, '\0');
assert(p != NULL);
_tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */
if (fp != NULL)
(void)ini_write(LocalBuffer, fp);
}
static int cache_accum(const TCHAR *string, int *size, int max)
{
int len = (int)_tcslen(string);
if (*size + len >= max)
return 0;
*size += len;
return 1;
}
static int cache_flush(TCHAR *buffer, int *size,
INI_FILETYPE *rfp, INI_FILETYPE *wfp, INI_FILEPOS *mark)
{
int terminator_len = (int)_tcslen(INI_LINETERM);
int pos = 0;
(void)ini_seek(rfp, mark);
assert(buffer != NULL);
buffer[0] = '\0';
assert(size != NULL);
assert(*size <= INI_BUFFERSIZE);
while (pos < *size) {
(void)ini_read(buffer + pos, INI_BUFFERSIZE - pos, rfp);
while (pos < *size && buffer[pos] != '\0')
pos++; /* cannot use _tcslen() because buffer may not be zero-terminated */
} /* while */
if (buffer[0] != '\0') {
assert(pos > 0 && pos <= INI_BUFFERSIZE);
if (pos == INI_BUFFERSIZE)
pos--;
buffer[pos] = '\0'; /* force zero-termination (may be left unterminated in the above while loop) */
(void)ini_write(buffer, wfp);
}
ini_tell(rfp, mark); /* update mark */
*size = 0;
/* return whether the buffer ended with a line termination */
return (pos > terminator_len) && (_tcscmp(buffer + pos - terminator_len, INI_LINETERM) == 0);
}
static int close_rename(INI_FILETYPE *rfp, INI_FILETYPE *wfp, const TCHAR *filename, TCHAR *buffer)
{
(void)ini_close(rfp);
(void)ini_close(wfp);
(void)ini_remove(filename);
(void)ini_tempname(buffer, filename, INI_BUFFERSIZE);
(void)ini_rename(buffer, filename);
return 1;
}
/** ini_puts()
* \param Section the name of the section to write the string in
* \param Key the name of the entry to write, or NULL to erase all keys in the section
* \param Value a pointer to the buffer the string, or NULL to erase the key
* \param Filename the name and full path of the .ini file to write to
*
* \return 1 if successful, otherwise 0
*/
int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename)
{
INI_FILETYPE rfp;
INI_FILETYPE wfp;
INI_FILEPOS mark;
INI_FILEPOS head, tail;
TCHAR *sp, *ep;
TCHAR LocalBuffer[INI_BUFFERSIZE];
int len, match, flag, cachelen;
assert(Filename != NULL);
if (!ini_openread(Filename, &rfp)) {
/* If the .ini file doesn't exist, make a new file */
if (Key != NULL && Value != NULL) {
if (!ini_openwrite(Filename, &wfp))
return 0;
writesection(LocalBuffer, Section, &wfp);
writekey(LocalBuffer, Key, Value, &wfp);
(void)ini_close(&wfp);
} /* if */
return 1;
} /* if */
/* If parameters Key and Value are valid (so this is not an "erase" request)
* and the setting already exists, there are two short-cuts to avoid rewriting
* the INI file.
*/
if (Key != NULL && Value != NULL) {
ini_tell(&rfp, &mark);
match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer), &head);
if (match) {
/* if the current setting is identical to the one to write, there is
* nothing to do.
*/
if (_tcscmp(LocalBuffer,Value) == 0) {
(void)ini_close(&rfp);
return 1;
} /* if */
/* if the new setting has the same length as the current setting, and the
* glue file permits file read/write access, we can modify in place.
*/
#if defined ini_openrewrite
/* we already have the start of the (raw) line, get the end too */
ini_tell(&rfp, &tail);
/* create new buffer (without writing it to file) */
writekey(LocalBuffer, Key, Value, NULL);
if (_tcslen(LocalBuffer) == (size_t)(tail - head)) {
/* length matches, close the file & re-open for read/write, then
* write at the correct position
*/
(void)ini_close(&rfp);
if (!ini_openrewrite(Filename, &wfp))
return 0;
(void)ini_seek(&wfp, &head);
(void)ini_write(LocalBuffer, &wfp);
(void)ini_close(&wfp);
return 1;
} /* if */
#endif
} /* if */
/* key not found, or different value & length -> proceed (but rewind the
* input file first)
*/
(void)ini_seek(&rfp, &mark);
} /* if */
/* Get a temporary file name to copy to. Use the existing name, but with
* the last character set to a '~'.
*/
ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
if (!ini_openwrite(LocalBuffer, &wfp)) {
(void)ini_close(&rfp);
return 0;
} /* if */
ini_tell(&rfp, &mark);
cachelen = 0;
/* Move through the file one line at a time until a section is
* matched or until EOF. Copy to temp file as it is read.
*/
len = (Section != NULL) ? (int)_tcslen(Section) : 0;
if (len > 0) {
do {
if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
/* Failed to find section, so add one to the end */
flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
if (Key!=NULL && Value!=NULL) {
if (!flag)
(void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */
writesection(LocalBuffer, Section, &wfp);
writekey(LocalBuffer, Key, Value, &wfp);
} /* if */
return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */
} /* if */
/* Copy the line from source to dest, but not if this is the section that
* we are looking for and this section must be removed
*/
sp = skipleading(LocalBuffer);
ep = _tcschr(sp, ']');
match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0);
if (!match || Key != NULL) {
if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
(void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
} /* if */
} /* if */
} while (!match);
} /* if */
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
/* when deleting a section, the section head that was just found has not been
* copied to the output file, but because this line was not "accumulated" in
* the cache, the position in the input file was reset to the point just
* before the section; this must now be skipped (again)
*/
if (Key == NULL) {
(void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
ini_tell(&rfp, &mark);
} /* if */
/* Now that the section has been found, find the entry. Stop searching
* upon leaving the section's area. Copy the file as it is read
* and create an entry if one is not found.
*/
len = (Key != NULL) ? (int)_tcslen(Key) : 0;
for( ;; ) {
if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
/* EOF without an entry so make one */
flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
if (Key!=NULL && Value!=NULL) {
if (!flag)
(void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */
writekey(LocalBuffer, Key, Value, &wfp);
} /* if */
return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */
} /* if */
sp = skipleading(LocalBuffer);
ep = _tcschr(sp, '='); /* Parse out the equal sign */
if (ep == NULL)
ep = _tcschr(sp, ':');
match = (ep != NULL && len > 0 && (int)(skiptrailing(ep,sp)-sp) == len && _tcsnicmp(sp,Key,len) == 0);
if ((Key != NULL && match) || *sp == '[')
break; /* found the key, or found a new section */
/* copy other keys in the section */
if (Key == NULL) {
ini_tell(&rfp, &mark); /* we are deleting the entire section, so update the read position */
} else {
if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
(void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
} /* if */
} /* if */
} /* for */
/* the key was found, or we just dropped on the next section (meaning that it
* wasn't found); in both cases we need to write the key, but in the latter
* case, we also need to write the line starting the new section after writing
* the key
*/
flag = (*sp == '[');
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
if (Key != NULL && Value != NULL)
writekey(LocalBuffer, Key, Value, &wfp);
/* cache_flush() reset the "read pointer" to the start of the line with the
* previous key or the new section; read it again (because writekey() destroyed
* the buffer)
*/
(void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
if (flag) {
/* the new section heading needs to be copied to the output file */
cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
} else {
/* forget the old key line */
ini_tell(&rfp, &mark);
} /* if */
/* Copy the rest of the INI file */
while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
(void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
} /* if */
} /* while */
cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */
}
/* Ansi C "itoa" based on Kernighan & Ritchie's "Ansi C" book. */
#define ABS(v) ((v) < 0 ? -(v) : (v))
static void strreverse(TCHAR *str)
{
int i, j;
for (i = 0, j = (int)_tcslen(str) - 1; i < j; i++, j--) {
TCHAR t = str[i];
str[i] = str[j];
str[j] = t;
} /* for */
}
static void long2str(long value, TCHAR *str)
{
int i = 0;
long sign = value;
int n;
/* generate digits in reverse order */
do {
n = (int)(value % 10); /* get next lowest digit */
str[i++] = (TCHAR)(ABS(n) + '0'); /* handle case of negative digit */
} while (value /= 10); /* delete the lowest digit */
if (sign < 0)
str[i++] = '-';
str[i] = '\0';
strreverse(str);
}
/** ini_putl()
* \param Section the name of the section to write the value in
* \param Key the name of the entry to write
* \param Value the value to write
* \param Filename the name and full path of the .ini file to write to
*
* \return 1 if successful, otherwise 0
*/
int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename)
{
TCHAR LocalBuffer[32];
long2str(Value, LocalBuffer);
return ini_puts(Section, Key, LocalBuffer, Filename);
}
#if defined INI_REAL
/** ini_putf()
* \param Section the name of the section to write the value in
* \param Key the name of the entry to write
* \param Value the value to write
* \param Filename the name and full path of the .ini file to write to
*
* \return 1 if successful, otherwise 0
*/
int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR *Filename)
{
TCHAR LocalBuffer[64];
ini_ftoa(LocalBuffer, Value);
return ini_puts(Section, Key, LocalBuffer, Filename);
}
#endif /* INI_REAL */
#endif /* !INI_READONLY */

@ -1,152 +0,0 @@
/* minIni - Multi-Platform INI file parser, suitable for embedded systems
*
* Copyright (c) CompuPhase, 2008-2012
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: minIni.h 5181 2015-01-21 09:44:28Z thiadmer $
*/
#ifndef MININI_H
#define MININI_H
#include "minGlue.h"
#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined INI_ANSIONLY
#include <tchar.h>
#define mTCHAR TCHAR
#else
/* force TCHAR to be "char", but only for minIni */
#define mTCHAR char
#endif
#if !defined INI_BUFFERSIZE
#define INI_BUFFERSIZE 512
#endif
#if defined __cplusplus
extern "C" {
#endif
int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
#if defined INI_REAL
INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename);
#endif
#if !defined INI_READONLY
int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
#if defined INI_REAL
int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
#endif
#endif /* INI_READONLY */
#if !defined INI_NOBROWSE
typedef int (*INI_CALLBACK)(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const void *UserData);
int ini_browse(INI_CALLBACK Callback, const void *UserData, const mTCHAR *Filename);
#endif /* INI_NOBROWSE */
#if defined __cplusplus
}
#endif
#if defined __cplusplus
#if defined __WXWINDOWS__
#include "wxMinIni.h"
#else
#include <string>
/* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */
class minIni
{
public:
minIni(const std::string& filename) : iniFilename(filename)
{ }
bool getbool(const std::string& Section, const std::string& Key, bool DefValue=false) const
{ return ini_getbool(Section.c_str(), Key.c_str(), int(DefValue), iniFilename.c_str()) != 0; }
long getl(const std::string& Section, const std::string& Key, long DefValue=0) const
{ return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
int geti(const std::string& Section, const std::string& Key, int DefValue=0) const
{ return static_cast<int>(this->getl(Section, Key, long(DefValue))); }
std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const
{
char buffer[INI_BUFFERSIZE];
ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
std::string getsection(int idx) const
{
char buffer[INI_BUFFERSIZE];
ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
std::string getkey(const std::string& Section, int idx) const
{
char buffer[INI_BUFFERSIZE];
ini_getkey(Section.c_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
#if defined INI_REAL
INI_REAL getf(const std::string& Section, const std::string& Key, INI_REAL DefValue=0) const
{ return ini_getf(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
#endif
#if ! defined INI_READONLY
bool put(const std::string& Section, const std::string& Key, long Value) const
{ return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, int Value) const
{ return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, bool Value) const
{ return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, const std::string& Value) const
{ return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, const char* Value) const
{ return ini_puts(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
#if defined INI_REAL
bool put(const std::string& Section, const std::string& Key, INI_REAL Value) const
{ return ini_putf(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
#endif
bool del(const std::string& Section, const std::string& Key) const
{ return ini_puts(Section.c_str(), Key.c_str(), 0, iniFilename.c_str()) != 0; }
bool del(const std::string& Section) const
{ return ini_puts(Section.c_str(), 0, 0, iniFilename.c_str()) != 0; }
#endif
private:
std::string iniFilename;
};
#endif /* __WXWINDOWS__ */
#endif /* __cplusplus */
#endif /* MININI_H */

@ -1,159 +0,0 @@
/*
* Platform
* __MSDOS__ set when compiling for DOS (not Windows)
* _Windows set when compiling for any version of Microsoft Windows
* __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode)
* __32BIT__ set when compiling in 32-bit "flat" mode (DOS, Windows, ARM)
* __64BIT__ set when compiling in 64-bit mode
* __ECOS__ set if Pawn was included with the eCos with configtool
* __LINUX__ set when compiling for Linux
*
* Copyright 1998-2011, ITB CompuPhase, The Netherlands.
* No usage restrictions, no warranties.
*/
#ifndef _OSDEFS_H
#define _OSDEFS_H
/* Every compiler uses different "default" macros to indicate the mode
* it is in. Throughout the source, we use the Borland C++ macros, so
* the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to
* those of Borland C++.
*/
#if defined(__WATCOMC__)
#if defined(__WINDOWS__) || defined(__NT__)
#define _Windows 1
#endif
#if defined(__386__) || defined(__NT__)
#define __32BIT__ 1
#endif
#if defined(_Windows) && defined(__32BIT__)
#define __WIN32__ 1
#endif
#elif defined(_MSC_VER)
#if defined(_WINDOWS) || defined(_WIN32)
#define _Windows 1
#endif
#if defined(_WIN32)
#define __WIN32__ 1
#define __32BIT__ 1
#endif
#elif defined __arm__
#define __32BIT__ 1
#elif defined __AVR__
#define __16BIT__ 1
#endif
#if !defined __16BIT__ && !defined __32BIT__ && !defined __64BIT__
#define __32BIT__ 1
#endif
#if (defined __linux || defined __linux__) && !defined __LINUX__
#define __LINUX__
#endif
/* To be able to eventually set __ECOS__, we have to find a symbol
* defined in a common place (so including the header file won't break
* anything for other platforms). <sys/types.h> includes
* <pkgconf/system.h> and in this later file we can find CYGPKG_PAWN
* if the Pawn package was included with configtool and so we know
* that we are compiling for eCos.
*/
#if defined CCSINFO
#include <sys/types.h>
#endif
#if defined CYGPKG_PAWN
#define __ECOS__ 1
#define HAVE_ALLOCA_H 0
#endif
#if defined __FreeBSD__
#include <sys/endian.h>
#elif defined __LINUX__
#include <endian.h>
#elif defined __ECOS__
#include <cyg/hal/hal_endian.h>
#define BIG_ENDIAN 4321
#define LITTLE_ENDIAN 1234
#if (CYG_BYTEORDER == CYG_LSBFIRST)
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN
#endif
/*
* eCos option management.
*/
#include <pkgconf/pawn.h>
#if CYGPKG_PAWN_AMX_ANSIONLY==1
#define AMX_ANSIONLY
#endif
#define PAWN_CELL_SIZE CYGPKG_PAWN_AMX_CELLSIZE
#if CYGPKG_PAWN_CORE_RANDOM==0
#define AMX_NORANDOM
#endif
#if CYGPKG_PAWN_CORE_PROPERTY==0
#define AMX_NOPROPLIST
#endif
#if CYGPKG_PAWN_AMX_CONS_FIXEDPOINT==1
#define FIXEDPOINT
#endif
#if CYGPKG_PAWN_AMX_CONS_FLOATPOINT==1
#define FLOATPOINT
#endif
#endif
/* Linux now has these */
#if !defined BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#if !defined LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */
#if !defined BYTE_ORDER
#if defined UCLINUX
#define BYTE_ORDER BIG_ENDIAN
#else
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif
#if defined __MSDOS__ || defined __WIN32__ || defined _Windows
#define DIRSEP_CHAR '\\'
#elif defined macintosh /* only the original Macintosh uses ':', OSX uses the '/' */
#define DIRSEP_CHAR ':'
#else
#define DIRSEP_CHAR '/'
#endif
/* _MAX_PATH is sometimes called differently and it may be in limits.h or
* stdlib.h instead of stdio.h.
*/
#if !defined _MAX_PATH
/* not defined, perhaps stdio.h was not included */
#if !defined PATH_MAX
#include <stdio.h>
#endif
#if !defined _MAX_PATH && !defined PATH_MAX
/* no _MAX_PATH and no MAX_PATH, perhaps it is in limits.h */
#include <limits.h>
#endif
#if !defined _MAX_PATH && !defined PATH_MAX
/* no _MAX_PATH and no MAX_PATH, perhaps it is in stdlib.h */
#include <stdlib.h>
#endif
/* if _MAX_PATH is undefined, try common alternative names */
#if !defined _MAX_PATH
#if defined MAX_PATH
#define _MAX_PATH MAX_PATH
#elif defined _POSIX_PATH_MAX
#define _MAX_PATH _POSIX_PATH_MAX
#else
/* everything failed, actually we have a problem here... */
#define _MAX_PATH 1024
#endif
#endif
#endif
#endif /* _OSDEFS_H */

@ -200,7 +200,6 @@ int main(int argc, char *argv[])
Utils::printVersion("TES3MP dedicated server", TES3MP_VERSION, version.mCommitHash, TES3MP_PROTO_VERSION);
setenv("AMXFILE", moddir.c_str(), 1);
setenv("MOD_DIR", moddir.c_str(), 1); // hack for lua
setenv("LUA_PATH", Utils::convertPath(plugin_home + "/scripts/?.lua" + ";"

@ -1,23 +0,0 @@
forward OnCreate(ID);
forward OnDestroy(ID);
forward OnSpawn(ID);
forward OnActivate(ID, actor);
forward OnCellChange(ID, cell);
forward OnItemCountChange(ID, count);
forward OnItemConditionChange(ID, Float:condition);
forward OnItemEquippedChange(ID, Bool:equipped);
forward OnActorValueChange(ID, ActorValue:index, Float:value);
forward OnActorBaseValueChange(ID, ActorValue:index, Float:value);
forward OnActorSneak(ID, Bool:sneaking);
forward OnActorDeath(ID, killer, cause);
forward OnActorAttack(victim, attacker, weapon, damage);
forward OnPlayerDisconnect(ID, reason);
forward OnPlayerRequestGame(ID);
forward OnPlayerChat(ID, message{});
forward OnClientAuthenticate(const name{}, const pwd{});
forward OnGameTimeChange(year, month, day, hour);
forward OnServerInit();
forward OnServerExit(Bool:error);
forward OnCharGen(ID);

@ -1,30 +0,0 @@
const Sex: {
Male = 0,
Female = 1,
}
const Race: {
Argoninan = "Argonian",
Breton = "Breton",
DarkElf = "Dark Elf",
HighElf = "High Elf",
Imperial = "Imperial",
Khajiit = "Khajiit",
Nord = "Nord",
Orc = "Orc",
Redguard = "Redguard",
WoodElf = "Wood Elf"
}
native Bool:Kick(ID);
native SetRespawnTime(interval);
native GetRespawnTime();
native SetSpawnCell(cell);
native GetSpawnCell();
native Bool:IsPlayer(ID);
native GetBaseName(ID, message);
native SetBaseName(ID);
native CharGen(ID);

@ -1,10 +0,0 @@
native Bool:IsCell(cell);
native Bool:IsInterior(cell);
native GetPosition(ID, Float:x, Float:y, Float:z);
native SetPosition(ID, Float:x, Float:y, Float:z);
native GetRotation(ID, Float:x, Float:y, Float:z);
native SetRotation(ID, Float:x, Float:y, Float:z);
native SetCell(ID, cell);
native GetCell(ID);

@ -1,15 +0,0 @@
native SetGameWeather(weather);
native SetGameTime(time);
native SetGameYear(year);
native SetGameMonth(month);
native SetGameDay(day);
native SetGameHour(hour);
native SetTimeScale(Float:scale);
native GetGameWeather();
native GetGameTime();
native GetGameYear();
native GetGameMonth();
native GetGameDay();
native GetGameHour();
native Float:GetTimeScale();
Loading…
Cancel
Save