From: Jan Kratochvil Date: Wed, 27 Apr 2011 20:03:04 +0000 (+0000) Subject: gdb/doc/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=559a7a62019960bacbbe4b099f3c7926352cb131;p=binutils-gdb.git gdb/doc/ * gdb.texinfo (Index Section Format): Change the version to 5. Describe the different formula. gdb/ Case insensitive lookups implementation. * dwarf2read.c: Include ctype.h. (struct mapped_index): New field version. (mapped_index_string_hash): New parameter index_version. New comment for it. Call tolower appropriately. (find_slot_in_mapped_hash): New variable cmp, initialize it, use it. Choose the right index version for mapped_index_string_hash. (dwarf2_read_index): Support also the index version 5. Initialize the new struct mapped_index field version. (hash_strtab_entry): Pass INT_MAX for the new parameter, explain why. (find_slot): Explain the version needs. Pass INT_MAX for the new parameter. (write_psymtabs_to_index): Produce version 5. * minsyms.c (lookup_minimal_symbol): New variable cmp, initialize it, use it. New comment for SYMBOL_MATCHES_SEARCH_NAME. * psymtab.c (lookup_partial_symbol): Find the SYMBOL_MATCHES_SEARCH_NAME start of the found block of matching entries. * symtab.c (lookup_symbol_in_language): Remove the case_sensitive_off NAME lowercasing. (search_symbols): Pass REG_ICASE to regcomp for case_sensitive_off. (completion_list_add_name): New variable ncmp, initialize it, use it. * symtab.h (SYMBOL_HASH_NEXT): Always call tolower. * utils.c (strcmp_iw): Support case_sensitive_off. (strcmp_iw_ordered): Sort in a way compatible with case_sensitive_off. New function comment part. New variables saved_string1, saved_string2 and case_pass. Add a proper second pass. gdb/testsuite/ * gdb.base/fortran-sym-case.c: New file. * gdb.base/fortran-sym-case.exp: New file. * gdb.dwarf2/dw2-case-insensitive-debug.S: New file. * gdb.dwarf2/dw2-case-insensitive.c: New file. * gdb.dwarf2/dw2-case-insensitive.exp: New file. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index beed476293c..d6e58354165 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,33 @@ +2011-04-27 Jan Kratochvil + + Case insensitive lookups implementation. + * dwarf2read.c: Include ctype.h. + (struct mapped_index): New field version. + (mapped_index_string_hash): New parameter index_version. New comment + for it. Call tolower appropriately. + (find_slot_in_mapped_hash): New variable cmp, initialize it, use it. + Choose the right index version for mapped_index_string_hash. + (dwarf2_read_index): Support also the index version 5. Initialize the + new struct mapped_index field version. + (hash_strtab_entry): Pass INT_MAX for the new parameter, explain why. + (find_slot): Explain the version needs. Pass INT_MAX for the new + parameter. + (write_psymtabs_to_index): Produce version 5. + * minsyms.c (lookup_minimal_symbol): New variable cmp, initialize it, + use it. New comment for SYMBOL_MATCHES_SEARCH_NAME. + * psymtab.c (lookup_partial_symbol): Find the + SYMBOL_MATCHES_SEARCH_NAME start of the found block of matching + entries. + * symtab.c (lookup_symbol_in_language): Remove the case_sensitive_off + NAME lowercasing. + (search_symbols): Pass REG_ICASE to regcomp for case_sensitive_off. + (completion_list_add_name): New variable ncmp, initialize it, use it. + * symtab.h (SYMBOL_HASH_NEXT): Always call tolower. + * utils.c (strcmp_iw): Support case_sensitive_off. + (strcmp_iw_ordered): Sort in a way compatible with case_sensitive_off. + New function comment part. New variables saved_string1, + saved_string2 and case_pass. Add a proper second pass. + 2011-04-27 Jan Kratochvil Replace re_comp/re_exec by regcomp/regexec. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index aa3c89347f0..514d5847824 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2011-04-27 Jan Kratochvil + Eli Zaretskii + + * gdb.texinfo (Index Section Format): Change the version to 5. + Describe the different formula. + 2011-04-24 Jan Kratochvil Eli Zaretskii diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 15ccf2ef020..ff5b7cb5f72 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -36993,7 +36993,8 @@ unless otherwise noted: @enumerate @item -The version number, currently 4. Versions 1, 2 and 3 are obsolete. +The version number, currently 5. Versions 1, 2 and 3 are obsolete. +Version 4 differs by its hashing function. @item The offset, from the start of the file, of the CU list. @@ -37061,9 +37062,18 @@ valid index for both a string and a CU vector. The hash value for a table entry is computed by applying an iterative hash function to the symbol's name. Starting with an initial value of @code{r = 0}, each (unsigned) character @samp{c} in -the string is incorporated into the hash using the formula -@code{r = r * 67 + c - 113}. The terminating @samp{\0} is not -incorporated into the hash. +the string is incorporated into the hash using the formula depending on the +index version: + +@table @asis +@item Version 4 +The formula is @code{r = r * 67 + c - 113}. + +@item Version 5 +The formula is @code{r = r * 67 + tolower (c) - 113}. +@end table + +The terminating @samp{\0} is not incorporated into the hash. The step size used in the hash table is computed via @code{((hash * 17) & (size - 1)) | 1}, where @samp{hash} is the hash diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0ca9532f70e..fdab83d649f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -149,6 +149,9 @@ DEF_VEC_I (offset_type); a comment by the code that writes the index. */ struct mapped_index { + /* Index data format version. */ + int version; + /* The total length of the buffer. */ off_t total_size; @@ -1972,17 +1975,23 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index) SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the implementation. This is necessary because the hash function is tied to the format of the mapped index file. The hash values do not have to match with - SYMBOL_HASH_NEXT. */ + SYMBOL_HASH_NEXT. + + Use INT_MAX for INDEX_VERSION if you generate the current index format. */ static hashval_t -mapped_index_string_hash (const void *p) +mapped_index_string_hash (int index_version, const void *p) { const unsigned char *str = (const unsigned char *) p; hashval_t r = 0; unsigned char c; while ((c = *str++) != 0) - r = r * 67 + c - 113; + { + if (index_version >= 5) + c = tolower (c); + r = r * 67 + c - 113; + } return r; } @@ -1998,6 +2007,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, struct cleanup *back_to = make_cleanup (null_cleanup, 0); offset_type hash; offset_type slot, step; + int (*cmp) (const char *, const char *); if (current_language->la_language == language_cplus || current_language->la_language == language_java @@ -2020,9 +2030,17 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } } - hash = mapped_index_string_hash (name); + /* Index version 4 did not support case insensitive searches. But the + indexes for case insensitive languages are built in lowercase, therefore + simulate our NAME being searched is also lowercased. */ + hash = mapped_index_string_hash ((index->version == 4 + && case_sensitivity == case_sensitive_off + ? 5 : index->version), + name); + slot = hash & (index->symbol_table_slots - 1); step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1; + cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp); for (;;) { @@ -2036,7 +2054,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]); - if (!strcmp (name, str)) + if (!cmp (name, str)) { *vec_out = (offset_type *) (index->constant_pool + MAYBE_SWAP (index->symbol_table[i + 1])); @@ -2080,15 +2098,17 @@ dwarf2_read_index (struct objfile *objfile) /* Versions earlier than 3 emitted every copy of a psymbol. This causes the index to behave very poorly for certain requests. Version 3 contained incomplete addrmap. So, it seems better to just ignore such - indices. */ + indices. Index version 4 uses a different hash function than index + version 5 and later. */ if (version < 4) return 0; /* Indexes with higher version than the one supported by GDB may be no longer backward compatible. */ - if (version > 4) + if (version > 5) return 0; map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index); + map->version = version; map->total_size = dwarf2_per_objfile->gdb_index.size; metadata = (offset_type *) (addr + sizeof (offset_type)); @@ -15256,13 +15276,16 @@ struct strtab_entry const char *str; }; -/* Hash function for a strtab_entry. */ +/* Hash function for a strtab_entry. + + Function is used only during write_hash_table so no index format backward + compatibility is needed. */ static hashval_t hash_strtab_entry (const void *e) { const struct strtab_entry *entry = e; - return mapped_index_string_hash (entry->str); + return mapped_index_string_hash (INT_MAX, entry->str); } /* Equality function for a strtab_entry. */ @@ -15400,12 +15423,15 @@ cleanup_mapped_symtab (void *p) } /* Find a slot in SYMTAB for the symbol NAME. Returns a pointer to - the slot. */ + the slot. + + Function is used only during write_hash_table so no index format backward + compatibility is needed. */ static struct symtab_index_entry ** find_slot (struct mapped_symtab *symtab, const char *name) { - offset_type index, step, hash = mapped_index_string_hash (name); + offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name); index = hash & (symtab->size - 1); step = ((hash * 17) & (symtab->size - 1)) | 1; @@ -15934,7 +15960,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) total_len = size_of_contents; /* The version number. */ - val = MAYBE_SWAP (4); + val = MAYBE_SWAP (5); obstack_grow (&contents, &val, sizeof (val)); /* The offset of the CU list from the start of the file. */ diff --git a/gdb/minsyms.c b/gdb/minsyms.c index a2c5ebc0b1d..249675bb3da 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -239,11 +239,16 @@ lookup_minimal_symbol (const char *name, const char *sfile, if (pass == 1) { - match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), - modified_name) == 0; + int (*cmp) (const char *, const char *); + + cmp = (case_sensitivity == case_sensitive_on + ? strcmp : strcasecmp); + match = cmp (SYMBOL_LINKAGE_NAME (msymbol), + modified_name) == 0; } else { + /* The function respects CASE_SENSITIVITY. */ match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, modified_name); } diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 93a7ea26a15..ea690ef6449 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -691,8 +691,15 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, internal_error (__FILE__, __LINE__, _("failed internal consistency check")); - while (top <= real_top - && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name)) + /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will + search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME. */ + while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name)) + top--; + + /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME. */ + top++; + + while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name)) { if (symbol_matches_domain (SYMBOL_LANGUAGE (*top), SYMBOL_DOMAIN (*top), domain)) diff --git a/gdb/symtab.c b/gdb/symtab.c index ebc822167ae..f9e2bca8dbc 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1056,19 +1056,6 @@ lookup_symbol_in_language (const char *name, const struct block *block, } } - if (case_sensitivity == case_sensitive_off) - { - char *copy; - int len, i; - - len = strlen (name); - copy = (char *) alloca (len + 1); - for (i= 0; i < len; i++) - copy[i] = tolower (name[i]); - copy[len] = 0; - modified_name = copy; - } - returnval = lookup_symbol_aux (modified_name, block, domain, lang, is_a_field_of_this); do_cleanups (cleanup); @@ -3069,7 +3056,9 @@ search_symbols (char *regexp, enum search_domain kind, } } - errcode = regcomp (&datum.preg, regexp, REG_NOSUB); + errcode = regcomp (&datum.preg, regexp, + REG_NOSUB | (case_sensitivity == case_sensitive_off + ? REG_ICASE : 0)); if (errcode != 0) { char *err = get_regcomp_error (errcode, &datum.preg); @@ -3519,10 +3508,13 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len, char *text, char *word) { int newsize; + int (*ncmp) (const char *, const char *, size_t); + + ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp); /* Clip symbols that cannot match. */ - if (strncmp (symname, sym_text, sym_text_len) != 0) + if (ncmp (symname, sym_text, sym_text_len) != 0) { return; } diff --git a/gdb/symtab.h b/gdb/symtab.h index e497bed3766..29e7d703b9e 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1012,7 +1012,8 @@ extern unsigned int msymbol_hash (const char *); is only a GDB in-memory computed value with no external files compatibility requirements. */ -#define SYMBOL_HASH_NEXT(hash, c) ((hash) * 67 + (c) - 113) +#define SYMBOL_HASH_NEXT(hash, c) \ + ((hash) * 67 + tolower ((unsigned char) (c)) - 113) extern struct objfile * msymbol_objfile (struct minimal_symbol *sym); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4aa5513f24a..47ccf633b4e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-04-27 Jan Kratochvil + + * gdb.base/fortran-sym-case.c: New file. + * gdb.base/fortran-sym-case.exp: New file. + * gdb.dwarf2/dw2-case-insensitive-debug.S: New file. + * gdb.dwarf2/dw2-case-insensitive.c: New file. + * gdb.dwarf2/dw2-case-insensitive.exp: New file. + 2011-04-27 Jan Kratochvil * lib/gdb.exp (gdb_test_multiple): Eror on newline in $message. diff --git a/gdb/testsuite/gdb.base/fortran-sym-case.c b/gdb/testsuite/gdb.base/fortran-sym-case.c new file mode 100644 index 00000000000..ffde268c42d --- /dev/null +++ b/gdb/testsuite/gdb.base/fortran-sym-case.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +int +main (int argc, char **aRGv) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/fortran-sym-case.exp b/gdb/testsuite/gdb.base/fortran-sym-case.exp new file mode 100644 index 00000000000..4b9cf762241 --- /dev/null +++ b/gdb/testsuite/gdb.base/fortran-sym-case.exp @@ -0,0 +1,27 @@ +# Copyright (C) 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +set testfile fortran-sym-case +if { [prepare_for_testing ${testfile}.exp ${testfile}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test "set language fortran" {Warning: the current language does not match this frame\.} + +gdb_test "frame" ", aRGv=.*" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S new file mode 100644 index 00000000000..5e4cd35cd40 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S @@ -0,0 +1,102 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + .section .debug_info +.Lcu1_begin: + /* CU header */ + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF Version */ + .4byte .Labbrev1_begin /* Offset into abbrev section */ + .byte 4 /* Pointer size */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .ascii "file1.txt\0" /* DW_AT_name */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 8 /* DW_AT_language (DW_LANG_Fortran90) */ + .4byte FUNC_lang /* DW_AT_low_pc */ + .4byte main /* DW_AT_high_pc */ + + .uleb128 3 /* Abbrev: DW_TAG_subprogram */ + .byte 1 /* DW_AT_external */ + .ascii "FUNC_lang\0" /* DW_AT_name */ + .4byte FUNC_lang /* DW_AT_low_pc */ + .4byte main /* DW_AT_high_pc */ + .byte 1 /* DW_AT_prototyped */ + .4byte .Ltype - .Lcu1_begin /* DW_AT_type */ + +.Ltype: + .uleb128 0x5 /* Abbrev: DW_TAG_base_type */ + .byte 0x4 /* DW_AT_byte_size */ + .byte 0x5 /* DW_AT_encoding */ + .ascii "foo\0" /* DW_AT_name */ + + .byte 0 /* End of children of CU */ +.Lcu1_end: + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x2e /* DW_TAG_subprogram */ + .byte 0 /* has_children */ + .uleb128 0x3f /* DW_AT_external */ + .uleb128 0xc /* DW_FORM_flag */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x27 /* DW_AT_prototyped */ + .uleb128 0xc /* DW_FORM_flag */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 0x5 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0x0 /* DW_children_no */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c new file mode 100644 index 00000000000..3be9c6368ab --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c @@ -0,0 +1,38 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Use DW_LANG_Fortran90 for case insensitive DWARF. */ + +void +FUNC_lang (void) +{ +} + +/* Symbol is present only in ELF .symtab. */ + +void +FUNC_symtab (void) +{ +} + +int +main (void) +{ + FUNC_lang (); + FUNC_symtab (); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp new file mode 100644 index 00000000000..78dc8180843 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp @@ -0,0 +1,49 @@ +# Copyright 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +set testfile "dw2-case-insensitive" + +if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.c ${testfile}-debug.S] {nodebug}] } { + return -1 +} + +gdb_test "show case-sensitive" {Case sensitivity in name search is "auto; currently on"\.} + +gdb_test "info functions fUnC_lang" \ + "All functions matching regular expression \"fUnC_lang\":" \ + "regexp case-sensitive on" + +gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.} + +gdb_test "info functions fUnC_lang" \ + "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\nfoo FUNC_lang\\(void\\);" \ + "regexp case-sensitive off" + +gdb_test "p fuNC_lang" { = {foo \(void\)} 0x[0-9a-f]+ } +gdb_test "p fuNC_symtab" { = {} 0x[0-9a-f]+ } + +if {[gdb_breakpoint "fuNC_lang"] == 1} { + pass "setting breakpoint at fuNC_lang" +} + +if {[gdb_breakpoint "fuNC_symtab"] == 1} { + pass "setting breakpoint at fuNC_symtab" +} diff --git a/gdb/utils.c b/gdb/utils.c index 850b80dc1e4..a1dac63a181 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2974,10 +2974,12 @@ strcmp_iw (const char *string1, const char *string2) { string2++; } - if (*string1 != *string2) - { - break; - } + if (case_sensitivity == case_sensitive_on && *string1 != *string2) + break; + if (case_sensitivity == case_sensitive_off + && (tolower ((unsigned char) *string1) + != tolower ((unsigned char) *string2))) + break; if (*string1 != '\0') { string1++; @@ -2998,6 +3000,10 @@ strcmp_iw (const char *string1, const char *string2) strcmp_iw(LIST_ELT, NAME), then the place to start looking is right where this function would put NAME. + This function must be neutral to the CASE_SENSITIVITY setting as the user + may choose it during later lookup. Therefore this function always sorts + primarily case-insensitively and secondarily case-sensitively. + Here are some examples of why using strcmp to sort is a bad idea: Whitespace example: @@ -3023,8 +3029,10 @@ strcmp_iw (const char *string1, const char *string2) int strcmp_iw_ordered (const char *string1, const char *string2) { - /* Formatting stub. */ - if (1) + const char *saved_string1 = string1, *saved_string2 = string2; + enum case_sensitivity case_pass = case_sensitive_off; + + for (;;) { /* C1 and C2 are valid only if *string1 != '\0' && *string2 != '\0'. Provide stub characters if we are already at the end of one of the @@ -3038,8 +3046,17 @@ strcmp_iw_ordered (const char *string1, const char *string2) while (isspace (*string2)) string2++; + switch (case_pass) + { + case case_sensitive_off: + c1 = tolower ((unsigned char) *string1); + c2 = tolower ((unsigned char) *string2); + break; + case case_sensitive_on: c1 = *string1; c2 = *string2; + break; + } if (c1 != c2) break; @@ -3057,7 +3074,7 @@ strcmp_iw_ordered (const char *string1, const char *string2) comparison in the cases where one of them is '\0' or '('. */ case '\0': if (*string2 == '\0') - return 0; + break; else return -1; case '(': @@ -3068,9 +3085,22 @@ strcmp_iw_ordered (const char *string1, const char *string2) default: if (*string2 == '\0' || *string2 == '(') return 1; - else - return c1 - c2; + else if (c1 > c2) + return 1; + else if (c1 < c2) + return -1; + /* PASSTHRU */ } + + if (case_pass == case_sensitive_on) + return 0; + + /* Otherwise the strings were equal in case insensitive way, make + a more fine grained comparison in a case sensitive way. */ + + case_pass = case_sensitive_on; + string1 = saved_string1; + string2 = saved_string2; } }