diff options
author | philippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2014-04-19 09:52:32 +0000 |
---|---|---|
committer | philippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2014-04-19 09:52:32 +0000 |
commit | 0c2923fb395e1dd3aa43e36d73a164e5718dcad6 (patch) | |
tree | 3975b6c30ae7af8ca59f2f59c5904471ea0d2667 | |
parent | 4f6f336badda2171d6e842cca3de63b53f4c9f0b (diff) | |
download | valgrind-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.c | 76 | ||||
-rw-r--r-- | include/pub_tool_libcbase.h | 18 | ||||
-rw-r--r-- | memcheck/mc_errors.c | 46 | ||||
-rw-r--r-- | memcheck/mc_main.c | 48 |
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 ); |