Factorise enum set parsing code

* add a function Bool VG_(parse_enum_set) in pub_tool_libcbase.h/m_libcbase.c
  (close to Bool VG_(parse_Addr)
* Implement Bool MC_(parse_leak_heuristics) and MC_(parse_leak_kinds)
  as a call to VG_(parse_enum_set)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13898
This commit is contained in:
Philippe Waroquiers 2014-04-19 09:52:32 +00:00
parent 9cbab7ee2c
commit d17935e604
4 changed files with 100 additions and 88 deletions

View File

@ -492,6 +492,82 @@ Bool VG_(parse_Addr) ( const HChar** ppc, Addr* result )
return True;
}
Bool VG_(parse_enum_set) ( const HChar *tokens,
const HChar *input,
UInt *enum_set)
{
const SizeT tokens_len = VG_(strlen)(tokens);
if (tokens_len > 1000) return False; /* "obviously invalid" */
HChar tok_tokens[tokens_len+1];
HChar *tokens_saveptr;
HChar *token;
UInt token_nr = 0;
UInt all_set = 0;
const SizeT input_len = VG_(strlen)(input);
if (input_len > 1000) return False; /* "obviously invalid" */
HChar tok_input[input_len+1];
HChar *input_saveptr;
HChar *input_word;
UInt word_nr = 0;
UInt known_words = 0;
Bool seen_all_kw = False;
Bool seen_none_kw = False;
*enum_set = 0;
VG_(strcpy) (tok_input, input);
for (input_word = VG_(strtok_r)(tok_input, ",", &input_saveptr);
input_word;
input_word = VG_(strtok_r)(NULL, ",", &input_saveptr)) {
word_nr++;
if (0 == VG_(strcmp)(input_word, "all")) {
seen_all_kw = True;
known_words++;
} else if (0 == VG_(strcmp)(input_word, "none")) {
seen_none_kw = True;
known_words++;
}
// Scan tokens + compute all_set. Do that even if all or none was
// recognised to have a correct value for all_set when exiting
// of the 'input' loop.
all_set = 0;
token_nr = 0;
VG_(strcpy) (tok_tokens, tokens);
for (token = VG_(strtok_r)(tok_tokens, ",", &tokens_saveptr);
token;
token = VG_(strtok_r)(NULL, ",", &tokens_saveptr)) {
if (0 != VG_(strcmp)(token, "-")) {
if (0 == VG_(strcmp)(input_word, token)) {
*enum_set |= 1 << token_nr;
known_words++;
}
all_set |= 1 << token_nr;
}
token_nr++;
}
}
if (known_words != word_nr)
return False; // One or more input_words not recognised.
if (seen_all_kw) {
if (seen_none_kw || *enum_set)
return False; // mixing all with either none or a specific value.
*enum_set = all_set;
} else if (seen_none_kw) {
if (seen_all_kw || *enum_set)
return False; // mixing none with either all or a specific value.
*enum_set = 0;
} else {
// seen neither all or none, we must see at least one value
if (*enum_set == 0)
return False;
}
return True;
}
SizeT VG_(strspn) ( const HChar* s, const HChar* accpt )
{
const HChar *p, *a;

View File

@ -111,6 +111,24 @@ extern HChar* VG_(strtok) (HChar* s, const HChar* delim);
False. */
extern Bool VG_(parse_Addr) ( const HChar** ppc, Addr* result );
/* Parse an "enum set" made of one or more words comma separated.
The allowed word values are given in tokens, separated
by comma.
If a word in tokens is found in input,
the corresponding bit will be set in *enum_set
(words in tokens are numbered starting from 0).
The special token - in tokens can be used to indicate
that the corresponding bit position cannot be set.
The words none and all can be used to indicate an empty
enum_set (0) or an enum_set with all bits corresponding
to tokens set. If none or all is given, no other word
can be given in input.
If parsing is successful, returns True and sets *enum_set.
If parsing fails, returns False. */
extern Bool VG_(parse_enum_set) ( const HChar *tokens,
const HChar *input,
UInt *enum_set);
/* Like strncpy(), but if 'src' is longer than 'ndest' inserts a '\0' as the
last character. */
extern void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest );

View File

@ -434,50 +434,8 @@ static const HChar* xml_leak_kind ( Reachedness lossmode )
Bool MC_(parse_leak_kinds) ( const HChar* str0, UInt* lks )
{
HChar tok_str0[VG_(strlen)(str0)+1];
HChar* saveptr;
HChar* token;
Bool seen_all_kw = False;
Bool seen_none_kw = False;
VG_(strcpy) (tok_str0, str0);
*lks = 0;
for (token = VG_(strtok_r)(tok_str0, ",", &saveptr);
token;
token = VG_(strtok_r)(NULL, ",", &saveptr)) {
if (0 == VG_(strcmp)(token, "reachable"))
*lks |= R2S(Reachable);
else if (0 == VG_(strcmp)(token, "possible"))
*lks |= R2S(Possible);
else if (0 == VG_(strcmp)(token, "indirect"))
*lks |= R2S(IndirectLeak);
else if (0 == VG_(strcmp)(token, "definite"))
*lks |= R2S(Unreached);
else if (0 == VG_(strcmp)(token, "all"))
seen_all_kw = True;
else if (0 == VG_(strcmp)(token, "none"))
seen_none_kw = True;
else
return False;
}
if (seen_all_kw) {
if (seen_none_kw || *lks)
return False; // mixing all with either none or a specific value.
*lks = RallS;
} else if (seen_none_kw) {
if (seen_all_kw || *lks)
return False; // mixing none with either all or a specific value.
*lks = 0;
} else {
// seen neither all or none, we must see at least one value
if (*lks == 0)
return False;
}
return True;
return VG_(parse_enum_set)("reachable,possible,indirect,definite",
str0, lks);
}
static const HChar* pp_Reachedness_for_leak_kinds(Reachedness r)

View File

@ -5114,50 +5114,8 @@ Int MC_(clo_mc_level) = 2;
static Bool MC_(parse_leak_heuristics) ( const HChar *str0, UInt *lhs )
{
SizeT str0len = VG_(strlen)(str0);
if (str0len > 1000) return False; /* "obviously invalid" */
HChar tok_str0[str0len+1];
HChar *saveptr;
HChar *token;
Bool seen_all_kw = False;
Bool seen_none_kw = False;
VG_(strcpy) (tok_str0, str0);
*lhs = 0;
for (token = VG_(strtok_r)(tok_str0, ",", &saveptr);
token;
token = VG_(strtok_r)(NULL, ",", &saveptr)) {
if (0 == VG_(strcmp)(token, "stdstring"))
*lhs |= H2S(LchStdString);
else if (0 == VG_(strcmp)(token, "newarray"))
*lhs |= H2S(LchNewArray);
else if (0 == VG_(strcmp)(token, "multipleinheritance"))
*lhs |= H2S(LchMultipleInheritance);
else if (0 == VG_(strcmp)(token, "all"))
seen_all_kw = True;
else if (0 == VG_(strcmp)(token, "none"))
seen_none_kw = True;
else
return False;
}
if (seen_all_kw) {
if (seen_none_kw || *lhs)
return False; // mixing all with either none or a specific value.
*lhs = HallS;
} else if (seen_none_kw) {
if (seen_all_kw || *lhs)
return False; // mixing none with either all or a specific value.
*lhs = 0;
} else {
// seen neither all or none, we must see at least one value
if (*lhs == 0)
return False;
}
return True;
return VG_(parse_enum_set) ("-,stdstring,newarray,multipleinheritance",
str0, lhs);
}
@ -6624,6 +6582,8 @@ static void mc_print_stats (void)
{
SizeT max_secVBit_szB, max_SMs_szB, max_shmem_szB;
VG_(message)(Vg_DebugMsg, " memcheck: freelist: vol %lld length %lld\n",
VG_(free_queue_volume), VG_(free_queue_length));
VG_(message)(Vg_DebugMsg,
" memcheck: sanity checks: %d cheap, %d expensive\n",
n_sanity_cheap, n_sanity_expensive );