From bc3d9d9cf7045df10d8c952875c724666fcbeae0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Jan 2023 03:09:41 -0500 Subject: [PATCH] Add string comparison funcs for ACS --- src/acs/call-funcs.cpp | 88 ++++++++++++++++++++++++++++++++++++++--- src/acs/call-funcs.hpp | 3 ++ src/acs/environment.cpp | 3 ++ 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index f5498894c..fb4c0e1df 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1019,15 +1019,93 @@ bool CallFunc_EndLog(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word (void)argV; (void)argC; - if (ACS_ActivatorIsLocal(thread) == true) - { - CONS_Printf("%s\n", thread->printBuf.data()); - } - + CONS_Printf("%s\n", thread->printBuf.data()); thread->printBuf.drop(); return false; } +/*-------------------------------------------------- + bool CallFunc_strcmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + ACS wrapper for strcmp. +--------------------------------------------------*/ +static int ACS_strcmp(ACSVM::String *a, ACSVM::String *b) +{ + for (char const *sA = a->str, *sB = b->str; ; ++sA, ++sB) + { + char cA = *sA, cB = *sB; + + if (cA != cB) + { + return (cA < cB) ? -1 : 1; + } + + if (!cA) + { + return 0; + } + } +} + +bool CallFunc_strcmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = NULL; + + ACSVM::String *strA = nullptr; + ACSVM::String *strB = nullptr; + + (void)argC; + + map = thread->scopeMap; + + strA = map->getString(argV[0]); + strB = map->getString(argV[1]); + + thread->dataStk.push(ACS_strcmp(strA, strB)); + return false; +} + +/*-------------------------------------------------- + bool CallFunc_strcasecmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + ACS wrapper for strcasecmp / stricmp. +--------------------------------------------------*/ +static int ACS_strcasecmp(ACSVM::String *a, ACSVM::String *b) +{ + for (char const *sA = a->str, *sB = b->str; ; ++sA, ++sB) + { + char cA = std::tolower(*sA), cB = std::tolower(*sB); + + if (cA != cB) + { + return (cA < cB) ? -1 : 1; + } + + if (!cA) + { + return 0; + } + } +} + +bool CallFunc_strcasecmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = NULL; + + ACSVM::String *strA = nullptr; + ACSVM::String *strB = nullptr; + + (void)argC; + + map = thread->scopeMap; + + strA = map->getString(argV[0]); + strB = map->getString(argV[1]); + + thread->dataStk.push(ACS_strcasecmp(strA, strB)); + return false; +} + /*-------------------------------------------------- bool CallFunc_CountEnemies(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 51513d78d..4bbe3eaec 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -70,6 +70,9 @@ bool CallFunc_PlayerRings(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM: bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_EndLog(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_strcmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_strcasecmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); + bool CallFunc_CountEnemies(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_CountPushables(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_HaveUnlockableTrigger(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index eef000078..2f021b26c 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -144,6 +144,9 @@ Environment::Environment() //addFuncDataACS0( 7, addCallFunc(CallFunc_GetSideUDMFInt)); //addFuncDataACS0( 8, addCallFunc(CallFunc_GetSideUDMFFixed)); + addFuncDataACS0( 100, addCallFunc(CallFunc_strcmp)); + addFuncDataACS0( 101, addCallFunc(CallFunc_strcasecmp)); + addFuncDataACS0( 300, addCallFunc(CallFunc_CountEnemies)); addFuncDataACS0( 301, addCallFunc(CallFunc_CountPushables)); addFuncDataACS0( 302, addCallFunc(CallFunc_HaveUnlockableTrigger));