Home | History | Annotate | Line # | Download | only in string
      1  1.1  christos /* $NetBSD: t_strchrnul.c,v 1.1 2023/01/30 19:49:49 christos Exp $ */
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Written by J.T. Conklin <jtc (at) acorntoolworks.com>
      5  1.1  christos  * Public domain.
      6  1.1  christos  */
      7  1.1  christos 
      8  1.1  christos #include <atf-c.h>
      9  1.1  christos #include <string.h>
     10  1.1  christos #include <unistd.h>
     11  1.1  christos #include <stdio.h>
     12  1.1  christos #include <stdlib.h>
     13  1.1  christos #include <dlfcn.h>
     14  1.1  christos 
     15  1.1  christos static char	*slow_strchrnul(char *, int);
     16  1.1  christos static void	 verify_strchrnul(char *, int, unsigned int, unsigned int);
     17  1.1  christos 
     18  1.1  christos char * (*volatile strchrnul_fn)(const char *, int);
     19  1.1  christos 
     20  1.1  christos static char *
     21  1.1  christos slow_strchrnul(char *buf, int ch)
     22  1.1  christos {
     23  1.1  christos 	unsigned char c = 1;
     24  1.1  christos 
     25  1.1  christos 	ch &= 0xff;
     26  1.1  christos 
     27  1.1  christos 	for (; ; buf++) {
     28  1.1  christos 		c = *buf;
     29  1.1  christos 		if (c == ch || c == 0)
     30  1.1  christos 			return buf;
     31  1.1  christos 	}
     32  1.1  christos }
     33  1.1  christos 
     34  1.1  christos static void
     35  1.1  christos verify_strchrnul(char *buf, int ch, unsigned int t, unsigned int a)
     36  1.1  christos {
     37  1.1  christos 	const char *off, *ok_off;
     38  1.1  christos 
     39  1.1  christos 	off = strchrnul_fn(buf, ch);
     40  1.1  christos 	ok_off = slow_strchrnul(buf, ch);
     41  1.1  christos 	if (off == ok_off)
     42  1.1  christos 		return;
     43  1.1  christos 
     44  1.1  christos 	fprintf(stderr, "test_strchrnul(\"%s\", %#x) gave %zd not %zd (test %d, "
     45  1.1  christos 	    "alignment %d)\n",
     46  1.1  christos 	    buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
     47  1.1  christos 
     48  1.1  christos 	atf_tc_fail("Check stderr for details");
     49  1.1  christos }
     50  1.1  christos 
     51  1.1  christos ATF_TC(strchrnul_basic);
     52  1.1  christos ATF_TC_HEAD(strchrnul_basic, tc)
     53  1.1  christos {
     54  1.1  christos 
     55  1.1  christos         atf_tc_set_md_var(tc, "descr", "Test strchrnul(3) results");
     56  1.1  christos }
     57  1.1  christos 
     58  1.1  christos ATF_TC_BODY(strchrnul_basic, tc)
     59  1.1  christos {
     60  1.1  christos 	void *dl_handle;
     61  1.1  christos 	char *off;
     62  1.1  christos 	char buf[32];
     63  1.1  christos 	unsigned int t, a;
     64  1.1  christos 
     65  1.1  christos 	const char *tab[] = {
     66  1.1  christos 		"",
     67  1.1  christos 		"a",
     68  1.1  christos 		"aa",
     69  1.1  christos 		"abc",
     70  1.1  christos 		"abcd",
     71  1.1  christos 		"abcde",
     72  1.1  christos 		"abcdef",
     73  1.1  christos 		"abcdefg",
     74  1.1  christos 		"abcdefgh",
     75  1.1  christos 
     76  1.1  christos 		"/",
     77  1.1  christos 		"//",
     78  1.1  christos 		"/a",
     79  1.1  christos 		"/a/",
     80  1.1  christos 		"/ab",
     81  1.1  christos 		"/ab/",
     82  1.1  christos 		"/abc",
     83  1.1  christos 		"/abc/",
     84  1.1  christos 		"/abcd",
     85  1.1  christos 		"/abcd/",
     86  1.1  christos 		"/abcde",
     87  1.1  christos 		"/abcde/",
     88  1.1  christos 		"/abcdef",
     89  1.1  christos 		"/abcdef/",
     90  1.1  christos 		"/abcdefg",
     91  1.1  christos 		"/abcdefg/",
     92  1.1  christos 		"/abcdefgh",
     93  1.1  christos 		"/abcdefgh/",
     94  1.1  christos 
     95  1.1  christos 		"a/",
     96  1.1  christos 		"a//",
     97  1.1  christos 		"a/a",
     98  1.1  christos 		"a/a/",
     99  1.1  christos 		"a/ab",
    100  1.1  christos 		"a/ab/",
    101  1.1  christos 		"a/abc",
    102  1.1  christos 		"a/abc/",
    103  1.1  christos 		"a/abcd",
    104  1.1  christos 		"a/abcd/",
    105  1.1  christos 		"a/abcde",
    106  1.1  christos 		"a/abcde/",
    107  1.1  christos 		"a/abcdef",
    108  1.1  christos 		"a/abcdef/",
    109  1.1  christos 		"a/abcdefg",
    110  1.1  christos 		"a/abcdefg/",
    111  1.1  christos 		"a/abcdefgh",
    112  1.1  christos 		"a/abcdefgh/",
    113  1.1  christos 
    114  1.1  christos 		"ab/",
    115  1.1  christos 		"ab//",
    116  1.1  christos 		"ab/a",
    117  1.1  christos 		"ab/a/",
    118  1.1  christos 		"ab/ab",
    119  1.1  christos 		"ab/ab/",
    120  1.1  christos 		"ab/abc",
    121  1.1  christos 		"ab/abc/",
    122  1.1  christos 		"ab/abcd",
    123  1.1  christos 		"ab/abcd/",
    124  1.1  christos 		"ab/abcde",
    125  1.1  christos 		"ab/abcde/",
    126  1.1  christos 		"ab/abcdef",
    127  1.1  christos 		"ab/abcdef/",
    128  1.1  christos 		"ab/abcdefg",
    129  1.1  christos 		"ab/abcdefg/",
    130  1.1  christos 		"ab/abcdefgh",
    131  1.1  christos 		"ab/abcdefgh/",
    132  1.1  christos 
    133  1.1  christos 		"abc/",
    134  1.1  christos 		"abc//",
    135  1.1  christos 		"abc/a",
    136  1.1  christos 		"abc/a/",
    137  1.1  christos 		"abc/ab",
    138  1.1  christos 		"abc/ab/",
    139  1.1  christos 		"abc/abc",
    140  1.1  christos 		"abc/abc/",
    141  1.1  christos 		"abc/abcd",
    142  1.1  christos 		"abc/abcd/",
    143  1.1  christos 		"abc/abcde",
    144  1.1  christos 		"abc/abcde/",
    145  1.1  christos 		"abc/abcdef",
    146  1.1  christos 		"abc/abcdef/",
    147  1.1  christos 		"abc/abcdefg",
    148  1.1  christos 		"abc/abcdefg/",
    149  1.1  christos 		"abc/abcdefgh",
    150  1.1  christos 		"abc/abcdefgh/",
    151  1.1  christos 
    152  1.1  christos 		"abcd/",
    153  1.1  christos 		"abcd//",
    154  1.1  christos 		"abcd/a",
    155  1.1  christos 		"abcd/a/",
    156  1.1  christos 		"abcd/ab",
    157  1.1  christos 		"abcd/ab/",
    158  1.1  christos 		"abcd/abc",
    159  1.1  christos 		"abcd/abc/",
    160  1.1  christos 		"abcd/abcd",
    161  1.1  christos 		"abcd/abcd/",
    162  1.1  christos 		"abcd/abcde",
    163  1.1  christos 		"abcd/abcde/",
    164  1.1  christos 		"abcd/abcdef",
    165  1.1  christos 		"abcd/abcdef/",
    166  1.1  christos 		"abcd/abcdefg",
    167  1.1  christos 		"abcd/abcdefg/",
    168  1.1  christos 		"abcd/abcdefgh",
    169  1.1  christos 		"abcd/abcdefgh/",
    170  1.1  christos 
    171  1.1  christos 		"abcde/",
    172  1.1  christos 		"abcde//",
    173  1.1  christos 		"abcde/a",
    174  1.1  christos 		"abcde/a/",
    175  1.1  christos 		"abcde/ab",
    176  1.1  christos 		"abcde/ab/",
    177  1.1  christos 		"abcde/abc",
    178  1.1  christos 		"abcde/abc/",
    179  1.1  christos 		"abcde/abcd",
    180  1.1  christos 		"abcde/abcd/",
    181  1.1  christos 		"abcde/abcde",
    182  1.1  christos 		"abcde/abcde/",
    183  1.1  christos 		"abcde/abcdef",
    184  1.1  christos 		"abcde/abcdef/",
    185  1.1  christos 		"abcde/abcdefg",
    186  1.1  christos 		"abcde/abcdefg/",
    187  1.1  christos 		"abcde/abcdefgh",
    188  1.1  christos 		"abcde/abcdefgh/",
    189  1.1  christos 
    190  1.1  christos 		"abcdef/",
    191  1.1  christos 		"abcdef//",
    192  1.1  christos 		"abcdef/a",
    193  1.1  christos 		"abcdef/a/",
    194  1.1  christos 		"abcdef/ab",
    195  1.1  christos 		"abcdef/ab/",
    196  1.1  christos 		"abcdef/abc",
    197  1.1  christos 		"abcdef/abc/",
    198  1.1  christos 		"abcdef/abcd",
    199  1.1  christos 		"abcdef/abcd/",
    200  1.1  christos 		"abcdef/abcde",
    201  1.1  christos 		"abcdef/abcde/",
    202  1.1  christos 		"abcdef/abcdef",
    203  1.1  christos 		"abcdef/abcdef/",
    204  1.1  christos 		"abcdef/abcdefg",
    205  1.1  christos 		"abcdef/abcdefg/",
    206  1.1  christos 		"abcdef/abcdefgh",
    207  1.1  christos 		"abcdef/abcdefgh/",
    208  1.1  christos 
    209  1.1  christos 		"abcdefg/",
    210  1.1  christos 		"abcdefg//",
    211  1.1  christos 		"abcdefg/a",
    212  1.1  christos 		"abcdefg/a/",
    213  1.1  christos 		"abcdefg/ab",
    214  1.1  christos 		"abcdefg/ab/",
    215  1.1  christos 		"abcdefg/abc",
    216  1.1  christos 		"abcdefg/abc/",
    217  1.1  christos 		"abcdefg/abcd",
    218  1.1  christos 		"abcdefg/abcd/",
    219  1.1  christos 		"abcdefg/abcde",
    220  1.1  christos 		"abcdefg/abcde/",
    221  1.1  christos 		"abcdefg/abcdef",
    222  1.1  christos 		"abcdefg/abcdef/",
    223  1.1  christos 		"abcdefg/abcdefg",
    224  1.1  christos 		"abcdefg/abcdefg/",
    225  1.1  christos 		"abcdefg/abcdefgh",
    226  1.1  christos 		"abcdefg/abcdefgh/",
    227  1.1  christos 
    228  1.1  christos 		"abcdefgh/",
    229  1.1  christos 		"abcdefgh//",
    230  1.1  christos 		"abcdefgh/a",
    231  1.1  christos 		"abcdefgh/a/",
    232  1.1  christos 		"abcdefgh/ab",
    233  1.1  christos 		"abcdefgh/ab/",
    234  1.1  christos 		"abcdefgh/abc",
    235  1.1  christos 		"abcdefgh/abc/",
    236  1.1  christos 		"abcdefgh/abcd",
    237  1.1  christos 		"abcdefgh/abcd/",
    238  1.1  christos 		"abcdefgh/abcde",
    239  1.1  christos 		"abcdefgh/abcde/",
    240  1.1  christos 		"abcdefgh/abcdef",
    241  1.1  christos 		"abcdefgh/abcdef/",
    242  1.1  christos 		"abcdefgh/abcdefg",
    243  1.1  christos 		"abcdefgh/abcdefg/",
    244  1.1  christos 		"abcdefgh/abcdefgh",
    245  1.1  christos 		"abcdefgh/abcdefgh/",
    246  1.1  christos 	};
    247  1.1  christos 
    248  1.1  christos 	dl_handle = dlopen(NULL, RTLD_LAZY);
    249  1.1  christos 	strchrnul_fn = dlsym(dl_handle, "test_strchrnul");
    250  1.1  christos 	if (!strchrnul_fn)
    251  1.1  christos 		strchrnul_fn = strchrnul;
    252  1.1  christos 
    253  1.1  christos 	for (a = 3; a < 3 + sizeof(long); ++a) {
    254  1.1  christos 		/* Put char and a \0 before the buffer */
    255  1.1  christos 		buf[a-1] = '/';
    256  1.1  christos 		buf[a-2] = '0';
    257  1.1  christos 		buf[a-3] = 0xff;
    258  1.1  christos 		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
    259  1.1  christos 			int len = strlen(tab[t]) + 1;
    260  1.1  christos 			memcpy(&buf[a], tab[t], len);
    261  1.1  christos 
    262  1.1  christos 			/* Put the char we are looking for after the \0 */
    263  1.1  christos 			buf[a + len] = '/';
    264  1.1  christos 
    265  1.1  christos 			/* Check search for NUL at end of string */
    266  1.1  christos 			verify_strchrnul(buf + a, 0, t, a);
    267  1.1  christos 
    268  1.1  christos 			/* Then for the '/' in the strings */
    269  1.1  christos 			verify_strchrnul(buf + a, '/', t, a);
    270  1.1  christos 
    271  1.1  christos 			/* check zero extension of char arg */
    272  1.1  christos 			verify_strchrnul(buf + a, 0xffffff00 | '/', t, a);
    273  1.1  christos 
    274  1.1  christos 			/* Replace all the '/' with 0xff */
    275  1.1  christos 			while (*(off = slow_strchrnul(buf + a, '/')) != '\0')
    276  1.1  christos 				*off = 0xff;
    277  1.1  christos 
    278  1.1  christos 			buf[a + len] = 0xff;
    279  1.1  christos 
    280  1.1  christos 			/* Check we can search for 0xff as well as '/' */
    281  1.1  christos 			verify_strchrnul(buf + a, 0xff, t, a);
    282  1.1  christos 		}
    283  1.1  christos 	}
    284  1.1  christos 	(void)dlclose(dl_handle);
    285  1.1  christos }
    286  1.1  christos 
    287  1.1  christos ATF_TP_ADD_TCS(tp)
    288  1.1  christos {
    289  1.1  christos 
    290  1.1  christos 	ATF_TP_ADD_TC(tp, strchrnul_basic);
    291  1.1  christos 
    292  1.1  christos 	return atf_no_error();
    293  1.1  christos }
    294