CF_EXPORT CFStringRef CFBundleCopyLocalizedStringForLocalization(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName, CFStringRef localizationName) { if (!key) { return (value ? (CFStringRef)CFRetain(value) : (CFStringRef)CFRetain(CFSTR(""))); } // Make sure to check the mixed localizations key early -- if the main bundle has not yet been cached, then we need to create the cache of the Info.plist before we start asking for resources (11172381) (void)CFBundleAllowMixedLocalizations(); if (!tableName || CFEqual(tableName, CFSTR(""))) tableName = _CFBundleDefaultStringTableName; CFStringRef result = _copyStringFromTable(bundle, tableName, key, localizationName); if (!result) { if (!value) { result = (CFStringRef)CFRetain(key); } else if (CFEqual(value, CFSTR(""))) { result = (CFStringRef)CFRetain(key); } else { result = (CFStringRef)CFRetain(value); } static Boolean capitalize = false; if (capitalize) { CFMutableStringRef capitalizedResult = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, result); os_log_error(_CFBundleLocalizedStringLogger(), "ERROR: %@ not found in table %@ of bundle %@", key, tableName, bundle); CFStringUppercase(capitalizedResult, NULL); CFRelease(result); result = capitalizedResult; } } os_log_debug(_CFBundleLocalizedStringLogger(), "Bundle: %{private}@, key: %{public}@, value: %{public}@, table: %{public}@, localizationName: %{public}@, result: %{public}@", bundle, key, value, tableName, localizationName, result); return result; }
void mono_log_write_asl (const char *log_domain, GLogLevelFlags level, mono_bool hdr, const char *message) { switch (level & G_LOG_LEVEL_MASK) { case G_LOG_LEVEL_MESSAGE: os_log (OS_LOG_DEFAULT, "%s%s%s\n", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", message); break; case G_LOG_LEVEL_INFO: os_log_info (OS_LOG_DEFAULT, "%s%s%s\n", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", message); break; case G_LOG_LEVEL_DEBUG: os_log_debug (OS_LOG_DEFAULT, "%s%s%s\n", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", message); break; case G_LOG_LEVEL_ERROR: case G_LOG_LEVEL_WARNING: os_log_error (OS_LOG_DEFAULT, "%s%s%s\n", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", message); case G_LOG_LEVEL_CRITICAL: default: os_log_fault (OS_LOG_DEFAULT, "%s%s%s\n", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", message); break; } if (level & G_LOG_LEVEL_ERROR) abort(); }
static CFStringRef _copyStringFromTable(CFBundleRef bundle, CFStringRef tableName, CFStringRef key, CFStringRef localizationName) { // Check the cache first. If it's not there, populate the cache and check again. __CFLock(&bundle->_lock); // Only consult the cache when a specific localization has not been requested. We only cache results for the preferred language as determined by normal bundle lookup rules. if (!localizationName && bundle->_stringTable) { CFDictionaryRef stringTable = (CFDictionaryRef)CFDictionaryGetValue(bundle->_stringTable, tableName); if (stringTable) { CFStringRef result = CFDictionaryGetValue(stringTable, key); if (result) { CFRetain(result); } __CFUnlock(&bundle->_lock); return result; } } // Not in the local cache, so load the table. Unlock so we don't hold the lock across file system access. __CFUnlock(&bundle->_lock); CFDictionaryRef stringsTable = NULL; CFURLRef stringsTableURL = NULL; CFURLRef stringsDictTableURL = NULL; // Find the resource URL. if (localizationName) { stringsTableURL = CFBundleCopyResourceURLForLocalization(bundle, tableName, _CFBundleStringTableType, NULL, localizationName); stringsDictTableURL = CFBundleCopyResourceURLForLocalization(bundle, tableName, _CFBundleStringDictTableType, NULL, localizationName); } else { stringsTableURL = CFBundleCopyResourceURL(bundle, tableName, _CFBundleStringTableType, NULL); stringsDictTableURL = CFBundleCopyResourceURL(bundle, tableName, _CFBundleStringDictTableType, NULL); } // Next, look on disk for the regular strings file. if (!stringsTable && stringsTableURL) { CFDataRef tableData = _CFDataCreateFromURL(stringsTableURL, NULL); if (tableData) { CFErrorRef error = NULL; stringsTable = (CFDictionaryRef)CFPropertyListCreateWithData(CFGetAllocator(bundle), tableData, kCFPropertyListImmutable, NULL, &error); CFRelease(tableData); if (stringsTable && CFDictionaryGetTypeID() != CFGetTypeID(stringsTable)) { os_log_error(_CFBundleLocalizedStringLogger(), "Unable to load .strings file: %@ / %@: Top-level object was not a dictionary", bundle, tableName); CFRelease(stringsTable); stringsTable = NULL; } else if (!stringsTable && error) { os_log_error(_CFBundleLocalizedStringLogger(), "Unable to load .strings file: %@ / %@: %@", bundle, tableName, error); CFRelease(error); error = NULL; } } } // Check for a .stringsdict file. if (stringsDictTableURL) { CFDataRef tableData = _CFDataCreateFromURL(stringsDictTableURL, NULL); if (tableData) { CFErrorRef error = NULL; CFDictionaryRef stringsDictTable = (CFDictionaryRef)CFPropertyListCreateWithData(CFGetAllocator(bundle), tableData, kCFPropertyListImmutable, NULL, &error); CFRelease(tableData); if (!stringsDictTable && error) { os_log_error(_CFBundleLocalizedStringLogger(), "Unable to load .stringsdict file: %@ / %@: %@", bundle, tableName, error); CFRelease(error); error = NULL; } else if (stringsDictTable && CFDictionaryGetTypeID() != CFGetTypeID(stringsDictTable)) { os_log_error(_CFBundleLocalizedStringLogger(), "Unable to load .stringsdict file: %@ / %@: Top-level object was not a dictionary", bundle, tableName); CFRelease(stringsDictTable); stringsDictTable = NULL; } else if (stringsDictTable) { // Post-process the strings table. CFMutableDictionaryRef mutableStringsDictTable; if (stringsTable) { // Any strings that are in the stringsTable that are not in the stringsDict must be added to the stringsDict. // However, any entry in the stringsDictTable must override the content from stringsTable. // Start by copying the stringsTable. mutableStringsDictTable = CFDictionaryCreateMutableCopy(NULL, 0, stringsTable); // Replace any stringsTable entries with entries from stringsDictTable. This will override any entries from the original stringsTable if they existed. CFDictionaryApplyFunction(stringsDictTable, __CFStringsDictMergeApplyFunction, mutableStringsDictTable); } else { // Start with a copy of the stringsDictTable on its own. mutableStringsDictTable = CFDictionaryCreateMutableCopy(NULL, 0, stringsDictTable); } CFRelease(stringsDictTable); if (stringsTable) CFRelease(stringsTable); // The new strings table is the result of all the transforms above. stringsTable = mutableStringsDictTable; } } } if (stringsTableURL) CFRelease(stringsTableURL); if (stringsDictTableURL) CFRelease(stringsDictTableURL); // Last resort: create an empty table if (!stringsTable) { os_log_debug(_CFBundleLocalizedStringLogger(), "Hit last resort and creating empty strings table"); stringsTable = CFDictionaryCreate(CFGetAllocator(bundle), NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } // Insert the result into our local cache if ((!CFStringHasSuffix(tableName, CFSTR(".nocache")) || !_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) && localizationName == NULL) { // Take lock again, because this we will unlock after getting the value out of the table. __CFLock(&bundle->_lock); if (!bundle->_stringTable) bundle->_stringTable = CFDictionaryCreateMutable(CFGetAllocator(bundle), 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // If another thread beat us to setting this tableName, then we'll just replace it here. CFDictionarySetValue(bundle->_stringTable, tableName, stringsTable); } else { // Take lock again, because this we will unlock after getting the value out of the table. __CFLock(&bundle->_lock); } // Finally, fetch the result from the table CFStringRef result = CFDictionaryGetValue(stringsTable, key); if (result) { CFRetain(result); } __CFUnlock(&bundle->_lock); CFRelease(stringsTable); return result; }