3 unsigned int const a_version_major
= A_VERSION_MAJOR
;
4 unsigned int const a_version_minor
= A_VERSION_MINOR
;
5 unsigned int const a_version_patch
= A_VERSION_PATCH
;
6 a_u32
const a_version_tweak
= A_VERSION_TWEAK
;
8 int a_version_check(unsigned int major
, unsigned int minor
, unsigned int patch
)
10 a_version inner
, outer
;
11 inner
.major
= a_version_major
;
12 inner
.minor
= a_version_minor
;
13 inner
.third
= a_version_patch
;
17 return a_version_cmp(&inner
, &outer
);
20 int a_version_cmp(a_version
const *lhs
, a_version
const *rhs
)
22 if (lhs
->major
< rhs
->major
) { return -3; }
23 if (lhs
->major
> rhs
->major
) { return +3; }
24 if (lhs
->minor
< rhs
->minor
) { return -2; }
25 if (lhs
->minor
> rhs
->minor
) { return +2; }
26 if (lhs
->third
< rhs
->third
) { return -1; }
27 if (lhs
->third
> rhs
->third
) { return +1; }
31 a_bool
a_version_lt(a_version
const *lhs
, a_version
const *rhs
)
33 if (lhs
->major
< rhs
->major
) { return A_TRUE
; }
34 if (lhs
->major
> rhs
->major
) { return A_FALSE
; }
35 if (lhs
->minor
< rhs
->minor
) { return A_TRUE
; }
36 if (lhs
->minor
> rhs
->minor
) { return A_FALSE
; }
37 if (lhs
->third
< rhs
->third
) { return A_TRUE
; }
38 if (lhs
->third
> rhs
->third
) { return A_FALSE
; }
42 a_bool
a_version_gt(a_version
const *lhs
, a_version
const *rhs
)
44 if (lhs
->major
> rhs
->major
) { return A_TRUE
; }
45 if (lhs
->major
< rhs
->major
) { return A_FALSE
; }
46 if (lhs
->minor
> rhs
->minor
) { return A_TRUE
; }
47 if (lhs
->minor
< rhs
->minor
) { return A_FALSE
; }
48 if (lhs
->third
> rhs
->third
) { return A_TRUE
; }
49 if (lhs
->third
< rhs
->third
) { return A_FALSE
; }
53 a_bool
a_version_le(a_version
const *lhs
, a_version
const *rhs
)
55 if (lhs
->major
< rhs
->major
) { return A_TRUE
; }
56 if (lhs
->major
> rhs
->major
) { return A_FALSE
; }
57 if (lhs
->minor
< rhs
->minor
) { return A_TRUE
; }
58 if (lhs
->minor
> rhs
->minor
) { return A_FALSE
; }
59 if (lhs
->third
< rhs
->third
) { return A_TRUE
; }
60 if (lhs
->third
> rhs
->third
) { return A_FALSE
; }
64 a_bool
a_version_ge(a_version
const *lhs
, a_version
const *rhs
)
66 if (lhs
->major
> rhs
->major
) { return A_TRUE
; }
67 if (lhs
->major
< rhs
->major
) { return A_FALSE
; }
68 if (lhs
->minor
> rhs
->minor
) { return A_TRUE
; }
69 if (lhs
->minor
< rhs
->minor
) { return A_FALSE
; }
70 if (lhs
->third
> rhs
->third
) { return A_TRUE
; }
71 if (lhs
->third
< rhs
->third
) { return A_FALSE
; }
75 a_bool
a_version_eq(a_version
const *lhs
, a_version
const *rhs
)
77 return (lhs
->major
== rhs
->major
) && (lhs
->minor
== rhs
->minor
) && (lhs
->third
== rhs
->third
);
80 a_bool
a_version_ne(a_version
const *lhs
, a_version
const *rhs
)
82 return (lhs
->major
!= rhs
->major
) || (lhs
->minor
!= rhs
->minor
) || (lhs
->third
!= rhs
->third
);
86 #if __has_warning("-Wdisabled-macro-expansion")
87 #pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
88 #endif /* -Wdisabled-macro-expansion */
90 static A_INLINE
char const *a_version_set_alpha_(a_version
*ctx
, char const *alpha
)
93 ctx
->alpha_
[0] = *alpha
;
94 for (++alpha
; isalpha((a_byte
)*alpha
); ++alpha
)
96 if (c
< sizeof(ctx
->alpha_
)) { ctx
->alpha_
[c
++] = *alpha
; }
100 if (c
< sizeof(ctx
->alpha_
)) { ctx
->alpha_
[c
++] = *alpha
; }
101 else { ctx
->alpha_
[c
- 1] = *alpha
; }
104 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
); }
116 unsigned int a_version_parse(a_version
*ctx
, char const *ver
)
124 if (!ver
) { return 0; }
125 ctx
->major
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
126 if (u
.s
[0] == '.' && u
.s
[1] >= '0' && u
.s
[1] <= '9') { ++u
.s
; }
128 ctx
->minor
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
129 if (u
.s
[0] == '.' && u
.s
[1] >= '0' && u
.s
[1] <= '9') { ++u
.s
; }
131 ctx
->third
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
132 if ((u
.s
[0] == '.' || u
.s
[0] == '-' || u
.s
[0] == '+' || isalpha((a_byte
)u
.s
[0])) &&
133 (isalnum((a_byte
)u
.s
[1]) || !u
.s
[1])) { u
.s
= a_version_set_alpha_(ctx
, u
.s
); }
135 ctx
->extra
= (unsigned int)strtoul(u
.s
, &u
.p
, 10);
144 return (unsigned int)(u
.s
- ver
);
148 #if defined(_MSC_VER) && (_MSC_VER < 1900)
149 #define snprintf sprintf_s
150 #endif /* _MSC_VER */
152 void a_version_alpha(a_version
const *ctx
, char alpha
[5])
155 for (c
= 0; c
< sizeof(ctx
->alpha_
) && ctx
->alpha_
[c
]; ++c
)
157 alpha
[c
] = ctx
->alpha_
[c
];
162 unsigned int a_version_tostr(a_version
const *ctx
, void *pdata
, a_size nbyte
)
165 char *p
= (char *)pdata
;
166 char alpha
[sizeof(ctx
->alpha_
) + 1];
167 if (ctx
->extra
|| isalpha((a_byte
)ctx
->alpha_
[0]) || isalpha((a_byte
)ctx
->alpha_
[1]))
169 a_version_alpha(ctx
, alpha
);
170 n
= snprintf(p
, nbyte
, "%u.%u.%u%s%u",
171 ctx
->major
, ctx
->minor
, ctx
->third
, alpha
, ctx
->extra
);
175 n
= snprintf(p
, nbyte
, "%u.%u.%u",
176 ctx
->major
, ctx
->minor
, ctx
->third
);
178 return n
> 0 ? (unsigned int)n
: 0;