/* Detect whether the character used to fill mask is in X */ #define DETECTCHAR(X,MASK) (DETECTNULL(X^MASK)) #endif /* OPTIMIZED_FOR_SIZE */ static char * strchr (const char *s, int c) { char pc = (char) c; #ifndef OPTIMIZED_FOR_SIZE const unsigned long *ps; unsigned long mask = 0; size_t i; /* Special case for finding \0. */ if (c == '\0') { while (UNALIGNED (s)) { if (*s == '\0') return (char *) s; ++s; } /* Operate a word at a time. */ ps = (const unsigned long *) s; while (!DETECTNULL (*ps)) ++ps; /* Found the end of the string. */ s = (const char *) ps; while (*s != '\0') ++s; return (char *) s; } /* All other bytes. Align the pointer, then search a long at a time. */ while (UNALIGNED (s)) { if (*s == '\0' || *s == pc) return *s ? (char *) s : 0; ++s; } ps = (const unsigned long *) s; for (i = 0; i < sizeof (unsigned long); ++i) mask = ((mask << CHAR_BIT) + ((unsigned char) pc & ~(~0 << CHAR_BIT))); /* Move ps a block at a time. */ while (!DETECTNULL (*ps) && !DETECTCHAR (*ps, mask)) ++ps; /* Pick up any residual with a byte searcher. */ s = (const char *) ps; #endif /* OPTIMIZED_FOR_SIZE */ /* The normal byte-search loop. */ while (*s && *s != pc) ++s; return *s == pc ? (char *) s : 0; }
char* strncat (char* destination, const char* source, size_t num) { char *s = destination; /* Skip over the data in s1 as quickly as possible. */ if (ALIGNED (destination)) { unsigned long *aligned_s1 = (unsigned long *)destination; while (!DETECTNULL (*aligned_s1)) aligned_s1++; destination = (char *)aligned_s1; } while (*destination) destination++; /* s1 now points to the its trailing null character, now copy up to N bytes from S2 into S1 stopping if a NULL is encountered in S2. It is not safe to use strncpy here since it copies EXACTLY N characters, NULL padding if necessary. */ while (num-- != 0 && (*destination++ = *source++)) { if (num == 0) *destination = '\0'; } return s; }
/* Detect whether the character used to fill mask is in X */ #define DETECTCHAR(X,MASK) (DETECTNULL(X^MASK)) #endif /* OPTIMIZED_FOR_SIZE */ static char * strchr (const char *s, int c) { char pc = (char) c; #ifndef OPTIMIZED_FOR_SIZE unsigned long *ps, mask = 0; size_t i; /* If s is unaligned, punt into the byte search loop. This should be rare. */ if (!UNALIGNED (s)) { ps = (unsigned long *) s; for (i = 0; i < sizeof (unsigned long); i++) mask = ((mask << CHAR_BIT) + ((unsigned char) pc & ~(~0 << CHAR_BIT))); /* Move ps a block at a time. */ while (!DETECTNULL (*ps) && !DETECTCHAR (*ps, mask)) ps++; /* Pick up any residual with a byte searcher. */ s = (char *) ps; } #endif /* The normal byte-search loop. */ while (*s && *s != pc) s++; return *s == pc ? (char *) s : 0; }
int strcmp(const char* str1, const char* str2) { unsigned long *a1; unsigned long *a2; /* If s1 or s2 are unaligned, then compare bytes. */ if (!UNALIGNED (str1, str2)) { /* If s1 and s2 are word-aligned, compare them a word at a time. */ a1 = (unsigned long*)str1; a2 = (unsigned long*)str2; while (*a1 == *a2) { /* To get here, *a1 == *a2, thus if we find a null in *a1, then the strings must be equal, so return zero. */ if (DETECTNULL (*a1)) return 0; a1++; a2++; } /* A difference was detected in last few bytes of s1, so search bytewise */ str1 = (char*)a1; str2 = (char*)a2; } while (*str1 != '\0' && *str1 == *str2) { str1++; str2++; } return (*(unsigned char *) str1) - (*(unsigned char *) str2); }
size_t strlen(const char *str) { const char *start = str; #if !defined(PREFER_SIZE_OVER_SPEED) unsigned long *aligned_addr; /* Align the pointer, so we can search a word at a time. */ while (UNALIGNED (str)) { if (!*str) return str - start; str++; } /* If the string is word-aligned, we can check for the presence of a null in each word-sized block. */ aligned_addr = (unsigned long *)str; while (!DETECTNULL (*aligned_addr)) aligned_addr++; /* Once a null is detected, we check each byte in that block for a precise position of the null. */ str = (char *) aligned_addr; #endif /* not PREFER_SIZE_OVER_SPEED */ while (*str) str++; return str - start; }
size_t strlen(const char *str) { #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) const char *start = str; while (*str) str++; return str - start; #else const char *start = str; unsigned long *aligned_addr; if (!UNALIGNED(str)) { /* If the string is word-aligned, we can check for the presence of a null in each word-sized block. */ aligned_addr = (unsigned long *)str; while (!DETECTNULL(*aligned_addr)) aligned_addr++; /* Once a null is detected, we check each byte in that block for a precise position of the null. */ str = (char *)aligned_addr; } while (*str) str++; return str - start; #endif /* not PREFER_SIZE_OVER_SPEED */ }
char* strcpy(char *to, const char *from) { char *dst = to; const char *src = from; long *aligned_dst; const long *aligned_src; /* If SRC or DEST is unaligned, then copy bytes. */ if (!UNALIGNED (src, dst)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while (!DETECTNULL(*aligned_src)) { *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while ((*dst++ = *src++)) ; return to; }
char* MFString_CopyCat(char *pDest, const char *pSrc, const char *pSrc2) { #if !defined(PREFER_SPEED_OVER_SIZE) char *s = pDest; while(*pDest = *pSrc++) { ++pDest; } while(*pDest++ = *pSrc2++) { } return s; #else char *dst = dst0; _CONST char *src = src0; long *aligned_dst; _CONST long *aligned_src; /* If SRC or DEST is unaligned, then copy bytes. */ if (!UNALIGNED (src, dst)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while (!DETECTNULL(*aligned_src)) { *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while (*dst++ = *src++) ; return dst0; #endif /* not PREFER_SIZE_OVER_SPEED */ }
int strncmp(const char *s1, const char *s2, size_t n) { #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) if (n == 0) return 0; while (n-- != 0 && *s1 == *s2) { if (n == 0 || *s1 == '\0') break; s1++; s2++; } return (*(unsigned char *) s1) - (*(unsigned char *) s2); #else unsigned long *a1; unsigned long *a2; if (n == 0) return 0; /* If s1 or s2 are unaligned, then compare bytes. */ if (!UNALIGNED (s1, s2)) { /* If s1 and s2 are word-aligned, compare them a word at a time. */ a1 = (unsigned long*)s1; a2 = (unsigned long*)s2; while (n >= sizeof (long) && *a1 == *a2) { n -= sizeof (long); /* If we've run out of bytes or hit a null, return zero since we already know *a1 == *a2. */ if (n == 0 || DETECTNULL (*a1)) return 0; a1++; a2++; } /* A difference was detected in last few bytes of s1, so search bytewise */ s1 = (char*)a1; s2 = (char*)a2; } while (n-- > 0 && *s1 == *s2) { /* If we've run out of bytes or hit a null, return zero since we already know *s1 == *s2. */ if (n == 0 || *s1 == '\0') return 0; s1++; s2++; } return (*(unsigned char *) s1) - (*(unsigned char *) s2); #endif /* not PREFER_SIZE_OVER_SPEED */ }
char *strncpy(char *dst0, const char *src0, size_t count) { #if defined(PREFER_SIZE_OVER_SPEED) char *dscan; const char *sscan; dscan = dst0; sscan = src0; while (count > 0) { --count; if ((*dscan++ = *sscan++) == '\0') break; } while (count-- > 0) *dscan++ = '\0'; return dst0; #else char *dst = dst0; const char *src = src0; long *aligned_dst; const long *aligned_src; /* If SRC and DEST is aligned and count large enough, then copy words. */ if (!UNALIGNED (src, dst) && !TOO_SMALL (count)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while (count >= sizeof (long int) && !DETECTNULL(*aligned_src)) { count -= sizeof (long int); *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while (count > 0) { --count; if ((*dst++ = *src++) == '\0') break; } while (count-- > 0) *dst++ = '\0'; return dst0; #endif /* not PREFER_SIZE_OVER_SPEED */ }
char* MFString_CopyN(char *pDest, const char *pSrc, int n) { #if !defined(PREFER_SPEED_OVER_SIZE) char *dscan; const char *sscan; dscan = pDest; sscan = pSrc; while(n > 0) { --n; if((*dscan++ = *sscan++) == '\0') break; } while(n-- > 0) *dscan++ = '\0'; return pDest; #else char *dst = dst0; _CONST char *src = src0; long *aligned_dst; _CONST long *aligned_src; /* If SRC and DEST is aligned and count large enough, then copy words. */ if(!UNALIGNED (src, dst) && !TOO_SMALL (count)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while(count >= sizeof (long int) && !DETECTNULL(*aligned_src)) { count -= sizeof (long int); *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while(count > 0) { --count; if((*dst++ = *src++) == '\0') break; } while(count-- > 0) *dst++ = '\0'; return dst0; #endif }
static void * memchr (const void *s, int c, size_t n) { const unsigned char *us; unsigned char uc = (unsigned char) c; #ifndef _OPTIMIZED_FOR_SIZE unsigned long *psrc; size_t i; unsigned long mask = 0, buffer = 0; #endif us = s; #ifndef _OPTIMIZED_FOR_SIZE /* If the size is small, or s is unaligned, punt into the bytewise loop. This should be rare. */ if (!TOO_SMALL (n) && !UNALIGNED (s)) { psrc = (unsigned long *) s; /* The fast code reads the data one word at a time and only performs the bytewise search on word-sized segments if they contain the search character, which is detected by XORing the word-sized segment with a word-sized block of the search character and then detecting the presence of a null character in the result. */ for (i = 0; i < LITTLEBLOCKSIZE; i++) mask = (mask << CHAR_BIT) + ((unsigned char) uc & ~(~0 << CHAR_BIT)); /* Check a block at a time if possible. */ while (n >= LITTLEBLOCKSIZE) { buffer = *psrc ^ mask; if (DETECTNULL (buffer)) break; /* found character, so go byte by byte from here */ n -= LITTLEBLOCKSIZE; psrc++; } /* Pick up any residual with a bytewise iterator. */ us = (unsigned char *) psrc; } #endif /* The normal bytewise loop. */ while (n--) { if (*us == uc) return (void *) us; us++; } return 0; }
small_int_t strnzcmp(const unsigned char *s1, const unsigned char *s2, size_t limit) { size_t n = limit; unsigned long *a1; unsigned long *a2; if (n == 0) return 0; /* If s1 or s2 are unaligned, then compare bytes. */ if (!UNALIGNED (s1, s2)) { /* If s1 and s2 are word-aligned, compare them a word at a time. */ a1 = (unsigned long*)s1; a2 = (unsigned long*)s2; while (n >= sizeof (long) && *a1 == *a2) { /* If we've run out of bytes or hit a null, return zero since we already know *a1 == *a2. */ if (n == 0 || DETECTNULL (*a1)) return 0; a1++; a2++; n -= sizeof (long); } /* A difference was detected in last few bytes of s1, so search bytewise */ s1 = (unsigned char*)a1; s2 = (unsigned char*)a2; } while (n > 0) { if (__glibc_unlikely(*s1 != *s2)){ if ((*s1 == '\0') || (*s2 == '\0')) return limit-n; return n - limit; } /* If we've run out of bytes or hit a null, return zero since we already know *s1 == *s2. */ if (__glibc_unlikely(*s1 == '\0')) { return limit-n; } s1++; s2++; n--; } return limit; }
small_int_t strncmp(const unsigned char *s1, const unsigned char *s2, size_t n) { unsigned long *a1; unsigned long *a2; if (n == 0) return 0; /* If s1 or s2 are unaligned, then compare bytes. */ if (!UNALIGNED (s1, s2)) { /* If s1 and s2 are word-aligned, compare them a word at a time. */ a1 = (unsigned long*)s1; a2 = (unsigned long*)s2; while (n >= sizeof (long) && *a1 == *a2) { n -= sizeof (long); /* If we've run out of bytes or hit a null, return zero since we already know *a1 == *a2. */ if (n == 0 || DETECTNULL (*a1)) return 0; a1++; a2++; } /* A difference was detected in last few bytes of s1, so search bytewise */ s1 = (unsigned char*)a1; s2 = (unsigned char*)a2; } while (n-- > 0 && *s1 == *s2) { /* If we've run out of bytes or hit a null, return zero since we already know *s1 == *s2. */ if (n == 0 || *s1 == '\0') return 0; s1++; s2++; } return *s1 - *s2; }
int strcmp(const char *s1, const char *s2) { #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } return (*(unsigned char *)s1) - (*(unsigned char *)s2); #else unsigned long *a1; unsigned long *a2; /* If s1 or s2 are unaligned, then compare bytes. */ if (!UNALIGNED(s1, s2)) { /* If s1 and s2 are word-aligned, compare them a word at a time. */ a1 = (unsigned long *)s1; a2 = (unsigned long *)s2; while (*a1 == *a2) { /* To get here, *a1 == *a2, thus if we find a null in *a1, then the strings must be equal, so return zero. */ if (DETECTNULL(*a1)) return 0; a1++; a2++; } /* A difference was detected in last few bytes of s1, so search bytewise */ s1 = (char *)a1; s2 = (char *)a2; } while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } return (*(unsigned char *)s1) - (*(unsigned char *)s2); #endif /* not PREFER_SIZE_OVER_SPEED */ }
char *strcat(char *s1, const char *s2) { #if defined(PREFER_SIZE_OVER_SPEED) char *s = s1; while (*s1) s1++; while ((*s1++ = *s2++)) ; return s; #else char *s = s1; /* Skip over the data in s1 as quickly as possible. */ if (ALIGNED (s1)) { unsigned long *aligned_s1 = (unsigned long *)s1; while (!DETECTNULL (*aligned_s1)) aligned_s1++; s1 = (char *)aligned_s1; } while (*s1) s1++; /* s1 now points to the its trailing null character, we can just use strcpy to do the work for us now. ?!? We might want to just include strcpy here. Also, this will cause many more unaligned string copies because s1 is much less likely to be aligned. I don't know if its worth tweaking strcpy to handle this better. */ strcpy (s1, s2); return s; #endif /* not PREFER_SIZE_OVER_SPEED */ }
char*_strcpy(char *dst0, const char *src0) { #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) char *s = dst0; while (*dst0++ = *src0++) ; return s; #else char *dst = dst0; _CONST char *src = src0; long *aligned_dst; _CONST long *aligned_src; /* If SRC or DEST is unaligned, then copy bytes. */ if (!UNALIGNED (src, dst)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while (!DETECTNULL(*aligned_src)) { *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while ((*dst++ = *src++)) ; return dst0; #endif /* not PREFER_SIZE_OVER_SPEED */ }
char* strncpy(char* destination, const char* source, size_t num) { char *dst = destination; const char *src = source; long *aligned_dst; const long *aligned_src; /* If SRC and DEST is aligned and count large enough, then copy words. */ if (!UNALIGNED (src, dst) && !TOO_SMALL (num)) { aligned_dst = (long*)dst; aligned_src = (long*)src; /* SRC and DEST are both "long int" aligned, try to do "long int" sized copies. */ while (num >= sizeof (long int) && !DETECTNULL(*aligned_src)) { num -= sizeof (long int); *aligned_dst++ = *aligned_src++; } dst = (char*)aligned_dst; src = (char*)aligned_src; } while (num > 0) { --num; if ((*dst++ = *src++) == '\0') break; } while (num-- > 0) *dst++ = '\0'; return destination; }
char* strcat (char* destination, const char* source) { char *s = destination; /* Skip over the data in s1 as quickly as possible. */ if (ALIGNED (destination)) { unsigned long *aligned_s1 = (unsigned long *)destination; while (!DETECTNULL (*aligned_s1)) aligned_s1++; destination = (char *)aligned_s1; } while (*destination) destination++; /* s1 now points to the its trailing null character, we can just use strcpy to do the work for us now. */ strcpy(destination, source); return s; }
char *strchr(const char *s1, int i) { const unsigned char *s = (const unsigned char *)s1; unsigned char c = i; #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) unsigned long mask,j; unsigned long *aligned_addr; /* Special case for finding 0. */ if (!c) { while (UNALIGNED (s)) { if (!*s) return (char *) s; s++; } /* Operate a word at a time. */ aligned_addr = (unsigned long *) s; while (!DETECTNULL (*aligned_addr)) aligned_addr++; /* Found the end of string. */ s = (const unsigned char *) aligned_addr; while (*s) s++; return (char *) s; } /* All other bytes. Align the pointer, then search a long at a time. */ while (UNALIGNED (s)) { if (!*s) return NULL; if (*s == c) return (char *) s; s++; } mask = c; for (j = 8; j < LBLOCKSIZE * 8; j <<= 1) mask = (mask << j) | mask; aligned_addr = (unsigned long *) s; while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask)) aligned_addr++; /* The block of bytes currently pointed to by aligned_addr contains either a null or the target char, or both. We catch it using the bytewise search. */ s = (unsigned char *) aligned_addr; #endif /* not PREFER_SIZE_OVER_SPEED */ while (*s && *s != c) s++; if (*s == c) return (char *)s; return NULL; }