]>
git.saurik.com Git - apple/xnu.git/blob - libsa/vers_rsrc.c
1 #include <libsa/vers_rsrc.h>
3 #include <libkern/OSByteOrder.h>
8 c
== '1' || c
== '2' || c
== '3' ||
9 c
== '4' || c
== '5' || c
== '6' ||
10 c
== '7' || c
== '8' || c
== '9');
21 int isreleasestate(char c
) {
22 return (c
== 'd' || c
== 'a' || c
== 'b' || c
== 'f');
26 UInt8
BCD_digit_for_char(char c
) {
28 case '0': return 0; break;
29 case '1': return 1; break;
30 case '2': return 2; break;
31 case '3': return 3; break;
32 case '4': return 4; break;
33 case '5': return 5; break;
34 case '6': return 6; break;
35 case '7': return 7; break;
36 case '8': return 8; break;
37 case '9': return 9; break;
38 default: return BCD_illegal
; break;
44 char BCD_char_for_digit(UInt8 digit
) {
46 case 0: return '0'; break;
47 case 1: return '1'; break;
48 case 2: return '2'; break;
49 case 3: return '3'; break;
50 case 4: return '4'; break;
51 case 5: return '5'; break;
52 case 6: return '6'; break;
53 case 7: return '7'; break;
54 case 8: return '8'; break;
55 case 9: return '9'; break;
56 default: return '?'; break;
62 VERS_revision
VERS_revision_for_string(const char ** string_p
) {
65 if (!string_p
|| !*string_p
) {
71 if (isspace(string
[0]) || string
[0] == '\0') {
76 if (isdigit(string
[1])) {
77 *string_p
= &string
[1];
78 return VERS_development
;
82 if (isdigit(string
[1])) {
83 *string_p
= &string
[1];
88 if (isdigit(string
[1])) {
89 *string_p
= &string
[1];
94 if (isdigit(string
[1])) {
95 *string_p
= &string
[1];
96 return VERS_candidate
;
97 } else if (string
[1] == 'c' && isdigit(string
[2])) {
98 *string_p
= &string
[2];
99 return VERS_candidate
;
114 int VERS_parse_string(const char * vers_string
, UInt32
* version_num
) {
117 const char * current_char_p
;
120 if (!vers_string
|| *vers_string
== '\0') {
126 current_char_p
= &vers_string
[0];
130 * Check for an initial digit of the major release number.
132 vers
.bytes
[0] = BCD_digit_for_char(*current_char_p
);
133 if (vers
.bytes
[0] == BCD_illegal
) {
141 * Check for a second digit of the major release number.
143 if (*current_char_p
== '\0') {
144 vers
.bytes
[2] = VERS_release
;
145 vers
.bytes
[3] = 0xff;
147 } else if (isdigit(*current_char_p
)) {
148 scratch
= BCD_digit_for_char(*current_char_p
);
149 if (scratch
== BCD_illegal
) {
152 vers
.bytes
[0] = BCD_combine(vers
.bytes
[0], scratch
);
155 if (*current_char_p
== '\0') {
156 vers
.bytes
[2] = VERS_release
;
157 vers
.bytes
[3] = 0xff;
159 } else if (isreleasestate(*current_char_p
)) {
161 } else if (*current_char_p
== '.') {
166 } else if (isreleasestate(*current_char_p
)) {
168 } else if (*current_char_p
== '.') {
176 * Check for the minor release number.
178 if (*current_char_p
== '\0') {
179 vers
.bytes
[2] = VERS_release
;
180 vers
.bytes
[3] = 0xff;
182 } else if (isdigit(*current_char_p
)) {
183 vers
.bytes
[1] = BCD_digit_for_char(*current_char_p
);
184 if (vers
.bytes
[1] == BCD_illegal
) {
188 // Make sure its the first nibble of byte 1!
189 vers
.bytes
[1] = BCD_combine(vers
.bytes
[1], 0);
193 if (*current_char_p
== '\0') {
194 vers
.bytes
[2] = VERS_release
;
195 vers
.bytes
[3] = 0xff;
197 } else if (isreleasestate(*current_char_p
)) {
199 } else if (*current_char_p
== '.') {
210 * Check for the bugfix number.
212 if (*current_char_p
== '\0') {
213 vers
.bytes
[2] = VERS_release
;
214 vers
.bytes
[3] = 0xff;
216 } else if (isdigit(*current_char_p
)) {
217 scratch
= BCD_digit_for_char(*current_char_p
);
218 if (scratch
== BCD_illegal
) {
222 /* vers.bytes[1] has its left nibble set already */
223 vers
.bytes
[1] = vers
.bytes
[1] | scratch
;
227 if (*current_char_p
== '\0') {
228 vers
.bytes
[2] = VERS_release
;
229 vers
.bytes
[3] = 0xff;
231 } else if (isreleasestate(*current_char_p
)) {
244 * Check for the release state.
246 if (*current_char_p
== '\0') {
247 vers
.bytes
[2] = VERS_release
;
248 vers
.bytes
[3] = 0xff;
251 vers
.bytes
[2] = VERS_revision_for_string(¤t_char_p
);
252 if (vers
.bytes
[2] == VERS_invalid
) {
259 * Get the nonrelease revision number (0..255).
261 if (vers
.bytes
[2] != VERS_release
) {
262 UInt32 revision_num
= 0;
265 if (*current_char_p
== '\0' || !isdigit(*current_char_p
)) {
268 for (i
= 0; i
< 3 && *current_char_p
!= '\0'; i
++, current_char_p
++) {
270 scratch_digit
= BCD_digit_for_char(*current_char_p
);
271 if (scratch_digit
== BCD_illegal
) {
275 revision_num
+= scratch_digit
;
277 if (isdigit(*current_char_p
) || revision_num
> 255) {
280 vers
.bytes
[3] = (UInt8
)revision_num
;
283 if (vers
.bytes
[2] == VERS_release
) {
284 vers
.bytes
[3] = 0xff;
286 if (vers
.bytes
[2] == VERS_candidate
) {
287 if (vers
.bytes
[3] == 0) {
290 vers
.bytes
[2] = VERS_release
;
297 *version_num
= OSSwapBigToHostInt32(vers
.vnum
);
302 #define VERS_STRING_MAX_LEN (12)
304 int VERS_string(char * buffer
, UInt32 length
, UInt32 vers
) {
305 VERS_version version
;
314 version
.vnum
= OSSwapHostToBigInt32(vers
);
316 /* No buffer, length less than longest possible vers string,
319 if (!buffer
|| length
< VERS_STRING_MAX_LEN
) {
324 bzero(buffer
, length
* sizeof(char));
328 * Major version number.
330 major1
= BCD_char_for_digit(BCD_get_left(version
.bytes
[0]));
333 } /* this is not an 'else' situation */
335 buffer
[cpos
] = major1
;
339 major2
= BCD_char_for_digit(BCD_get_right(version
.bytes
[0]));
344 buffer
[cpos
] = major2
;
349 * Minor & bug-fix version numbers.
351 minor
= BCD_char_for_digit(BCD_get_left(version
.bytes
[1]));
355 bugfix
= BCD_char_for_digit(BCD_get_right(version
.bytes
[1]));
361 /* Always display the minor version number.
365 buffer
[cpos
] = minor
;
369 /* Only display the bugfix version number if it's nonzero.
374 buffer
[cpos
] = bugfix
;
379 /* If the release state is final, we're done!
381 if (version
.bytes
[2] == VERS_release
&& version
.bytes
[3] == 255) {
388 * Do the release state and update level.
390 switch (version
.bytes
[2]) {
391 case VERS_development
:
404 if (version
.bytes
[3] < 255) {
406 buffer
[cpos
+1] = 'c';
420 if (version
.bytes
[2] != VERS_release
) {
421 sprintf(&buffer
[cpos
], "%d", version
.bytes
[3]);
423 if (version
.bytes
[3] < 255) {
424 sprintf(&buffer
[cpos
], "%d", version
.bytes
[3] + 1);