Author: pulkomandy Date: 2010-07-01 13:54:09 +0200 (Thu, 01 Jul 2010) New Revision: 37323 Changeset: http://dev.haiku-os.org/changeset/37323/haiku Added: haiku/trunk/src/kits/locale/CatalogStub.cpp Modified: haiku/trunk/build/jam/BuildSetup haiku/trunk/headers/os/locale/Catalog.h haiku/trunk/headers/os/locale/LocaleRoster.h haiku/trunk/src/kits/locale/Catalog.cpp haiku/trunk/src/kits/locale/Jamfile haiku/trunk/src/kits/locale/LocaleRoster.cpp haiku/trunk/src/preferences/locale/Jamfile haiku/trunk/src/preferences/locale/LanguageListView.cpp haiku/trunk/src/preferences/locale/Locale.cpp haiku/trunk/src/preferences/locale/LocaleWindow.cpp haiku/trunk/src/preferences/locale/TimeFormatSettingsView.cpp Log: Add a new way of using the locale kit with static accessors instead of global variables. This has the following consequences : * Applications don't have to declare BCatalog fCatalog themselves, it's now done automatically * Libs and add-ons can be localized just the same way (except static libraries) For now this new system is yet disabled as I'm looking for some peer review before going on. To enable it you have to define B_TRANSLATE_USE_NEW_MACROS in each file doing catalog access. This will not stay, I'll update the other apps to use it. The linking in jamfiles must be not only with liblocale.so, but also liblocalestub.a. Not sure how to handle this for user-side applications. Libraries are also required to provide a MIME signature to use any catalog. The locale preflet is updated to the new system (as a test). Othe rapps will follow if everyone is ok with this approach. Modified: haiku/trunk/build/jam/BuildSetup =================================================================== --- haiku/trunk/build/jam/BuildSetup 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/build/jam/BuildSetup 2010-07-01 11:54:09 UTC (rev 37323) @@ -456,11 +456,17 @@ HAIKU_LIBSUPC++ = $(HAIKU_SHARED_LIBSUPC++) ; } + # network libraries HAIKU_NETWORK_LIBS = network ; HAIKU_NETAPI_LIB = bnetapi ; HAIKU_SELECT_UNAME_ETC_LIB = ; # libroot, against which we link anyway + +# locale libraries +HAIKU_LOCALE_LIBS = liblocale.so liblocalestub.a ; + + # library and executable glue code local commonGlueCode = <src!system!glue>init_term_dyn.o Modified: haiku/trunk/headers/os/locale/Catalog.h =================================================================== --- haiku/trunk/headers/os/locale/Catalog.h 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/headers/os/locale/Catalog.h 2010-07-01 11:54:09 UTC (rev 37323) @@ -33,6 +33,8 @@ status_t GetLanguage(BString *lang); status_t GetFingerprint(uint32 *fp); + status_t SetCatalog(const char* signature, uint32 fingerprint); + status_t InitCheck() const; int32 CountItems() const; @@ -56,6 +58,21 @@ extern BCatalog* be_catalog; extern BCatalog* be_app_catalog; + +// Proxy class for handling a "shared object local" catalog. +// This must be included (statically linked) into each shared object needing +// a catalog on its own (application, add-on, library, ...). The shared object +// must also have a mimetype so that the catalog can be identified. +class BCatalogStub { + private: + static BCatalog sCatalog; + static vint32 sCatalogInitOnce; + + public: + static BCatalog* GetCatalog(); +}; + + #ifndef B_AVOID_TRANSLATION_MACROS // macros for easy catalog-access, define B_AVOID_TRANSLATION_MACROS if // you don't want these: @@ -79,9 +96,25 @@ // source-file. +#ifdef B_TRANSLATE_USE_NEW_MACROS // Translation macros which may be used to shorten translation requests: #undef B_TRANSLATE #define B_TRANSLATE(str) \ + BCatalogStub::GetCatalog()->GetString((str), B_TRANSLATE_CONTEXT) + +#undef B_TRANSLATE_COMMENT +#define B_TRANSLATE_COMMENT(str, cmt) \ + BCatalogStub::GetCatalog()->GetString((str), B_TRANSLATE_CONTEXT, (cmt)) + +#undef B_TRANSLATE_ALL +#define B_TRANSLATE_ALL(str, ctx, cmt) \ + BCatalogStub::GetCatalog()->GetString((str), (ctx), (cmt)) + +#undef B_TRANSLATE_ID +#define B_TRANSLATE_ID(id) \ + BCatalogStub::GetCatalog()->GetString((id)) +#else +#define B_TRANSLATE(str) \ be_catalog->GetString((str), B_TRANSLATE_CONTEXT) #undef B_TRANSLATE_COMMENT @@ -95,6 +128,7 @@ #undef B_TRANSLATE_ID #define B_TRANSLATE_ID(id) \ be_catalog->GetString((id)) +#endif // Translation markers which can be used to mark static strings/IDs which // are used as key for translation requests (at other places in the code): Modified: haiku/trunk/headers/os/locale/LocaleRoster.h =================================================================== --- haiku/trunk/headers/os/locale/LocaleRoster.h 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/headers/os/locale/LocaleRoster.h 2010-07-01 11:54:09 UTC (rev 37323) @@ -36,6 +36,7 @@ // status_t GetCatalog(BLocale *,const char *mimeType, BCatalog *catalog); // status_t GetCatalog(const char *mimeType, BCatalog *catalog); // status_t SetCatalog(BLocale *,const char *mimeType, BCatalog *catalog); + BCatalog* GetCatalog(BCatalog* catalog, vint32* catalogInitStatus); // status_t GetLocaleFor(const char *langCode, const char *countryCode); Modified: haiku/trunk/src/kits/locale/Catalog.cpp =================================================================== --- haiku/trunk/src/kits/locale/Catalog.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/kits/locale/Catalog.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -103,6 +103,21 @@ status_t +BCatalog::SetCatalog(const char* signature, uint32 fingerprint) +{ + // TODO: The previous fCatalog is leaked here. (The whole chain, it + // looks like.) We should take care that internal members are always + // properly maintained. + // No other method should touch fCatalog directly, either (constructor for + // example) + fCatalog + = be_locale_roster->LoadCatalog(signature, NULL, fingerprint); + + return B_OK; +} + + +status_t BCatalog::GetAppCatalog(BCatalog* catalog) { app_info appInfo; @@ -120,14 +135,9 @@ BNode appNode(&appInfo.ref); appNode.ReadAttr(BLocaleRoster::kCatFingerprintAttr, B_UINT32_TYPE, 0, &fingerprint, sizeof(uint32)); + catalog->SetCatalog(sig.String(), fingerprint); // try to load catalog (with given fingerprint): - // TODO: Not so nice C++ design here, leading to such bugs: The previous - // fCatalog is leaked here. (The whole chain, it looks like.) There should - // be a SetCatalog() method (it can be private), and that should take care - // that internal members are always properly maintained. - catalog->fCatalog - = be_locale_roster->LoadCatalog(sig.String(), NULL, fingerprint); - + // load native embedded id-based catalog. If such a catalog exists, // we can fall back to native strings for id-based access, too. BCatalogAddOn *embeddedCatalog Added: haiku/trunk/src/kits/locale/CatalogStub.cpp =================================================================== --- haiku/trunk/src/kits/locale/CatalogStub.cpp (rev 0) +++ haiku/trunk/src/kits/locale/CatalogStub.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -0,0 +1,29 @@ +/* + * Copyright 2010, Adrien Destugues <pulkomandy@xxxxxxxxxxxxxxxxx>. + * Distributed under the terms of the MIT License. + */ + + +#ifndef __CATALOG_STUB_H__ +#define __CATALOG_STUB_H__ + + +#define B_TRANSLATE_USE_NEW_MACROS + + +#include <Catalog.h> +#include <Locale.h> +#include <LocaleRoster.h> + +BCatalog BCatalogStub::sCatalog; +vint32 BCatalogStub::sCatalogInitOnce = false; + + +/* static */ BCatalog* +BCatalogStub::GetCatalog() +{ + return be_locale_roster->GetCatalog(&sCatalog, &sCatalogInitOnce); +} + + +#endif Modified: haiku/trunk/src/kits/locale/Jamfile =================================================================== --- haiku/trunk/src/kits/locale/Jamfile 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/kits/locale/Jamfile 2010-07-01 11:54:09 UTC (rev 37323) @@ -41,6 +41,10 @@ : be $(TARGET_LIBSTDC++) libicu-common.so libicu-i18n.so ; +StaticLibrary liblocalestub.a + : CatalogStub.cpp + ; + SEARCH on [ FGristFiles StringForSize.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; SEARCH on [ FGristFiles ColorControl.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; Modified: haiku/trunk/src/kits/locale/LocaleRoster.cpp =================================================================== --- haiku/trunk/src/kits/locale/LocaleRoster.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/kits/locale/LocaleRoster.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -16,6 +16,7 @@ #include <stdio.h> // for debug only #include <syslog.h> +#include <AppFileInfo.h> #include <Autolock.h> #include <Catalog.h> #include <Collator.h> @@ -177,8 +178,8 @@ fInstantiateEmbeddedFunc = NULL; fCreateFunc = NULL; fLanguagesFunc = NULL; - log_team(LOG_DEBUG, "catalog-add-on %s has been unloaded", - fName.String()); +// log_team(LOG_DEBUG, "catalog-add-on %s has been unloaded", +// fName.String()); } } @@ -364,9 +365,6 @@ } } - log_team(LOG_ERR, "Found : %s priority: %d\n", - dent->d_name,priority); - if (priority >= 0) { // add-ons with priority < 0 will be ignored BCatalogAddOnInfo* addOnInfo @@ -386,10 +384,6 @@ for (int32 i=0; i<fCatalogAddOnInfos.CountItems(); ++i) { BCatalogAddOnInfo *info = static_cast<BCatalogAddOnInfo*>(fCatalogAddOnInfos.ItemAt(i)); - log_team(LOG_INFO, - "roster uses catalog-add-on %s/%s with priority %d", - info->fIsEmbedded ? "(embedded)" : info->fPath.String(), - info->fName.String(), info->fPriority); } } @@ -425,10 +419,65 @@ } +BCatalog* +BLocaleRoster::GetCatalog(BCatalog* catalog, vint32* catalogInitStatus) +{ + // This function is used in the translation macros, so it can't return a + // status_t. Maybe it could throw exceptions ? + + if (catalog == NULL) { + log_team(LOG_ERR, "GetCatalog called with a NULL catalog!"); + return catalog; + } + + if (*catalogInitStatus == true) { + // Catalog already loaded - nothing else to do + return catalog; + } + + // figure out image (shared object) from catalog address + image_info info; + int32 cookie = 0; + bool found = false; + + while (get_next_image_info(0, &cookie, &info) == B_OK) { + if ((char*)info.data < (char*)catalog && (char*)info.data+info.data_size + > (char*)catalog) { + found = true; + break; + } + } + + if (!found) { + log_team(LOG_DEBUG, "Catalog %x doesn't belong to any image !",catalog); + return catalog; + } + // figure out mimetype from image + BFile objectFile(info.name, B_READ_ONLY); + BAppFileInfo objectInfo(&objectFile); + char objectSignature[B_MIME_TYPE_LENGTH]; + objectInfo.GetSignature(objectSignature); + + // drop supertype from mimetype (should be "application/"): + char* stripSignature = objectSignature; + while(*(stripSignature++)!='/'); + + log_team(LOG_DEBUG, + "Image %s (address %x) requested catalog with mimetype %s", + info.name, catalog, stripSignature); + + // load the catalog for this mimetype and return it to the app + catalog->SetCatalog(stripSignature, 0); + *catalogInitStatus = true; + + return catalog; +} + + status_t BLocaleRoster::GetSystemCatalog(BCatalogAddOn **catalog) const { - if(!catalog) + if (!catalog) return B_BAD_VALUE; *catalog = be_locale_roster->LoadCatalog("system"); return B_OK; Modified: haiku/trunk/src/preferences/locale/Jamfile =================================================================== --- haiku/trunk/src/preferences/locale/Jamfile 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/preferences/locale/Jamfile 2010-07-01 11:54:09 UTC (rev 37323) @@ -10,8 +10,8 @@ LocaleWindow.cpp TimeFormatSettingsView.cpp - : be liblocale.so $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) libicu-common.so - libicu-data.so libshared.a + : be $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) libicu-common.so + libicu-data.so libshared.a $(HAIKU_LOCALE_LIBS) : Locale.rdef ; Modified: haiku/trunk/src/preferences/locale/LanguageListView.cpp =================================================================== --- haiku/trunk/src/preferences/locale/LanguageListView.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/preferences/locale/LanguageListView.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -16,6 +16,7 @@ #include <new> +#define B_TRANSLATE_USE_NEW_MACROS #include <Bitmap.h> #include <Country.h> #include <Catalog.h> Modified: haiku/trunk/src/preferences/locale/Locale.cpp =================================================================== --- haiku/trunk/src/preferences/locale/Locale.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/preferences/locale/Locale.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -4,6 +4,9 @@ */ +#define B_TRANSLATE_USE_NEW_MACROS + + #include "Locale.h" #include "LocaleWindow.h" @@ -57,7 +60,6 @@ private: Settings fSettings; LocaleWindow* fLocaleWindow; - BCatalog fCatalog; }; @@ -140,8 +142,6 @@ : BApplication(kSignature) { - be_locale->GetAppCatalog(&fCatalog); - fLocaleWindow = new LocaleWindow(); if (fSettings.Message().HasPoint("window_location")) { Modified: haiku/trunk/src/preferences/locale/LocaleWindow.cpp =================================================================== --- haiku/trunk/src/preferences/locale/LocaleWindow.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/preferences/locale/LocaleWindow.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -5,6 +5,9 @@ */ +#define B_TRANSLATE_USE_NEW_MACROS + + #include "Locale.h" #include "LocaleWindow.h" #include "LanguageListView.h" Modified: haiku/trunk/src/preferences/locale/TimeFormatSettingsView.cpp =================================================================== --- haiku/trunk/src/preferences/locale/TimeFormatSettingsView.cpp 2010-06-30 18:04:25 UTC (rev 37322) +++ haiku/trunk/src/preferences/locale/TimeFormatSettingsView.cpp 2010-07-01 11:54:09 UTC (rev 37323) @@ -4,6 +4,9 @@ */ +#define B_TRANSLATE_USE_NEW_MACROS + + #include "TimeFormatSettingsView.h" #include <Alert.h>