2009-05-08 13:28:41 +00:00
|
|
|
/*
|
|
|
|
* OpenClonk, http://www.openclonk.org
|
|
|
|
*
|
2009-06-05 13:41:20 +00:00
|
|
|
* Copyright (c) 1998-2000, 2007 Matthes Bender
|
|
|
|
* Copyright (c) 2002, 2004-2005, 2007 Sven Eberhardt
|
2010-12-23 00:01:24 +00:00
|
|
|
* Copyright (c) 2005, 2007, 2009 Peter Wortmann
|
2011-09-01 14:58:52 +00:00
|
|
|
* Copyright (c) 2005-2009, 2011 Günther Brammer
|
2010-12-23 00:01:24 +00:00
|
|
|
* Copyright (c) 2009-2010 Nicolas Hake
|
2009-05-08 13:28:41 +00:00
|
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
|
|
|
|
*
|
|
|
|
* Portions might be copyrighted by other authors who have contributed
|
|
|
|
* to OpenClonk.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
* See isc_license.txt for full license and disclaimer.
|
|
|
|
*
|
|
|
|
* "Clonk" is a registered trademark of Matthes Bender.
|
|
|
|
* See clonk_trademark_license.txt for full license.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* All kinds of valuable helpers */
|
|
|
|
|
|
|
|
#ifndef INC_STANDARD
|
|
|
|
#define INC_STANDARD
|
|
|
|
|
2010-03-28 23:58:02 +00:00
|
|
|
#include "PlatformAbstraction.h"
|
|
|
|
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
// Small helpers
|
|
|
|
template <class T> inline T Max(T val1, T val2) { return val1 > val2 ? val1 : val2; }
|
|
|
|
template <class T> inline T Min(T val1, T val2) { return val1 < val2 ? val1 : val2; }
|
|
|
|
template <class T> inline T Abs(T val) { return val > 0 ? val : -val; }
|
2010-04-20 16:20:24 +00:00
|
|
|
template <class T, class U, class V> inline bool Inside(T ival, U lbound, V rbound) { return ival >= lbound && ival <= rbound; }
|
2009-05-08 13:28:41 +00:00
|
|
|
template <class T> inline T BoundBy(T bval, T lbound, T rbound) { return bval < lbound ? lbound : bval > rbound ? rbound : bval; }
|
|
|
|
template <class T> inline int Sign(T val) { return val < 0 ? -1 : val > 0 ? 1 : 0; }
|
|
|
|
template <class T> inline void Swap(T &v1, T &v2) { T t = v1; v1 = v2; v2 = t; }
|
|
|
|
template <class T> inline void Toggle(T &v) { v = !v; }
|
|
|
|
|
|
|
|
inline int DWordAligned(int val)
|
2010-03-28 17:58:21 +00:00
|
|
|
{
|
2010-03-27 16:05:02 +00:00
|
|
|
if (val%4) { val>>=2; val<<=2; val+=4; }
|
2009-05-08 13:28:41 +00:00
|
|
|
return val;
|
2010-03-28 17:58:21 +00:00
|
|
|
}
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2);
|
|
|
|
int Angle(int iX1, int iY1, int iX2, int iY2);
|
|
|
|
int Pow(int base, int exponent);
|
2011-05-01 16:55:02 +00:00
|
|
|
int32_t StrToI32(const char *s, int base, const char **scan_end);
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2009-07-12 00:33:58 +00:00
|
|
|
#include <cstring>
|
2009-05-08 13:28:41 +00:00
|
|
|
inline void ZeroMem(void *lpMem, size_t dwSize)
|
2010-03-28 17:58:21 +00:00
|
|
|
{
|
2009-07-12 00:33:58 +00:00
|
|
|
std::memset(lpMem,'\0',dwSize);
|
2010-03-28 17:58:21 +00:00
|
|
|
}
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
inline void MemCopy(const void *lpMem1, void *lpMem2, size_t dwSize)
|
2010-03-28 17:58:21 +00:00
|
|
|
{
|
2009-07-12 00:33:58 +00:00
|
|
|
std::memmove(lpMem2,lpMem1,dwSize);
|
2010-03-28 17:58:21 +00:00
|
|
|
}
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
bool ForLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
|
2010-03-28 17:58:21 +00:00
|
|
|
bool (*fnCallback)(int32_t, int32_t, int32_t), int32_t iPar=0,
|
|
|
|
int32_t *lastx=NULL, int32_t *lasty=NULL);
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2009-07-12 00:33:58 +00:00
|
|
|
#include <cctype>
|
|
|
|
inline char CharCapital(char cChar) { return std::toupper(cChar); }
|
2009-05-08 13:28:41 +00:00
|
|
|
bool IsIdentifier(char cChar);
|
2010-03-25 19:57:08 +00:00
|
|
|
inline bool IsWhiteSpace(char cChar) { return !!std::isspace((unsigned char)cChar); }
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2010-04-20 16:20:24 +00:00
|
|
|
inline size_t SLen(const char *sptr) { return sptr?std::strlen(sptr):0; }
|
|
|
|
inline size_t SLenUntil(const char *szStr, char cUntil)
|
2009-07-12 00:33:58 +00:00
|
|
|
{
|
|
|
|
if (!szStr) return 0;
|
|
|
|
const char *end = std::strchr(szStr, cUntil);
|
|
|
|
return end ? end-szStr : std::strlen(szStr);
|
|
|
|
}
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2011-03-09 23:26:31 +00:00
|
|
|
// get a character at the current string pos and advance pos by that character
|
|
|
|
uint32_t GetNextUTF8Character(const char **pszString); // GetNextCharacter helper
|
|
|
|
inline uint32_t GetNextCharacter(const char **pszString)
|
|
|
|
{
|
|
|
|
unsigned char c=**pszString;
|
|
|
|
if (c<128) { ++*pszString; return c; }
|
|
|
|
else return GetNextUTF8Character(pszString);
|
|
|
|
}
|
|
|
|
// Get string length in characters (not bytes)
|
|
|
|
int GetCharacterCount(const char * s);
|
|
|
|
|
2009-07-12 00:33:58 +00:00
|
|
|
inline bool SEqual(const char *szStr1, const char *szStr2) { return szStr1&&szStr2?!std::strcmp(szStr1,szStr2):false; }
|
2009-05-08 13:28:41 +00:00
|
|
|
bool SEqual2(const char *szStr1, const char *szStr2);
|
|
|
|
bool SEqualUntil(const char *szStr1, const char *szStr2, char cWild);
|
|
|
|
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen=-1);
|
|
|
|
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen = -1);
|
|
|
|
|
2009-07-12 00:33:58 +00:00
|
|
|
inline int SCompare(const char *szStr1, const char *szStr2) { return szStr1&&szStr2?std::strcmp(szStr1,szStr2):0; }
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2010-04-20 16:20:24 +00:00
|
|
|
void SCopy(const char *szSource, char *sTarget);
|
|
|
|
void SCopy(const char *szSource, char *sTarget, size_t iMaxL);
|
2009-05-08 13:28:41 +00:00
|
|
|
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL=-1, int iIndex=0);
|
|
|
|
void SCopyUntil(const char *szSource, char *sTarget, const char * sUntil, size_t iMaxL);
|
|
|
|
void SCopyIdentifier(const char *szSource, char *sTarget, int iMaxL=0);
|
|
|
|
bool SCopyPrecedingIdentifier(const char *pBegin, const char *pIdentifier, char *sTarget, int iSize);
|
|
|
|
bool SCopySegment(const char *fstr, int segn, char *tstr, char sepa=';', int iMaxL=-1, bool fSkipWhitespace=false);
|
|
|
|
bool SCopySegmentEx(const char *fstr, int segn, char *tstr, char sepa1, char sepa2, int iMaxL=-1, bool fSkipWhitespace=false);
|
|
|
|
bool SCopyNamedSegment(const char *szString, const char *szName, char *sTarget, char cSeparator=';', char cNameSeparator='=', int iMaxL=-1);
|
|
|
|
bool SCopyEnclosed(const char *szSource, char cOpen, char cClose, char *sTarget, int iSize);
|
|
|
|
|
|
|
|
void SAppend(const char *szSource, char *szTarget, int iMaxL=-1);
|
|
|
|
void SAppendChar(char cChar, char *szStr);
|
|
|
|
|
|
|
|
void SInsert(char *szString, const char *szInsert, int iPosition=0, int iMaxLen=-1);
|
|
|
|
void SDelete(char *szString, int iLen, int iPosition=0);
|
|
|
|
|
|
|
|
int SCharPos(char cTarget, const char *szInStr, int iIndex=0);
|
|
|
|
int SCharLastPos(char cTarget, const char *szInStr);
|
2010-04-25 12:27:06 +00:00
|
|
|
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil=NULL);
|
|
|
|
unsigned int SCharCountEx(const char *szString, const char *szCharList);
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
void SReplaceChar(char *str, char fc, char tc);
|
|
|
|
|
|
|
|
const char *SSearch(const char *szString, const char *szIndex);
|
|
|
|
const char *SSearchNoCase(const char *szString, const char *szIndex);
|
|
|
|
const char *SSearchIdentifier(const char *szString, const char *szIndex);
|
|
|
|
const char *SSearchFunction(const char *szString, const char *szIndex);
|
|
|
|
|
|
|
|
const char *SAdvanceSpace(const char *szSPos);
|
|
|
|
const char *SAdvancePast(const char *szSPos, char cPast);
|
|
|
|
|
|
|
|
bool SGetModule(const char *szList, int iIndex, char *sTarget, int iSize=-1);
|
|
|
|
bool SIsModule(const char *szList, const char *szString, int *ipIndex=NULL, bool fCaseSensitive=false);
|
|
|
|
bool SAddModule(char *szList, const char *szModule, bool fCaseSensitive=false);
|
|
|
|
bool SAddModules(char *szList, const char *szModules, bool fCaseSensitive=false);
|
|
|
|
bool SRemoveModule(char *szList, const char *szModule, bool fCaseSensitive=false);
|
|
|
|
bool SRemoveModules(char *szList, const char *szModules, bool fCaseSensitive=false);
|
|
|
|
int SModuleCount(const char *szList);
|
|
|
|
|
|
|
|
void SRemoveComments(char *szScript);
|
|
|
|
void SNewSegment(char *szStr, const char *szSepa=";");
|
|
|
|
void SCapitalize(char *szString);
|
|
|
|
void SWordWrap(char *szText, char cSpace, char cSepa, int iMaxLine);
|
|
|
|
int SClearFrontBack(char *szString, char cClear=' ');
|
|
|
|
|
|
|
|
int SGetLine(const char *szText, const char *cpPosition);
|
|
|
|
int SLineGetCharacters(const char *szText, const char *cpPosition);
|
|
|
|
|
|
|
|
// case sensitive wildcard match with some extra functionality
|
|
|
|
// can match strings like "*Cl?nk*vour" to "Clonk Endeavour"
|
2009-08-15 18:50:32 +00:00
|
|
|
bool SWildcardMatchEx(const char *szString, const char *szWildcard);
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
#define LineFeed "\x00D\x00A"
|
|
|
|
|
|
|
|
// sprintf wrapper
|
|
|
|
|
2009-08-12 20:03:50 +00:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdarg>
|
2009-05-08 13:28:41 +00:00
|
|
|
|
|
|
|
// old, insecure sprintf
|
|
|
|
inline int osprintf(char *str, const char *fmt, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
|
|
|
inline int osprintf(char *str, const char *fmt, ...)
|
|
|
|
{
|
2010-03-27 16:05:02 +00:00
|
|
|
va_list args; va_start(args, fmt);
|
|
|
|
return vsprintf(str, fmt, args);
|
2009-05-08 13:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// wrapper to detect "char *"
|
|
|
|
template <typename T> struct NoPointer { static void noPointer() { } };
|
|
|
|
template <> struct NoPointer<char *> { };
|
|
|
|
|
|
|
|
// secure sprintf
|
|
|
|
#define sprintf ssprintf
|
|
|
|
template <typename T>
|
2010-03-28 17:58:21 +00:00
|
|
|
inline int ssprintf(T &str, const char *fmt, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
2009-05-08 13:28:41 +00:00
|
|
|
template <typename T>
|
2010-03-28 17:58:21 +00:00
|
|
|
inline int ssprintf(T &str, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
NoPointer<T>::noPointer();
|
|
|
|
int n = sizeof(str);
|
|
|
|
va_list args; va_start(args, fmt);
|
|
|
|
int m = vsnprintf(str, n, fmt, args);
|
|
|
|
if (m >= n) { m = n-1; str[m] = 0; }
|
|
|
|
return m;
|
|
|
|
}
|
2009-05-08 13:28:41 +00:00
|
|
|
|
2011-04-05 18:58:40 +00:00
|
|
|
// Checks a string for conformance with UTF-8
|
|
|
|
bool IsValidUtf8(const char *string, int length = -1);
|
|
|
|
|
2009-05-08 13:28:41 +00:00
|
|
|
#endif // INC_STANDARD
|