字符串处理函数

本文探讨了Android C库在版本9.0.0_r3中的字符串处理函数实现,链接指向了开源代码。同时,还介绍了Linux内核v5.7.2中的相关函数,通过链接提供了详细源码供读者查阅。

Android C库:
http://androidxref.com/9.0.0_r3/xref/bionic/libc/upstream-openbsd/lib/libc/string/

/*
37 * sizeof(word) MUST BE A POWER OF TWO
38 * SO THAT wmask BELOW IS ALL ONES
39 */
40typedef	long word;		/* "word" used for optimal copy speed */
41
42#define	wsize	sizeof(word)
43#define	wmask	(wsize - 1)
44
45/*
46 * Copy a block of memory, handling overlap.拷贝一块内存
47 */
48void *
49memmove(void *dst0, const void *src0, size_t length)
50{
51	char *dst = dst0;
52	const char *src = src0;
53	size_t t;
54
55	if (length == 0 || dst == src)		/* nothing to do */
56		goto done;
57
58	/*
59	 * Macros: loop-t-times; and loop-t-times, t>0
60	 */
61#define	TLOOP(s) if (t) TLOOP1(s)
62#define	TLOOP1(s) do { s; } while (--t)
63
64	if ((unsigned long)dst < (unsigned long)src) {
65		/*
66		 * Copy forward.
67		 */
68		t = (long)src;	/* only need low bits */
69		if ((t | (long)dst) & wmask) {
70			/*
71			 * Try to align operands.  This cannot be done
72			 * unless the low bits match.
73			 */
74			if ((t ^ (long)dst) & wmask || length < wsize)
75				t = length;
76			else
77				t = wsize - (t & wmask);
78			length -= t;
79			TLOOP1(*dst++ = *src++);
80		}
81		/*
82		 * Copy whole words, then mop up any trailing bytes.
83		 */
84		t = length / wsize;
85		TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
86		t = length & wmask;
87		TLOOP(*dst++ = *src++);
88	} else {
89		/*
90		 * Copy backwards.  Otherwise essentially the same.
91		 * Alignment works as before, except that it takes
92		 * (t&wmask) bytes to align, not wsize-(t&wmask).
93		 */
94		src += length;
95		dst += length;
96		t = (long)src;
97		if ((t | (long)dst) & wmask) {
98			if ((t ^ (long)dst) & wmask || length <= wsize)
99				t = length;
100			else
101				t &= wmask;
102			length -= t;
103			TLOOP1(*--dst = *--src);
104		}
105		t = length / wsize;
106		TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
107		t = length & wmask;
108		TLOOP(*--dst = *--src);
109	}
110done:
111	return (dst0);
112}
39char *
40stpcpy(char *to, const char *from)
41{
42	for (; (*to = *from) != '\0'; ++from, ++to);
43	return(to);
39char *
40strcat(char *s, const char *append)
41{
42	char *save = s;
43
44	for (; *s; ++s);
45	while ((*s++ = *append++) != '\0');
46	return(save);
47}


37/*
38 * Compare strings.
39 */
40int
41strcmp(const char *s1, const char *s2)
42{
43	while (*s1 == *s2++)
44		if (*s1++ == 0)
45			return (0);
46	return (*(unsigned char *)s1 - *(unsigned char *)--s2);
47}
48DEF_STRONG(strcmp);
36/*
37 * Concatenate src on the end of dst.  At most strlen(dst)+n+1 bytes
38 * are written at dst (at most n+1 bytes being appended).  Return dst.
39 */
40char *
41strncat(char *dst, const char *src, size_t n)
42{
43	if (n != 0) {
44		char *d = dst;
45		const char *s = src;
46
47		while (*d != 0)
48			d++;
49		do {
50			if ((*d = *s++) == 0)
51				break;
52			d++;
53		} while (--n != 0);
54		*d = 0;
55	}
56	return (dst);
57}
34int
35strncmp(const char *s1, const char *s2, size_t n)
36{
37
38	if (n == 0)
39		return (0);
40	do {
41		if (*s1 != *s2++)
42			return (*(unsigned char *)s1 - *(unsigned char *)--s2);
43		if (*s1++ == 0)
44			break;
45	} while (--n != 0);
46	return (0);
47}
37/*
38 * Copy src to dst, truncating or null-padding to always copy n bytes.
39 * Return dst.
40 */
41char *
42strncpy(char *dst, const char *src, size_t n)
43{
44	if (n != 0) {
45		char *d = dst;
46		const char *s = src;
47
48		do {
49			if ((*d++ = *s++) == 0) {
50				/* NUL pad the remaining n-1 bytes */
51				while (--n != 0)
52					*d++ = 0;
53				break;
54			}
55		} while (--n != 0);
56	}
57	return (dst);
58}

内核C库:
https://elixir.bootlin.com/linux/v5.7.2/source/lib/string.c

/**
 * strncmp - Compare two length-limited strings
 * @cs: One string
 * @ct: Another string
 * @count: The maximum number of bytes to compare
 */
int strncmp(const char *cs, const char *ct, size_t count)
{
	unsigned char c1, c2;

	while (count) {
		c1 = *cs++;
		c2 = *ct++;
		if (c1 != c2)
			return c1 < c2 ? -1 : 1;
		if (!c1)
			break;
		count--;
	}
	return 0;
}
/**
 * strcmp - Compare two strings
 * @cs: One string
 * @ct: Another string
 */
#undef strcmp
int strcmp(const char *cs, const char *ct)
{
	unsigned char c1, c2;

	while (1) {
		c1 = *cs++;
		c2 = *ct++;
		if (c1 != c2)
			return c1 < c2 ? -1 : 1;
		if (!c1)
			break;
	}
	return 0;
}
/**
 * strncasecmp - Case insensitive, length-limited string comparison
 * @s1: One string
 * @s2: The other string
 * @len: the maximum number of characters to compare
 */
int strncasecmp(const char *s1, const char *s2, size_t len)
{
	/* Yes, Virginia, it had better be unsigned */
	unsigned char c1, c2;

	if (!len)
		return 0;

	do {
		c1 = *s1++;
		c2 = *s2++;
		if (!c1 || !c2)
			break;
		if (c1 == c2)
			continue;
		c1 = tolower(c1);
		c2 = tolower(c2);
		if (c1 != c2)
			break;
	} while (--len);
	return (int)c1 - (int)c2;
}
int strcasecmp(const char *s1, const char *s2)
{
	int c1, c2;

	do {
		c1 = tolower(*s1++);
		c2 = tolower(*s2++);
	} while (c1 == c2 && c1 != 0);
	return c1 - c2;
}
/**
 * strcpy - Copy a %NUL terminated string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 */

char *strcpy(char *dest, const char *src)
{
	char *tmp = dest;

	while ((*dest++ = *src++) != '\0')
		/* nothing */;
	return tmp;
}
/**
 * strncpy - Copy a length-limited, C-string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: The maximum number of bytes to copy
 *
 * The result is not %NUL-terminated if the source exceeds
 * @count bytes.
 *
 * In the case where the length of @src is less than  that  of
 * count, the remainder of @dest will be padded with %NUL.
 *
 */
char *strncpy(char *dest, const char *src, size_t count)
{
	char *tmp = dest;

	while (count) {
		if ((*tmp = *src) != 0)
			src++;
		tmp++;
		count--;
	}
	return dest;
}
/**
 * strlcpy - Copy a C-string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @size: size of destination buffer
 *
 * Compatible with ``*BSD``: the result is always a valid
 * NUL-terminated string that fits in the buffer (unless,
 * of course, the buffer size is zero). It does not pad
 * out the result like strncpy() does.
 */
size_t strlcpy(char *dest, const char *src, size_t size)
{
	size_t ret = strlen(src);

	if (size) {
		size_t len = (ret >= size) ? size - 1 : ret;
		memcpy(dest, src, len);
		dest[len] = '\0';
	}
	return ret;
}
/**
 * strncat - Append a length-limited, C-string to another
 * @dest: The string to be appended to
 * @src: The string to append to it
 * @count: The maximum numbers of bytes to copy
 *
 * Note that in contrast to strncpy(), strncat() ensures the result is
 * terminated.
 */
char *strncat(char *dest, const char *src, size_t count)
{
	char *tmp = dest;

	if (count) {
		while (*dest)
			dest++;
		while ((*dest++ = *src++) != 0) {
			if (--count == 0) {
				*dest = '\0';
				break;
			}
		}
	}
	return tmp;
}
/**
 * strlcat - Append a length-limited, C-string to another
 * @dest: The string to be appended to
 * @src: The string to append to it
 * @count: The size of the destination buffer.
 */
size_t strlcat(char *dest, const char *src, size_t count)
{
	size_t dsize = strlen(dest);
	size_t len = strlen(src);
	size_t res = dsize + len;

	/* This would be a bug */
	BUG_ON(dsize >= count);

	dest += dsize;
	count -= dsize;
	if (len >= count)
		len = count-1;
	memcpy(dest, src, len);
	dest[len] = 0;
	return res;
}
/**
 * memset - Fill a region of memory with the given value
 * @s: Pointer to the start of the area.
 * @c: The byte to fill the area with
 * @count: The size of the area.
 *
 * Do not use memset() to access IO space, use memset_io() instead.
 */
void *memset(void *s, int c, size_t count)
{
	char *xs = s;

	while (count--)
		*xs++ = c;
	return s;
}
/**
 * memcpy - Copy one area of memory to another
 * @dest: Where to copy to
 * @src: Where to copy from
 * @count: The size of the area.
 *
 * You should not use this function to access IO space, use memcpy_toio()
 * or memcpy_fromio() instead.
 */
void *memcpy(void *dest, const void *src, size_t count)
{
	char *tmp = dest;
	const char *s = src;

	while (count--)
		*tmp++ = *s++;
	return dest;
}
/**
 * memmove - Copy one area of memory to another
 * @dest: Where to copy to
 * @src: Where to copy from
 * @count: The size of the area.
 *
 * Unlike memcpy(), memmove() copes with overlapping areas.
 */
void *memmove(void *dest, const void *src, size_t count)
{
	char *tmp;
	const char *s;

	if (dest <= src) {
		tmp = dest;
		s = src;
		while (count--)
			*tmp++ = *s++;
	} else {
		tmp = dest;
		tmp += count;
		s = src;
		s += count;
		while (count--)
			*--tmp = *--s;
	}
	return dest;
}
/**
 * memcmp - Compare two areas of memory
 * @cs: One area of memory
 * @ct: Another area of memory
 * @count: The size of the area.
 */
#undef memcmp
__visible int memcmp(const void *cs, const void *ct, size_t count)
{
	const unsigned char *su1, *su2;
	int res = 0;

	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
		if ((res = *su1 - *su2) != 0)
			break;
	return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值