list.c revision 645f5050
1645f5050Syouri/*****************************************************************************/ 2645f5050Syouri/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ 3645f5050Syouri/** Salt Lake City, Utah **/ 4645f5050Syouri/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ 5645f5050Syouri/** Cambridge, Massachusetts **/ 6645f5050Syouri/** **/ 7645f5050Syouri/** All Rights Reserved **/ 8645f5050Syouri/** **/ 9645f5050Syouri/** Permission to use, copy, modify, and distribute this software and **/ 10645f5050Syouri/** its documentation for any purpose and without fee is hereby **/ 11645f5050Syouri/** granted, provided that the above copyright notice appear in all **/ 12645f5050Syouri/** copies and that both that copyright notice and this permis- **/ 13645f5050Syouri/** sion notice appear in supporting documentation, and that the **/ 14645f5050Syouri/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ 15645f5050Syouri/** in publicity pertaining to distribution of the software without **/ 16645f5050Syouri/** specific, written prior permission. **/ 17645f5050Syouri/** **/ 18645f5050Syouri/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ 19645f5050Syouri/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ 20645f5050Syouri/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ 21645f5050Syouri/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ 22645f5050Syouri/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ 23645f5050Syouri/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ 24645f5050Syouri/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ 25645f5050Syouri/** OR PERFORMANCE OF THIS SOFTWARE. **/ 26645f5050Syouri/*****************************************************************************/ 27645f5050Syouri/* 28645f5050Syouri * [ ctwm ] 29645f5050Syouri * 30645f5050Syouri * Copyright 1992 Claude Lecommandeur. 31645f5050Syouri * 32645f5050Syouri * Permission to use, copy, modify and distribute this software [ctwm] and 33645f5050Syouri * its documentation for any purpose is hereby granted without fee, provided 34645f5050Syouri * that the above copyright notice appear in all copies and that both that 35645f5050Syouri * copyright notice and this permission notice appear in supporting documen- 36645f5050Syouri * tation, and that the name of Claude Lecommandeur not be used in adverti- 37645f5050Syouri * sing or publicity pertaining to distribution of the software without 38645f5050Syouri * specific, written prior permission. Claude Lecommandeur make no represen- 39645f5050Syouri * tations about the suitability of this software for any purpose. It is 40645f5050Syouri * provided "as is" without express or implied warranty. 41645f5050Syouri * 42645f5050Syouri * Claude Lecommandeur DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 43645f5050Syouri * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 44645f5050Syouri * EVENT SHALL Claude Lecommandeur BE LIABLE FOR ANY SPECIAL, INDIRECT OR 45645f5050Syouri * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 46645f5050Syouri * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 47645f5050Syouri * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 48645f5050Syouri * PERFORMANCE OF THIS SOFTWARE. 49645f5050Syouri * 50645f5050Syouri * Author: Claude Lecommandeur [ lecom@sic.epfl.ch ][ April 1992 ] 51645f5050Syouri */ 52645f5050Syouri 53645f5050Syouri 54645f5050Syouri/********************************************************************** 55645f5050Syouri * 56645f5050Syouri * $XConsortium: list.c,v 1.20 91/01/09 17:13:30 rws Exp $ 57645f5050Syouri * 58645f5050Syouri * TWM code to deal with the name lists for the NoTitle list and 59645f5050Syouri * the AutoRaise list 60645f5050Syouri * 61645f5050Syouri * 11-Apr-88 Tom LaStrange Initial Version. 62645f5050Syouri * 63645f5050Syouri * Do the necessary modification to be integrated in ctwm. 64645f5050Syouri * Can no longer be used for the standard twm. 65645f5050Syouri * 66645f5050Syouri * 22-April-92 Claude Lecommandeur. 67645f5050Syouri * 68645f5050Syouri * 69645f5050Syouri **********************************************************************/ 70645f5050Syouri 71645f5050Syouri#include <stdio.h> 72645f5050Syouri#ifdef VMS 73645f5050Syouri#include <string.h> 74645f5050Syouri#endif 75645f5050Syouri#include "twm.h" 76645f5050Syouri#include "screen.h" 77645f5050Syouri#include "gram.tab.h" 78645f5050Syouri#include "list.h" 79645f5050Syouri#include "util.h" 80645f5050Syouri 81645f5050Syouri#ifdef USE_GNU_REGEX 82645f5050Syouri# include <regex.h> 83645f5050Syouri#endif /* USE_GNU_REGEX */ 84645f5050Syouri 85645f5050Syouri 86645f5050Syouriextern void twmrc_error_prefix(void); 87645f5050Syouri 88645f5050Syouri/*********************************************************************** 89645f5050Syouri * 90645f5050Syouri * Procedure: 91645f5050Syouri * AddToList - add a window name to the appropriate list 92645f5050Syouri * 93645f5050Syouri * Inputs: 94645f5050Syouri * list - the address of the pointer to the head of a list 95645f5050Syouri * name - a pointer to the name of the window 96645f5050Syouri * ptr - pointer to list dependent data 97645f5050Syouri * 98645f5050Syouri * Special Considerations 99645f5050Syouri * If the list does not use the ptr value, a non-null value 100645f5050Syouri * should be placed in it. LookInList returns this ptr value 101645f5050Syouri * and procedures calling LookInList will check for a non-null 102645f5050Syouri * return value as an indication of success. 103645f5050Syouri * 104645f5050Syouri *********************************************************************** 105645f5050Syouri */ 106645f5050Syouri 107645f5050Syouri#if 0 /* appears not to be used anywhere */ 108645f5050Syouristatic int is_pattern (char *p); 109645f5050Syouri#endif 110645f5050Syouri 111645f5050Syourivoid AddToList(name_list **list_head, char *name, char *ptr) 112645f5050Syouri{ 113645f5050Syouri name_list *nptr; 114645f5050Syouri 115645f5050Syouri if (!list_head) return; /* ignore empty inserts */ 116645f5050Syouri 117645f5050Syouri nptr = (name_list *)malloc(sizeof(name_list)); 118645f5050Syouri if (nptr == NULL) 119645f5050Syouri { 120645f5050Syouri twmrc_error_prefix(); 121645f5050Syouri fprintf (stderr, "unable to allocate %lu bytes for name_list\n", 122645f5050Syouri (unsigned long) sizeof(name_list)); 123645f5050Syouri Done(0); 124645f5050Syouri } 125645f5050Syouri 126645f5050Syouri nptr->next = *list_head; 127645f5050Syouri#ifdef VMS 128645f5050Syouri { 129645f5050Syouri char *ftemp; 130645f5050Syouri ftemp = (char *) malloc((strlen(name)+1)*sizeof(char)); 131645f5050Syouri nptr->name = strcpy (ftemp,name); 132645f5050Syouri } 133645f5050Syouri#else 134645f5050Syouri nptr->name = (char*) strdup (name); 135645f5050Syouri#endif 136645f5050Syouri nptr->ptr = (ptr == NULL) ? (char *)TRUE : ptr; 137645f5050Syouri *list_head = nptr; 138645f5050Syouri} 139645f5050Syouri 140645f5050Syouri/*********************************************************************** 141645f5050Syouri * 142645f5050Syouri * Procedure: 143645f5050Syouri * LookInList - look through a list for a window name, or class 144645f5050Syouri * 145645f5050Syouri * Returned Value: 146645f5050Syouri * the ptr field of the list structure or NULL if the name 147645f5050Syouri * or class was not found in the list 148645f5050Syouri * 149645f5050Syouri * Inputs: 150645f5050Syouri * list - a pointer to the head of a list 151645f5050Syouri * name - a pointer to the name to look for 152645f5050Syouri * class - a pointer to the class to look for 153645f5050Syouri * 154645f5050Syouri *********************************************************************** 155645f5050Syouri */ 156645f5050Syouri 157645f5050Syourivoid *LookInList(name_list *list_head, char *name, XClassHint *class) 158645f5050Syouri{ 159645f5050Syouri name_list *nptr; 160645f5050Syouri 161645f5050Syouri /* look for the name first */ 162645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 163645f5050Syouri if (match (nptr->name, name)) 164645f5050Syouri return (nptr->ptr); 165645f5050Syouri 166645f5050Syouri if (class) 167645f5050Syouri { 168645f5050Syouri /* look for the res_name next */ 169645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 170645f5050Syouri if (match (nptr->name, class->res_name)) 171645f5050Syouri return (nptr->ptr); 172645f5050Syouri 173645f5050Syouri /* finally look for the res_class */ 174645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 175645f5050Syouri if (match (nptr->name, class->res_class)) 176645f5050Syouri return (nptr->ptr); 177645f5050Syouri } 178645f5050Syouri return (NULL); 179645f5050Syouri} 180645f5050Syouri 181645f5050Syourivoid *LookInNameList(name_list *list_head, char *name) 182645f5050Syouri{ 183645f5050Syouri return (LookInList(list_head, name, NULL)); 184645f5050Syouri} 185645f5050Syouri 186645f5050Syourivoid *LookPatternInList(name_list *list_head, char *name, XClassHint *class) 187645f5050Syouri{ 188645f5050Syouri name_list *nptr; 189645f5050Syouri 190645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 191645f5050Syouri if (match (nptr->name, name)) 192645f5050Syouri return (nptr->name); 193645f5050Syouri 194645f5050Syouri if (class) 195645f5050Syouri { 196645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 197645f5050Syouri if (match (nptr->name, class->res_name)) 198645f5050Syouri return (nptr->name); 199645f5050Syouri 200645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 201645f5050Syouri if (match (nptr->name, class->res_class)) 202645f5050Syouri return (nptr->name); 203645f5050Syouri } 204645f5050Syouri return (NULL); 205645f5050Syouri} 206645f5050Syouri 207645f5050Syourivoid *LookPatternInNameList (name_list *list_head, char *name) 208645f5050Syouri{ 209645f5050Syouri return (LookPatternInList(list_head, name, NULL)); 210645f5050Syouri} 211645f5050Syouri 212645f5050Syouri/*********************************************************************** 213645f5050Syouri * 214645f5050Syouri * Procedure: 215645f5050Syouri * GetColorFromList - look through a list for a window name, or class 216645f5050Syouri * 217645f5050Syouri * Returned Value: 218645f5050Syouri * TRUE if the name was found 219645f5050Syouri * FALSE if the name was not found 220645f5050Syouri * 221645f5050Syouri * Inputs: 222645f5050Syouri * list - a pointer to the head of a list 223645f5050Syouri * name - a pointer to the name to look for 224645f5050Syouri * class - a pointer to the class to look for 225645f5050Syouri * 226645f5050Syouri * Outputs: 227645f5050Syouri * ptr - fill in the list value if the name was found 228645f5050Syouri * 229645f5050Syouri *********************************************************************** 230645f5050Syouri */ 231645f5050Syouri 232645f5050Syouriint GetColorFromList(name_list *list_head, char *name, 233645f5050Syouri XClassHint *class, Pixel *ptr) 234645f5050Syouri{ 235645f5050Syouri int save; 236645f5050Syouri name_list *nptr; 237645f5050Syouri 238645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 239645f5050Syouri if (match (nptr->name, name)) 240645f5050Syouri { 241645f5050Syouri save = Scr->FirstTime; 242645f5050Syouri Scr->FirstTime = TRUE; 243645f5050Syouri GetColor(Scr->Monochrome, ptr, nptr->ptr); 244645f5050Syouri Scr->FirstTime = save; 245645f5050Syouri return (TRUE); 246645f5050Syouri } 247645f5050Syouri 248645f5050Syouri if (class) 249645f5050Syouri { 250645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 251645f5050Syouri if (match (nptr->name, class->res_name)) 252645f5050Syouri { 253645f5050Syouri save = Scr->FirstTime; 254645f5050Syouri Scr->FirstTime = TRUE; 255645f5050Syouri GetColor(Scr->Monochrome, ptr, nptr->ptr); 256645f5050Syouri Scr->FirstTime = save; 257645f5050Syouri return (TRUE); 258645f5050Syouri } 259645f5050Syouri 260645f5050Syouri for (nptr = list_head; nptr != NULL; nptr = nptr->next) 261645f5050Syouri if (match (nptr->name, class->res_class)) 262645f5050Syouri { 263645f5050Syouri save = Scr->FirstTime; 264645f5050Syouri Scr->FirstTime = TRUE; 265645f5050Syouri GetColor(Scr->Monochrome, ptr, nptr->ptr); 266645f5050Syouri Scr->FirstTime = save; 267645f5050Syouri return (TRUE); 268645f5050Syouri } 269645f5050Syouri } 270645f5050Syouri return (FALSE); 271645f5050Syouri} 272645f5050Syouri 273645f5050Syouri/*********************************************************************** 274645f5050Syouri * 275645f5050Syouri * Procedure: 276645f5050Syouri * FreeList - free up a list 277645f5050Syouri * 278645f5050Syouri *********************************************************************** 279645f5050Syouri */ 280645f5050Syouri 281645f5050Syourivoid FreeList(name_list **list) 282645f5050Syouri{ 283645f5050Syouri name_list *nptr; 284645f5050Syouri name_list *tmp; 285645f5050Syouri 286645f5050Syouri for (nptr = *list; nptr != NULL; ) 287645f5050Syouri { 288645f5050Syouri tmp = nptr->next; 289645f5050Syouri free((char *) nptr); 290645f5050Syouri nptr = tmp; 291645f5050Syouri } 292645f5050Syouri *list = NULL; 293645f5050Syouri} 294645f5050Syouri 295645f5050Syouri#ifdef USE_GNU_REGEX 296645f5050Syouri 297645f5050Syouri#define MAXPATLEN 256 298645f5050Syouri 299645f5050Syouriint match (pattern, string) 300645f5050Syouri char *pattern, *string; 301645f5050Syouri{ 302645f5050Syouri regex_t preg; 303645f5050Syouri int error; 304645f5050Syouri 305645f5050Syouri if ((pattern == NULL) || (string == NULL)) return 0; 306645f5050Syouri error = regcomp (&preg, pattern, REG_EXTENDED | REG_NOSUB); 307645f5050Syouri if (error != 0) { 308645f5050Syouri char buf [256]; 309645f5050Syouri (void) regerror (error, &preg, buf, sizeof buf); 310645f5050Syouri fprintf (stderr, "%s : %s\n", buf, pattern); 311645f5050Syouri return 0; 312645f5050Syouri } 313645f5050Syouri error = regexec (&preg, string, 5, 0, 0); 314645f5050Syouri regfree (&preg); 315645f5050Syouri if (error == 0) return 1; 316645f5050Syouri return 0; 317645f5050Syouri} 318645f5050Syouri 319645f5050Syouri#else 320645f5050Syouri 321645f5050Syouri 322645f5050Syouri 323645f5050Syouriint regex_match (char *p, char *t); 324645f5050Syouriint regex_match_after_star (char *p, char *t); 325645f5050Syouri 326645f5050Syouri#if 0 /* appears not to be used anywhere */ 327645f5050Syouristatic int is_pattern (char *p) 328645f5050Syouri{ 329645f5050Syouri while ( *p ) { 330645f5050Syouri switch ( *p++ ) { 331645f5050Syouri case '?': 332645f5050Syouri case '*': 333645f5050Syouri case '[': 334645f5050Syouri return TRUE; 335645f5050Syouri case '\\': 336645f5050Syouri if ( !*p++ ) return FALSE; 337645f5050Syouri } 338645f5050Syouri } 339645f5050Syouri return FALSE; 340645f5050Syouri} 341645f5050Syouri#endif 342645f5050Syouri 343645f5050Syouri#define ABORT 2 344645f5050Syouri 345645f5050Syouriint regex_match (char *p, char *t) 346645f5050Syouri{ 347645f5050Syouri register char range_start, range_end; 348645f5050Syouri int invert; 349645f5050Syouri int member_match; 350645f5050Syouri int loop; 351645f5050Syouri 352645f5050Syouri for ( ; *p; p++, t++ ) { 353645f5050Syouri if (!*t) return ( *p == '*' && *++p == '\0' ) ? TRUE : ABORT; 354645f5050Syouri switch ( *p ) { 355645f5050Syouri case '?': 356645f5050Syouri break; 357645f5050Syouri case '*': 358645f5050Syouri return regex_match_after_star (p, t); 359645f5050Syouri case '[': { 360645f5050Syouri p++; 361645f5050Syouri invert = FALSE; 362645f5050Syouri if ( *p == '!' || *p == '^') { 363645f5050Syouri invert = TRUE; 364645f5050Syouri p++; 365645f5050Syouri } 366645f5050Syouri if ( *p == ']' ) return ABORT; 367645f5050Syouri member_match = FALSE; 368645f5050Syouri loop = TRUE; 369645f5050Syouri while ( loop ) { 370645f5050Syouri if (*p == ']') { 371645f5050Syouri loop = FALSE; 372645f5050Syouri continue; 373645f5050Syouri } 374645f5050Syouri if (*p == '\\') range_start = range_end = *++p; 375645f5050Syouri else range_start = range_end = *p; 376645f5050Syouri if (!range_start) return ABORT; 377645f5050Syouri if (*++p == '-') { 378645f5050Syouri range_end = *++p; 379645f5050Syouri if (range_end == '\0' || range_end == ']') return ABORT; 380645f5050Syouri if (range_end == '\\') range_end = *++p; 381645f5050Syouri p++; 382645f5050Syouri } 383645f5050Syouri if ( range_start < range_end ) { 384645f5050Syouri if (*t >= range_start && *t <= range_end) { 385645f5050Syouri member_match = TRUE; 386645f5050Syouri loop = FALSE; 387645f5050Syouri } 388645f5050Syouri } 389645f5050Syouri else { 390645f5050Syouri if (*t >= range_end && *t <= range_start) { 391645f5050Syouri member_match = TRUE; 392645f5050Syouri loop = FALSE; 393645f5050Syouri } 394645f5050Syouri } 395645f5050Syouri } 396645f5050Syouri if ((invert && member_match) || !(invert || member_match)) return (FALSE); 397645f5050Syouri if (member_match) { 398645f5050Syouri while (*p != ']') { 399645f5050Syouri if (!*p) return (ABORT); 400645f5050Syouri if (*p == '\\') p++; 401645f5050Syouri p++; 402645f5050Syouri } 403645f5050Syouri } 404645f5050Syouri break; 405645f5050Syouri } 406645f5050Syouri case '\\': 407645f5050Syouri p++; 408645f5050Syouri 409645f5050Syouri default: 410645f5050Syouri if (*p != *t) return (FALSE); 411645f5050Syouri } 412645f5050Syouri } 413645f5050Syouri return (!*t); 414645f5050Syouri} 415645f5050Syouri 416645f5050Syouriint regex_match_after_star (char *p, char *t) 417645f5050Syouri{ 418645f5050Syouri register int mat; 419645f5050Syouri register int nextp; 420645f5050Syouri 421645f5050Syouri while ((*p == '?') || (*p == '*')) { 422645f5050Syouri if (*p == '?') { 423645f5050Syouri if ( !*t++ ) return ABORT; 424645f5050Syouri } 425645f5050Syouri p++; 426645f5050Syouri } 427645f5050Syouri if ( !*p ) return TRUE; 428645f5050Syouri 429645f5050Syouri nextp = *p; 430645f5050Syouri if (nextp == '\\') nextp = p[1]; 431645f5050Syouri 432645f5050Syouri mat = FALSE; 433645f5050Syouri while (mat == FALSE) { 434645f5050Syouri if ( nextp == *t || nextp == '[' ) mat = regex_match(p, t); 435645f5050Syouri if ( !*t++ ) mat = ABORT; 436645f5050Syouri } 437645f5050Syouri return (mat); 438645f5050Syouri} 439645f5050Syouri 440645f5050Syouriint match (char *p, char *t) 441645f5050Syouri{ 442645f5050Syouri if ((p == NULL) || (t == NULL)) return (FALSE); 443645f5050Syouri return ((regex_match (p,t) == TRUE) ? TRUE : FALSE); 444645f5050Syouri} 445645f5050Syouri 446645f5050Syouri#endif 447645f5050Syouri 448645f5050Syouri 449645f5050Syouri 450645f5050Syouri 451