home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbmalloc.zip / testmem.c < prev    next >
C/C++ Source or Header  |  1993-01-04  |  25KB  |  752 lines

  1. /*
  2.  * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  3.  *
  4.  * This software may be distributed freely as long as the following conditions
  5.  * are met:
  6.  *         * the distribution, or any derivative thereof, may not be
  7.  *          included as part of a commercial product
  8.  *        * full source code is provided including this copyright
  9.  *        * there is no charge for the software itself (there may be
  10.  *          a minimal charge for the copying or distribution effort)
  11.  *        * this copyright notice is not modified or removed from any
  12.  *          source file
  13.  */
  14. /* 
  15.  * This stuff is all stolen (with permission, since it was in the public
  16.  * domain) from Henry Spencer's string and memory library.  Thanks Henry.
  17.  */
  18.  
  19. /*
  20.  * Test program for string(3) routines.
  21.  * 
  22.  * Note that at least one Bell Labs implementation of the string
  23.  * routines flunks a couple of these tests -- the ones which test
  24.  * behavior on "negative" characters.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <sys/types.h>
  29. #include "malloc.h"
  30.  
  31. #ifndef index
  32. char * index();
  33. char * rindex();
  34. #endif
  35.  
  36. VOIDTYPE    first();
  37. VOIDTYPE    second();
  38.  
  39. #define    STREQ(a, b)    (strcmp((a), (b)) == 0)
  40.  
  41. char *it = "<UNSET>";        /* Routine name for message routines. */
  42. int waserror = 0;        /* For exit status. */
  43.  
  44. STRCMPTYPE structest[] = "\004\203";    /* For testing signedness of chars. */
  45. MEMCMPTYPE memuctest[] = "\004\203";    /* For testing signedness of chars. */
  46. int strcharsigned;            /* Result. */
  47. int memcharsigned;            /* Result. */
  48.  
  49. /*
  50.  - check - complain if condition is not true
  51.  */
  52. VOIDTYPE
  53. check(thing, number)
  54. int thing;
  55. int number;            /* Test number for error message. */
  56. {
  57.     if (!thing) {
  58.         printf("%s flunked test %d\n", it, number);
  59.         waserror = 1;
  60.     }
  61. }
  62.  
  63. /*
  64.  - equal - complain if first two args don't strcmp as equal
  65.  */
  66. VOIDTYPE
  67. equal(a, b, number)
  68. char *a;
  69. char *b;
  70. int number;            /* Test number for error message. */
  71. {
  72.     check(a != NULL && b != NULL && STREQ(a, b), number);
  73. }
  74.  
  75. char one[50];
  76. char two[50];
  77.  
  78. #ifdef UNIXERR
  79. #define ERR 1
  80. #endif
  81. #ifdef BERKERR
  82. #define ERR 1
  83. #endif
  84. #ifdef ERR
  85. int f;
  86. extern char *sys_errlist[];
  87. extern int sys_nerr;
  88. extern int errno;
  89. #endif
  90.  
  91. /* ARGSUSED */
  92. int
  93. main(argc, argv)
  94. int argc;
  95. char *argv[];
  96. {
  97.     /*
  98.      * First, establish whether string chars are signed.
  99.      */
  100.     if (structest[0] < structest[1])
  101.         strcharsigned = 0;
  102.     else
  103.         strcharsigned = 1;
  104.  
  105.     /*
  106.      * then establish whether memory chars are signed.
  107.      */
  108.     if (memuctest[0] < memuctest[1])
  109.         memcharsigned = 0;
  110.     else
  111.         memcharsigned = 1;
  112.  
  113.     /*
  114.      * Then, do the rest of the work.  Split into two functions because
  115.      * some compilers get unhappy about a single immense function.
  116.      */
  117.     first();
  118.     second();
  119.  
  120.     exit((waserror) ? 1 : 0);
  121.     /*NOTREACHED*/
  122. }
  123.  
  124. VOIDTYPE
  125. first()
  126. {
  127.     /*
  128.      * Test strcmp first because we use it to test other things.
  129.      */
  130.     it = "strcmp";
  131.     check(strcmp("", "") == 0, 1);        /* Trivial case. */
  132.     check(strcmp("a", "a") == 0, 2);    /* Identity. */
  133.     check(strcmp("abc", "abc") == 0, 3);    /* Multicharacter. */
  134.     check(strcmp("abc", "abcd") < 0, 4);    /* Length mismatches. */
  135.     check(strcmp("abcd", "abc") > 0, 5);
  136.     check(strcmp("abcd", "abce") < 0, 6);    /* Honest miscompares. */
  137.     check(strcmp("abce", "abcd") > 0, 7);
  138.     check(strcmp("a\203", "a") > 0, 8);    /* Tricky if char signed. */
  139.     if (strcharsigned)            /* Sign-bit comparison. */
  140.         check(strcmp("a\203", "a\003") < 0, 9);
  141.     else
  142.         check(strcmp("a\203", "a\003") > 0, 9);
  143.     check(strcmp("a", "a\203") < 0, 10);    /* Tricky if char signed. */
  144.  
  145.     /*
  146.      * now test stricmp (make sure it does everything of strcmp and then
  147.      * some)
  148.      */
  149.     it = "stricmp";
  150.     check(stricmp("", "") == 0, 1);        /* Trivial case. */
  151.     check(stricmp("a", "a") == 0, 2);    /* Identity. */
  152.     check(stricmp("abc", "abc") == 0, 3);    /* Multicharacter. */
  153.     check(stricmp("abc", "abcd") < 0, 4);    /* Length mismatches. */
  154.     check(stricmp("abcd", "abc") > 0, 5);
  155.     check(stricmp("abcd", "abce") < 0, 6);    /* Honest miscompares. */
  156.     check(stricmp("abce", "abcd") > 0, 7);
  157.     check(stricmp("a\203", "a") > 0, 8);    /* Tricky if char signed. */
  158.     if (strcharsigned)            /* Sign-bit comparison. */
  159.         check(stricmp("a\203", "a\003") < 0, 9);
  160.     else
  161.         check(stricmp("a\203", "a\003") > 0, 9);
  162.     check(stricmp("a", "a\203") < 0, 10);    /* Tricky if char signed. */
  163.     check(stricmp("a", "A") == 0, 11);    /* Identity. */
  164.     check(stricmp("aBc", "abc") == 0, 12);    /* Multicharacter. */
  165.     check(stricmp("abC", "abcd") < 0, 13);    /* Length mismatches. */
  166.     check(stricmp("abcD", "abc") > 0, 14);
  167.     check(stricmp("abcD", "abce") < 0, 15);    /* Honest miscompares. */
  168.     check(stricmp("abcd", "abcE") < 0, 16);    /* Honest miscompares. */
  169.  
  170.     /*
  171.      * Test strcpy next because we need it to set up other tests.
  172.      */
  173.     it = "strcpy";
  174.     check(strcpy(one, "abcd") == one, 1);    /* Returned value. */
  175.     equal(one, "abcd", 2);            /* Basic test. */
  176.  
  177.     VOIDCAST strcpy(one, "x");
  178.     equal(one, "x", 3);            /* Writeover. */
  179.     equal(one+2, "cd", 4);            /* Wrote too much? */
  180.  
  181.     VOIDCAST strcpy(two, "hi there");
  182.     VOIDCAST strcpy(one, two);
  183.     equal(one, "hi there", 5);        /* Basic test encore. */
  184.     equal(two, "hi there", 6);        /* Stomped on source? */
  185.  
  186.     VOIDCAST strcpy(one, "");
  187.     equal(one, "", 7);            /* Boundary condition. */
  188.  
  189.     /*
  190.      * strcat
  191.      */
  192.     it = "strcat";
  193.     VOIDCAST strcpy(one, "ijk");
  194.     check(strcat(one, "lmn") == one, 1);    /* Returned value. */
  195.     equal(one, "ijklmn", 2);        /* Basic test. */
  196.  
  197.     VOIDCAST strcpy(one, "x");
  198.     VOIDCAST strcat(one, "yz");
  199.     equal(one, "xyz", 3);            /* Writeover. */
  200.     equal(one+4, "mn", 4);            /* Wrote too much? */
  201.  
  202.     VOIDCAST strcpy(one, "gh");
  203.     VOIDCAST strcpy(two, "ef");
  204.     VOIDCAST strcat(one, two);
  205.     equal(one, "ghef", 5);            /* Basic test encore. */
  206.     equal(two, "ef", 6);            /* Stomped on source? */
  207.  
  208.     VOIDCAST strcpy(one, "");
  209.     VOIDCAST strcat(one, "");
  210.     equal(one, "", 7);            /* Boundary conditions. */
  211.     VOIDCAST strcpy(one, "ab");
  212.     VOIDCAST strcat(one, "");
  213.     equal(one, "ab", 8);
  214.     VOIDCAST strcpy(one, "");
  215.     VOIDCAST strcat(one, "cd");
  216.     equal(one, "cd", 9);
  217.  
  218.     /*
  219.      * strncat - first test it as strcat, with big counts, then
  220.      * test the count mechanism.
  221.      */
  222.     it = "strncat";
  223.     VOIDCAST strcpy(one, "ijk");
  224.     check(strncat(one, "lmn", 99) == one, 1);    /* Returned value. */
  225.     equal(one, "ijklmn", 2);        /* Basic test. */
  226.  
  227.     VOIDCAST strcpy(one, "x");
  228.     VOIDCAST strncat(one, "yz", 99);
  229.     equal(one, "xyz", 3);            /* Writeover. */
  230.     equal(one+4, "mn", 4);            /* Wrote too much? */
  231.  
  232.     VOIDCAST strcpy(one, "gh");
  233.     VOIDCAST strcpy(two, "ef");
  234.     VOIDCAST strncat(one, two, 99);
  235.     equal(one, "ghef", 5);            /* Basic test encore. */
  236.     equal(two, "ef", 6);            /* Stomped on source? */
  237.  
  238.     VOIDCAST strcpy(one, "");
  239.     VOIDCAST strncat(one, "", 99);
  240.     equal(one, "", 7);            /* Boundary conditions. */
  241.     VOIDCAST strcpy(one, "ab");
  242.     VOIDCAST strncat(one, "", 99);
  243.     equal(one, "ab", 8);
  244.     VOIDCAST strcpy(one, "");
  245.     VOIDCAST strncat(one, "cd", 99);
  246.     equal(one, "cd", 9);
  247.  
  248.     VOIDCAST strcpy(one, "ab");
  249.     VOIDCAST strncat(one, "cdef", 2);
  250.     equal(one, "abcd", 10);            /* Count-limited. */
  251.  
  252.     VOIDCAST strncat(one, "gh", 0);
  253.     equal(one, "abcd", 11);            /* Zero count. */
  254.  
  255.     VOIDCAST strncat(one, "gh", 2);
  256.     equal(one, "abcdgh", 12);        /* Count and length equal. */
  257.  
  258.     /*
  259.      * strncmp - first test as strcmp with big counts, then test
  260.      * count code.
  261.      */
  262.     it = "strncmp";
  263.     check(strncmp("", "", 99) == 0, 1);    /* Trivial case. */
  264.     check(strncmp("a", "a", 99) == 0, 2);    /* Identity. */
  265.     check(strncmp("abc", "abc", 99) == 0, 3);    /* Multicharacter. */
  266.     check(strncmp("abc", "abcd", 99) < 0, 4);    /* Length unequal. */
  267.     check(strncmp("abcd", "abc", 99) > 0, 5);
  268.     check(strncmp("abcd", "abce", 99) < 0, 6);    /* Honestly unequal. */
  269.     check(strncmp("abce", "abcd", 99) > 0, 7);
  270.     check(strncmp("a\203", "a", 2) > 0, 8);    /* Tricky if '\203' < 0 */
  271.     if (strcharsigned)            /* Sign-bit comparison. */
  272.         check(strncmp("a\203", "a\003", 2) < 0, 9);
  273.     else
  274.         check(strncmp("a\203", "a\003", 2) > 0, 9);
  275.     check(strncmp("abce", "abcd", 3) == 0, 10);    /* Count limited. */
  276.     check(strncmp("abce", "abc", 3) == 0, 11);    /* Count == length. */
  277.     check(strncmp("abcd", "abce", 4) < 0, 12);    /* Nudging limit. */
  278.     check(strncmp("abc", "def", 0) == 0, 13);    /* Zero count. */
  279.  
  280.     /*
  281.      * strincmp - first test as strincmp with big counts, then test
  282.      * count code, then test with different cases
  283.      */
  284.     it = "strincmp";
  285.     check(strincmp("", "", 99) == 0, 1);    /* Trivial case. */
  286.     check(strincmp("a", "a", 99) == 0, 2);    /* Identity. */
  287.     check(strincmp("abc", "abc", 99) == 0, 3);    /* Multicharacter. */
  288.     check(strincmp("abc", "abcd", 99) < 0, 4);    /* Length unequal. */
  289.     check(strincmp("abcd", "abc", 99) > 0, 5);
  290.     check(strincmp("abcd", "abce", 99) < 0, 6);    /* Honestly unequal. */
  291.     check(strincmp("abce", "abcd", 99) > 0, 7);
  292.     check(strincmp("a\203", "a", 2) > 0, 8);/* Tricky if '\203' < 0 */
  293.     if (strcharsigned)            /* Sign-bit comparison. */
  294.         check(strincmp("a\203", "a\003", 2) < 0, 9);
  295.     else
  296.         check(strincmp("a\203", "a\003", 2) > 0, 9);
  297.     check(strincmp("abce", "abcd", 3) == 0, 10);    /* Count limited. */
  298.     check(strincmp("abce", "abc", 3) == 0, 11);    /* Count == length. */
  299.     check(strincmp("abcd", "abce", 4) < 0, 12);    /* Nudging limit. */
  300.     check(strincmp("abc", "def", 0) == 0, 13);    /* Zero count. */
  301.  
  302.     check(strincmp("a", "A", 99) == 0, 14);    /* Identity. */
  303.     check(strincmp("abC", "abc", 99) == 0, 15);    /* Multicharacter. */
  304.     check(strincmp("abC", "abcd", 99) < 0, 16);    /* Length unequal. */
  305.     check(strincmp("abcd", "Abc", 99) > 0, 17);
  306.     check(strincmp("abcD", "abce", 99) < 0, 18);    /* Honestly unequal. */
  307.     check(strincmp("abcE", "abcd", 99) > 0, 19);
  308.     check(strincmp("abce", "abcd", 99) > 0, 20);
  309.  
  310.     /*
  311.      * strncpy - testing is a bit different because of odd semantics
  312.      */
  313.     it = "strncpy";
  314.     check(strncpy(one, "abc", 4) == one, 1);    /* Returned value. */
  315.     equal(one, "abc", 2);            /* Did the copy go right? */
  316.  
  317.     VOIDCAST strcpy(one, "abcdefgh");
  318.     VOIDCAST strncpy(one, "xyz", 2);
  319.     equal(one, "xycdefgh", 3);        /* Copy cut by count. */
  320.  
  321.     VOIDCAST strcpy(one, "abcdefgh");
  322.     VOIDCAST strncpy(one, "xyz", 3);    /* Copy cut just before NUL. */
  323.     equal(one, "xyzdefgh", 4);
  324.  
  325.     VOIDCAST strcpy(one, "abcdefgh");
  326.     VOIDCAST strncpy(one, "xyz", 4);    /* Copy just includes NUL. */
  327.     equal(one, "xyz", 5);
  328.     equal(one+4, "efgh", 6);        /* Wrote too much? */
  329.  
  330.     VOIDCAST strcpy(one, "abcdefgh");
  331.     VOIDCAST strncpy(one, "xyz", 5);    /* Copy includes padding. */
  332.     equal(one, "xyz", 7);
  333.     equal(one+4, "", 8);
  334.     equal(one+5, "fgh", 9);
  335.  
  336.     VOIDCAST strcpy(one, "abc");
  337.     VOIDCAST strncpy(one, "xyz", 0);    /* Zero-length copy. */
  338.     equal(one, "abc", 10);    
  339.  
  340.     VOIDCAST strncpy(one, "", 2);        /* Zero-length source. */
  341.     equal(one, "", 11);
  342.     equal(one+1, "", 12);    
  343.     equal(one+2, "c", 13);
  344.  
  345.     VOIDCAST strcpy(one, "hi there");
  346.     VOIDCAST strncpy(two, one, 9);
  347.     equal(two, "hi there", 14);        /* Just paranoia. */
  348.     equal(one, "hi there", 15);        /* Stomped on source? */
  349.  
  350.     /*
  351.      * strlen
  352.      */
  353.     it = "strlen";
  354.     check(strlen("") == 0, 1);        /* Empty. */
  355.     check(strlen("a") == 1, 2);        /* Single char. */
  356.     check(strlen("abcd") == 4, 3);        /* Multiple chars. */
  357.  
  358.     /*
  359.      * strchr
  360.      */
  361.     it = "strchr";
  362.     check(strchr("abcd", 'z') == NULL, 1);    /* Not found. */
  363.     VOIDCAST strcpy(one, "abcd");
  364.     check(strchr(one, 'c') == one+2, 2);    /* Basic test. */
  365.     check(strchr(one, 'd') == one+3, 3);    /* End of string. */
  366.     check(strchr(one, 'a') == one, 4);    /* Beginning. */
  367.     check(strchr(one, '\0') == one+4, 5);    /* Finding NUL. */
  368.     VOIDCAST strcpy(one, "ababa");
  369.     check(strchr(one, 'b') == one+1, 6);    /* Finding first. */
  370.     VOIDCAST strcpy(one, "");
  371.     check(strchr(one, 'b') == NULL, 7);    /* Empty string. */
  372.     check(strchr(one, '\0') == one, 8);    /* NUL in empty string. */
  373.  
  374.     /*
  375.      * strstr (minimal testing added by cpc)
  376.      */
  377.     it = "strstr";
  378.     check(strstr("abcd", "z") == NULL, 1);    /* Not found. */
  379.     VOIDCAST strcpy(one, "abcd");
  380.     check(strstr(one, "c") == one+2, 2);    /* Basic test. */
  381.     check(strstr(one, "cd") == one+2, 3);    /* Basic test. */
  382.     check(strstr(one, "d") == one+3, 4);    /* End of string. */
  383.     check(strstr(one, "a") == one, 5);    /* Beginning. */
  384.     check(strstr(one, "") == one, 6);    /* Finding NUL. */
  385.     VOIDCAST strcpy(one, "ababa");
  386.     check(strstr(one, "b") == one+1, 7);    /* Finding first. */
  387.     VOIDCAST strcpy(one, "");
  388.     check(strstr(one, "b") == NULL, 8);    /* Empty string. */
  389.     check(strstr(one, "") == one, 9);    /* NUL in empty string. */
  390.  
  391.     /*
  392.      * index - just like strchr
  393.      */
  394.     it = "index";
  395.     check(index("abcd", 'z') == NULL, 1);    /* Not found. */
  396.     VOIDCAST strcpy(one, "abcd");
  397.     check(index(one, 'c') == one+2, 2);    /* Basic test. */
  398.     check(index(one, 'd') == one+3, 3);    /* End of string. */
  399.     check(index(one, 'a') == one, 4);    /* Beginning. */
  400.     check(index(one, '\0') == one+4, 5);    /* Finding NUL. */
  401.     VOIDCAST strcpy(one, "ababa");
  402.     check(index(one, 'b') == one+1, 6);    /* Finding first. */
  403.     VOIDCAST strcpy(one, "");
  404.     check(index(one, 'b') == NULL, 7);    /* Empty string. */
  405.     check(index(one, '\0') == one, 8);    /* NUL in empty string. */
  406.  
  407.     /*
  408.      * strrchr
  409.      */
  410.     it = "strrchr";
  411.     check(strrchr("abcd", 'z') == NULL, 1);    /* Not found. */
  412.     VOIDCAST strcpy(one, "abcd");
  413.     check(strrchr(one, 'c') == one+2, 2);    /* Basic test. */
  414.     check(strrchr(one, 'd') == one+3, 3);    /* End of string. */
  415.     check(strrchr(one, 'a') == one, 4);    /* Beginning. */
  416.     check(strrchr(one, '\0') == one+4, 5);    /* Finding NUL. */
  417.     VOIDCAST strcpy(one, "ababa");
  418.     check(strrchr(one, 'b') == one+3, 6);    /* Finding last. */
  419.     VOIDCAST strcpy(one, "");
  420.     check(strrchr(one, 'b') == NULL, 7);    /* Empty string. */
  421.     check(strrchr(one, '\0') == one, 8);    /* NUL in empty string. */
  422.  
  423.     /*
  424.      * rindex - just like strrchr
  425.      */
  426.     it = "rindex";
  427.     check(rindex("abcd", 'z') == NULL, 1);    /* Not found. */
  428.     VOIDCAST strcpy(one, "abcd");
  429.     check(rindex(one, 'c') == one+2, 2);    /* Basic test. */
  430.     check(rindex(one, 'd') == one+3, 3);    /* End of string. */
  431.     check(rindex(one, 'a') == one, 4);    /* Beginning. */
  432.     check(rindex(one, '\0') == one+4, 5);    /* Finding NUL. */
  433.     VOIDCAST strcpy(one, "ababa");
  434.     check(rindex(one, 'b') == one+3, 6);    /* Finding last. */
  435.     VOIDCAST strcpy(one, "");
  436.     check(rindex(one, 'b') == NULL, 7);    /* Empty string. */
  437.     check(rindex(one, '\0') == one, 8);    /* NUL in empty string. */
  438. }
  439.  
  440. VOIDTYPE
  441. second()
  442. {
  443.     /*
  444.      * strpbrk - somewhat like strchr
  445.      */
  446.     it = "strpbrk";
  447.     check(strpbrk("abcd", "z") == NULL, 1);    /* Not found. */
  448.     VOIDCAST strcpy(one, "abcd");
  449.     check(strpbrk(one, "c") == one+2, 2);    /* Basic test. */
  450.     check(strpbrk(one, "d") == one+3, 3);    /* End of string. */
  451.     check(strpbrk(one, "a") == one, 4);    /* Beginning. */
  452.     check(strpbrk(one, "") == NULL, 5);    /* Empty search list. */
  453.     check(strpbrk(one, "cb") == one+1, 6);    /* Multiple search. */
  454.     VOIDCAST strcpy(one, "abcabdea");
  455.     check(strpbrk(one, "b") == one+1, 7);    /* Finding first. */
  456.     check(strpbrk(one, "cb") == one+1, 8);    /* With multiple search. */
  457.     check(strpbrk(one, "db") == one+1, 9);    /* Another variant. */
  458.     VOIDCAST strcpy(one, "");
  459.     check(strpbrk(one, "bc") == NULL, 10);    /* Empty string. */
  460.     check(strpbrk(one, "") == NULL, 11);    /* Both strings empty. */
  461.  
  462. #if 0
  463.     /*
  464.      * strstr - somewhat like strchr
  465.      */
  466.     it = "strstr";
  467.     check(strstr("abcd", "z") == NULL, 1);    /* Not found. */
  468.     check(strstr("abcd", "abx") == NULL, 2);    /* Dead end. */
  469.     VOIDCAST strcpy(one, "abcd");
  470.     check(strstr(one, "c") == one+2, 3);    /* Basic test. */
  471.     check(strstr(one, "bc") == one+1, 4);    /* Multichar. */
  472.     check(strstr(one, "d") == one+3, 5);    /* End of string. */
  473.     check(strstr(one, "cd") == one+2, 6);    /* Tail of string. */
  474.     check(strstr(one, "abc") == one, 7);    /* Beginning. */
  475.     check(strstr(one, "abcd") == one, 8);    /* Exact match. */
  476.     check(strstr(one, "abcde") == NULL, 9);    /* Too long. */
  477.     check(strstr(one, "de") == NULL, 10);    /* Past end. */
  478.     check(strstr(one, "") == one+4, 11);    /* Finding empty. */
  479.     VOIDCAST strcpy(one, "ababa");
  480.     check(strstr(one, "ba") == one+1, 12);    /* Finding first. */
  481.     VOIDCAST strcpy(one, "");
  482.     check(strstr(one, "b") == NULL, 13);    /* Empty string. */
  483.     check(strstr(one, "") == one, 14);    /* Empty in empty string. */
  484.     VOIDCAST strcpy(one, "bcbca");
  485.     check(strstr(one, "bca") == one+2, 15);    /* False start. */
  486.     VOIDCAST strcpy(one, "bbbcabbca");
  487.     check(strstr(one, "bbca") == one+1, 16);    /* With overlap. */
  488. #endif
  489.  
  490.     /*
  491.      * strspn
  492.      */
  493.     it = "strspn";
  494.     check(strspn("abcba", "abc") == 5, 1);    /* Whole string. */
  495.     check(strspn("abcba", "ab") == 2, 2);    /* Partial. */
  496.     check(strspn("abc", "qx") == 0, 3);    /* None. */
  497.     check(strspn("", "ab") == 0, 4);    /* Null string. */
  498.     check(strspn("abc", "") == 0, 5);    /* Null search list. */
  499.  
  500.     /*
  501.      * strcspn
  502.      */
  503.     it = "strcspn";
  504.     check(strcspn("abcba", "qx") == 5, 1);    /* Whole string. */
  505.     check(strcspn("abcba", "cx") == 2, 2);    /* Partial. */
  506.     check(strcspn("abc", "abc") == 0, 3);    /* None. */
  507.     check(strcspn("", "ab") == 0, 4);    /* Null string. */
  508.     check(strcspn("abc", "") == 3, 5);    /* Null search list. */
  509.  
  510.     /*
  511.      * strtok - the hard one
  512.      */
  513.     it = "strtok";
  514.     VOIDCAST strcpy(one, "first, second, third");
  515.     equal(strtok(one, ", "), "first", 1);    /* Basic test. */
  516.     equal(one, "first", 2);
  517.     equal(strtok((char *)NULL, ", "), "second", 3);
  518.     equal(strtok((char *)NULL, ", "), "third", 4);
  519.     check(strtok((char *)NULL, ", ") == NULL, 5);
  520.     VOIDCAST strcpy(one, ", first, ");
  521.     equal(strtok(one, ", "), "first", 6);    /* Extra delims, 1 tok. */
  522.     check(strtok((char *)NULL, ", ") == NULL, 7);
  523.     VOIDCAST strcpy(one, "1a, 1b; 2a, 2b");
  524.     equal(strtok(one, ", "), "1a", 8);    /* Changing delim lists. */
  525.     equal(strtok((char *)NULL, "; "), "1b", 9);
  526.     equal(strtok((char *)NULL, ", "), "2a", 10);
  527.     VOIDCAST strcpy(two, "x-y");
  528.     equal(strtok(two, "-"), "x", 11);    /* New string before done. */
  529.     equal(strtok((char *)NULL, "-"), "y", 12);
  530.     check(strtok((char *)NULL, "-") == NULL, 13);
  531.     VOIDCAST strcpy(one, "a,b, c,, ,d");
  532.     equal(strtok(one, ", "), "a", 14);    /* Different separators. */
  533.     equal(strtok((char *)NULL, ", "), "b", 15);
  534.     equal(strtok((char *)NULL, " ,"), "c", 16);    /* Permute list too. */
  535.     equal(strtok((char *)NULL, " ,"), "d", 17);
  536.     check(strtok((char *)NULL, ", ") == NULL, 18);
  537.     check(strtok((char *)NULL, ", ") == NULL, 19);    /* Persistence. */
  538.     VOIDCAST strcpy(one, ", ");
  539.     check(strtok(one, ", ") == NULL, 20);    /* No tokens. */
  540.     VOIDCAST strcpy(one, "");
  541.     check(strtok(one, ", ") == NULL, 21);    /* Empty string. */
  542.     VOIDCAST strcpy(one, "abc");
  543.     equal(strtok(one, ", "), "abc", 22);    /* No delimiters. */
  544.     check(strtok((char *)NULL, ", ") == NULL, 23);
  545.     VOIDCAST strcpy(one, "abc");
  546.     equal(strtok(one, ""), "abc", 24);    /* Empty delimiter list. */
  547.     check(strtok((char *)NULL, "") == NULL, 25);
  548.     VOIDCAST strcpy(one, "abcdefgh");
  549.     VOIDCAST strcpy(one, "a,b,c");
  550.     equal(strtok(one, ","), "a", 26);    /* Basics again... */
  551.     equal(strtok((char *)NULL, ","), "b", 27);
  552.     equal(strtok((char *)NULL, ","), "c", 28);
  553.     check(strtok((char *)NULL, ",") == NULL, 29);
  554.     equal(one+6, "gh", 30);            /* Stomped past end? */
  555.     equal(one, "a", 31);            /* Stomped old tokens? */
  556.     equal(one+2, "b", 32);
  557.     equal(one+4, "c", 33);
  558.  
  559.     /*
  560.      * memcmp
  561.      */
  562.     it = "memcmp";
  563.     check(memcmp("a", "a", 1) == 0, 1);    /* Identity. */
  564.     check(memcmp("abc", "abc", 3) == 0, 2);    /* Multicharacter. */
  565.     check(memcmp("abcd", "abce", 4) < 0, 3);    /* Honestly unequal. */
  566.     check(memcmp("abce", "abcd", 4) > 0, 4);
  567.     check(memcmp("alph", "beta", 4) < 0, 5);
  568.     if (memcharsigned)            /* Sign-bit comparison. */
  569.         check(memcmp("a\203", "a\003", 2) < 0, 6);
  570.     else
  571.         check(memcmp("a\203", "a\003", 2) > 0, 6);
  572.     check(memcmp("abce", "abcd", 3) == 0, 7);    /* Count limited. */
  573.     check(memcmp("abc", "def", 0) == 0, 8);    /* Zero count. */
  574.  
  575.     /*
  576.      * memchr
  577.      */
  578.     it = "memchr";
  579.     check(memchr("abcd", 'z', 4) == NULL, 1);    /* Not found. */
  580.     VOIDCAST strcpy(one, "abcd");
  581.     check(memchr(one, 'c', 4) == one+2, 2);    /* Basic test. */
  582.     check(memchr(one, 'd', 4) == one+3, 3);    /* End of string. */
  583.     check(memchr(one, 'a', 4) == one, 4);    /* Beginning. */
  584.     check(memchr(one, '\0', 5) == one+4, 5);    /* Finding NUL. */
  585.     VOIDCAST strcpy(one, "ababa");
  586.     check(memchr(one, 'b', 5) == one+1, 6);    /* Finding first. */
  587.     check(memchr(one, 'b', 0) == NULL, 7);    /* Zero count. */
  588.     check(memchr(one, 'a', 1) == one, 8);    /* Singleton case. */
  589.     VOIDCAST strcpy(one, "a\203b");
  590.     check(memchr(one, 0203, 3) == one+1, 9);    /* Unsignedness. */
  591.  
  592.     /*
  593.      * memcpy
  594.      *
  595.      * Note that X3J11 says memcpy must work regardless of overlap.
  596.      * The SVID says it might fail.
  597.      */
  598.     it = "memcpy";
  599.     check(memcpy(one, "abc", 4) == one, 1);    /* Returned value. */
  600.     equal(one, "abc", 2);            /* Did the copy go right? */
  601.  
  602.     VOIDCAST strcpy(one, "abcdefgh");
  603.     VOIDCAST memcpy(one+1, "xyz", 2);
  604.     equal(one, "axydefgh", 3);        /* Basic test. */
  605.  
  606.     VOIDCAST strcpy(one, "abc");
  607.     VOIDCAST memcpy(one, "xyz", 0);
  608.     equal(one, "abc", 4);            /* Zero-length copy. */
  609.  
  610.     VOIDCAST strcpy(one, "hi there");
  611.     VOIDCAST strcpy(two, "foo");
  612.     VOIDCAST memcpy(two, one, 9);
  613.     equal(two, "hi there", 5);        /* Just paranoia. */
  614.     equal(one, "hi there", 6);        /* Stomped on source? */
  615.  
  616.     VOIDCAST strcpy(one, "abcdefgh");
  617.     VOIDCAST memcpy(one+1, one, 9);
  618.     equal(one, "aabcdefgh", 7);        /* Overlap, right-to-left. */
  619.  
  620.     VOIDCAST strcpy(one, "abcdefgh");
  621.     VOIDCAST memcpy(one+1, one+2, 7);
  622.     equal(one, "acdefgh", 8);        /* Overlap, left-to-right. */
  623.  
  624.     VOIDCAST strcpy(one, "abcdefgh");
  625.     VOIDCAST memcpy(one, one, 9);
  626.     equal(one, "abcdefgh", 9);        /* 100% overlap. */
  627.  
  628.     /*
  629.      * memccpy - first test like memcpy, then the search part
  630.      *
  631.      * The SVID, the only place where memccpy is mentioned, says
  632.      * overlap might fail, so we don't try it.  Besides, it's hard
  633.      * to see the rationale for a non-left-to-right memccpy.
  634.      */
  635.     it = "memccpy";
  636.     check(memccpy(one, "abc", 'q', 4) == NULL, 1);    /* Returned value. */
  637.     equal(one, "abc", 2);            /* Did the copy go right? */
  638.  
  639.     VOIDCAST strcpy(one, "abcdefgh");
  640.     VOIDCAST memccpy(one+1, "xyz", 'q', 2);
  641.     equal(one, "axydefgh", 3);        /* Basic test. */
  642.  
  643.     VOIDCAST strcpy(one, "abc");
  644.     VOIDCAST memccpy(one, "xyz", 'q', 0);
  645.     equal(one, "abc", 4);            /* Zero-length copy. */
  646.  
  647.     VOIDCAST strcpy(one, "hi there");
  648.     VOIDCAST strcpy(two, "foo");
  649.     VOIDCAST memccpy(two, one, 'q', 9);
  650.     equal(two, "hi there", 5);        /* Just paranoia. */
  651.     equal(one, "hi there", 6);        /* Stomped on source? */
  652.  
  653.     VOIDCAST strcpy(one, "abcdefgh");
  654.     VOIDCAST strcpy(two, "horsefeathers");
  655.     check(memccpy(two, one, 'f', 9) == two+6, 7);    /* Returned value. */
  656.     equal(one, "abcdefgh", 8);        /* Source intact? */
  657.     equal(two, "abcdefeathers", 9);        /* Copy correct? */
  658.  
  659.     VOIDCAST strcpy(one, "abcd");
  660.     VOIDCAST strcpy(two, "bumblebee");
  661.     check(memccpy(two, one, 'a', 4) == two+1, 10);    /* First char. */
  662.     equal(two, "aumblebee", 11);
  663.     check(memccpy(two, one, 'd', 4) == two+4, 12);    /* Last char. */
  664.     equal(two, "abcdlebee", 13);
  665.     VOIDCAST strcpy(one, "xyz");
  666.     check(memccpy(two, one, 'x', 1) == two+1, 14);    /* Singleton. */
  667.     equal(two, "xbcdlebee", 15);
  668.  
  669.     /*
  670.      * memset
  671.      */
  672.     it = "memset";
  673.     VOIDCAST strcpy(one, "abcdefgh");
  674.     check(memset(one+1, 'x', 3) == one+1, 1);    /* Return value. */
  675.     equal(one, "axxxefgh", 2);        /* Basic test. */
  676.  
  677.     VOIDCAST memset(one+2, 'y', 0);
  678.     equal(one, "axxxefgh", 3);        /* Zero-length set. */
  679.  
  680.     VOIDCAST memset(one+5, 0, 1);
  681.     equal(one, "axxxe", 4);            /* Zero fill. */
  682.     equal(one+6, "gh", 5);            /* And the leftover. */
  683.  
  684.     VOIDCAST memset(one+2, 010045, 1);
  685.     equal(one, "ax\045xe", 6);        /* Unsigned char convert. */
  686.  
  687.     /*
  688.      * bcopy - much like memcpy
  689.      *
  690.      * Berklix manual is silent about overlap, so don't test it.
  691.      */
  692.     it = "bcopy";
  693.     VOIDCAST bcopy("abc", one, 4);
  694.     equal(one, "abc", 1);            /* Simple copy. */
  695.  
  696.     VOIDCAST strcpy(one, "abcdefgh");
  697.     VOIDCAST bcopy("xyz", one+1, 2);
  698.     equal(one, "axydefgh", 2);        /* Basic test. */
  699.  
  700.     VOIDCAST strcpy(one, "abc");
  701.     VOIDCAST bcopy("xyz", one, 0);
  702.     equal(one, "abc", 3);            /* Zero-length copy. */
  703.  
  704.     VOIDCAST strcpy(one, "hi there");
  705.     VOIDCAST strcpy(two, "foo");
  706.     VOIDCAST bcopy(one, two, 9);
  707.     equal(two, "hi there", 4);        /* Just paranoia. */
  708.     equal(one, "hi there", 5);        /* Stomped on source? */
  709.  
  710.     /*
  711.      * bzero
  712.      */
  713.     it = "bzero";
  714.     VOIDCAST strcpy(one, "abcdef");
  715.     bzero(one+2, 2);
  716.     equal(one, "ab", 1);            /* Basic test. */
  717.     equal(one+3, "", 2);
  718.     equal(one+4, "ef", 3);
  719.  
  720.     VOIDCAST strcpy(one, "abcdef");
  721.     bzero(one+2, 0);
  722.     equal(one, "abcdef", 4);        /* Zero-length copy. */
  723.  
  724.     /*
  725.      * bcmp - somewhat like memcmp
  726.      */
  727.     it = "bcmp";
  728.     check(bcmp("a", "a", 1) == 0, 1);    /* Identity. */
  729.     check(bcmp("abc", "abc", 3) == 0, 2);    /* Multicharacter. */
  730.     check(bcmp("abcd", "abce", 4) != 0, 3);    /* Honestly unequal. */
  731.     check(bcmp("abce", "abcd", 4) != 0, 4);
  732.     check(bcmp("alph", "beta", 4) != 0, 5);
  733.     check(bcmp("abce", "abcd", 3) == 0, 6);    /* Count limited. */
  734.     check(bcmp("abc", "def", 0) == 0, 8);    /* Zero count. */
  735.  
  736. #ifdef ERR
  737.     /*
  738.      * strerror - VERY system-dependent
  739.      */
  740.     it = "strerror";
  741.     f = open("/", 1);    /* Should always fail. */
  742.     check(f < 0 && errno > 0 && errno < sys_nerr, 1);
  743.     equal(strerror(errno), sys_errlist[errno], 2);
  744. #ifdef UNIXERR
  745.     equal(strerror(errno), "Is a directory", 3);
  746. #endif
  747. #ifdef BERKERR
  748.     equal(strerror(errno), "Permission denied", 3);
  749. #endif
  750. #endif
  751. }
  752.