/* Test non-array inputs to string comparison functions. Copyright (C) 2024 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ /* This skeleton file is included from string/test-strncmp-nonarray.c and wcsmbs/test-wcsncmp-nonarray.c to test that reading of the arrays stops at the first null character. TEST_IDENTIFIER must be the test function identifier. TEST_NAME is the same as a string. CHAR must be defined as the character type. */ #include #include #include #include #include #include #include /* Much shorter than test-Xnlen-nonarray.c because of deeply nested loops. */ enum { buffer_length = 80 }; /* The test buffer layout follows what is described test-Xnlen-nonarray.c, except that there two buffers, left and right. The variables a_count, zero_count, start_offset are all duplicated. */ /* Return the maximum string length for a string that starts at start_offset. */ static int string_length (int a_count, int start_offset) { if (start_offset == buffer_length || start_offset >= a_count) return 0; else return a_count - start_offset; } /* This is the valid maximum length argument computation for strnlen/wcsnlen. See text-Xnlen-nonarray.c. */ static int maximum_length (int start_offset, int zero_count) { if (start_offset == buffer_length) return 0; else if (zero_count > 0) /* Effectively unbounded, but we need to stop fairly low, otherwise testing takes too long. */ return buffer_length + 32; else return buffer_length - start_offset; } typedef __typeof (TEST_IDENTIFIER) *proto_t; #define TEST_MAIN #include "test-string.h" IMPL (TEST_IDENTIFIER, 1) static int test_main (void) { TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length); test_init (); struct support_next_to_fault left_ntf = support_next_to_fault_allocate (buffer_length * sizeof (CHAR)); CHAR *left_buffer = (CHAR *) left_ntf.buffer; struct support_next_to_fault right_ntf = support_next_to_fault_allocate (buffer_length * sizeof (CHAR)); CHAR *right_buffer = (CHAR *) right_ntf.buffer; FOR_EACH_IMPL (impl, 0) { printf ("info: testing %s\n", impl->name); for (size_t i = 0; i < buffer_length; ++i) left_buffer[i] = 'A'; for (int left_zero_count = 0; left_zero_count <= buffer_length; ++left_zero_count) { if (left_zero_count > 0) left_buffer[buffer_length - left_zero_count] = 0; int left_a_count = buffer_length - left_zero_count; for (size_t i = 0; i < buffer_length; ++i) right_buffer[i] = 'A'; for (int right_zero_count = 0; right_zero_count <= buffer_length; ++right_zero_count) { if (right_zero_count > 0) right_buffer[buffer_length - right_zero_count] = 0; int right_a_count = buffer_length - right_zero_count; for (int left_start_offset = 0; left_start_offset <= buffer_length; ++left_start_offset) { CHAR *left_start_pointer = left_buffer + left_start_offset; int left_maxlen = maximum_length (left_start_offset, left_zero_count); int left_length = string_length (left_a_count, left_start_offset); for (int right_start_offset = 0; right_start_offset <= buffer_length; ++right_start_offset) { CHAR *right_start_pointer = right_buffer + right_start_offset; int right_maxlen = maximum_length (right_start_offset, right_zero_count); int right_length = string_length (right_a_count, right_start_offset); /* Maximum length is modelled after strnlen/wcsnlen, and must be valid for both pointer arguments at the same time. */ int maxlen = MIN (left_maxlen, right_maxlen); for (int length_argument = 0; length_argument <= maxlen; ++length_argument) { if (test_verbose) { printf ("left: zero_count=%d" " a_count=%d start_offset=%d\n", left_zero_count, left_a_count, left_start_offset); printf ("right: zero_count=%d" " a_count=%d start_offset=%d\n", right_zero_count, right_a_count, right_start_offset); printf ("length argument: %d\n", length_argument); } /* Effective lengths bounded by length argument. The effective length determines the outcome of the comparison. */ int left_effective = MIN (left_length, length_argument); int right_effective = MIN (right_length, length_argument); if (left_effective == right_effective) TEST_COMPARE (CALL (impl, left_start_pointer, right_start_pointer, length_argument), 0); else if (left_effective < right_effective) TEST_COMPARE (CALL (impl, left_start_pointer, right_start_pointer, length_argument) < 0, 1); else TEST_COMPARE (CALL (impl, left_start_pointer, right_start_pointer, length_argument) > 0, 1); } } } } } } return 0; } #include