Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#6113 closed bug (fixed)

Locale Kit needs a way to load catalogs from libraries

Reported by: zooey Owned by: pulkomandy
Priority: normal Milestone: R1
Component: Kits/Locale Kit Version: R1/Development
Keywords: Cc:
Blocked By: Blocking: #5889
Has a Patch: no Platform: All

Description

Currently, the locale kit API only offers ways for apps and add-ons to load a catalog, but the same can't be done from a library (like libtracker, for instance).

This is just one part of the needed Locale Kit API overhaul this summer.

Change History (12)

comment:1 by Karvjorm, 9 years ago

I have planned to test some extra Singleton class to save BCatalog file. It would be public there. Each library .cpp file will test if the singleton class exists and if there isn't any, it will create the class and call be_locale->GetAppCatalog(&fAppCatalog). A library can include namespace classes and non-namespace functions. This could be then non-namespace class, so the non-namespace functions can access fAppCatalog, I think.

comment:2 by pulkomandy, 9 years ago

Owner: changed from zooey to pulkomandy
Status: newassigned

Ok. It is possible to load a catalog by hand if you provide it with a signature (this is what we do already for thing like StringForSize). For now this stuff is gathered in a single catalog attached to the locale library, but it is likely better to split it over to other libs.

in reply to:  2 comment:3 by zooey, 9 years ago

Replying to pulkomandy:

Ok. It is possible to load a catalog by hand if you provide it with a signature (this is what we do already for thing like StringForSize).

Do we? I can't seem to find it. All I can see is that we are calling LocaleRoster::GetSystemCatalog(), which in turn uses the private method LocaleRoster::LoadCatalog(). But since that is private, no one else can use it to load a catalog with an explicit signature.

For now this stuff is gathered in a single catalog attached to the locale library, but it is likely better to split it over to other libs.

Yes, only libbe should use the 'system' catalog (which we could rename to libbe.catalog), any other library should use its own catalog.

comment:4 by Karvjorm, 9 years ago

I have tried to solve this problem here: Ticket #6116 http://dev.haiku-os.org/ticket/6116

comment:5 by bonefish, 9 years ago

A few suggestions: I would get rid of be_catalog and be_app_catalog. Global variables are evil. Static accessors can be used instead. This also allows for lazy initialization. The static accessor method for the catalog of the current shared object would not live in liblocale.so, but in a static library any shared object that wants to use translations needs to link against. It would look like:

static BCatalog sCatalog;
static vint32 sCatalogInitOnce;


/*static*/ BCatalog*
BCatalog::CurrentCatalog()
{
	return _CurrentCatalog(&sCatalog, &sCatalogInitOnce);
}

_CurrentCatalog() can live in liblocale.so. Using the given address it can easily find out for which shared object to load the catalog. For users preferring explicit initialization a respective method returning an error code could be added as well.

comment:6 by bonefish, 9 years ago

I forgot to mention: CurrentCatalog() should have hidden visibility, so one cannot accidentally forget to link against the static lib.

comment:7 by axeld, 9 years ago

Sounds good to me.

comment:8 by pulkomandy, 9 years ago

Ok, I'm getting it. One more question, however : how can it find out the shared object from the address ? I had a look at the be book but couldn't find anything (I think it's in Kernel/Image, but...). Do I need to use get_image_info and look for the address ranges, until I find the one that matches the pointer ? Isn't there any "reverse lookup" for this ?

Also, is there a reliable way to derive a mimetype from this info ? For an application I know only of be_app->GetAppInfo ; I have no idea what I can do for add-ons and libraries. Is there even a mimetype set on libraries at all ?

in reply to:  8 comment:9 by bonefish, 9 years ago

Replying to pulkomandy:

Ok, I'm getting it. One more question, however : how can it find out the shared object from the address ? I had a look at the be book but couldn't find anything (I think it's in Kernel/Image, but...). Do I need to use get_image_info and look for the address ranges, until I find the one that matches the pointer ? Isn't there any "reverse lookup" for this ?

No, ATM iterating through the images via get_next_image_info() is the only way. Maybe we should introduce a

status_t get_image_info_for_address(team_id team, addr_t address, image_info* info);

to make this more efficient.

Also, is there a reliable way to derive a mimetype from this info ? For an application I know only of be_app->GetAppInfo ; I have no idea what I can do for add-ons and libraries.

Once you have the library/add-on path you can use BAppFileInfo::GetSignature().

Is there even a mimetype set on libraries at all ?

Usually not, but that could made a requirement, if a library wishes to use the locale kit.

comment:10 by pulkomandy, 9 years ago

Resolution: fixed
Status: assignedclosed

Fixed in hrev37323.

comment:11 by mt, 9 years ago

I think collectcatkeys.cpp (hrev37336) seems to not correctly updated.
My local copy still using BString rxString("(be_catalog
s*->
s*GetString
s*" after svn update. (both on Haiku and on Ubntsu.)

comment:12 by mt, 9 years ago

DoCatlogs rule (or collectcatkeys in tools) seems omitting BCatalogStub::GetCatalog().
(catkeys seems small!!)

Note: See TracTickets for help on using tickets.