[RFC/PATCH v2 3/5] libbb: add ends_with() function

tito farmatito at tiscali.it
Fri Aug 21 20:31:05 UTC 2015


Hi,

I've written a little test program to look at some corner cases for this new ends_with function:

#include <string.h>
#include <stdio.h>

int ends_with(const char *str, const char *key)
{
	size_t str_len = strlen(str), key_len = strlen(key);

	if (str_len >= key_len) {
		if (strcmp(str + str_len - key_len, key) == 0) {
			return 1;
		}
	}

	return 0;
}

int my_ends_with(const char *str, const char *key)
{
	char *p;
	const char *s = str;
	
	while((p = strstr(s, key)) != NULL && *key != 0) {
	//	printf("p = %s s = %s\n", p, s);
		if (strcmp(p, key) == 0)
			return 1;
		s++;
	}
	return 0;
}

int main(int argc, char **argv)
{
	printf("'%s' ends_with '%s' = %s\n", "testprova", "test", (ends_with("testprova", "test")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "testprova", "prova", (ends_with("testprova", "prova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "prova", (ends_with("test", "prova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "testprova", (ends_with("test", "testprova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "", "testprova", (ends_with("", "testprova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "", (ends_with("test", "")) ? "yes" : "no");
	puts("======================================================================================================");
	printf("'%s' ends_with '%s' = %s\n", "testprova", "test", (my_ends_with("testprova", "test")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "testprova", "prova", (my_ends_with("testprova", "prova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "prova", (my_ends_with("test", "prova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "testprova", (my_ends_with("test", "testprova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "", "testprova", (my_ends_with("", "testprova")) ? "yes" : "no");
	printf("'%s' ends_with '%s' = %s\n", "test", "", (my_ends_with("test", "")) ? "yes" : "no");

	return 0;
}

The output is:

 ./test
'testprova' ends_with 'test' = no
'testprova' ends_with 'prova' = yes
'test' ends_with 'prova' = no
'test' ends_with 'testprova' = no
'' ends_with 'testprova' = no
'test' ends_with '' = yes

and I wonder if the last test result is correct:

'test' ends_with '' = yes

Just for fun I've also added a different implementation that
seems to do the right thing (at least for me):

'testprova' ends_with 'test' = no
'testprova' ends_with 'prova' = yes
'test' ends_with 'prova' = no
'test' ends_with 'testprova' = no
'' ends_with 'testprova' = no
'test' ends_with '' = no

Ciao,
Tito
 


 

On 08/21/2015 06:26 PM, walter harms wrote:
>
>
> Am 21.08.2015 16:23, schrieb Bartosz Golaszewski:
>> This function checks if given key can be found at the end of the string.
>>
>> Signed-off-by: Bartosz Golaszewski <bartekgola at gmail.com>
>> ---
>>   include/libbb.h              |  1 +
>>   libbb/compare_string_array.c | 30 ++++++++++++++++++++++++++++++
>>   2 files changed, 31 insertions(+)
>>
>> diff --git a/include/libbb.h b/include/libbb.h
>> index a56b684..7b41c9b 100644
>> --- a/include/libbb.h
>> +++ b/include/libbb.h
>> @@ -422,6 +422,7 @@ const char *bb_basename(const char *name) FAST_FUNC;
>>   char *last_char_is(const char *s, int c) FAST_FUNC;
>>   const char* endofname(const char *name) FAST_FUNC;
>>   char *is_prefixed_with(const char *string, const char *key) FAST_FUNC;
>> +int ends_with(const char *str, const char *key) FAST_FUNC;
>>
>>   int ndelay_on(int fd) FAST_FUNC;
>>   int ndelay_off(int fd) FAST_FUNC;
>> diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
>> index e24815a..a2d77c7 100644
>> --- a/libbb/compare_string_array.c
>> +++ b/libbb/compare_string_array.c
>> @@ -23,6 +23,19 @@ char* FAST_FUNC is_prefixed_with(const char *string, const char *key)
>>   #endif
>>   }
>>
>> +int FAST_FUNC ends_with(const char *str, const char *key)
>> +{
>> +	size_t str_len = strlen(str), key_len = strlen(key);
>> +
>> +	if (str_len >= key_len) {
>> +		if (strcmp(str + str_len - key_len, key) == 0) {
>> +			return 1;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>
> maybe its a bit late but ...
>
> the function name is a bit unfortunate whats about has_suffix() ?
>
> you can improve readability by returning strcmp directly and calculating
> the len immediately.
>
> int has_suffix(const char *str, const char *key)
> {
>          size_t len = strlen(str)-strlen(key);
>
>          if (len < 0 )
> 		return -1;
>
>          return strcmp(str + len, key);
> }
>
> re,
>   wh
>
>
>>   /* returns the array index of the string */
>>   /* (index of first match is returned, or -1) */
>>   int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key)
>> @@ -110,3 +123,20 @@ smallint FAST_FUNC yesno(const char *str)
>>   	return ret / 3;
>>   }
>>   #endif
>> +
>> +#if ENABLE_UNIT_TEST
>> +
>> +BBUNIT_DEFINE_TEST(ends_with)
>> +{
>> +	BBUNIT_ASSERT_TRUE(ends_with("foo bar", "bar"));
>> +	BBUNIT_ASSERT_TRUE(ends_with("foo", "foo"));
>> +	BBUNIT_ASSERT_TRUE(ends_with("foo", ""));
>> +	BBUNIT_ASSERT_TRUE(ends_with("", ""));
>> +
>> +	BBUNIT_ASSERT_FALSE(ends_with("foo", "bar foo"));
>> +	BBUNIT_ASSERT_FALSE(ends_with("foo foo", "bar"));
>> +
>> +	BBUNIT_ENDTEST;
>> +}
>> +
>> +#endif /* ENABLE_UNIT_TEST */
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
>


More information about the busybox mailing list