+static void Cmd_Apropos_f(void)
+{
+ cmd_function_t *cmd;
+ cvar_t *cvar;
+ cmdalias_t *alias;
+ const char *partial;
+ int count;
+ qboolean ispattern;
+
+ if (Cmd_Argc() > 1)
+ partial = Cmd_Args();
+ else
+ {
+ Con_Printf("usage: apropos <string>\n");
+ return;
+ }
+
+ ispattern = partial && (strchr(partial, '*') || strchr(partial, '?'));
+ if(!ispattern)
+ partial = va("*%s*", partial);
+
+ count = 0;
+ for (cvar = cvar_vars; cvar; cvar = cvar->next)
+ {
+ if (!matchpattern_with_separator(cvar->name, partial, true, "", false))
+ if (!matchpattern_with_separator(cvar->description, partial, true, "", false))
+ continue;
+ Con_Printf ("cvar ^3%s^7 is \"%s\" [\"%s\"] %s\n", cvar->name, cvar->string, cvar->defstring, cvar->description);
+ count++;
+ }
+ for (cmd = cmd_functions; cmd; cmd = cmd->next)
+ {
+ if (!matchpattern_with_separator(cmd->name, partial, true, "", false))
+ if (!matchpattern_with_separator(cmd->description, partial, true, "", false))
+ continue;
+ Con_Printf("command ^2%s^7: %s\n", cmd->name, cmd->description);
+ count++;
+ }
+ for (alias = cmd_alias; alias; alias = alias->next)
+ {
+ // procede here a bit differently as an alias value always got a final \n
+ if (!matchpattern_with_separator(alias->name, partial, true, "", false))
+ if (!matchpattern_with_separator(alias->value, partial, true, "\n", false)) // when \n is as separator wildcards don't match it
+ continue;
+ Con_Printf("alias ^5%s^7: %s", alias->name, alias->value); // do not print an extra \n
+ count++;
+ }
+ Con_Printf("%i result%s\n\n", count, (count > 1) ? "s" : "");
+}
+