And here is mine - somewhat tortuous. endswith() alone is short.
I think I neglected to take care of the phrase being longer than
the searchee, which could cause UB.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Yes, I know strlcat and strlcpy are in the implementors
namespace. Change them if you must.
See <
http://cbfalconer.home.att.net/download/strlcpy.zip>
for documentation and rationale.
The objective is to detect whether a given string terminates
another string. This is a fairly tortuous way of doing
"endswith", but is fairly clear.
By C.B.Falconer. Released to public domain
*/
/* ---------------------- */
/* reverse string in place. Return length */
static size_t revstring(char *string)
{
char *last, temp;
size_t lgh;
if ((lgh = strlen(string)) > 1) {
last = string + lgh; /* points to '\0' */
while (last-- > string) {
temp = *string; *string++ = *last; *last = temp;
}
}
return lgh;
} /* revstring */
/* ---------------------- */
static size_t strlcpy(char *dst, const char *src, size_t sz)
{
const char *start = src;
if (src && sz--) {
while ((*dst++ = *src))
if (sz--) src++;
else {
*(--dst) = '\0';
break;
}
}
if (src) {
while (*src++) continue;
return src - start - 1;
}
else if (sz) *dst = '\0';
return 0;
} /* strlcpy */
/* ---------------------- */
static size_t strlcat(char *dst, const char *src, size_t sz)
{
char *start = dst;
while (*dst++) /* assumes sz >= strlen(dst) */
if (sz) sz--; /* i.e. well formed string */
dst--;
return dst - start + strlcpy(dst, src, sz);
} /* strlcat */
/* ---------------------- */
/* does searchme end with the phrase phrase? */
/* illustrates the power of reversing things */
/* (if not the efficacy) */
static int endswith(char *phrase, char *searchme)
{
int result, lgh, i;
lgh = revstring(phrase); revstring(searchme);
result = 1;
for (i = 0; i < lgh; i++) /* strncmp if we had it */
if (phrase
!= searchme) {
result = 0; break;
}
revstring(phrase); revstring(searchme);
return result;
} /* endswith */
/* ---------------------- */
int main(int argc, char **argv)
{
char *searchme, *tmp;
size_t searchlgh;
int i;
if (argc < 3) puts("Usage: endswith phrase string");
else {
searchlgh = 1 + strlen(argv[2]);
searchme = malloc(searchlgh);
strlcpy(searchme, argv[2], searchlgh);
for (i = 3; i < argc; i++) {
/* append blank and argv to searchme */
searchlgh += (1 + strlen(argv));
if (!(tmp = realloc(searchme, searchlgh))) break;
else {
searchme = tmp;
strlcat(searchme, " ", searchlgh);
strlcat(searchme, argv, searchlgh);
}
}
printf("\"%s\" does ", searchme);
if (!endswith(argv[1], searchme)) printf("not ");
printf("end with \"%s\"\n", argv[1]);
}
return 0;
} /* main, endswith */