inweb-bootstrap/docs/foundation-module/7-vn.html
2020-05-09 13:05:00 +01:00

385 lines
77 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Version Numbers</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Octagram.png" width=72 height=72">
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul><h2>Example Webs</h2><ul>
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
<li><a href="../eastertide/index.html">eastertide</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Version Numbers' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#7">Chapter 7: Semantic Versioning</a></li><li><b>Version Numbers</b></li></ul></div>
<p class="purpose">Semantic version numbers such as 3.7.1.</p>
<ul class="toc"><li><a href="7-vn.html#SP1">&#167;1. Standard adoption</a></li><li><a href="7-vn.html#SP5">&#167;5. Printing and parsing</a></li><li><a href="7-vn.html#SP8">&#167;8. Precendence</a></li><li><a href="7-vn.html#SP11">&#167;11. Trichotomy</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Standard adoption. </b>The Semantic Version Number standard, semver 2.0.0, provides a strict set
of rules for the format and meaning of version numbers: see <span class="extract"><span class="extract-syntax">https://semver.org</span></span>.
</p>
<p class="commentary">Prior to the standard most version numbers in computing usage looked like
dot-divided runs of non-negative integers: for example, 4, 7.1, and 0.2.3.
The standard now requires exactly three: major, minor and patch. It's
therefore formally incorrect to have a version 2, or a version 2.3. We will
not be so strict on the textual form, which we will allow to be abbreviated.
Thus:
</p>
<ul class="items"><li>(a) The text <span class="extract"><span class="extract-syntax">6.4.7</span></span> is understood to mean 6.4.7 and printed back as <span class="extract"><span class="extract-syntax">6.4.7</span></span>
</li><li>(b) The text <span class="extract"><span class="extract-syntax">6</span></span> is understood to mean 6.0.0 and printed back as <span class="extract"><span class="extract-syntax">6</span></span>
</li><li>(c) The text <span class="extract"><span class="extract-syntax">6.1</span></span> is understood to mean 6.1.0 and printed back as <span class="extract"><span class="extract-syntax">6.1</span></span>
</li><li>(d) The text <span class="extract"><span class="extract-syntax">6.1.0</span></span> is understood to mean 6.1.0 and printed back as <span class="extract"><span class="extract-syntax">6.1.0</span></span>
</li></ul>
<p class="commentary">Similarly, the absence of a version number (called "null" below) will be
understood to mean 0.0.0, but will be distinguished from the explicit choice
to number something as 0.0.0.
</p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>A complication is that Inform 7 extensions have for many years allowed two
forms of version number: either just <span class="extract"><span class="extract-syntax">N</span></span>, which fits the scheme above, or
<span class="extract"><span class="extract-syntax">N/DDDDDD</span></span>, which does not. This is a format which was chosen for sentimental
reasons: IF enthusiasts know it well from the banner text of the Infocom
titles of the 1980s. This story file, for instance, was compiled at the
time of the Reykjavik summit between Presidents Gorbachev and Reagan:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> Moonmist</span>
<span class="plain-syntax"> Infocom interactive fiction - a mystery story</span>
<span class="plain-syntax"> Copyright (c) 1986 by Infocom, Inc. All rights reserved.</span>
<span class="plain-syntax"> Moonmist is a trademark of Infocom, Inc.</span>
<span class="plain-syntax"> Release number 9 / Serial number 861022</span>
</pre>
<p class="commentary">Story file collectors customarily abbreviate this in catalogues to <span class="extract"><span class="extract-syntax">9/861022</span></span>.
</p>
<p class="commentary">We will therefore allow this notation, and convert it silently each way.
<span class="extract"><span class="extract-syntax">N/DDDDDD</span></span> is equivalent to <span class="extract"><span class="extract-syntax">N.DDDDDD</span></span>. Thus, <span class="extract"><span class="extract-syntax">9/861022</span></span> means 9.861022.0 in
semver precedence order.
</p>
<p class="commentary">In all non-textual respects, and in particular on precedence rules, we follow
the standard exactly. The only reason we allow these abbreviations is because
we don't want to force Inform extension writers to type "Version 3.4.1 of
Such-and-Such by Me begins here", and so on: it would break all existing
extensions, for one thing, and it looks unfriendly.
</p>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>In the array below, unspecified numbers are stored as <span class="extract"><span class="extract-syntax">-1</span></span>. The three
components are otherwise required to be non-negative integers.
</p>
<p class="commentary">Semver allows for more elaborate forms: for example <span class="extract"><span class="extract-syntax">3.1.41-alpha.72.zeta+6Q45</span></span>
would mean 3.1.41 but with prerelease versioning <span class="extract"><span class="extract-syntax">alpha.72.zeta</span></span> and build
metadata <span class="extract"><span class="extract-syntax">6Q45</span></span>. The <span class="extract"><span class="extract-syntax">prerelease_segments</span></span> list for this would be a list of
three texts: <span class="extract"><span class="extract-syntax">alpha</span></span>, <span class="extract"><span class="extract-syntax">72</span></span>, <span class="extract"><span class="extract-syntax">zeta</span></span>.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> major, minor, patch</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prerelease_segments</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">text_stream</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">build_metadata</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number_holder</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">version</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">semantic_version_number_holder</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure semantic_version_number is accessed in 7/vnr and here.</li><li>The structure semantic_version_number_holder is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>All invalid strings of numbers &mdash; i.e., breaking the above rules &mdash; are
called "null" versions, and can never be valid as the version of anything.
Instead they are used to represent the absence of a version number.
(In particular, a string of <span class="extract"><span class="extract-syntax">-1</span></span>s is null.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::null</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::null</span></span>:<br/><a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Version Number Ranges - <a href="7-vnr.html#SP3">&#167;3</a>, <a href="7-vnr.html#SP4">&#167;4</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">push</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">ignored</span><span class="plain-syntax"> </span><span class="string-syntax">"-Wconditional-uninitialized"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">build_metadata</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">pop</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::is_null</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::is_null</span></span>:<br/><a href="7-vn.html#SP5">&#167;5</a><br/>Version Number Ranges - <a href="7-vnr.html#SP4">&#167;4</a>, <a href="7-vnr.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">allow</span><span class="plain-syntax">=</span><span class="constant-syntax">TRUE</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &lt; -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> should never happen</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == -1) </span><span class="identifier-syntax">allow</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">allow</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> should never happen</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="identifier-syntax">version_numbers</span><span class="plain-syntax">[0] &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. Printing and parsing. </b>Printing is simple enough:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::to_text</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::to_text</span></span>:<br/><a href="7-vn.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::is_null</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"null"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="identifier-syntax">prerelease_segments</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"-"</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="identifier-syntax">build_metadata</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"+%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">build_metadata</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>And this provides for the <span class="extract"><span class="extract-syntax">%v</span></span> escape, though we must be careful when
using this to pass a pointer to the version, not the version itself;
variadic macros are not carefully enough type-checked by <span class="extract"><span class="extract-syntax">clang</span></span> or <span class="extract"><span class="extract-syntax">gcc</span></span>
to catch this sort of slip.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::writer</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::writer</span></span>:<br/>Foundation Module - <a href="1-fm.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="7-vn.html#SP5" class="function-link"><span class="function-syntax">VersionNumbers::to_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, *</span><span class="identifier-syntax">V</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>Parsing is much more of a slog. The following returns a null version if
the text <span class="extract"><span class="extract-syntax">T</span></span> is in any respect malformed, i.e., if it deviates from the
above specification in even the most trivial way. We parse the three parts
of a semver version in order: e.g. <span class="extract"><span class="extract-syntax">3.1.41-alpha.72.zeta+6Q45</span></span> the first
part is up to the hyphen, the second part between the hyphen and the plus
sign, and the third part runs to the end. The second and third parts are
optional, but if both are given, they must be in that order.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">MMP_SEMVERPART</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PRE_SEMVERPART</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">BM_SEMVERPART</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::from_text</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::from_text</span></span>:<br/>Build Files - <a href="8-bf.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">component</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">dots_used</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">slashes_used</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">part</span><span class="plain-syntax"> = </span><span class="constant-syntax">MMP_SEMVERPART</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">part</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MMP_SEMVERPART:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="identifier-syntax">dots_used</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) </span><span class="identifier-syntax">slashes_used</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'+'</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">val</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">component</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">component</span><span class="plain-syntax">] = </span><span class="identifier-syntax">val</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">component</span><span class="plain-syntax">++; </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) </span><span class="identifier-syntax">part</span><span class="plain-syntax"> = </span><span class="constant-syntax">PRE_SEMVERPART</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'+'</span><span class="plain-syntax">) </span><span class="identifier-syntax">part</span><span class="plain-syntax"> = </span><span class="constant-syntax">BM_SEMVERPART</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP1" class="function-link"><span class="function-syntax">Characters::isdigit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">c</span><span class="plain-syntax"> - </span><span class="character-syntax">'0'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">val</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">slashes_used</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">val</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">digit</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">*</span><span class="identifier-syntax">val</span><span class="plain-syntax"> + </span><span class="identifier-syntax">digit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PRE_SEMVERPART:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-vn.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Add prerelease content</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'+'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-vn.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Add prerelease content</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">; </span><span class="identifier-syntax">part</span><span class="plain-syntax"> = </span><span class="constant-syntax">BM_SEMVERPART</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BM_SEMVERPART:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">build_metadata</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">build_metadata</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">build_metadata</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">part</span><span class="plain-syntax"> == </span><span class="constant-syntax">PRE_SEMVERPART</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="7-vn.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Add prerelease content</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dots_used</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">slashes_used</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">slashes_used</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">component</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</span><span class="plain-syntax"> != </span><span class="constant-syntax">6</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">part</span><span class="plain-syntax"> == </span><span class="constant-syntax">MMP_SEMVERPART</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">val</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">component</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="identifier-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">component</span><span class="plain-syntax">] = </span><span class="identifier-syntax">val</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_1"></a><b>&#167;7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add prerelease content</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP4" class="function-link"><span class="function-syntax">VersionNumbers::null</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="identifier-syntax">prerelease_segments</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">), </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prerelease</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-vn.html#SP7">&#167;7</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. Precendence. </b>The most important part of the semver standard is the rule on which versions
take precedence over which others, and we follow it exactly. The following
criteria are used in turn: major version; minor version; patch version;
any prerelease elements, which must be compared numerically if consisting
of digits only, and alphabetically otherwise; and finally the number of
prerelease elements. Build metadata is disregarded entirely.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::le</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::le</span></span>:<br/><a href="7-vn.html#SP11">&#167;11</a><br/>Version Number Ranges - <a href="7-vnr.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">SEMVER_NUMBER_DEPTH</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N1</span><span class="plain-syntax"> = </span><a href="7-vn.html#SP9" class="function-link"><span class="function-syntax">VersionNumbers::floor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N2</span><span class="plain-syntax"> = </span><a href="7-vn.html#SP9" class="function-link"><span class="function-syntax">VersionNumbers::floor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V2</span><span class="plain-syntax">.</span><span class="element-syntax">version_numbers</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N1</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">N2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N1</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">N2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I1</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">V1</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">)?(</span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::first</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">)):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I2</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">V2</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">)?(</span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::first</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V2</span><span class="plain-syntax">.</span><span class="element-syntax">prerelease_segments</span><span class="plain-syntax">)):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">I1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">I2</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T1</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *) </span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::content</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T2</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *) </span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::content</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N1</span><span class="plain-syntax"> = </span><a href="7-vn.html#SP10" class="function-link"><span class="function-syntax">VersionNumbers::strict_atoi</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N2</span><span class="plain-syntax"> = </span><a href="7-vn.html#SP10" class="function-link"><span class="function-syntax">VersionNumbers::strict_atoi</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">N1</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">N2</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N1</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">N2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N1</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">N2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::ne</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">T2</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">Str::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">T2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I1</span><span class="plain-syntax"> = </span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I2</span><span class="plain-syntax"> = </span><a href="2-llas.html#SP6" class="function-link"><span class="function-syntax">LinkedLists::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">I1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">I2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">I1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">I2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>The effect of this is to read unspecified versions of major, minor or patch
as if they were 0:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::floor</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::floor</span></span>:<br/><a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>This returns a non-negative integer if <span class="extract"><span class="extract-syntax">T</span></span> contains only digits, and <span class="extract"><span class="extract-syntax">-1</span></span>
otherwise. If the value has more than about 10 digits, then the result will
not be meaningful, which I think is a technical violation of the standard.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::strict_atoi</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::strict_atoi</span></span>:<br/><a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP1" class="function-link"><span class="function-syntax">Characters::isdigit</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">)) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_first_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'0'</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP7" class="function-link"><span class="function-syntax">Str::atoi</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. Trichotomy. </b>We now use the above function to construct ordering relations on semvers.
These are trichotomous, that is, for each pair <span class="extract"><span class="extract-syntax">V1, V2</span></span>, exactly one of the
<span class="extract"><span class="extract-syntax">VersionNumbers::eq(V1, V2)</span></span>, <span class="extract"><span class="extract-syntax">VersionNumbers::gt(V1, V2)</span></span>, <span class="extract"><span class="extract-syntax">VersionNumbers::lt(V1, V2)</span></span>
is true.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::eq</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::eq</span></span>:<br/><a href="7-vn.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="7-vn.html#SP8" class="function-link"><span class="function-syntax">VersionNumbers::le</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="7-vn.html#SP8" class="function-link"><span class="function-syntax">VersionNumbers::le</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V2</span><span class="plain-syntax">, </span><span class="identifier-syntax">V1</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::ne</span><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP11" class="function-link"><span class="function-syntax">VersionNumbers::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">))?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::gt</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::gt</span></span>:<br/><a href="7-vn.html#SP12">&#167;12</a><br/>Version Number Ranges - <a href="7-vnr.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP8" class="function-link"><span class="function-syntax">VersionNumbers::le</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">))?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::ge</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::ge</span></span>:<br/>Version Number Ranges - <a href="7-vnr.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-vn.html#SP8" class="function-link"><span class="function-syntax">VersionNumbers::le</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V2</span><span class="plain-syntax">, </span><span class="identifier-syntax">V1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::lt</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::lt</span></span>:<br/>Version Number Ranges - <a href="7-vnr.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP11" class="function-link"><span class="function-syntax">VersionNumbers::ge</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">))?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>And the following can be used for sorting, following the <span class="extract"><span class="extract-syntax">strcmp</span></span> convention.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">VersionNumbers::cmp</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">VersionNumbers::cmp</span></span>:<br/>Version Number Ranges - <a href="7-vnr.html#SP8">&#167;8</a>, <a href="7-vnr.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="reserved-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP11" class="function-link"><span class="function-syntax">VersionNumbers::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-vn.html#SP11" class="function-link"><span class="function-syntax">VersionNumbers::gt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V1</span><span class="plain-syntax">, </span><span class="identifier-syntax">V2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-sd.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresscurrentchapter">7</li><li class="progresscurrent">vn</li><li class="progresssection"><a href="7-vnr.html">vnr</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="7-vnr.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>