aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphilippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>2014-04-19 09:52:32 +0000
committerphilippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>2014-04-19 09:52:32 +0000
commit0c2923fb395e1dd3aa43e36d73a164e5718dcad6 (patch)
tree3975b6c30ae7af8ca59f2f59c5904471ea0d2667
parent4f6f336badda2171d6e842cca3de63b53f4c9f0b (diff)
downloadvalgrind-0c2923fb395e1dd3aa43e36d73a164e5718dcad6.tar.gz
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 a5019735-40e9-0310-863c-91ae7b9d1cf9
-rw-r--r--coregrind/m_libcbase.c76
-rw-r--r--include/pub_tool_libcbase.h18
-rw-r--r--memcheck/mc_errors.c46
-rw-r--r--memcheck/mc_main.c48
4 files changed, 100 insertions, 88 deletions
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index 0c334ed24..61f6fefd4 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -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;
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index fcc0ed116..951a702dc 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -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 );
diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c
index 5f1dd1e82..424e51297 100644
--- a/memcheck/mc_errors.c
+++ b/memcheck/mc_errors.c
@@ -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)
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 5eda4ff24..619aeb565 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -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 );