From 14c65a35f085acf2ae62bec29208f8de33aad66d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 10 Nov 2020 08:19:33 +0100 Subject: [PATCH] %require: accept version numbers with three parts ("3.7.4") * src/parse-gram.y (str_to_version): Support three parts. * data/skeletons/location.cc, data/skeletons/stack.hh: Adjust. --- data/skeletons/location.cc | 2 +- data/skeletons/stack.hh | 2 +- src/parse-gram.c | 47 +++++++++++++++++++++++++------------- src/parse-gram.y | 47 +++++++++++++++++++++++++------------- 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/data/skeletons/location.cc b/data/skeletons/location.cc index 33c9e50df..c96381e93 100644 --- a/data/skeletons/location.cc +++ b/data/skeletons/location.cc @@ -22,7 +22,7 @@ m4_pushdef([b4_copyright_years], # b4_position_file # ---------------- # Name of the file containing the position class, if we want this file. -b4_defines_if([b4_required_version_if([302], [], +b4_defines_if([b4_required_version_if([30200], [], [m4_define([b4_position_file], [position.hh])])])]) diff --git a/data/skeletons/stack.hh b/data/skeletons/stack.hh index 0fd362583..38bff8ba1 100644 --- a/data/skeletons/stack.hh +++ b/data/skeletons/stack.hh @@ -19,7 +19,7 @@ # b4_stack_file # ------------- # Name of the file containing the stack class, if we want this file. -b4_defines_if([b4_required_version_if([302], [], +b4_defines_if([b4_required_version_if([30200], [], [m4_define([b4_stack_file], [stack.hh])])]) diff --git a/src/parse-gram.c b/src/parse-gram.c index d8eb81cce..917fb35a1 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -3032,11 +3032,9 @@ handle_pure_parser (location const *loc, char const *directive) } -/* Convert VERSION into an int (MAJOR * 100 + MINOR). Return -1 on - errors. - - Changes of behavior are only on minor version changes, so "3.0.5" - is the same as "3.0": 300. */ +/* Convert VERSION into an int (MAJOR * 10000 + MINOR * 100 + MICRO). + E.g., "3.7.4" => 30704, "3.8" => 30800. + Return -1 on errors. */ static int str_to_version (char const *version) { @@ -3044,18 +3042,35 @@ str_to_version (char const *version) int res = 0; errno = 0; char *cp = NULL; - long major = strtol (version, &cp, 10); - if (errno || cp == version || *cp != '.' || major < 0 - || INT_MULTIPLY_WRAPV (major, 100, &res)) - return -1; - ++cp; - char *cp1 = NULL; - long minor = strtol (cp, &cp1, 10); - if (errno || cp1 == cp || (*cp1 != '\0' && *cp1 != '.') - || ! (0 <= minor && minor < 100) - || INT_ADD_WRAPV (minor, res, &res)) - return -1; + { + long major = strtol (version, &cp, 10); + if (errno || cp == version || *cp != '.' || major < 0 + || INT_MULTIPLY_WRAPV (major, 10000, &res)) + return -1; + } + + { + ++cp; + char *prev = cp; + long minor = strtol (cp, &cp, 10); + if (errno || cp == prev || (*cp != '\0' && *cp != '.') + || ! (0 <= minor && minor < 100) + || INT_MULTIPLY_WRAPV (minor, 100, &minor) + || INT_ADD_WRAPV (minor, res, &res)) + return -1; + } + + if (*cp == '.') + { + ++cp; + char *prev = cp; + long micro = strtol (cp, &cp, 10); + if (errno || cp == prev || (*cp != '\0' && *cp != '.') + || ! (0 <= micro && micro < 100) + || INT_ADD_WRAPV (micro, res, &res)) + return -1; + } IGNORE_TYPE_LIMITS_END return res; diff --git a/src/parse-gram.y b/src/parse-gram.y index 925e07731..dc7761307 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -1043,11 +1043,9 @@ handle_pure_parser (location const *loc, char const *directive) } -/* Convert VERSION into an int (MAJOR * 100 + MINOR). Return -1 on - errors. - - Changes of behavior are only on minor version changes, so "3.0.5" - is the same as "3.0": 300. */ +/* Convert VERSION into an int (MAJOR * 10000 + MINOR * 100 + MICRO). + E.g., "3.7.4" => 30704, "3.8" => 30800. + Return -1 on errors. */ static int str_to_version (char const *version) { @@ -1055,18 +1053,35 @@ str_to_version (char const *version) int res = 0; errno = 0; char *cp = NULL; - long major = strtol (version, &cp, 10); - if (errno || cp == version || *cp != '.' || major < 0 - || INT_MULTIPLY_WRAPV (major, 100, &res)) - return -1; - ++cp; - char *cp1 = NULL; - long minor = strtol (cp, &cp1, 10); - if (errno || cp1 == cp || (*cp1 != '\0' && *cp1 != '.') - || ! (0 <= minor && minor < 100) - || INT_ADD_WRAPV (minor, res, &res)) - return -1; + { + long major = strtol (version, &cp, 10); + if (errno || cp == version || *cp != '.' || major < 0 + || INT_MULTIPLY_WRAPV (major, 10000, &res)) + return -1; + } + + { + ++cp; + char *prev = cp; + long minor = strtol (cp, &cp, 10); + if (errno || cp == prev || (*cp != '\0' && *cp != '.') + || ! (0 <= minor && minor < 100) + || INT_MULTIPLY_WRAPV (minor, 100, &minor) + || INT_ADD_WRAPV (minor, res, &res)) + return -1; + } + + if (*cp == '.') + { + ++cp; + char *prev = cp; + long micro = strtol (cp, &cp, 10); + if (errno || cp == prev || (*cp != '\0' && *cp != '.') + || ! (0 <= micro && micro < 100) + || INT_ADD_WRAPV (micro, res, &res)) + return -1; + } IGNORE_TYPE_LIMITS_END return res;