1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 //
21 // alias.c
22 //
23
24 #include "common.h"
25
26 #define MAX_ALIAS_HASH 32
27
28 aliasCmd_t *com_aliasList;
29 aliasCmd_t *com_aliasHashTree[MAX_ALIAS_HASH];
30
31 int com_aliasCount;
32
33 /*
34 =============================================================================
35
36 ALIASES
37
38 =============================================================================
39 */
40
41 /*
42 ============
43 Alias_Exists
44 ============
45 */
Alias_Exists(char * aliasName)46 aliasCmd_t *Alias_Exists (char *aliasName)
47 {
48 aliasCmd_t *alias;
49 uint32 hash;
50
51 if (!aliasName)
52 return NULL;
53
54 hash = Com_HashGeneric (aliasName, MAX_ALIAS_HASH);
55 for (alias=com_aliasHashTree[hash] ; alias ; alias=alias->hashNext) {
56 if (!Q_stricmp (aliasName, alias->name))
57 return alias;
58 }
59
60 return NULL;
61 }
62
63
64 /*
65 ============
66 Alias_CallBack
67 ============
68 */
Alias_CallBack(void (* callBack)(const char * name))69 void Alias_CallBack (void (*callBack) (const char *name))
70 {
71 aliasCmd_t *alias;
72
73 for (alias=com_aliasList ; alias ; alias=alias->next)
74 callBack (alias->name);
75 }
76
77
78 /*
79 ============
80 Alias_AddAlias
81 ============
82 */
Alias_AddAlias(char * aliasName)83 static void Alias_AddAlias (char *aliasName)
84 {
85 aliasCmd_t *alias;
86 char cmd[2048];
87 int i, c;
88
89 // Check if it's already a command
90 if (Cmd_Exists (aliasName)) {
91 Com_Printf (PRNT_WARNING, "Alias_AddAlias: \"%s\" already defined as a command\n", aliasName);
92 return;
93 }
94
95 // Check if it's already a cvar
96 if (Cvar_Exists (aliasName)) {
97 Com_Printf (PRNT_WARNING, "Alias_AddAlias: \"%s\" already defined as a cvar\n", aliasName);
98 return;
99 }
100
101 // Check name length
102 if (strlen(aliasName)+1 >= MAX_ALIAS_NAME) {
103 Com_Printf (PRNT_WARNING, "Alias_AddAlias: name \"%s\" too long\n", aliasName);
104 return;
105 }
106
107 // See if it's actually getting a value
108 if (Cmd_Argc () < 3) {
109 Com_Printf (PRNT_WARNING, "Alias_AddAlias: no commands for \"%s\" alias\n", aliasName);
110 return;
111 }
112
113 // If the alias already exists, reuse it
114 alias = Alias_Exists (aliasName);
115 if (alias) {
116 Mem_Free (alias->value);
117 }
118 else {
119 alias = Mem_PoolAlloc (sizeof (aliasCmd_t), com_aliasSysPool, 0);
120 alias->hashValue = Com_HashGeneric (aliasName, MAX_ALIAS_HASH);
121
122 // Link it in
123 alias->next = com_aliasList;
124 com_aliasList = alias;
125
126 // Link it into the hash tree
127 alias->hashNext = com_aliasHashTree[alias->hashValue];
128 com_aliasHashTree[alias->hashValue] = alias;
129 }
130 Q_strncpyz (alias->name, aliasName, sizeof (alias->name));
131
132 // Copy the rest of the command line
133 cmd[0] = 0; // Start out with a null string
134 c = Cmd_Argc ();
135 for (i=2 ; i<c ; i++) {
136 Q_strcatz (cmd, Cmd_Argv (i), sizeof (cmd));
137 if (i != (c - 1))
138 Q_strcatz (cmd, " ", sizeof (cmd));
139 }
140 Q_strcatz (cmd, "\n", sizeof (cmd));
141
142 alias->value = Mem_PoolStrDup (cmd, com_aliasSysPool, 0);
143 }
144
145
146 /*
147 ============
148 Alias_RemoveAlias
149 ============
150 */
Alias_RemoveAlias(char * aliasName)151 void Alias_RemoveAlias (char *aliasName)
152 {
153 aliasCmd_t *alias, **prev;
154
155 if (!aliasName || !aliasName[0]) {
156 Com_Printf (PRNT_WARNING, "Alias_RemoveAlias: NULL aliasName\n");
157 return;
158 }
159
160 // de-link it from alias list
161 prev = &com_aliasList;
162 for ( ; ; ) {
163 alias = *prev;
164 if (!alias) {
165 Com_Printf (PRNT_WARNING, "Alias_RemoveAlias: %s not added\n", aliasName);
166 return;
167 }
168
169 if (!Q_stricmp (aliasName, alias->name)) {
170 *prev = alias->next;
171 break;
172 }
173 prev = &alias->next;
174 }
175
176 // de-link it from hash list
177 prev = &com_aliasHashTree[alias->hashValue];
178 for ( ; ; ) {
179 alias = *prev;
180 if (!alias) {
181 Com_Printf (PRNT_WARNING, "Alias_RemoveAlias: %s not added to hash list\n", aliasName);
182 return;
183 }
184
185 if (!Q_stricmp (aliasName, alias->name)) {
186 *prev = alias->hashNext;
187 if (alias->value)
188 Mem_Free (alias->value);
189 Mem_Free (alias);
190 return;
191 }
192 prev = &alias->hashNext;
193 }
194 }
195
196 /*
197 ==============================================================================
198
199 CONSOLE COMMANDS
200
201 ==============================================================================
202 */
203
204 /*
205 ===============
206 Cmd_Alias_f
207
208 Creates a new command that executes a command string (possibly ; seperated)
209 ===============
210 */
Cmd_Alias_f(void)211 static void Cmd_Alias_f (void)
212 {
213 if (Cmd_Argc () == 1) {
214 Com_Printf (0, "syntax: alias <name> <value>; 'aliaslist' to see a list\n");
215 return;
216 }
217
218 Alias_AddAlias (Cmd_Argv (1));
219 }
220
221
222 /*
223 ===============
224 Cmd_Unalias_f
225
226 Kills an alias
227 ===============
228 */
Cmd_Unalias_f(void)229 static void Cmd_Unalias_f (void)
230 {
231 if (Cmd_Argc () != 2) {
232 Com_Printf (0, "syntax: unalias <name>; 'aliaslist' to see a list\n");
233 return;
234 }
235
236 Alias_RemoveAlias (Cmd_Argv (1));
237 }
238
239
240 /*
241 ============
242 Cmd_AliasList_f
243 ============
244 */
alphaSortCmp(const void * _a,const void * _b)245 static int alphaSortCmp (const void *_a, const void *_b) {
246 const aliasCmd_t *a = (const aliasCmd_t *) _a;
247 const aliasCmd_t *b = (const aliasCmd_t *) _b;
248
249 return Q_stricmp (a->name, b->name);
250 }
Cmd_AliasList_f(void)251 static void Cmd_AliasList_f (void)
252 {
253 aliasCmd_t *alias, *sortedList;
254 int i, j;
255 int matching;
256 int longest;
257 int total;
258 char *wildCard;
259
260 if ((Cmd_Argc () != 1) && (Cmd_Argc () != 2)) {
261 Com_Printf (0, "usage: aliaslist [wildcard]\n");
262 return;
263 }
264
265 if (Cmd_Argc () == 2)
266 wildCard = Cmd_Argv (1);
267 else
268 wildCard = "*";
269
270 // create a list
271 for (matching=0, total=0, alias=com_aliasList ; alias ; alias=alias->next, total++) {
272 if (!Q_WildcardMatch (wildCard, alias->name, 1))
273 continue;
274 matching++;
275 }
276
277 if (!matching) {
278 Com_Printf (0, "%i aliases total, %i matching\n", total, matching);
279 return;
280 }
281
282 sortedList = Mem_PoolAlloc (matching * sizeof (aliasCmd_t), com_aliasSysPool, 0);
283 for (matching=0, longest=0, alias=com_aliasList ; alias ; alias=alias->next) {
284 if (!Q_WildcardMatch (wildCard, alias->name, 1))
285 continue;
286
287 if ((int)strlen (alias->name) > longest)
288 longest = strlen (alias->name);
289
290 sortedList[matching++] = *alias;
291 }
292
293 // sort it
294 qsort (sortedList, matching, sizeof (sortedList[0]), alphaSortCmp);
295
296 // print it
297 longest++;
298 for (i=0 ; i<matching ; i++) {
299 alias = &sortedList[i];
300
301 Com_Printf (0, alias->name);
302 for (j=0 ; j<longest-(int)strlen(alias->name) ; j++)
303 Com_Printf (0, " ");
304 Com_Printf (0, "\"%s\"\n", alias->value);
305 }
306
307 if (matching)
308 Mem_Free (sortedList);
309 Com_Printf (0, "%i aliases total, %i matching\n", total, matching);
310 }
311
312 /*
313 =============================================================================
314
315 INITIALIZATION
316
317 =============================================================================
318 */
319
320 /*
321 ============
322 Alias_Init
323 ============
324 */
Alias_Init(void)325 void Alias_Init (void)
326 {
327 memset (com_aliasHashTree, 0, sizeof (com_aliasHashTree));
328
329 Cmd_AddCommand ("alias", Cmd_Alias_f, "Adds an alias command");
330 Cmd_AddCommand ("unalias", Cmd_Unalias_f, "Removes an alias command");
331 Cmd_AddCommand ("aliaslist", Cmd_AliasList_f, "Prints out a list of alias commands");
332 }
333