From 109bf32ad5b14ec3c6d05d97a87f56c233bec5df Mon Sep 17 00:00:00 2001
From: Harald van Dijk <harald@gigawatt.nl>
Date: Sun, 28 Apr 2024 01:38:34 +0100
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/input.c | 4 ++--
src/var.c | 27 +++++++++++----------------
src/var.h | 15 +++++++++++++++
4 files changed, 38 insertions(+), 40 deletions(-)
@@ -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;
}
@@ -151,8 +153,7 @@ aliascmd(int argc, char **argv)
} else
printalias(ap);
} else {
- *v++ = '\0';
- setalias(n, v);
+ setalias(n, v + 1);
}
}
@@ -191,36 +192,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;
}
}
@@ -386,7 +386,7 @@ pushstring(char *s, void *ap)
sp->ap = (struct alias *)ap;
if (ap) {
((struct alias *)ap)->flag |= ALIASINUSE;
- sp->string = s;
+ sp->string = ((struct alias *)ap)->name;
}
parsefile->nextc = s;
parsefile->nleft = len;
@@ -405,7 +405,7 @@ static void popstring(void)
parsefile->nextc[-1] == '\t') {
checkkwd |= CHKALIAS;
}
- if (sp->string != sp->ap->val) {
+ if (sp->string != sp->ap->name) {
ckfree(sp->string);
}
}
@@ -622,12 +622,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];
}
@@ -641,19 +636,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;
}
@@ -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.43.0
On 26/04/2024 03:49, Herbert Xu wrote: > Could you please post a combined patch? Thanks! Okay, the attached patch combines both. It applies on top of 177072c2. Cheers, Harald van Dijk