~ctwm/ctwm/trunk

304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1
/*
554.1.10 by Matthew Fuller
Pull out the simple cases of long-form twm+Claude copyright/license
2
 *       Copyright 1988 by Evans & Sutherland Computer Corporation,
3
 *                          Salt Lake City, Utah
4
 *  Portions Copyright 1989 by the Massachusetts Institute of Technology
5
 *                        Cambridge, Massachusetts
6
 *
7
 * Copyright 1992 Claude Lecommandeur.
11 by Claude Lecommandeur
CTWM version 3.2p1
8
 */
1 by Claude Lecommandeur
CTWM version 1.1
9
10
/**********************************************************************
11
 *
12
 * $XConsortium: list.c,v 1.20 91/01/09 17:13:30 rws Exp $
13
 *
14
 * TWM code to deal with the name lists for the NoTitle list and
15
 * the AutoRaise list
16
 *
17
 * 11-Apr-88 Tom LaStrange        Initial Version.
18
 *
19
 * Do the necessary modification to be integrated in ctwm.
20
 * Can no longer be used for the standard twm.
21
 *
22
 * 22-April-92 Claude Lecommandeur.
23
 *
24
 *
25
 **********************************************************************/
26
395.1.1 by Matthew Fuller
Move ctwm.h to always be included first.
27
#include "ctwm.h"
28
1 by Claude Lecommandeur
CTWM version 1.1
29
#include <stdio.h>
491.1.14 by Matthew Fuller
Remove incorrect pre-ANSI potential override prototypes for malloc()
30
#include <stdlib.h>
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
31
648.1.1 by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind
32
#include "ctwm_shutdown.h"
1 by Claude Lecommandeur
CTWM version 1.1
33
#include "screen.h"
93 by Richard Levitte
- Convert all functions to use proper prototypes.
34
#include "list.h"
35
#include "util.h"
240.1.2 by Rhialto
3 - Selected a number of cleanups from Stefan Monnier
36
#include "parse.h"
1 by Claude Lecommandeur
CTWM version 1.1
37
320 by Matthew Fuller
Rename USE_GNU_REGEX to USE_SYS_REGEX, since it has nothing to do with
38
#ifdef USE_SYS_REGEX
79 by Dan Lilliehorn
Lots of updates and bugfixes.
39
# include <regex.h>
320 by Matthew Fuller
Rename USE_GNU_REGEX to USE_SYS_REGEX, since it has nothing to do with
40
#endif /* USE_SYS_REGEX */
79 by Dan Lilliehorn
Lots of updates and bugfixes.
41
42
17 by Claude Lecommandeur
CTWM version 3.5
43
1 by Claude Lecommandeur
CTWM version 1.1
44
/***********************************************************************
45
 *
46
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
47
 *      AddToList - add a window name to the appropriate list
1 by Claude Lecommandeur
CTWM version 1.1
48
 *
49
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
50
 *      list    - the address of the pointer to the head of a list
51
 *      name    - a pointer to the name of the window
52
 *      ptr     - pointer to list dependent data
1 by Claude Lecommandeur
CTWM version 1.1
53
 *
54
 *  Special Considerations
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
55
 *      If the list does not use the ptr value, a non-null value
56
 *      should be placed in it.  LookInList returns this ptr value
57
 *      and procedures calling LookInList will check for a non-null
58
 *      return value as an indication of success.
1 by Claude Lecommandeur
CTWM version 1.1
59
 *
60
 ***********************************************************************
61
 */
62
337.1.3 by Matthew Fuller
Change AddToList() to expect a void * for that ptr, since that's what
63
void AddToList(name_list **list_head, const char *name, void *ptr)
1 by Claude Lecommandeur
CTWM version 1.1
64
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
65
	name_list *nptr;
66
67
	if(!list_head) {
68
		return;        /* ignore empty inserts */
69
	}
70
491.1.8 by Matthew Fuller
Stop casting return values of [mc]alloc(). void * has existed for 27
71
	nptr = malloc(sizeof(name_list));
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
72
	if(nptr == NULL) {
73
		fprintf(stderr, "unable to allocate %lu bytes for name_list\n",
74
		        (unsigned long) sizeof(name_list));
648.1.19 by Matthew Fuller
Done() -> DoShutdown(). Imperative form is more descriptive, and it's
75
		DoShutdown();
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
76
	}
77
78
	nptr->next = *list_head;
491.1.9 by Matthew Fuller
Cleanup strdup() casting too.
79
	nptr->name = strdup(name);
492.2.117 by Matthew Fuller
Just use 1 as the placeholder value here instead of TRUE.
80
	nptr->ptr = (ptr == NULL) ? (char *)1 : ptr;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
81
	*list_head = nptr;
82
}
1 by Claude Lecommandeur
CTWM version 1.1
83
84
/***********************************************************************
85
 *
86
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
87
 *      LookInList - look through a list for a window name, or class
1 by Claude Lecommandeur
CTWM version 1.1
88
 *
89
 *  Returned Value:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
90
 *      the ptr field of the list structure or NULL if the name
91
 *      or class was not found in the list
1 by Claude Lecommandeur
CTWM version 1.1
92
 *
93
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
94
 *      list    - a pointer to the head of a list
95
 *      name    - a pointer to the name to look for
96
 *      class   - a pointer to the class to look for
1 by Claude Lecommandeur
CTWM version 1.1
97
 *
98
 ***********************************************************************
99
 */
100
323.1.9 by Matthew Fuller
These names for lists are trivially const.
101
void *LookInList(name_list *list_head, const char *name, XClassHint *class)
1 by Claude Lecommandeur
CTWM version 1.1
102
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
103
	name_list *nptr;
104
105
	/* look for the name first */
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
106
	for(nptr = list_head; nptr != NULL; nptr = nptr->next) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
107
		if(match(nptr->name, name)) {
108
			return (nptr->ptr);
109
		}
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
110
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
111
112
	if(class) {
113
		/* look for the res_name next */
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
114
		for(nptr = list_head; nptr != NULL; nptr = nptr->next) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
115
			if(match(nptr->name, class->res_name)) {
116
				return (nptr->ptr);
117
			}
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
118
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
119
120
		/* finally look for the res_class */
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
121
		for(nptr = list_head; nptr != NULL; nptr = nptr->next) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
122
			if(match(nptr->name, class->res_class)) {
123
				return (nptr->ptr);
124
			}
318.1.9 by Matthew Fuller
Add "unnecessary" braces around these for loops. Their bodies are an
125
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
126
	}
127
	return (NULL);
1 by Claude Lecommandeur
CTWM version 1.1
128
}
129
323.1.9 by Matthew Fuller
These names for lists are trivially const.
130
void *LookInNameList(name_list *list_head, const char *name)
1 by Claude Lecommandeur
CTWM version 1.1
131
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
132
	return (LookInList(list_head, name, NULL));
1 by Claude Lecommandeur
CTWM version 1.1
133
}
134
556.1.36 by Matthew Fuller
Add another shortcut func to return the list stuff with our standard
135
void *LookInListWin(name_list *list_head, TwmWindow *twin)
136
{
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
137
	return LookInList(list_head, twin->name, &(twin->class));
556.1.36 by Matthew Fuller
Add another shortcut func to return the list stuff with our standard
138
}
139
556.1.21 by Matthew Fuller
Add a trivial wrapper to cover an overwhelmingly common case.
140
bool IsInList(name_list *list_head, TwmWindow *twin)
141
{
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
142
	return (bool)LookInList(list_head, twin->name, &(twin->class));
556.1.21 by Matthew Fuller
Add a trivial wrapper to cover an overwhelmingly common case.
143
}
144
325 by Matthew Fuller
Run make indent.
145
void *LookPatternInList(name_list *list_head, const char *name,
146
                        XClassHint *class)
6 by Claude Lecommandeur
CTWM version 2.2
147
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
148
	name_list *nptr;
149
150
	for(nptr = list_head; nptr != NULL; nptr = nptr->next)
151
		if(match(nptr->name, name)) {
152
			return (nptr->name);
153
		}
154
155
	if(class) {
156
		for(nptr = list_head; nptr != NULL; nptr = nptr->next)
157
			if(match(nptr->name, class->res_name)) {
158
				return (nptr->name);
159
			}
160
161
		for(nptr = list_head; nptr != NULL; nptr = nptr->next)
162
			if(match(nptr->name, class->res_class)) {
163
				return (nptr->name);
164
			}
165
	}
166
	return (NULL);
6 by Claude Lecommandeur
CTWM version 2.2
167
}
168
323.1.9 by Matthew Fuller
These names for lists are trivially const.
169
void *LookPatternInNameList(name_list *list_head, const char *name)
6 by Claude Lecommandeur
CTWM version 2.2
170
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
171
	return (LookPatternInList(list_head, name, NULL));
6 by Claude Lecommandeur
CTWM version 2.2
172
}
173
1 by Claude Lecommandeur
CTWM version 1.1
174
/***********************************************************************
175
 *
176
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
177
 *      GetColorFromList - look through a list for a window name, or class
1 by Claude Lecommandeur
CTWM version 1.1
178
 *
179
 *  Returned Value:
492.2.100 by Matthew Fuller
Update comment
180
 *      true  if the name was found
181
 *      false if the name was not found
1 by Claude Lecommandeur
CTWM version 1.1
182
 *
183
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
184
 *      list    - a pointer to the head of a list
185
 *      name    - a pointer to the name to look for
186
 *      class   - a pointer to the class to look for
1 by Claude Lecommandeur
CTWM version 1.1
187
 *
188
 *  Outputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
189
 *      ptr     - fill in the list value if the name was found
1 by Claude Lecommandeur
CTWM version 1.1
190
 *
191
 ***********************************************************************
192
 */
193
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
194
bool GetColorFromList(name_list *list_head, char *name,
195
                      XClassHint *class, Pixel *ptr)
1 by Claude Lecommandeur
CTWM version 1.1
196
{
492.2.105 by Matthew Fuller
Switch some temp vars holding Scr->FirstTime over to bool.
197
	bool save;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
198
	name_list *nptr;
199
200
	for(nptr = list_head; nptr != NULL; nptr = nptr->next)
201
		if(match(nptr->name, name)) {
202
			save = Scr->FirstTime;
492.2.104 by Matthew Fuller
Massive rewrite of various struct Screen config params that are
203
			Scr->FirstTime = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
204
			GetColor(Scr->Monochrome, ptr, nptr->ptr);
205
			Scr->FirstTime = save;
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
206
			return true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
207
		}
208
209
	if(class) {
210
		for(nptr = list_head; nptr != NULL; nptr = nptr->next)
211
			if(match(nptr->name, class->res_name)) {
212
				save = Scr->FirstTime;
492.2.104 by Matthew Fuller
Massive rewrite of various struct Screen config params that are
213
				Scr->FirstTime = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
214
				GetColor(Scr->Monochrome, ptr, nptr->ptr);
215
				Scr->FirstTime = save;
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
216
				return true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
217
			}
218
219
		for(nptr = list_head; nptr != NULL; nptr = nptr->next)
220
			if(match(nptr->name, class->res_class)) {
221
				save = Scr->FirstTime;
492.2.104 by Matthew Fuller
Massive rewrite of various struct Screen config params that are
222
				Scr->FirstTime = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
223
				GetColor(Scr->Monochrome, ptr, nptr->ptr);
224
				Scr->FirstTime = save;
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
225
				return true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
226
			}
1 by Claude Lecommandeur
CTWM version 1.1
227
	}
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
228
	return false;
1 by Claude Lecommandeur
CTWM version 1.1
229
}
230
231
/***********************************************************************
232
 *
233
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
234
 *      FreeList - free up a list
1 by Claude Lecommandeur
CTWM version 1.1
235
 *
236
 ***********************************************************************
237
 */
238
93 by Richard Levitte
- Convert all functions to use proper prototypes.
239
void FreeList(name_list **list)
1 by Claude Lecommandeur
CTWM version 1.1
240
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
241
	name_list *nptr;
242
	name_list *tmp;
1 by Claude Lecommandeur
CTWM version 1.1
243
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
244
	for(nptr = *list; nptr != NULL;) {
245
		tmp = nptr->next;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
246
		free(nptr->name);
491.1.11 by Matthew Fuller
Stop casting arg to free(), especially to char *.
247
		free(nptr);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
248
		nptr = tmp;
249
	}
250
	*list = NULL;
1 by Claude Lecommandeur
CTWM version 1.1
251
}
5 by Claude Lecommandeur
CTWM version 2.1
252
320 by Matthew Fuller
Rename USE_GNU_REGEX to USE_SYS_REGEX, since it has nothing to do with
253
#ifdef USE_SYS_REGEX
79 by Dan Lilliehorn
Lots of updates and bugfixes.
254
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
255
bool match(const char *pattern, const char *string)
79 by Dan Lilliehorn
Lots of updates and bugfixes.
256
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
257
	regex_t preg;
258
	int error;
79 by Dan Lilliehorn
Lots of updates and bugfixes.
259
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
260
	if((pattern == NULL) || (string == NULL)) {
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
261
		return false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
262
	}
263
	error = regcomp(&preg, pattern, REG_EXTENDED | REG_NOSUB);
264
	if(error != 0) {
265
		char buf [256];
522.1.1 by Matthew Fuller
Eliminate most (void) casts; they don't really add anything, and just
266
		regerror(error, &preg, buf, sizeof buf);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
267
		fprintf(stderr, "%s : %s\n", buf, pattern);
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
268
		return false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
269
	}
270
	error = regexec(&preg, string, 5, 0, 0);
271
	regfree(&preg);
272
	if(error == 0) {
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
273
		return true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
274
	}
492.2.96 by Matthew Fuller
bool-ify another couple boolean functions.
275
	return false;
79 by Dan Lilliehorn
Lots of updates and bugfixes.
276
}
277
278
#else
279
280
281
302.1.45 by Olaf 'Rhialto' Seibert
Some more const.
282
int regex_match(const char *p, const char *t);
283
int regex_match_after_star(const char *p, const char *t);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
284
285
#if 0                           /* appears not to be used anywhere */
286
static int is_pattern(char *p)
287
{
288
	while(*p) {
289
		switch(*p++) {
290
			case '?':
291
			case '*':
292
			case '[':
293
				return TRUE;
294
			case '\\':
295
				if(!*p++) {
296
					return FALSE;
297
				}
298
		}
299
	}
300
	return FALSE;
301
}
302
#endif
303
304
#define ABORT 2
305
302.1.45 by Olaf 'Rhialto' Seibert
Some more const.
306
int regex_match(const char *p, const char *t)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
307
{
434 by Matthew Fuller
Eliminate register qualifiers. The judgements of even very smart
308
	char range_start, range_end;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
309
	int invert;
310
	int member_match;
311
	int loop;
312
313
	for(; *p; p++, t++) {
314
		if(!*t) {
315
			return (*p == '*' && *++p == '\0') ? TRUE : ABORT;
316
		}
317
		switch(*p) {
318
			case '?':
319
				break;
320
			case '*':
321
				return regex_match_after_star(p, t);
322
			case '[': {
323
				p++;
324
				invert = FALSE;
325
				if(*p == '!' || *p == '^') {
326
					invert = TRUE;
327
					p++;
328
				}
329
				if(*p == ']') {
330
					return ABORT;
331
				}
332
				member_match = FALSE;
333
				loop = TRUE;
334
				while(loop) {
335
					if(*p == ']') {
336
						loop = FALSE;
337
						continue;
338
					}
339
					if(*p == '\\') {
340
						range_start = range_end = *++p;
341
					}
342
					else {
343
						range_start = range_end = *p;
344
					}
345
					if(!range_start) {
346
						return ABORT;
347
					}
348
					if(*++p == '-') {
349
						range_end = *++p;
350
						if(range_end == '\0' || range_end == ']') {
351
							return ABORT;
352
						}
353
						if(range_end == '\\') {
354
							range_end = *++p;
355
						}
356
						p++;
357
					}
358
					if(range_start < range_end) {
359
						if(*t >= range_start && *t <= range_end) {
360
							member_match = TRUE;
361
							loop = FALSE;
362
						}
363
					}
364
					else {
365
						if(*t >= range_end && *t <= range_start) {
366
							member_match = TRUE;
367
							loop = FALSE;
368
						}
369
					}
370
				}
371
				if((invert && member_match) || !(invert || member_match)) {
372
					return (FALSE);
373
				}
374
				if(member_match) {
375
					while(*p != ']') {
376
						if(!*p) {
377
							return (ABORT);
378
						}
379
						if(*p == '\\') {
380
							p++;
381
						}
382
						p++;
383
					}
384
				}
385
				break;
386
			}
387
			case '\\':
388
				p++;
389
390
			default:
391
				if(*p != *t) {
392
					return (FALSE);
393
				}
394
		}
395
	}
396
	return (!*t);
397
}
398
302.1.45 by Olaf 'Rhialto' Seibert
Some more const.
399
int regex_match_after_star(const char *p, const char *t)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
400
{
434 by Matthew Fuller
Eliminate register qualifiers. The judgements of even very smart
401
	int mat;
402
	int nextp;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
403
404
	while((*p == '?') || (*p == '*')) {
405
		if(*p == '?') {
406
			if(!*t++) {
407
				return ABORT;
408
			}
409
		}
410
		p++;
411
	}
412
	if(!*p) {
5 by Claude Lecommandeur
CTWM version 2.1
413
		return TRUE;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
414
	}
415
416
	nextp = *p;
417
	if(nextp == '\\') {
418
		nextp = p[1];
419
	}
420
421
	mat = FALSE;
422
	while(mat == FALSE) {
423
		if(nextp == *t || nextp == '[') {
424
			mat = regex_match(p, t);
425
		}
426
		if(!*t++) {
427
			mat = ABORT;
428
		}
429
	}
430
	return (mat);
431
}
432
302.1.44 by Olaf 'Rhialto' Seibert
Merge from trunk (with a few small conflicts).
433
int match(const char *p, const char *t)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
434
{
435
	if((p == NULL) || (t == NULL)) {
436
		return (FALSE);
437
	}
438
	return ((regex_match(p, t) == TRUE) ? TRUE : FALSE);
5 by Claude Lecommandeur
CTWM version 2.1
439
}
79 by Dan Lilliehorn
Lots of updates and bugfixes.
440
441
#endif
442
443
444
445