1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-28 08:02:54 +00:00

sh: introduce a function to iterate over all hashed commands

While aliases and built-ins are opportunistically stored in cmdtable, each
function will be added to it immediately on definition.

Factor out the hashing function, write the iterator function and make it use
the hashing function.

Add the cmdname pointer to struct cmdentry so that the command name can be
exposed that way.

Differential Revision:	https://reviews.freebsd.org/D40619
This commit is contained in:
Piotr Pawel Stefaniak 2023-04-30 18:30:56 +02:00
parent 0fd450e289
commit bec7b9a219
2 changed files with 41 additions and 7 deletions

View File

@ -545,6 +545,19 @@ clearcmdentry(void)
}
static unsigned int
hashname(const char *p)
{
unsigned int hashval;
hashval = (unsigned char)*p << 4;
while (*p)
hashval += *p++;
return (hashval % CMDTABLESIZE);
}
/*
* Locate a command in the command hash table. If "add" is nonzero,
* add the command to the table if it is not already present. The
@ -559,17 +572,11 @@ static struct tblentry **lastcmdentry;
static struct tblentry *
cmdlookup(const char *name, int add)
{
unsigned int hashval;
const char *p;
struct tblentry *cmdp;
struct tblentry **pp;
size_t len;
p = name;
hashval = (unsigned char)*p << 4;
while (*p)
hashval += *p++;
pp = &cmdtable[hashval % CMDTABLESIZE];
pp = &cmdtable[hashname(name)];
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (equal(cmdp->cmdname, name))
break;
@ -588,6 +595,31 @@ cmdlookup(const char *name, int add)
return cmdp;
}
const void *
itercmd(const void *entry, struct cmdentry *result)
{
const struct tblentry *e = entry;
size_t i = 0;
if (e != NULL) {
if (e->next != NULL) {
e = e->next;
goto success;
}
i = hashname(e->cmdname) + 1;
}
for (; i < CMDTABLESIZE; i++)
if ((e = cmdtable[i]) != NULL)
goto success;
return (NULL);
success:
result->cmdtype = e->cmdtype;
result->cmdname = e->cmdname;
return (e);
}
/*
* Delete the command entry returned on the last lookup.
*/

View File

@ -53,6 +53,7 @@ struct cmdentry {
struct funcdef *func;
} u;
int special;
const char *cmdname;
};
@ -71,3 +72,4 @@ int unsetfunc(const char *);
int isfunc(const char *);
int typecmd_impl(int, char **, int, const char *);
void clearcmdentry(void);
const void *itercmd(const void *, struct cmdentry *);