Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » U++ community news and announcements » .ini file helpers
.ini file helpers [message #36723] Fri, 29 June 2012 00:38 Go to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
INI_BOOL, INI_STRING, INI_INT now can be used to encapsulate reading parameters from .ini file (while also providing overview and info about parameters), as demonstrated by reference/INI example.

#include <Core/Core.h>

using namespace Upp;

namespace Config {

INI_BOOL(flag1, false, "This is bool parameter 1")
INI_BOOL(flag2, true, "This is bool parameter 2")

INI_STRING(text, "default text", "Text parameter");

INI_INT(number, 123456, "Number parameter");

};

CONSOLE_APP_MAIN
{
	DDUMP(Config::flag1);
	DDUMP(Config::flag2);
	DDUMP(Config::text);
	DDUMP(Config::number);
	
	LOG(GetIniInfoFormatted());

	Config::number = 321;
	DDUMP(Config::number);
	
	LOG(GetIniInfoFormatted());
}

Re: .ini file helpers [message #36763 is a reply to message #36723] Tue, 03 July 2012 09:56 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
After some initial experiences, we are now using "namespace Ini" instead of "namespace Config", also classes used to represent flags are now public, so that they can be placed in .h:

In .cpp:

namespace Ini {
INI_BOOL(flag1, false, "This is bool parameter 1");
};


In .h:

namespace Ini {
Bool flag1;
};

Re: .ini file helpers [message #36831 is a reply to message #36723] Tue, 10 July 2012 21:14 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

Hi Mirek,

Today I tried to use the Ini* helper functions, but I found out that they are not very intuitive. I believe that with a little work, they might become much more useful.

I see these problems:
1) INI_DOUBLE is missing.

2) Once you call GetIniKey, the file is loaded and it is not possible to reload configuration. In a daemons/services, it is often desirable to reload config without restarting.

3) There are currently two separate mechanisms SetIniFile+GetIniKey function and the Ini namespace with INI_* macros. I didn't notice any connection between those two, but they are both shown in the reference/INI example.

Now tell me where I'm wrong Smile If I'm not, then I think all these problems are solvable.

The first one is trivial.

The second could be solved simply by using global static VectorMap for the key-value pairs and adding ReloadIniFile() function. Something like:
static StaticMutex sMtx;
static char  sIniFile[256];
static bool s_ini_loaded;
static VectorMap<String, String> s_ini_key;

void SetIniFile(const char *name) {
	Mutex::Lock __(sMtx);
	strcpy(sIniFile, name);
}

void ReloadIniFile(const char *name) {
	Mutex::Lock __(sMtx);
	if(*name)
		strcpy(sIniFile, name);
	s_ini_loaded = true;
	s_ini_key = LoadIniFile(*sIniFile ? sIniFile : ~ConfigFile("q.ini"));
	#ifdef PLATFORM_WIN32
		if(s_ini_key.GetCount() == 0)
			s_ini_key = LoadIniFile(~GetExeDirFile("q.ini"));
		if(s_ini_key.GetCount() == 0)
			s_ini_key = LoadIniFile("c:\\q.ini");
	#endif
	#ifdef PLATFORM_POSIX
		if(s_ini_key.GetCount() == 0)
			s_ini_key = LoadIniFile(GetHomeDirFile("q.ini"));
	#endif
}

String GetIniKey(const char *id, const String& def) {
	if(!s_ini_loaded)
		ReloadIniFile(sIniFile);
	return s_ini_key.Get(id, def);
}


But I think there is better solution and it is related to the problem 3). I propose to drop the GetIniKey function altogether (or keep it just as wrapper for backward compatibility). If we rewrite LoadIniStream to guess value types (not very difficult) and store them as Value instead of String AND add a reference to original Ini::IniXYZ variable into the IniInfo struct, we could iterate through IniInfos after each reload and update the values of the variables in the Ini namespace. In this way, the values declared in code would be possible to overwrite by values from INI file, even at multiple times if desired. Also, GetIniKey would be unnecessary, as Ini::MyVar would be always up to date and shorter to write.

I'm not sure if I expressed myself clear enough, ask if there is anything non-understandable or if you see any unsolvable problem within this proposal...

Best regards,
Honza
Re: .ini file helpers [message #36834 is a reply to message #36831] Tue, 10 July 2012 22:19 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
dolik.rce wrote on Tue, 10 July 2012 15:14

Hi Mirek,

Today I tried to use the Ini* helper functions, but I found out that they are not very intuitive. I believe that with a little work, they might become much more useful.

I see these problems:
1) INI_DOUBLE is missing.



Well, seemed sort of unnecessary...

Quote:


2) Once you call GetIniKey, the file is loaded and it is not possible to reload configuration. In a daemons/services, it is often desirable to reload config without restarting.



Fair enough, even if I cannot really imagine when I would want to change config (something you do usually a couple of times per month, at most) withou restarting. You would have to code your daemon really carefully to allow this... Wink

Quote:


3) There are currently two separate mechanisms SetIniFile+GetIniKey function and the Ini namespace with INI_* macros. I didn't notice any connection between those two, but they are both shown in the reference/INI example.



INI_* are just top-level encapsulation for GetIniKey. In fact, GetIniKey is very old part of U++, but it proved quite resilient Smile We have to keep it if only for maintaining BW compatibility.

Quote:


The second could be solved simply by using global static VectorMap for the key-value pairs and adding ReloadIniFile() function. Something like:
}[/code]



How about this:

void ReloadIniFile()
{
	s_ini_loaded = false;
}

void SetIniFile(const char *name) {
	Mutex::Lock __(sMtx);
	strcpy(sIniFile, name);
	ReloadIniFile();
}


Quote:


But I think there is better solution and it is related to the problem 3). I propose to drop the GetIniKey function altogether (or keep it just as wrapper for backward compatibility). If we rewrite LoadIniStream to guess value types (not very difficult)



IME, guessing value types is difficult AND wrong...

Mirek
Re: .ini file helpers [message #36835 is a reply to message #36834] Tue, 10 July 2012 22:36 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
INI_DOUBLE added.

BTW, I feel like we would rather need INI_INT64 and make it understand 'K', 'M', 'G' ('T') (like buffer=16M). Adding to RM for now...
Re: .ini file helpers [message #36837 is a reply to message #36834] Tue, 10 July 2012 23:03 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

mirek wrote on Tue, 10 July 2012 22:19

dolik.rce wrote on Tue, 10 July 2012 15:14

1) INI_DOUBLE is missing.


Well, seemed sort of unnecessary...
Well, at my work many different things is configured using configuration files, including doubles, arrays and other weird things Smile

mirek wrote on Tue, 10 July 2012 22:19

dolik.rce wrote on Tue, 10 July 2012 15:14


2) Once you call GetIniKey, the file is loaded and it is not possible to reload configuration. In a daemons/services, it is often desirable to reload config without restarting.



Fair enough, even if I cannot really imagine when I would want to change config (something you do usually a couple of times per month, at most) without restarting. You would have to code your daemon really carefully to allow this... Wink
It is quite common, just look at how many initscripts in /etc/init.d of any linux distro have a reload option Wink

mirek wrote on Tue, 10 July 2012 22:19

INI_* are just top-level encapsulation for GetIniKey.
Could you please explain that? I don't see any relation between these two things. (Maybe I'm just blind Smile )

mirek wrote on Tue, 10 July 2012 22:19

How about this:

void ReloadIniFile()
{
	s_ini_loaded = false;
}

void SetIniFile(const char *name) {
	Mutex::Lock __(sMtx);
	strcpy(sIniFile, name);
	ReloadIniFile();
}

Ok, that would work too Smile

mirek wrote on Tue, 10 July 2012 22:19

IME, guessing value types is difficult AND wrong...
Ok, I take that back. We don't have to guess, we know what the type is Smile At least where programmer tells us with INI_* macro. And if he tells us, it would be IMHO much more logical to serve it to him already converted to correct type.[/quote]

mirek wrote on Tue, 10 July 2012 22:19

INI_DOUBLE added.

BTW, I feel like we would rather need INI_INT64 and make it understand 'K', 'M', 'G' ('T') (like buffer=16M). Adding to RM for now...
I think the functions for suffixes are good idea. Also, allowing hexadecimal numbers would be nice Wink

Honza
Re: .ini file helpers [message #36841 is a reply to message #36837] Wed, 11 July 2012 10:12 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
mirek wrote on Tue, 10 July 2012 22:19

INI_* are just top-level encapsulation for GetIniKey.
Could you please explain that? I don't see any relation between these two things. (Maybe I'm just blind Smile )
[/quote]

Well, there is something like key=value type of configuration file which we want to support. We want to support reading such files and obtaining values for specific keys. Hence GetIniKey.

On higher level, we would like framework to perhaps take care about some of these values - parse the Value for appropriate type, store into global variable. That is INI_* stuff.

Quote:


mirek wrote on Tue, 10 July 2012 22:19

How about this:

void ReloadIniFile()
{
	s_ini_loaded = false;
}

void SetIniFile(const char *name) {
	Mutex::Lock __(sMtx);
	strcpy(sIniFile, name);
	ReloadIniFile();
}

Ok, that would work too Smile



Unfortunately, it is not that simple - we are using ONCELOCK_(loaded) in Ini variables, will need some more adjusting (as would need your version).

Mirek
Re: .ini file helpers [message #36842 is a reply to message #36841] Wed, 11 July 2012 11:10 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

Ok, now I see where I did a mistake. I called GetIniFormatted before SetIniFile to see the defualts. But GetIniFormatted calls GetIniKey and it fixes the file to q.ini, so the subsequent call to SetIniFile is useless. I guess all my confusion came from that.

I'll have a closer look at the reloading problem...

Honza
Re: .ini file helpers [message #36843 is a reply to message #36842] Wed, 11 July 2012 11:43 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
dolik.rce wrote on Wed, 11 July 2012 05:10


I'll have a closer look at the reloading problem...

Honza


I will fix that soon. But to be fast enough, I am afraid thread__ variables will be needed Wink

Mirek
Re: .ini file helpers [message #36859 is a reply to message #36837] Fri, 13 July 2012 12:30 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
dolik.rce wrote on Tue, 10 July 2012 17:03


BTW, I feel like we would rather need INI_INT64 and make it understand 'K', 'M', 'G' ('T') (like buffer=16M). Adding to RM for now...
I think the functions for suffixes are good idea. Also, allowing hexadecimal numbers would be nice Wink

Honza[/quote]

KMGT + 0x and INI_INT64 implemented...

Mirek
Re: .ini file helpers [message #36936 is a reply to message #36859] Tue, 24 July 2012 09:24 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Code changed to use DCL pattern to avoid mutex on (repeated) read path (hopefully I got all the lock-free voodoo right Smile

[Updated on: Tue, 24 July 2012 09:25]

Report message to a moderator

Previous Topic: TheIDE now supports JavaScript syntax highlighting for .js file extension
Next Topic: GetIniKey is now disallowed when APP_MAIN is not running
Goto Forum:
  


Current Time: Thu Mar 28 21:26:56 CET 2024

Total time taken to generate the page: 0.01452 seconds