From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id 640D4385E02D for ; Tue, 5 Dec 2023 15:02:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 640D4385E02D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 640D4385E02D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::636 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701788554; cv=none; b=G+W882ooimK9r2B36L9c/UJluRiwCE1tABG0FPQQwWyLYLUTK4s8j1mlAIYbPB31lZSK2UKlZp8BmUsL7FAgbAmfH2nTlSA8Tjbt+wMTodNZLGCCNwgyum4C1dEr6WfTdldZw7DmWwpCBYUxVpBr4GPD6FrzbpH3hXaDN9RBAaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701788554; c=relaxed/simple; bh=BG1WCfyxoRxcIIo9aiaAmSlcLCOnJyQgjPnspjcRxDo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=oTXRySpYW85H7Z5LZDfSmCwSfHSYtiz5PyC9tRPv1MLfpqCLF8ryzf362mc5bhU2kmyd24id2bDRdcRu0b6c3kKSqhVtseVSClXfuUB6t/t8IqPlO41vIXmO4zUd51bEX2rt357kY8jukBAX27clc9HOP058yqopbOiJj0U8fiE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1d098b87eeeso20446425ad.0 for ; Tue, 05 Dec 2023 07:02:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701788542; x=1702393342; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=IAFzWaGVbQDKYNrgh8S4yHeKOdojMMAuT5PFoBbPDhE=; b=hW/z6bumW2JM+qXRAnWGncVgM2KOIx1/cITIFQdryF/0x+eAekXWhY+SCbsJ1EAEpD o/hZ4leZAWPzOINTL2Ye3crmNNckYJ8J3lCJ8+kfTc/+GdMylIVKJqLELrmdVgnMKW2p WHCiUGAXBRiq1tL+AwGfsVI88Sw+9Wk2ulP2AZzVdcsx01TrCAcTnidqTMArH9pBrkwN oMb2xXJ2yOfW4TwXUEEpi1PgPZkzmLDy4uBWCIqty5JX7r+mIpr83fsDTS3gJ4EkWORD +Vm04Qswpm6IyXOUG/uuMBaKFdNe/TupWjl/yijUfunX8VFF+KtSqXZz09vv/13vR6V7 CMFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701788542; x=1702393342; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IAFzWaGVbQDKYNrgh8S4yHeKOdojMMAuT5PFoBbPDhE=; b=pEAoBGVIQgv3PDkyrnI4KraLIQeCarjBo6FuTFsaPWDEW6juywrXZve2578V2XgKoA RjWhdpbMfY7asOR6IHzol6zrNQ5o0bNzDHih2+P+wO7IvihkpP9Llsxo5x8w2neNsKwk 78RSUzVor9bxQ9CcQUJQCdKI0vEc+oFandhLjrawsvra38xblpfpohbM34I91p75RKp6 WGuGVF7UqsdXlIJnQJj4nViiW7eWvOGPq/7w2/sNF3Z6aUxg+NdmHxeX6+LJC+P8Nr+D GityJpsphlAL0UlY6w5161mRwzltu3MzCCZ0RZTeuY8pKp3LxNb+u/Xwqp0BF8q7YMVt eubA== X-Gm-Message-State: AOJu0YwJD5sVnSlsYfxBjXrFjqKwbuZFYjMJLEH35QWFM11UVYVi4LJe lO9Cu/+xrs0I9LHB1Och3SbDEWmPww46Gw== X-Google-Smtp-Source: AGHT+IGXXt7nDUATJK6I+gMfWd75rzcriwSA7pzXucCfyrl3XtOCIZpX5o+Bhk9sJtTgPEiP5Qw/mw== X-Received: by 2002:a17:902:d492:b0:1d0:b42f:e40f with SMTP id c18-20020a170902d49200b001d0b42fe40fmr3351018plg.30.1701788542194; Tue, 05 Dec 2023 07:02:22 -0800 (PST) Received: from localhost.localdomain ([2001:448a:20a0:566a:d0c2:108c:e5ff:5f7f]) by smtp.gmail.com with ESMTPSA id p17-20020a170902ead100b001d0ab572458sm3513729pld.121.2023.12.05.07.02.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 07:02:21 -0800 (PST) From: James Tirta Halim To: newlib@sourceware.org Cc: James Tirta Halim Subject: [PATCH] strchr, strchrnul: implement strchr() as strchrnul() Date: Tue, 5 Dec 2023 21:58:39 +0700 Message-ID: <20231205145839.474295-1-tirtajames45@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --- newlib/libc/string/strchr.c | 81 +--------------------------------- newlib/libc/string/strchrnul.c | 77 +++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 81 deletions(-) diff --git a/newlib/libc/string/strchr.c b/newlib/libc/string/strchr.c index 96f30be04..382275b1d 100644 --- a/newlib/libc/string/strchr.c +++ b/newlib/libc/string/strchr.c @@ -30,87 +30,10 @@ QUICKREF #include #include -/* Nonzero if X is not aligned on a "long" boundary. */ -#define UNALIGNED(X) ((long)X & (sizeof (long) - 1)) - -/* How many bytes are loaded each iteration of the word copy loop. */ -#define LBLOCKSIZE (sizeof (long)) - -#if LONG_MAX == 2147483647L -#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) -#else -#if LONG_MAX == 9223372036854775807L -/* Nonzero if X (a long int) contains a NULL byte. */ -#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) -#else -#error long int is not a 32bit or 64bit type. -#endif -#endif - -/* DETECTCHAR returns nonzero if (long)X contains the byte used - to fill (long)MASK. */ -#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK)) - 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; + s1 = strchrnul(s1, i); + return s1 && *s1 ? (char *) s1 : NULL; } diff --git a/newlib/libc/string/strchrnul.c b/newlib/libc/string/strchrnul.c index f5c3eb25d..69f66db63 100644 --- a/newlib/libc/string/strchrnul.c +++ b/newlib/libc/string/strchrnul.c @@ -29,12 +29,85 @@ QUICKREF */ #include +#include + +/* Nonzero if X is not aligned on a "long" boundary. */ +#define UNALIGNED(X) ((long)X & (sizeof (long) - 1)) + +/* How many bytes are loaded each iteration of the word copy loop. */ +#define LBLOCKSIZE (sizeof (long)) + +#if LONG_MAX == 2147483647L +#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) +#else +#if LONG_MAX == 9223372036854775807L +/* Nonzero if X (a long int) contains a NULL byte. */ +#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) +#else +#error long int is not a 32bit or 64bit type. +#endif +#endif + +/* DETECTCHAR returns nonzero if (long)X contains the byte used + to fill (long)MASK. */ +#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK)) char * strchrnul (const char *s1, int i) { - char *s = strchr(s1, 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 || *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 */ - return s ? s : (char *)s1 + strlen(s1); + while (*s && *s != c) + s++; + return (char *) s; } -- 2.43.0