@@ -100,6 +100,9 @@ char *T_strchrnul(const char *s, int c)
100100char * T_strrstr (const char * haystack , const char * needle )
101101 __attribute__((nonnull (1 , 2 )));
102102
103+ char * T_strsep (char * * __restrict s , const char * __restrict delim )
104+ __attribute__((nonnull (1 , 2 )));
105+
103106void T_bzero (void * s , size_t n );
104107
105108#else
@@ -121,6 +124,7 @@ void T_bzero(void* s, size_t n);
121124#define T_strncmp strncmp
122125#define T_strchrnul strchrnul
123126#define T_strrstr strrstr
127+ #define T_strsep strsep
124128#define T_bzero bzero
125129
126130#endif
@@ -1017,6 +1021,75 @@ int strchrnul_test(void) {
10171021 return 0 ;
10181022}
10191023
1024+ static char * truth_strsep (char * * __restrict stringp , const char * __restrict delim ) {
1025+ char * const begin_str = * stringp ;
1026+ if (begin_str == NULL ) {
1027+ return NULL ;
1028+ }
1029+ size_t length = strcspn (begin_str , delim );
1030+ char * end_str = begin_str + length ;
1031+ if (* end_str != '\0' ) {
1032+ * end_str ++ = '\0' ;
1033+ * stringp = end_str ;
1034+ } else {
1035+ * stringp = NULL ;
1036+ }
1037+ return begin_str ;
1038+ }
1039+
1040+ static int strsep_loop_test (char * str_1 , char * str_2 ) {
1041+ for (;;) {
1042+ char * __restrict prev_1 = T_strsep (& str_1 , ", ." );
1043+ char * __restrict prev_2 = truth_strsep (& str_2 , ", ." );
1044+ if (str_1 == NULL || str_2 == NULL ) {
1045+ break ;
1046+ }
1047+ ptrdiff_t diff_1 = (str_1 - prev_1 );
1048+ ptrdiff_t diff_2 = (str_2 - prev_2 );
1049+ if (diff_1 != diff_2 ) {
1050+ test_printf ("%td != %td\n%p %p\n1: %.20s\n2: %.20s\n" , diff_1 , diff_2 , prev_1 , prev_2 , str_1 , str_2 );
1051+ return __LINE__ ;
1052+ }
1053+ C (diff_1 == diff_2 );
1054+ }
1055+ C (str_1 == NULL && str_2 == NULL );
1056+ return 0 ;
1057+ }
1058+
1059+ int strsep_test (char * * dup_1 , char * * dup_2 ) {
1060+ {
1061+ char * ptr = NULL_ptr ;
1062+ C (T_strsep (& ptr , SINK ) == NULL );
1063+ C (T_strsep (& ptr , NULL_ptr ) == NULL );
1064+ C (T_strsep ((char * * )SINK , SINK ) == NULL );
1065+ C (T_strsep ((char * * )SINK , NULL_ptr ) == NULL );
1066+ }
1067+ const size_t len = strlen (gnu_copypasta );
1068+ const size_t size = len + 1 ;
1069+ * dup_1 = strdup (gnu_copypasta );
1070+ * dup_2 = strndup (gnu_copypasta , len );
1071+ C (* dup_1 != NULL && * dup_2 != NULL );
1072+ C (strcmp (* dup_1 , * dup_2 ) == 0 );
1073+ {
1074+ char * ptr , * prev ;
1075+ ptr = * dup_2 ;
1076+ prev = T_strsep (& ptr , "" );
1077+ C (ptr == NULL );
1078+ C (prev == * dup_2 );
1079+ ptr = * dup_2 ;
1080+ prev = T_strsep (& ptr , "zZ" );
1081+ C (ptr == NULL );
1082+ C (prev == * dup_2 );
1083+ C (memcmp (* dup_1 , * dup_2 , size ) == 0 );
1084+ }
1085+ {
1086+ int ret ;
1087+ TEST (strsep_loop_test (* dup_1 , * dup_2 ));
1088+ C (memcmp (* dup_1 , * dup_2 , size ) == 0 );
1089+ }
1090+ return 0 ;
1091+ }
1092+
10201093int run_tests (void ) {
10211094 int ret = 0 ;
10221095
@@ -1051,6 +1124,17 @@ int run_tests(void) {
10511124 TEST (strrstr_test ());
10521125 TEST (strchrnul_test ());
10531126
1127+ /* strsep */ {
1128+ char * dup_1 = SINK , * dup_2 = SINK ;
1129+ ret = strsep_test (& dup_1 , & dup_2 );
1130+ if (dup_1 == NULL || dup_2 == NULL ) {
1131+ perror ("str(n)dup returned NULL" );
1132+ }
1133+ free (dup_1 ); dup_1 = NULL ;
1134+ free (dup_2 ); dup_2 = NULL ;
1135+ if (ret != 0 ) { return ret ; }
1136+ }
1137+
10541138 return 0 ;
10551139}
10561140
0 commit comments