/*****************************************************************************/ /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ /** Salt Lake City, Utah **/ /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ /** Cambridge, Massachusetts **/ /** **/ /** All Rights Reserved **/ /** **/ /** Permission to use, copy, modify, and distribute this software and **/ /** its documentation for any purpose and without fee is hereby **/ /** granted, provided that the above copyright notice appear in all **/ /** copies and that both that copyright notice and this permis- **/ /** sion notice appear in supporting documentation, and that the **/ /** names of Evans & Sutherland and M.I.T. not be used in advertising **/ /** in publicity pertaining to distribution of the software without **/ /** specific, written prior permission. **/ /** **/ /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ /** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ /** OR PERFORMANCE OF THIS SOFTWARE. **/ /*****************************************************************************/ /* * [ ctwm ] * * Copyright 1992 Claude Lecommandeur. * * Permission to use, copy, modify and distribute this software [ctwm] and * its documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting documen- * tation, and that the name of Claude Lecommandeur not be used in adverti- * sing or publicity pertaining to distribution of the software without * specific, written prior permission. Claude Lecommandeur make no represen- * tations about the suitability of this software for any purpose. It is * provided "as is" without express or implied warranty. * * Claude Lecommandeur DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL Claude Lecommandeur BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Claude Lecommandeur [ lecom@sic.epfl.ch ][ April 1992 ] */ /********************************************************************** * * $XConsortium: list.c,v 1.20 91/01/09 17:13:30 rws Exp $ * * TWM code to deal with the name lists for the NoTitle list and * the AutoRaise list * * 11-Apr-88 Tom LaStrange Initial Version. * * Do the necessary modification to be integrated in ctwm. * Can no longer be used for the standard twm. * * 22-April-92 Claude Lecommandeur. * * **********************************************************************/ #include #ifdef VMS #include #endif #include "twm.h" #include "screen.h" #include "gram.tab.h" #include "list.h" #include "util.h" #ifdef USE_GNU_REGEX # include #endif /* USE_GNU_REGEX */ extern void twmrc_error_prefix(void); /*********************************************************************** * * Procedure: * AddToList - add a window name to the appropriate list * * Inputs: * list - the address of the pointer to the head of a list * name - a pointer to the name of the window * ptr - pointer to list dependent data * * Special Considerations * If the list does not use the ptr value, a non-null value * should be placed in it. LookInList returns this ptr value * and procedures calling LookInList will check for a non-null * return value as an indication of success. * *********************************************************************** */ #if 0 /* appears not to be used anywhere */ static int is_pattern (char *p); #endif void AddToList(name_list **list_head, char *name, char *ptr) { name_list *nptr; if (!list_head) return; /* ignore empty inserts */ nptr = (name_list *)malloc(sizeof(name_list)); if (nptr == NULL) { twmrc_error_prefix(); fprintf (stderr, "unable to allocate %lu bytes for name_list\n", (unsigned long) sizeof(name_list)); Done(0); } nptr->next = *list_head; #ifdef VMS { char *ftemp; ftemp = (char *) malloc((strlen(name)+1)*sizeof(char)); nptr->name = strcpy (ftemp,name); } #else nptr->name = (char*) strdup (name); #endif nptr->ptr = (ptr == NULL) ? (char *)TRUE : ptr; *list_head = nptr; } /*********************************************************************** * * Procedure: * LookInList - look through a list for a window name, or class * * Returned Value: * the ptr field of the list structure or NULL if the name * or class was not found in the list * * Inputs: * list - a pointer to the head of a list * name - a pointer to the name to look for * class - a pointer to the class to look for * *********************************************************************** */ void *LookInList(name_list *list_head, char *name, XClassHint *class) { name_list *nptr; /* look for the name first */ for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, name)) return (nptr->ptr); if (class) { /* look for the res_name next */ for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_name)) return (nptr->ptr); /* finally look for the res_class */ for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_class)) return (nptr->ptr); } return (NULL); } void *LookInNameList(name_list *list_head, char *name) { return (LookInList(list_head, name, NULL)); } void *LookPatternInList(name_list *list_head, char *name, XClassHint *class) { name_list *nptr; for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, name)) return (nptr->name); if (class) { for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_name)) return (nptr->name); for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_class)) return (nptr->name); } return (NULL); } void *LookPatternInNameList (name_list *list_head, char *name) { return (LookPatternInList(list_head, name, NULL)); } /*********************************************************************** * * Procedure: * GetColorFromList - look through a list for a window name, or class * * Returned Value: * TRUE if the name was found * FALSE if the name was not found * * Inputs: * list - a pointer to the head of a list * name - a pointer to the name to look for * class - a pointer to the class to look for * * Outputs: * ptr - fill in the list value if the name was found * *********************************************************************** */ int GetColorFromList(name_list *list_head, char *name, XClassHint *class, Pixel *ptr) { int save; name_list *nptr; for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, name)) { save = Scr->FirstTime; Scr->FirstTime = TRUE; GetColor(Scr->Monochrome, ptr, nptr->ptr); Scr->FirstTime = save; return (TRUE); } if (class) { for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_name)) { save = Scr->FirstTime; Scr->FirstTime = TRUE; GetColor(Scr->Monochrome, ptr, nptr->ptr); Scr->FirstTime = save; return (TRUE); } for (nptr = list_head; nptr != NULL; nptr = nptr->next) if (match (nptr->name, class->res_class)) { save = Scr->FirstTime; Scr->FirstTime = TRUE; GetColor(Scr->Monochrome, ptr, nptr->ptr); Scr->FirstTime = save; return (TRUE); } } return (FALSE); } /*********************************************************************** * * Procedure: * FreeList - free up a list * *********************************************************************** */ void FreeList(name_list **list) { name_list *nptr; name_list *tmp; for (nptr = *list; nptr != NULL; ) { tmp = nptr->next; free((char *) nptr); nptr = tmp; } *list = NULL; } #ifdef USE_GNU_REGEX #define MAXPATLEN 256 int match (pattern, string) char *pattern, *string; { regex_t preg; int error; if ((pattern == NULL) || (string == NULL)) return 0; error = regcomp (&preg, pattern, REG_EXTENDED | REG_NOSUB); if (error != 0) { char buf [256]; (void) regerror (error, &preg, buf, sizeof buf); fprintf (stderr, "%s : %s\n", buf, pattern); return 0; } error = regexec (&preg, string, 5, 0, 0); regfree (&preg); if (error == 0) return 1; return 0; } #else int regex_match (char *p, char *t); int regex_match_after_star (char *p, char *t); #if 0 /* appears not to be used anywhere */ static int is_pattern (char *p) { while ( *p ) { switch ( *p++ ) { case '?': case '*': case '[': return TRUE; case '\\': if ( !*p++ ) return FALSE; } } return FALSE; } #endif #define ABORT 2 int regex_match (char *p, char *t) { register char range_start, range_end; int invert; int member_match; int loop; for ( ; *p; p++, t++ ) { if (!*t) return ( *p == '*' && *++p == '\0' ) ? TRUE : ABORT; switch ( *p ) { case '?': break; case '*': return regex_match_after_star (p, t); case '[': { p++; invert = FALSE; if ( *p == '!' || *p == '^') { invert = TRUE; p++; } if ( *p == ']' ) return ABORT; member_match = FALSE; loop = TRUE; while ( loop ) { if (*p == ']') { loop = FALSE; continue; } if (*p == '\\') range_start = range_end = *++p; else range_start = range_end = *p; if (!range_start) return ABORT; if (*++p == '-') { range_end = *++p; if (range_end == '\0' || range_end == ']') return ABORT; if (range_end == '\\') range_end = *++p; p++; } if ( range_start < range_end ) { if (*t >= range_start && *t <= range_end) { member_match = TRUE; loop = FALSE; } } else { if (*t >= range_end && *t <= range_start) { member_match = TRUE; loop = FALSE; } } } if ((invert && member_match) || !(invert || member_match)) return (FALSE); if (member_match) { while (*p != ']') { if (!*p) return (ABORT); if (*p == '\\') p++; p++; } } break; } case '\\': p++; default: if (*p != *t) return (FALSE); } } return (!*t); } int regex_match_after_star (char *p, char *t) { register int mat; register int nextp; while ((*p == '?') || (*p == '*')) { if (*p == '?') { if ( !*t++ ) return ABORT; } p++; } if ( !*p ) return TRUE; nextp = *p; if (nextp == '\\') nextp = p[1]; mat = FALSE; while (mat == FALSE) { if ( nextp == *t || nextp == '[' ) mat = regex_match(p, t); if ( !*t++ ) mat = ABORT; } return (mat); } int match (char *p, char *t) { if ((p == NULL) || (t == NULL)) return (FALSE); return ((regex_match (p,t) == TRUE) ? TRUE : FALSE); } #endif