po: Update German man pages translation
[dpkg.git] / lib / dpkg / deb-version.c
blobcee5ddd6aabaf809a4dba2beedc84dcc94e18577
1 /*
2 * libdpkg - Debian packaging suite library routines
3 * deb-version.c - deb format version handling routines
5 * Copyright © 2012-2013 Guillem Jover <guillem@debian.org>
7 * This 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 2 of the License, or
10 * (at your option) any later version.
12 * This 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.
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/>.
21 #include <config.h>
22 #include <compat.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <stdlib.h>
28 #include <dpkg/i18n.h>
29 #include <dpkg/c-ctype.h>
30 #include <dpkg/dpkg.h>
31 #include <dpkg/deb-version.h>
33 /**
34 * Parse a .deb format version.
36 * It takes a string and parses a .deb archive format version in the form
37 * of "X.Y", without any leading whitespace, and ending in either a newline
38 * or a NUL. If there is any syntax error a descriptive error string is
39 * returned.
41 * @param version The version to return.
42 * @param str The string to parse.
44 * @return An error string, or NULL if there was no error.
46 const char *
47 deb_version_parse(struct deb_version *version, const char *str)
49 const char *str_minor, *end;
50 unsigned int major = 0;
51 unsigned int minor = 0;
52 unsigned int divlimit = INT_MAX / 10;
53 int modlimit = INT_MAX % 10;
55 for (end = str; *end && c_isdigit(*end); end++) {
56 int ord = *end - '0';
58 if (major > divlimit || (major == divlimit && ord > modlimit))
59 return _("format version with too big major component");
61 major = major * 10 + ord;
64 if (end == str)
65 return _("format version with empty major component");
66 if (*end != '.')
67 return _("format version has no dot");
69 for (end = str_minor = end + 1; *end && c_isdigit(*end); end++) {
70 int ord = *end - '0';
72 if (minor > divlimit || (minor == divlimit && ord > modlimit))
73 return _("format version with too big minor component");
75 minor = minor * 10 + ord;
78 if (end == str_minor)
79 return _("format version with empty minor component");
80 if (*end != '\n' && *end != '\0')
81 return _("format version followed by junk");
83 version->major = major;
84 version->minor = minor;
86 return NULL;