summaryrefslogtreecommitdiff
path: root/graphics/sketch/langver.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/sketch/langver.c')
-rw-r--r--graphics/sketch/langver.c115
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);
+}