<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://nsis.sourceforge.io/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Get_Text_From_KeyValues_%28VDF%29_Files</id>
	<title>Get Text From KeyValues (VDF) Files - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://nsis.sourceforge.io/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Get_Text_From_KeyValues_%28VDF%29_Files"/>
	<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;action=history"/>
	<updated>2026-08-12T23:46:22Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25593&amp;oldid=prev</id>
		<title>Soupcan: /* Drawbacks */ Add note about not supporting conditionals</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25593&amp;oldid=prev"/>
		<updated>2020-11-12T15:30:47Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Drawbacks: &lt;/span&gt; Add note about not supporting conditionals&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:30, 12 November 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l16&quot;&gt;Line 16:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 16:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It only gets the &amp;#039;&amp;#039;string value(s)&amp;#039;&amp;#039; of the &amp;#039;&amp;#039;child key(s)&amp;#039;&amp;#039; specified. (You can&amp;#039;t query a parent key to get a list of its children, for example).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It only gets the &amp;#039;&amp;#039;string value(s)&amp;#039;&amp;#039; of the &amp;#039;&amp;#039;child key(s)&amp;#039;&amp;#039; specified. (You can&amp;#039;t query a parent key to get a list of its children, for example).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Key names cannot include the &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; character, due to it being used as a delimiter (values can still contain any character, of course).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Key names cannot include the &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; character, due to it being used as a delimiter (values can still contain any character, of course).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Conditionals, e.g. [$WIN32], are not supported&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Usage ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Usage ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25592:rev-25593 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25592&amp;oldid=prev</id>
		<title>Soupcan: Add note about the use of &gt; in key names</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25592&amp;oldid=prev"/>
		<updated>2020-10-25T18:54:01Z</updated>

		<summary type="html">&lt;p&gt;Add note about the use of &amp;gt; in key names&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:54, 25 October 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l11&quot;&gt;Line 11:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 11:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Drawbacks ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Drawbacks ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;There are a &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;couple &lt;/del&gt;minor drawbacks to this parser:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;There are a &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;few &lt;/ins&gt;minor drawbacks to this parser:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It does not support the KeyValues commands &amp;lt;code&amp;gt;#include&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;#base&amp;lt;/code&amp;gt; (these are rarely used).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It does not support the KeyValues commands &amp;lt;code&amp;gt;#include&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;#base&amp;lt;/code&amp;gt; (these are rarely used).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It only gets the &amp;#039;&amp;#039;string value(s)&amp;#039;&amp;#039; of the &amp;#039;&amp;#039;child key(s)&amp;#039;&amp;#039; specified. (You can&amp;#039;t query a parent key to get a list of its children, for example).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* It only gets the &amp;#039;&amp;#039;string value(s)&amp;#039;&amp;#039; of the &amp;#039;&amp;#039;child key(s)&amp;#039;&amp;#039; specified. (You can&amp;#039;t query a parent key to get a list of its children, for example).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Key names cannot include the &amp;lt;code&gt;&gt;&amp;lt;/code&gt; character, due to it being used as a delimiter (values can still contain any character, of course).&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Usage ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Usage ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25591:rev-25592 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25591&amp;oldid=prev</id>
		<title>Soupcan: add missing colon in example title</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25591&amp;oldid=prev"/>
		<updated>2020-10-23T03:27:55Z</updated>

		<summary type="html">&lt;p&gt;add missing colon in example title&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 03:27, 23 October 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l55&quot;&gt;Line 55:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Read Multiple Keyvalues&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Read Multiple Keyvalues&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:&lt;/ins&gt;&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In this example, we will check for all music files listed in a music script:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In this example, we will check for all music files listed in a music script:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25590:rev-25591 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25590&amp;oldid=prev</id>
		<title>Soupcan: Add missing StrCpy command to example</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25590&amp;oldid=prev"/>
		<updated>2020-10-21T16:13:44Z</updated>

		<summary type="html">&lt;p&gt;Add missing StrCpy command to example&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:13, 21 October 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l69&quot;&gt;Line 69:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 69:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;StrCpy $1 0&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;DetailPrint &amp;quot;The level music for Frigate is:&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;DetailPrint &amp;quot;The level music for Frigate is:&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25589:rev-25590 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25589&amp;oldid=prev</id>
		<title>Soupcan: Remove commented out code</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25589&amp;oldid=prev"/>
		<updated>2020-10-21T16:10:50Z</updated>

		<summary type="html">&lt;p&gt;Remove commented out code&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:10, 21 October 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l262&quot;&gt;Line 262:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 262:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		FileRead $vdfFileHandle $vdfCurrentChar 1&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		FileRead $vdfFileHandle $vdfCurrentChar 1&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		IfErrors ReachedEOF&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		IfErrors ReachedEOF&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;		;DetailPrint $vdfCurrentChar&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		; If we are in an open quote, don&amp;#039;t check for comments&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		; If we are in an open quote, don&amp;#039;t check for comments&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25588:rev-25589 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25588&amp;oldid=prev</id>
		<title>Soupcan: Add to category &quot;Text Files Manipulation Functions&quot;</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25588&amp;oldid=prev"/>
		<updated>2020-10-20T20:49:05Z</updated>

		<summary type="html">&lt;p&gt;Add to category &amp;quot;Text Files Manipulation Functions&amp;quot;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;â† Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 20:49, 20 October 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l564&quot;&gt;Line 564:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 564:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;FunctionEnd&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;FunctionEnd&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/highlight-nsis&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:Text Files Manipulation Functions]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key n22049_wiki-wiki_:diff::1.12:old-25587:rev-25588 --&gt;
&lt;/table&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25587&amp;oldid=prev</id>
		<title>Soupcan: Created</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=Get_Text_From_KeyValues_(VDF)_Files&amp;diff=25587&amp;oldid=prev"/>
		<updated>2020-10-20T20:43:02Z</updated>

		<summary type="html">&lt;p&gt;Created&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{PageAuthor|Soupcan}}&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This is a header for reading [https://developer.valvesoftware.com/wiki/KeyValues KeyValues] (also known as Valve Data File [VDF]) files.&lt;br /&gt;
&lt;br /&gt;
It can read the value of a specified key name using &amp;lt;code&amp;gt;${ReadVDFStr}&amp;lt;/code&amp;gt;, or it can read multiple values (if the same key name is present multiple times in the file) using &amp;lt;code&amp;gt;${ReadVDFStrMultiple}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It supports the key features of VDF files, including comments, escape sequences, etc.&lt;br /&gt;
&lt;br /&gt;
== Drawbacks ==&lt;br /&gt;
&lt;br /&gt;
There are a couple minor drawbacks to this parser:&lt;br /&gt;
&lt;br /&gt;
* It does not support the KeyValues commands &amp;lt;code&amp;gt;#include&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;#base&amp;lt;/code&amp;gt; (these are rarely used).&lt;br /&gt;
* It only gets the &amp;#039;&amp;#039;string value(s)&amp;#039;&amp;#039; of the &amp;#039;&amp;#039;child key(s)&amp;#039;&amp;#039; specified. (You can&amp;#039;t query a parent key to get a list of its children, for example).&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
This header provides an easy syntax for reading VDF files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;${ReadVDFStr} $outvar vdf_filename key_name&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
Or...&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;${ReadVDFStrMultiple} $outvar vdf_filename key_name index&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$outvar&amp;lt;/code&amp;gt;: The output will be returned to this var.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vdf_filename&amp;lt;/code&amp;gt; is the path to the VDF file to be read.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;key_name&amp;lt;/code&amp;gt; is the full &amp;quot;path&amp;quot; to the key which you want to read. It can contain multiple keys and subkeys, delimited by &amp;#039;&amp;gt;&amp;#039;.&lt;br /&gt;
Note: You can only query keys that do not have any children.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt;: If using &amp;lt;code&amp;gt;${ReadVDFStrMultiple}&amp;lt;/code&amp;gt;, it will read the Nth matching key, unlike ${ReadVDFStr} which will return the 1st. This is useful for reading multiple values with the same key name.&lt;br /&gt;
&lt;br /&gt;
To use &amp;lt;code&amp;gt;${ReadVDFStrMultiple}&amp;lt;/code&amp;gt;, you can keep querying it with an incrementing index, until the errors flag is set, indicating that no more matching keys could be found.&lt;br /&gt;
&lt;br /&gt;
If there is an error, the errors flag will be set and the error message will be copied to &amp;lt;code&amp;gt;$vdfError&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Read a Single Keyvalue:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
In this example, we will use the following file as our input:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;parent key&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;key&amp;quot;  &amp;quot;value&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
NSIS code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;&lt;br /&gt;
${ReadVDFStr} $0 &amp;#039;test.txt&amp;#039; &amp;#039;parent key&amp;gt;key&amp;#039;&lt;br /&gt;
; $0 = value&lt;br /&gt;
&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Read Multiple Keyvalues&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
In this example, we will check for all music files listed in a music script:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;music&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;file&amp;quot;  &amp;quot;music/frigate.mp3&amp;quot;&lt;br /&gt;
     &amp;quot;file&amp;quot;  &amp;quot;music/frigate2.mp3&amp;quot;&lt;br /&gt;
     &amp;quot;file&amp;quot;  &amp;quot;music/train.mp3&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
NSIS code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;&lt;br /&gt;
DetailPrint &amp;quot;The level music for Frigate is:&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Loop:&lt;br /&gt;
    ${ReadVDFStrMultiple} $0 &amp;quot;test.txt&amp;quot; &amp;quot;music&amp;gt;file&amp;quot; $1&lt;br /&gt;
    IfErrors Done&lt;br /&gt;
    DetailPrint &amp;quot;$1: $0&amp;quot;&lt;br /&gt;
    IntOp $1 $1 + 1&lt;br /&gt;
    Goto Loop&lt;br /&gt;
&lt;br /&gt;
Done:&lt;br /&gt;
&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In each iteration of the loop, $0 will be set to the value of the next &amp;lt;code&amp;gt;file&amp;lt;/code&amp;gt; key. In our example, the following text is output to the details view:&lt;br /&gt;
&lt;br /&gt;
 The level music for Frigate is:&lt;br /&gt;
 0: music/frigate.mp3&lt;br /&gt;
 1: music/frigate2.mp3&lt;br /&gt;
 2: music/train.mp3&lt;br /&gt;
&lt;br /&gt;
== The Code ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Parser for Valve Data Format, also known as the KeyValues&lt;br /&gt;
format: https://developer.valvesoftware.com/wiki/KeyValues&lt;br /&gt;
&lt;br /&gt;
Written by soupcan for GoldenEye: Source&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This header provides an easy syntax for reading VDF files.&lt;br /&gt;
Usage: ${ReadVDFStr} $outvar vdf_filename key_name&lt;br /&gt;
Or...: ${ReadVDFStrMultiple} $outvar vdf_filename key_name index&lt;br /&gt;
&lt;br /&gt;
$outvar: The output will be returned to this var.&lt;br /&gt;
&lt;br /&gt;
vdf_filename is the path to the VDF file to be read.&lt;br /&gt;
&lt;br /&gt;
key_name is the full &amp;quot;path&amp;quot; to the key which you want to read.&lt;br /&gt;
It can contain multiple keys and subkeys, delimited by &amp;#039;&amp;gt;&amp;#039;&lt;br /&gt;
Note: You can only query keys that do not have any children.&lt;br /&gt;
&lt;br /&gt;
Index: If using ${ReadVDFStrMultiple}, it will read the Nth&lt;br /&gt;
matching key, unlike ${ReadVDFStr} which will return the 1st.&lt;br /&gt;
This is useful for reading multiple values with the same key&lt;br /&gt;
name.&lt;br /&gt;
&lt;br /&gt;
To use ${ReadVDFStrMultiple}, you can keep querying it with an&lt;br /&gt;
incrementing index, until the errors flag is set, indicating&lt;br /&gt;
that no more matching keys could be found.&lt;br /&gt;
&lt;br /&gt;
If there is an error, the errors flag will be set and the error&lt;br /&gt;
message will be copied to $vdfError&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
Var vdfOut ; $outvar&lt;br /&gt;
Var vdfError&lt;br /&gt;
Var vdfFile ; File name&lt;br /&gt;
Var vdfFileHandle ; File handle&lt;br /&gt;
Var vdfIndex ; If parsing multiple keys, which index are we looking for?&lt;br /&gt;
             ; This is simply the number of matching keys we&amp;#039;ve hit so far.&lt;br /&gt;
Var vdfCurIndex ; Which index are we currently on?&lt;br /&gt;
Var vdfKey ; Full &amp;quot;path&amp;quot; to the key/subkey of the VDF&lt;br /&gt;
Var vdfCurrentKey ; Current VDF key being processed&lt;br /&gt;
Var vdfLevel ; Current &amp;quot;level&amp;quot; (how many curley brackets deep)&lt;br /&gt;
Var vdfDepth ; Depth/level of the target key&lt;br /&gt;
Var vdfToken ; The current token returned by the vdfGetNextToken function.&lt;br /&gt;
Var vdfBracket ; Used by vdfGetNextToken to signal to vdfMain when an opening or&lt;br /&gt;
               ; closing bracket is found. We do it this way instead of using&lt;br /&gt;
               ; vdfToken, because a quoted curley bracket could otherwise fool&lt;br /&gt;
               ; our parser.&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
!define ReadVDFStr &amp;quot;!insertmacro ReadVDFStr&amp;quot;&lt;br /&gt;
!define ReadVDFStrMultiple &amp;quot;!insertmacro ReadVDFStrMultiple&amp;quot;&lt;br /&gt;
&lt;br /&gt;
!macro ReadVDFStr outvar filename key&lt;br /&gt;
	StrCpy $vdfFile &amp;quot;${filename}&amp;quot;&lt;br /&gt;
	StrCpy $vdfKey &amp;quot;${key}&amp;quot;&lt;br /&gt;
	StrCpy $vdfIndex &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	Call vdfMain&lt;br /&gt;
	StrCpy &amp;quot;${outvar}&amp;quot; $vdfOut&lt;br /&gt;
!macroend&lt;br /&gt;
&lt;br /&gt;
!macro ReadVDFStrMultiple outvar filename key index&lt;br /&gt;
	StrCpy $vdfFile &amp;quot;${filename}&amp;quot;&lt;br /&gt;
	StrCpy $vdfKey &amp;quot;${key}&amp;quot;&lt;br /&gt;
	StrCpy $vdfIndex &amp;quot;${index}&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	Call vdfMain&lt;br /&gt;
	StrCpy &amp;quot;${outvar}&amp;quot; $vdfOut&lt;br /&gt;
!macroend&lt;br /&gt;
&lt;br /&gt;
; Get depth of the provided $vdfKey and stores it in $vdfDepth&lt;br /&gt;
; Depth starts at 0, e.g. &amp;quot;ges_version&amp;quot; is 0 while &amp;quot;ges_version&amp;gt;text&amp;quot; is 1&lt;br /&gt;
Function vdfGetKeyDepth&lt;br /&gt;
	Push $0 ; $0 = length of string&lt;br /&gt;
	Push $1 ; $1 = numeric index of char in string&lt;br /&gt;
	Push $2 ; $2 = current char&lt;br /&gt;
&lt;br /&gt;
	StrLen $0 $vdfKey&lt;br /&gt;
	StrCpy $vdfDepth 0&lt;br /&gt;
	StrCpy $1 1&lt;br /&gt;
&lt;br /&gt;
	ReadNextChar:&lt;br /&gt;
		; Read char at index ($1) of $vdfKey and store it in $2&lt;br /&gt;
		StrCpy $2 $vdfKey 1 $1&lt;br /&gt;
&lt;br /&gt;
		; If current char $2 == &amp;#039;&amp;gt;&amp;#039;, increment $vdfDepth&lt;br /&gt;
		StrCmp $2 &amp;quot;&amp;gt;&amp;quot; +1 NoMatch&lt;br /&gt;
			IntOp $vdfDepth $vdfDepth + 1&lt;br /&gt;
		NoMatch:&lt;br /&gt;
		; Increment index&lt;br /&gt;
		IntOp $1 $1 + 1&lt;br /&gt;
&lt;br /&gt;
		; If index &amp;gt;= StrLen, return&lt;br /&gt;
		; Otherwise, restart loop&lt;br /&gt;
		IntCmp $0 $1 +1 +1 ReadNextChar&lt;br /&gt;
&lt;br /&gt;
		Pop $2&lt;br /&gt;
		Pop $1&lt;br /&gt;
		Pop $0&lt;br /&gt;
&lt;br /&gt;
FunctionEnd&lt;br /&gt;
&lt;br /&gt;
; This function gets the VDF key at $vdfLevel&lt;br /&gt;
; and stores it in $vdfCurrentKey&lt;br /&gt;
Function vdfGetCurrentKey&lt;br /&gt;
	Push $0 ; $0 = length of string&lt;br /&gt;
	Push $1 ; $1 = numeric index of char in string&lt;br /&gt;
	Push $2 ; $2 = current char&lt;br /&gt;
	Push $3 ; $3 = current level being processed&lt;br /&gt;
&lt;br /&gt;
	StrLen $0 $vdfKey&lt;br /&gt;
	StrCpy $vdfCurrentKey &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $1 0&lt;br /&gt;
	StrCpy $3 0&lt;br /&gt;
&lt;br /&gt;
	ReadNextChar:&lt;br /&gt;
		; Read char at index ($1) of $vdfKey and store it in $2&lt;br /&gt;
		StrCpy $2 $vdfKey 1 $1&lt;br /&gt;
&lt;br /&gt;
		; If we&amp;#039;re at our target level...&lt;br /&gt;
		StrCmp $3 $vdfLevel +1 NotEqual&lt;br /&gt;
			; Return immediately if current char is &amp;gt;&lt;br /&gt;
			StrCmp $2 &amp;quot;&amp;gt;&amp;quot; RReturn +1&lt;br /&gt;
			; Otherwise, copy current char $2 to $vdfCurrentKey&lt;br /&gt;
			StrCpy $vdfCurrentKey &amp;quot;$vdfCurrentKey$2&amp;quot;&lt;br /&gt;
		NotEqual:&lt;br /&gt;
&lt;br /&gt;
		; If current char $2 == &amp;#039;&amp;gt;&amp;#039;, increment level&lt;br /&gt;
		StrCmp $2 &amp;quot;&amp;gt;&amp;quot; +1 NoMatch&lt;br /&gt;
			IntOp $3 $3 + 1&lt;br /&gt;
		NoMatch:&lt;br /&gt;
		; Increment index&lt;br /&gt;
		IntOp $1 $1 + 1&lt;br /&gt;
&lt;br /&gt;
		; If index &amp;gt;= StrLen, return&lt;br /&gt;
		; Otherwise, restart loop&lt;br /&gt;
		IntCmp $0 $1 +1 +1 ReadNextChar&lt;br /&gt;
&lt;br /&gt;
		RReturn:&lt;br /&gt;
&lt;br /&gt;
		Pop $3&lt;br /&gt;
		Pop $2&lt;br /&gt;
		Pop $1&lt;br /&gt;
		Pop $0&lt;br /&gt;
FunctionEnd&lt;br /&gt;
&lt;br /&gt;
; This function gets the next token. A token is any text in the file,&lt;br /&gt;
; including key names, values and brackets. Comments are skipped.&lt;br /&gt;
;&lt;br /&gt;
; This function handles double-quotes for keys/values with spaces in&lt;br /&gt;
; them. It also handles the escape sequences \n, \t, \\, and \&amp;quot;.&lt;br /&gt;
Function vdfGetNextToken&lt;br /&gt;
	Var /GLOBAL vdfJunk ; /dev/null&lt;br /&gt;
	Var /GLOBAL vdfCurrentChar ; current char in file&lt;br /&gt;
	Var /GLOBAL vdfIsQuoted ; Are we currently in an open double quote?&lt;br /&gt;
	Var /GLOBAL vdfIsEscaped ; Was the previous character the escape character &amp;#039;\&amp;#039;?&lt;br /&gt;
	Var /GLOBAL vdfIsLastCharFwdSlash ; Is the previous char an (unquoted) forward slash? Two of these in a row is a comment.&lt;br /&gt;
&lt;br /&gt;
	StrCpy $vdfToken &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfBracket &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfCurrentChar &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfIsQuoted &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfIsEscaped &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfIsLastCharFwdSlash &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	ReadNextChar:&lt;br /&gt;
		; Read the char into $vdfCurrentChar and advance offset by 1&lt;br /&gt;
		FileRead $vdfFileHandle $vdfCurrentChar 1&lt;br /&gt;
		IfErrors ReachedEOF&lt;br /&gt;
&lt;br /&gt;
		;DetailPrint $vdfCurrentChar&lt;br /&gt;
&lt;br /&gt;
		; If we are in an open quote, don&amp;#039;t check for comments&lt;br /&gt;
		StrCmp $vdfIsQuoted &amp;#039;&amp;#039; +1 CommentEnd&lt;br /&gt;
&lt;br /&gt;
			; If this char, and previous char, were forward slashes&lt;br /&gt;
			; skip to next line as this is a comment&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;#039;/&amp;#039; +1 NotFSlash&lt;br /&gt;
				; If the last char was also a forward slash, skip to next line&lt;br /&gt;
				; Also unset the var since we will want a fresh start for the next line.&lt;br /&gt;
				StrCmp $vdfIsLastCharFwdSlash &amp;#039;1&amp;#039; +1 NotFSlash&lt;br /&gt;
					; Calling FileRead without a maxlen will take us to the next line.&lt;br /&gt;
					; We don&amp;#039;t care about the output so we just write to our junk var&lt;br /&gt;
					FileRead $vdfFileHandle $vdfJunk&lt;br /&gt;
					StrCpy $vdfIsLastCharFwdSlash &amp;#039;&amp;#039;&lt;br /&gt;
					; Subtract last char (fwd slash) from vdfToken&lt;br /&gt;
					StrCpy $vdfToken $vdfToken -1&lt;br /&gt;
					Goto ReadNextChar&lt;br /&gt;
&lt;br /&gt;
			NotFSlash:&lt;br /&gt;
&lt;br /&gt;
			; Set the vdfIsLastCharFwdSlash variable&lt;br /&gt;
			StrCpy $vdfIsLastCharFwdSlash &amp;#039;&amp;#039;&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;#039;/&amp;#039; +1 StillNotAFSlash&lt;br /&gt;
				StrCpy $vdfIsLastCharFwdSlash 1&lt;br /&gt;
			StillNotAFSlash:&lt;br /&gt;
&lt;br /&gt;
		CommentEnd:&lt;br /&gt;
&lt;br /&gt;
		; Opening/closing brackets --&lt;br /&gt;
		; These are not supposed to be at the beginning or end of another token&lt;br /&gt;
		; unless it&amp;#039;s quoted. So, if we find one while unquoted, we return its&lt;br /&gt;
		; result immediately.&lt;br /&gt;
		StrCmp $vdfIsQuoted &amp;#039;&amp;#039; +1 SkipBracket&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;#039;{&amp;#039; +1 NotOpeningBracket&lt;br /&gt;
				StrCmp $vdfToken &amp;#039;&amp;#039; +1 ReturnCurrentToken&lt;br /&gt;
					StrCpy $vdfBracket &amp;#039;{&amp;#039;&lt;br /&gt;
					Return&lt;br /&gt;
&lt;br /&gt;
			NotOpeningBracket:&lt;br /&gt;
				; Processing for closing bracket&lt;br /&gt;
				StrCmp $vdfCurrentChar &amp;#039;}&amp;#039; +1 SkipBracket&lt;br /&gt;
					StrCmp $vdfToken &amp;#039;&amp;#039; +1 ReturnCurrentToken&lt;br /&gt;
						StrCpy $vdfBracket &amp;#039;}&amp;#039;&lt;br /&gt;
						Return&lt;br /&gt;
&lt;br /&gt;
			ReturnCurrentToken:&lt;br /&gt;
				; Rewind back 1 char, to make sure we don&amp;#039;t&lt;br /&gt;
				; skip the bracket next time&lt;br /&gt;
				FileSeek $vdfFileHandle -1 CUR&lt;br /&gt;
				Return&lt;br /&gt;
&lt;br /&gt;
		SkipBracket:&lt;br /&gt;
&lt;br /&gt;
		; Skip all quote parsing if we&amp;#039;re escaped&lt;br /&gt;
		StrCmp $vdfIsEscaped &amp;#039;&amp;#039; +1 SkipAllQuoteParsing&lt;br /&gt;
&lt;br /&gt;
		; If current char is a quote, toggle the $vdfIsQuoted flag &lt;br /&gt;
		StrCmp $vdfCurrentChar &amp;#039;&amp;quot;&amp;#039; +1 NotQuote&lt;br /&gt;
			StrCmp $vdfIsQuoted &amp;#039;&amp;#039; +1 IsCurrentlyQuoted&lt;br /&gt;
				StrCpy $vdfIsQuoted 1&lt;br /&gt;
				Goto QuoteFlagEnd&lt;br /&gt;
			IsCurrentlyQuoted:&lt;br /&gt;
				StrCpy $vdfIsQuoted &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
		QuoteFlagEnd:&lt;br /&gt;
&lt;br /&gt;
		; If current char is a quote, and the $vdfIsQuoted flag is&lt;br /&gt;
		; unset (meaning we&amp;#039;re ending a quote), return&lt;br /&gt;
		; &lt;br /&gt;
		; If current char is a quote, and the $vdfIsQuoted flag is&lt;br /&gt;
		; set (meaning we&amp;#039;re beginning a quote), goto ReadNextChar&lt;br /&gt;
		; if we haven&amp;#039;t read a token yet. If we have, return.&lt;br /&gt;
&lt;br /&gt;
		StrCmp $vdfCurrentChar &amp;#039;&amp;quot;&amp;#039; +1 NotQuote&lt;br /&gt;
			StrCmp $vdfIsQuoted &amp;#039;&amp;#039; +1 IsOpeningQuote&lt;br /&gt;
				Return&lt;br /&gt;
			IsOpeningQuote:&lt;br /&gt;
				StrCmp $vdfToken &amp;#039;&amp;#039; ReadNextChar&lt;br /&gt;
				Return&lt;br /&gt;
&lt;br /&gt;
		NotQuote:&lt;br /&gt;
&lt;br /&gt;
		; If current char is a whitespace, and we are NOT in an open&lt;br /&gt;
		; quote block, read next char UNLESS we already wrote something&lt;br /&gt;
		; into $vdfToken&lt;br /&gt;
&lt;br /&gt;
		; Skip if quoted.&lt;br /&gt;
		StrCmp $vdfIsQuoted &amp;#039;&amp;#039; +1 SkipWhitespace&lt;br /&gt;
&lt;br /&gt;
			; Space&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot; &amp;quot; CharIsWhitespace +1&lt;br /&gt;
			; Carriage return&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;$\r&amp;quot; CharIsWhitespace +1&lt;br /&gt;
			; Newline&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;$\n&amp;quot; CharIsWhitespace +1&lt;br /&gt;
			; Tab&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;$\t&amp;quot; CharIsWhitespace +1&lt;br /&gt;
&lt;br /&gt;
			Goto SkipWhitespace&lt;br /&gt;
&lt;br /&gt;
			CharIsWhitespace:&lt;br /&gt;
				StrCmp $vdfToken &amp;#039;&amp;#039; ReadNextChar +1&lt;br /&gt;
					Return&lt;br /&gt;
&lt;br /&gt;
		SkipWhitespace:&lt;br /&gt;
&lt;br /&gt;
		SkipAllQuoteParsing:&lt;br /&gt;
&lt;br /&gt;
		; Handle escape sequences if vdfIsEscaped is set&lt;br /&gt;
		StrCmp $vdfIsEscaped &amp;#039;&amp;#039; ParseEscapeEnd&lt;br /&gt;
			; Newline&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;n&amp;quot; +1 Tab&lt;br /&gt;
				StrCpy $vdfCurrentChar &amp;quot;$\n&amp;quot;&lt;br /&gt;
				Goto RemoveLastChar&lt;br /&gt;
&lt;br /&gt;
			Tab:&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;t&amp;quot; +1 Backslash&lt;br /&gt;
				StrCpy $vdfCurrentChar &amp;quot;$\t&amp;quot;&lt;br /&gt;
				Goto RemoveLastChar&lt;br /&gt;
&lt;br /&gt;
			Backslash:&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;quot;\&amp;quot; +1 Quote&lt;br /&gt;
				StrCpy $vdfCurrentChar &amp;#039;\&amp;#039;&lt;br /&gt;
				Goto RemoveLastChar&lt;br /&gt;
&lt;br /&gt;
			Quote:&lt;br /&gt;
			StrCmp $vdfCurrentChar &amp;#039;&amp;quot;&amp;#039; +1&lt;br /&gt;
				StrCpy $vdfCurrentChar &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
				Goto RemoveLastChar&lt;br /&gt;
&lt;br /&gt;
			; If the char isn&amp;#039;t a recognized escape sequence, finish&lt;br /&gt;
			Goto ParseEscapeEnd&lt;br /&gt;
&lt;br /&gt;
		RemoveLastChar:&lt;br /&gt;
			; Remove backslash&lt;br /&gt;
			StrCpy $vdfToken $vdfToken -1&lt;br /&gt;
&lt;br /&gt;
		ParseEscapeEnd:&lt;br /&gt;
&lt;br /&gt;
		; Is this char a back slash?&lt;br /&gt;
		StrCmp $vdfCurrentChar &amp;#039;\&amp;#039; +1 Unescape&lt;br /&gt;
			; Set vdfIsEscaped, but only if isEscaped isn&amp;#039;t already set&lt;br /&gt;
			; if it is, unset it&lt;br /&gt;
			StrCmp $vdfIsEscaped &amp;quot;&amp;quot; +1 Unescape&lt;br /&gt;
				StrCpy $vdfIsEscaped &amp;#039;1&amp;#039;&lt;br /&gt;
				Goto SetEscapedEnd&lt;br /&gt;
		Unescape:&lt;br /&gt;
			StrCpy $vdfIsEscaped &amp;#039;&amp;#039;&lt;br /&gt;
		SetEscapedEnd:&lt;br /&gt;
&lt;br /&gt;
		StrCpy $vdfToken &amp;quot;$vdfToken$vdfCurrentChar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		Goto ReadNextChar&lt;br /&gt;
&lt;br /&gt;
	ReachedEOF:&lt;br /&gt;
		SetErrors&lt;br /&gt;
		Return&lt;br /&gt;
&lt;br /&gt;
FunctionEnd&lt;br /&gt;
&lt;br /&gt;
!macro vdfError text&lt;br /&gt;
	StrCpy $vdfOut &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfError &amp;quot;${text}&amp;quot;&lt;br /&gt;
	StrCpy $vdfErrorState 1&lt;br /&gt;
	Goto RReturn&lt;br /&gt;
!macroend&lt;br /&gt;
&lt;br /&gt;
Function vdfMain&lt;br /&gt;
	Var /GLOBAL vdfFileSize ; file size of input file&lt;br /&gt;
	Var /GLOBAL vdfPreExistingErrorState ; error state when function was called&lt;br /&gt;
	Var /GLOBAL vdfErrorState ; whether to SetErrors at the end of the function, regardless of pre-existing error state&lt;br /&gt;
	Var /GLOBAL vdfIsValue ; set if processing a value. this is so we know if we&amp;#039;re processing a value, or some other token type.&lt;br /&gt;
	Var /GLOBAL vdfCurLevel ; current level of the token being processed&lt;br /&gt;
&lt;br /&gt;
	StrCpy $vdfPreExistingErrorState &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfErrorState &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfError &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfFileSize &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfLevel 0&lt;br /&gt;
	StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
	StrCpy $vdfCurLevel 0&lt;br /&gt;
	StrCpy $vdfCurIndex 0&lt;br /&gt;
&lt;br /&gt;
	; Get current error state, to restore it later.&lt;br /&gt;
	StrCpy $vdfPreExistingErrorState 0&lt;br /&gt;
	IfErrors +1 NoErrors &lt;br /&gt;
		StrCpy $vdfPreExistingErrorState 1&lt;br /&gt;
	NoErrors:&lt;br /&gt;
	ClearErrors&lt;br /&gt;
&lt;br /&gt;
	IfFileExists $vdfFile FileExists&lt;br /&gt;
		!insertmacro vdfError &amp;quot;File doesn&amp;#039;t exist.&amp;quot;&lt;br /&gt;
	FileExists:&lt;br /&gt;
&lt;br /&gt;
	FileOpen $vdfFileHandle $vdfFile r&lt;br /&gt;
	&lt;br /&gt;
	; Get file size&lt;br /&gt;
	FileSeek $vdfFileHandle 0 END $vdfFileSize&lt;br /&gt;
&lt;br /&gt;
	; Check that file isn&amp;#039;t more than 4MiB in length&lt;br /&gt;
	IntCmp $vdfFileSize 4194304 FileSizeOk FileSizeOk&lt;br /&gt;
		!insertmacro vdfError &amp;quot;File too large.&amp;quot;&lt;br /&gt;
	FileSizeOk:&lt;br /&gt;
&lt;br /&gt;
	; Rewind back to starting position&lt;br /&gt;
	FileSeek $vdfFileHandle 0&lt;br /&gt;
&lt;br /&gt;
	Call vdfGetKeyDepth ; Initializes $vdfDepth&lt;br /&gt;
	Call vdfGetCurrentKey ; Sets $vdfCurrentKey to its initial value&lt;br /&gt;
&lt;br /&gt;
	GetToken:&lt;br /&gt;
		ClearErrors&lt;br /&gt;
		Call vdfGetNextToken&lt;br /&gt;
		IfErrors +1 NoParserErrors&lt;br /&gt;
			!insertmacro vdfError &amp;quot;Reached EOF without finding key.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		NoParserErrors:&lt;br /&gt;
&lt;br /&gt;
		StrCmp $vdfBracket &amp;#039;{&amp;#039; +1 SkipLevelUp&lt;br /&gt;
			IntOp $vdfCurLevel $vdfCurLevel + 1&lt;br /&gt;
			StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
			Goto GetToken&lt;br /&gt;
&lt;br /&gt;
		SkipLevelUp:&lt;br /&gt;
&lt;br /&gt;
		StrCmp $vdfBracket &amp;#039;}&amp;#039; +1 SkipLevelDn&lt;br /&gt;
			IntOp $vdfCurLevel $vdfCurLevel - 1&lt;br /&gt;
			StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
			Goto GetToken&lt;br /&gt;
&lt;br /&gt;
		SkipLevelDn:&lt;br /&gt;
&lt;br /&gt;
		; If this is a value, rather than key, get next token&lt;br /&gt;
		StrCmp $vdfIsValue &amp;#039;&amp;#039; TokenIsKey&lt;br /&gt;
			StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
			Goto GetToken&lt;br /&gt;
&lt;br /&gt;
		TokenIsKey:&lt;br /&gt;
&lt;br /&gt;
		; Set isValue, so that next token isn&amp;#039;t treated like a key&lt;br /&gt;
		StrCpy $vdfIsValue 1&lt;br /&gt;
		&lt;br /&gt;
		; Get next token if we arent at our target depth for our next key&lt;br /&gt;
		StrCmp $vdfCurLevel $vdfLevel +1 GetToken&lt;br /&gt;
&lt;br /&gt;
		; If the token == our key name, get the next token (the value)&lt;br /&gt;
		StrCmp $vdfToken $vdfCurrentKey +1 GetToken&lt;br /&gt;
			Call vdfGetNextToken&lt;br /&gt;
			StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
			; If current level == key depth, treat next token like it&amp;#039;s the value we&amp;#039;re looking for&lt;br /&gt;
			StrCmp $vdfLevel $vdfDepth +1 ExpectingBracket&lt;br /&gt;
				; Check if we actually got a value, or a bracket&lt;br /&gt;
				StrCmp $vdfBracket &amp;#039;&amp;#039; GotValue&lt;br /&gt;
					!insertmacro vdfError &amp;quot;Got &amp;#039;$vdfBracket&amp;#039;, expecting value string&amp;quot;&lt;br /&gt;
				GotValue:&lt;br /&gt;
					; Check if we&amp;#039;re reading multiple keys, or just this one...&lt;br /&gt;
					StrCmp $vdfIndex &amp;#039;&amp;#039; ReturnToken&lt;br /&gt;
						; Check if we&amp;#039;re at our destination index&lt;br /&gt;
						StrCmp $vdfIndex $vdfCurIndex ReturnToken&lt;br /&gt;
							; And if we aren&amp;#039;t, increment our current index and try again&lt;br /&gt;
							IntOp $vdfCurIndex $vdfCurIndex + 1&lt;br /&gt;
							Goto GetToken&lt;br /&gt;
&lt;br /&gt;
					ReturnToken:&lt;br /&gt;
						StrCpy $vdfOut $vdfToken&lt;br /&gt;
						Goto RReturn&lt;br /&gt;
&lt;br /&gt;
			; Otherwise, we&amp;#039;re expecting an opening bracket...&lt;br /&gt;
			ExpectingBracket:&lt;br /&gt;
				; Increment levels and depth, get next key&lt;br /&gt;
				StrCmp $vdfBracket &amp;#039;{&amp;#039; +1 NoBracketMatch&lt;br /&gt;
					IntOp $vdfCurLevel $vdfCurLevel + 1&lt;br /&gt;
					IntOp $vdfLevel $vdfLevel + 1&lt;br /&gt;
					StrCpy $vdfIsValue &amp;#039;&amp;#039;&lt;br /&gt;
					Call vdfGetCurrentKey&lt;br /&gt;
					Goto GetToken&lt;br /&gt;
&lt;br /&gt;
				NoBracketMatch:&lt;br /&gt;
					!insertmacro vdfError &amp;quot;Got &amp;#039;$vdfBracket$vdfToken&amp;#039;, expecting &amp;#039;{&amp;#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	RReturn:&lt;br /&gt;
		FileClose $vdfFileHandle&lt;br /&gt;
&lt;br /&gt;
		; Restore prior error state&lt;br /&gt;
		ClearErrors&lt;br /&gt;
		StrCmp $vdfPreExistingErrorState 1 +1 DontSetErrors&lt;br /&gt;
			SetErrors&lt;br /&gt;
		DontSetErrors:&lt;br /&gt;
&lt;br /&gt;
		; If our internal error flag was set, then set errors&lt;br /&gt;
		; regardless of prior error state.&lt;br /&gt;
		StrCmp $vdfErrorState &amp;quot;&amp;quot; ReallyDontSetErrors&lt;br /&gt;
			SetErrors&lt;br /&gt;
		ReallyDontSetErrors:&lt;br /&gt;
&lt;br /&gt;
FunctionEnd&lt;br /&gt;
&amp;lt;/highlight-nsis&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soupcan</name></author>
	</entry>
</feed>