Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
c496fb7a
Commit
c496fb7a
authored
Feb 18, 2010
by
Matthias Braun
Browse files
some cleanups in preparation for a new tarval_from_str interface
[r27179]
parent
8eee4801
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/tv/strcalc.c
View file @
c496fb7a
...
...
@@ -45,8 +45,6 @@
#define _digit(a) ((a)+SC_0)
#define _bitisset(digit, pos) (((digit) & SHIFT(pos)) != SC_0)
#define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__, __LINE__)
/* shortcut output for debugging */
# define sc_print_hex(a) sc_print((a), 0, SC_HEX, 0)
# define sc_print_dec(a) sc_print((a), 0, SC_DEC, 1)
...
...
@@ -277,14 +275,6 @@ static const char *binary_table[16] = {
/*****************************************************************************
* private functions
*****************************************************************************/
static
void
_fail_char
(
const
char
*
str
,
size_t
len
,
const
char
fchar
,
int
pos
,
const
char
*
file
,
int
line
)
{
printf
(
"ERROR:
\n
"
);
printf
(
"Unexpected character '%c' in %s:%d
\n
"
,
fchar
,
file
,
line
);
while
(
len
--
&&
*
str
)
printf
(
"%c"
,
*
str
++
);
printf
(
"
\n
"
);
while
(
--
pos
)
printf
(
" "
);
printf
(
"^
\n
"
);
exit
(
-
1
);
}
/**
* implements the bitwise NOT operation
...
...
@@ -823,139 +813,85 @@ void sign_extend(void *buffer, ir_mode *mode)
}
}
/* FIXME doesn't check for overflows */
void
sc_val_from_str
(
const
char
*
str
,
unsigned
int
len
,
void
*
buffer
,
ir_mode
*
mode
)
/* we assume that '0'-'9', 'a'-'z' and 'A'-'Z' are a range.
* The C-standard does theoretically allow otherwise. */
static
inline
void
check_ascii
(
void
)
{
const
char
*
orig_str
=
str
;
unsigned
int
orig_len
=
len
;
assert
(
'1'
-
'0'
==
1
&&
'2'
-
'0'
==
2
&&
'3'
-
'0'
==
3
&&
'4'
-
'0'
==
4
&&
'5'
-
'0'
==
5
&&
'6'
-
'0'
==
6
&&
'7'
-
'0'
==
7
&&
'8'
-
'0'
==
8
&&
'9'
-
'0'
==
9
);
assert
(
'b'
-
'a'
==
1
&&
'c'
-
'a'
==
2
&&
'd'
-
'a'
==
3
&&
'e'
-
'a'
==
4
&&
'f'
-
'a'
==
5
);
assert
(
'B'
-
'A'
==
1
&&
'C'
-
'A'
==
2
&&
'D'
-
'A'
==
3
&&
'E'
-
'A'
==
4
&&
'F'
-
'A'
==
5
);
}
char
sign
=
0
;
char
*
base
,
*
val
;
int
sc_val_from_str
(
char
sign
,
unsigned
base
,
const
char
*
str
,
unsigned
int
len
,
void
*
buffer
)
{
char
*
sc_base
,
*
val
;
base
=
alloca
(
calc_buffer_size
);
val
=
alloca
(
calc_buffer_size
);
assert
(
sign
==
-
1
||
sign
==
1
);
assert
(
str
!=
NULL
);
assert
(
len
>
0
);
check_ascii
();
/* verify valid pointers (not null) */
assert
(
str
);
/* a string no characters long is an error */
assert
(
len
);
assert
(
base
>
1
&&
base
<=
16
);
sc_base
=
alloca
(
calc_buffer_size
);
sc_val_from_ulong
(
base
,
sc_base
);
if
(
buffer
==
NULL
)
buffer
=
calc_buffer
;
val
=
alloca
(
calc_buffer_size
);
if
(
buffer
==
NULL
)
buffer
=
calc_buffer
;
CLEAR_BUFFER
(
buffer
);
CLEAR_BUFFER
(
base
);
CLEAR_BUFFER
(
val
);
/* strip leading spaces */
while
((
len
>
0
)
&&
(
*
str
==
' '
))
{
len
--
;
str
++
;
}
/* if the first two characters are 0x or 0X -> hex
* if the first is a 0 -> oct
* else dec, strip leading -/+ and remember sign
*
* only a + or - sign is no number resulting in an error */
if
(
len
>=
2
)
{
switch
(
str
[
0
])
{
case
'0'
:
if
(
str
[
1
]
==
'x'
||
str
[
1
]
==
'X'
)
{
/* hex */
str
+=
2
;
len
-=
2
;
base
[
1
]
=
SC_1
;
base
[
0
]
=
SC_0
;
}
else
{
/* oct */
str
+=
1
;
len
-=
1
;
base
[
1
]
=
SC_0
;
base
[
0
]
=
SC_8
;
}
break
;
case
'+'
:
str
+=
1
;
len
-=
1
;
base
[
1
]
=
SC_0
;
base
[
0
]
=
SC_A
;
break
;
case
'-'
:
str
+=
1
;
len
-=
1
;
sign
=
1
;
base
[
1
]
=
SC_0
;
base
[
0
]
=
SC_A
;
break
;
default:
/* dec, else would have begun with 0x or 0 */
base
[
1
]
=
SC_0
;
base
[
0
]
=
SC_A
;
}
}
else
{
/* dec, else would have begun with 0x or 0 */
base
[
1
]
=
SC_0
;
base
[
0
]
=
SC_A
;
}
/* BEGIN string evaluation, from left to right */
while
(
len
>
0
)
{
switch
(
*
str
)
{
case
'f'
:
case
'e'
:
case
'd'
:
case
'c'
:
case
'b'
:
case
'a'
:
if
(
base
[
0
]
>
SC_A
||
base
[
1
]
>
SC_0
)
{
/* (base > 10) */
val
[
0
]
=
_digit
((
*
str
)
-
'a'
+
10
);
}
else
fail_char
(
orig_str
,
orig_len
,
*
str
,
str
-
orig_str
+
1
);
break
;
case
'F'
:
case
'E'
:
case
'D'
:
case
'C'
:
case
'B'
:
case
'A'
:
if
(
base
[
0
]
>
SC_A
||
base
[
1
]
>
SC_0
)
{
/* (base > 10) */
val
[
0
]
=
_digit
((
*
str
)
-
'A'
+
10
);
}
else
fail_char
(
orig_str
,
orig_len
,
*
str
,
str
-
orig_str
+
1
);
break
;
case
'9'
:
case
'8'
:
if
(
base
[
0
]
>
SC_8
||
base
[
1
]
>
SC_0
)
{
/* (base > 8) */
val
[
0
]
=
_digit
((
*
str
)
-
'0'
);
}
else
fail_char
(
orig_str
,
orig_len
,
*
str
,
str
-
orig_str
+
1
);
break
;
case
'7'
:
case
'6'
:
case
'5'
:
case
'4'
:
case
'3'
:
case
'2'
:
case
'1'
:
case
'0'
:
val
[
0
]
=
_digit
((
*
str
)
-
'0'
);
break
;
char
c
=
*
str
;
unsigned
v
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
v
=
c
-
'0'
;
else
if
(
c
>=
'A'
&&
c
<=
'Z'
)
v
=
c
-
'A'
;
else
if
(
c
>=
'a'
&&
c
<=
'z'
)
v
=
c
-
'z'
;
else
return
0
;
default:
fail_char
(
orig_str
,
orig_len
,
*
str
,
str
-
orig_str
+
1
)
;
}
/* switch (*str) */
if
(
v
>=
base
)
return
0
;
val
[
0
]
=
v
;
/* Radix conversion from base b to base B:
* (UnUn-1...U1U0)b == ((((Un*b + Un-1)*b + ...)*b + U1)*b + U0)B */
do_mul
(
base
,
calc_buffer
,
calc_buffer
);
/* multiply current value with base */
do_add
(
val
,
calc_buffer
,
calc_buffer
);
/* add next digit to current value */
/* multiply current value with base */
do_mul
(
sc_base
,
buffer
,
buffer
);
/* add next digit to current value */
do_add
(
val
,
buffer
,
buffer
);
/* get ready for the next letter */
str
++
;
len
--
;
}
/* while (len > 0 ) */
if
(
sign
)
do_negate
(
calc_
buffer
,
calc_
buffer
);
if
(
sign
<
0
)
do_negate
(
buffer
,
buffer
);
/* beware: even if hex numbers have no sign, we need sign extension here */
sign_extend
(
calc_buffer
,
mode
);
return
1
;
}
void
sc_val_from_long
(
long
value
,
void
*
buffer
)
...
...
ir/tv/strcalc.h
View file @
c496fb7a
...
...
@@ -191,8 +191,12 @@ int sc_get_buffer_length(void);
void
sign_extend
(
void
*
buffer
,
ir_mode
*
mode
);
/** create an value form a string representation */
void
sc_val_from_str
(
const
char
*
str
,
unsigned
int
len
,
void
*
buffer
,
ir_mode
*
mode
);
/**
* create an value form a string representation
* @return 1 if ok, 0 in case of parse error
*/
int
sc_val_from_str
(
char
sign
,
unsigned
base
,
const
char
*
str
,
unsigned
int
len
,
void
*
buffer
);
/** create a value from a long */
void
sc_val_from_long
(
long
l
,
void
*
buffer
);
...
...
ir/tv/tv.c
View file @
c496fb7a
...
...
@@ -325,6 +325,58 @@ static const ieee_descriptor_t *get_descriptor(const ir_mode *mode)
* public functions declared in tv.h
*/
static
tarval
*
new_tarval_from_str_int
(
const
char
*
str
,
size_t
len
,
ir_mode
*
mode
)
{
void
*
buffer
;
unsigned
base
=
10
;
char
sign
=
1
;
int
ok
;
/* skip leading spaces */
while
(
len
>
0
&&
str
[
0
]
==
' '
)
{
++
str
;
--
len
;
}
if
(
len
==
0
)
return
tarval_bad
;
/* 1 sign character allowed */
if
(
str
[
0
]
==
'-'
)
{
sign
=
-
1
;
++
str
;
--
len
;
}
else
if
(
str
[
0
]
==
'+'
)
{
++
str
;
--
len
;
}
/* a number starting with '0x' is hexadeciaml,
* a number starting with '0' (and at least 1 more char) is octal */
if
(
len
>=
2
&&
str
[
0
]
==
'0'
)
{
if
(
str
[
1
]
==
'x'
||
str
[
1
]
==
'X'
)
{
str
+=
2
;
len
-=
2
;
base
=
16
;
}
else
{
++
str
;
--
len
;
base
=
8
;
}
}
if
(
len
==
0
)
return
tarval_bad
;
buffer
=
alloca
(
sc_get_buffer_length
());
ok
=
sc_val_from_str
(
sign
,
base
,
str
,
len
,
buffer
);
if
(
!
ok
)
return
tarval_bad
;
sign_extend
(
buffer
,
mode
);
return
get_tarval_overflow
(
buffer
,
sc_get_buffer_length
(),
mode
);
}
/*
* Constructors =============================================================
*/
...
...
@@ -362,8 +414,7 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
return
get_tarval_null
(
mode
);
/* FALLTHROUGH */
case
irms_int_number
:
sc_val_from_str
(
str
,
len
,
NULL
,
mode
);
return
get_tarval
(
sc_get_buffer
(),
sc_get_buffer_length
(),
mode
);
return
new_tarval_from_str_int
(
str
,
len
,
mode
);
}
panic
(
"Unsupported tarval creation with mode %F"
,
mode
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment