📄 string.c
字号:
/* Tester for string functions. Copyright (C) 1995-2000, 2001 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif/* Make sure we don't test the optimized inline functions if we want to test the real implementation. */#if !defined DO_STRING_INLINES#undef __USE_STRING_INLINES#endif#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <fcntl.h>#define STREQ(a, b) (strcmp((a), (b)) == 0)const char *it = "<UNSET>"; /* Routine name for message routines. */size_t errors = 0;/* Complain if condition is not true. */static voidcheck (int thing, int number){ if (!thing) { printf("%s flunked test %d\n", it, number); ++errors; }}/* Complain if first two args don't strcmp as equal. */static voidequal (const char *a, const char *b, int number){ check(a != NULL && b != NULL && STREQ (a, b), number);}char one[50];char two[50];char *cp;static voidtest_strcmp (void){ it = "strcmp"; check (strcmp ("", "") == 0, 1); /* Trivial case. */ check (strcmp ("a", "a") == 0, 2); /* Identity. */ check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */ check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */ check (strcmp ("abcd", "abc") > 0, 5); check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */ check (strcmp ("abce", "abcd") > 0, 7); check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */ check (strcmp ("a\203", "a\003") > 0, 9); { char buf1[0x40], buf2[0x40]; int i, j; for (i=0; i < 0x10; i++) for (j = 0; j < 0x10; j++) { int k; for (k = 0; k < 0x3f; k++) { buf1[j] = '0' ^ (k & 4); buf2[j] = '4' ^ (k & 4); } buf1[i] = buf1[0x3f] = 0; buf2[j] = buf2[0x3f] = 0; for (k = 0; k < 0xf; k++) { int cnum = 0x10+0x10*k+0x100*j+0x1000*i; check (strcmp (buf1+i,buf2+j) == 0, cnum); buf1[i+k] = 'A' + i + k; buf1[i+k+1] = 0; check (strcmp (buf1+i,buf2+j) > 0, cnum+1); check (strcmp (buf2+j,buf1+i) < 0, cnum+2); buf2[j+k] = 'B' + i + k; buf2[j+k+1] = 0; check (strcmp (buf1+i,buf2+j) < 0, cnum+3); check (strcmp (buf2+j,buf1+i) > 0, cnum+4); buf2[j+k] = 'A' + i + k; buf1[i] = 'A' + i + 0x80; check (strcmp (buf1+i,buf2+j) > 0, cnum+5); check (strcmp (buf2+j,buf1+i) < 0, cnum+6); buf1[i] = 'A' + i; } } }}#define SIMPLE_COPY(fn, n, str, ntest) \ do { \ int __n; \ char *cp; \ for (__n = 0; __n < (int) sizeof (one); ++__n) \ one[__n] = 'Z'; \ fn (one, str); \ for (cp = one, __n = 0; __n < n; ++__n, ++cp) \ check (*cp == '0' + (n % 10), ntest); \ check (*cp == '\0', ntest); \ } while (0)static voidtest_strcpy (void){ int i; it = "strcpy"; check (strcpy (one, "abcd") == one, 1); /* Returned value. */ equal (one, "abcd", 2); /* Basic test. */ (void) strcpy (one, "x"); equal (one, "x", 3); /* Writeover. */ equal (one+2, "cd", 4); /* Wrote too much? */ (void) strcpy (two, "hi there"); (void) strcpy (one, two); equal (one, "hi there", 5); /* Basic test encore. */ equal (two, "hi there", 6); /* Stomped on source? */ (void) strcpy (one, ""); equal (one, "", 7); /* Boundary condition. */ for (i = 0; i < 16; i++) { (void) strcpy (one + i, "hi there"); /* Unaligned destination. */ equal (one + i, "hi there", 8 + (i * 2)); (void) strcpy (two, one + i); /* Unaligned source. */ equal (two, "hi there", 9 + (i * 2)); } SIMPLE_COPY(strcpy, 0, "", 41); SIMPLE_COPY(strcpy, 1, "1", 42); SIMPLE_COPY(strcpy, 2, "22", 43); SIMPLE_COPY(strcpy, 3, "333", 44); SIMPLE_COPY(strcpy, 4, "4444", 45); SIMPLE_COPY(strcpy, 5, "55555", 46); SIMPLE_COPY(strcpy, 6, "666666", 47); SIMPLE_COPY(strcpy, 7, "7777777", 48); SIMPLE_COPY(strcpy, 8, "88888888", 49); SIMPLE_COPY(strcpy, 9, "999999999", 50); SIMPLE_COPY(strcpy, 10, "0000000000", 51); SIMPLE_COPY(strcpy, 11, "11111111111", 52); SIMPLE_COPY(strcpy, 12, "222222222222", 53); SIMPLE_COPY(strcpy, 13, "3333333333333", 54); SIMPLE_COPY(strcpy, 14, "44444444444444", 55); SIMPLE_COPY(strcpy, 15, "555555555555555", 56); SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);}static voidtest_stpcpy (void){ it = "stpcpy"; check ((stpcpy (one, "a") - one) == 1, 1); equal (one, "a", 2); check ((stpcpy (one, "ab") - one) == 2, 3); equal (one, "ab", 4); check ((stpcpy (one, "abc") - one) == 3, 5); equal (one, "abc", 6); check ((stpcpy (one, "abcd") - one) == 4, 7); equal (one, "abcd", 8); check ((stpcpy (one, "abcde") - one) == 5, 9); equal (one, "abcde", 10); check ((stpcpy (one, "abcdef") - one) == 6, 11); equal (one, "abcdef", 12); check ((stpcpy (one, "abcdefg") - one) == 7, 13); equal (one, "abcdefg", 14); check ((stpcpy (one, "abcdefgh") - one) == 8, 15); equal (one, "abcdefgh", 16); check ((stpcpy (one, "abcdefghi") - one) == 9, 17); equal (one, "abcdefghi", 18); check ((stpcpy (one, "x") - one) == 1, 19); equal (one, "x", 20); /* Writeover. */ equal (one+2, "cdefghi", 21); /* Wrote too much? */ check ((stpcpy (one, "xx") - one) == 2, 22); equal (one, "xx", 23); /* Writeover. */ equal (one+3, "defghi", 24); /* Wrote too much? */ check ((stpcpy (one, "xxx") - one) == 3, 25); equal (one, "xxx", 26); /* Writeover. */ equal (one+4, "efghi", 27); /* Wrote too much? */ check ((stpcpy (one, "xxxx") - one) == 4, 28); equal (one, "xxxx", 29); /* Writeover. */ equal (one+5, "fghi", 30); /* Wrote too much? */ check ((stpcpy (one, "xxxxx") - one) == 5, 31); equal (one, "xxxxx", 32); /* Writeover. */ equal (one+6, "ghi", 33); /* Wrote too much? */ check ((stpcpy (one, "xxxxxx") - one) == 6, 34); equal (one, "xxxxxx", 35); /* Writeover. */ equal (one+7, "hi", 36); /* Wrote too much? */ check ((stpcpy (one, "xxxxxxx") - one) == 7, 37); equal (one, "xxxxxxx", 38); /* Writeover. */ equal (one+8, "i", 39); /* Wrote too much? */ check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40); equal (one, "abc", 41); equal (one + 4, "xxx", 42); SIMPLE_COPY(stpcpy, 0, "", 43); SIMPLE_COPY(stpcpy, 1, "1", 44); SIMPLE_COPY(stpcpy, 2, "22", 45); SIMPLE_COPY(stpcpy, 3, "333", 46); SIMPLE_COPY(stpcpy, 4, "4444", 47); SIMPLE_COPY(stpcpy, 5, "55555", 48); SIMPLE_COPY(stpcpy, 6, "666666", 49); SIMPLE_COPY(stpcpy, 7, "7777777", 50); SIMPLE_COPY(stpcpy, 8, "88888888", 51); SIMPLE_COPY(stpcpy, 9, "999999999", 52); SIMPLE_COPY(stpcpy, 10, "0000000000", 53); SIMPLE_COPY(stpcpy, 11, "11111111111", 54); SIMPLE_COPY(stpcpy, 12, "222222222222", 55); SIMPLE_COPY(stpcpy, 13, "3333333333333", 56); SIMPLE_COPY(stpcpy, 14, "44444444444444", 57); SIMPLE_COPY(stpcpy, 15, "555555555555555", 58); SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);}static voidtest_stpncpy (void){ it = "stpncpy"; memset (one, 'x', sizeof (one)); check (stpncpy (one, "abc", 2) == one + 2, 1); check (stpncpy (one, "abc", 3) == one + 3, 2); check (stpncpy (one, "abc", 4) == one + 3, 3); check (one[3] == '\0' && one[4] == 'x', 4); check (stpncpy (one, "abcd", 5) == one + 4, 5); check (one[4] == '\0' && one[5] == 'x', 6); check (stpncpy (one, "abcd", 6) == one + 4, 7); check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);}static voidtest_strcat (void){ it = "strcat"; (void) strcpy (one, "ijk"); check (strcat (one, "lmn") == one, 1); /* Returned value. */ equal (one, "ijklmn", 2); /* Basic test. */ (void) strcpy (one, "x"); (void) strcat (one, "yz"); equal (one, "xyz", 3); /* Writeover. */ equal (one+4, "mn", 4); /* Wrote too much? */ (void) strcpy (one, "gh"); (void) strcpy (two, "ef"); (void) strcat (one, two); equal (one, "ghef", 5); /* Basic test encore. */ equal (two, "ef", 6); /* Stomped on source? */ (void) strcpy (one, ""); (void) strcat (one, ""); equal (one, "", 7); /* Boundary conditions. */ (void) strcpy (one, "ab"); (void) strcat (one, ""); equal (one, "ab", 8); (void) strcpy (one, ""); (void) strcat (one, "cd"); equal (one, "cd", 9);}static voidtest_strncat (void){ /* First test it as strcat, with big counts, then test the count mechanism. */ it = "strncat"; (void) strcpy (one, "ijk"); check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */ equal (one, "ijklmn", 2); /* Basic test. */ (void) strcpy (one, "x"); (void) strncat (one, "yz", 99); equal (one, "xyz", 3); /* Writeover. */ equal (one+4, "mn", 4); /* Wrote too much? */ (void) strcpy (one, "gh"); (void) strcpy (two, "ef"); (void) strncat (one, two, 99); equal (one, "ghef", 5); /* Basic test encore. */ equal (two, "ef", 6); /* Stomped on source? */ (void) strcpy (one, ""); (void) strncat (one, "", 99); equal (one, "", 7); /* Boundary conditions. */ (void) strcpy (one, "ab"); (void) strncat (one, "", 99); equal (one, "ab", 8); (void) strcpy (one, ""); (void) strncat (one, "cd", 99); equal (one, "cd", 9); (void) strcpy (one, "ab"); (void) strncat (one, "cdef", 2); equal (one, "abcd", 10); /* Count-limited. */ (void) strncat (one, "gh", 0); equal (one, "abcd", 11); /* Zero count. */ (void) strncat (one, "gh", 2); equal (one, "abcdgh", 12); /* Count and length equal. */}static voidtest_strncmp (void){ /* First test as strcmp with big counts, then test count code. */ it = "strncmp"; check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */ check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */ check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */ check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */ check (strncmp ("abcd", "abc", 99) > 0, 5); check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */ check (strncmp ("abce", "abcd", 99) > 0, 7); check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */ check (strncmp ("a\203", "a\003", 2) > 0, 9); check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */ check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */ check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */ check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */}static voidtest_strncpy (void){ /* Testing is a bit different because of odd semantics. */ it = "strncpy"; check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */ equal (one, "abc", 2); /* Did the copy go right? */ (void) strcpy (one, "abcdefgh"); (void) strncpy (one, "xyz", 2); equal (one, "xycdefgh", 3); /* Copy cut by count. */ (void) strcpy (one, "abcdefgh"); (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */ equal (one, "xyzdefgh", 4); (void) strcpy (one, "abcdefgh"); (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */ equal (one, "xyz", 5); equal (one+4, "efgh", 6); /* Wrote too much? */ (void) strcpy (one, "abcdefgh"); (void) strncpy (one, "xyz", 5); /* Copy includes padding. */ equal (one, "xyz", 7); equal (one+4, "", 8); equal (one+5, "fgh", 9); (void) strcpy (one, "abc"); (void) strncpy (one, "xyz", 0); /* Zero-length copy. */ equal (one, "abc", 10); (void) strncpy (one, "", 2); /* Zero-length source. */ equal (one, "", 11); equal (one+1, "", 12); equal (one+2, "c", 13); (void) strcpy (one, "hi there"); (void) strncpy (two, one, 9); equal (two, "hi there", 14); /* Just paranoia. */ equal (one, "hi there", 15); /* Stomped on source? */}static voidtest_strlen (void){ it = "strlen"; check (strlen ("") == 0, 1); /* Empty. */ check (strlen ("a") == 1, 2); /* Single char. */ check (strlen ("abcd") == 4, 3); /* Multiple chars. */ { char buf[4096]; int i; char *p; for (i=0; i < 0x100; i++) { p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i; strcpy (p, "OK"); strcpy (p+3, "BAD/WRONG"); check (strlen (p) == 2, 4+i); } }}static voidtest_strchr (void){ it = "strchr"; check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */ (void) strcpy (one, "abcd"); check (strchr (one, 'c') == one+2, 2); /* Basic test. */ check (strchr (one, 'd') == one+3, 3); /* End of string. */ check (strchr (one, 'a') == one, 4); /* Beginning. */ check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */ (void) strcpy (one, "ababa"); check (strchr (one, 'b') == one+1, 6); /* Finding first. */ (void) strcpy (one, ""); check (strchr (one, 'b') == NULL, 7); /* Empty string. */ check (strchr (one, '\0') == one, 8); /* NUL in empty string. */ { char buf[4096]; int i; char *p; for (i=0; i < 0x100; i++) { p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i; strcpy (p, "OK"); strcpy (p+3, "BAD/WRONG"); check (strchr (p, '/') == NULL, 9+i); } }}static voidtest_strchrnul (void){ const char *os; it = "strchrnul"; cp = strchrnul ((os = "abcd"), 'z'); check (*cp == '\0', 1); /* Not found. */ check (cp == os + 4, 2); (void) strcpy (one, "abcd"); check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */ check (strchrnul (one, 'd') == one+3, 4); /* End of string. */ check (strchrnul (one, 'a') == one, 5); /* Beginning. */ check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */ (void) strcpy (one, "ababa"); check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */ (void) strcpy (one, ""); check (strchrnul (one, 'b') == one, 8); /* Empty string. */ check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */ { char buf[4096]; int i; char *p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -