Can you use multiple message domains in boost::locale? - c++

I have a number of applications that share a number of general libraries. I am trying to internationalize my applications using boost::locale. It will be easy for me to create a separate .mo file for each general library and for each specific application. I was wandering if it is possible to simultaneously use multiple message domains like this:
boost::locale::generator gen;
gen.add_messages_path(".");
gen.add_messages_domain("lib1");
gen.add_messages_domain("lib2");
std::locale::global(gen("zh_CN.UTF-8"));
.
.
.
boost::locale::gettext("Show image");
I was expecting boost::locale to search in both lib1.mo and lib2.mo, however this doesn't seem to work. Only messages from the first domain added are found, in this case from lib1.mo. If I add lib2 before lib1, then only messages from lib2 are found.
I know you can use a domain explicitly in the call like this:
boost::locale::dgettext("lib2", "Show image");
This does work, but I would like to avoid specifying the domain for every call. I am also not sure that this will work well with extracting the strings with xgettext.
Is it possible what I am trying to do? Am I missing something?
Please suggest any alternative if you know one.
I use msvc 9.0 (2008) and boost 1.48.

Since there were no answers posted to this question I assume that this is not possible with boost::locale. I will shortly therefore outline what I did to achieve my required functionality:
I created a singleton class with the following interface
class MY_GETTEXT
{
public:
void SetPath(const std::string& i_path);
void AddDomain(const std::string& i_domain);
void ChangeLocale(const std::string& i_locale);
std::string gettext(const std::string i_msg_id);
};
AddDomain is called for each domain you want to use, and adds it to a member set m_language_domains_a. ChangeLocale does some locale manipulation and stores a locale in the member m_locale, I will ignore its implementation here.
To translate you should simply call MY_GETTEXT::gettext. Its implementation looks like this:
std::string MY_GETTEXT::gettext(const std::string i_msg_id)
{
BOOST_FOREACH(const std::string& domain , m_language_domains_a)
{
if (boost::locale::translate(i_msg_id).str(m_locale, domain) != i_msg_id)
{
return boost::locale::translate(i_msg_id).str(m_locale, domain);
}
}
return i_msg_id;
}

Related

c++ best way to realise global switches/flags to control program behaviour without tying the classes to a common point

Let me elaborate on the title:
I want to implement a system that would allow me to enable/disable/modify the general behavior of my program. Here are some examples:
I could switch off and on logging
I could change if my graphing program should use floating or pixel coordinates
I could change if my calculations should be based upon some method or some other method
I could enable/disable certain aspects like maybe a extension api
I could enable/disable some basic integrated profiler (if I had one)
These are some made-up examples.
Now I want to know what the most common solution for this sort of thing is.
I could imagine this working with some sort of singelton class that gets instanced globally or in some other globally available object. Another thing that would be possible would be just constexpr or other variables floating around in a namespace, again globally.
However doing something like that, globally, feels like bad practise.
second part of the question
This might sound like I cant decide what I want, but I want a way to modify all these switches/flags or whatever they are actually called in a single location, without tying any of my classes to it. I don't know if this is possible however.
Why don't I want to do that? Well I like to make my classes somewhat reusable and I don't like tying classes together, unless its required by the DRY principle and or inheritance. I basically couldn't get rid of the flags without modifying the possible hundreds of classes that used them.
What I have tried in the past
Having it all as compiler defines. This worked reasonably well, however I didnt like that I couldnt make it so if the flag file was gone there were some sort of default settings that would make the classes themselves still operational and changeable (through these default values)
Having it as a class and instancing it globally (system class). Worked ok, however I didnt like instancing anything globally. Also same problem as above
Instancing the system class locally and passing it to the classes on construction. This was kinda cool, since I could make multiple instruction sets. However at the same time that kinda ruined the point since it would lead to things that needed to have one flag set the same to have them set differently and therefore failing to properly work together. Also passing it on every construction was a pain.
A static class. This one worked ok for the longest time, however there is still the problem when there are missing dependencies.
Summary
Basically I am looking for a way to have a single "place" where I can mess with some values (bools, floats etc.) and that will change the behaviour of all classes using them for whatever, where said values either overwrite default values or get replaced by default values if said "place" isnt defined.
If a Singleton class does not work for you , maybe using a DI container may fit in your third approach? It may help with the construction and make the code more testable.
There are some DI frameworks for c++, like https://github.com/google/fruit/wiki or https://github.com/boost-experimental/di which you can use.
If you decide to use switch/flags, pay attention for "cyclometric complexity".
If you do not change the skeleton of your algorithm but only his behaviour according to the objets in parameter, have a look at "template design pattern". This method allow you to define a generic algorithm and specify particular step for a particular situation.
Here's an approach I found useful; I don't know if it's what you're looking for, but maybe it will give you some ideas.
First, I created a BehaviorFlags.h file that declares the following function:
// Returns true iff the given feature/behavior flag was specified for us to use
bool IsBehaviorFlagEnabled(const char * flagName);
The idea being that any code in any of your classes could call this function to find out if a particular behavior should be enabled or not. For example, you might put this code at the top of your ExtensionsAPI.cpp file:
#include "BehaviorFlags.h"
static const enableExtensionAPI = IsBehaviorFlagEnabled("enable_extensions_api");
[...]
void DoTheExtensionsAPIStuff()
{
if (enableExtensionsAPI == false) return;
[... otherwise do the extensions API stuff ...]
}
Note that the IsBehaviorFlagEnabled() call is only executed once at program startup, for best run-time efficiency; but you also have the option of calling IsBehaviorFlagEnabled() on every call to DoTheExtensionsAPIStuff(), if run-time efficiency is less important that being able to change your program's behavior without having to restart your program.
As far as how the IsBehaviorFlagEnabled() function itself is implemented, it looks something like this (simplified version for demonstration purposes):
bool IsBehaviorFlagEnabled(const char * fileName)
{
// Note: a real implementation would find the user's home directory
// using the proper API and not just rely on ~ to expand to the home-dir path
std::string filePath = "~/MyProgram_Settings/";
filePath += fileName;
FILE * fpIn = fopen(filePath.c_str(), "r"); // i.e. does the file exist?
bool ret = (fpIn != NULL);
fclose(fpIn);
return ret;
}
The idea being that if you want to change your program's behavior, you can do so by creating a file (or folder) in the ~/MyProgram_Settings directory with the appropriate name. E.g. if you want to enable your Extensions API, you could just do a
touch ~/MyProgram_Settings/enable_extensions_api
... and then re-start your program, and now IsBehaviorFlagEnabled("enable_extensions_api") returns true and so your Extensions API is enabled.
The benefits I see of doing it this way (as opposed to parsing a .ini file at startup or something like that) are:
There's no need to modify any "central header file" or "registry file" every time you add a new behavior-flag.
You don't have to put a ParseINIFile() function at the top of main() in order for your flags-functionality to work correctly.
You don't have to use a text editor or memorize a .ini syntax to change the program's behavior
In a pinch (e.g. no shell access) you can create/remove settings simply using the "New Folder" and "Delete" functionality of the desktop's window manager.
The settings are persistent across runs of the program (i.e. no need to specify the same command line arguments every time)
The settings are persistent across reboots of the computer
The flags can be easily modified by a script (via e.g. touch ~/MyProgram_Settings/blah or rm -f ~/MyProgram_Settings/blah) -- much easier than getting a shell script to correctly modify a .ini file
If you have code in multiple different .cpp files that needs to be controlled by the same flag-file, you can just call IsBehaviorFlagEnabled("that_file") from each of them; no need to have every call site refer to the same global boolean variable if you don't want them to.
Extra credit: If you're using a bug-tracker and therefore have bug/feature ticket numbers assigned to various issues, you can creep the elegance a little bit further by also adding a class like this one:
/** This class encapsulates a feature that can be selectively disabled/enabled by putting an
* "enable_behavior_xxxx" or "disable_behavior_xxxx" file into the ~/MyProgram_Settings folder.
*/
class ConditionalBehavior
{
public:
/** Constructor.
* #param bugNumber Bug-Tracker ID number associated with this bug/feature.
* #param defaultState If true, this beheavior will be enabled by default (i.e. if no corresponding
* file exists in ~/MyProgram_Settings). If false, it will be disabled by default.
* #param switchAtVersion If specified, this feature's default-enabled state will be inverted if
* GetMyProgramVersion() returns any version number greater than this.
*/
ConditionalBehavior(int bugNumber, bool defaultState, int switchAtVersion = -1)
{
if ((switchAtVersion >= 0)&&(GetMyProgramVersion() >= switchAtVersion)) _enabled = !_enabled;
std::string fn = defaultState ? "disable" : "enable";
fn += "_behavior_";
fn += to_string(bugNumber);
if ((IsBehaviorFlagEnabled(fn))
||(IsBehaviorFlagEnabled("enable_everything")))
{
_enabled = !_enabled;
printf("Note: %s Behavior #%i\n", _enabled?"Enabling":"Disabling", bugNumber);
}
}
/** Returns true iff this feature should be enabled. */
bool IsEnabled() const {return _enabled;}
private:
bool _enabled;
};
Then, in your ExtensionsAPI.cpp file, you might have something like this:
// Extensions API feature is tracker #4321; disabled by default for now
// but you can try it out via "touch ~/MyProgram_Settings/enable_feature_4321"
static const ConditionalBehavior _feature4321(4321, false);
// Also tracker #4222 is now enabled-by-default, but you can disable
// it manually via "touch ~/MyProgram_Settings/disable_feature_4222"
static const ConditionalBehavior _feature4222(4222, true);
[...]
void DoTheExtensionsAPIStuff()
{
if (_feature4321.IsEnabled() == false) return;
[... otherwise do the extensions API stuff ...]
}
... or if you know that you are planning to make your Extensions API enabled-by-default starting with version 4500 of your program, you can set it so that Extensions API will be enabled-by-default only if GetMyProgramVersion() returns 4500 or greater:
static ConditionalBehavior _feature4321(4321, false, 4500);
[...]
... also, if you wanted to get more elaborate, the API could be extended so that IsBehaviorFlagEnabled() can optionally return a string to the caller containing the contents of the file it found (if any), so that you could do shell commands like:
echo "opengl" > ~/MyProgram_Settings/graphics_renderer
... to tell your program to use OpenGL for its 3D graphics, or etc:
// In Renderer.cpp
std::string rendererType;
if (IsDebugFlagEnabled("graphics_renderer", &rendererType))
{
printf("The user wants me to use [%s] for rendering 3D graphics!\n", rendererType.c_str());
}
else printf("The user didn't specify what renderer to use.\n");

C++ - Using a variable without knowing what it is called

I have a program that uses plug-ins. As I'm in development, these plug-ins are currently just .h and .cpp files that I add or remove from my project before re-compiling, but eventually they will be libraries.
Each plug-in contains lists of data in vectors, and I need to dynamically load data from the plug-ins without knowing which plug-ins are present. For instance:
// plugin1.h
extern vector<int> plugin1Data;
// plugin2.h
extern vector<int> plugin2Data;
// main.cpp
vector<vector<int>> pluginDataList;
int CountPlugins () {
// Some function that counts how many plug-ins are present, got this bit covered ;)
}
int main() {
int numPlugins = CountPlugins();
for (int i = 0; i < numPlugins; i++) {
vector<int> newPluginData = /***WAY TO ADD PLUGIN DATA!!!***/;
pluginDataList.push_back(newPluginData);
}
}
I already access the names of each plugin present during my CountPlugins() function, and have a list of names, so my first gut feeling was to use the name from each plugin to create a variable name like:
vector<string> pluginNames = /*filled by CountPlugins*/;
string pluginDataName = pluginNames.at(i) + "Data";
// Use pluginDataName to locate plugin1Data or plugin2Data
That's something I've done before in c# when I used to mess around with unity, but I've read a few stackoverflow posts clearly stating that it's not possible in c++. It's also a fairly messy solution in C# anyway as far as I remember.
If each plugin was a class instead of just a group of vectors, I could access the specific data doing something like plugin2.data... but then I still need to be able to reference the object stored within each plugin, and that'll mean that when I get round to compiling the plugins as libraries, I'll always have to link to class declaration and definition, which isn't ideal (though not out of the question if it'll give a nicer solution over all).
I'm all out of ideas after that, any help you can offer will be most welcome!
Thanks! Pete
Why dont you save the data as JSON between the application and the plugins ? That way you will also allow other types of tech to plug-into your app, like javascript based plugins via an embedded version of v8 or c#/.net plugins via mono.'

NetBeans code-template expansion; string manipulation

I'm trying to use the Code Templates feature with PHP in NetBeans (7.3), however I'm finding it rather limited. Given the following desired output:
public function addFoo(Foo $foo) {
$this->fooCollection[] = $foo;
}
I'm trying to have every instance of "foo"/"Foo" be variable; so I used a variable:
public function add${name}(${name} $$${name}) {
$this->${name}Collection[] = $$${name};
}
Of course, when expanded there isn't any regard given to the desired capitalization rules, because I can't find a way to implement that; the result being (given I populate ${name} with "Foo"):
public function addFoo(Foo $Foo) { // note the uppercase "Foo" in the argument
$this->FooCollection[] = $Foo; // and collection property names...
} // not what I had in mind
Now, I've read that NetBeans supports FreeMarker in it's templates, but that seems to be only for file-templates and not snippet-templates like these.
As far as I can tell, the FreeMarker version would look something like the following; however, it doesn't work, and ${name?capitalize} is simply seen as another variable name.
public function add${name?capitalize}(${name?capitalize} $$${name}) {
$this->${name}Collection[] = $$${name};
}
Passing "foo", allowing capitalize to fix it for type-names, second-words, etc.
Is there any way to get FreeMarker support here, or an alternative?
I'm open to any suggestions really; third-party plugins included. I just don't want to have to abandon NetBeans.
Addendum
The example given is trivial; an obvious solution for it specifically would be:
public function add${upperName}(${upperName} $$${lowerName}) {
$this->${lowerName}Collection[] = $$${lowerName};
}
Where upper/lower would be "Foo"/"foo" respectively. However, it's just an example, and I'm looking for something more robust in general (such as FreeMarker support)

How do I use the registry?

In the simplest possible terms (I'm an occasional programmer who lacks up-to-date detailed programming knowledge) can someone explain the simplest way to make use of the registry in codegear C++ (2007).
I have a line of code in an old (OLD!) program I wrote which is causing a significant delay in startup...
DLB->Directory=pIniFile->ReadString("Options","Last Directory","no key!");
The code is making use of an ini file. I would like to be able to use the registry instead (to write variables such as the last directory the application was using)
But the specifics are not important. I'd just like a generic how-to about using the registry that's specific to codegear c++ builder.
I've googled this, but as usual with this type of thing I get lots of pages about c++ builder and a few pages about the windows registry, but no pages that explain how to use one with the other.
Use the TRegistry class... (include registry.hpp)
//Untested, but something like...
TRegistry *reg = new TRegistry;
reg->RootKey = HKEY_CURRENT_USER; // Or whatever root you want to use
reg->OpenKey("theKey",true);
reg->ReadString("theParam",defaultValue);
reg->CloseKey();
Note, opening and reading a ini file is usually pretty fast, so maybe you need to test your assumption that the reading of the ini is actually your problem, I don't think that just grabbing your directory name from the registry instead is going to fix your problem.
Include the Registry.hpp file:
#include <Registry.hpp>
Then in any function you have, you can write the following to read the value:
String __fastcall ReadRegistryString(const String &key, const String &name,
const String &def)
{
TRegistry *reg = new TRegistry();
String result;
try {
reg->RootKey = HKEY_CURRENT_USER;
if (reg->OpenKeyReadOnly(key)) {
result = reg->ReadString(name, def);
reg->CloseKey();
}
}
__finally {
delete reg;
}
return result;
}
So reading the value should be as easy as:
ShowMessage(ReadRegistryString("Options", "Last Directory", "none"));
You can use the following to write the value:
void __fastcall WriteRegistryString(const String &key, const String &name,
const String &value)
{
TRegistry *reg = new TRegistry();
try {
reg->RootKey = HKEY_CURRENT_USER;
if (reg->OpenKey(key, true)) {
reg->WriteString(name, value);
reg->CloseKey();
}
}
__finally {
delete reg;
}
}
Should be self explaining, remembering the try ... finally is actually really helpful when using the VCL TRegistry class.
Edit
I've heard that .ini files are stored in the registry in Windows, so if you want the speed advantage of ini files you should call them something else - like .cfg
This is something I've heard from an although reliable source, I haven't tested it myself.
Tim is right but an even simpler class to use is TIniRegFile but it is also more limited in what you can do.
Please see the documentation for the QSettings class from the Qt 4.5 library. It will allow you to load and store your program's configuration settings easily and in a cross-platform manner. The Windows implementation uses the Windows registry for loading and storing your program's configuration data. On other platforms, the platform's preferred, native mechanism for storing configuration data will be used. This is far better than interacting with the Windows registry directly, as you will not be tied to a specific platform.

Managed C++ - Importing different DLLs based on configuration file

I am currently writing an application that will serve a similar purpose for multiple clients, but requires adaptations to how it will handle the data it is feed. In essence it will serve the same purpose, but hand out data totally differently.
So I decided to prodeed like this:
-Make common engine library that will hold the common functionalities of all ways and present the default interface ensuring that the different engines will respond the same way.
-Write a specific engine for each way of functioning....each one compiles into its own .dll.
So my project will end up with a bunch of libraries with some looking like this:
project_engine_base.dll
project_engine_way1.dll
project_engine_way2.dll
Now in the configuration file that we use for the user preferences there will an engine section so that we may decide which engine to use:
[ENGINE]
Way1
So somewhere in the code we will want to do:
If (this->M_ENGINE == "Way1")
//load dll for way1
Else If (this->M_ENGINE == "Way2")
//load dll for way2
Else
//no engines selected...tell user to modify settings and restart application
The question is...How will I import my dll(s) this way? Is it even possible? If not can I get some suggestions on how to achieve a similar way of functioning?
I am aware I could just import all of the dlls right at the start and just choose which engine to use, but the idea was that I didn't want to import too many engines for nothing and waste resources and we didn't want to have to ship all of those dlls to our customers. One customer will use one engine another will use a different one. Some of our customer will use more than one possibly hence the reason why I wanted to externalize this and allow our users to use a configuration file for engine switching.
Any ideas?
EDIT:
Just realized that even though each of my engine would present the same interface if they are loaded dynamically at runtime and not all referenced in the project, my project would not compile. So I don't have a choice but to include them all in my project don't I?
That also means they all have to be shipped to my customers. The settings in the configuration would only dictate with class I would use to initialize my engine member.
OR
I could have each of these engines be compiled to the same name. Only import one dll in my main project and that particular engine would be used all the time. That would render my customers unable to use our application for multiple clients of their own. Unless they were willing to manually switch dlls. Yuck
Any suggestions?
EDIT #2:
At this point seeing my options, I could also juste make one big dll containing the base engine as well as all the child ones and my configuration to let the user chose. Instead of referencing multiple dlls and shipping them all. Just have one huge one and ship/reference that one only. I am not too fond of this either as it means shipping one big dll to all of my customers instead of just one or two small ones that suit there needs. This is still the best solution that I've come up with though.
I am still looking for better suggestions or answers to my original question.
Thanks.
Use separate DLLs for each engine and use LoadLibrary in your main project to load the specific engine based on the configuration.
Have your engine interface in some common header file that all engines will derive from and this interface will be used in your main project aswell.
It might look like this:
// this should be an abstract class
class engine {
public:
virtual void func1() = 0;
virtual void func2() = 0;
...
};
In each different engine implementation export a function from the DLL, something like this:
// might aswell use auto_ptr here
engine* getEngine() { return new EngineImplementationNumberOne(); }
Now in your main project simply load the DLL you're interested in using LoadLibrary and then GetProcAddress the getEngine function.
string dllname;
if (this->M_ENGINE == "Way1")
dllname = "dllname1.dll";
else if (this->M_ENGINE == "Way2")
dllname = "dllname2.dll";
else
throw configuration_error();
HMODULE h = LoadLibraryA(dllname.c_str());
typedef engine* (*TCreateEngine)();
TCreateEngine func = (TCreateEngine)GetProcAddress(h, "getEngine");
engine* e = func();
The name of the exported function will probably get mangled, so you could either use DEF files or extern "C" in your DLLs, also don't forget to check for errors.
The solution I came to is the following:
Engine_Base^ engine_for_app;
Assembly^ SampleAssembly;
Type^ engineType;
if (this->M_ENGINE == "A")
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_A.dll");
engineType = SampleAssembly->GetType("Engine_A");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2));
}
else
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_B.dll");
engineType = SampleAssembly->GetType("Engine_B");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2, param3, param4));
}
I used the answer from Daniel and the comments that were made on his answer. After some extra research I came across the LoadFrom method.