From patchwork Wed Jan 11 18:59:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harald van Dijk X-Patchwork-Id: 13097109 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7617FC54EBC for ; Wed, 11 Jan 2023 18:59:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235706AbjAKS7p (ORCPT ); Wed, 11 Jan 2023 13:59:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230465AbjAKS7h (ORCPT ); Wed, 11 Jan 2023 13:59:37 -0500 Received: from mail.gigawatt.nl (mail.gigawatt.nl [IPv6:2001:41d0:801:2000::19e9]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id ADF123D1D7 for ; Wed, 11 Jan 2023 10:59:35 -0800 (PST) Received: from [192.168.178.37] (uk.gigawatt.nl [51.148.134.205]) by mail.gigawatt.nl (Postfix) with ESMTPSA id C80671214 for ; Wed, 11 Jan 2023 18:59:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.gigawatt.nl C80671214 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gigawatt.nl; s=default; t=1673463571; bh=7/dO99ZzrpXYp2VB7Yrj8u9cDZbzHP7r/Tmhetg3bxA=; l=6598; h=Date:Subject:From:To:References:In-Reply-To:From; b=PCuQ2RkbtTgDSIwaJ82ecJUDC+/zY15UVtRFV0EcguZ56JYTlKwsRn2fp1yDRPSpd XNINkQnwlsQbx4Rf9b44YOtHe4og43s/uSgS6JwRUIK1xODqxbQ9rJlglC2XkmeKuQ xs683QLRRECrwyqp5zy7AiIMJWFBT8KrU3sV8ysQ= Message-ID: Date: Wed, 11 Jan 2023 18:59:34 +0000 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Thunderbird/109.0 Subject: [PATCH][resend] Simplify alias storage. Content-Language: en-US From: Harald van Dijk To: DASH shell mailing list References: In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org On 11/01/2023 18:23, Harald van Dijk wrote: > Rather than storing the alias name and value separately, we can reduce > simplify code and reduce code size by storing them in name=value form. > This allows us to re-use some code from var.c to handle hashing and > comparisons, so long as we update that to account for aliases' special > handling of a leading = character. This is okay to do for variables as > well, as for variables the leading character is guaranteed to not be =. Apparently this got messed up when I actually sent it. Re-sending as an attachment. Apologies for the noise. Cheers, Harald van Dijk From eaff1be753f58741a593e6b6a4035533b242a16d Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Wed, 11 Jan 2023 14:08:02 +0000 Subject: [PATCH] Simplify alias storage. Rather than storing the alias name and value separately, we can reduce simplify code and reduce code size by storing them in name=value form. This allows us to re-use some code from var.c to handle hashing and comparisons, so long as we update that to account for aliases' special handling of a leading = character. This is okay to do for variables as well, as for variables the leading character is guaranteed to not be =. --- src/alias.c | 32 ++++++++++---------------------- src/var.c | 27 +++++++++++---------------- src/var.h | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/alias.c b/src/alias.c index fcad43b..bb963a6 100644 --- a/src/alias.c +++ b/src/alias.c @@ -41,6 +41,7 @@ #include "mystring.h" #include "alias.h" #include "options.h" /* XXX for argptr (should remove?) */ +#include "var.h" #define ATABSIZE 39 @@ -55,25 +56,26 @@ void setalias(const char *name, const char *val) { struct alias *ap, **app; + size_t namelen; app = __lookupalias(name); ap = *app; INTOFF; if (ap) { if (!(ap->flag & ALIASINUSE)) { - ckfree(ap->val); + ckfree(ap->name); } - ap->val = savestr(val); ap->flag &= ~ALIASDEAD; } else { /* not found */ ap = ckmalloc(sizeof (struct alias)); - ap->name = savestr(name); - ap->val = savestr(val); ap->flag = 0; ap->next = 0; *app = ap; } + namelen = val - name; + ap->name = savestr(name); + ap->val = ap->name + namelen; INTON; } @@ -150,8 +152,7 @@ aliascmd(int argc, char **argv) } else printalias(ap); } else { - *v++ = '\0'; - setalias(n, v); + setalias(n, v + 1); } } @@ -190,36 +191,23 @@ freealias(struct alias *ap) { next = ap->next; ckfree(ap->name); - ckfree(ap->val); ckfree(ap); return next; } void printalias(const struct alias *ap) { - out1str(single_quote(ap->name)); - out1fmt("=%s\n", single_quote(ap->val)); + out1fmt("%s\n", single_quote(ap->name)); } STATIC struct alias ** __lookupalias(const char *name) { - unsigned int hashval; struct alias **app; - const char *p; - unsigned int ch; - p = name; - - ch = (unsigned char)*p; - hashval = ch << 4; - while (ch) { - hashval += ch; - ch = (unsigned char)*++p; - } - app = &atab[hashval % ATABSIZE]; + app = &atab[hashval(name) % ATABSIZE]; for (; *app; app = &(*app)->next) { - if (equal(name, (*app)->name)) { + if (varequal(name, (*app)->name)) { break; } } diff --git a/src/var.c b/src/var.c index b70d72c..64d93aa 100644 --- a/src/var.c +++ b/src/var.c @@ -625,12 +625,7 @@ void unsetvar(const char *s) STATIC struct var ** hashvar(const char *p) { - unsigned int hashval; - - hashval = ((unsigned char) *p) << 4; - while (*p && *p != '=') - hashval += (unsigned char) *p++; - return &vartab[hashval % VTABSIZE]; + return &vartab[hashval(p) % VTABSIZE]; } @@ -644,19 +639,19 @@ hashvar(const char *p) int varcmp(const char *p, const char *q) { - int c, d; - - while ((c = *p) == (d = *q)) { - if (!c || c == '=') - goto out; + int c = *p, d = *q; + while (c == d) { + if (!c) + break; p++; q++; + c = *p; + d = *q; + if (c == '=') + c = '\0'; + if (d == '=') + d = '\0'; } - if (c == '=') - c = 0; - if (d == '=') - d = 0; -out: return c - d; } diff --git a/src/var.h b/src/var.h index aa7575a..2aece9d 100644 --- a/src/var.h +++ b/src/var.h @@ -153,6 +153,21 @@ int unsetcmd(int, char **); void unsetvar(const char *); int varcmp(const char *, const char *); +static inline unsigned int hashval(const char *p) +{ + unsigned int hashval; + + hashval = ((unsigned char) *p) << 4; + while (*p) { + hashval += (unsigned char) *p++; + if (*p == '=') + break; + } + + return hashval; +} + + static inline int varequal(const char *a, const char *b) { return !varcmp(a, b); } -- 2.39.0