From eaff1be753f58741a593e6b6a4035533b242a16d Mon Sep 17 00:00:00 2001
From: Harald van Dijk <harald@gigawatt.nl>
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(-)
@@ -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;
}
}
@@ -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;
}
@@ -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