mirror of
https://github.com/zeldaret/tp
synced 2026-05-23 06:54:28 -04:00
jgadget debug improvements (#3000)
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
#ifndef BINARY_H
|
||||
#define BINARY_H
|
||||
#ifndef JGADGET_BINARY_H
|
||||
#define JGADGET_BINARY_H
|
||||
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "dolphin/types.h"
|
||||
#include "JSystem/JGadget/search.h"
|
||||
|
||||
namespace JGadget {
|
||||
@@ -12,8 +11,7 @@ struct TEBit {
|
||||
u32 value;
|
||||
};
|
||||
|
||||
const void* parseVariableUInt_16_32_following(const void* pu16, u32* pu32First, u32* pu32Second,
|
||||
TEBit* tebit);
|
||||
const void* parseVariableUInt_16_32_following(const void* pu16, u32* pu32First, u32* pu32Second, TEBit* tebit);
|
||||
|
||||
inline bool isPower2(unsigned int arg0) {
|
||||
return arg0 != 0 && (arg0 & arg0 - 1) == 0;
|
||||
@@ -57,14 +55,6 @@ struct TParse_header_block {
|
||||
bool parse(const void* ppData_inout, u32 a2) {
|
||||
return parse_next(&ppData_inout, a2);
|
||||
}
|
||||
|
||||
bool checkNext(const void** ptrLocation, u32* headerEnd, u32 idx) {
|
||||
bool checkNext = false;
|
||||
if (parseHeader_next(ptrLocation, headerEnd, idx)) {
|
||||
checkNext = true;
|
||||
}
|
||||
return checkNext;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -194,4 +184,4 @@ struct TValueIterator_misaligned : public TValueIterator<TParseValue_misaligned<
|
||||
} // namespace binary
|
||||
} // namespace JGadget
|
||||
|
||||
#endif /* BINARY_H */
|
||||
#endif /* JGADGET_BINARY_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
#ifndef JGADGET_DEFINE_H
|
||||
#define JGADGET_DEFINE_H
|
||||
|
||||
#include "types.h"
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -25,11 +25,13 @@ public:
|
||||
JGadget_outMessage& operator<<(u32);
|
||||
JGadget_outMessage& operator<<(const void*);
|
||||
|
||||
static const int BUFFER_SIZE = 256;
|
||||
|
||||
private:
|
||||
MessageFunc mMsgFunc;
|
||||
char mBuffer[256];
|
||||
char mBuffer[BUFFER_SIZE];
|
||||
char* mWrite_p;
|
||||
char* mFile;
|
||||
const char* mFile;
|
||||
int mLine;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#ifndef SEARCH_H
|
||||
#define SEARCH_H
|
||||
#ifndef JGADGET_SEARCH_H
|
||||
#define JGADGET_SEARCH_H
|
||||
|
||||
#include "dolphin/os.h"
|
||||
#include <dolphin/types.h>
|
||||
#include <iterator.h>
|
||||
#include <functional.h>
|
||||
#include <algorithm.h>
|
||||
|
||||
namespace JGadget {
|
||||
|
||||
namespace search {
|
||||
|
||||
template <typename T>
|
||||
struct TExpandStride_ {};
|
||||
|
||||
@@ -18,11 +16,29 @@ struct TExpandStride_<s32> {
|
||||
static s32 get(s32 n) { return n << 3; }
|
||||
};
|
||||
|
||||
struct TPR1IsEqual_string_ {
|
||||
TPR1IsEqual_string_(const char* sz) {
|
||||
string_ = sz;
|
||||
}
|
||||
|
||||
bool operator()(const char* sz) const {
|
||||
bool ret;
|
||||
if (string_ == NULL) {
|
||||
ret = sz == NULL;
|
||||
} else {
|
||||
ret = sz != NULL && strcmp(string_, sz) == 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* string_;
|
||||
};
|
||||
|
||||
} // namespace search
|
||||
|
||||
//! @todo: mangled name isn't correct, fix this
|
||||
//! Current: toValueFromIndex<PFdd_d>__7JGadgetFiPCPFdd_dUlRCPFdd_d
|
||||
//! Target: toValueFromIndex<PFdd_d>__7JGadgetFiPCPFdd_dUlRCPFdd_d_RCPFdd_d
|
||||
const char* toStringFromIndex(int index, const char* const* pValue, u32 count, const char* fallback);
|
||||
int toIndexFromString_linear(const char*, const char* const*, u32, int);
|
||||
|
||||
template <typename T>
|
||||
inline const T& toValueFromIndex(int idx, const T* pValue, u32 count, const T& fallback) {
|
||||
JUT_ASSERT(200, pValue!=NULL);
|
||||
@@ -34,6 +50,21 @@ inline const T& toValueFromIndex(int idx, const T* pValue, u32 count, const T& f
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Predicate>
|
||||
inline int toIndexFromValue_linear_if(Predicate p, const T* pValue, u32 count, int fallback) {
|
||||
JUT_ASSERT(212, pValue!=NULL);
|
||||
|
||||
const T* first = pValue;
|
||||
const T* last = pValue + count;
|
||||
const T* found = std::find_if(first, last, p);
|
||||
|
||||
if (found == last) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return std::distance(first, found);
|
||||
}
|
||||
|
||||
template <typename Category, typename T, typename Distance, typename Pointer, typename Reference>
|
||||
struct TIterator : public std::iterator<Category, T, Distance, Pointer, Reference> {
|
||||
};
|
||||
@@ -130,4 +161,4 @@ inline Iterator findUpperBound_binary_current(Iterator first, Iterator last, Ite
|
||||
|
||||
} // namespace JGadget
|
||||
|
||||
#endif /* SEARCH_H */
|
||||
#endif /* JGADGET_SEARCH_H */
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#ifndef JGADGET_STD_STREAM_H
|
||||
#define JGADGET_STD_STREAM_H
|
||||
|
||||
#include "JSystem/JGadget/std-streambuf.h"
|
||||
#include "global.h"
|
||||
|
||||
namespace JGadget {
|
||||
class TStream_base {
|
||||
public:
|
||||
TStream_base() {}
|
||||
virtual ~TStream_base() = 0;
|
||||
|
||||
void setf(u32);
|
||||
void setf(u32, u32);
|
||||
void width(s32);
|
||||
|
||||
s32 precision() const {
|
||||
return precision_;
|
||||
}
|
||||
|
||||
s32 width() const {
|
||||
return width_;
|
||||
}
|
||||
|
||||
u32 flags() const {
|
||||
return flags_;
|
||||
}
|
||||
|
||||
void Init_() {
|
||||
flags_ = skipws|dec;
|
||||
width_ = 0;
|
||||
precision_ = 6;
|
||||
}
|
||||
|
||||
static const u32 skipws = 0x400000;
|
||||
static const u32 dec = 0x1;
|
||||
|
||||
private:
|
||||
/* 0x4 */ u32 flags_;
|
||||
/* 0x8 */ s32 width_;
|
||||
/* 0xC */ s32 precision_;
|
||||
};
|
||||
|
||||
class TStream : public TStream_base {
|
||||
public:
|
||||
TStream();
|
||||
virtual ~TStream() = 0;
|
||||
|
||||
void init(TStreamBuffer* psb);
|
||||
bool fail() const;
|
||||
bool good() const;
|
||||
void setstate(u8 state);
|
||||
void clear(u8 state);
|
||||
TStreamBuffer* rdbuf() const;
|
||||
void fill(char);
|
||||
static char widen(char);
|
||||
static char narrow(char, char);
|
||||
|
||||
char fill() const {
|
||||
return fill_;
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0x10 */ u8 state_;
|
||||
/* 0x14 */ TStreamBuffer* rdbuf_;
|
||||
/* 0x18 */ char fill_;
|
||||
};
|
||||
|
||||
class TInputStream {
|
||||
public:
|
||||
struct sentry {
|
||||
sentry(TInputStream& stream, bool);
|
||||
|
||||
operator bool() const { return _0x0; }
|
||||
|
||||
/* 0x0 */ bool _0x0;
|
||||
};
|
||||
|
||||
int get();
|
||||
|
||||
TStream* _0x0;
|
||||
virtual ~TInputStream();
|
||||
|
||||
private:
|
||||
/* 0x08 */ int field_0x8;
|
||||
};
|
||||
|
||||
class TOutputStream {
|
||||
public:
|
||||
struct sentry {
|
||||
sentry(TOutputStream& stream) {
|
||||
_0x0 = &stream;
|
||||
|
||||
_0x4 = stream._0x0->good();
|
||||
if (!_0x4) {
|
||||
stream._0x0->setstate(2);
|
||||
}
|
||||
}
|
||||
|
||||
~sentry() {
|
||||
if (!_0x0->_0x0->fail() && (_0x0->_0x0->flags() & 2)) {
|
||||
_0x0->flush();
|
||||
}
|
||||
}
|
||||
|
||||
operator bool() const { return _0x4; }
|
||||
|
||||
/* 0x0 */ TOutputStream* _0x0;
|
||||
/* 0x4 */ bool _0x4;
|
||||
};
|
||||
|
||||
struct TBufferIterator {
|
||||
TBufferIterator(TStreamBuffer* psb) {
|
||||
buffer_ = psb;
|
||||
}
|
||||
|
||||
void operator=(char param_0) {
|
||||
if (buffer_ != NULL && TTrait_char<char>::eq_int_type(buffer_->sputc(param_0), TTrait_char<char>::eof())) {
|
||||
buffer_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TBufferIterator& operator*() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void operator++() {}
|
||||
|
||||
bool failed() const { return buffer_ == NULL; }
|
||||
|
||||
TStreamBuffer* buffer_;
|
||||
};
|
||||
|
||||
TOutputStream& operator<<(const char*);
|
||||
TOutputStream& operator<<(char);
|
||||
TOutputStream& operator<<(s32);
|
||||
TOutputStream& operator<<(u32);
|
||||
TOutputStream& operator<<(bool);
|
||||
TOutputStream& operator<<(double);
|
||||
|
||||
void flush();
|
||||
TBufferIterator& Put_CString_prefixed_(const char*, u32, const char*, u32);
|
||||
TBufferIterator& Put_longInt_(u32, bool);
|
||||
TBufferIterator& Put(double);
|
||||
|
||||
TBufferIterator& Put(const char* param_0, u32 param_1) {
|
||||
return Put_CString_prefixed_(param_0, param_1, NULL, 0);
|
||||
}
|
||||
|
||||
TBufferIterator& Put(s32 param_0) {
|
||||
return Put_longInt_(param_0, true);
|
||||
}
|
||||
|
||||
TBufferIterator& Put(u32 param_0) {
|
||||
return Put_longInt_(param_0, false);
|
||||
}
|
||||
|
||||
TBufferIterator& Put(bool param_0) {
|
||||
u32 flags = _0x0->flags();
|
||||
const TCString_* s = &saaosz_bool_[!(flags & 8) ? 0 : 1][param_0 ? 1 : 0];
|
||||
return Put_CString_prefixed_(s->sz, s->len, NULL, 0);
|
||||
}
|
||||
|
||||
TStream* _0x0;
|
||||
virtual ~TOutputStream();
|
||||
|
||||
struct TCString_ {
|
||||
const char* sz;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct saoCaseNumeral_struct {
|
||||
const char _0[16];
|
||||
TCString_ _1; // 0x10
|
||||
TCString_ _2; // 0x18
|
||||
TCString_ _3; // 0x20
|
||||
};
|
||||
|
||||
static const saoCaseNumeral_struct saoCaseNumeral_[2];
|
||||
static const TCString_ saoszPrefix_sign_[3];
|
||||
static const TCString_ saaosz_bool_[2][2];
|
||||
static const TCString_ soszPrefix_oct_;
|
||||
|
||||
static const saoCaseNumeral_struct& getCaseNumeral_(u32 flags) {
|
||||
return saoCaseNumeral_[!(flags & 4) ? 0 : 1];
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0x08 */ int field_0x8;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* JGADGET_STD_STREAM_H */
|
||||
@@ -0,0 +1,76 @@
|
||||
#ifndef JGADGET_STD_STREAMBUF_H
|
||||
#define JGADGET_STD_STREAMBUF_H
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace JGadget {
|
||||
template <typename T>
|
||||
struct TTrait_char {};
|
||||
|
||||
template <>
|
||||
struct TTrait_char<char> {
|
||||
static int eof() { return -1; }
|
||||
static int to_int_type(char value) { return (int)value; }
|
||||
static char to_char_type(int value) { return (char)value; }
|
||||
static bool eq_int_type(int a, int b) { return a == b; }
|
||||
static size_t length(const char* sz) { return strlen(sz); }
|
||||
};
|
||||
|
||||
class TStreamBuffer {
|
||||
public:
|
||||
TStreamBuffer() {
|
||||
pBase_get_ = NULL;
|
||||
pEnd_get_ = NULL;
|
||||
pCurrent_get_ = NULL;
|
||||
pBase_put_ = NULL;
|
||||
pEnd_put_ = NULL;
|
||||
pCurrent_put_ = NULL;
|
||||
}
|
||||
|
||||
virtual ~TStreamBuffer() = 0;
|
||||
|
||||
int sputc(char param_0) {
|
||||
if (pCurrent_put_ < pEnd_put_) {
|
||||
*pCurrent_put_ = param_0;
|
||||
pCurrent_put_++;
|
||||
return TTrait_char<char>::to_int_type(param_0);
|
||||
} else {
|
||||
return overflow(TTrait_char<char>::to_int_type(param_0));
|
||||
}
|
||||
}
|
||||
|
||||
int sgetc();
|
||||
|
||||
int sbumpc() {
|
||||
if (pCurrent_get_ < pEnd_get_) {
|
||||
int var_r29 = TTrait_char<char>::to_int_type(*pCurrent_get_);
|
||||
pCurrent_get_++;
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
return uflow();
|
||||
}
|
||||
|
||||
int snextc() {
|
||||
int var_r31 = TTrait_char<char>::eof();
|
||||
return TTrait_char<char>::eq_int_type(sbumpc(), var_r31) ? var_r31 : sgetc();
|
||||
}
|
||||
|
||||
virtual void setbuf(char*, s32);
|
||||
virtual s32 sync();
|
||||
virtual int underflow();
|
||||
virtual int uflow();
|
||||
virtual s32 xsputn(const char*, s32);
|
||||
virtual int overflow(int);
|
||||
|
||||
/* 0x04 */ char* pBase_get_;
|
||||
/* 0x08 */ char* pEnd_get_;
|
||||
/* 0x0C */ char* pCurrent_get_;
|
||||
/* 0x10 */ char* pBase_put_;
|
||||
/* 0x14 */ char* pEnd_put_;
|
||||
/* 0x18 */ char* pCurrent_put_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* JGADGET_STD_STREAMBUF_H */
|
||||
@@ -70,6 +70,10 @@ namespace JUTAssertion {
|
||||
inline void showAssert(u32 device, const char* file, int line, const char* msg) {
|
||||
showAssert_f(device, file, line, "%s", msg);
|
||||
}
|
||||
|
||||
inline void setWarningMessage(u32 device, char* file, int line, const char* msg) {
|
||||
setWarningMessage_f(device, file, line, "%s", msg);
|
||||
}
|
||||
};
|
||||
|
||||
extern bool sAssertVisible;
|
||||
|
||||
@@ -1,62 +1,81 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JGadget/binary.h"
|
||||
#include "JSystem/JGadget/define.h"
|
||||
#include <stdint.h>
|
||||
|
||||
const void*
|
||||
JGadget::binary::parseVariableUInt_16_32_following(void const* buffer, u32* param_1, u32* param_2,
|
||||
JGadget::binary::TEBit* param_3) {
|
||||
JGadget::binary::TEBit temp;
|
||||
if (param_3 == NULL) {
|
||||
param_3 = &temp;
|
||||
#if DEBUG
|
||||
static void dummyString() {
|
||||
// probably some stripped function that called JUT_ASSERT here
|
||||
DEAD_STRING("Halt");
|
||||
}
|
||||
#endif
|
||||
|
||||
const void* JGadget::binary::parseVariableUInt_16_32_following(const void* pBuffer, u32* pu32First, u32* pu32Second,
|
||||
JGadget::binary::TEBit* pTEBit) {
|
||||
u16* pu16 = (u16*)pBuffer;
|
||||
JUT_ASSERT(122, pu16!=NULL);
|
||||
JUT_ASSERT(123, pu32First!=NULL);
|
||||
JUT_ASSERT(124, pu32Second!=NULL);
|
||||
|
||||
JGadget::binary::TEBit spC;
|
||||
if (pTEBit == NULL) {
|
||||
pTEBit = &spC;
|
||||
}
|
||||
u32 uVar1 = *(u16*)buffer;
|
||||
const void* rv;
|
||||
if ((uVar1 & 0x8000) == 0) {
|
||||
param_3->value = 0x10;
|
||||
*param_1 = uVar1;
|
||||
*param_2 = *(u16*)((u8*)buffer + 2);
|
||||
rv = (u8*)buffer + 4;
|
||||
|
||||
u32 var_r30 = *pu16;
|
||||
if ((var_r30 & 0x8000) == 0) {
|
||||
pTEBit->value = 0x10;
|
||||
|
||||
*pu32First = var_r30;
|
||||
pu16++;
|
||||
*pu32Second = *pu16;
|
||||
|
||||
return pu16 + 1;
|
||||
} else {
|
||||
param_3->value = 0x20;
|
||||
uVar1 <<= 16;
|
||||
uVar1 &= 0x7fff0000;
|
||||
uVar1 |= *(u16*)((u8*)buffer + 2);
|
||||
*param_1 = uVar1;
|
||||
*param_2 = *(u32*)((u8*)buffer + 4);
|
||||
rv = (u8*)buffer + 8;
|
||||
pTEBit->value = 0x20;
|
||||
|
||||
var_r30 &= 0x7FFF;
|
||||
var_r30 <<= 16;
|
||||
pu16++;
|
||||
var_r30 |= *pu16;
|
||||
|
||||
*pu32First = var_r30;
|
||||
pu16++;
|
||||
*pu32Second = *(u32*)pu16;
|
||||
|
||||
return pu16 + 2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
JGadget::binary::TParse_header_block::~TParse_header_block() {
|
||||
}
|
||||
JGadget::binary::TParse_header_block::~TParse_header_block() {}
|
||||
|
||||
bool JGadget::binary::TParse_header_block::parse_next(void const** ptrLocation, u32 idx) {
|
||||
u32 headerEnd, blockEnd;
|
||||
bool JGadget::binary::TParse_header_block::parse_next(const void** ppData_inout, u32 idx) {
|
||||
u32 uBlock, uData;
|
||||
|
||||
if ((ptrLocation == NULL) || (*ptrLocation == NULL)) {
|
||||
if (ppData_inout == NULL || *ppData_inout == NULL) {
|
||||
JGADGET_WARNMSG(172, "data not specified");
|
||||
return false;
|
||||
}
|
||||
bool check, checkLastBlock;
|
||||
checkLastBlock = check = false;
|
||||
|
||||
check = checkNext(ptrLocation, &headerEnd, idx);
|
||||
|
||||
checkLastBlock = check;
|
||||
if (!(idx & 1) && (check == false)) {
|
||||
return check;
|
||||
bool var_r29 = true;
|
||||
var_r29 = parseHeader_next(ppData_inout, &uBlock, idx) && var_r29;
|
||||
|
||||
if (!(idx & 1) && !var_r29) {
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
while (headerEnd > 0) {
|
||||
check = false;
|
||||
if (parseBlock_next(ptrLocation, &blockEnd, idx) && checkLastBlock) {
|
||||
check = true;
|
||||
while (uBlock > 0) {
|
||||
const void* p = *ppData_inout;
|
||||
var_r29 = parseBlock_next(ppData_inout, &uData, idx) && var_r29;
|
||||
|
||||
JUT_ASSERT(192, std::uintptr_t(*ppData_inout)==std::uintptr_t(p)+uData);
|
||||
|
||||
if ((idx & 2) == 0 && !var_r29) {
|
||||
return var_r29;
|
||||
}
|
||||
checkLastBlock = check;
|
||||
if (((idx & 2) == 0) && (check == false)) {
|
||||
return check;
|
||||
}
|
||||
headerEnd--;
|
||||
uBlock--;
|
||||
}
|
||||
return checkLastBlock;
|
||||
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JGadget/define.h"
|
||||
|
||||
#define MSL_USE_INLINES 1
|
||||
#include <ctype.h>
|
||||
|
||||
JGadget_outMessage::JGadget_outMessage(MessageFunc fn, const char* file, int line) {
|
||||
mMsgFunc = fn;
|
||||
mFile = file;
|
||||
mLine = line;
|
||||
|
||||
mWrite_p = mBuffer;
|
||||
*mWrite_p = 0;
|
||||
}
|
||||
|
||||
JGadget_outMessage::~JGadget_outMessage() {
|
||||
for (u8* p = (u8*)mBuffer; p != (u8*)mWrite_p; p++) {
|
||||
char c = *p;
|
||||
if (!isprint(c) && !isspace(c)) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
|
||||
mMsgFunc(mFile, mLine, mBuffer);
|
||||
}
|
||||
|
||||
JGadget_outMessage& JGadget_outMessage::operator<<(const char* sz) {
|
||||
JUT_ASSERT(99, sz!=NULL);
|
||||
|
||||
while (*sz != 0 && mWrite_p < mBuffer + (BUFFER_SIZE - 1)) {
|
||||
*mWrite_p = *sz;
|
||||
mWrite_p++;
|
||||
sz++;
|
||||
}
|
||||
|
||||
*mWrite_p = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JGadget_outMessage& JGadget_outMessage::operator<<(char c) {
|
||||
char sz[2];
|
||||
sz[0] = c;
|
||||
sz[1] = 0;
|
||||
|
||||
return *this << sz;
|
||||
}
|
||||
|
||||
JGadget_outMessage& JGadget_outMessage::operator<<(s32 value) {
|
||||
char sz[64];
|
||||
snprintf(sz, 64, "%d", value);
|
||||
|
||||
return *this << sz;
|
||||
}
|
||||
|
||||
JGadget_outMessage& JGadget_outMessage::operator<<(u32 value) {
|
||||
char sz[64];
|
||||
snprintf(sz, 64, "%u", value);
|
||||
|
||||
return *this << sz;
|
||||
}
|
||||
|
||||
JGadget_outMessage& JGadget_outMessage::operator<<(const void* data) {
|
||||
char sz[64];
|
||||
snprintf(sz, 64, "%p", data);
|
||||
|
||||
return *this << sz;
|
||||
}
|
||||
|
||||
void JGadget_outMessage::warning(const char* file, int line, const char* message) {
|
||||
JUTAssertion::setWarningMessage(3, (char*)file, line, message);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JGadget/search.h"
|
||||
|
||||
const char* JGadget::toStringFromIndex(int index, const char* const* pValue, u32 count, const char* fallback) {
|
||||
return toValueFromIndex<const char*>(index, pValue, count, fallback);
|
||||
}
|
||||
|
||||
int JGadget::toIndexFromString_linear(const char* sz, const char* const* pValue, u32 count, int fallback) {
|
||||
JUT_ASSERT(29, sz!=NULL);
|
||||
return toIndexFromValue_linear_if<const char*, search::TPR1IsEqual_string_>(
|
||||
search::TPR1IsEqual_string_(sz), pValue, count, fallback);
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JGadget/std-stream.h"
|
||||
#include "JSystem/JGadget/define.h"
|
||||
#include <ctype.h>
|
||||
#include <float.h>
|
||||
|
||||
namespace JGadget {
|
||||
namespace {
|
||||
namespace floatingpoint_ {
|
||||
int classify(double x) {
|
||||
int fp = __fpclassifyd(x);
|
||||
switch (fp) {
|
||||
case FP_ZERO:
|
||||
return 1;
|
||||
case FP_SUBNORMAL:
|
||||
return 2;
|
||||
case FP_NORMAL:
|
||||
return 3;
|
||||
case FP_INFINITE:
|
||||
return 4;
|
||||
case FP_QNAN:
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TStream_base::~TStream_base() {}
|
||||
TStream::~TStream() {}
|
||||
|
||||
void TStream::init(TStreamBuffer* psb) {
|
||||
Init_();
|
||||
state_ = 0;
|
||||
rdbuf_ = psb;
|
||||
fill_ = widen(' ');
|
||||
|
||||
JUT_ASSERT(126, rdbuf()==psb);
|
||||
JUT_ASSERT(127, flags()==(skipws|dec));
|
||||
JUT_ASSERT(128, width()==0);
|
||||
JUT_ASSERT(129, precision()==6);
|
||||
JUT_ASSERT(130, fill()==' ');
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TInputStream::sentry::sentry(TInputStream& stream, bool param_1) {
|
||||
_0x0 = stream._0x0->good();
|
||||
if (!_0x0) {
|
||||
stream._0x0->setstate(2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!param_1 && (stream._0x0->flags() & TStream_base::dec)) {
|
||||
TStreamBuffer* rdbuf = stream._0x0->rdbuf();
|
||||
int var_r28 = rdbuf->sgetc();
|
||||
|
||||
while (true) {
|
||||
var_r28 = rdbuf->snextc();
|
||||
|
||||
if (TTrait_char<char>::eq_int_type(var_r28, TTrait_char<char>::eof())) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isspace(TTrait_char<char>::to_char_type(var_r28))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_0x0 = stream._0x0->good();
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TInputStream::~TInputStream() {}
|
||||
|
||||
int TInputStream::get() {
|
||||
int var_r29;
|
||||
int var_r28 = TTrait_char<char>::eof();
|
||||
field_0x8 = 0;
|
||||
|
||||
var_r29 = var_r28;
|
||||
sentry entry(*this, true);
|
||||
if (entry) {
|
||||
TStreamBuffer* var_r26 = _0x0->rdbuf();
|
||||
int var_r27 = 0;
|
||||
|
||||
var_r29 = var_r26->sbumpc();
|
||||
if (TTrait_char<char>::eq_int_type(var_r29, var_r28)) {
|
||||
var_r27 |= 0x3;
|
||||
} else {
|
||||
field_0x8++;
|
||||
}
|
||||
}
|
||||
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream::~TOutputStream() {}
|
||||
|
||||
void TOutputStream::flush() {}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(const char* param_0) {
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(param_0, TTrait_char<char>::length(param_0));
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(char param_0) {
|
||||
char sz[2];
|
||||
sz[0] = param_0;
|
||||
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(sz, 1);
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(s32 param_0) {
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(param_0);
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(u32 param_0) {
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(param_0);
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(bool param_0) {
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(param_0);
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream& TOutputStream::operator<<(double param_0) {
|
||||
sentry entry(*this);
|
||||
if (entry) {
|
||||
TBufferIterator& sp8 = Put(param_0);
|
||||
if (TBufferIterator(sp8).failed()) {
|
||||
_0x0->setstate(6);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NONMATCHING
|
||||
TOutputStream::TBufferIterator& TOutputStream::Put(double param_0) {
|
||||
u32 flags = _0x0->flags();
|
||||
|
||||
const saoCaseNumeral_struct& sp24 = getCaseNumeral_(flags);
|
||||
|
||||
const TCString_* var_r28 = &saoszPrefix_sign_[0];
|
||||
if (param_0 < 0.0f) {
|
||||
var_r28 = &saoszPrefix_sign_[2];
|
||||
param_0 = -param_0;
|
||||
} else if (flags & 0x1000) {
|
||||
var_r28 = &saoszPrefix_sign_[1];
|
||||
}
|
||||
|
||||
TCString_ sp30;
|
||||
int sp1C = floatingpoint_::classify(param_0);
|
||||
switch (sp1C) {
|
||||
case 5:
|
||||
sp30 = sp24._3;
|
||||
break;
|
||||
case 4:
|
||||
sp30 = sp24._2;
|
||||
break;
|
||||
default:
|
||||
char sp28[8];
|
||||
char* var_r30 = sp28;
|
||||
|
||||
*var_r30 = '%';
|
||||
if (flags & 0x800) {
|
||||
*++var_r30 = '#';
|
||||
}
|
||||
*++var_r30 = '.';
|
||||
*++var_r30 = '*';
|
||||
|
||||
static const char pcFormat[] = "gGffeE";
|
||||
const char* var_r29 = pcFormat;
|
||||
|
||||
u32 sp18 = flags & 0xF0000000;
|
||||
switch (sp18) {
|
||||
case 0:
|
||||
break;
|
||||
case 0x10000000:
|
||||
var_r29 += 2;
|
||||
break;
|
||||
case 0x20000000:
|
||||
var_r29 += 4;
|
||||
break;
|
||||
default:
|
||||
JGADGET_WARNMSG1(580, "illegal float-field : ", sp18);
|
||||
bool sp9 = false;
|
||||
}
|
||||
|
||||
if (flags & 4) {
|
||||
var_r29++;
|
||||
}
|
||||
|
||||
*++var_r30 = *var_r29;
|
||||
*++var_r30 = 0;
|
||||
|
||||
char sp38[64];
|
||||
int sp14 = snprintf(sp38, 64, sp28, param_0, _0x0->precision());
|
||||
sp30.sz = sp38;
|
||||
|
||||
int sp10;
|
||||
bool sp8 = sp14 >= 0 && (u32)sp14 < 64;
|
||||
if (sp8) {
|
||||
sp10 = sp14;
|
||||
} else {
|
||||
JUT_ASSERT(590, false);
|
||||
int spC = 0x3F;
|
||||
sp10 = spC;
|
||||
}
|
||||
|
||||
sp30.len = sp10;
|
||||
}
|
||||
|
||||
return Put_CString_prefixed_(sp30.sz, sp30.len, var_r28->sz, var_r28->len);
|
||||
}
|
||||
|
||||
TOutputStream::TBufferIterator& TOutputStream::Put_CString_prefixed_(const char* param_0, u32 param_1, const char* param_2, u32 param_3) {
|
||||
TBufferIterator sp8(_0x0->rdbuf());
|
||||
if (sp8.failed()) {
|
||||
return sp8;
|
||||
}
|
||||
|
||||
u32 flags = _0x0->flags();
|
||||
char fill = _0x0->fill();
|
||||
s32 width = _0x0->width();
|
||||
|
||||
s32 var_r26 = param_1 + param_3;
|
||||
s32 var_r31 = 0;
|
||||
if (width > var_r26) {
|
||||
var_r31 = width - var_r26;
|
||||
}
|
||||
|
||||
if (!(flags & 0x50000)) {
|
||||
while (var_r31 != 0) {
|
||||
*sp8 = fill;
|
||||
var_r31--;
|
||||
++sp8;
|
||||
}
|
||||
}
|
||||
|
||||
while (param_3 != 0) {
|
||||
*sp8 = *param_2;
|
||||
param_3--;
|
||||
param_2++;
|
||||
++sp8;
|
||||
}
|
||||
|
||||
if (flags & 0x40000) {
|
||||
while (var_r31 != 0) {
|
||||
*sp8 = fill;
|
||||
var_r31--;
|
||||
++sp8;
|
||||
}
|
||||
}
|
||||
|
||||
while (param_1 != 0) {
|
||||
*sp8 = *param_0;
|
||||
param_1--;
|
||||
param_0++;
|
||||
++sp8;
|
||||
}
|
||||
|
||||
if (flags & 0x10000) {
|
||||
while (var_r31 != 0) {
|
||||
*sp8 = fill;
|
||||
var_r31--;
|
||||
++sp8;
|
||||
}
|
||||
}
|
||||
|
||||
_0x0->width(0);
|
||||
return sp8;
|
||||
}
|
||||
|
||||
// NONMATCHING - stack
|
||||
TOutputStream::TBufferIterator& TOutputStream::Put_longInt_(u32 param_0, bool param_1) {
|
||||
bool spC = false;
|
||||
|
||||
char buf[33];
|
||||
char* pbufBegin = buf;
|
||||
char* pbufEnd = &buf[32];
|
||||
char* pbuf = pbufEnd;
|
||||
|
||||
u32 flags = _0x0->flags();
|
||||
|
||||
const saoCaseNumeral_struct& sp20 = getCaseNumeral_(flags);
|
||||
const char* sp1C = sp20._0;
|
||||
int sp18 = 10;
|
||||
|
||||
const TCString_* var_r29 = &saoszPrefix_sign_[0];
|
||||
|
||||
u32 sp14 = flags & 0xFC00000;
|
||||
switch (sp14) {
|
||||
case 0x400000:
|
||||
if (param_1) {
|
||||
int sp10 = param_0;
|
||||
if (sp10 < 0) {
|
||||
var_r29 = &saoszPrefix_sign_[2];
|
||||
param_0 = -sp10;
|
||||
} else if (flags & 0x1000) {
|
||||
var_r29 = &saoszPrefix_sign_[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x800000:
|
||||
sp18 = 0x10;
|
||||
if (param_0 != 0 && (flags & 0x400)) {
|
||||
var_r29 = &sp20._1;
|
||||
}
|
||||
break;
|
||||
case 0x1000000:
|
||||
sp18 = 8;
|
||||
if (param_0 != 0 && (flags & 0x400)) {
|
||||
var_r29 = &soszPrefix_oct_;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
JGADGET_WARNMSG1(737, "illegal base-field : ", sp14);
|
||||
bool spA = false;
|
||||
}
|
||||
|
||||
if (param_0 == 0) {
|
||||
pbuf--;
|
||||
*pbuf = TStream::widen('0');
|
||||
} else {
|
||||
do {
|
||||
pbuf--;
|
||||
*pbuf = TStream::widen(sp1C[param_0 % sp18]);
|
||||
param_0 /= sp18;
|
||||
} while (param_0 != 0);
|
||||
}
|
||||
|
||||
JUT_ASSERT(737, (pbufBegin<=pbuf)&&(pbuf<pbufEnd));
|
||||
return Put_CString_prefixed_(pbuf, pbufEnd - pbuf, var_r29->sz, var_r29->len);
|
||||
}
|
||||
|
||||
const TOutputStream::saoCaseNumeral_struct TOutputStream::saoCaseNumeral_[2] = {
|
||||
{
|
||||
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'},
|
||||
{"0x", 2},
|
||||
{"inf", 3},
|
||||
{"nan", 3},
|
||||
},
|
||||
{
|
||||
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'},
|
||||
{"0X", 2},
|
||||
{"INF", 3},
|
||||
{"NAN", 3},
|
||||
},
|
||||
};
|
||||
|
||||
const TOutputStream::TCString_ TOutputStream::saoszPrefix_sign_[3] = {
|
||||
{"", 0},
|
||||
{"+", 1},
|
||||
{"-", 1},
|
||||
};
|
||||
|
||||
const TOutputStream::TCString_ TOutputStream::saaosz_bool_[2][2] = {
|
||||
{{"0", 1}, {"1", 1}},
|
||||
{{"false", 5}, {"true", 4}},
|
||||
};
|
||||
|
||||
const TOutputStream::TCString_ TOutputStream::soszPrefix_oct_ = {"0", 1};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JGadget/std-streambuf.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include <algorithm.h>
|
||||
|
||||
namespace JGadget {
|
||||
TStreamBuffer::~TStreamBuffer() {}
|
||||
|
||||
void TStreamBuffer::setbuf(char*, s32) {}
|
||||
|
||||
s32 TStreamBuffer::sync() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TStreamBuffer::underflow() {
|
||||
return TTrait_char<char>::eof();
|
||||
}
|
||||
|
||||
int TStreamBuffer::uflow() {
|
||||
int var_r30 = TTrait_char<char>::eof();
|
||||
int var_r29;
|
||||
|
||||
if (TTrait_char<char>::eq_int_type(underflow(), var_r30)) {
|
||||
return var_r30;
|
||||
}
|
||||
|
||||
var_r29 = TTrait_char<char>::to_int_type(*pCurrent_get_);
|
||||
pCurrent_get_++;
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
s32 TStreamBuffer::xsputn(const char* param_0, s32 param_1) {
|
||||
s32 var_r29 = std::min(param_1, pEnd_put_ - pCurrent_put_);
|
||||
if (var_r29 > 0) {
|
||||
const char* var_r27 = param_0 + var_r29;
|
||||
JUT_ASSERT(70, pCurrent_put_!=NULL);
|
||||
pCurrent_put_ = std::copy<char>(param_0, var_r27, pCurrent_put_);
|
||||
param_0 = var_r27;
|
||||
param_1 -= var_r29;
|
||||
}
|
||||
|
||||
while (param_1 > 0) {
|
||||
if (TTrait_char<char>::eq_int_type(sputc(*param_0), TTrait_char<char>::eof())) {
|
||||
break;
|
||||
}
|
||||
|
||||
param_1--;
|
||||
param_0++;
|
||||
var_r29++;
|
||||
s32 var_r25 = var_r29;
|
||||
}
|
||||
|
||||
return var_r29;
|
||||
}
|
||||
|
||||
int TStreamBuffer::overflow(int) {
|
||||
return TTrait_char<char>::eof();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include <algorithm.h>
|
||||
|
||||
static void dummy() {
|
||||
u32 a = 0;
|
||||
u32 b = 1;
|
||||
std::min<u32>(a, b);
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "JSystem/JKernel/JKRFileFinder.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
|
||||
#include "ctype.h"
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
|
||||
@@ -35,9 +35,9 @@ char* JSUInputStream::read(char* str) {
|
||||
}
|
||||
|
||||
s32 JSUInputStream::skip(s32 count) {
|
||||
u8 buffer;
|
||||
s32 skipCount = 0;
|
||||
for (; skipCount < count; skipCount++) {
|
||||
s32 skipCount;
|
||||
for (skipCount = 0; skipCount < count; skipCount++) {
|
||||
u8 buffer;
|
||||
if (readData(&buffer, sizeof(buffer)) != sizeof(buffer)) {
|
||||
setState(IOS_STATE_1);
|
||||
break;
|
||||
|
||||
@@ -23,11 +23,9 @@ JSUPtrList::JSUPtrList(bool init) {
|
||||
|
||||
JSUPtrList::~JSUPtrList() {
|
||||
JSUPtrLink* node = mHead;
|
||||
s32 removed = 0;
|
||||
while (mLength > removed) {
|
||||
for (int i = 0; i < mLength; i++) {
|
||||
node->mList = NULL;
|
||||
node = node->getNext();
|
||||
removed += 1;
|
||||
node = node->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +45,9 @@ void JSUPtrList::setFirst(JSUPtrLink* first) {
|
||||
}
|
||||
|
||||
bool JSUPtrList::append(JSUPtrLink* ptr) {
|
||||
JSUPtrList* list = ptr->mList;
|
||||
bool result = (NULL == list);
|
||||
bool result = ptr->mList == NULL;
|
||||
if (!result) {
|
||||
result = list->remove(ptr);
|
||||
result = ptr->mList->remove(ptr);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
@@ -70,10 +67,9 @@ bool JSUPtrList::append(JSUPtrLink* ptr) {
|
||||
}
|
||||
|
||||
bool JSUPtrList::prepend(JSUPtrLink* ptr) {
|
||||
JSUPtrList* list = ptr->mList;
|
||||
bool result = (NULL == list);
|
||||
bool result = ptr->mList == NULL;
|
||||
if (!result) {
|
||||
result = list->remove(ptr);
|
||||
result = ptr->mList->remove(ptr);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
@@ -103,7 +99,7 @@ bool JSUPtrList::insert(JSUPtrLink* before, JSUPtrLink* ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = (NULL == ptr->mList);
|
||||
bool result = ptr->mList == NULL;
|
||||
if (!result) {
|
||||
result = ptr->mList->remove(ptr);
|
||||
}
|
||||
@@ -152,7 +148,7 @@ JSUPtrLink* JSUPtrList::getNthLink(u32 index) const {
|
||||
|
||||
JSUPtrLink* node = mHead;
|
||||
for (u32 i = 0; i < index; i++) {
|
||||
node = node->getNext();
|
||||
node = node->mNext;
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <iterator.h>
|
||||
#include <string.h>
|
||||
#include <functional.h>
|
||||
#include "global.h"
|
||||
|
||||
namespace std {
|
||||
|
||||
@@ -127,6 +128,36 @@ inline void fill(ForwardIt first, ForwardIt last, const T& value) {
|
||||
}
|
||||
}
|
||||
|
||||
#if PLATFORM_SHIELD
|
||||
template <class T, bool IsPOD = true>
|
||||
struct __msl_copy {
|
||||
static T* copy(T* first, T* last, T* result) {
|
||||
for (; first < last; ++first, ++result)
|
||||
*result = *first;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct __msl_copy<T, true> {
|
||||
static T* copy(T* first, T* last, T* result) {
|
||||
size_t n = static_cast<size_t>(last - first);
|
||||
memmove(result, first, n * sizeof(T));
|
||||
return result + n;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T* copy(T* first, T* last, T* result) {
|
||||
return __msl_copy<T>::copy(first, last, result);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* copy(const T* first, const T* last, T* result) {
|
||||
return __msl_copy<T>::copy(const_cast<T*>(first), const_cast<T*>(last), result);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class InputIt, class OutputIt>
|
||||
inline OutputIt copy(InputIt first, InputIt last,
|
||||
OutputIt d_first) {
|
||||
@@ -177,6 +208,11 @@ inline T* copy_backward(T* first, T* last, T* result) {
|
||||
return __copy_backward<T, true>::copy_backward(first, last, result);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const T& min(const T& a, const T& b) {
|
||||
return b < a ? b : a;
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,7 +56,20 @@ extern const unsigned short __ctype_mapC[0x100];
|
||||
|
||||
#endif
|
||||
|
||||
int tolower(int);
|
||||
int isalnum(int c);
|
||||
int isalpha(int c);
|
||||
int isblank(int c);
|
||||
int iscntrl(int c);
|
||||
int isdigit(int c);
|
||||
int isgraph(int c);
|
||||
int islower(int c);
|
||||
int isprint(int c);
|
||||
int ispunct(int c);
|
||||
int isupper(int c);
|
||||
int isxdigit(int c);
|
||||
int isspace(int c);
|
||||
int tolower(int c);
|
||||
int toupper(int c);
|
||||
|
||||
#if MSL_USE_INLINES
|
||||
MSL_INLINE int isalnum(int c) {
|
||||
|
||||
Reference in New Issue
Block a user