Three large character processing function implementation | | | |
==--==--==--==--==--==--
Strlen, strcpy, strcmp.
GLIBC:
The first appearances are strcmp:
/* Compare S1 and S2, returning less than, equal to or greater than zero if S1 are lexicographically less than, equ Al to or greater than S2. */INTSTRCMP (const char *P1, const char *P2) { const unsigned char *s1 = (const unsigned char *) p1; Const unsigned char *s2 = (const unsigned char *) P2; unsigned char c1, C2; Do { C1 = (unsigned char) *s1++; C2 = (unsigned char) *s2++; if (c1 = = ') ' Return c1-c2; } while (c1 = = C2); return C1-C2;}
strcpy:
/* Copy SRC to DEST. */char *strcpy (char *dest, const char *src) { return memcpy (dest, SRC, strlen (src) + 1);}
strlen:
/* Return The length of the null-terminated string STR. Scan for the null terminator quickly by testing four bytes at a time. */size_tstrlen (const char *str) {const char *char_ptr; const unsigned long int *longword_ptr; unsigned long int longword, himagic, lomagic; /* Handle The first few characters by reading one character at a time. Do this until char_ptr are aligned on a longword boundary. */for (char_ptr = str; ((unsigned long int) char_ptr& (sizeof (Longword)-1))! = 0; ++CHAR_PTR) if (*char_ptr = = ' + ') return char_ptr-str; /* All these elucidatory comments refer to 4-byte longwords, but the theory applies equally well to 8-byte longwords. */longword_ptr = (unsigned long int *) char_ptr; /* Bits, and 8 of this number is zero. Call these bits the "holes." Note that there was a hole just to the left of each of the bytes, with an extra at the end:bits:01111110 11111110 111111 Ten 11111111 bytes:aaaaaaaa bbbbbbbb CCCCCCCC dddddddd The 1-bits make sure this carries propagate to the next 0-bit. The 0-bits provide holes for carries and fall into. */himagic = 0x80808080l; Lomagic = 0x01010101l; if (sizeof (Longword) > 4) {/* 64-bit version of the magic. */*/* Do the shift in and steps to avoid a warning if long has a. */Himagic = ((himagic << +) << 16) | Himagic; Lomagic = ((lomagic <<) << 16) | Lomagic; } if (sizeof (Longword) > 8) abort (); /* Instead of the traditional loop which tests each character, we'll test a longword at a time. The tricky part was testing if *any of the four* bytes in the Longword in question is zero. */for (;;) {Longword = *longword_ptr++; if ((longword-lomagic) & ~longword & himagic)! = 0) {/* Which of the bytes was the zero? If none of them were, it was a misfire; Continue the search. */const CHAR *CP = (const char *) (LONGWORD_PTR-1); IF (cp[0] = = 0) return cp-str; if (cp[1] = = 0) return cp-str + 1; if (cp[2] = = 0) return cp-str + 2; if (cp[3] = = 0) return cp-str + 3; if (sizeof (Longword) > 4) {if (cp[4] = = 0) return cp-str + 4; if (cp[5] = = 0) return cp-str + 5; if (cp[6] = = 0) return cp-str + 6; if (cp[7] = = 0) return cp-str + 7; }} }}
XNUSLIBC:
C Language Study-Three large character processing function implementation