// Returns true and advances "mangled_cur" if we find "c" at // "mangled_cur" position. static bool ParseChar(State *state, const char c) { if (RemainingLength(state) >= 1 && *state->mangled_cur == c) { ++state->mangled_cur; return true; } return false; }
// The demangler entry point. bool Demangle(const char *mangled, char *out, int out_size) { State state; InitState(&state, mangled, out, out_size); return (ParseMangledName(&state) && state.overflowed == false && RemainingLength(&state) == 0); }
// Returns true and advances "mangled_cur" if we find "two_chars" at // "mangled_cur" position. static bool ParseTwoChar(State *state, const char *two_chars) { if (RemainingLength(state) >= 2 && state->mangled_cur[0] == two_chars[0] && state->mangled_cur[1] == two_chars[1]) { state->mangled_cur += 2; return true; } return false; }
//-------------------------------------------------------------------------- VeChar8 VeAssetIStream::Peek() noexcept { if (RemainingLength() <= 0) { SetError(true); return -1; } VeChar8 c8Res(-1); VE_ASSERT_EQ(AAsset_read(m_pkAsset, &c8Res, 1), 1); AAsset_seek(m_pkAsset, -1, SEEK_CUR); return c8Res; }
// The demangler entry point. int gimli_demangle(const char *mangled, char *out, int out_size) { State state; #ifdef __MACH__ /* skip leading '_' that is present on this platform */ mangled++; #endif InitState(&state, mangled, out, out_size); return (ParseMangledName(&state) && state.overflowed == false && RemainingLength(&state) == 0); }
// <identifier> ::= <unqualified source code identifier> static bool ParseIdentifier(State *state) { if (state->number == -1 || RemainingLength(state) < state->number) { return false; } if (IdentifierIsAnonymousNamespace(state)) { MaybeAppend(state, "(anonymous namespace)"); } else { MaybeAppendWithLength(state, state->mangled_cur, state->number); } state->mangled_cur += state->number; state->number = -1; // Reset the number. return true; }
// <operator-name> ::= nw, and other two letters cases // ::= cv <type> # (cast) // ::= v <digit> <source-name> # vendor extended operator static bool ParseOperatorName(State *state) { if (RemainingLength(state) < 2) { return false; } // First check with "cv" (cast) case. State copy = *state; if (ParseTwoChar(state, "cv") && MaybeAppend(state, "operator ") && EnterNestedName(state) && ParseType(state) && LeaveNestedName(state, copy.nest_level)) { return true; } *state = copy; // Then vendor extended operators. if (ParseChar(state, 'v') && ParseCharClass(state, "0123456789") && ParseSourceName(state)) { return true; } *state = copy; // Other operator names should start with a lower alphabet followed // by a lower/upper alphabet. if (!(IsLower(state->mangled_cur[0]) && IsAlpha(state->mangled_cur[1]))) { return false; } // We may want to perform a binary search if we really need speed. const AbbrevPair *p; for (p = kOperatorList; p->abbrev != nullptr; ++p) { if (state->mangled_cur[0] == p->abbrev[0] && state->mangled_cur[1] == p->abbrev[1]) { MaybeAppend(state, "operator"); if (IsLower(*p->real_name)) { // new, delete, etc. MaybeAppend(state, " "); } MaybeAppend(state, p->real_name); state->mangled_cur += 2; return true; } } return false; }
//-------------------------------------------------------------------------- void* VeAssetIStream::Skip(VeSizeT stBytes) noexcept { stBytes = VE_MIN(stBytes, RemainingLength()); AAsset_seek(m_pkAsset, stBytes, SEEK_CUR); return nullptr; }
//-------------------------------------------------------------------------- void* VeFileIStream::Skip(VeSizeT stBytes) noexcept { VeSizeT stSkip = VE_MIN(stBytes, RemainingLength()); m_stPointer += stSkip; return nullptr; }