X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Fstrcalc.c;h=b012b7479694ae7b1460d1bc604b68212786d884;hb=2d09549421b49587d4680a94dab277646e9fef44;hp=8cb4268eb43c935693eb7462537ab65c418accf8;hpb=d1c8d32451932715b5fc072fb1e9fed15c96a4c5;p=libfirm diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index 8cb4268eb..b012b7479 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -1,49 +1,76 @@ -/****i* strcalc/implementation - * - * AUTHORS - * Matthias Heil - * - * NOTES - ******/ +/* + * Project: libFIRM + * File name: ir/tv/strcalc.c + * Purpose: + * Author: Mathias Heil + * Modified by: + * Created: + * CVS-ID: $Id$ + * Copyright: (c) 2003 Universität Karlsruhe + * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include /* assertions */ -#include /* memset/memcmp */ #include "strcalc.h" -#include /* output for error messages */ #include +#ifdef HAVE_ALLOCA_H +# include +#endif +#ifdef HAVE_MALLOC_H +# include +#endif +#include /* assertions */ +#include /* memset/memcmp */ +#include /* output for error messages */ +#include /* definition of LONG_MIN, used in sc_get_val_from_long */ /* * local definitions and macros */ -#define CLEAR_CALC_BUFFER() assert(calc_buffer); memset(calc_buffer, SC_0, CALC_BUFFER_SIZE) +#define CLEAR_BUFFER(b) assert(b); memset(b, SC_0, CALC_BUFFER_SIZE) #define _val(a) ((a)-SC_0) #define _digit(a) ((a)+SC_0) #define _bitisset(digit, pos) (and_table[_val(digit)][_val(shift_table[pos])] != SC_0) #define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__, __LINE__) -#ifdef STRCALC_DEBUG - /* shortcut output for debugging only, gices always full precisition */ +/* shortcut output for debugging */ # define sc_print_hex(a) sc_print((a), 0, SC_HEX) # define sc_print_dec(a) sc_print((a), 0, SC_DEC) # define sc_print_oct(a) sc_print((a), 0, SC_OCT) # define sc_print_bin(a) sc_print((a), 0, SC_BIN) + +#ifdef STRCALC_DEBUG_PRINTCOMP +# define DEBUGPRINTF_COMPUTATION(x) printf x +#else +# define DEBUGPRINTF_COMPUTATION(x) ((void)0) +#endif +#ifdef STRCALC_DEBUG # define DEBUGPRINTF(x) printf x #else # define DEBUGPRINTF(x) ((void)0) #endif + /* * private variables */ static char *calc_buffer = NULL; /* buffer holding all results */ static char *output_buffer = NULL; /* buffer for output */ -static int BIT_PATTERN_SIZE; -static int CALC_BUFFER_SIZE; -static int MAX_VALUE_SIZE; +static int BIT_PATTERN_SIZE; /* maximum number of bits */ +static int CALC_BUFFER_SIZE; /* size of internally stored values */ +static int MAX_VALUE_SIZE; /* maximum size of values */ + +static int carry_flag; /* some computation set carry_flag: */ + /* rightshift if bits were lost due to shifting */ + /* division if there was a remainder */ static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 }; static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 }; @@ -94,7 +121,7 @@ static const char and_table[16][16] = { SC_8, SC_8, SC_8, SC_8, SC_C, SC_C, SC_C, SC_C }, { SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5, - SC_8, SC_9, SC_8, SC_9, SC_D, SC_E, SC_D, SC_E }, + SC_8, SC_9, SC_8, SC_9, SC_C, SC_D, SC_C, SC_D }, { SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6, SC_8, SC_8, SC_A, SC_A, SC_C, SC_C, SC_E, SC_E }, @@ -469,8 +496,8 @@ static void _inc(char *val, char *buffer) return; } } - /* here a carry could be lost, this is intended because this will only - * happen when a value changes sign. */ + /* here a carry could be lost, this is intended because this should + * happen only when a value changes sign. */ } static void _negate(const char *val, char *buffer) @@ -493,20 +520,24 @@ static void _add(const char *val1, const char *val2, char *buffer) buffer[counter] = add2[0]; carry = add_table[_val(add1[1])][_val(add2[1])][0]; } - /* loose last carry, which will occur only when changing sign */ + carry_flag = carry != SC_0; } static void _mul(const char *val1, const char *val2, char *buffer) { - char temp_buffer[CALC_BUFFER_SIZE]; /* result buffer */ - char neg_val1[CALC_BUFFER_SIZE]; /* abs of val1 */ - char neg_val2[CALC_BUFFER_SIZE]; /* abs of val2 */ + char* temp_buffer; /* result buffer */ + char* neg_val1; /* abs of val1 */ + char* neg_val2; /* abs of val2 */ const char *mul, *add1, *add2; /* intermediate result containers */ char carry = SC_0; /* container for carries */ char sign = 0; /* marks result sign */ int c_inner, c_outer; /* loop counters */ + temp_buffer = alloca(CALC_BUFFER_SIZE); + neg_val1 = alloca(CALC_BUFFER_SIZE); + neg_val2 = alloca(CALC_BUFFER_SIZE); + /* init result buffer to zeroes */ memset(temp_buffer, SC_0, CALC_BUFFER_SIZE); @@ -559,6 +590,7 @@ static void _mul(const char *val1, const char *val2, char *buffer) /* A carry may hang over */ /* c_outer is always smaller than MAX_VALUE_SIZE! */ temp_buffer[MAX_VALUE_SIZE + c_outer] = carry; + carry = SC_0; } } @@ -570,7 +602,8 @@ static void _mul(const char *val1, const char *val2, char *buffer) static void _sub(const char *val1, const char *val2, char *buffer) { - char temp_buffer[CALC_BUFFER_SIZE]; /* intermediate buffer to hold -val2 */ + char *temp_buffer; /* intermediate buffer to hold -val2 */ + temp_buffer = alloca(CALC_BUFFER_SIZE); _negate(val2, temp_buffer); _add(val1, temp_buffer, buffer); @@ -591,22 +624,26 @@ static void _push(const char digit, char *buffer) static void _divmod(const char *dividend, const char *divisor, char *quot, char *rem) { const char *minus_divisor; - char neg_val1[CALC_BUFFER_SIZE]; - char neg_val2[CALC_BUFFER_SIZE]; + char *neg_val1; + char *neg_val2; char sign = 0; /* remember result sign */ int c_dividend; /* loop counters */ + neg_val1 = alloca(CALC_BUFFER_SIZE); + neg_val2 = alloca(CALC_BUFFER_SIZE); + /* clear result buffer */ memset(quot, SC_0, CALC_BUFFER_SIZE); memset(rem, SC_0, CALC_BUFFER_SIZE); + /* if the divisor is zero this won't work (quot is zero) */ + if (sc_comp(divisor, quot) == 0) assert(0 && "division by zero!"); + /* if the dividend is zero result is zero (quot is zero)*/ if (sc_comp(dividend, quot) == 0) return; - /* if the divisor is zero this won't work (quot is zero) */ - if (sc_comp(divisor, quot) == 0) assert(0 && "division by zero!"); if (_sign(dividend) == -1) { @@ -627,7 +664,7 @@ static void _divmod(const char *dividend, const char *divisor, char *quot, char minus_divisor = neg_val2; } - /* if divisor >= dividend quotision is easy + /* if divisor >= dividend division is easy * (remember these are absolute values) */ switch (sc_comp(dividend, divisor)) { @@ -639,11 +676,11 @@ static void _divmod(const char *dividend, const char *divisor, char *quot, char memcpy(rem, dividend, CALC_BUFFER_SIZE); return; - default: /* unluckily quotision is necessary :( */ + default: /* unluckily division is necessary :( */ break; } - for (c_dividend = MAX_VALUE_SIZE - 1; c_dividend >= 0; c_dividend--) + for (c_dividend = CALC_BUFFER_SIZE - 1; c_dividend >= 0; c_dividend--) { _push(dividend[c_dividend], rem); _push(SC_0, quot); @@ -665,6 +702,8 @@ static void _divmod(const char *dividend, const char *divisor, char *quot, char } } + carry_flag = !sc_is_zero(rem); + if (sign) { _negate(quot, quot); @@ -760,6 +799,9 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign /* if shifting far enough the result is either 0 or -1 */ if (offset >= radius) { + if (!sc_is_zero(val1)) { + carry_flag = 1; + } memset(buffer, sign, CALC_BUFFER_SIZE); return; } @@ -767,16 +809,27 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign shift = offset % 4; offset = offset / 4; + /* check if any bits are lost, and set carry_flag if so */ + for (counter = 0; counter < offset; counter++) + { + if (val1[counter] != 0) + { + carry_flag = 1; + break; + } + } + if ((_val(val1[counter]) & ((1< 0) { buffer[counter] = shrs_table[_val(val1[offset])][shift][0]; counter = 1; } - - /* shift digits to the right with offset, carry and all */ for (; counter < radius/4 - offset; counter++) { - shrs = shrs_table[_val(val1[counter + offset])][shift]; buffer[counter] = shrs[0]; buffer[counter-1] = or_table[_val(buffer[counter-1])][_val(shrs[1])]; @@ -784,7 +837,7 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign /* the last digit is special in regard of signed/unsigned shift */ bitoffset = radius%4; - msd = val1[radius/4]; /* most significant digit */ + msd = (radius/4 0) buffer[counter - 1] = or_table[_val(buffer[counter-1])][_val(shrs[1])]; /* fill with SC_F or SC_0 depending on sign */ @@ -811,15 +865,9 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign /* positive: low-order -> high order, negative other direction */ static void _rot(const char *val1, char *buffer, long offset, int radius, unsigned is_signed) { - char temp1[CALC_BUFFER_SIZE]; - char temp2[CALC_BUFFER_SIZE]; - - const char *shl; - char carry = SC_0; - - int counter, old_counter; - int shift; - int bitoffset; + char *temp1, *temp2; + temp1 = alloca(CALC_BUFFER_SIZE); + temp2 = alloca(CALC_BUFFER_SIZE); offset = offset % radius; @@ -832,6 +880,7 @@ static void _rot(const char *val1, char *buffer, long offset, int radius, unsign _shl(val1, temp1, offset, radius, is_signed); _shr(val1, temp2, radius - offset, radius, is_signed, 0); _bitor(temp1, temp2, buffer); + carry_flag = 0; /* set by shr, but due to rot this is false */ } /***************************************************************************** @@ -848,21 +897,25 @@ const int sc_get_buffer_length(void) } /* XXX doesn't check for overflows */ -void sc_val_from_str(const char *str, unsigned int len) +void sc_val_from_str(const char *str, unsigned int len, void *buffer) { const char *orig_str = str; unsigned int orig_len = len; char sign = 0; - char base[CALC_BUFFER_SIZE]; - char val[CALC_BUFFER_SIZE]; + char *base, *val; + + base = alloca(CALC_BUFFER_SIZE); + val = alloca(CALC_BUFFER_SIZE); /* verify valid pointers (not null) */ assert(str); /* a string no characters long is an error */ assert(len); - CLEAR_CALC_BUFFER(); + if (buffer == NULL) buffer = calc_buffer; + + CLEAR_BUFFER(buffer); memset(base, SC_0, CALC_BUFFER_SIZE); memset(val, SC_0, CALC_BUFFER_SIZE); @@ -918,7 +971,7 @@ void sc_val_from_str(const char *str, unsigned int len) base[1] = SC_0; base[0] = SC_A; } - /* begin string evaluation, from left to right */ + /* BEGIN string evaluation, from left to right */ while (len > 0) { switch (*str) @@ -992,26 +1045,54 @@ void sc_val_from_str(const char *str, unsigned int len) } } -void sc_val_from_long(long value) +void sc_val_from_long(long value, void *buffer) { char *pos; - int sign; + char sign, is_minlong; + + if (buffer == NULL) buffer = calc_buffer; + pos = buffer; - pos = calc_buffer; sign = (value < 0); + is_minlong = value == LONG_MIN; - /* FIXME MININT won't work */ - if (sign) value = -value; + /* use absolute value, special treatment of MIN_LONG */ + if (sign) { + if (is_minlong) + value = -(value+1); + else + value = -value; + } - CLEAR_CALC_BUFFER(); + CLEAR_BUFFER(buffer); - while ((value != 0) && (pos < calc_buffer + CALC_BUFFER_SIZE)) + while ((value != 0) && (pos < (char*)buffer + CALC_BUFFER_SIZE)) { - *pos++ = _digit(value % 16); - value /= 16; + *pos++ = _digit(value & 0xf); + value >>= 4; + } + + + if (sign) { + if (is_minlong) + _inc(buffer, buffer); + + _negate(buffer, buffer); } +} + +void sc_val_from_ulong(unsigned long value, void *buffer) +{ + char *pos; - if (sign) _negate(calc_buffer, calc_buffer); + if (buffer == NULL) buffer = calc_buffer; + pos = buffer; + + while (pos < (char*)buffer + CALC_BUFFER_SIZE) + { + *pos++ = _digit(value & 0xf); + value >>= 4; + } } long sc_val_to_long(const void *val) @@ -1026,15 +1107,17 @@ long sc_val_to_long(const void *val) return l; } -void sc_min_from_bits(unsigned int num_bits, unsigned int sign) +void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) { char* pos; int i, bits; - CLEAR_CALC_BUFFER(); + if (buffer == NULL) buffer = calc_buffer; + CLEAR_BUFFER(buffer); + if (!sign) return; /* unsigned means minimum is 0(zero) */ - pos = calc_buffer; + pos = buffer; bits = num_bits - 1; for (i = 0; i < bits/4; i++) @@ -1046,13 +1129,14 @@ void sc_min_from_bits(unsigned int num_bits, unsigned int sign) *pos++ = SC_F; } -void sc_max_from_bits(unsigned int num_bits, unsigned int sign) +void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) { char* pos; int i, bits; - CLEAR_CALC_BUFFER(); - pos = calc_buffer; + if (buffer == NULL) buffer = calc_buffer; + CLEAR_BUFFER(buffer); + pos = buffer; bits = num_bits - sign; for (i = 0; i < bits/4; i++) @@ -1064,96 +1148,110 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign) *pos++ = SC_0; } -void sc_calc(const void* value1, const void* value2, unsigned op) +void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer) { - char unused_res[CALC_BUFFER_SIZE]; /* temp buffer holding unused result of divmod */ + char *unused_res; /* temp buffer holding unused result of divmod */ const char *val1 = (const char *)value1; const char *val2 = (const char *)value2; - CLEAR_CALC_BUFFER(); - DEBUGPRINTF(("%s ", sc_print(value1, SC_HEX))); + unused_res = alloca(CALC_BUFFER_SIZE); + CLEAR_BUFFER(calc_buffer); + carry_flag = 0; + + DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1))); switch (op) { case SC_NEG: _negate(val1, calc_buffer); - DEBUGPRINTF(("negated: %s\n", sc_print_hex(calc_buffer))); - return; + DEBUGPRINTF_COMPUTATION(("negated: %s\n", sc_print_hex(calc_buffer))); + break; case SC_OR: - DEBUGPRINTF(("| ")); + DEBUGPRINTF_COMPUTATION(("| ")); _bitor(val1, val2, calc_buffer); break; case SC_AND: - DEBUGPRINTF(("& ")); + DEBUGPRINTF_COMPUTATION(("& ")); _bitand(val1, val2, calc_buffer); break; case SC_XOR: - DEBUGPRINTF(("^ ")); + DEBUGPRINTF_COMPUTATION(("^ ")); _bitxor(val1, val2, calc_buffer); break; case SC_NOT: _bitnot(val1, calc_buffer); - DEBUGPRINTF(("bit-negated: %s\n", sc_print_hex(calc_buffer))); - return; + DEBUGPRINTF_COMPUTATION(("bit-negated: %s\n", sc_print_hex(calc_buffer))); + break; case SC_ADD: - DEBUGPRINTF(("+ ")); + DEBUGPRINTF_COMPUTATION(("+ ")); _add(val1, val2, calc_buffer); break; case SC_SUB: - DEBUGPRINTF(("- ")); + DEBUGPRINTF_COMPUTATION(("- ")); _sub(val1, val2, calc_buffer); break; case SC_MUL: - DEBUGPRINTF(("* ")); + DEBUGPRINTF_COMPUTATION(("* ")); _mul(val1, val2, calc_buffer); break; case SC_DIV: - DEBUGPRINTF(("/ ")); + DEBUGPRINTF_COMPUTATION(("/ ")); _divmod(val1, val2, calc_buffer, unused_res); break; case SC_MOD: - DEBUGPRINTF(("%% ")); + DEBUGPRINTF_COMPUTATION(("%% ")); _divmod(val1, val2, unused_res, calc_buffer); break; default: assert(0); } - DEBUGPRINTF(("%s -> ", sc_print_hex(value2))); - DEBUGPRINTF(("%s\n", sc_print_hex(calc_buffer))); + DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2))); + DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer))); + + if ((buffer != NULL) && (buffer != calc_buffer)) + { + memcpy(buffer, calc_buffer, CALC_BUFFER_SIZE); + } } -void sc_bitcalc(const void* value1, const void* value2, int radius, int sign, unsigned op) +void sc_bitcalc(const void* value1, const void* value2, int radius, int sign, unsigned op, void* buffer) { const char *val1 = (const char *)value1; const char *val2 = (const char *)value2; long offset; + carry_flag = 0; offset = sc_val_to_long(val2); - DEBUGPRINTF(("%s ", sc_print_hex(value1))); + DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1))); switch (op) { case SC_SHL: - DEBUGPRINTF(("<< %d ", offset)); + DEBUGPRINTF_COMPUTATION(("<< %ld ", offset)); _shl(val1, calc_buffer, offset, radius, sign); break; case SC_SHR: - DEBUGPRINTF((">> %d ", offset)); + DEBUGPRINTF_COMPUTATION((">> %ld ", offset)); _shr(val1, calc_buffer, offset, radius, sign, 0); break; case SC_SHRS: - DEBUGPRINTF((">>> %d ", offset)); + DEBUGPRINTF_COMPUTATION((">>> %ld ", offset)); _shr(val1, calc_buffer, offset, radius, sign, 1); break; case SC_ROT: - DEBUGPRINTF(("<<>> %d ", offset)); + DEBUGPRINTF_COMPUTATION(("<<>> %ld ", offset)); _rot(val1, calc_buffer, offset, radius, sign); break; default: assert(0); } - DEBUGPRINTF(("-> %s\n", sc_print_hex(calc_buffer))); + DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer))); + + if ((buffer != NULL) && (buffer != calc_buffer)) + { + memmove(buffer, calc_buffer, CALC_BUFFER_SIZE); + } } int sc_comp(const void* value1, const void* value2) @@ -1184,9 +1282,8 @@ int sc_get_highest_set_bit(const void *value) { const char *val = (const char*)value; int high, counter; - char sign; - high = CALC_BUFFER_SIZE * 4; + high = CALC_BUFFER_SIZE * 4 - 1; for (counter = CALC_BUFFER_SIZE-1; counter >= 0; counter--) { if (val[counter] == SC_0) high -= 4; @@ -1218,7 +1315,28 @@ int sc_get_lowest_set_bit(const void *value) else return low + 3; } } - return low; + return -1; +} + +int sc_is_zero(const void *value) +{ + const char* val = (const char *)value; + int counter; + + for (counter = 0; counter < CALC_BUFFER_SIZE; counter++) { + if (val[counter] != SC_0) return 0; + } + return 1; +} + +int sc_is_negative(const void *value) +{ + return _sign(value) == -1; +} + +int sc_had_carry(void) +{ + return carry_flag; } unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) @@ -1240,16 +1358,14 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) /* * convert to a string + * XXX Doesn't check buffer bounds */ const char *sc_print(const void *value, unsigned bits, enum base_t base) { static const char big_digits[] = "0123456789ABCDEF"; static const char small_digits[] = "0123456789abcdef"; - char base_val[CALC_BUFFER_SIZE]; - char div1_res[CALC_BUFFER_SIZE]; - char div2_res[CALC_BUFFER_SIZE]; - char rem_res[CALC_BUFFER_SIZE]; + char *base_val, *div1_res, *div2_res, *rem_res; int counter, nibbles, i, sign; char x; @@ -1259,21 +1375,34 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) char *pos; const char *digits = small_digits; + base_val = alloca(CALC_BUFFER_SIZE); + div1_res = alloca(CALC_BUFFER_SIZE); + div2_res = alloca(CALC_BUFFER_SIZE); + rem_res = alloca(CALC_BUFFER_SIZE); + pos = output_buffer + BIT_PATTERN_SIZE; - *pos = '\0'; + *(--pos) = '\0'; /* special case */ - if (bits == 0) + if (bits == 0) { bits = BIT_PATTERN_SIZE; - +#ifdef STRCALC_DEBUG_FULLPRINT + bits <<= 1; +#endif + } nibbles = bits >> 2; switch (base) { case SC_HEX: digits = big_digits; case SC_hex: - for (counter = 0; counter < nibbles; ++counter) + for (counter = 0; counter < nibbles; ++counter) { *(--pos) = digits[_val(val[counter])]; +#ifdef STRCALC_DEBUG_GROUPPRINT + if ((counter+1)%8 == 0) + *(--pos) = ' '; +#endif + } /* last nibble must be masked */ if (bits & 3) { @@ -1282,9 +1411,13 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) } /* now kill zeros */ - for (; counter > 1; --counter, ++pos) + for (; counter > 1; --counter, ++pos) { +#ifdef STRCALC_DEBUG_GROUPPRINT + if (pos[0] == ' ') ++pos; +#endif if (pos[0] != '0') break; + } break; case SC_BIN: @@ -1364,34 +1497,44 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) break; default: + printf("%i\n", base); assert(0); return NULL; } return pos; } -void init_strcalc(int precision_in_bytes) +void init_strcalc(int precision) { if (calc_buffer == NULL) { - if (precision_in_bytes <= 0) precision_in_bytes = DEFAULT_PRECISION_IN_BYTES; + if (precision <= 0) precision = SC_DEFAULT_PRECISION; - BIT_PATTERN_SIZE = (8 * precision_in_bytes); - CALC_BUFFER_SIZE = (4 * precision_in_bytes); - MAX_VALUE_SIZE = (2 * precision_in_bytes); + /* round up to multiple of 4 */ + precision = (precision + 3) & ~3; - calc_buffer = malloc(CALC_BUFFER_SIZE * sizeof(char)); - output_buffer = malloc(BIT_PATTERN_SIZE * sizeof(char)); + BIT_PATTERN_SIZE = (precision); + CALC_BUFFER_SIZE = (precision / 2); + MAX_VALUE_SIZE = (precision / 4); - if (calc_buffer == NULL || output_buffer == NULL) - { + calc_buffer = malloc(CALC_BUFFER_SIZE+1 * sizeof(char)); + output_buffer = malloc(BIT_PATTERN_SIZE+1 * sizeof(char)); + + if (calc_buffer == NULL || output_buffer == NULL) { assert(0 && "malloc failed"); exit(-1); } - DEBUGPRINTF(("init strcalc: \n\tPRECISION: %d\n\tCALC_BUFFER_SIZE = %d\n\tMAX_VALUE_SIZE = %d\n\tbuffer pointer: %p\n", precision_in_bytes, CALC_BUFFER_SIZE, MAX_VALUE_SIZE, calc_buffer)); + DEBUGPRINTF(("init strcalc: \n\tPRECISION: %d\n\tCALC_BUFFER_SIZE = %d\n\tMAX_VALUE_SIZE = %d\n\tbuffer pointer: %p\n", precision, CALC_BUFFER_SIZE, MAX_VALUE_SIZE, calc_buffer)); } } -int get_precision() + + +void finish_strcalc() { + free(calc_buffer); calc_buffer = NULL; + free(output_buffer); output_buffer = NULL; +} + +int sc_get_precision(void) { - return CALC_BUFFER_SIZE/4; + return BIT_PATTERN_SIZE; }