1 http://sourceware.org/ml/gdb-patches/2011-04/msg00418.html
2 Subject: Re: [patch 3/3] case insensitive: the fix [rediff]
4 On Fri, 22 Apr 2011 21:05:07 +0200, Eli Zaretskii wrote:
5 > This @table will look weird in the manual: it produces lines that
6 > begin with a lower-case letter. Perhaps reorder thusly:
8 OK, thanks for the review.
16 2011-04-22 Jan Kratochvil <jan.kratochvil@redhat.com>
17 Eli Zaretskii <eliz@gnu.org>
19 * gdb.texinfo (Index Section Format): Change the version to 5.
20 Describe the different formula.
23 2011-04-08 Jan Kratochvil <jan.kratochvil@redhat.com>
25 * dwarf2read.c: Include ctype.h.
26 (struct mapped_index): New field version.
27 (mapped_index_string_hash): New parameter index_version. New comment
28 for it. Call tolower appropriately.
29 (find_slot_in_mapped_hash): New variable cmp, initialize it, use it.
30 Choose the right index version for mapped_index_string_hash.
31 (dwarf2_read_index): Support also the index version 5. Initialize the
32 new struct mapped_index field version.
33 (hash_strtab_entry): Pass INT_MAX for the new parameter, explain why.
34 (find_slot): Explain the version needs. Pass INT_MAX for the new
36 (write_psymtabs_to_index): Produce version 5.
37 * minsyms.c (lookup_minimal_symbol): New variable cmp, initialize it,
38 use it. New comment for SYMBOL_MATCHES_SEARCH_NAME.
39 * psymtab.c (lookup_partial_symbol): Find the
40 SYMBOL_MATCHES_SEARCH_NAME start of the found block of matching
42 * symtab.c (lookup_symbol_in_language): Remove the case_sensitive_off
44 (search_symbols): Pass REG_ICASE to regcomp for case_sensitive_off.
45 (completion_list_add_name): New variable ncmp, initialize it, use it.
46 * symtab.h (SYMBOL_HASH_NEXT): Always call tolower.
47 * utils.c (strcmp_iw): Support case_sensitive_off.
48 (strcmp_iw_ordered): Sort in a way compatible with case_sensitive_off.
49 New function comment part. New variables saved_string1,
50 saved_string2 and case_pass. Add a proper second pass.
53 2011-04-08 Jan Kratochvil <jan.kratochvil@redhat.com>
55 * gdb.base/fortran-sym-case.c: New file.
56 * gdb.base/fortran-sym-case.exp: New file.
57 * gdb.dwarf2/dw2-case-insensitive-debug.S: New file.
58 * gdb.dwarf2/dw2-case-insensitive.c: New file.
59 * gdb.dwarf2/dw2-case-insensitive.exp: New file.
61 Index: gdb-7.2.90.20110525/gdb/dwarf2read.c
62 ===================================================================
63 --- gdb-7.2.90.20110525.orig/gdb/dwarf2read.c 2011-05-25 17:12:51.000000000 +0200
64 +++ gdb-7.2.90.20110525/gdb/dwarf2read.c 2011-05-25 19:12:33.000000000 +0200
65 @@ -152,6 +152,9 @@ DEF_VEC_I (offset_type);
66 a comment by the code that writes the index. */
69 + /* Index data format version. */
72 /* The total length of the buffer. */
75 @@ -1997,17 +2000,23 @@ create_addrmap_from_index (struct objfil
76 SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
77 implementation. This is necessary because the hash function is tied to the
78 format of the mapped index file. The hash values do not have to match with
79 - SYMBOL_HASH_NEXT. */
82 + Use INT_MAX for INDEX_VERSION if you generate the current index format. */
85 -mapped_index_string_hash (const void *p)
86 +mapped_index_string_hash (int index_version, const void *p)
88 const unsigned char *str = (const unsigned char *) p;
92 while ((c = *str++) != 0)
93 - r = r * 67 + c - 113;
95 + if (index_version >= 5)
97 + r = r * 67 + c - 113;
102 @@ -2023,6 +2032,7 @@ find_slot_in_mapped_hash (struct mapped_
103 struct cleanup *back_to = make_cleanup (null_cleanup, 0);
105 offset_type slot, step;
106 + int (*cmp) (const char *, const char *);
108 if (current_language->la_language == language_cplus
109 || current_language->la_language == language_java
110 @@ -2045,9 +2055,16 @@ find_slot_in_mapped_hash (struct mapped_
114 - hash = mapped_index_string_hash (name);
115 + /* Index version 4 did not support case insensitive searches. But the
116 + indexes for case insensitive languages are built in lowercase, therefore
117 + simulate our NAME being searched is also lowercased. */
118 + hash = mapped_index_string_hash ((index->version == 4
119 + && case_sensitivity == case_sensitive_off
120 + ? 5 : index->version),
122 slot = hash & (index->symbol_table_slots - 1);
123 step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1;
124 + cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
128 @@ -2061,7 +2078,7 @@ find_slot_in_mapped_hash (struct mapped_
131 str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]);
132 - if (!strcmp (name, str))
133 + if (!cmp (name, str))
135 *vec_out = (offset_type *) (index->constant_pool
136 + MAYBE_SWAP (index->symbol_table[i + 1]));
137 @@ -2105,15 +2122,17 @@ dwarf2_read_index (struct objfile *objfi
138 /* Versions earlier than 3 emitted every copy of a psymbol. This
139 causes the index to behave very poorly for certain requests. Version 3
140 contained incomplete addrmap. So, it seems better to just ignore such
142 + indices. Index version 4 uses a different hash function than index
143 + version 5 and later. */
146 /* Indexes with higher version than the one supported by GDB may be no
147 longer backward compatible. */
152 map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
153 + map->version = version;
154 map->total_size = dwarf2_per_objfile->gdb_index.size;
156 metadata = (offset_type *) (addr + sizeof (offset_type));
157 @@ -15692,13 +15711,16 @@ struct strtab_entry
161 -/* Hash function for a strtab_entry. */
162 +/* Hash function for a strtab_entry.
164 + Function is used only during write_hash_table so no index format backward
165 + compatibility is needed. */
168 hash_strtab_entry (const void *e)
170 const struct strtab_entry *entry = e;
171 - return mapped_index_string_hash (entry->str);
172 + return mapped_index_string_hash (INT_MAX, entry->str);
175 /* Equality function for a strtab_entry. */
176 @@ -15836,12 +15858,15 @@ cleanup_mapped_symtab (void *p)
179 /* Find a slot in SYMTAB for the symbol NAME. Returns a pointer to
183 + Function is used only during write_hash_table so no index format backward
184 + compatibility is needed. */
186 static struct symtab_index_entry **
187 find_slot (struct mapped_symtab *symtab, const char *name)
189 - offset_type index, step, hash = mapped_index_string_hash (name);
190 + offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
192 index = hash & (symtab->size - 1);
193 step = ((hash * 17) & (symtab->size - 1)) | 1;
194 @@ -16369,7 +16394,7 @@ write_psymtabs_to_index (struct objfile
195 total_len = size_of_contents;
197 /* The version number. */
198 - val = MAYBE_SWAP (4);
199 + val = MAYBE_SWAP (5);
200 obstack_grow (&contents, &val, sizeof (val));
202 /* The offset of the CU list from the start of the file. */
203 Index: gdb-7.2.90.20110525/gdb/minsyms.c
204 ===================================================================
205 --- gdb-7.2.90.20110525.orig/gdb/minsyms.c 2011-05-25 17:12:51.000000000 +0200
206 +++ gdb-7.2.90.20110525/gdb/minsyms.c 2011-05-25 17:13:13.000000000 +0200
207 @@ -239,11 +239,16 @@ lookup_minimal_symbol (const char *name,
211 - match = strcmp (SYMBOL_LINKAGE_NAME (msymbol),
212 - modified_name) == 0;
213 + int (*cmp) (const char *, const char *);
215 + cmp = (case_sensitivity == case_sensitive_on
216 + ? strcmp : strcasecmp);
217 + match = cmp (SYMBOL_LINKAGE_NAME (msymbol),
218 + modified_name) == 0;
222 + /* The function respects CASE_SENSITIVITY. */
223 match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
226 Index: gdb-7.2.90.20110525/gdb/psymtab.c
227 ===================================================================
228 --- gdb-7.2.90.20110525.orig/gdb/psymtab.c 2011-04-20 22:10:29.000000000 +0200
229 +++ gdb-7.2.90.20110525/gdb/psymtab.c 2011-05-25 17:13:13.000000000 +0200
230 @@ -690,8 +690,15 @@ lookup_partial_symbol (struct partial_sy
231 internal_error (__FILE__, __LINE__,
232 _("failed internal consistency check"));
234 - while (top <= real_top
235 - && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
236 + /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
237 + search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME. */
238 + while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
241 + /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME. */
244 + while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
246 if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
247 SYMBOL_DOMAIN (*top), domain))
248 Index: gdb-7.2.90.20110525/gdb/symtab.c
249 ===================================================================
250 --- gdb-7.2.90.20110525.orig/gdb/symtab.c 2011-05-25 17:12:51.000000000 +0200
251 +++ gdb-7.2.90.20110525/gdb/symtab.c 2011-05-25 17:13:49.000000000 +0200
252 @@ -1062,19 +1062,6 @@ lookup_symbol_in_language (const char *n
256 - if (case_sensitivity == case_sensitive_off)
261 - len = strlen (name);
262 - copy = (char *) alloca (len + 1);
263 - for (i= 0; i < len; i++)
264 - copy[i] = tolower (name[i]);
266 - modified_name = copy;
269 returnval = lookup_symbol_aux (modified_name, block, domain, lang,
271 do_cleanups (cleanup);
272 @@ -3106,7 +3093,9 @@ search_symbols (char *regexp, domain_enu
276 - errcode = regcomp (&datum.preg, regexp, REG_NOSUB);
277 + errcode = regcomp (&datum.preg, regexp,
278 + REG_NOSUB | (case_sensitivity == case_sensitive_off
282 char *err = get_regcomp_error (errcode, &datum.preg);
283 @@ -3546,7 +3535,11 @@ rbreak_command (char *regexp, int from_t
285 compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
287 - if (strncmp (name, sym_text, sym_text_len) != 0)
288 + int (*ncmp) (const char *, const char *, size_t);
290 + ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp);
292 + if (ncmp (name, sym_text, sym_text_len) != 0)
295 if (sym_text[sym_text_len] == '(')
296 Index: gdb-7.2.90.20110525/gdb/symtab.h
297 ===================================================================
298 --- gdb-7.2.90.20110525.orig/gdb/symtab.h 2011-05-25 17:12:51.000000000 +0200
299 +++ gdb-7.2.90.20110525/gdb/symtab.h 2011-05-25 17:13:13.000000000 +0200
300 @@ -1036,7 +1036,8 @@ extern unsigned int msymbol_hash (const
301 is only a GDB in-memory computed value with no external files compatibility
304 -#define SYMBOL_HASH_NEXT(hash, c) ((hash) * 67 + (c) - 113)
305 +#define SYMBOL_HASH_NEXT(hash, c) \
306 + ((hash) * 67 + tolower ((unsigned char) (c)) - 113)
308 extern struct objfile * msymbol_objfile (struct minimal_symbol *sym);
310 Index: gdb-7.2.90.20110525/gdb/testsuite/gdb.base/fortran-sym-case.c
311 ===================================================================
312 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
313 +++ gdb-7.2.90.20110525/gdb/testsuite/gdb.base/fortran-sym-case.c 2011-05-25 17:13:13.000000000 +0200
315 +/* This testcase is part of GDB, the GNU debugger.
317 + Copyright 2011 Free Software Foundation, Inc.
319 + This program is free software; you can redistribute it and/or modify
320 + it under the terms of the GNU General Public License as published by
321 + the Free Software Foundation; either version 3 of the License, or
322 + (at your option) any later version.
324 + This program is distributed in the hope that it will be useful,
325 + but WITHOUT ANY WARRANTY; without even the implied warranty of
326 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
327 + GNU General Public License for more details.
329 + You should have received a copy of the GNU General Public License
330 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
333 +main (int argc, char **aRGv)
337 Index: gdb-7.2.90.20110525/gdb/testsuite/gdb.base/fortran-sym-case.exp
338 ===================================================================
339 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
340 +++ gdb-7.2.90.20110525/gdb/testsuite/gdb.base/fortran-sym-case.exp 2011-05-25 17:13:13.000000000 +0200
342 +# Copyright (C) 2011 Free Software Foundation, Inc.
344 +# This program is free software; you can redistribute it and/or modify
345 +# it under the terms of the GNU General Public License as published by
346 +# the Free Software Foundation; either version 3 of the License, or
347 +# (at your option) any later version.
349 +# This program is distributed in the hope that it will be useful,
350 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
351 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
352 +# GNU General Public License for more details.
354 +# You should have received a copy of the GNU General Public License
355 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
357 +set testfile fortran-sym-case
358 +if { [prepare_for_testing ${testfile}.exp ${testfile}] } {
366 +gdb_test "set language fortran" {Warning: the current language does not match this frame\.}
368 +gdb_test "frame" ", aRGv=.*"
369 Index: gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S
370 ===================================================================
371 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
372 +++ gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S 2011-05-25 17:13:13.000000000 +0200
374 +/* This testcase is part of GDB, the GNU debugger.
376 + Copyright 2011 Free Software Foundation, Inc.
378 + This program is free software; you can redistribute it and/or modify
379 + it under the terms of the GNU General Public License as published by
380 + the Free Software Foundation; either version 3 of the License, or
381 + (at your option) any later version.
383 + This program is distributed in the hope that it will be useful,
384 + but WITHOUT ANY WARRANTY; without even the implied warranty of
385 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
386 + GNU General Public License for more details.
388 + You should have received a copy of the GNU General Public License
389 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
391 + .section .debug_info
394 + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
396 + .2byte 2 /* DWARF Version */
397 + .4byte .Labbrev1_begin /* Offset into abbrev section */
398 + .byte 4 /* Pointer size */
401 + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
402 + .ascii "file1.txt\0" /* DW_AT_name */
403 + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
404 + .byte 8 /* DW_AT_language (DW_LANG_Fortran90) */
405 + .4byte FUNC_lang /* DW_AT_low_pc */
406 + .4byte main /* DW_AT_high_pc */
408 + .uleb128 3 /* Abbrev: DW_TAG_subprogram */
409 + .byte 1 /* DW_AT_external */
410 + .ascii "FUNC_lang\0" /* DW_AT_name */
411 + .4byte FUNC_lang /* DW_AT_low_pc */
412 + .4byte main /* DW_AT_high_pc */
413 + .byte 1 /* DW_AT_prototyped */
414 + .4byte .Ltype - .Lcu1_begin /* DW_AT_type */
417 + .uleb128 0x5 /* Abbrev: DW_TAG_base_type */
418 + .byte 0x4 /* DW_AT_byte_size */
419 + .byte 0x5 /* DW_AT_encoding */
420 + .ascii "foo\0" /* DW_AT_name */
422 + .byte 0 /* End of children of CU */
426 + .section .debug_abbrev
428 + .uleb128 1 /* Abbrev code */
429 + .uleb128 0x11 /* DW_TAG_compile_unit */
430 + .byte 1 /* has_children */
431 + .uleb128 0x3 /* DW_AT_name */
432 + .uleb128 0x8 /* DW_FORM_string */
433 + .uleb128 0x25 /* DW_AT_producer */
434 + .uleb128 0x8 /* DW_FORM_string */
435 + .uleb128 0x13 /* DW_AT_language */
436 + .uleb128 0xb /* DW_FORM_data1 */
437 + .uleb128 0x11 /* DW_AT_low_pc */
438 + .uleb128 0x1 /* DW_FORM_addr */
439 + .uleb128 0x12 /* DW_AT_high_pc */
440 + .uleb128 0x1 /* DW_FORM_addr */
441 + .byte 0x0 /* Terminator */
442 + .byte 0x0 /* Terminator */
444 + .uleb128 3 /* Abbrev code */
445 + .uleb128 0x2e /* DW_TAG_subprogram */
446 + .byte 0 /* has_children */
447 + .uleb128 0x3f /* DW_AT_external */
448 + .uleb128 0xc /* DW_FORM_flag */
449 + .uleb128 0x3 /* DW_AT_name */
450 + .uleb128 0x8 /* DW_FORM_string */
451 + .uleb128 0x11 /* DW_AT_low_pc */
452 + .uleb128 0x1 /* DW_FORM_addr */
453 + .uleb128 0x12 /* DW_AT_high_pc */
454 + .uleb128 0x1 /* DW_FORM_addr */
455 + .uleb128 0x27 /* DW_AT_prototyped */
456 + .uleb128 0xc /* DW_FORM_flag */
457 + .uleb128 0x49 /* DW_AT_type */
458 + .uleb128 0x13 /* DW_FORM_ref4 */
459 + .byte 0x0 /* Terminator */
460 + .byte 0x0 /* Terminator */
462 + .uleb128 0x5 /* Abbrev code */
463 + .uleb128 0x24 /* DW_TAG_base_type */
464 + .byte 0x0 /* DW_children_no */
465 + .uleb128 0xb /* DW_AT_byte_size */
466 + .uleb128 0xb /* DW_FORM_data1 */
467 + .uleb128 0x3e /* DW_AT_encoding */
468 + .uleb128 0xb /* DW_FORM_data1 */
469 + .uleb128 0x3 /* DW_AT_name */
470 + .uleb128 0x8 /* DW_FORM_string */
471 + .byte 0x0 /* Terminator */
472 + .byte 0x0 /* Terminator */
474 + .byte 0x0 /* Terminator */
475 + .byte 0x0 /* Terminator */
476 Index: gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c
477 ===================================================================
478 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
479 +++ gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c 2011-05-25 17:13:13.000000000 +0200
481 +/* This testcase is part of GDB, the GNU debugger.
483 + Copyright 2011 Free Software Foundation, Inc.
485 + This program is free software; you can redistribute it and/or modify
486 + it under the terms of the GNU General Public License as published by
487 + the Free Software Foundation; either version 3 of the License, or
488 + (at your option) any later version.
490 + This program is distributed in the hope that it will be useful,
491 + but WITHOUT ANY WARRANTY; without even the implied warranty of
492 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
493 + GNU General Public License for more details.
495 + You should have received a copy of the GNU General Public License
496 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
498 +/* Use DW_LANG_Fortran90 for case insensitive DWARF. */
505 +/* Symbol is present only in ELF .symtab. */
519 Index: gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
520 ===================================================================
521 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
522 +++ gdb-7.2.90.20110525/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp 2011-05-25 17:13:13.000000000 +0200
524 +# Copyright 2011 Free Software Foundation, Inc.
526 +# This program is free software; you can redistribute it and/or modify
527 +# it under the terms of the GNU General Public License as published by
528 +# the Free Software Foundation; either version 3 of the License, or
529 +# (at your option) any later version.
531 +# This program is distributed in the hope that it will be useful,
532 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
533 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
534 +# GNU General Public License for more details.
536 +# You should have received a copy of the GNU General Public License
537 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
540 +# This test can only be run on targets which support DWARF-2 and use gas.
541 +if {![dwarf2_support]} {
545 +set testfile "dw2-case-insensitive"
547 +if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.c ${testfile}-debug.S] {nodebug}] } {
551 +gdb_test "show case-sensitive" {Case sensitivity in name search is "auto; currently on"\.}
553 +gdb_test "info functions fUnC_lang" \
554 + "All functions matching regular expression \"fUnC_lang\":" \
555 + "regexp case-sensitive on"
557 +gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.}
559 +gdb_test "info functions fUnC_lang" \
560 + "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\nfoo FUNC_lang\\(void\\);" \
561 + "regexp case-sensitive off"
563 +gdb_test "p fuNC_lang" { = {foo \(void\)} 0x[0-9a-f]+ <FUNC_lang>}
564 +gdb_test "p fuNC_symtab" { = {<text variable, no debug info>} 0x[0-9a-f]+ <FUNC_symtab>}
566 +if {[gdb_breakpoint "fuNC_lang"] == 1} {
567 + pass "setting breakpoint at fuNC_lang"
570 +if {[gdb_breakpoint "fuNC_symtab"] == 1} {
571 + pass "setting breakpoint at fuNC_symtab"
573 Index: gdb-7.2.90.20110525/gdb/utils.c
574 ===================================================================
575 --- gdb-7.2.90.20110525.orig/gdb/utils.c 2011-05-25 17:12:51.000000000 +0200
576 +++ gdb-7.2.90.20110525/gdb/utils.c 2011-05-25 17:13:13.000000000 +0200
577 @@ -3003,10 +3003,12 @@ strcmp_iw (const char *string1, const ch
581 - if (*string1 != *string2)
585 + if (case_sensitivity == case_sensitive_on && *string1 != *string2)
587 + if (case_sensitivity == case_sensitive_off
588 + && (tolower ((unsigned char) *string1)
589 + != tolower ((unsigned char) *string2)))
591 if (*string1 != '\0')
594 @@ -3027,6 +3029,10 @@ strcmp_iw (const char *string1, const ch
595 strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
596 where this function would put NAME.
598 + This function must be neutral to the CASE_SENSITIVITY setting as the user
599 + may choose it during later lookup. Therefore this function always sorts
600 + primarily case-insensitively and secondarily case-sensitively.
602 Here are some examples of why using strcmp to sort is a bad idea:
605 @@ -3052,8 +3058,10 @@ strcmp_iw (const char *string1, const ch
607 strcmp_iw_ordered (const char *string1, const char *string2)
609 - /* Formatting stub. */
611 + const char *saved_string1 = string1, *saved_string2 = string2;
612 + enum case_sensitivity case_pass = case_sensitive_off;
616 /* C1 and C2 are valid only if *string1 != '\0' && *string2 != '\0'.
617 Provide stub characters if we are already at the end of one of the
618 @@ -3067,8 +3075,17 @@ strcmp_iw_ordered (const char *string1,
619 while (isspace (*string2))
624 + case case_sensitive_off:
625 + c1 = tolower ((unsigned char) *string1);
626 + c2 = tolower ((unsigned char) *string2);
628 + case case_sensitive_on:
636 @@ -3086,7 +3103,7 @@ strcmp_iw_ordered (const char *string1,
637 comparison in the cases where one of them is '\0' or '('. */
639 if (*string2 == '\0')
645 @@ -3097,9 +3114,22 @@ strcmp_iw_ordered (const char *string1,
647 if (*string2 == '\0' || *string2 == '(')
658 + if (case_pass == case_sensitive_on)
661 + /* Otherwise the strings were equal in case insensitive way, make
662 + a more fine grained comparison in a case sensitive way. */
664 + case_pass = case_sensitive_on;
665 + string1 = saved_string1;
666 + string2 = saved_string2;