char * Locale_GetUserLanguage(void) { char *locale; LocaleMap const *map; /* * Get the current message locale and map to our standard language name. */ locale = LocaleGetLocaleForCategory(LC_MESSAGES); if (locale != NULL) { int codesetStart = Str_Strcspn(locale, "."); for (map = localeMap; map->standardName != NULL && Str_Strncasecmp(locale, map->standardName, codesetStart) != 0 && Str_Strncasecmp(locale, map->systemName, codesetStart) != 0; map++) { } Log("LOCALE %s -> %s\n", locale, map->standardName == NULL ? "NULL" : map->standardName); free(locale); locale = Util_SafeStrdup(map->standardName); } return locale; }
Bool StrUtil_CaselessStartsWith(const char *s, // IN const char *prefix) // IN { ASSERT(s != NULL); ASSERT(prefix != NULL); return Str_Strncasecmp(s, prefix, strlen(prefix)) == 0; }
static MsgList * MsgId2MsgList(const char *idFmt) // IN message ID and English message { MsgList *m; const char *idp, *strp; /* All message strings must be prefixed by the message ID. */ ASSERT(Msg_HasMsgID(idFmt)); /* * Find the beginning of the ID (idp) and the string (strp). * The string should have the correct MSG_MAGIC(...)... form. */ idp = idFmt + MSG_MAGIC_LEN + 1; strp = strchr(idp, ')') + 1; m = Util_SafeMalloc(sizeof *m); m->format = Util_SafeStrdup(strp); m->next = NULL; m->args = NULL; m->numArgs = 0; if (vmx86_debug) { uint32 i; static const char *prfx[] = { "msg.", // bora/lib, VMX, ... "vob.", // Vmkernel OBservation "vpxa.", // VirtualCenter host agent "vpxd.", // VirtualCenter server "hostd.", // Host agent // Additional prefixes go here, but do not add "button." }; for (i = 0; i < ARRAYSIZE(prfx); i++) { if (!Str_Strncasecmp(idp, prfx[i], strlen(prfx[i]))) { break; } } if (i >= ARRAYSIZE(prfx)) { Panic("%s error: Invalid msg prefix in <%s>\n", __FUNCTION__, idp); } } m->id = Util_SafeStrndup(idp, strp - idp - 1 /* ')' character */); return m; }
Unicode File_StripSlashes(ConstUnicode path) // IN: { Unicode result, volume, dir, base; /* * SplitName handles all drive letter/UNC/whatever cases, all we * have to do is make sure the dir part is stripped of slashes if * there isn't a base part. */ File_SplitName(path, &volume, &dir, &base); if (!Unicode_IsEmpty(dir) && Unicode_IsEmpty(base)) { char *dir2 = Unicode_GetAllocBytes(dir, STRING_ENCODING_UTF8); size_t i = strlen(dir2); /* * Don't strip first slash on Windows, since we want at least * one slash to trail a drive letter/colon or UNC specifier. */ #if defined(_WIN32) while ((i > 1) && (('/' == dir2[i - 1]) || ('\\' == dir2[i - 1]))) { #else while ((i > 0) && ('/' == dir2[i - 1])) { #endif i--; } Unicode_Free(dir); dir = Unicode_AllocWithLength(dir2, i, STRING_ENCODING_UTF8); free(dir2); } result = Unicode_Join(volume, dir, base, NULL); Unicode_Free(volume); Unicode_Free(dir); Unicode_Free(base); return result; } /* *----------------------------------------------------------------------------- * * File_MapPathPrefix -- * * Given a path and a newPrefix -> oldPrefix mapping, transform * oldPath according to the mapping. * * Results: * The new path, or NULL if there is no mapping. * * Side effects: * The returned string is allocated, free it. * *----------------------------------------------------------------------------- */ char * File_MapPathPrefix(const char *oldPath, // IN: const char **oldPrefixes, // IN: const char **newPrefixes, // IN: size_t numPrefixes) // IN: { int i; size_t oldPathLen = strlen(oldPath); for (i = 0; i < numPrefixes; i++) { char *newPath; char *oldPrefix; char *newPrefix; size_t oldPrefixLen; oldPrefix = File_StripSlashes(oldPrefixes[i]); newPrefix = File_StripSlashes(newPrefixes[i]); oldPrefixLen = strlen(oldPrefix); /* * If the prefix matches on a DIRSEPS boundary, or the prefix is the * whole string, replace it. * * If we don't insist on matching a whole directory name, we could * mess things of if one directory is a substring of another. * * Perform a case-insensitive compare on Windows. (There are * case-insensitive filesystems on MacOS also, but the problem * is more acute with Windows because of frequent drive-letter * case mismatches. So in lieu of actually asking the * filesystem, let's just go with a simple ifdef for now.) */ if ((oldPathLen >= oldPrefixLen) && #ifdef _WIN32 (Str_Strncasecmp(oldPath, oldPrefix, oldPrefixLen) == 0) && #else (Str_Strncmp(oldPath, oldPrefix, oldPrefixLen) == 0) && #endif (strchr(VALID_DIRSEPS, oldPath[oldPrefixLen]) || (oldPath[oldPrefixLen] == '\0'))) { size_t newPrefixLen = strlen(newPrefix); size_t newPathLen = (oldPathLen - oldPrefixLen) + newPrefixLen; ASSERT(newPathLen > 0); ASSERT(oldPathLen >= oldPrefixLen); newPath = Util_SafeMalloc((newPathLen + 1) * sizeof(char)); memcpy(newPath, newPrefix, newPrefixLen); memcpy(newPath + newPrefixLen, oldPath + oldPrefixLen, oldPathLen - oldPrefixLen + 1); /* * It should only match once. Weird self-referencing mappings * aren't allowed. */ free(oldPrefix); free(newPrefix); return newPath; } free(oldPrefix); free(newPrefix); } return NULL; }
static int StrUtilStrncasecmp(const char *s1, const char *s2, size_t n) { return Str_Strncasecmp(s1, s2, n); }