diff options
Diffstat (limited to 'graphics/sketch/langver.c')
-rw-r--r-- | graphics/sketch/langver.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/graphics/sketch/langver.c b/graphics/sketch/langver.c new file mode 100644 index 0000000000..d68c1cd8e7 --- /dev/null +++ b/graphics/sketch/langver.c @@ -0,0 +1,115 @@ +#include <string.h> +#include "langver.h" + +int +is_digit (int ch) +{ + return '0' <= ch && ch <= '9'; +} + +int +lower (int ch) +{ + return ('A' <= ch && ch <= 'Z') ? ch + ('a' - 'A') : ch; +} + +int +is_alpha(int ch) +{ + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'); +} + +int +parse_pst_version (PST_VERSION *v, char *str, SRC_LINE line) +{ +#define M (sizeof v->key / 2) + int i = 0, iv = 0, i_minor = -1; + + memset(v->key, '0', sizeof v->key); + memset(v->str, '\0', sizeof v->str); + + if (strlen(str) > sizeof v->str - 1) + { + err (line, "PSTricks version string too long"); + return 1; + } + A : + if ( is_digit (str[i]) ) + { + v->str[iv++] = str[i++]; + goto B; + } + else + { + err (line, "bad character '%c' in PSTricks version", str[i]); + return 2; + } + B : + if ( is_digit (str[i]) ) + { + v->str[iv++] = str[i++]; + goto B; + } + else if ( str[i] == '.' ) + { + memcpy (&v->key[M - i], v->str, i); // save major in key + v->str[iv++] = str[i++]; + i_minor = iv; // remember where minor version starts + goto C; + } + else + { + err (line, "expected dot in PSTricks version"); + return 3; + } + C : + if ( is_digit (str[i]) ) + { + v->str[iv++] = str[i++]; + goto D; + } + else + { + err (line, "expected digit after dot in PSTricks version"); + return 4; + } + D : + if ( is_digit (str[i]) ) + { + v->str[iv++] = str[i++]; + goto D; + } + else if ( is_alpha(str[i]) ) + { + v->str[iv++] = lower (str[i++]); + goto F; + } + else if ( str[i] == '\0' ) + { + memcpy (&v->key[M], &v->str[i_minor], i - i_minor); // save minor in key + return 0; /* accept */ + } + else + { + err (line, "expected digit or subversion letter in PSTricks version"); + return 5; + } + F: + if ( str[i] == '\0' ) + { + memcpy (&v->key[M], &v->str[i_minor], i - i_minor); + return 0; /* accept */ + } + else + { + err (line, "expected end of PSTricks version, found '%c'", str[i]); + return 6; + } + return -1; +} + +int +pst_version_cmp(PST_VERSION *a, PST_VERSION *b) +{ + return strncmp(a->key, b->key, sizeof a->key); +} |