Skip to content

Commit

Permalink
Merge pull request #182 from fingolfin/forbid-ctype
Browse files Browse the repository at this point in the history
ALL: Avoid using is* macros from ctype.h
  • Loading branch information
wjp committed Feb 21, 2012
2 parents 80b3439 + 02ebd55 commit 9ffe3e1
Show file tree
Hide file tree
Showing 41 changed files with 236 additions and 105 deletions.
2 changes: 1 addition & 1 deletion base/commandLine.cpp
Expand Up @@ -277,7 +277,7 @@ void registerDefaults() {
// resp. between "--some-option" and "--no-some-option".
#define DO_OPTION_BOOL(shortCmd, longCmd) \
if (isLongCmd ? (!strcmp(s+2, longCmd) || !strcmp(s+2, "no-"longCmd)) : (tolower(s[1]) == shortCmd)) { \
bool boolValue = (islower(static_cast<unsigned char>(s[1])) != 0); \
bool boolValue = (Common::isLower(s[1]) != 0); \
s += 2; \
if (isLongCmd) { \
boolValue = !strcmp(s, longCmd); \
Expand Down
6 changes: 3 additions & 3 deletions common/config-file.cpp
Expand Up @@ -30,7 +30,7 @@ namespace Common {

bool ConfigFile::isValidName(const String &name) {
const char *p = name.c_str();
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
return *p == 0;
}
Expand Down Expand Up @@ -108,7 +108,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;

if (*p == '\0')
Expand All @@ -131,7 +131,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {

// Skip leading whitespaces
const char *t = line.c_str();
while (isspace(static_cast<unsigned char>(*t)))
while (isSpace(*t))
t++;

// Skip empty lines / lines with only whitespace
Expand Down
6 changes: 3 additions & 3 deletions common/config-manager.cpp
Expand Up @@ -29,7 +29,7 @@

static bool isValidDomainName(const Common::String &domName) {
const char *p = domName.c_str();
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
while (*p && (Common::isAlnum(*p) || *p == '-' || *p == '_'))
p++;
return *p == 0;
}
Expand Down Expand Up @@ -187,7 +187,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Get the domain name, and check whether it's valid (that
// is, verify that it only consists of alphanumerics,
// dashes and underscores).
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_'))
p++;

if (*p == '\0')
Expand All @@ -205,7 +205,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {

// Skip leading whitespaces
const char *t = line.c_str();
while (isspace(static_cast<unsigned char>(*t)))
while (isSpace(*t))
t++;

// Skip empty lines / lines with only whitespace
Expand Down
43 changes: 43 additions & 0 deletions common/forbidden.h
Expand Up @@ -317,6 +317,49 @@

#endif // FORBIDDEN_SYMBOL_EXCEPTION_unistd_h


//
// Disable various symbols from ctype.h
//
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_ctype_h

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalnum
#undef isalnum
#define isalnum(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalpha
#undef isalpha
#define isalpha(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isdigit
#undef isdigit
#define isdigit(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isnumber
#undef isnumber
#define isnumber(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_islower
#undef islower
#define islower(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isspace
#undef isspace
#define isspace(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_isupper
#undef isupper
#define isupper(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif

#endif // FORBIDDEN_SYMBOL_EXCEPTION_ctype_h

#ifndef FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#undef mkdir
#define mkdir(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
Expand Down
8 changes: 4 additions & 4 deletions common/str.cpp
Expand Up @@ -405,13 +405,13 @@ void String::trim() {
makeUnique();

// Trim trailing whitespace
while (_size >= 1 && isspace(static_cast<unsigned char>(_str[_size - 1])))
while (_size >= 1 && isSpace(_str[_size - 1]))
--_size;
_str[_size] = 0;

// Trim leading whitespace
char *t = _str;
while (isspace((unsigned char)*t))
while (isSpace(*t))
t++;

if (t != _str) {
Expand Down Expand Up @@ -606,14 +606,14 @@ String operator+(const String &x, char y) {
}

char *ltrim(char *t) {
while (isspace(static_cast<unsigned char>(*t)))
while (isSpace(*t))
t++;
return t;
}

char *rtrim(char *t) {
int l = strlen(t) - 1;
while (l >= 0 && isspace(static_cast<unsigned char>(t[l])))
while (l >= 0 && isSpace(t[l]))
t[l--] = 0;
return t;
}
Expand Down
43 changes: 43 additions & 0 deletions common/util.cpp
Expand Up @@ -19,6 +19,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#define FORBIDDEN_SYMBOL_EXCEPTION_isalnum
#define FORBIDDEN_SYMBOL_EXCEPTION_isalpha
#define FORBIDDEN_SYMBOL_EXCEPTION_isdigit
#define FORBIDDEN_SYMBOL_EXCEPTION_isnumber
#define FORBIDDEN_SYMBOL_EXCEPTION_islower
#define FORBIDDEN_SYMBOL_EXCEPTION_isspace
#define FORBIDDEN_SYMBOL_EXCEPTION_isupper


#include "common/util.h"
#include "common/translation.h"
#include "common/config-manager.h"
Expand Down Expand Up @@ -406,4 +415,38 @@ void updateGameGUIOptions(const String &options, const String &langOption) {
}
}

#define ENSURE_ASCII_CHAR(c) \
if (c < 0 || c > 127) \
return false

bool isAlnum(int c) {
ENSURE_ASCII_CHAR(c);
return isalnum((byte)c);
}

bool isAlpha(int c) {
ENSURE_ASCII_CHAR(c);
return isalpha((byte)c);
}

bool isDigit(int c) {
ENSURE_ASCII_CHAR(c);
return isdigit((byte)c);
}

bool isLower(int c) {
ENSURE_ASCII_CHAR(c);
return islower((byte)c);
}

bool isSpace(int c) {
ENSURE_ASCII_CHAR(c);
return isspace((byte)c);
}

bool isUpper(int c) {
ENSURE_ASCII_CHAR(c);
return isupper((byte)c);
}

} // End of namespace Common
64 changes: 64 additions & 0 deletions common/util.h
Expand Up @@ -133,6 +133,70 @@ extern void hexdump(const byte * data, int len, int bytesPerLine = 16, int start
*/
bool parseBool(const String &val, bool &valAsBool);


/**
* Test whether the given character is alphanumeric (a-z, A-Z, 0-9).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is alphanumeric, false otherwise.
*/
bool isAlnum(int c);

/**
* Test whether the given character is an alphabetic letter (a-z, A-Z).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is TODO, false otherwise.
*/
bool isAlpha(int c);

/**
* Test whether the given character is a decimal-digit (0-9).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is a decimal-digit, false otherwise.
*/
bool isDigit(int c);

/**
* Test whether the given character is a lower-case letter (a-z).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is a lower-case letter, false otherwise.
*/
bool isLower(int c);

/**
* Test whether the given character is a white-space.
* White-space characters are ' ', '\t', '\r', '\n', '\v', '\f'.
*
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is a white-space, false otherwise.
*/
bool isSpace(int c);

/**
* Test whether the given character is an upper-case letter (A-Z).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is an upper-case letter, false otherwise.
*/
bool isUpper(int c);


/**
* List of game language.
*/
Expand Down
10 changes: 5 additions & 5 deletions common/xmlparser.cpp
Expand Up @@ -263,15 +263,15 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
int *num_ptr;

while (count--) {
while (isspace(static_cast<unsigned char>(*key)))
while (isSpace(*key))
key++;

num_ptr = va_arg(args, int*);
*num_ptr = strtol(key, &parseEnd, 10);

key = parseEnd;

while (isspace(static_cast<unsigned char>(*key)))
while (isSpace(*key))
key++;

if (count && *key++ != ',')
Expand Down Expand Up @@ -463,10 +463,10 @@ bool XMLParser::parse() {
}

bool XMLParser::skipSpaces() {
if (!isspace(static_cast<unsigned char>(_char)))
if (!isSpace(_char))
return false;

while (_char && isspace(static_cast<unsigned char>(_char)))
while (_char && isSpace(_char))
_char = _stream->readByte();

return true;
Expand Down Expand Up @@ -516,7 +516,7 @@ bool XMLParser::parseToken() {
_char = _stream->readByte();
}

return isspace(static_cast<unsigned char>(_char)) != 0 || _char == '>' || _char == '=' || _char == '/';
return isSpace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
}

} // End of namespace Common
2 changes: 1 addition & 1 deletion common/xmlparser.h
Expand Up @@ -295,7 +295,7 @@ class XMLParser {
* in their name.
*/
virtual inline bool isValidNameChar(char c) {
return isalnum(static_cast<unsigned char>(c)) || c == '_';
return isAlnum(c) || c == '_';
}

/**
Expand Down
14 changes: 1 addition & 13 deletions engines/agi/agi.cpp
Expand Up @@ -250,19 +250,7 @@ void AgiEngine::processEvents() {
// Not a special key, so get the ASCII code for it
key = event.kbd.ascii;

// Function isalpha is defined in <ctype.h> so the following applies to it:
//
// The C Programming Language Standard states:
// The header <ctype.h> declares several functions useful for classifying
// and mapping characters. In all cases the argument is an int, the value
// of which shall be representable as an unsigned char or shall equal the
// value of the macro EOF. If the argument has any other value, the
// behavior is undefined.
//
// For a concrete example (e.g. in Microsoft Visual Studio 2003):
// When used with a debug CRT library, isalpha will display a CRT assert
// if passed a parameter that isn't EOF or in the range of 0 through 0xFF.
if (key >= 0 && key <= 0xFF && isalpha(key)) {
if (Common::isAlpha(key)) {
// Key is A-Z.
// Map Ctrl-A to 1, Ctrl-B to 2, etc.
if (event.kbd.flags & Common::KBD_CTRL) {
Expand Down
4 changes: 2 additions & 2 deletions engines/agi/wagparser.cpp
Expand Up @@ -112,11 +112,11 @@ WagFileParser::~WagFileParser() {
bool WagFileParser::checkAgiVersionProperty(const WagProperty &version) const {
if (version.getCode() == WagProperty::PC_INTVERSION && // Must be AGI interpreter version property
version.getSize() >= 3 && // Need at least three characters for a version number like "X.Y"
isdigit(static_cast<unsigned char>(version.getData()[0])) && // And the first character must be a digit
Common::isDigit(version.getData()[0]) && // And the first character must be a digit
(version.getData()[1] == ',' || version.getData()[1] == '.')) { // And the second a comma or a period

for (int i = 2; i < version.getSize(); i++) // And the rest must all be digits
if (!isdigit(static_cast<unsigned char>(version.getData()[i])))
if (!Common::isDigit(version.getData()[i]))
return false; // Bail out if found a non-digit after the decimal point

return true;
Expand Down
8 changes: 4 additions & 4 deletions engines/agos/script_pn.cpp
Expand Up @@ -466,8 +466,8 @@ void AGOSEngine_PN::opn_opcode35() {
void AGOSEngine_PN::opn_opcode36() {
for (int i = 0; i < _dataBase[57] + 1; ++i)
_wordcp[i] = 0;
if (isspace(static_cast<unsigned char>(*_inpp)))
while ((*_inpp) && (isspace(static_cast<unsigned char>(*_inpp))))
if (Common::isSpace(*_inpp))
while ((*_inpp) && (Common::isSpace(*_inpp)))
_inpp++;
if (*_inpp == 0) {
setScriptReturn(false);
Expand All @@ -481,7 +481,7 @@ void AGOSEngine_PN::opn_opcode36() {
}

int ct = 1;
while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(static_cast<unsigned char>(*_inpp))) && (*_inpp != '\0') &&
while ((*_inpp != '.') && (*_inpp != ',') && (!Common::isSpace(*_inpp)) && (*_inpp != '\0') &&
(*_inpp!='"')) {
if (ct < _dataBase[57])
_wordcp[ct++] = *_inpp;
Expand Down Expand Up @@ -581,7 +581,7 @@ void AGOSEngine_PN::opn_opcode46() {
return;
}
x++;
while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(static_cast<unsigned char>(*x))) && (*x != '\0'))
while ((*x != '.') && (*x != ',') && (*x != '"') && (!Common::isSpace(*x)) && (*x != '\0'))
pcf(*x++);
setScriptReturn(true);
}
Expand Down
2 changes: 1 addition & 1 deletion engines/agos/string.cpp
Expand Up @@ -152,7 +152,7 @@ const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) {
}

if (upperCase && *dst) {
if (islower(*dst))
if (Common::isLower(*dst))
*dst = toupper(*dst);
}

Expand Down

0 comments on commit 9ffe3e1

Please sign in to comment.