Skip to content

Commit

Permalink
Added "apropos" and "find" commands from QuakeSpasm
Browse files Browse the repository at this point in the history
"find" is an alias for "apropos" (for consistency with MarkV)
  • Loading branch information
j0zzz committed Nov 12, 2022
1 parent 44e0853 commit 09dc623
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 1 deletion.
59 changes: 59 additions & 0 deletions trunk/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,63 @@ void Cmd_PrintTxt_f (void)
fclose (f);
}

static char* Cmd_TintSubstring(const char* in, const char* substr, char* out, size_t outsize)
{
int l;
char *m;

Q_strlcpy(out, in, outsize);
while ((m = Q_strcasestr(out, substr)))
{
l = strlen(substr);
while (l-- > 0)
if (*m >= ' ' && *m < 127)
*m++ |= 0x80;
}
return out;
}

/*
============
Cmd_Apropos_f
scans through each command and cvar names+descriptions for the given substring
we don't support descriptions, so this isn't really all that useful, but even without the sake of consistency it still combines cvars+commands under a single command.
============
*/
void Cmd_Apropos_f(void)
{
char tmpbuf[256];
int hits = 0;
cmd_function_t *cmd;
cvar_t *var;
const char *substr = Cmd_Argv(1);

if (!*substr)
{
Con_Printf("%s <substring> : search through commands and cvars for the given substring\n", Cmd_Argv(0));
return;
}
for (cmd = cmd_functions; cmd; cmd = cmd->next)
{
if (Q_strcasestr(cmd->name, substr))
{
hits++;
Con_Printf("%s\n", Cmd_TintSubstring(cmd->name, substr, tmpbuf, sizeof(tmpbuf)));
}
}

for (var = Cvar_FindVarAfter("", 0); var; var = var->next)
{
if (Q_strcasestr(var->name, substr))
{
hits++;
Con_Printf("%s (current value: \"%s\")\n", Cmd_TintSubstring(var->name, substr, tmpbuf, sizeof(tmpbuf)), var->string);
}
}
if (!hits)
Con_Printf("no cvars nor commands contain that substring\n");
}

/*
============
Cmd_Init
Expand All @@ -1639,6 +1696,8 @@ void Cmd_Init (void)
Cmd_AddCommand ("alias", Cmd_Alias_f);
Cmd_AddCommand ("cmd", Cmd_ForwardToServer);
Cmd_AddCommand ("wait", Cmd_Wait_f);
Cmd_AddCommand("apropos", Cmd_Apropos_f);
Cmd_AddCommand("find", Cmd_Apropos_f);

Cmd_AddCommand ("cmdlist", Cmd_CmdList_f);
Cmd_AddCommand ("dir", Cmd_Dir_f);
Expand Down
41 changes: 40 additions & 1 deletion trunk/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ size_t Q_strlcat(char *dst, const char *src, size_t siz)
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/

size_t Q_strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
Expand All @@ -343,6 +342,46 @@ size_t Q_strlcpy(char *dst, const char *src, size_t siz)
return(s - src - 1); /* count does not include NUL */
}

//joe: from QuakeSpasm
char* Q_strcasestr(const char* haystack, const char* needle)
{
int c1, c2, c2f;
int i;
c2f = *needle;
if (c2f >= 'a' && c2f <= 'z')
c2f -= ('a' - 'A');
if (!c2f)
return (char*)haystack;
while (1)
{
c1 = *haystack;
if (!c1)
return NULL;
if (c1 >= 'a' && c1 <= 'z')
c1 -= ('a' - 'A');
if (c1 == c2f)
{
for (i = 1; ; i++)
{
c1 = haystack[i];
c2 = needle[i];
if (c1 >= 'a' && c1 <= 'z')
c1 -= ('a' - 'A');
if (c2 >= 'a' && c2 <= 'z')
c2 -= ('a' - 'A');
if (!c2)
return (char*)haystack; //end of needle means we found a complete match
if (!c1) //end of haystack means we can't possibly find needle in it any more
return NULL;
if (c1 != c2) //mismatch means no match starting at haystack[0]
break;
}
}
haystack++;
}
return NULL; //didn't find it
}

/*
============================================================================
Expand Down
3 changes: 3 additions & 0 deletions trunk/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ void Q_snprintfz (char *dest, size_t size, char *fmt, ...);
size_t Q_strlcat(char *dst, const char *src, size_t siz);
size_t Q_strlcpy(char *dst, const char *src, size_t siz);

/* locale-insensitive case-insensitive alternative to strstr */
extern char* Q_strcasestr(const char* haystack, const char* needle);

static inline int Q_isdigit(int c)
{
return (c >= '0' && c <= '9');
Expand Down
24 changes: 24 additions & 0 deletions trunk/cvar.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ cvar_t *Cvar_FindVar (char *var_name)
return NULL;
}

cvar_t *Cvar_FindVarAfter(char *prev_name, unsigned int with_flags)
{
cvar_t *var;

if (*prev_name)
{
var = Cvar_FindVar(prev_name);
if (!var)
return NULL;
var = var->next;
}
else
var = cvar_vars;

// search for the next cvar matching the needed flags
while (var)
{
if ((var->flags & with_flags) || !with_flags)
break;
var = var->next;
}
return var;
}

/*
============
Cvar_ResetVar
Expand Down
2 changes: 2 additions & 0 deletions trunk/cvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ qboolean Cvar_Command (void);
void Cvar_WriteVariables (FILE *f);

cvar_t *Cvar_FindVar (char *var_name);
cvar_t *Cvar_FindVarAfter(char* prev_name, unsigned int with_flags);

void Cvar_Init (void);

extern cvar_t *cvar_vars;
Expand Down

0 comments on commit 09dc623

Please sign in to comment.