void processLDFlags(const String& ldFlags, StringVec& libs) { // Tokenize flags StringVec ldFlagTokens; tokenize(ldFlags, ldFlagTokens, " \t", "", "\"'", "", "", true, false); // Expand -Wl, and -Xlinker tokens to make parsing easier StringVec ldFlagsFixed; replaceWlArgs(ldFlagTokens, ldFlagsFixed); String savedToken; for (auto opt : ldFlagsFixed) { if (savedToken.empty()) { opt = reduceLinkerToken(opt); if (opt == "-library" || opt == "-framework") { savedToken = opt; } else if (strBeginsWith(opt, "-l")) { String libName = strEndsWith(opt, ".o") ? opt.substr(2) : "lib" + opt.substr(2) + ".?"; libs.push_back(libName); } else if (strEndsWith(opt, ".a") || strEndsWith(opt, ".dylib") || strEndsWith(opt, ".o")) { libs.push_back(opt); } } else { if (savedToken == "-library") { libs.push_back(opt); } else if (savedToken == "-framework") { std::string frameworkName = opt.substr(0, opt.find(',')) + ".framework"; libs.push_back(frameworkName); } savedToken.clear(); } } }
CMnemosynthDb::SEndpoint *CMnemosynthDb::GetOrAddEndpoint (const CString &sName, DWORD dwProcessID) // GetOrAddEndpoint // // Returns an endpoint for the given name { CSmartLock Lock(m_cs); // If we already have it, skip SEndpoint *pEndpoint = FindEndpoint(sName); if (pEndpoint != NULL) { // If this is a new process ID, then it means that the module // has been restarted, so we need to restart the sequence number.s if (dwProcessID != 0 && dwProcessID != pEndpoint->dwProcessID) { #ifdef DEBUG_MODULE_RESTART printf("[%s] Resetting endpoint %s to process ID %x\n", (LPSTR)m_pProcess->GetModuleName(), (LPSTR)sName, dwProcessID); #endif pEndpoint->dwProcessID = dwProcessID; pEndpoint->dwSeqRecv = 0; pEndpoint->dwSeqSent = 0; } return pEndpoint; } // Add DWORD dwID = m_dwNextID++; pEndpoint = m_Endpoints.Insert(dwID); pEndpoint->dwID = dwID; pEndpoint->sName = sName; pEndpoint->pPort = NULL; pEndpoint->dwSeqRecv = 0; pEndpoint->dwSeqSent = 0; // If the module name ends with CentralModule then this is // a module with Exarch (responsible for cross-machine sync) pEndpoint->bCentralModule = strEndsWith(sName, STR_CENTRAL_MODULE); // If the module starts with our machine name, then this is // a local endpoint. pEndpoint->bLocalMachine = strStartsWith(sName, m_pProcess->GetMachineName()); pEndpoint->dwProcessID = (pEndpoint->bLocalMachine ? dwProcessID : 0); // This endpoint needs a full update of everything we've got pEndpoint->bFullUpdate = true; // Done return pEndpoint; }
END_TEST START_TEST(test_strEndsWith) { fail_unless(!strEndsWith("foo.bar", ".foo"), NULL); fail_unless(strEndsWith("foo.bar", ".bar"), NULL); fail_unless(!strEndsWith("foo.bar", "o"), NULL); fail_unless(strEndsWith("foo.bar", "r"), NULL); fail_unless(strEndsWith("foo.bar", "oo.bar"), NULL); fail_unless(strEndsWith("foo.bar", "foo.bar"), NULL); fail_unless(!strEndsWith("foo.bar", "xoo.bar"), NULL); fail_unless(!strEndsWith("fo", "foo"), NULL); fail_unless(!strEndsWith("", "foo"), NULL); }
List<Object *>::Iterator Object::findChild(const char *pattern, List<Object *>::Iterator first) const { if(!pattern) return nullptr; List<Object *>::Iterator pos; CString r(pattern); auto wildcard_pos = r.find(WILDCARD_CHAR); if(wildcard_pos == r.end()) { pos = p.children.find([&r](Object *o) -> bool { return r == o->name().data(); }, first); } else if(r.front() == WILDCARD_CHAR) { pos = p.children.find([&r](Object *o) -> bool { return strEndsWith(o->name().data(), r.data()+1, o->name().size(), r.size()-1); }, first); } else if(r.back() == WILDCARD_CHAR) { r.resize(r.size()-1); pos = p.children.find([&r](Object *o) -> bool { return strStartsWith(o->name().data(), r.data(), o->name().size(), r.size()); }, first); } else { pos = p.children.find([&r, &wildcard_pos](Object *o) -> bool { size_t wildcard_idx = (&(*wildcard_pos))-r.data(); bool ends = strEndsWith(o->name().data(), r.data()+wildcard_idx+1, o->name().size(), r.size()-wildcard_idx-1); CString s(r.data(), wildcard_idx); bool starts = strStartsWith(o->name().data(), s.data(), o->name().size(), s.size()); return starts && ends; }, first); } return pos; }
XCScheme::XCScheme(const String& absSchemePath, const PBXProject* owner) : m_absPath(absSchemePath), m_parentProject(owner) { // Record the scheme name m_name = sb_fname(sb_basename(m_absPath)); #if defined(_MSC_VER) // Disambiguate scheme names from different users String userDir = sb_basename(sb_dirname(sb_dirname(m_absPath))); if (strEndsWith(userDir, ".xcuserdatad")) m_name = m_name + " (" + sb_fname(userDir) + ")"; #endif }
char *convertDottedPathToSlashedPath (char *filename) { char *result = g_strdup (filename); char *tmp; for (tmp = result; *tmp; tmp++) if (*tmp == '.') *tmp = '/'; if (strEndsWith (result, "/balsa")) result[strlen (result) - 6] = '.'; return result; }
std::string rangeFromOverflow(const std::string &prefix, const std::string &done){ if (strContains(overflow, prefix)){ if (strEndsWith(overflow, prefix)) return prefix; v1.clear(); std::string tmp = overflow.substr(overflow.find(prefix) + prefix.length()); auto pos = tmp.find(done); if (pos != std::string::npos){ overflow = tmp.substr(pos); return prefix + tmp.substr(0,pos); } else return prefix + tmp; } return ""; }
bool LEVELSELECT::addLevelListEntry(char* levelFileName) { if (strlen(levelFileName)+1 > MAX_PATH) { error("LEVELSELECT::addLevelListEntry", "Parameter levelFileName too long. Max length is MAX_PATH (%d).", MAX_PATH); return false; } if (!strEndsWith(levelFileName, ".lvl")) { logger(true, "WARNING: Unknown file in level directory %s: %s", GetCurrent()->GetDirectory()->name, levelFileName); return false; } LEVELFILE *lastLevel = GetCurrent()->GetLevel(); LEVELFILE *newLevel; //get last level if (lastLevel != NULL) { while (lastLevel->next != NULL) { lastLevel = lastLevel->next; } } newLevel = (LEVELFILE*)malloc(sizeof(LEVELFILE)); newLevel->prev = lastLevel; newLevel->next = NULL; if (lastLevel != NULL) { lastLevel->next = newLevel; newLevel->index = lastLevel->index+1; } else { newLevel->index = 0; } strcpy(newLevel->name, levelFileName); newLevel->name[strlen(newLevel->name)-4] = '\0'; //cut off fileextension (to get levelname) newLevel->directory = GetCurrent()->currentDirectory; GetCurrent()->GetLevelPath(newLevel->path, newLevel); newLevel->score = HIGHSCORE(newLevel->name, newLevel->directory->name); newLevel->level = new LEVEL({(windX/2+160), 160}, 17, newLevel->path, true); if (GetCurrent()->GetLevel() == NULL) GetCurrent()->currentLevel = newLevel; return true; }
bool CArchonProcess::SendMessage (const CString &sAddress, const SArchonMessage &Msg) // SendMessage // // Sends a message to the given address. If we fail, we reply as appropriate. { bool bSuccess; CMessagePort *pPort = Bind(sAddress); if (pPort) { bSuccess = pPort->SendMessage(Msg); } else { Log(MSG_LOG_ERROR, strPattern(ERR_CANT_BIND, sAddress)); bSuccess = false; } // If we failed to send the message, then we might want to reply to the // client. if (!bSuccess) { // If this is a notification port then we ignore the error (it just // means that no one is listening). if (!strEndsWith(sAddress, STR_NOTIFY_SUFFIX) && !strStartsWith(Msg.sMsg, MSG_ERROR_PREFIX)) { // Reply to client, if necessary if (!CMessagePort::IsNullAddr(Msg.sReplyAddr)) SendMessageCommand(Msg.sReplyAddr, MSG_ERROR_UNABLE_TO_COMPLY, NULL_STR, Msg.dwTicket, CDatum(strPattern(ERR_CANT_SEND_TO, sAddress))); else Log(MSG_LOG_ERROR, strPattern("Failed sending message to: %s.", sAddress)); } } // Done return bSuccess; }
static String expandRecursivePath(const String& path, const String& prefix, const VariableCollectionHierarchy& vch) { // Check if recursive expansion is necessary if (!strEndsWith(path, "/**")) return addPrefixQuoted(path, prefix, vch); // Remove the pesky /** ending String fixedPath = path.substr(0, path.length() - 3); // Expand the path and get an absolute project path String expandedPath = vch.expand(fixedPath); String projectPath = vch.getValue("PROJECT_DIR"); // Make an absolute path String absPath = joinPaths(projectPath, expandedPath); // Get a list of subdirectories to ignore StringVec ignoreList; vch.getValue("EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES", ignoreList); // Get recursive paths StringVec dirVec; getRecursiveDirList(absPath, dirVec, ignoreList); // Sort the paths such that they are in breadth-first, alphabetic order std::sort(dirVec.begin(), dirVec.end(), compare_nocase_breadth_first); // Substitute back the original form of the path (which likely contains variables) String ret; for (unsigned i = 0; i < dirVec.size(); i++) { dirVec[i].replace(0, absPath.length(), fixedPath); ret += addPrefixQuoted(dirVec[i], prefix, vch); } // Check that the recursive expansion succeeded if (dirVec.empty()) { SBLog::info() << "Failed recursive expansion of \"" << absPath << "\". Path does not exist." << std::endl; return ""; } else { return ret; } }
CDatum CUserInfoSession::CreateSanitizedUserRecord (CDatum dRecord) // CreateSanitizedUserRecord // // Creates a user record suitable for returning to clients. In partincular, // we remove the authentication information. { int i; // Create a destination CComplexStruct *pDest = new CComplexStruct; // Copy all appropriate fields for (i = 0; i < dRecord.GetCount(); i++) { // If this is an auth field, then skip it if (strEquals(dRecord.GetKey(i), FIELD_AUTH_DESC)) ; else if (strEndsWith(dRecord.GetKey(i), FIELD_AUTH_DESC_SUFFIX)) ; // Otherwise, copy it else pDest->SetElement(dRecord.GetKey(i), dRecord.GetElement(i)); } // Done return CDatum(pDest); }
void SBFrameworksBuildPhase::writeVCProjectFiles(VCProject& proj) const { // We don't support linking with frameworks when building bundles TargetProductType productType = m_parentTarget.getProductType(); if (productType == TargetBundle) { if (!m_phase->getBuildFileList().empty()) { SBLog::warning() << "Ignoring all frameworkss in \"" << m_parentTarget.getName() << "\" bundle target." << std::endl; } return; } String linkTarget; if (productType == TargetApplication) linkTarget = "Link"; else if (productType == TargetStaticLib) linkTarget = "Lib"; // Get paths to all the build files (frameworks) StringVec buildFilePaths; if (m_phase) { const BuildFileList& buildFiles = m_phase->getBuildFileList(); sbAssert(buildFiles.size() == m_buildFileTargets.size()); for (size_t i = 0; i < buildFiles.size(); i++) { const PBXFile* file = buildFiles[i]->getFile(); // Ignore any frameworks build from source (they will be added as project references) if (file && !m_buildFileTargets[i]) buildFilePaths.push_back(file->getFullPath()); } } for (auto bs : m_parentTarget.getBuildSettings()) { VCProjectConfiguration* config = proj.addConfiguration(bs.first); // Extrace libs/frameworks from OTHER_LDFLAGS StringVec buildFilePaths(buildFilePaths); processLDFlags(bs.second->getValue("OTHER_LDFLAGS"), buildFilePaths); // Construct a list of libraries to link against StringSet linkedLibs; linkedLibs.insert("%(AdditionalDependencies)"); for (auto filePath : buildFilePaths) { if (productType == TargetStaticLib && !strEndsWith(filePath, ".a")) continue; String winLibName = sb_fname(sb_basename(filePath)) + ".lib"; // If the library is blocked then add the replacement library to our additional dependencies auto it = s_blockedLibraries.find(winLibName); while (it != s_blockedLibraries.end()) { // get the replacement library. winLibName = it->second; // follow any transitive replacement. it = s_blockedLibraries.find(winLibName); } if (!winLibName.empty()) { linkedLibs.insert(winLibName); } } // AdditionalDependencies String additionalDeps = joinStrings(linkedLibs, ";"); if (!additionalDeps.empty()) { config->setItemDefinition(linkTarget, "AdditionalDependencies", additionalDeps); } } }
void CExarchEngine::MsgAddModule (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgAddModule // // Exarch.addModule [{machineName}] {filePath} [{debug}] { CSmartLock Lock(m_cs); CString sError; // Must be admin service if (!ValidateSandboxAdmin(Msg, pSecurityCtx)) return; // Get parameters bool bHasMachineName = (Msg.dPayload.GetCount() >= 2 && !strEndsWith(strToLower(Msg.dPayload.GetElement(0)), STR_EXE_SUFFIX)); int iArg = 0; CString sMachineName = (bHasMachineName ? Msg.dPayload.GetElement(iArg++) : NULL_STR); CString sModuleFilePath = Msg.dPayload.GetElement(iArg++); CDatum dDebug = Msg.dPayload.GetElement(iArg++); // If we have a machine name, try to parse it in case the user gave us // a partial name. if (bHasMachineName) { if (!ParseMachineName(sMachineName, &sMachineName)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern("Unknown machine: %s", sMachineName), Msg); return; } } // If this is not for our machine, then we need to send a message to the // other machine. if (!sMachineName.IsEmpty() && !strEqualsNoCase(GetMachineName(), sMachineName)) { CString sAddress = GenerateMachineAddress(sMachineName, ADDRESS_EXARCH_COMMAND); if (sAddress.IsEmpty()) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern("Unable to generate address for: %s", sMachineName), Msg); return; } StartSession(Msg, new CAddModuleSession(this, sAddress, sModuleFilePath)); } // Otherwise, we add a local module else { // Add the module CString sModuleName; if (!AddModule(sModuleFilePath, strEqualsNoCase(dDebug, FIELD_DEBUG), &sModuleName, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Add it to our list of modules CComplexArray *pModuleList = new CComplexArray(m_dMachineConfig.GetElement(FIELD_MODULES)); pModuleList->Append(CDatum(sModuleName)); CComplexStruct *pConfig = new CComplexStruct(m_dMachineConfig); pConfig->SetElement(FIELD_MODULES, CDatum(pModuleList)); m_dMachineConfig = CDatum(pConfig); // Save it WriteConfig(); // Done SendMessageReply(MSG_OK, CDatum(), Msg); } }
void RunFile (const CString &sFilespec, bool bNoLogo) { ALERROR error; CCodeChain &CC = g_pUniverse->GetCC(); CCodeChainCtx Ctx; // Verify the file CString sRunFile = sFilespec; if (!strEndsWith(sRunFile, CONSTLIT(".")) && pathGetExtension(sRunFile).IsBlank()) sRunFile.Append(CONSTLIT(".tlisp")); // Open the file CFileReadBlock InputFile(sRunFile); if (error = InputFile.Open()) { printf("error : Unable to open file '%s'.\n", sRunFile.GetASCIIZPointer()); return; } if (!bNoLogo) printf("%s\n", sRunFile.GetASCIIZPointer()); // Parse CString sInputFile(InputFile.GetPointer(0), InputFile.GetLength(), TRUE); CString sOutput; int iOffset = 0; while (true) { int iCharCount; ICCItem *pCode = Ctx.Link(sInputFile, iOffset, &iCharCount); if (pCode->IsNil()) break; else if (pCode->IsError()) { printf("error : %s\n", pCode->GetStringValue().GetASCIIZPointer()); Ctx.Discard(pCode); return; } iOffset += iCharCount; // Execute ICCItem *pResult = Ctx.Run(pCode); // Compose output if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); // Free Ctx.Discard(pResult); Ctx.Discard(pCode); } // Output result printf("%s\n", sOutput.GetASCIIZPointer()); }
int main(int argc, char* argv[]) { #if defined _DEBUG printf("+++ start\n"); int argi=0; printf("+++ argc: %d\n", argc); for ( argi; argi<argc; argi++) { printf("+++ argv[%d]='%s'\n", argi, argv[argi]); } #endif if ( argc>1 ) { if ( findParam(argv, argc, "-h")>0 || findParam(argv, argc, "--help")>0 ) { help(argv[0]); return RET_SUCCES; } } else { printf("error: not enought params\n"); help(argv[0]); return RET_ERR_PARAMS; } bfo=0; if ( findParam(argv, argc, "-d")>0 || findParam(argv, argc, "--debug")>0 ) { bfo |= BFO_DEBUG; #if defined _DEBUG printf("+++ main: in debug BF mode: bfo: 0x%X\n", bfo); #endif } bf_mem=(UCHAR*)calloc(BF_MEMORY_SIZE, sizeof(char)); if ( !bf_mem ) { #if defined _DEBUG printf("--- main: bf_mem=NULL\n"); #else printf("error: can't allocate memory for BF cells\n"); #endif return RET_ERR_MEM; } FILE* bf_sc_fd; if ( argc>1 && strEndsWith(argv[argc-1], "bf") ) { bf_sc_fd=fopen(argv[argc-1], "r"); if ( bf_sc_fd ) { bf_sc=(UCHAR*)calloc(BUFFER_SIZE, sizeof(char)); int bf_sc_sz=0; int readb=0; while( !feof(bf_sc_fd) ) { if ( bf_sc ) { readb=fread(bf_sc+bf_sc_sz*BUFFER_SIZE*sizeof(char), BUFFER_SIZE*sizeof(char), 1, bf_sc_fd); // #if defined _DEBUG // printf("bf_sc::fread #%d:\n%s (%d)\n", bf_sc_sz+1, bf_sc, readb); // #endif if ( readb==1 ) { bf_sc_sz+=1; bf_sc=(UCHAR*)realloc(bf_sc, (bf_sc_sz+1)*BUFFER_SIZE*sizeof(char)); memset(bf_sc+(BUFFER_SIZE*bf_sc_sz), 0, BUFFER_SIZE); } } else { #if defined _DEBUG printf("--- bf_sc=NULL\n"); #endif return RET_ERR_MEM; } } close(bf_sc_fd); if ( bf_sc ) { #if defined _DEBUG printf("bf_sc @ 0x%X (%d):\n'%s'\n", bf_sc, BUFFER_SIZE*(bf_sc_sz+1)*sizeof(char), bf_sc); #endif if ( strEndsWith(argv[argc-1], ".qbf") || findParam(argv, argc, "-q")>0 || findParam(argv, argc, "--quick")>0 ) { bfo |= BFO_QUICK; #if defined _DEBUG printf("+++ main: in quick BF mode: bfo: 0x%X\n", bfo); #endif #if defined _DEBUG printf("+++ main: prepare sc\n"); #endif bf_sc=prepare(bf_sc); if ( bf_sc ) { #if defined _DEBUG printf("bf_sc @ 0x%X (%d):\n'%s'\n", bf_sc, BUFFER_SIZE*(bf_sc_sz+1)*sizeof(char), bf_sc); #endif } else { #if defined _DEBUG printf("--- main: can't prepare SC\n"); #endif return RET_ERR_SC; } } } if ( findParam(argv, argc, "-sc")>0 || findParam(argv, argc, "--show-code")>0 ) { printf("Source code:\n'%s'\n", bf_sc); } if ( bf_sc ) { int sz=strlen(bf_sc); #if defined _DEBUG printf("+++ bf_sc[%d]=0x%02X\n", sz-1, bf_sc[sz-1]); #endif // TODO: str replace ? if ( bf_sc[sz-1]==0x0a || bf_sc[sz-1]==0x0d ) bf_sc[sz-1]=0; if ( bf_sc[sz-2]==0x0a || bf_sc[sz-2]==0x0a ) bf_sc[sz-2]=0; if ( validate(bf_sc) ) { bf_mp=bf_mem; execute(bf_sc); printf("\n"); free(bf_sc); free(bf_mem); } else { printf("code is invalid\n"); } } } else { printf("can't open '%s'\n", argv[argc-1]); } } else { printf("'%s' seems to be not a BF source\n", argv[argc-1]); } #if defined _DEBUG printf("+++ stop\n"); #endif return RET_SUCCES; };
/*********************************************************************************************************************************** Test Run ***********************************************************************************************************************************/ void testRun(void) { FUNCTION_HARNESS_VOID(); // ***************************************************************************************************************************** if (testBegin("strNew(), strNewBuf(), strNewN(), strEmpty(), strPtr(), strSize(), and strFree()")) { // We don't want this struct to grow since there are generally a lot of strings, so make sure it doesn't grow without us // knowing about it TEST_RESULT_UINT(sizeof(StringConst), TEST_64BIT() ? 16 : 12, "check StringConst struct size"); // Test the size macro TEST_RESULT_VOID(CHECK_SIZE(555), "valid size"); TEST_ERROR(CHECK_SIZE(STRING_SIZE_MAX + 1), AssertError, "string size must be <= 1073741824 bytes"); String *string = strNew("static string"); TEST_RESULT_STR(strPtr(string), "static string", "new with static string"); TEST_RESULT_INT(strSize(string), 13, "check size"); TEST_RESULT_BOOL(strEmpty(string), false, "is not empty"); TEST_RESULT_INT(strlen(strPtr(string)), 13, "check size with strlen()"); TEST_RESULT_CHAR(strPtr(string)[2], 'a', "check character"); TEST_RESULT_VOID(strFree(string), "free string"); // ------------------------------------------------------------------------------------------------------------------------- TEST_RESULT_STR(strPtr(strNewN("testmorestring", 4)), "test", "new string with size limit"); // ------------------------------------------------------------------------------------------------------------------------- Buffer *buffer = bufNew(8); memcpy(bufPtr(buffer), "12345678", 8); bufUsedSet(buffer, 8); TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "12345678", "new string from buffer"); // ------------------------------------------------------------------------------------------------------------------------- string = strNewFmt("formatted %s %04d", "string", 1); TEST_RESULT_STR(strPtr(string), "formatted string 0001", "new with formatted string"); TEST_RESULT_PTR(strPtr(NULL), NULL, "null string pointer"); TEST_RESULT_VOID(strFree(string), "free string"); TEST_RESULT_VOID(strFree(NULL), "free null string"); } // ***************************************************************************************************************************** if (testBegin("STRING_STATIC()")) { TEST_RESULT_STR(strPtr(TEST_STRING), "a very interesting string!", "check static string"); TEST_RESULT_STR(strPtr(strSubN(TEST_STRING, 0, 6)), "a very", "read-only strSub() works"); } // ***************************************************************************************************************************** if (testBegin("strBase() and strPath()")) { TEST_RESULT_STR(strPtr(strBase(STRDEF(""))), "", "empty string"); TEST_RESULT_STR(strPtr(strBase(STRDEF("/"))), "", "/ only"); TEST_RESULT_STR(strPtr(strBase(STRDEF("/file"))), "file", "root file"); TEST_RESULT_STR(strPtr(strBase(STRDEF("/dir1/dir2/file"))), "file", "subdirectory file"); TEST_RESULT_STR(strPtr(strPath(STRDEF(""))), "", "empty string"); TEST_RESULT_STR(strPtr(strPath(STRDEF("/"))), "/", "/ only"); TEST_RESULT_STR(strPtr(strPath(STRDEF("/file"))), "/", "root path"); TEST_RESULT_STR(strPtr(strPath(STRDEF("/dir1/dir2/file"))), "/dir1/dir2", "subdirectory file"); } // ***************************************************************************************************************************** if (testBegin("strCat(), strCatChr(), and strCatFmt()")) { String *string = strNew("XXXX"); String *string2 = strNew("ZZZZ"); TEST_RESULT_STR(strPtr(strCat(string, "YYYY")), "XXXXYYYY", "cat string"); TEST_RESULT_SIZE(string->extra, 4, "check extra"); TEST_RESULT_STR(strPtr(strCatFmt(string, "%05d", 777)), "XXXXYYYY00777", "cat formatted string"); TEST_RESULT_SIZE(string->extra, 6, "check extra"); TEST_RESULT_STR(strPtr(strCatChr(string, '!')), "XXXXYYYY00777!", "cat chr"); TEST_RESULT_SIZE(string->extra, 5, "check extra"); TEST_RESULT_STR(strPtr(string2), "ZZZZ", "check unaltered string"); } // ***************************************************************************************************************************** if (testBegin("strDup()")) { const String *string = STRDEF("duplicated string"); String *stringDup = strDup(string); TEST_RESULT_STR(strPtr(stringDup), strPtr(string), "duplicated strings match"); TEST_RESULT_PTR(strDup(NULL), NULL, "duplicate null string"); } // ***************************************************************************************************************************** if (testBegin("strBeginsWith() and strBeginsWithZ()")) { TEST_RESULT_BOOL(strBeginsWith(STRDEF(""), STRDEF("aaa")), false, "empty string"); TEST_RESULT_BOOL(strBeginsWith(STRDEF("astring"), STRDEF("")), true, "empty begins with"); TEST_RESULT_BOOL(strBeginsWithZ(STRDEF("astring"), "astr"), true, "partial begins with"); TEST_RESULT_BOOL(strBeginsWithZ(STRDEF("astring"), "astring"), true, "equal strings"); } // ***************************************************************************************************************************** if (testBegin("strEndsWith() and strEndsWithZ()")) { TEST_RESULT_BOOL(strEndsWith(STRDEF(""), STRDEF(".doc")), false, "empty string"); TEST_RESULT_BOOL(strEndsWith(STRDEF("astring"), STRDEF("")), true, "empty ends with"); TEST_RESULT_BOOL(strEndsWithZ(STRDEF("astring"), "ing"), true, "partial ends with"); TEST_RESULT_BOOL(strEndsWithZ(STRDEF("astring"), "astring"), true, "equal strings"); } // ***************************************************************************************************************************** if (testBegin("strEq(), strEqZ(), strCmp(), strCmpZ()")) { TEST_RESULT_BOOL(strEq(STRDEF("equalstring"), STRDEF("equalstring")), true, "strings equal"); TEST_RESULT_BOOL(strEq(STRDEF("astring"), STRDEF("anotherstring")), false, "strings not equal"); TEST_RESULT_BOOL(strEq(STRDEF("astring"), STRDEF("bstring")), false, "equal length strings not equal"); TEST_RESULT_INT(strCmp(STRDEF("equalstring"), STRDEF("equalstring")), 0, "strings equal"); TEST_RESULT_INT(strCmp(STRDEF("a"), STRDEF("b")), -1, "a < b"); TEST_RESULT_INT(strCmp(STRDEF("b"), STRDEF("a")), 1, "b > a"); TEST_RESULT_BOOL(strEqZ(STRDEF("equalstring"), "equalstring"), true, "strings equal"); TEST_RESULT_BOOL(strEqZ(STRDEF("astring"), "anotherstring"), false, "strings not equal"); TEST_RESULT_BOOL(strEqZ(STRDEF("astring"), "bstring"), false, "equal length strings not equal"); TEST_RESULT_INT(strCmpZ(STRDEF("equalstring"), "equalstring"), 0, "strings equal"); TEST_RESULT_INT(strCmpZ(STRDEF("a"), "b"), -1, "a < b"); TEST_RESULT_INT(strCmpZ(STRDEF("b"), "a"), 1, "b > a"); } // ***************************************************************************************************************************** if (testBegin("strFirstUpper(), strFirstLower(), strUpper(), strLower()")) { TEST_RESULT_STR(strPtr(strFirstUpper(strNew(""))), "", "empty first upper"); TEST_RESULT_STR(strPtr(strFirstUpper(strNew("aaa"))), "Aaa", "first upper"); TEST_RESULT_STR(strPtr(strFirstUpper(strNew("Aaa"))), "Aaa", "first already upper"); TEST_RESULT_STR(strPtr(strFirstLower(strNew(""))), "", "empty first lower"); TEST_RESULT_STR(strPtr(strFirstLower(strNew("AAA"))), "aAA", "first lower"); TEST_RESULT_STR(strPtr(strFirstLower(strNew("aAA"))), "aAA", "first already lower"); TEST_RESULT_STR(strPtr(strLower(strNew("K123aBc"))), "k123abc", "all lower"); TEST_RESULT_STR(strPtr(strLower(strNew("k123abc"))), "k123abc", "already lower"); TEST_RESULT_STR(strPtr(strLower(strNew("C"))), "c", "char lower"); TEST_RESULT_STR(strPtr(strLower(strNew(""))), "", "empty lower"); TEST_RESULT_STR(strPtr(strUpper(strNew("K123aBc"))), "K123ABC", "all upper"); TEST_RESULT_STR(strPtr(strUpper(strNew("K123ABC"))), "K123ABC", "already upper"); TEST_RESULT_STR(strPtr(strUpper(strNew("c"))), "C", "char upper"); TEST_RESULT_STR(strPtr(strUpper(strNew(""))), "", "empty upper"); } // ***************************************************************************************************************************** if (testBegin("strQuote()")) { TEST_RESULT_STR(strPtr(strQuote(STRDEF("abcd"), STRDEF("'"))), "'abcd'", "quote string"); } // ***************************************************************************************************************************** if (testBegin("strReplaceChr()")) { TEST_RESULT_STR(strPtr(strReplaceChr(strNew("ABCD"), 'B', 'R')), "ARCD", "replace chr"); } // ***************************************************************************************************************************** if (testBegin("strSub() and strSubN()")) { TEST_RESULT_STR(strPtr(strSub(STRDEF("ABCD"), 2)), "CD", "sub string"); TEST_RESULT_STR(strPtr(strSubN(STRDEF("ABCD"), 1, 2)), "BC", "sub string with length"); } // ***************************************************************************************************************************** if (testBegin("strTrim()")) { TEST_RESULT_STR(strPtr(strTrim(strNew(""))), "", "trim empty"); TEST_RESULT_STR(strPtr(strTrim(strNew("X"))), "X", "no trim (one char)"); TEST_RESULT_STR(strPtr(strTrim(strNew("no-trim"))), "no-trim", "no trim (string)"); TEST_RESULT_STR(strPtr(strTrim(strNew(" \t\r\n"))), "", "all whitespace"); TEST_RESULT_STR(strPtr(strTrim(strNew(" \tbegin-only"))), "begin-only", "trim begin"); TEST_RESULT_STR(strPtr(strTrim(strNew("end-only\t "))), "end-only", "trim end"); TEST_RESULT_STR(strPtr(strTrim(strNew("\n\rboth\r\n"))), "both", "trim both"); TEST_RESULT_STR(strPtr(strTrim(strNew("begin \r\n\tend"))), "begin \r\n\tend", "ignore whitespace in middle"); } // ***************************************************************************************************************************** if (testBegin("strChr() and strTrunc()")) { TEST_RESULT_INT(strChr(STRDEF("abcd"), 'c'), 2, "c found"); TEST_RESULT_INT(strChr(STRDEF("abcd"), 'C'), -1, "capital C not found"); TEST_RESULT_INT(strChr(STRDEF("abcd"), 'i'), -1, "i not found"); TEST_RESULT_INT(strChr(STRDEF(""), 'x'), -1, "empty string - x not found"); String *val = strNew("abcdef"); TEST_ERROR( strTrunc(val, (int)(strSize(val) + 1)), AssertError, "assertion 'idx >= 0 && (size_t)idx <= this->size' failed"); TEST_ERROR(strTrunc(val, -1), AssertError, "assertion 'idx >= 0 && (size_t)idx <= this->size' failed"); TEST_RESULT_STR(strPtr(strTrunc(val, strChr(val, 'd'))), "abc", "simple string truncated"); strCat(val, "\r\n to end"); TEST_RESULT_STR(strPtr(strTrunc(val, strChr(val, 'n'))), "abc\r\n to e", "complex string truncated"); TEST_RESULT_STR(strPtr(strTrunc(val, strChr(val, 'a'))), "", "complete string truncated - empty string"); TEST_RESULT_INT(strSize(val), 0, "0 size"); TEST_RESULT_STR(strPtr(strTrunc(val, 0)), "", "test coverage of empty string - no error thrown for index 0"); } // ***************************************************************************************************************************** if (testBegin("strToLog() and strObjToLog()")) { TEST_RESULT_STR(strPtr(strToLog(STRDEF("test"))), "{\"test\"}", "format string"); TEST_RESULT_STR(strPtr(strToLog(NULL)), "null", "format null string"); char buffer[256]; TEST_RESULT_UINT(strObjToLog(NULL, (StrObjToLogFormat)strToLog, buffer, sizeof(buffer)), 4, "format null string"); TEST_RESULT_STR(buffer, "null", "check null string"); TEST_RESULT_UINT(strObjToLog(STRDEF("teststr"), (StrObjToLogFormat)strToLog, buffer, sizeof(buffer)), 11, "format string"); TEST_RESULT_STR(buffer, "{\"teststr\"}", "check string"); } // ***************************************************************************************************************************** if (testBegin("strSizeFormat()")) { TEST_RESULT_STR(strPtr(strSizeFormat(0)), "0B", "zero bytes"); TEST_RESULT_STR(strPtr(strSizeFormat(1023)), "1023B", "1023 bytes"); TEST_RESULT_STR(strPtr(strSizeFormat(1024)), "1KB", "1 KB"); TEST_RESULT_STR(strPtr(strSizeFormat(2200)), "2.1KB", "2.1 KB"); TEST_RESULT_STR(strPtr(strSizeFormat(1048576)), "1MB", "1 MB"); TEST_RESULT_STR(strPtr(strSizeFormat(20162900)), "19.2MB", "19.2 MB"); TEST_RESULT_STR(strPtr(strSizeFormat(1073741824)), "1GB", "1 GB"); TEST_RESULT_STR(strPtr(strSizeFormat(1073741824 + 107374183)), "1.1GB", "1.1 GB"); TEST_RESULT_STR(strPtr(strSizeFormat(UINT64_MAX)), "17179869183GB", "uint64 max"); } // ***************************************************************************************************************************** if (testBegin("strLstNew(), strLstAdd*(), strLstGet(), strLstMove(), strLstSize(), and strLstFree()")) { // Add strings to the list // ------------------------------------------------------------------------------------------------------------------------- StringList *list = NULL; MEM_CONTEXT_TEMP_BEGIN() { list = strLstNew(); for (int listIdx = 0; listIdx <= LIST_INITIAL_SIZE; listIdx++) { if (listIdx == 0) { TEST_RESULT_PTR(strLstAdd(list, NULL), list, "add null item"); } else TEST_RESULT_PTR(strLstAdd(list, strNewFmt("STR%02d", listIdx)), list, "add item %d", listIdx); } strLstMove(list, MEM_CONTEXT_OLD()); } MEM_CONTEXT_TEMP_END(); TEST_RESULT_INT(strLstSize(list), 9, "list size"); // Read them back and check values // ------------------------------------------------------------------------------------------------------------------------- for (unsigned int listIdx = 0; listIdx < strLstSize(list); listIdx++) { if (listIdx == 0) { TEST_RESULT_PTR(strLstGet(list, listIdx), NULL, "check null item"); } else TEST_RESULT_STR(strPtr(strLstGet(list, listIdx)), strPtr(strNewFmt("STR%02u", listIdx)), "check item %u", listIdx); } TEST_RESULT_VOID(strLstFree(list), "free string list"); TEST_RESULT_VOID(strLstFree(NULL), "free null string list"); }
bool dmtcp::Util::strEndsWith(const dmtcp::string& str, const char *pattern) { return strEndsWith(str.c_str(), pattern); }