/* ***************************************************************************** * utils/version.c -- decode and encode a version. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * This file is part of libg1m. * libg1m is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3.0 of the License, * or (at your option) any later version. * * libg1m 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libg1m; if not, see . * ************************************************************************** */ #include #include /** * g1m_check_version: * Check if a version string is well formatted. * * @arg raw the string to check. * @return if there was an error. */ int g1m_check_version(const char *raw) { /* check length */ if (memchr(raw, 0, 10)) return (g1m_error_op); /* check characters */ if (!isdigit(raw[0]) || !isdigit(raw[1]) || raw[2] != '.' || !isdigit(raw[3]) || !isdigit(raw[4]) || raw[5] != '.' || !isdigit(raw[6]) || !isdigit(raw[7]) || !isdigit(raw[8]) || !isdigit(raw[9])) return (g1m_error_op); /* no error! */ return (0); } /** * g1m_decode_version: * Decode a version from a 'MM.mm.ffff' formatted version string. * * @arg raw the string to decode from. * @arg version the structure where to store the information. * @return the error code (if any). */ int g1m_decode_version(const char *raw, g1m_version_t *version) { /* helper values */ const int two = '0' + '0' * 10; /* get the basic version data */ *version = (g1m_version_t){ .g1m_version_major = raw[0] * 10 + raw[1] - two, .g1m_version_minor = raw[3] * 10 + raw[4] - two}; /* get normal values */ version->g1m_version_zone = raw[6] - '0'; version->g1m_version_math = raw[7] - '0'; /* get build flags */ version->g1m_version_flags = 0; if (raw[8] != '0') version->g1m_version_flags |= g1m_versionflag_indev; if (raw[9] != '0') version->g1m_version_flags |= g1m_versionflag_spe; /* no error */ return (0); } /** * g1m_encode_version: * Encode a version into an 'MM.mm.ffff' formatted version string. * * @arg version the version to encode. * @arg the string to encode into. * @return the error code (if any). */ int g1m_encode_version(const g1m_version_t *version, char *raw) { /* make buffer */ char buf[11]; sprintf(buf, "%02u.%02u.%c%c%c%c", version->g1m_version_major, version->g1m_version_minor, version->g1m_version_zone + '0', version->g1m_version_math + '0', version->g1m_version_flags & g1m_versionflag_indev ? '1' : '0', version->g1m_version_flags & g1m_versionflag_spe ? '1' : '0'); /* copy final */ memcpy(raw, buf, 10); return (0); }