From 97d6da0c5b45c481699a3c688fcc5e73375f612f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 20 Oct 2019 14:39:17 +0200 Subject: [PATCH] parser: clarify version checking * src/parse-gram.y: Use the same conventions for gnulib as elsewhere: . (str_to_version): New. (handle_require): Use it. Prefer < to >. --- src/parse-gram.c | 95 ++++++++++++++++++++++++++++-------------------- src/parse-gram.h | 2 +- src/parse-gram.y | 65 +++++++++++++++++++++------------ 3 files changed, 98 insertions(+), 64 deletions(-) diff --git a/src/parse-gram.c b/src/parse-gram.c index 86cd782d..3a365d06 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.4.2.189-f435. */ +/* A Bison parser, made by GNU Bison 3.4.2.191-54c5d. */ /* Bison implementation for Yacc-like parsers in C @@ -48,7 +48,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.4.2.189-f435" +#define YYBISON_VERSION "3.4.2.191-54c5d" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -105,22 +105,23 @@ /* Unqualified %code blocks. */ #include "system.h" - #include - #include "c-ctype.h" + #include + #include + #include + #include + #include + #include + #include "complain.h" #include "conflicts.h" #include "files.h" #include "getargs.h" #include "gram.h" - #include "intprops.h" #include "named-ref.h" - #include "quotearg.h" #include "reader.h" #include "scan-code.h" #include "scan-gram.h" - #include "vasnprintf.h" - #include "xmemdup0.h" static int current_prec = 0; static location current_lhs_loc; @@ -490,19 +491,19 @@ union yyalloc /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 292, 292, 301, 302, 306, 307, 313, 317, 322, - 323, 328, 329, 330, 331, 332, 337, 342, 343, 344, - 345, 346, 347, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 359, 360, 369, 370, 374, 385, 389, 393, - 401, 411, 412, 422, 423, 429, 442, 442, 447, 447, - 452, 456, 466, 467, 468, 469, 473, 474, 479, 480, - 484, 485, 489, 490, 491, 504, 513, 517, 521, 529, - 530, 534, 547, 548, 560, 564, 568, 576, 578, 583, - 590, 600, 604, 608, 616, 617, 625, 626, 632, 633, - 634, 641, 641, 649, 650, 651, 656, 659, 661, 663, - 665, 667, 669, 671, 673, 675, 680, 681, 690, 714, - 715, 716, 717, 729, 731, 758, 763, 764, 769, 778, - 779, 783, 784 + 0, 293, 293, 302, 303, 307, 308, 314, 318, 323, + 324, 329, 330, 331, 332, 333, 338, 343, 344, 345, + 346, 347, 348, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 360, 361, 370, 371, 375, 386, 390, 394, + 402, 412, 413, 423, 424, 430, 443, 443, 448, 448, + 453, 457, 467, 468, 469, 470, 474, 475, 480, 481, + 485, 486, 490, 491, 492, 505, 514, 518, 522, 530, + 531, 535, 548, 549, 561, 565, 569, 577, 579, 584, + 591, 601, 605, 609, 617, 618, 626, 627, 633, 634, + 635, 642, 642, 650, 651, 652, 657, 660, 662, 664, + 666, 668, 670, 672, 674, 676, 681, 682, 691, 715, + 716, 717, 718, 730, 732, 759, 764, 765, 770, 779, + 780, 784, 785 }; #endif @@ -2979,37 +2980,53 @@ 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. */ +static int +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; + + return res; +} + + static void handle_require (location const *loc, char const *version) { - /* Changes of behavior are only on minor version changes, so "3.0.5" - is the same as "3.0". */ - errno = 0; - char *cp = NULL, *cp1; - long major = strtol (version, &cp, 10); - if (errno || cp == version || *cp != '.' || major < 0) - { - complain (loc, complaint, _("invalid version requirement: %s"), - version); - return; - } - ++cp; - long minor = strtol (cp, &cp1, 10); - if (errno || cp1 == cp || ! (0 <= minor && minor < 100) - || INT_MULTIPLY_WRAPV (major, 100, &required_version) - || INT_ADD_WRAPV (minor, required_version, &required_version)) + required_version = str_to_version (version); + if (required_version == -1) { complain (loc, complaint, _("invalid version requirement: %s"), version); + required_version = 0; return; } + /* Pretend to be at least 3.4, to check features published in 3.4 while developping it. */ const char* api_version = "3.4"; const char* package_version = - strverscmp (api_version, PACKAGE_VERSION) > 0 + 0 < strverscmp (api_version, PACKAGE_VERSION) ? api_version : PACKAGE_VERSION; - if (strverscmp (version, package_version) > 0) + if (0 < strverscmp (version, package_version)) { complain (loc, complaint, _("require bison %s, but have %s"), version, package_version); diff --git a/src/parse-gram.h b/src/parse-gram.h index 97b9d1a5..e3c56af1 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.4.2.189-f435. */ +/* A Bison parser, made by GNU Bison 3.4.2.191-54c5d. */ /* Bison interface for Yacc-like parsers in C diff --git a/src/parse-gram.y b/src/parse-gram.y index 54b20880..f8c42545 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -32,22 +32,23 @@ %code { #include "system.h" - #include - #include "c-ctype.h" + #include + #include + #include + #include + #include + #include + #include "complain.h" #include "conflicts.h" #include "files.h" #include "getargs.h" #include "gram.h" - #include "intprops.h" #include "named-ref.h" - #include "quotearg.h" #include "reader.h" #include "scan-code.h" #include "scan-gram.h" - #include "vasnprintf.h" - #include "xmemdup0.h" static int current_prec = 0; static location current_lhs_loc; @@ -970,37 +971,53 @@ 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. */ +static int +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; + + return res; +} + + static void handle_require (location const *loc, char const *version) { - /* Changes of behavior are only on minor version changes, so "3.0.5" - is the same as "3.0". */ - errno = 0; - char *cp = NULL, *cp1; - long major = strtol (version, &cp, 10); - if (errno || cp == version || *cp != '.' || major < 0) - { - complain (loc, complaint, _("invalid version requirement: %s"), - version); - return; - } - ++cp; - long minor = strtol (cp, &cp1, 10); - if (errno || cp1 == cp || ! (0 <= minor && minor < 100) - || INT_MULTIPLY_WRAPV (major, 100, &required_version) - || INT_ADD_WRAPV (minor, required_version, &required_version)) + required_version = str_to_version (version); + if (required_version == -1) { complain (loc, complaint, _("invalid version requirement: %s"), version); + required_version = 0; return; } + /* Pretend to be at least 3.4, to check features published in 3.4 while developping it. */ const char* api_version = "3.4"; const char* package_version = - strverscmp (api_version, PACKAGE_VERSION) > 0 + 0 < strverscmp (api_version, PACKAGE_VERSION) ? api_version : PACKAGE_VERSION; - if (strverscmp (version, package_version) > 0) + if (0 < strverscmp (version, package_version)) { complain (loc, complaint, _("require bison %s, but have %s"), version, package_version);