/* * AppTypes * * Generates consistent type definitions, and * checks the word alignment on this machine. * * This program writes a file called "apptypes.h" * which contains platform-specific information * defining numeric types and determining * how data should be aligned within structures. * * This program attempts to find 8-bit, 16-bit * and 32-bit integer types to use in definitions * of app_uint8, app_int16 and app_int32. * We don't just assume C's "int" is 32-bits in size; * this would be non-portable. Instead, this program * uses the C language sizeof() operator to determine * the sizes of built-in C types such as "int". It * then writes a header file which is used in * compiling other programs. We can then safely * assume that app_int32 is 32 bits in size, no more, * no less. * * This program also tries to make app_float32 a * floating point type of 32-bits in size, and * app_float64 a floating point type of 64-bits size. * These may not succeed, and even if they do, * there is no guarantee that the resulting type * has that many bits of precision on the hardware. * But at least we can try to get the structure * alignment and packing correct. * * The "apptypes.h" header file is used when * compiling other files below this directory. */ #include #include #include char *filename = "apptypes.h"; char *progname = "apptypes"; struct AlignChar { char dummy; char data; }; struct AlignShort { char dummy; short data; }; struct AlignInt { char dummy; int data; }; struct AlignLong { char dummy; long data; }; struct AlignFloat { char dummy; float data; }; struct AlignDouble { char dummy; double data; }; struct AlignLongDouble { char dummy; long double data; }; struct AlignPointer { char dummy; void * data; }; int main(int argc, char *argv[]) { FILE *f; struct AlignChar align_char; struct AlignShort align_short; struct AlignInt align_int; struct AlignLong align_long; struct AlignFloat align_float; struct AlignDouble align_double; struct AlignLongDouble align_long_double; struct AlignPointer align_pointer; int size_app_float32 = 4; int size_app_float64 = 8; int size_app_pointer = 0; int offset_app_int8 = 0; int offset_app_int16 = 0; int offset_app_int32 = 0; int offset_app_float32 = 0; int offset_app_float64 = 0; int offset_app_pointer = 0; int offset_maximum = 0; f = fopen(filename, "w"); if (f == NULL) { fprintf(stderr, "%s: warning: couldn't create file %s\n", progname, filename); fprintf(stderr, "%s: warning: using stdout instead\n", progname); f = stdout; } fprintf(f, "/*\n"); fprintf(f, " * %s\n", filename); fprintf(f, " * Contains platform and compiler-specific definitions.\n"); fprintf(f, " * Do not edit this machine-generated file.\n"); fprintf(f, " * Re-compile and run %s.c instead.\n", progname); fprintf(f, " */\n\n"); /* * Print standard types. */ fprintf(f, "/* Standard type names: */\n"); if (sizeof(char) == 1) { fprintf(f, "typedef signed char app_int8; "); fprintf(f, "/* 8-bit signed integer. */\n"); fprintf(f, "typedef unsigned char app_uint8; "); fprintf(f, "/* 8-bit unsigned integer. */\n"); offset_app_int8 = sizeof(align_char) - sizeof(char); } else { /* This is a serious error. We need char to be 8 bits */ /* otherwise most C programs will break. */ /* So, we send an error into the file to alert the user */ /* to find an 8-bit int. */ fprintf(f, "Could not find an 8-bit integer type!\n"); fprintf(f, "typedef signed ?!?! app_int8;\n"); fprintf(f, "typedef unsigned ?!?! app_uint8;\n"); } /* * Find a 16-bit integer type. */ if (sizeof(short) == 2) { fprintf(f, "typedef short app_int16; "); fprintf(f, "/* 16-bit signed integer. */\n"); fprintf(f, "typedef unsigned short app_uint16; "); fprintf(f, "/* 16-bit unsigned integer. */\n"); offset_app_int16 = sizeof(align_short) - sizeof(short); } else { /* We could use wchar_t, but that type is somewhat */ /* obsolete and may not be supported by all compilers. */ /* So, we send an error into the file to alert the user */ /* to find a 16-bit int. */ fprintf(f, "Could not find a 16-bit integer type!\n"); fprintf(f, "typedef ?!?!? app_int16;\n"); fprintf(f, "typedef unsigned ?!?!? app_uint16;\n"); } /* * Find a 32-bit integer type. */ if (sizeof(int) == 4) { fprintf(f, "typedef int app_int32; "); fprintf(f, "/* 32-bit signed integer. */\n"); fprintf(f, "typedef unsigned int app_uint32; "); fprintf(f, "/* 32-bit unsigned integer. */\n"); offset_app_int32 = sizeof(align_int) - sizeof(int); } else if (sizeof(long) == 4) { fprintf(f, "typedef long app_int32; "); fprintf(f, "/* 32-bit signed integer. */\n"); fprintf(f, "typedef unsigned long app_uint32; "); fprintf(f, "/* 32-bit unsigned integer. */\n"); offset_app_int32 = sizeof(align_long) - sizeof(long); } else if (sizeof(short) == 4) { /* Rather unlikely to be true. */ fprintf(f, "typedef short app_int32; "); fprintf(f, "/* 32-bit signed integer. */\n"); fprintf(f, "typedef unsigned short app_uint32; "); fprintf(f, "/* 32-bit unsigned integer. */\n"); offset_app_int32 = sizeof(align_short) - sizeof(short); } else { /* Send an error into the file to alert the user */ /* to find a 32-bit int. */ fprintf(f, "Could not find a 32-bit integer type!\n"); fprintf(f, "typedef ?!?! app_int32;\n"); fprintf(f, "typedef unsigned ?!?! app_uint32;\n"); } /* * Find the 32-bit float and 64-bit real types. */ if (sizeof(float) == 4) { fprintf(f, "typedef float app_float32; "); offset_app_float32 = sizeof(align_float) - sizeof(float); } else if (sizeof(double) == 4) { fprintf(f, "typedef double app_float32; "); offset_app_float32 = sizeof(align_double) - sizeof(double); } else if (sizeof(long double) == 4) { /* Very strange indeed. */ fprintf(f, "typedef long double app_float32; "); offset_app_float32 = sizeof(align_long_double) - sizeof(long double); } else { /* Give up, and use float. */ fprintf(f, "typedef float app_float32; "); offset_app_float32 = sizeof(align_float) - sizeof(float); size_app_float32 = sizeof(float); } fprintf(f, "/* Small floating-point number. */\n"); if (sizeof(float) == 8) { fprintf(f, "typedef float app_float64; "); offset_app_float64 = sizeof(align_float) - sizeof(float); } else if (sizeof(double) == 8) { fprintf(f, "typedef double app_float64; "); offset_app_float64 = sizeof(align_double) - sizeof(double); } else if (sizeof(long double) == 8) { fprintf(f, "typedef long double app_float64; "); offset_app_float64 = sizeof(align_long_double) - sizeof(long double); } else { /* Give up, and use double. */ fprintf(f, "typedef double app_float64; "); offset_app_float64 = sizeof(align_double) - sizeof(double); size_app_float64 = sizeof(double); } fprintf(f, "/* Large floating-point number. */\n"); /* * Print the pointer type. */ fprintf(f, "typedef void * app_pointer; "); fprintf(f, "/* Largest pointer. */\n"); fprintf(f, "\n"); offset_app_pointer = sizeof(align_pointer) - sizeof(void *); size_app_pointer = sizeof(void *); /* * Define some other common type names. */ fprintf(f, "/* Common type names: */\n"); fprintf(f, "typedef app_uint8 app_byte; "); fprintf(f, "/* 8-bit unsigned integer. */\n"); fprintf(f, "typedef app_int8 app_sbyte; "); fprintf(f, "/* 8-bit signed integer. */\n"); fprintf(f, "typedef app_int16 app_short; "); fprintf(f, "/* 16-bit signed integer. */\n"); fprintf(f, "typedef app_uint16 app_ushort; "); fprintf(f, "/* 16-bit unsigned integer. */\n"); fprintf(f, "typedef app_int32 app_int; "); fprintf(f, "/* 32-bit signed integer. */\n"); fprintf(f, "typedef app_uint32 app_uint; "); fprintf(f, "/* 32-bit unsigned integer. */\n"); fprintf(f, "typedef app_float32 app_float; "); fprintf(f, "/* 32-bit floating point number. */\n"); fprintf(f, "typedef app_float64 app_real; "); fprintf(f, "/* 64-bit floating point number. */\n"); fprintf(f, "typedef app_uint32 app_char; "); fprintf(f, "/* 32-bit Unicode Char. */\n"); fprintf(f, "\n"); /* * Write printf formats to use. */ fprintf(f, "/* The printf length modifier format strings. */\n"); if (sizeof(char) == 1) fprintf(f, "#define APP_BYTE_PRINTF_FMT \n"); else fprintf(f, "#define APP_BYTE_PRINTF_FMT ???\n"); if (sizeof(short) == 2) fprintf(f, "#define APP_SHORT_PRINTF_FMT \"h\"\n"); else fprintf(f, "#define APP_SHORT_PRINTF_FMT ???\n"); if (sizeof(int) == 4) fprintf(f, "#define APP_INT_PRINTF_FMT \n"); else if (sizeof(long) == 4) fprintf(f, "#define APP_INT_PRINTF_FMT \"l\"\n"); else if (sizeof(short) == 4) fprintf(f, "#define APP_INT_PRINTF_FMT \n"); else fprintf(f, "#define APP_INT_PRINTF_FMT ???\n"); if (sizeof(float) == 4) fprintf(f, "#define APP_FLOAT_PRINTF_FMT \n"); else if (sizeof(double) == 4) fprintf(f, "#define APP_FLOAT_PRINTF_FMT \n"); else if (sizeof(long double) == 4) fprintf(f, "#define APP_FLOAT_PRINTF_FMT \"L\"\n"); else fprintf(f, "#define APP_FLOAT_PRINTF_FMT \n"); if (sizeof(float) == 8) fprintf(f, "#define APP_REAL_PRINTF_FMT \n"); else if (sizeof(double) == 8) fprintf(f, "#define APP_REAL_PRINTF_FMT \n"); else if (sizeof(long double) == 8) fprintf(f, "#define APP_REAL_PRINTF_FMT \"L\"\n"); else fprintf(f, "#define APP_REAL_PRINTF_FMT \n"); fprintf(f, "\n"); /* * Write scanf formats to use. */ fprintf(f, "/* The scanf length modifier format strings. */\n"); if (sizeof(char) == 1) fprintf(f, "#define APP_BYTE_SCANF_FMT \n"); else fprintf(f, "#define APP_BYTE_SCANF_FMT ???\n"); if (sizeof(short) == 2) fprintf(f, "#define APP_SHORT_SCANF_FMT \"h\"\n"); else fprintf(f, "#define APP_SHORT_SCANF_FMT ???\n"); if (sizeof(int) == 4) fprintf(f, "#define APP_INT_SCANF_FMT \n"); else if (sizeof(long) == 4) fprintf(f, "#define APP_INT_SCANF_FMT \"l\"\n"); else if (sizeof(short) == 4) fprintf(f, "#define APP_INT_SCANF_FMT \n"); else fprintf(f, "#define APP_INT_SCANF_FMT ???\n"); if (sizeof(float) == 4) fprintf(f, "#define APP_FLOAT_SCANF_FMT \n"); else if (sizeof(double) == 4) fprintf(f, "#define APP_FLOAT_SCANF_FMT \"l\"\n"); else if (sizeof(long double) == 4) fprintf(f, "#define APP_FLOAT_SCANF_FMT \"L\"\n"); else fprintf(f, "#define APP_FLOAT_SCANF_FMT \n"); if (sizeof(float) == 8) fprintf(f, "#define APP_REAL_SCANF_FMT \n"); else if (sizeof(double) == 8) fprintf(f, "#define APP_REAL_SCANF_FMT \"l\"\n"); else if (sizeof(long double) == 8) fprintf(f, "#define APP_REAL_SCANF_FMT \"L\"\n"); else fprintf(f, "#define APP_REAL_SCANF_FMT \"l\"\n"); fprintf(f, "\n"); /* * Print type-sizes. */ fprintf(f, "/* Type sizes (in bytes). */\n"); fprintf(f, "enum {\n"); fprintf(f, "\tAPP_BYTE_SIZE = 1,\n"); fprintf(f, "\tAPP_SHORT_SIZE = 2,\n"); fprintf(f, "\tAPP_INT_SIZE = 4,\n"); fprintf(f, "\tAPP_FLOAT_SIZE = %d,\n", size_app_float32); fprintf(f, "\tAPP_REAL_SIZE = %d,\n", size_app_float64); fprintf(f, "\tAPP_POINTER_SIZE = %d\n", size_app_pointer); fprintf(f, "};\n\n"); /* * Write alignment specifiers, by examining struct offsets. */ fprintf(f, "/* Type packing alignment within structures. */\n"); fprintf(f, "enum {\n"); fprintf(f, "\tAPP_BYTE_PACKING = %d,\n", offset_app_int8); fprintf(f, "\tAPP_SHORT_PACKING = %d,\n", offset_app_int16); fprintf(f, "\tAPP_INT_PACKING = %d,\n", offset_app_int32); fprintf(f, "\tAPP_FLOAT_PACKING = %d,\n", offset_app_float32); fprintf(f, "\tAPP_REAL_PACKING = %d,\n", offset_app_float64); fprintf(f, "\tAPP_POINTER_PACKING = %d,\n", offset_app_pointer); offset_maximum = offset_app_int8; if (offset_maximum < offset_app_int16) offset_maximum = offset_app_int16; if (offset_maximum < offset_app_int32) offset_maximum = offset_app_int32; if (offset_maximum < offset_app_float32) offset_maximum = offset_app_float32; if (offset_maximum < offset_app_float64) offset_maximum = offset_app_float64; if (offset_maximum < offset_app_pointer) offset_maximum = offset_app_pointer; fprintf(f, "\tAPP_MAXIMUM_PACKING = %d\n", offset_maximum); fprintf(f, "};\n\n"); /* * Write arithmetic limits. Note, these are fixed. */ fprintf(f, "/* Arithmetic limits. */\n"); fprintf(f, "#define APP_BYTE_MIN (0)\n"); fprintf(f, "#define APP_BYTE_MAX (255)\n"); fprintf(f, "#define APP_SBYTE_MIN (-128)\n"); fprintf(f, "#define APP_SBYTE_MAX (127)\n"); fprintf(f, "\n"); fprintf(f, "#define APP_SHORT_MIN (-32768)\n"); fprintf(f, "#define APP_SHORT_MAX (32767)\n"); fprintf(f, "#define APP_USHORT_MIN (0)\n"); fprintf(f, "#define APP_USHORT_MAX (65535)\n"); fprintf(f, "\n"); if ((sizeof(int) != 4) && (sizeof(long) == 4)) { fprintf(f, "#define APP_INT_MIN (-2147483648L)\n"); fprintf(f, "#define APP_INT_MAX (2147483647L)\n"); fprintf(f, "#define APP_UINT_MIN (0UL)\n"); fprintf(f, "#define APP_UINT_MAX (4294967295UL)\n"); fprintf(f, "\n"); fprintf(f, "#define APP_CHAR_MIN (0UL)\n"); fprintf(f, "#define APP_CHAR_MAX (4294967295UL)\n"); } else { fprintf(f, "#define APP_INT_MIN (-2147483648)\n"); fprintf(f, "#define APP_INT_MAX (2147483647)\n"); fprintf(f, "#define APP_UINT_MIN (0)\n"); fprintf(f, "#define APP_UINT_MAX (4294967295)\n"); fprintf(f, "\n"); fprintf(f, "#define APP_CHAR_MIN (0)\n"); fprintf(f, "#define APP_CHAR_MAX (4294967295)\n"); } fprintf(f, "\n"); /* * Close the file and finish. */ fclose(f); return 0; }