(root)/
bison-3.8.2/
src/
strversion.c
       1  /* Convert version string to int.
       2  
       3     Copyright (C) 2020-2021 Free Software Foundation, Inc.
       4  
       5     This file is part of Bison, the GNU Compiler Compiler.
       6  
       7     This program is free software: you can redistribute it and/or modify
       8     it under the terms of the GNU General Public License as published by
       9     the Free Software Foundation, either version 3 of the License, or
      10     (at your option) any later version.
      11  
      12     This program is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15     GNU General Public License for more details.
      16  
      17     You should have received a copy of the GNU General Public License
      18     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      19  
      20  #include <config.h>
      21  #include "system.h"
      22  
      23  #include "strversion.h"
      24  
      25  #include <errno.h>
      26  #include <intprops.h>
      27  
      28  int
      29  strversion_to_int (char const *version)
      30  {
      31    IGNORE_TYPE_LIMITS_BEGIN
      32    int res = 0;
      33    errno = 0;
      34    char *cp = NULL;
      35  
      36    {
      37      long major = strtol (version, &cp, 10);
      38      if (errno || cp == version || *cp != '.' || major < 0
      39          || INT_MULTIPLY_WRAPV (major, 10000, &res))
      40        return -1;
      41    }
      42  
      43    {
      44      ++cp;
      45      char *prev = cp;
      46      long minor = strtol (cp, &cp, 10);
      47      if (errno || cp == prev || (*cp != '\0' && *cp != '.')
      48          || ! (0 <= minor && minor < 100)
      49          || INT_MULTIPLY_WRAPV (minor, 100, &minor)
      50          || INT_ADD_WRAPV (minor, res, &res))
      51        return -1;
      52    }
      53  
      54    if (*cp == '.')
      55      {
      56        ++cp;
      57        char *prev = cp;
      58        long micro = strtol (cp, &cp, 10);
      59        if (errno || cp == prev || (*cp != '\0' && *cp != '.')
      60            || ! (0 <= micro && micro < 100)
      61            || INT_ADD_WRAPV (micro, res, &res))
      62          return -1;
      63      }
      64  
      65    IGNORE_TYPE_LIMITS_END
      66    return res;
      67  }