#ifdef HAVE_CONFIG_H #include #endif #include /* * True if w contains a zero byte. Subtracting ONES from w propagates a * borrow into the high bit of a byte exactly when that byte is zero; * ANDing with ~w keeps only bytes that were zero and high-bit-clear in w. * ONES and its shifted form are derived from the word width, so this works * for both 32- and 64-bit unsigned long. */ static unsigned long haszero(unsigned long w) { const unsigned long ones = (unsigned long)-1 / 0xff; return (w - ones) & ~w & (ones << 7); } /* * Return the length of s, excluding the terminating NUL. */ size_t strlen(const char *s) { const unsigned long word = sizeof(unsigned long); const char *p = s; /* Check the head byte-wise until p is word-aligned. */ for (; (unsigned long)p % word != 0; p++) { if (*p == '\0') { return (size_t)(p - s); } } /* Scan whole words for a zero byte. */ for (;;) { unsigned long w; __builtin_memcpy(&w, p, sizeof w); if (haszero(w)) { break; } p += word; } /* Resolve the terminating word byte-wise. */ for (;;) { if (*p == '\0') { return (size_t)(p - s); } p++; } }