Quantcast
Channel: Rainmeter Forums
Viewing all articles
Browse latest Browse all 1056

Bugs & Feature Suggestions • Re: [BUG] @Include recursion tree is flawed

$
0
0
There does seem to be a flaw someplace, as the meters do get ordered incorrectly per the docs.

That said, your interpretation of how Rainmeter files get parsed is completely wrong. Understanding how they do get parsed won't resolve the issue, but the vision of some magical Rainmeter recursive super-file-parser needs a little reality check.

Rainmeter uses "standard" Windows .INI format files (.INI type files existed before Windows, but they only follow a general agreed-upon convention, not some RFC/ISO standard). These files are read using ancient been-around-since-1.0 Windows APIs, GetPrivateProfileSectionNames, GetPrivateProfileSection, GetPrivateProfileString, etc.

The key thing to note here is that the "@include" syntax is purely a Rainmeter invention. The Win32 API does not have any mechanism to read nested .INI files. None. Zilch. Nada.

So, what really happens when Rainmeter reads your .INI files?

First, Rainmeter will pass the name of the top level skin .INI to GetPrivateProfileSectionNames. This eats the entire file in one bite. No magical line-at-a-time parsing or recursion. The return of this function is simple list of all the section names in the file. So, in your example, this is simply a one-element list containing "Rainmeter". if you had a more typical file, you'd get a longer list of all the "[...]" section names in the file.

Next, Rainmeter will loop through each item in the section name list and call GetPrivateProfileSection to read the contents of the section. Again, this eats the entire section in one bite. What you get back from this is an array of all the lines in the section (the "key=value" lines).

You'll notice we have not read any other files yet. This where the Rainmeter magic happens. As the code chews through each section in the list of section names, it checks each line in the section looking for "@key=value" entries. If it finds one in a particular section, it will recursively call the "INI reading routine" and start again with the new .INI (which in your example, is "A.inc". The entire A.inc file is read and the list of A's sections is obtained. It is keeping track of where it is in the list of sections, so it able to insert the A.inc section name list into the "MainSkin.ini" section list, after the [Rainmeter] section. The code then reads the each of the A sections, encounters the "@include=C.ini", and the loop repeats again.

After C.inc is read and the sections inserted into section list, and the remainder of the A.inc sections processed and found to have no more includes, then we bubble back up to the top. This is where the second include file in the top level skin is encountered, B.ini. Again we read the whole file, read each section looking for includes, and finally insert all the "B" sections into the section list.

This is where I think there could be a minor error in the insertion code, where it is off by one and inserting the sections 1-element too high in the section list. Possibly it has gotten slightly lost due to multiple includes in a single section, with some of those includes having more includes.

In fact, if you nest a D.inc into the C.ini file, the B.inc sections will be inserted even further off up the list. So yeah, there is a glitch someplace.

This isn't a solution, but as a work-around you can force the correct order by moving the line @IncludeB=B.inc into its own section, thus allowing the code to be able to clearly identify the proper insertion point.
P.S.: There also seems to be a glitch if the last section of an included file contains an @include line. In this case the insertion point gets wildly thrown off (like inserts the file's sections at the beginning of the main section list).

Statistics: Posted by SilverAzide — Today, 1:10 am



Viewing all articles
Browse latest Browse all 1056

Trending Articles