#define CHAZ_USE_SHORT_NAMES #include "Charmonizer/Core/HeadCheck.h" #include "Charmonizer/Core/ModHandler.h" #include "Charmonizer/Core/Util.h" #include "Charmonizer/Probe/Integers.h" #include #include #include static char *code_buf = NULL; static size_t code_buf_len = 0; /* Determine endian-ness of this machine. */ static chaz_bool_t machine_is_big_endian(); static char sizes_code[] = METAQUOTE #include "_charm.h" int main () { Charm_Setup; printf("%d %d %d %d %d", (int)sizeof(char), (int)sizeof(short), (int)sizeof(int), (int)sizeof(long), (int)sizeof(void *) ); return 0; } METAQUOTE; static char type64_code[] = METAQUOTE #include "_charm.h" int main() { Charm_Setup; printf("%%d", (int)sizeof(%s)); return 0; } METAQUOTE; static char literal64_code[] = METAQUOTE #include "_charm.h" #define big 9000000000000000000%s int main() { Charm_Setup; printf("1\n"); return 0; } METAQUOTE; void chaz_Integers_run(void) { char *output; size_t output_len; int sizeof_char = -1; int sizeof_short = -1; int sizeof_int = -1; int sizeof_ptr = -1; int sizeof_long = -1; int sizeof_long_long = -1; int sizeof___int64 = -1; chaz_bool_t has_8 = false; chaz_bool_t has_16 = false; chaz_bool_t has_32 = false; chaz_bool_t has_64 = false; chaz_bool_t has_long_long = false; chaz_bool_t has___int64 = false; chaz_bool_t has_inttypes = check_header("inttypes.h"); char i32_t_type[10]; char i32_t_postfix[10]; char u32_t_postfix[10]; char i64_t_type[10]; char i64_t_postfix[10]; char u64_t_postfix[10]; START_RUN("Integers"); /* document endian-ness */ if (machine_is_big_endian()) append_conf("#define CHY_BIG_END\n"); else append_conf("#define CHY_LITTLE_END\n"); /* Record sizeof() for several common integer types. */ output = capture_output(sizes_code, strlen(sizes_code), &output_len); if (output != NULL) { char *end_ptr = output; sizeof_char = strtol(output, &end_ptr, 10); output = end_ptr; sizeof_short = strtol(output, &end_ptr, 10); output = end_ptr; sizeof_int = strtol(output, &end_ptr, 10); output = end_ptr; sizeof_long = strtol(output, &end_ptr, 10); output = end_ptr; sizeof_ptr = strtol(output, &end_ptr, 10); } /* determine whether long longs are available */ code_buf_len = grow_buf(&code_buf, code_buf_len, sizeof(type64_code) + 200); sprintf(code_buf, type64_code, "long long"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) { has_long_long = true; sizeof_long_long = strtol(output, NULL, 10); } /* determine whether the __int64 type is available */ sprintf(code_buf, type64_code, "__int64"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) { has___int64 = true; sizeof___int64 = strtol(output, NULL, 10); } /* figure out which integer types are available */ if (sizeof_char == 1) { has_8 = true; } if (sizeof_short == 2) { has_16 = true; } if (sizeof_int == 4) { has_32 = true; strcpy(i32_t_type, "int"); strcpy(i32_t_postfix, ""); strcpy(u32_t_postfix, "U"); } else if (sizeof_long == 4) { has_32 = true; strcpy(i32_t_type, "long"); strcpy(i32_t_postfix, "L"); strcpy(u32_t_postfix, "UL"); } if (sizeof_long == 8) { has_64 = true; strcpy(i64_t_type, "long"); } else if (sizeof_long_long == 8) { has_64 = true; strcpy(i64_t_type, "long long"); } else if (sizeof___int64 == 8) { has_64 = true; strcpy(i64_t_type, "__int64"); } /* probe for 64-bit literal syntax */ if (has_64 && sizeof_long == 8) { strcpy(i64_t_postfix, "L"); strcpy(u64_t_postfix, "UL"); } else if (has_64) { sprintf(code_buf, literal64_code, "LL"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) { strcpy(i64_t_postfix, "LL"); } else { sprintf(code_buf, literal64_code, "i64"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) strcpy(i64_t_postfix, "i64"); else die("64-bit types, but no literal syntax found"); } sprintf(code_buf, literal64_code, "ULL"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) { strcpy(u64_t_postfix, "ULL"); } else { sprintf(code_buf, literal64_code, "Ui64"); output = capture_output(code_buf, strlen(code_buf), &output_len); if (output != NULL) strcpy(u64_t_postfix, "Ui64"); else die("64-bit types, but no literal syntax found"); } } /* write out some conditional defines */ if (has_inttypes) append_conf("#define CHY_HAS_INTTYPES_H\n"); if (has_long_long) append_conf("#define CHY_HAS_LONG_LONG\n"); if (has___int64) append_conf("#define CHY_HAS___INT64\n"); /* write out sizes */ append_conf("#define CHY_SIZEOF_CHAR %d\n", sizeof_char); append_conf("#define CHY_SIZEOF_SHORT %d\n", sizeof_short); append_conf("#define CHY_SIZEOF_INT %d\n", sizeof_int); append_conf("#define CHY_SIZEOF_LONG %d\n", sizeof_long); append_conf("#define CHY_SIZEOF_PTR %d\n", sizeof_ptr); if (has_long_long) { append_conf("#define CHY_SIZEOF_LONG_LONG %d\n", sizeof_long_long); } if (has___int64) { append_conf("#define CHY_SIZEOF___INT64 %d\n", sizeof___int64); } /* write affirmations, typedefs and maximums/minimums */ append_conf("typedef int chy_bool_t;\n"); if (has_8) { append_conf( "#define CHY_HAS_I8_T\n" "typedef char chy_i8_t;\n" "typedef unsigned char chy_u8_t;\n" "#define CHY_I8_MAX 0x7F\n" "#define CHY_I8_MIN (-I8_MAX - 1)\n" "#define CHY_U8_MAX (I8_MAX * 2 + 1)\n" ); } if (has_16) { append_conf( "#define CHY_HAS_I16_T\n" "typedef short chy_i16_t;\n" "typedef unsigned short chy_u16_t;\n" "#define CHY_I16_MAX 0x7FFF\n" "#define CHY_I16_MIN (-I16_MAX - 1)\n" "#define CHY_U16_MAX (I16_MAX * 2 + 1)\n" ); } if (has_32) { append_conf("#define CHY_HAS_I32_T\n"); append_conf("typedef %s chy_i32_t;\n", i32_t_type); append_conf("typedef unsigned %s chy_u32_t;\n", i32_t_type); append_conf("#define CHY_I32_MAX 0x7FFFFFFF%s\n", i32_t_postfix); append_conf("#define CHY_I32_MIN (-I32_MAX - 1)\n"); append_conf("#define CHY_U32_MAX (I32_MAX * 2%s + 1%s)\n", u32_t_postfix, u32_t_postfix); } if (has_64) { append_conf("#define CHY_HAS_I64_T\n"); append_conf("typedef %s chy_i64_t;\n", i64_t_type); append_conf("typedef unsigned %s chy_u64_t;\n", i64_t_type); append_conf("#define CHY_I64_MAX 0x7FFFFFFFFFFFFFFF%s\n", i64_t_postfix); append_conf("#define CHY_I64_MIN (-I64_MAX - 1%s)\n", i64_t_postfix); append_conf("#define CHY_U64_MAX (I64_MAX * 2%s + 1%s)\n", u64_t_postfix, u64_t_postfix); } /* create the I64P and U64P printf macros */ if (has_64) { int i; char *options[] = { "ll", "l", "L", "q", /* Some *BSDs */ "I64", /* Microsoft */ NULL, }; /* buffer to hold the code, and its start and end */ char format_64_code[1000]; static char format_64_code_a[] = METAQUOTE #include "_charm.h" int main() { Charm_Setup; printf( METAQUOTE; static char format_64_code_b[] = METAQUOTE ); return 0; } METAQUOTE; for (i = 0; options[i] != NULL; i++) { /* try to print 2**64-1, and see if we get it back intact */ sprintf(format_64_code, "%s\"%%%su\", 18446744073709551615%s%s", format_64_code_a, options[i], u64_t_postfix, format_64_code_b); output = capture_output(format_64_code, strlen(format_64_code), &output_len); if ( output_len != 0 && strcmp(output, "18446744073709551615") == 0 ) { append_conf("#define CHY_I64P \"%sd\"\n", options[i]); append_conf("#define CHY_U64P \"%su\"\n", options[i]); break; } } } /* write out the 32-bit and 64-bit literal macros */ if (has_32) { if (strcmp(i32_t_postfix, "") == 0) { append_conf("#define CHY_I32_C(n) n\n"); append_conf("#define CHY_U32_C(n) n##%s\n", u32_t_postfix); } else { append_conf("#define CHY_I32_C(n) n##%s\n", i32_t_postfix); append_conf("#define CHY_U32_C(n) n##%s\n", u32_t_postfix); } } if (has_64) { append_conf("#define CHY_I64_C(n) n##%s\n", i64_t_postfix); append_conf("#define CHY_U64_C(n) n##%s\n", u64_t_postfix); } /* true and false */ append_conf( "#ifndef true\n" " #define true 1\n" "#endif\n" "#ifndef false\n" " #define false 0\n" "#endif\n" ); /* shorten */ START_SHORT_NAMES; if ( machine_is_big_endian() ) { shorten_macro("BIG_END"); } else { shorten_macro("LITTLE_END"); } shorten_macro("SIZEOF_CHAR"); shorten_macro("SIZEOF_SHORT"); shorten_macro("SIZEOF_LONG"); shorten_macro("SIZEOF_INT"); shorten_macro("SIZEOF_PTR"); if (has_long_long) { shorten_macro("HAS_LONG_LONG"); shorten_macro("SIZEOF_LONG_LONG"); } if (has___int64) { shorten_macro("HAS___INT64"); shorten_macro("SIZEOF___INT64"); } if (has_inttypes) shorten_macro("HAS_INTTYPES_H"); shorten_typedef("bool_t"); if (has_8) { shorten_macro("HAS_I8_T"); shorten_typedef("i8_t"); shorten_typedef("u8_t"); shorten_macro("I8_MAX"); shorten_macro("I8_MIN"); shorten_macro("U8_MAX"); } if (has_16) { shorten_macro("HAS_I16_T"); shorten_typedef("i16_t"); shorten_typedef("u16_t"); shorten_macro("I16_MAX"); shorten_macro("I16_MIN"); shorten_macro("U16_MAX"); } if (has_32) { shorten_macro("HAS_I32_T"); shorten_typedef("i32_t"); shorten_typedef("u32_t"); shorten_macro("I32_MAX"); shorten_macro("I32_MIN"); shorten_macro("U32_MAX"); shorten_macro("I32_C"); shorten_macro("U32_C"); } if (has_64) { shorten_macro("HAS_I64_T"); shorten_typedef("i64_t"); shorten_typedef("u64_t"); shorten_macro("I64_MAX"); shorten_macro("I64_MIN"); shorten_macro("U64_MAX"); shorten_macro("I64P"); shorten_macro("U64P"); shorten_macro("I64_C"); shorten_macro("U64_C"); } END_SHORT_NAMES; END_RUN; } static chaz_bool_t machine_is_big_endian() { long one = 1; return !(*((char *)(&one))); } /** * Copyright 2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */