Code:
int func_rdChar32( char32_t *dst, alu_block_t *src, long *nextpos )
{
char *str = src->block;
if ( (size_t)(*nextpos) < src->bytes.used )
{
*dst = str[*nextpos];
return 0;
}
*dst = 0;
return EOF;
}
int func_wrChar32( char32_t src, alu_block_t *dst )
{
int ret;
char *str;
if ( dst->bytes.used >= dst->bytes.last )
{
ret = alu_block_expand( dst, dst->bytes.used + 50 );
if ( ret != 0 )
return ret;
}
str = dst->block;
alu_printf( "str = '%s'", str );
str[dst->bytes.used] = src;
alu_printf( "str = '%s'", str );
dst->bytes.used++;
return 0;
}
void func_flipstr( alu_block_t *dst )
{
char *str = dst->block, c;
size_t n, v;
for ( n = 0, v = dst->bytes.used; n < v; ++n, --v )
{
c = str[n];
str[n] = str[v];
str[v] = c;
}
}
int print_value( alu_t *alu, char *num, size_t size, size_t base )
{
uint_t tmp = -1;
int ret = alu_get_reg( alu, &tmp, sizeof(size_t) );
alu_block_t src = {0};
long nextpos = 0;
if ( ret != 0 )
{
alu_error(ret);
return ret;
}
src.block = num;
src.bytes.upto = size;
src.bytes.last = size - 1;
src.bytes.used = strnlen( num, size - 1 );
alu_printf( "num = '%s'", num );
ret = alu_str2reg(
alu, &src, tmp,
(alu_func_rdChar32_t)func_rdChar32,
&nextpos,
base, false
);
if ( ret != 0 )
{
alu_error(ret);
return ret;
}
(void)memset( &src, 0, sizeof(alu_block_t) );
ret = alu_block( &src, size, 0 );
if ( ret != 0 )
{
alu_error(ret);
return ret;
}
ret = alu_reg2str(
alu, &src, tmp,
(alu_func_wrChar32_t)func_wrChar32,
(alu_func_flipstr_t)func_flipstr,
base, false
);
if ( ret != 0 )
alu_error(ret);
(void)alu_printf( "alu = '%s'", (char*)(src.block) );
alu_block_release( &src );
return ret;
}
...
int alu_str2reg
(
alu_t *alu,
void *src,
uint_t dst,
alu_func_rdChar32_t nextchar,
long *nextpos,
size_t base,
bool lowercase
)
{
size_t b, perN;
alu_reg_t *MUL, *VAL, *DST;
alu_bit_t n;
int ret;
uint_t mul = -1, val = -1;
char32_t *V, c = 0;
char *base_str = lowercase ?
ALU_BASE_STR_0toztoZ :
ALU_BASE_STR_0toZtoz;
if ( !nextpos )
return EDESTADDRREQ;
if ( *nextpos < 0 )
*nextpos = 0;
ret = alu_check1( alu, dst );
if ( ret != 0 )
return ret;
if ( !val || !nextchar )
return EADDRNOTAVAIL;
if ( base < 2 || base > strlen(base_str) )
return ERANGE;
ret = alu_get_reg( alu, &val, sizeof(size_t) );
if ( ret != 0 )
return ret;
ret = alu_get_reg( alu, &mul, sizeof(size_t) );
if ( ret != 0 )
{
alu_rem_reg( alu, val );
return ret;
}
/* Hook registers */
MUL = alu->regv + mul;
VAL = alu->regv + val;
DST = alu->regv + dst;
/* Clear all registers in direct use */
perN = alu->buff.perN;
V = MUL->part;
*V = base;
V = VAL->part;
n = DST->last;
alu_reset_reg( alu, dst, false );
memset( DST->part, 0, alu->buff.perN );
do
{
/* Failsafe if failed to get character but return code is 0 */
c = -1;
ret = nextchar( &c, src, nextpos );
if ( ret != 0 && ret != EOF )
return ret;
for ( b = 0; b < base; ++b )
{
if ( c == (char32_t)(base_str[b]) )
break;
}
if ( b == base )
break;
++(*nextpos);
if ( *(n.S) & n.B )
{
ret = alu_setup_reg(
alu, alu->buff.qty.upto, perN + sizeof(size_t)
);
if ( ret != 0 )
return ret;
(void)alu_reset_reg( alu, dst, false );
perN = alu->buff.perN;
V = VAL->part;
n = DST->last;
}
*V = c;
(void)alu_mul( alu, dst, mul );
(void)alu_add( alu, dst, val );
}
while ( ret == 0 );
alu_rem_reg( alu, mul );
alu_rem_reg( alu, val );
return 0;
}
int alu_reg2str
(
alu_t *alu,
void *dst,
uint_t src,
alu_func_wrChar32_t nextchar,
alu_func_flipstr_t flipstr,
size_t base,
bool lowercase
)
{
alu_reg_t *DIV, *VAL, *NUM;
int ret;
uint_t num = -1, div = -1, val = -1;
char32_t *V;
char *base_str = lowercase ?
ALU_BASE_STR_0toztoZ :
ALU_BASE_STR_0toZtoz;
ret = alu_check1( alu, src );
if ( ret != 0 )
return ret;
if ( !val || !nextchar || !flipstr )
return EADDRNOTAVAIL;
if ( base < 2 || base > strlen(base_str) )
return ERANGE;
ret = alu_get_reg( alu, &num, sizeof(size_t) );
if ( ret != 0 )
return ret;
ret = alu_get_reg( alu, &val, sizeof(size_t) );
if ( ret != 0 )
{
(void)alu_rem_reg( alu, num );
return ret;
}
ret = alu_get_reg( alu, &div, sizeof(size_t) );
if ( ret != 0 )
{
(void)alu_rem_reg( alu, num );
(void)alu_rem_reg( alu, val );
return ret;
}
/* Hook registers */
DIV = alu->regv + div;
VAL = alu->regv + val;
NUM = alu->regv + num;
(void)alu_mov( alu, num, src );
V = DIV->part;
*V = base;
V = VAL->part;
do
{
(void)alu_divide( alu, num, div, val );
ret = nextchar( base_str[*V], dst );
if ( ret != 0 )
return ret;
}
while ( alu_compare( *NUM, *DIV, NULL ) >= 0 );
alu_rem_reg( alu, num );
alu_rem_reg( alu, div );
alu_rem_reg( alu, val );
ret = nextchar( 0, dst );
if ( ret != 0 )
return ret;
flipstr( dst );
return 0;
}
General reminder the full code is hosted at