Adding CMDLIST and CVARLIST tutorial
by Matthias "Maddes" Buecher <maddes@bigfoot.com> http://www.inside3d.com/

You all know the commands "cmdlist" and "cvarlist" from Quake II and Quake 3 Arena, which are lacking in Classic Quake.
This tutorial will show you how to add them.

For "cmdlist" we need a new function in cmd.c, which you should add before all other functions.
It is based on the existing functions Cmd_Exists() and Cmd_CompleteCommand(), it loops through the linked list of all commands.
If a parameter is stated, it also compares the beginning of the command with it, so "cmdlist cl" displays only client variables.
You shouldn't have any problems to understand as there's no special logic in it.

// 2000-01-09 CmdList command by Maddes  start
/*
========
Cmd_List
========
*/
void Cmd_List_f (void)
{
	cmd_function_t	*cmd;
	char 		*partial;
	int		len;
	int		count;

	if (Cmd_Argc() > 1)
	{
		partial = Cmd_Argv (1);
		len = Q_strlen(partial);
	}
	else
	{
		partial = NULL;
		len = 0;
	}
	
	count=0;
	for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
	{
		if (partial && Q_strncmp (partial,cmd->name, len))
		{
			continue;
		}
		Con_Printf ("\"%s\"\n", cmd->name);
		count++;
	}

	Con_Printf ("%i command(s)", count);
	if (partial)
	{
		Con_Printf (" beginning with \"%s\"", partial);
	}
	Con_Printf ("\n");
}
// 2000-01-09 CmdList command by Maddes  end


At last you have to give the function a corresponding command, here "cmdlist".
Add the following line at the end of Cmd_Init() and "cmdlist" is fully implemented.

Cmd_AddCommand ("cvarlist", Cvar_List_f);	// 2000-01-09 CvarList command by Maddes


Nearly the same is done for "cvarlist", just add the following function to cvar.c.
It works the same way as it does for "cmdlist".

// 2000-01-09 CvarList command by Maddes  start
/*
=========
Cvar_List
=========
*/
void Cvar_List_f (void)
{
	cvar_t		*cvar;
	char 		*partial;
	int		len;
	int		count;

	if (Cmd_Argc() > 1)
	{
		partial = Cmd_Argv (1);
		len = Q_strlen(partial);
	}
	else
	{
		partial = NULL;
		len = 0;
	}

	count=0;
	for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
	{
		if (partial && Q_strncmp (partial,cvar->name, len))
		{
			continue;
		}
		Con_Printf ("\"%s\" is \"%s\"\n", cvar->name, cvar->string);
		count++;
	}

	Con_Printf ("%i cvar(s)", count);
	if (partial)
	{
		Con_Printf (" beginning with \"%s\"", partial);
	}
	Con_Printf ("\n");
}
// 2000-01-09 CvarList command by Maddes  end


Add the following line at the end of Cmd_Init() in cmd.c.

Cmd_AddCommand ("cvarlist", Cvar_List_f);	// 2000-01-09 CvarList command by Maddes


The only difference to "cmdlist" is that this function is defined in cvar.c and referenced in cmd.c, so we have to declare it in cvar.h.
(What a lovely example for the difference between definition and declaration, isn't it? :)

void	Cvar_List_f (void);	// 2000-01-09 CvarList command by Maddes
