4 unsigned int const a_version_major
= A_VERSION_MAJOR
;
5 unsigned int const a_version_minor
= A_VERSION_MINOR
;
6 unsigned int const a_version_patch
= A_VERSION_PATCH
;
7 a_u32
const a_version_tweak
= A_VERSION_TWEAK
;
9 int a_version_check(unsigned int major
, unsigned int minor
, unsigned int patch
)
11 a_version inner
, outer
;
12 inner
.major
= a_version_major
;
13 inner
.minor
= a_version_minor
;
14 inner
.third
= a_version_patch
;
18 return a_version_cmp(&inner
, &outer
);
21 int a_version_cmp(a_version
const *lhs
, a_version
const *rhs
)
23 if (lhs
->major
< rhs
->major
) { return -3; }
24 if (lhs
->major
> rhs
->major
) { return +3; }
25 if (lhs
->minor
< rhs
->minor
) { return -2; }
26 if (lhs
->minor
> rhs
->minor
) { return +2; }
27 if (lhs
->third
< rhs
->third
) { return -1; }
28 if (lhs
->third
> rhs
->third
) { return +1; }
32 a_bool
a_version_lt(a_version
const *lhs
, a_version
const *rhs
)
34 if (lhs
->major
< rhs
->major
) { return A_TRUE
; }
35 if (lhs
->major
> rhs
->major
) { return A_FALSE
; }
36 if (lhs
->minor
< rhs
->minor
) { return A_TRUE
; }
37 if (lhs
->minor
> rhs
->minor
) { return A_FALSE
; }
38 if (lhs
->third
< rhs
->third
) { return A_TRUE
; }
39 if (lhs
->third
> rhs
->third
) { return A_FALSE
; }
43 a_bool
a_version_gt(a_version
const *lhs
, a_version
const *rhs
)
45 if (lhs
->major
> rhs
->major
) { return A_TRUE
; }
46 if (lhs
->major
< rhs
->major
) { return A_FALSE
; }
47 if (lhs
->minor
> rhs
->minor
) { return A_TRUE
; }
48 if (lhs
->minor
< rhs
->minor
) { return A_FALSE
; }
49 if (lhs
->third
> rhs
->third
) { return A_TRUE
; }
50 if (lhs
->third
< rhs
->third
) { return A_FALSE
; }
54 a_bool
a_version_le(a_version
const *lhs
, a_version
const *rhs
)
56 if (lhs
->major
< rhs
->major
) { return A_TRUE
; }
57 if (lhs
->major
> rhs
->major
) { return A_FALSE
; }
58 if (lhs
->minor
< rhs
->minor
) { return A_TRUE
; }
59 if (lhs
->minor
> rhs
->minor
) { return A_FALSE
; }
60 if (lhs
->third
< rhs
->third
) { return A_TRUE
; }
61 if (lhs
->third
> rhs
->third
) { return A_FALSE
; }
65 a_bool
a_version_ge(a_version
const *lhs
, a_version
const *rhs
)
67 if (lhs
->major
> rhs
->major
) { return A_TRUE
; }
68 if (lhs
->major
< rhs
->major
) { return A_FALSE
; }
69 if (lhs
->minor
> rhs
->minor
) { return A_TRUE
; }
70 if (lhs
->minor
< rhs
->minor
) { return A_FALSE
; }
71 if (lhs
->third
> rhs
->third
) { return A_TRUE
; }
72 if (lhs
->third
< rhs
->third
) { return A_FALSE
; }
76 a_bool
a_version_eq(a_version
const *lhs
, a_version
const *rhs
)
78 return (lhs
->major
== rhs
->major
) && (lhs
->minor
== rhs
->minor
) && (lhs
->third
== rhs
->third
);
81 a_bool
a_version_ne(a_version
const *lhs
, a_version
const *rhs
)
83 return (lhs
->major
!= rhs
->major
) || (lhs
->minor
!= rhs
->minor
) || (lhs
->third
!= rhs
->third
);
88 static A_INLINE
char const *a_version_set_alpha_(a_version
*ctx
, char const *alpha
)
91 ctx
->alpha
[0] = *alpha
;
92 for (++alpha
; isalpha((a_byte
)*alpha
); ++alpha
)
94 if (c
< sizeof(ctx
->alpha
)) { ctx
->alpha
[c
++] = *alpha
; }
98 if (c
< sizeof(ctx
->alpha
)) { ctx
->alpha
[c
++] = *alpha
; }
99 else { ctx
->alpha
[c
- 1] = *alpha
; }
102 while (c
< sizeof(ctx
->alpha
)) { ctx
->alpha
[c
++] = 0; }
108 void a_version_set_alpha(a_version
*ctx
, char const *alpha
)
110 if ((*alpha
== '.' || *alpha
== '-' || *alpha
== '+' || isalpha((a_byte
)*alpha
)) &&
111 (isalpha((a_byte
)alpha
[1]) || !alpha
[1])) { a_version_set_alpha_(ctx
, alpha
); }
114 unsigned int a_version_parse(a_version
*ctx
, char const *ver
)
122 if (!ver
) { return 0; }
123 ctx
->major
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
124 if (u
.s
[0] == '.' && u
.s
[1] >= '0' && u
.s
[1] <= '9') { ++u
.s
; }
126 ctx
->minor
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
127 if (u
.s
[0] == '.' && u
.s
[1] >= '0' && u
.s
[1] <= '9') { ++u
.s
; }
129 ctx
->third
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
130 if ((u
.s
[0] == '.' || u
.s
[0] == '-' || u
.s
[0] == '+' || isalpha((a_byte
)u
.s
[0])) &&
131 (isalnum((a_byte
)u
.s
[1]) || !u
.s
[1])) { u
.s
= a_version_set_alpha_(ctx
, u
.s
); }
133 ctx
->extra
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
142 return (unsigned int)(u
.s
- ver
);
146 #if defined(_MSC_VER) && (_MSC_VER < 1900)
147 #define snprintf sprintf_s
148 #endif /* _MSC_VER */
150 void a_version_alpha(a_version
const *ctx
, char alpha
[5])
153 for (c
= 0; c
< sizeof(ctx
->alpha
) && ctx
->alpha
[c
]; ++c
)
155 alpha
[c
] = ctx
->alpha
[c
];
160 unsigned int a_version_tostr(a_version
const *ctx
, void *pdata
, a_size nbyte
)
163 char *p
= (char *)pdata
;
164 char alpha
[sizeof(ctx
->alpha
) + 1];
165 if (ctx
->extra
|| isalpha((a_byte
)ctx
->alpha
[0]) || isalpha((a_byte
)ctx
->alpha
[1]))
167 a_version_alpha(ctx
, alpha
);
168 n
= snprintf(p
, nbyte
, "%u.%u.%u%s%u",
169 ctx
->major
, ctx
->minor
, ctx
->third
, alpha
, ctx
->extra
);
173 n
= snprintf(p
, nbyte
, "%u.%u.%u",
174 ctx
->major
, ctx
->minor
, ctx
->third
);
176 return n
> 0 ? (unsigned int)n
: 0;