diff options
Diffstat (limited to 'src/mkhdr.c')
-rw-r--r-- | src/mkhdr.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/mkhdr.c b/src/mkhdr.c new file mode 100644 index 0000000..f281d64 --- /dev/null +++ b/src/mkhdr.c @@ -0,0 +1,222 @@ +#include "config.h" + +#ifdef HAVE_BROKEN_INCLUDES +#define _ANSI_C_SOURCE +#define _POSIX_SOURCE +#endif + +#include <stdio.h> + +extern void exit(int status); +extern int fclose(FILE *stream); + +#ifndef TRUE +#define TRUE (1 == 1) +#endif + +#ifndef FALSE +#define FALSE (1 != 1) +#endif + +struct description_int +{ + int int_size; + char int_name[20]; +}; +struct description_int int_descrs[] = +{ +#ifdef LONGLONG + { sizeof(unsigned long long), "unsigned long long" }, +#endif + { sizeof(unsigned long), "unsigned long" }, + { sizeof(unsigned int), "unsigned int" }, + { sizeof(unsigned short), "unsigned short" }, + { sizeof(unsigned char), "unsigned char" } +}; +int size_count = sizeof(int_descrs) / sizeof(struct description_int); + +struct trnc_data +{ + long a, b, q, r; +}; +struct trnc_data trunc_tbl[] = +{ + { 13, 4, 3, 1 }, + { 13, -4, -3, 1 }, + { -13, 4, -3, -1 }, + { -13, -4, 3, -1 }, + { 15, 4, 3, 3 }, + { 15, -4, -3, 3 }, + { -15, 4, -3, -3 }, + { -15, -4, 3, -3 } +}; +int size_trunc_tbl = sizeof(trunc_tbl) / sizeof(struct trnc_data); + +struct rand_data +{ + unsigned long dig_size, a1, c1, a2, c2; +}; +struct rand_data rand_tbl[] = +{ + { 8, 197, 11, 37, 37 }, + { 16, 805, 345, 925, 767 }, + { 18, 13405, 4801, 20325, 19777 }, + { 32, 13405, 4801, 20325, 19777 } +}; +int size_rand_tbl = sizeof(rand_tbl) / sizeof(struct rand_data); + +int digit_bits; + +int +div_trunc_p(void) +{ + int i; + + for (i = 0; i < size_trunc_tbl; i++) + { + if (trunc_tbl[i].a / trunc_tbl[i].b != trunc_tbl[i].q) + { + printf("%ld / %ld = %ld, should have been %ld\n", + trunc_tbl[i].a, + trunc_tbl[i].b, + trunc_tbl[i].a / trunc_tbl[i].b, + trunc_tbl[i].q); + printf("when division truncates towards zero.\n"); + return FALSE; + } + if (trunc_tbl[i].a % trunc_tbl[i].b != trunc_tbl[i].r) + { + printf("%ld %% %ld = %ld, should have been %ld\n", + trunc_tbl[i].a, + trunc_tbl[i].b, + trunc_tbl[i].a % trunc_tbl[i].b, + trunc_tbl[i].r); + printf("when division truncates towards zero.\n"); + printf("Here a != q*b + r. Very strange!\n"); + return FALSE; + } + } + return TRUE; +} + +int +charsize(void) +{ + int i = 0; + unsigned char ch = 1; + unsigned char oldch = 0; + + while (ch > oldch) + { + oldch = ch; + ch <<= 1; + i++; + } + return i; +} + +void +RandDefsOut(FILE *fpOut, int dig_size) +{ + int i = 0; + + while ((i < size_rand_tbl) && (dig_size != (int)rand_tbl[i].dig_size)) + { + i++; + } + if (i == size_rand_tbl) + { + if (dig_size < (int) rand_tbl[0].dig_size) + { + printf("Digit size %d too small.\n", dig_size); + exit(10); + } + while ((int) rand_tbl[--i].dig_size > dig_size) + { + /* Count down `i' */ + } + } + fprintf(fpOut, "\n#define BIG_RAND_A1 %ld\n", rand_tbl[i].a1); + fprintf(fpOut, "#define BIG_RAND_C1 %ld\n", rand_tbl[i].c1); + fprintf(fpOut, "#define BIG_RAND_A2 %ld\n", rand_tbl[i].a2); + fprintf(fpOut, "#define BIG_RAND_C2 %ld\n", rand_tbl[i].c2); +} + +int +main(void) +{ + int i, j = 0, ints_found = FALSE, char_bits; + FILE *fpOut; + + if (!div_trunc_p()) + { + printf("Can't do division on this machine!\n"); + exit(10); + } + + if ((fpOut = fopen("internal.h", "w")) == NULL) + { + printf("Could not create \"internal.h\".\n"); + exit(10); + } + + fprintf(fpOut, "#ifndef _BIGNUM_INTERNAL_H_\n"); + fprintf(fpOut, "#define _BIGNUM_INTERNAL_H_\n\n"); + + char_bits = charsize(); + + for (i = 0; (i < size_count - 1) && !ints_found; i++) + { + for (j = i + 1; (j < size_count) && !ints_found; j++) + { + if (int_descrs[i].int_size >= 2 * int_descrs[j].int_size) + { + fprintf(fpOut, + "#define BIGNUM_DIGIT %s\n", + int_descrs[j].int_name); + fprintf(fpOut, + "#define BIGNUM_TWO_DIGITS %s\n\n", + int_descrs[i].int_name); + ints_found = TRUE; + } + } + } + + if (!ints_found) + { + fprintf(stderr, "Strange, no integer type was two times bigger "); + fprintf(stderr, "than another integer type.\n"); + fprintf(stderr, "Can't create header file.\nExiting.\n"); + exit(10); + } + + if (i > 0) i--; + if (j > 0) j--; + + digit_bits = char_bits * int_descrs[j].int_size; + fprintf(fpOut, "#define BIG_CHARBITS %d\n", char_bits); + fprintf(fpOut, "#define BIGNUM_DIGIT_BITS %d\n", digit_bits); + fprintf(fpOut, "#define BIGNUM_TWO_DIGITS_BITS %d\n\n", + char_bits * int_descrs[i].int_size); + + fprintf(fpOut, "struct big_struct\n{\n int sign;\n"); + fprintf(fpOut, " unsigned long dgs_alloc;\n"); + fprintf(fpOut, " unsigned long dgs_used;\n"); + fprintf(fpOut, " BIGNUM_DIGIT *dp;\n};\n"); + + RandDefsOut(fpOut, char_bits * int_descrs[j].int_size); + + if (sizeof(long) == sizeof(int)) + { + fprintf(fpOut, "\n#define MEMCPY_LONG_COUNTER\n"); + } + +#ifdef BIG_SHORT_NAMES + fprintf(fpOut, "\n#define BIG_SHORT_NAMES\n"); +#endif + + fprintf(fpOut, "\n#endif\n"); + fclose(fpOut); + exit(0); + return 0; /* Keep gcc from complaining */ +} |