/*
 *  version.sli
 *
 *  This file is part of NEST.
 *
 *  Copyright (C) 2004 The NEST Initiative
 *
 *  NEST is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  NEST is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with NEST.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/* 
    SLI version number handling library

    Note: this file depends on misc_helpers.sli,
          because it uses "breakup", "reverse", and
          "SLIFunctionWrapper".
          Hence misc_helpers.sli must be loaded first
          in sli-init.sli.
*/


%% note: this library cannot use the provide/require mechanism, because this
%% would lead to infinite recuresion during initialization!


/version namespace

  %%%%%%  
  % pad version arrays with zeros to make them same length  
  %%%%%%  
  /:padversions[/arraytype /v1  /arraytype /v2]
  {
    v1 length v2 length max /m Set
    v1  m  v1 length  sub  array join  
    v2  m  v2 length  sub  array join
  } bind SLIFunctionWrapper


/* BeginDocumentation
Name: version::validate - Assure correct format of version number array.

Synopsis: [version] validate -> -

Description:
Assures that the passed array is composed of truly positive integers
only, and contains at least one element.

Parameters:
[version] - Version number array. See [1] for details.

Examples:
[1 23 5]  validate -> -
[]        validate -> (raises /SytaxError)
[1 -23 5] validate -> (raises /SytaxError)
[1 2.3 5] validate -> (raises /SytaxError)

Diagnostics:
If argument is no valid version number array, an error message is
issued and /SytaxError is raised.

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /validate[/arraytype /v]
  {
    v length 0 eq
    {
      M_ERROR funcname cvs (Version number array must contain at least one number.) message    
      funcname /SyntaxError raiseerror      
    } if
    v
    {
      dup
      type /integertype neq
      {
        pop        
        M_ERROR funcname cvs (Version number array must contain integers only.) message    
        funcname /SyntaxError raiseerror      
      } if
      0 lt
      {
        M_ERROR funcname cvs (Version number array must contain positive integers only.) message    
        funcname /SyntaxError raiseerror      
      } if
    } forall
  } bind SLIFunctionWrapper


/* BeginDocumentation
Name: version::vcmp - Compare two version number arrays.

Synopsis: [version1] [version2] vcmp -> -1 | 0 | +1

Description:
Compare two version number arrays. The result is
  0, if version1 equals version2
 -1, if version1 is smaller than version2
 +1, if version1 is greater than version2

The common semantics of version numbers is applied, e.g.:
  [1 5] = [1 5 0 0 0 0 0]
  [1 5] > [1 4]
  [1 5] > [1]
  [1 5] > [1 4 99 99 99]
  [1 5] < [2 0]
  [1 5] < [1 5 1]
  [1 1] < [1 10]
etc.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] vcmp ->  0
[1 5] [1 4]           vcmp ->  1
[1 5] [1 5 1]         vcmp -> -1

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /vcmp[/arraytype /v1  /arraytype /v2]
  {
    v1 validate  v2 validate
    v1 v2 :padversions /v2 Set /v1 Set
    /result 0 def
    0  1  v1 length 1 sub  {
      /i Set      
      v2 i get  /n2 Set
      v1 i get  /n1 Set
      n1 n2 lt {/result -1 def exit} if      
      n1 n2 gt {/result +1 def exit} if      
      % it's neither greater nor smaller, so contine.
    } for
    result
  } bind SLIFunctionWrapper


/* BeginDocumentation
Name: version::veq - Are two version number arrays equal?

Synopsis: [version1] [version2] veq -> true | false

Description:
Compare two version number arrays. The result is
 true,  if version1 equals version2
 false, otherwise

The common semantics of version numbers is applied, see version::vcmp.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] veq -> true
[1 5] [1 4]           veq -> false

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /veq[/arraytype /arraytype]
  {
    vcmp 0 eq
  } bind def


/* BeginDocumentation
Name: version::vlt - "Less than" for version number arrays.

Synopsis: [version1] [version2] vlt -> true | false

Description:
Compare two version number arrays. The result is
 true,  if version1 is less than version2
 false, otherwise

The common semantics of version numbers is applied, see version::vcmp.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] vlt -> false
[1 5] [1 4]           vlt -> false
[1 5] [1 5 1]         vlt -> true

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /vlt[/arraytype /arraytype]
  {
    vcmp -1 eq
  } bind def


/* BeginDocumentation
Name: version::vgt - "Greater than" for version number arrays.

Synopsis: [version1] [version2] vgt -> true | false

Description:
Compare two version number arrays. The result is
 true,  if version1 is greater than version2
 false, otherwise

The common semantics of version numbers is applied, see version::vcmp.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] vgt -> false
[1 5] [1 4]           vgt -> true
[1 5] [1 5 1]         vgt -> false

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /vgt[/arraytype /arraytype]
  {
    vcmp +1 eq
  } bind def


/* BeginDocumentation
Name: version::vleq - "Less or equal" for version number arrays.

Synopsis: [version1] [version2] vleq -> true | false

Description:
Compare two version number arrays. The result is
 true,  if version1 is less than or equal to version2
 false, otherwise

The common semantics of version numbers is applied, see version::vcmp.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] vleq -> true
[1 5] [1 4]           vleq -> false
[1 5] [1 5 1]         vleq -> true

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /vleq[/arraytype /arraytype]
  {
    vcmp +1 neq
  } bind def


/* BeginDocumentation
Name: version::vgeq - "Greater or equal" for version number arrays.

Synopsis: [version1] [version2] vgeq -> true | false

Description:
Compare two version number arrays. The result is
 true,  if version1 is greater than or equal to version2
 false, otherwise

The common semantics of version numbers is applied, see version::vcmp.

Parameters:
version{1|2} - Version number arrays (see version::validate and [1]).

Examples:
[1 5] [1 5 0 0 0 0 0] vgeq -> true
[1 5] [1 4]           vgeq -> true
[1 5] [1 5 1]         vgeq -> false

Diagnostics:
/SyntaxError is raised, if parameters are no valid version number
arrays (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /vgeq[/arraytype /arraytype]
  {
    vcmp -1 neq
  } bind def




/* BeginDocumentation
Name: version::s2v - Convert version number string to array.

Synopsis: (version) s2v -> [version]

Description:
Converts a version number contained in a string to a version number
array. The string is expected to contain a "usual" dot-separated version
number, e.g. (1.23.5) (no leading "V").
As one and only exception, the string may also contain a CVS revision
string, e.g. (<dollar>Revision: 0.8.15<dollar>). In all other cases, [0] is returned.
For CVS revision strings of not yet checked-in files, [0] is
returned, too.

Parameters:
(version) - Version number string. See description above.
[version] - Version number array (see version::validate and [1]).

Examples:
(1.23.5)                           s2v -> [1 23 5]
(<dollar>Revision: 9.9<dollar>) s2v -> [9 9]
(<dollar>Revision<dollar>)               s2v -> [0]
(v3.5)                            s2v -> [0]

Diagnostics:
/SyntaxError is raised, if result is no valid version number
array (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /s2v[/stringtype /s]
  {
    % first, handle possible CVS revision string. There are two possible versions:    

    % revision string that has a number:    
    s ($Revision: ) search
    {
      %stack: (number $) ($Revision: ) () 
      pop pop
      %stack:  (number $)
      reverse 0 2 erase reverse
      %stack:  (number)      
    } if

    % revision string that has not yet a number:    
    dup ($Revision) ($) join eq
    {
      pop      
      (9999999.9)
        M_DEBUG (library::s2v) (Found non-substituted $Revision) ($ string, returning a large number.) join message
        M_DEBUG (library::s2v) (Please check that keyword substitution is turned on for this file.) message
      %stack:  (number)      
    } if

    % at this point we assume that it's a normal version number.
    (.) breakup {cvi} Map  
    dup validate  
  } bind SLIFunctionWrapper


/* BeginDocumentation
Name: version::v2s - Convert version number array to string.

Synopsis: [version] s2v -> (version)

Description:
Converts a version number array to a version number string. The string
contains the "usual" dot-separated version number, e.g. (1.23.5) (no
leading "V").

Parameters:
(version) - Version number string. See description above.
[version] - Version number array (see version::validate and [1]).

Examples:
[1 23 5]  ->  (1.23.5)
[1 0 0 0] ->  (1.0.0.0)

Diagnostics:
/SyntaxError is raised, if result is no valid version number
array (see version::validate).

Author: Ruediger Kupper

FirstVersion: 29-jul-2003

Availability: SLI2.0, library: version

References:
[1] Ruediger Kupper, SLI library management,
    HRI-EU Report 06/05, Honda Research Institute Europe GmbH, 2006.

SeeAlso: version::validate, version::vcmp, version::veq, version::vlt, version::vgt, version::vleq, version::vgeq, version::s2v, version::v2s
*/
  /v2s[/arraytype /v]
  {
    v validate  
    v 0 get cvs % get first number
    v 0 1 erase % get all other numbers
    {cvs (.) exch join join} forall
  } bind SLIFunctionWrapper  

end % namespace