1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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);
}
|