Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-06

Why was XML format chosen for storing settings in Lazarus IDE?

42 messages · 13 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I thought I would pose this question in a new thread seeing that the other thread got totally high-jacked (and not by me for a change). :)

I'm curious to know what was the reason behind the decision to use XML for storing simple Lazarus settings, instead of the much simpler INI format? This is a legit question and I'm very curious as to the answer. Please note, this is not a feature request or me telling the Lazarus devs to change yet another thing in Lazarus. This is simply me asking a question I don't have an answer too.

Here are some points that were raised before:

* FCL, LCL and Lazarus IDE have XML read/write code. They don't all work the same, and I doubt they all have the same functionality.
* Not all code in Lazarus IDE uses the same XML read/write code
* Most XML examples in my ~/.lazarus/ directory would be much simpler presented if they where INI files.
* FPC and Delphi has brilliant INI file support, and it's dead easy to use.
* What is the actual advantage of XML in this case or was it chosen simply because XML was the flavour of the month at time of implementation. Yes, at one point everything had to be XML or it just wasn't cool. :-)
* Reading INI fast is FAST.

To make others understand my confusion regarding the XML choice, here is an example, using the compileroptions.xml file located in my ~/.lazarus/ directory.

-------------------[ compileroptions.xml
]-------------------------------------
<?xml version="1.0"?>
<CONFIG>
<CompilerOptionsVersion Value="8"/>
<CompilerOptionsSearchPaths>
<IncludeFiles Value="$(ProjOutDir)/"/>
<UnitOutputDirectory Value="units/$(TargetCPU)-$(TargetOS)/"/> </CompilerOptionsSearchPaths>
<CompilerOptionsParsing>
<SyntaxOptions>
<UseAnsiStrings Value="True"/>
</SyntaxOptions>
</CompilerOptionsParsing>
<CompilerOptionsOther>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</CompilerOptionsOther>
</CONFIG>
-----------------------------------------------------------------------------------------

This is a relatively small example, but still highlights my point. Just looking at it gives me a headache. ;-) Now lets convert that to a INI styled file.

BTW: Does anybody know what INI actually stands for? Initialization maybe?

-------------------[ compileroptions.ini
]-------------------------------------
[SearchPaths]
IncludeFiles=$(ProjOutDir)/
UnitOutputDirectory=units/$(TargetCPU)-$(TargetOS)/

[Parsing]
UseAnsiStrings=1

[Other]
UseMsgFile=1
CompilerPath=$(CompPath)
---------------------------------------------

Now both examples contain the same information, but lets be honest.. Which one is easier to read (via human or program), manually tweak if needed via human in IDE screws up, takes up less disk space.

I fully understand that XML has it's place in data transport and helps describe complex data. But using XML for something as simple as storing a few application settings. It just seems very inappropriate in this case, and a classic example of over-engineering.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Jaqui Greenlees
to Graeme Geldenhuys
Graeme Geldenhuys wrote 12 lines
Hi, I thought I would pose this question in a new thread seeing that the other thread got totally high-jacked (and not by me for a change). :) I'm curious to know what was the reason behind the decision to use XML for storing simple Lazarus settings, instead of the much simpler INI format? This is a legit question and I'm very curious as to the answer. Please note, this is not a feature request or me telling the Lazarus devs to change yet another thing in Lazarus. This is simply me asking a question I don't have an answer too.

I wasn't part of the decision making process on it, but I do believe that the XML format is a better option despite the lower human readability of it. if needed it is far simpler to extend the format to handle future requirements of the project than it would be to get an ini style file to do the same. In this I mean where he file is being used for more than just a few configuration settings. This would mean that the XML format is paving the way for future development(s) that an ini may not support.

Jaqui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20100618/57f94c7f/attachment.html>

Reply by email

Graeme Geldenhuys
to Jaqui Greenlees
Jaqui Greenlees wrote
few configuration settings. This would mean that the XML format is paving the way for future development(s) that an ini may not support.

Thanks for your reply.

For that argument to be more credible, and for XML to be a more appropriate format, then Lazarus IDE should have used a single .xml file for all settings. After all, XML is good at hierarchy-styled data. But as it is used now, having many small and rather flat-hierarchy xml files makes no sense. In the current usage style of saving settings, INI files would have made more sense.

At this point I would also like to point out that INI files could be used for rather complex settings too. Inno Setup (*.iss files), Apache Web Server (*.conf) and Makefile's (eg: FPC's Makefile.fpc) being such examples. They might not have the traditional INI file extension, but for all intent purposes, they are in the INI file format.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Henry Vermaak
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…
Graeme Geldenhuys wrote
Now both examples contain the same information, but lets be honest.. Which one is easier to read (via human or program), manually tweak if needed via human in IDE screws up, takes up less disk space.

The ini file is easier to read when it's small, but it's limited in obvious ways. Xml makes hierarchies very clear. You can't put sections inside sections in an ini file, so you have to resort to other hacks and tricks, which you would have to parse manually. Most people just tend to flatten it out, which you did in your example. With this solution you need to combat duplicate names, say, for example there was a UseAnsiStrings tag in another block in the CompilerOptionsParsing block. You would've had to add some prefix, which in time will make the ini more unreadable.

I fully understand that XML has it's place in data transport and helps describe complex data. But using XML for something as simple as storing a few application settings. It just seems very inappropriate in this case, and a classic example of over-engineering.

Possibly. I tend to store app settings in an ini file, but it's not a very scalable solution, as Jaqui suggested.

Henry

Reply by email

Michael Schnell
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…

For me XML is a quite logical extension to INI format.

While I feel that an XML file for flat structures (like doable in INI) only imposes a slight overhead in the file regarding INI, it provides some important extensions:

- it's a commonly agreed standard with open source handling software available everywhere
- it provides a standard way to handle Unicode (or I at least hope so)
- it provides a standard way to handle binary code (bas64)
- it is extensible to non-flat structures.

The downside of course is that the handling code is a lot more complex and thus slower.

If Lazarus uses several different libraries for XML handling this of course should be cured. A single library should be used and provided to the Lazarus users to call in their projects.

-Michael

Reply by email

Graeme Geldenhuys
to Henry Vermaak: The ini file is easier to read when it's small, but it's limited in obvious ways. Xml…
Henry Vermaak wrote
obvious ways. Xml makes hierarchies very clear.

Yes, I stated that, but that doesn't seem to be how Lazarus IDE uses it. If *all* settings was stored in a single settings.xml file, then yes, XML would probably make more sense.

other hacks and tricks, which you would have to parse manually. Most people just tend to flatten it out, which you did in your example.

In my example, the filename itself told me it is "compiler options", so I didn't see the need to duplicate that fact in the section names. I wouldn't really go as far as calling it a "trick" or "hack", just normalization of data and removing duplicates. :)

CompilerOptionsParsing block. You would've had to add some prefix, which in time will make the ini more unreadable.

Umm... the current xml files already use stacks of prefixes. For example "compileroptionsXXX" or "XXXoptions". So in the case of XML, all those prefixes are accepted behaviour (which then could be too in INI files), or those prefixes could be removed from the XML files and make it more (human) readable than it currently is.

Possibly. I tend to store app settings in an ini file,

So do I and probably most other developers here too. Even FPC's RTL uses INI files for ~/.config/<appname>/ settings which Lazarus IDE could have piggybacked on. That's why I am interested to here the reason from a Lazarus core developer why Lazarus IDE chose XML. Maybe they know something us poor mortals don't. ;-)

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Henry Vermaak
to Graeme Geldenhuys
Graeme Geldenhuys wrote 6 lines
On 18/06/2010, Henry Vermaak ?wrote: > obvious ways. ?Xml makes hierarchies very clear. Yes, I stated that, but that doesn't seem to be how Lazarus IDE uses it. If *all* settings was stored in a single settings.xml file, then yes, XML would probably make more sense.

One file would make sense, I agree.

snip

Sure it's _possible_ to implement all of this in ini format. It's just not sane and logical and scalable.

Sure it is harder to read, but luckily you won't have to read it often. Why are you even complaining about this? Another storm in a teacup?

Reply by email

Graeme Geldenhuys
to Henry Vermaak: One file would make sense, I agree. Sure it's _possible_ to implement all of this in ini…
Henry Vermaak wrote
often. Why are you even complaining about this? Another storm in a teacup?

At this point, mostly out of curiosity. :)

On the other hand, there is no clear documentation about this for developers that would like to extend Lazarus IDE. For example, I wrote a few IDE add-ons over the years, and in all cases I simply followed the crowd blindly (due to lack of docs) and created yet more .xml files (one for each extension). My preference would have been INI files because they are easier to use, and the settings stored was very simple.

My last add-on was semi-rejected (or simply hanging in limo) mostly because I created yet another xml file (but this time for good reasons
- a design/shared usage choice), and because I didn't use one of the many ways (apparently some are preferred above others) in Lazarus IDE code to read/write from such xml files.

So if there was some logical reason for using xml, and a clear-cut reason why it was chosen and what exact method must be used to read/write them, then I would like to document that somewhere in the wiki for other Lazarus add-on developers.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Henry Vermaak
to Graeme Geldenhuys
Graeme Geldenhuys wrote 24 lines
On 18/06/2010, Henry Vermaak ?wrote: > often. ?Why are you even complaining about this? ?Another storm in a > teacup? At this point, mostly out of curiosity. ?:) On the other hand, there is no clear documentation about this for developers that would like to extend Lazarus IDE. For example, I wrote a few IDE add-ons over the years, and in all cases I simply followed the crowd blindly (due to lack of docs) and created yet more .xml files (one for each extension). ?My preference would have been INI files because they are easier to use, and the settings stored was very simple. My last add-on was semi-rejected (or simply hanging in limo) mostly because I created yet another xml file (but this time for good reasons - a design/shared usage choice), and because I didn't use one of the many ways (apparently some are preferred above others) in Lazarus IDE code to read/write from such xml files. So if there was some logical reason for using xml, and a clear-cut reason why it was chosen and what exact method must be used to read/write them, then I would like to document that somewhere in the wiki for other Lazarus add-on developers.

Fair enough. You've got a couple of viewpoints or reasons for xml now (not that it really matters, since they're using it now anyway and are unlikely to change). So all we need for the docs is which way is preferable to do xml read/write.

Does lazarus have a nice xml options class that add-ons can query to retrieve their settings, or does every add-on have to do this themselves? I can see that there's a lot of benefit in abstracting this out.

Reply by email

Alexander Klenin
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…
Graeme Geldenhuys wrote
I'm curious to know what was the reason behind the decision to use XML for storing simple Lazarus settings, instead of the much simpler INI format?

In my view, the points for XML vs INI are:
1) well-defined encoding support
2) well-defined quoting
3) ability to represent arbitrary hierarchy in a consistent manner (vs. different methods for different ini-files)
The points against XML are:
1) unsuited for processing by humans
2) inefficient storage due to closing tags -- not important because config files are rather small
3) somewhat inefficient in processing -- which can be ameliorated by a good XML library,
I do not actually know how good FPC/Lazarus libraries are.
4) reading/writing code is ugly and full of duplication -- but this is a problem of Lazaurs,
not intrinsic to XML itself

From these points, it seems to me that benefits of XML out-weight it's

deficiencies.

However, if we would discuss a format that Lazarus should use (which we do not, according to the original post ;-), I would like to suggest a better alternative to both: lfm files. Benefits of LFM vs. XML:
1) compact
2) human-readable
3) can be read/written directly to the object via RTTI, thus drastically simplifying read/write code
(I estimate a few thousands lines of code might be eliminated from Lazarus).

Benefits of LFM vs. ini:
1) has now-quite-well-defined, but good enough support for encoding and quoting
2) is able to represent arbitrary data structures as well as XML

See below for an example.

Show quoted text 47 lines
To make others understand my confusion regarding the XML choice, here is an example, using the compileroptions.xml file located in my ~/.lazarus/ directory. -------------------[ ?compileroptions.xml ]------------------------------------- <?xml version="1.0"?> <CONFIG> ?<CompilerOptionsVersion Value="8"/> ?<CompilerOptionsSearchPaths> ? ?<IncludeFiles Value="$(ProjOutDir)/"/> ? ?<UnitOutputDirectory Value="units/$(TargetCPU)-$(TargetOS)/"/> ?</CompilerOptionsSearchPaths> ?<CompilerOptionsParsing> ? ?<SyntaxOptions> ? ? ?<UseAnsiStrings Value="True"/> ? ?</SyntaxOptions> ?</CompilerOptionsParsing> ?<CompilerOptionsOther> ? ?<CompilerMessages> ? ? ?<UseMsgFile Value="True"/> ? ?</CompilerMessages> ? ?<CompilerPath Value="$(CompPath)"/> ?</CompilerOptionsOther> </CONFIG> ----------------------------------------------------------------------------------------- This is a relatively small example, but still highlights my point. Just looking at it gives me a headache. ;-) Now lets convert that to a INI styled file. BTW: Does anybody know what INI actually stands for? Initialization maybe? -------------------[ ?compileroptions.ini ]------------------------------------- [SearchPaths] IncludeFiles=$(ProjOutDir)/ UnitOutputDirectory=units/$(TargetCPU)-$(TargetOS)/ [Parsing] UseAnsiStrings=1 [Other] UseMsgFile=1 CompilerPath=$(CompPath) ---------------------------------------------

object Options: TLazCompilerOptions
object SearchPaths: TSearchPaths
IncludeFiles='$(ProjOutDir)/'
UnitOutputDirectory='units/$(TargetCPU)-$(TargetOS)/'

  end
  object Parsing: TParsingOptions
    UseAnsiStrings=1
  end
  object Other: TOtherOptions
    UseMsgFile=1
    CompilerPath='$(CompPath)'
  end

end

Alexander S. Klenin

Reply by email

Mark Morgan Lloyd
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…
Graeme Geldenhuys wrote
BTW: Does anybody know what INI actually stands for? Initialization maybe?

It's as much of "initialization" as MS could fit into a three-letter extension when it started using it for Windows in the early-80s.

Show quoted text 8 lines
Now both examples contain the same information, but lets be honest.. Which one is easier to read (via human or program), manually tweak if needed via human in IDE screws up, takes up less disk space. I fully understand that XML has it's place in data transport and helps describe complex data. But using XML for something as simple as storing a few application settings. It just seems very inappropriate in this case, and a classic example of over-engineering.

I agree, but quite frankly we've got it, it works, so let's live with it. Unless, of course, you're volunteering to write a unit which will convert seamlessly and reliably between the two formats, so that the IDE will work out whether the user has updated the human-readable one and import accordingly.

Frankly, .ini files that users could (and did) update manually with the wrong kind of editor were a support nightmare. But (as others have said) that doesn't detract from their usefulness.

I'm currently using a TInifile subclassed to add array- and record-style setting names, which pass nicely through the standard reader. However that raises a significant question: if I'd coded something to expect a simple value and then needed to turn it into an array, how many .ini files would need to be updated and could a program do it 100% reliably?

That isn't quite academic: it has, in effect, happened now that the IDE handles multiple editor windows. XML- and any worthwhile parser- knows how to handle that out of the box, a non-standard hack might not.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Alexander Klenin
to Alexander Klenin: On Fri, Jun 18, 2010 at 20:15, Graeme Geldenhuys In my view, the points for XML vs INI…
Alexander Klenin wrote
4) reading/writing code is ugly and full of duplication -- but this is a problem of Lazaurs, ?not intrinsic to XML itself

[skip]

Show quoted text 5 lines
Benefits of LFM vs. XML: 3) can be read/written directly to the object via RTTI, thus drastically simplifying read/write code (I estimate a few thousands lines of code might be eliminated from Lazarus).

To illustrate, here is a snipped of Lazarus code reading the compiler options:

  { Linking }
  p:=Path+'Linking/';
  GenerateDebugInfo :=
XMLConfigFile.GetValue(p+'Debugging/GenerateDebugInfo/Value', false);
  UseLineInfoUnit :=
XMLConfigFile.GetValue(p+'Debugging/UseLineInfoUnit/Value', true);
  GenerateDwarf :=
XMLConfigFile.GetValue(p+'Debugging/GenerateDwarf/Value', false);
  UseHeaptrc := XMLConfigFile.GetValue(p+'Debugging/UseHeaptrc/Value', false);
  UseValgrind := XMLConfigFile.GetValue(p+'Debugging/UseValgrind/Value', false);
  GenGProfCode :=
XMLConfigFile.GetValue(p+'Debugging/GenGProfCode/Value', false);
  StripSymbols :=
XMLConfigFile.GetValue(p+'Debugging/StripSymbols/Value', false);

and here is the corresponding code to write them:

  { Linking }
  p:=Path+'Linking/';
  XMLConfigFile.SetDeleteValue(p+'Debugging/GenerateDebugInfo/Value',
GenerateDebugInfo,false);
  XMLConfigFile.SetDeleteValue(p+'Debugging/UseLineInfoUnit/Value',
UseLineInfoUnit,true);
  XMLConfigFile.SetDeleteValue(p+'Debugging/GenerateDwarf/Value',
GenerateDwarf, false);
  XMLConfigFile.SetDeleteValue(p+'Debugging/UseHeaptrc/Value',
UseHeaptrc,false);
  XMLConfigFile.SetDeleteValue(p+'Debugging/UseValgrind/Value',
UseValgrind,false);
  XMLConfigFile.SetDeleteValue(p+'Debugging/GenGProfCode/Value',
GenGProfCode,false);
  XMLConfigFile.SetDeleteValue(p+'Debugging/StripSymbols/Value',
StripSymbols,false);

Clearly, those are not not the best examples of applying DRY principle ;-)

Alexander S. Klenin

Reply by email

Graeme Geldenhuys
to Alexander Klenin
Alexander Klenin wrote
To illustrate, here is a snipped of Lazarus code reading the compiler options:

And to show you how confusing it is inside the Lazarus IDE code, here is another example - very different from you example.

------------------------------------
const
  SConfigFile         = 'idebrowserwin.xml';
  KeyStartDir         = 'StartDir';
  KeyCustomDir        = 'CustomDir';
  KeySplitterPos      = 'SplitterPos';
resourcestring
  SFileBrowserIDEMenu = 'IDEFileBrowser';
  SFileBrowserIDEMenuCaption = 'File Browser window';

{ TFileBrowserController }

procedure TFileBrowserController.ReadConfig;
begin
  with GetIDEConfigStorage(SConfigFile, True) do
    try
      FStartDir  := TStartDir(GetValue(KeyStartDir, Ord(sdProjectDir)));
      FCustomDir := GetValue(KeyCustomDir, '');
    finally
      Free;
    end;
end;
procedure TFileBrowserController.WriteConfig;
begin
  with GetIDEConfigStorage(SConfigFile, True) do
    try
      SetValue(KeyStartDir, Ord(FstartDir));
      SetValue(KeyCustomDir, CustomDir);
      FNeedSave := False;
    finally
      Free;
    end;
end;

------------------------------------

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Marco van de Voort
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…
Graeme Geldenhuys wrote 7 lines
I'm curious to know what was the reason behind the decision to use XML for storing simple Lazarus settings, instead of the much simpler INI format? This is a legit question and I'm very curious as to the answer. Please note, this is not a feature request or me telling the Lazarus devs to change yet another thing in Lazarus. This is simply me asking a question I don't have an answer too.

I don't know why Lazarus does, but I can tell you why I changed from .ini to .xml (actually lazarus' exact units) in my work app.

The simple reason is that .ini is one level only, and XML has an infinite nesting depth.

Reply by email

Graeme Geldenhuys
to Henry Vermaak: Fair enough. You've got a couple of viewpoints or reasons for xml now (not that it…
Henry Vermaak wrote
themselves? I can see that there's a lot of benefit in abstracting this out.

Correct. Having one way (class) of reading/writing xml settings inside the IDE would help a huge amount. With INI it is damn easy - one class TINIFile and you are set.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Marco van de Voort
to Henry Vermaak: The ini file is easier to read when it's small, but it's limited in obvious ways. Xml…
Henry Vermaak wrote 9 lines
On 18 June 2010 10:15, Graeme Geldenhuys wrote: > > Now both examples contain the same information, but lets be honest.. > Which one is easier to read (via human or program), manually tweak if > needed via human in IDE screws up, takes up less disk space. The ini file is easier to read when it's small, but it's limited in obvious ways. Xml makes hierarchies very clear. You can't put sections inside sections in an ini file,

I actually tried to implement this once by using [[[section]]] and [[[subsubsection]].

There were two main problems:
- copy and paste between levels didn't work.
- you get a bit of a dangling else problem because you don't have closing delimiters.

Warning, this source is old (previous millenium) and serious convoluted since one of my first tried to reuse one parser for both INI files and keyword based config files.

http://www.stack.nl/~marcov/files/conffile.zip

Reply by email

Graeme Geldenhuys
to Alexander Klenin: On Fri, Jun 18, 2010 at 20:15, Graeme Geldenhuys In my view, the points for XML vs INI…
Alexander Klenin wrote 7 lines
Benefits of LFM vs. ini: 1) has now-quite-well-defined, but good enough support for encoding and quoting 2) is able to represent arbitrary data structures as well as XML See below for an example.

Not that I really want to deviate from the original thread, but in your case, I not through JSON into the mix too. :) I haven't worked with JSON myself, but from looking at output examples, JSON seems a lot more logical and readable than XML (for many use cases).

I suppose JSON could be a option for simple settings too, replacing INI with something that is as readable as INI, supports infinite nested settings, supports various data types including objects and arrays and uses less bytes than the equivalent XML file (in most cases, but you can butcher XML to use less bytes but with that comes unreadable output).

See Also: http://en.wikipedia.org/wiki/JSON

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Alexander Klenin
to Marco van de Voort: I actually tried to implement this once by using [[[section]]] and [[[subsubsection]].…
Marco van de Voort wrote
I actually tried to implement this once by using [[[section]]] and [[[subsubsection]].

I did that recently for one of my projects,
but using [.subsection] [..subsection] [...subsubsection] instead.

There were two main problems: - copy and paste between levels didn't work.

And that is not necessarily bad thing, especially in config files pasting content in a different nesting level is usually an error.

- you get a bit of a dangling else problem because you don't have ? ?closing delimiters.

I solved that by using [section.subsection.subsubsection] syntax, with leading names optional, and replaced by previous values when omitted.

Alexander S. Klenin

Reply by email

Graeme Geldenhuys
to Marco van de Voort: I don't know why Lazarus does, but I can tell you why I changed from .ini to .xml…
Marco van de Voort wrote
The simple reason is that .ini is one level only, and XML has an infinite nesting depth.

Technically yes, but also no. For example. 'regedit' in Microsoft Windows can export the registry (a f***ken huge tree and garbled mess) to a .reg text files which is in fact a INI file. They use nesting as follows, which could very easy be added to TINIFile (and I'm actually thinking of doing this - see below).

--------------------------
[Level1]
Version=8

[Level1\Level2]
Company=Widgets Inc.

[Level1\Level2\Level3]
FullName=John Doe
Age=35
--------------------------

The TINIFile's Section support could be extended to use '\' which means no real change needed, or implement a dot notation. eg: A nested section or value can be referenced as Level1.Version or Level1.Level2.Level3.FullName

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to Marco van de Voort: I don't know why Lazarus does, but I can tell you why I changed from .ini to .xml…
Marco van de Voort wrote
The simple reason is that .ini is one level only, and XML has an infinite nesting depth.

Could you give a small code example of how you read/write values in a nested hierarchy, or do you use some custom written component (something like TRegFile, TINIFile)?

I personally don't like referencing a value via something like...

GetXMLNode('\CompilerOptions\SomeTab\SomeValue').Text

If so, INI files could be used in exactly the same way (as my previous post about Windows regedit showed).

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Mattias Gaertner
to Graeme Geldenhuys: I thought I would pose this question in a new thread seeing that the other thread got…
Show quoted text 11 lines
Hi, I thought I would pose this question in a new thread seeing that the other thread got totally high-jacked (and not by me for a change). :) I'm curious to know what was the reason behind the decision to use XML for storing simple Lazarus settings, instead of the much simpler INI format? This is a legit question and I'm very curious as to the answer. Please note, this is not a feature request or me telling the Lazarus devs to change yet another thing in Lazarus. This is simply me asking a question I don't have an answer too.

xml is only the backend.
No IDE config reads/writes xml directly, but uses components like TXMLConfig or TConfigStorage to read/write Path/Value pairs. For me it is important that the configs are independent of the backend and could be changed for example to ini or a registry. I think the hierarchical structure of the xml is more future proof than ini (when more categories are added to a config).

Here are some points that were raised before: * FCL, LCL and Lazarus IDE have XML read/write code. They don't all work the same, and I doubt they all have the same functionality.

FCL and LCL have the same XML write/read code.
There is a UTF8 optimized version in the codetools directory, which is also used by the IDE. Most configs can be read by both.

* Not all code in Lazarus IDE uses the same XML read/write code

What do you mean?

* Most XML examples in my ~/.lazarus/ directory would be much simpler presented if they where INI files.

True.
But they only need to be simple enough. So far no one had problems reading the xml syntax.

* FPC and Delphi has brilliant INI file support, and it's dead easy to use.

Same for xmlconfig.

* What is the actual advantage of XML in this case or was it chosen simply because XML was the flavour of the month at time of implementation. Yes, at one point everything had to be XML or it just wasn't cool. :-)

No, then we would have accessed the DOM nodes directly.

* Reading INI fast is FAST.

The ini file unit is much faster now than ten years ago. Same for the xmlconfig. Reading the png of the splashscreen takes more time than reading all IDE xml files, even if they contain thousands of units and include files like mine.

Show quoted text 28 lines
To make others understand my confusion regarding the XML choice, here is an example, using the compileroptions.xml file located in my ~/.lazarus/ directory. -------------------[ compileroptions.xml ]------------------------------------- <?xml version="1.0"?> <CONFIG> <CompilerOptionsVersion Value="8"/> <CompilerOptionsSearchPaths> <IncludeFiles Value="$(ProjOutDir)/"/> <UnitOutputDirectory Value="units/$(TargetCPU)-$(TargetOS)/"/> </CompilerOptionsSearchPaths> <CompilerOptionsParsing> <SyntaxOptions> <UseAnsiStrings Value="True"/> </SyntaxOptions> </CompilerOptionsParsing> <CompilerOptionsOther> <CompilerMessages> <UseMsgFile Value="True"/> </CompilerMessages> <CompilerPath Value="$(CompPath)"/> </CompilerOptionsOther> </CONFIG> ----------------------------------------------------------------------------------------- This is a relatively small example, but still highlights my point.

The clever thing about the xmlconfig is that it only write changes and auto deletes empty nodes. That's why you see such a flat xml file.

Just looking at it gives me a headache. ;-) Now lets convert that to a INI styled file. BTW: Does anybody know what INI actually stands for? Initialization maybe?

I guess yes.

Show quoted text 16 lines
-------------------[ compileroptions.ini ]------------------------------------- [SearchPaths] IncludeFiles=$(ProjOutDir)/ UnitOutputDirectory=units/$(TargetCPU)-$(TargetOS)/ [Parsing] UseAnsiStrings=1 [Other] UseMsgFile=1 CompilerPath=$(CompPath) --------------------------------------------- Now both examples contain the same information, but lets be honest..

.. that's not equivalent. You have combined sections and risks name clashes.

Which one is easier to read (via human or program), manually tweak if needed via human in IDE screws up, takes up less disk space.

Of course you can hand craft nice ini sections if you know the full set of options. But what if you don't know how a config will grow in ten years?

I fully understand that XML has it's place in data transport and helps describe complex data. But using XML for something as simple as storing a few application settings. It just seems very inappropriate in this case, and a classic example of over-engineering.

The xml backend of the IDE is only one place - the TXMLConfig. Change that and the IDE would write ini files.

Mattias

Reply by email

Graeme Geldenhuys
to Mattias Gaertner
Mattias Gaertner wrote
> * Not all code in Lazarus IDE uses the same XML read/write code What do you mean?

See the examples of reading/writing to XML (all actual code from the IDE) posted earlier. Two very different methods are being used. I vaguely remember seeing a 3rd method as well somewhere.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Mattias Gaertner
to Graeme Geldenhuys: See the examples of reading/writing to XML (all actual code from the IDE) posted earlier.…
Show quoted text 9 lines
On 18/06/2010, Mattias Gaertner wrote: > >> * Not all code in Lazarus IDE uses the same XML read/write code > > What do you mean? See the examples of reading/writing to XML (all actual code from the IDE) posted earlier. Two very different methods are being used. I vaguely remember seeing a 3rd method as well somewhere.

There are two ways: the backend independent TConfigStorage, which by default uses TXMLConfig and using TXMLConfig directly. The IDEIntf only provides the TConfigStorage.
For the code there is no difference except that there are some more utility functions for writing lists and trees to xmlconfig.

Mattias

Reply by email

Marco van de Voort
to Graeme Geldenhuys: Technically yes, but also no. For example. 'regedit' in Microsoft Windows can export the…
Graeme Geldenhuys wrote 21 lines
> > The simple reason is that .ini is one level only, and XML has an infinite > nesting depth. Technically yes, but also no. For example. 'regedit' in Microsoft Windows can export the registry (a f***ken huge tree and garbled mess) to a .reg text files which is in fact a INI file. They use nesting as follows, which could very easy be added to TINIFile (and I'm actually thinking of doing this - see below). -------------------------- [Level1] Version=8 [Level1\Level2] Company=Widgets Inc. [Level1\Level2\Level3] FullName=John Doe Age=35 --------------------------

Yes. You can always try to map something multilevel on what it is not. But that is not the point.

The TINIFile's Section support could be extended to use '\' which means no real change needed, or implement a dot notation. eg: A nested section or value can be referenced as Level1.Version or Level1.Level2.Level3.FullName

It would be a freak format. Better use something standarized.

I think that is a high price for notepad editability.

If user editability matters so much to you, make a simple treeview based editor.

Reply by email

Alexander Klenin
to Martin: There is code that read XML via RTTI directly to the object.
Martin wrote 9 lines
On 18/06/2010 12:21, Alexander Klenin wrote: >> >> Benefits of LFM vs. XML: >> 3) can be read/written directly to the object via RTTI, thus >> drastically simplifying read/write code >> (I estimate a few thousands lines of code might be eliminated from >> Lazarus). There is code that read XML via RTTI directly to the object.

By "there is" do you mean "in the universe" or "in Lazarus sources"? In the first case -- of course, I know that, I have written and used such code myself.
In the second -- why it is not used then?

Alexander S. Klenin

Reply by email

Marco van de Voort
to Graeme Geldenhuys: Could you give a small code example of how you read/write values in a nested hierarchy,…
Graeme Geldenhuys wrote 8 lines
On 18/06/2010, Marco van de Voort wrote: > > The simple reason is that .ini is one level only, and XML has an infinite > nesting depth. Could you give a small code example of how you read/write values in a nested hierarchy, or do you use some custom written component (something like TRegFile, TINIFile)?

I use laz_xml, an own modified version.

The main reason for the modification has nothing to do with the config use. (but with the ability to read malformed XMLs of a certain vendor, no not Microsoft)

My own program has a modular shaped as a tree. It can stream its state to a file.

I personally don't like referencing a value via something like... GetXMLNode('\CompilerOptions\SomeTab\SomeValue').Text

It depends on the purpose. In my case this would be

procedure tsometab.loadfromxml(xml:TXMLConfig;key:string);
begin
 somevalue:=xmlgetvalue(key+'/SomeValue','SomevalueDefault');
end;

with sometab being loaded from the compileroptions module, which is in turn called by Main.

If so, INI files could be used in exactly the same way (as my previous post about Windows regedit showed).

I see no point in inventing own formats for something as benign as this.

Hierarchical structures are always harder to edit with a linear editor like a texteditor. If it bothers you, make a general hierarchical editor based on a treeview. (and probably there are already many)

Reply by email

Martin
to Alexander Klenin: By "there is" do you mean "in the universe" or "in Lazarus sources"? In the first case --…
Alexander Klenin wrote 15 lines
>>> Benefits of LFM vs. XML: >>> 3) can be read/written directly to the object via RTTI, thus >>> drastically simplifying read/write code >>> (I estimate a few thousands lines of code might be eliminated from >>> Lazarus). >>> > There is code that read XML via RTTI directly to the object. > By "there is" do you mean "in the universe" or "in Lazarus sources"? In the first case -- of course, I know that, I have written and used such code myself. In the second -- why it is not used then?

Both, since the Lazarus sources are included in the universe.

EditorOptions.pp => and it is used there.

It is hard to use it for older settings, since often the name of the values are not the rtti names needed. It is used for some of the newer setting (e.g. colors)

Also the old code works => so why change it, just for the off-chance to introduce bugs?

Martin

Reply by email

Alexander Klenin
to Martin
Martin wrote 8 lines
>> There is code that read XML via RTTI directly to the object. > > By "there is" do you mean "in the universe" or "in Lazarus sources"? > In the first case -- of course, I know that, I have written and used > such code myself. > In the second -- why it is not used then? Both, since the Lazarus sources are included in the universe.

:-)

EditorOptions.pp => and it is used there.

Yes, I have taken a look.

It is hard to use it for older settings, since often the name of the values are not the rtti names needed. It is used for some of the newer setting (e.g. colors)

Config backwards-compatibility is a hard problem, but it is essentially the same as the problem of LFM backwards-compatibility, which is an argument in favor of using the same approach, if not the same code. (I.e. I suggest something like
aXMLConfig.RegisterAlias('OldPath\OldOption', 'NewPath\NewOption'))

Also the old code works => so why change it, just for the off-chance to introduce bugs?

There are many reasons for refactoring, I think you know them well enough. To put it bluntly, adding a new Lazarus option it is now rather frustrating experience.
Primary culprit is the fact that there are many places to modify scattered around the code.
Consistently implementing RTTI-based save/loading will eliminate two such places,
which would be a big step forward.

Alexander S. Klenin

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: Thanks for your reply. For that argument to be more credible, and for XML to be a more…
Show quoted text 8 lines
> few configuration settings. This would mean that the XML format is paving > the way for future development(s) that an ini may not support. Thanks for your reply. For that argument to be more credible, and for XML to be a more appropriate format, then Lazarus IDE should have used a single .xml file for all settings.

Please note the complex hierarchy that already exists. Multiple configuration directories, configs stored in common directories or together with a project, etc. The docking IDE will add further config data, to be discussed where and how.

All that may deserve some brush-up, once the use of multiple IDE instances and multiple layouts has settled down a bit more.

DoDi

Reply by email

waldo kitty
to Henry Vermaak: One file would make sense, I agree. Sure it's _possible_ to implement all of this in ini…

On 6/18/2010 06:27, Henry Vermaak wrote to Graeme Geldenhuys :

Sure it is harder to read, but luckily you won't have to read it often. Why are you even complaining about this? Another storm in a teacup?

why is it that folk think that someone is complaining about stuff when they ask a simple question? heck, even my writings have been misread for some reason that i've not found or understood :(

Reply by email

waldo kitty
to Alexander Klenin: On Fri, Jun 18, 2010 at 20:15, Graeme Geldenhuys Irrespective to the topic of this…
Alexander Klenin wrote 8 lines
On Fri, Jun 18, 2010 at 20:15, Graeme Geldenhuys wrote: > * FCL, LCL and Lazarus IDE have XML read/write code. They don't all > work the same, and I doubt they all have the same functionality. > * Not all code in Lazarus IDE uses the same XML read/write code Irrespective to the topic of this thread, IMSHO these should be treated as bugs and be fixed.

+1

all the XML handling code should be the same (it isn't a single unit??) and used in the same manner throughout...

Reply by email

Hans-Peter Diettrich
to Alexander Klenin: [skip] To illustrate, here is a snipped of Lazarus code reading the compiler options: {…
XMLConfigFile.SetDeleteValue(p+'Debugging/StripSymbols/Value', StripSymbols,false); Clearly, those are not not the best examples of applying DRY principle ;-)

ACK. Hard coded pathes break any accepted design rules :-(

Actually I'm struggling with Mattias, about the many (obsolete) classes and methods in the Lazarus IDE. IMO the IDE would profit from a general refactoring, but who would do that, and who would make the result only work again? Not to mention the many changes that are on the road with the new (dockable) layout management.

So we must be happy that Mattias does the work right now, and we must accept the way how he makes things work. I've stopped working on an alternative IDE model, because right now I see no chance that it ever would be merged with the ongoing work in the trunk version.

DoDi

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: Could you give a small code example of how you read/write values in a nested hierarchy,…
I personally don't like referencing a value via something like... GetXMLNode('\CompilerOptions\SomeTab\SomeValue').Text

IMO the ...CompilerOptions should be represented by an XML node, that is handed to the reader and writer methods. The dedicated methods add their structure to that node, ignoring where exactly that node sits in the overall document tree.

DoDi

Reply by email

Santiago A.
to Marco van de Voort: I actually tried to implement this once by using [[[section]]] and [[[subsubsection]].…

El 18/06/2010 13:51, Marco van de Voort escribi?:

Show quoted text 5 lines
I actually tried to implement this once by using [[[section]]] and [[[subsubsection]].

Once I saw a program using this kind of inifiles.

[section A]
k1=v1
k2=v2
[section A/ subsection]
k1=v1
k2=v2
[section B]
k1=v1
k2=v2
[section B/ subsection]
k1=v1
k2=v2

As far as I know, it is a standard inifile. Perhaps it could be improved in the output sorting the subsections after the section and indenting.

Santiago A.

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: IMO the ...CompilerOptions should be represented by an XML node, that is handed to the…
Hans-Peter Diettrich wrote 10 lines
Graeme Geldenhuys schrieb: > I personally don't like referencing a value via something like... > > ?GetXMLNode('\CompilerOptions\SomeTab\SomeValue').Text IMO the ...CompilerOptions should be represented by an XML node, that is handed to the reader and writer methods. The dedicated methods add their structure to that node, ignoring where exactly that node sits in the overall document tree.

That is better, but a single aXMLConfig.ReadObject(aCompilerOptions) call is better still --
look at examples in editoroptions.pp

Alexander S. Klenin

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: ACK. Hard coded pathes break any accepted design rules :-( Actually I'm struggling with…
Hans-Peter Diettrich wrote 6 lines
Alexander Klenin schrieb: Actually I'm struggling with Mattias, about the many (obsolete) classes and methods in the Lazarus IDE. IMO the IDE would profit from a general refactoring, but who would do that, and who would make the result only work again? Not to mention the many changes that are on the road with the new (dockable) layout management.

This is a serious problem for Lazarus development, but the need for stability and backwards compatibility should not be underestimated either. I can make a few suggestions:
1) Take a small steps, one a a time. Really. First eliminate obvious duplicates and other most trivial design problems. Then *get those changes accepted*, after that, move to more serious refactorings.
2) Ask for forgiveness, not permission.
My attempts to start a meaningful refactoring of some core IDE code were halted by core developers due to fear of potential backwards compatibility problems. Meanwhile, I quietly rewrote almost 100% of TAChart code, introducing some (hopefully minor) incompatibilities, and AFAIR got a single complaint on forum,
which was promptly resolved, and not even by me.

To access the magnitude of change, compare this:
http://github.com/graemeg/lazarus/blob/4a181e6bda93a20797630f16a5103fff85ad46da/components/tachart/taseries.pas#L594 with that:
http://github.com/graemeg/lazarus/blob/upstream/components/tachart/taseries.pas#L360

I have a nagging suspicion that if I'd just committed my attempted core refactoring,
nobody would ever notice ;-)

Alexander S. Klenin

Reply by email

David W Noon
to Hans-Peter Diettrich

On Fri, 18 Jun 2010 23:44:01 +0200, Hans-Peter Diettrich wrote about Re: [Lazarus] Why was XML format chosen for storing settings in Lazarus IDE?:

Show quoted text 7 lines
Alexander Klenin schrieb: > This is a serious problem for Lazarus development, but the need for > stability and backwards compatibility should not be underestimated > either. How must the IDE be backwards compatible?

That's easy: if I start the IDE and it refuses to open any of my existing projects, I am seriously pissed off!

Regards, Dave [RLU #314465] ======================================================================= (David W Noon) =======================================================================

Reply by email