list.c revision 0bbfda8a
10bbfda8aSnia/* 20bbfda8aSnia * Copyright 1988 by Evans & Sutherland Computer Corporation, 30bbfda8aSnia * Salt Lake City, Utah 40bbfda8aSnia * Portions Copyright 1989 by the Massachusetts Institute of Technology 50bbfda8aSnia * Cambridge, Massachusetts 6645f5050Syouri * 70bbfda8aSnia * Copyright 1992 Claude Lecommandeur. 8645f5050Syouri */ 9645f5050Syouri 10645f5050Syouri/********************************************************************** 11645f5050Syouri * 12645f5050Syouri * $XConsortium: list.c,v 1.20 91/01/09 17:13:30 rws Exp $ 13645f5050Syouri * 14645f5050Syouri * TWM code to deal with the name lists for the NoTitle list and 15645f5050Syouri * the AutoRaise list 16645f5050Syouri * 17645f5050Syouri * 11-Apr-88 Tom LaStrange Initial Version. 18645f5050Syouri * 19645f5050Syouri * Do the necessary modification to be integrated in ctwm. 20645f5050Syouri * Can no longer be used for the standard twm. 21645f5050Syouri * 22645f5050Syouri * 22-April-92 Claude Lecommandeur. 23645f5050Syouri * 24645f5050Syouri * 25645f5050Syouri **********************************************************************/ 26645f5050Syouri 270bbfda8aSnia#include "ctwm.h" 280bbfda8aSnia 29645f5050Syouri#include <stdio.h> 300bbfda8aSnia#include <stdlib.h> 310bbfda8aSnia 32645f5050Syouri#include "screen.h" 33645f5050Syouri#include "list.h" 34645f5050Syouri#include "util.h" 350bbfda8aSnia#include "parse.h" 36645f5050Syouri 370bbfda8aSnia#ifdef USE_SYS_REGEX 38645f5050Syouri# include <regex.h> 390bbfda8aSnia#endif /* USE_SYS_REGEX */ 40645f5050Syouri 41645f5050Syouri 42645f5050Syouri 43645f5050Syouri/*********************************************************************** 44645f5050Syouri * 45645f5050Syouri * Procedure: 460bbfda8aSnia * AddToList - add a window name to the appropriate list 47645f5050Syouri * 48645f5050Syouri * Inputs: 490bbfda8aSnia * list - the address of the pointer to the head of a list 500bbfda8aSnia * name - a pointer to the name of the window 510bbfda8aSnia * ptr - pointer to list dependent data 52645f5050Syouri * 53645f5050Syouri * Special Considerations 540bbfda8aSnia * If the list does not use the ptr value, a non-null value 550bbfda8aSnia * should be placed in it. LookInList returns this ptr value 560bbfda8aSnia * and procedures calling LookInList will check for a non-null 570bbfda8aSnia * return value as an indication of success. 58645f5050Syouri * 59645f5050Syouri *********************************************************************** 60645f5050Syouri */ 61645f5050Syouri 620bbfda8aSniavoid AddToList(name_list **list_head, const char *name, void *ptr) 63645f5050Syouri{ 640bbfda8aSnia name_list *nptr; 650bbfda8aSnia 660bbfda8aSnia if(!list_head) { 670bbfda8aSnia return; /* ignore empty inserts */ 680bbfda8aSnia } 690bbfda8aSnia 700bbfda8aSnia nptr = malloc(sizeof(name_list)); 710bbfda8aSnia if(nptr == NULL) { 720bbfda8aSnia fprintf(stderr, "unable to allocate %lu bytes for name_list\n", 730bbfda8aSnia (unsigned long) sizeof(name_list)); 740bbfda8aSnia Done(0); 750bbfda8aSnia } 760bbfda8aSnia 770bbfda8aSnia nptr->next = *list_head; 780bbfda8aSnia nptr->name = strdup(name); 790bbfda8aSnia nptr->ptr = (ptr == NULL) ? (char *)1 : ptr; 800bbfda8aSnia *list_head = nptr; 810bbfda8aSnia} 82645f5050Syouri 83645f5050Syouri/*********************************************************************** 84645f5050Syouri * 85645f5050Syouri * Procedure: 860bbfda8aSnia * LookInList - look through a list for a window name, or class 87645f5050Syouri * 88645f5050Syouri * Returned Value: 890bbfda8aSnia * the ptr field of the list structure or NULL if the name 900bbfda8aSnia * or class was not found in the list 91645f5050Syouri * 92645f5050Syouri * Inputs: 930bbfda8aSnia * list - a pointer to the head of a list 940bbfda8aSnia * name - a pointer to the name to look for 950bbfda8aSnia * class - a pointer to the class to look for 96645f5050Syouri * 97645f5050Syouri *********************************************************************** 98645f5050Syouri */ 99645f5050Syouri 1000bbfda8aSniavoid *LookInList(name_list *list_head, const char *name, XClassHint *class) 1010bbfda8aSnia{ 1020bbfda8aSnia name_list *nptr; 1030bbfda8aSnia 1040bbfda8aSnia /* look for the name first */ 1050bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1060bbfda8aSnia if(match(nptr->name, name)) { 1070bbfda8aSnia return (nptr->ptr); 1080bbfda8aSnia } 1090bbfda8aSnia } 1100bbfda8aSnia 1110bbfda8aSnia if(class) { 1120bbfda8aSnia /* look for the res_name next */ 1130bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1140bbfda8aSnia if(match(nptr->name, class->res_name)) { 1150bbfda8aSnia return (nptr->ptr); 1160bbfda8aSnia } 1170bbfda8aSnia } 1180bbfda8aSnia 1190bbfda8aSnia /* finally look for the res_class */ 1200bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1210bbfda8aSnia if(match(nptr->name, class->res_class)) { 1220bbfda8aSnia return (nptr->ptr); 1230bbfda8aSnia } 1240bbfda8aSnia } 1250bbfda8aSnia } 1260bbfda8aSnia return (NULL); 1270bbfda8aSnia} 1280bbfda8aSnia 1290bbfda8aSniavoid *LookInNameList(name_list *list_head, const char *name) 130645f5050Syouri{ 1310bbfda8aSnia return (LookInList(list_head, name, NULL)); 132645f5050Syouri} 133645f5050Syouri 1340bbfda8aSniavoid *LookInListWin(name_list *list_head, TwmWindow *twin) 135645f5050Syouri{ 1360bbfda8aSnia return LookInList(list_head, twin->name, &(twin->class)); 137645f5050Syouri} 138645f5050Syouri 1390bbfda8aSniabool IsInList(name_list *list_head, TwmWindow *twin) 140645f5050Syouri{ 1410bbfda8aSnia return (bool)LookInList(list_head, twin->name, &(twin->class)); 142645f5050Syouri} 143645f5050Syouri 1440bbfda8aSniavoid *LookPatternInList(name_list *list_head, const char *name, 1450bbfda8aSnia XClassHint *class) 146645f5050Syouri{ 1470bbfda8aSnia name_list *nptr; 1480bbfda8aSnia 1490bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1500bbfda8aSnia if(match(nptr->name, name)) { 1510bbfda8aSnia return (nptr->name); 1520bbfda8aSnia } 1530bbfda8aSnia 1540bbfda8aSnia if(class) { 1550bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1560bbfda8aSnia if(match(nptr->name, class->res_name)) { 1570bbfda8aSnia return (nptr->name); 1580bbfda8aSnia } 1590bbfda8aSnia 1600bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1610bbfda8aSnia if(match(nptr->name, class->res_class)) { 1620bbfda8aSnia return (nptr->name); 1630bbfda8aSnia } 1640bbfda8aSnia } 1650bbfda8aSnia return (NULL); 1660bbfda8aSnia} 1670bbfda8aSnia 1680bbfda8aSniavoid *LookPatternInNameList(name_list *list_head, const char *name) 1690bbfda8aSnia{ 1700bbfda8aSnia return (LookPatternInList(list_head, name, NULL)); 171645f5050Syouri} 172645f5050Syouri 173645f5050Syouri/*********************************************************************** 174645f5050Syouri * 175645f5050Syouri * Procedure: 1760bbfda8aSnia * GetColorFromList - look through a list for a window name, or class 177645f5050Syouri * 178645f5050Syouri * Returned Value: 1790bbfda8aSnia * true if the name was found 1800bbfda8aSnia * false if the name was not found 181645f5050Syouri * 182645f5050Syouri * Inputs: 1830bbfda8aSnia * list - a pointer to the head of a list 1840bbfda8aSnia * name - a pointer to the name to look for 1850bbfda8aSnia * class - a pointer to the class to look for 186645f5050Syouri * 187645f5050Syouri * Outputs: 1880bbfda8aSnia * ptr - fill in the list value if the name was found 189645f5050Syouri * 190645f5050Syouri *********************************************************************** 191645f5050Syouri */ 192645f5050Syouri 1930bbfda8aSniabool GetColorFromList(name_list *list_head, char *name, 1940bbfda8aSnia XClassHint *class, Pixel *ptr) 195645f5050Syouri{ 1960bbfda8aSnia bool save; 1970bbfda8aSnia name_list *nptr; 1980bbfda8aSnia 1990bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2000bbfda8aSnia if(match(nptr->name, name)) { 2010bbfda8aSnia save = Scr->FirstTime; 2020bbfda8aSnia Scr->FirstTime = true; 2030bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2040bbfda8aSnia Scr->FirstTime = save; 2050bbfda8aSnia return true; 2060bbfda8aSnia } 207645f5050Syouri 2080bbfda8aSnia if(class) { 2090bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2100bbfda8aSnia if(match(nptr->name, class->res_name)) { 2110bbfda8aSnia save = Scr->FirstTime; 2120bbfda8aSnia Scr->FirstTime = true; 2130bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2140bbfda8aSnia Scr->FirstTime = save; 2150bbfda8aSnia return true; 2160bbfda8aSnia } 2170bbfda8aSnia 2180bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2190bbfda8aSnia if(match(nptr->name, class->res_class)) { 2200bbfda8aSnia save = Scr->FirstTime; 2210bbfda8aSnia Scr->FirstTime = true; 2220bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2230bbfda8aSnia Scr->FirstTime = save; 2240bbfda8aSnia return true; 2250bbfda8aSnia } 2260bbfda8aSnia } 2270bbfda8aSnia return false; 228645f5050Syouri} 229645f5050Syouri 230645f5050Syouri/*********************************************************************** 231645f5050Syouri * 232645f5050Syouri * Procedure: 2330bbfda8aSnia * FreeList - free up a list 234645f5050Syouri * 235645f5050Syouri *********************************************************************** 236645f5050Syouri */ 237645f5050Syouri 238645f5050Syourivoid FreeList(name_list **list) 239645f5050Syouri{ 2400bbfda8aSnia name_list *nptr; 2410bbfda8aSnia name_list *tmp; 2420bbfda8aSnia 2430bbfda8aSnia for(nptr = *list; nptr != NULL;) { 2440bbfda8aSnia tmp = nptr->next; 2450bbfda8aSnia free(nptr->name); 2460bbfda8aSnia free(nptr); 2470bbfda8aSnia nptr = tmp; 2480bbfda8aSnia } 2490bbfda8aSnia *list = NULL; 250645f5050Syouri} 251645f5050Syouri 2520bbfda8aSnia#ifdef USE_SYS_REGEX 253645f5050Syouri 2540bbfda8aSniabool match(const char *pattern, const char *string) 255645f5050Syouri{ 2560bbfda8aSnia regex_t preg; 2570bbfda8aSnia int error; 2580bbfda8aSnia 2590bbfda8aSnia if((pattern == NULL) || (string == NULL)) { 2600bbfda8aSnia return false; 2610bbfda8aSnia } 2620bbfda8aSnia error = regcomp(&preg, pattern, REG_EXTENDED | REG_NOSUB); 2630bbfda8aSnia if(error != 0) { 2640bbfda8aSnia char buf [256]; 2650bbfda8aSnia regerror(error, &preg, buf, sizeof buf); 2660bbfda8aSnia fprintf(stderr, "%s : %s\n", buf, pattern); 2670bbfda8aSnia return false; 2680bbfda8aSnia } 2690bbfda8aSnia error = regexec(&preg, string, 5, 0, 0); 2700bbfda8aSnia regfree(&preg); 2710bbfda8aSnia if(error == 0) { 2720bbfda8aSnia return true; 2730bbfda8aSnia } 2740bbfda8aSnia return false; 275645f5050Syouri} 276645f5050Syouri 277645f5050Syouri#else 278645f5050Syouri 279645f5050Syouri 280645f5050Syouri 2810bbfda8aSniaint regex_match(const char *p, const char *t); 2820bbfda8aSniaint regex_match_after_star(const char *p, const char *t); 283645f5050Syouri 2840bbfda8aSnia#if 0 /* appears not to be used anywhere */ 2850bbfda8aSniastatic int is_pattern(char *p) 286645f5050Syouri{ 2870bbfda8aSnia while(*p) { 2880bbfda8aSnia switch(*p++) { 2890bbfda8aSnia case '?': 2900bbfda8aSnia case '*': 2910bbfda8aSnia case '[': 2920bbfda8aSnia return TRUE; 2930bbfda8aSnia case '\\': 2940bbfda8aSnia if(!*p++) { 2950bbfda8aSnia return FALSE; 2960bbfda8aSnia } 2970bbfda8aSnia } 298645f5050Syouri } 2990bbfda8aSnia return FALSE; 300645f5050Syouri} 301645f5050Syouri#endif 302645f5050Syouri 303645f5050Syouri#define ABORT 2 304645f5050Syouri 3050bbfda8aSniaint regex_match(const char *p, const char *t) 306645f5050Syouri{ 3070bbfda8aSnia char range_start, range_end; 3080bbfda8aSnia int invert; 3090bbfda8aSnia int member_match; 3100bbfda8aSnia int loop; 3110bbfda8aSnia 3120bbfda8aSnia for(; *p; p++, t++) { 3130bbfda8aSnia if(!*t) { 3140bbfda8aSnia return (*p == '*' && *++p == '\0') ? TRUE : ABORT; 315645f5050Syouri } 3160bbfda8aSnia switch(*p) { 3170bbfda8aSnia case '?': 3180bbfda8aSnia break; 3190bbfda8aSnia case '*': 3200bbfda8aSnia return regex_match_after_star(p, t); 3210bbfda8aSnia case '[': { 3220bbfda8aSnia p++; 3230bbfda8aSnia invert = FALSE; 3240bbfda8aSnia if(*p == '!' || *p == '^') { 3250bbfda8aSnia invert = TRUE; 3260bbfda8aSnia p++; 3270bbfda8aSnia } 3280bbfda8aSnia if(*p == ']') { 3290bbfda8aSnia return ABORT; 3300bbfda8aSnia } 3310bbfda8aSnia member_match = FALSE; 3320bbfda8aSnia loop = TRUE; 3330bbfda8aSnia while(loop) { 3340bbfda8aSnia if(*p == ']') { 3350bbfda8aSnia loop = FALSE; 3360bbfda8aSnia continue; 3370bbfda8aSnia } 3380bbfda8aSnia if(*p == '\\') { 3390bbfda8aSnia range_start = range_end = *++p; 3400bbfda8aSnia } 3410bbfda8aSnia else { 3420bbfda8aSnia range_start = range_end = *p; 3430bbfda8aSnia } 3440bbfda8aSnia if(!range_start) { 3450bbfda8aSnia return ABORT; 3460bbfda8aSnia } 3470bbfda8aSnia if(*++p == '-') { 3480bbfda8aSnia range_end = *++p; 3490bbfda8aSnia if(range_end == '\0' || range_end == ']') { 3500bbfda8aSnia return ABORT; 3510bbfda8aSnia } 3520bbfda8aSnia if(range_end == '\\') { 3530bbfda8aSnia range_end = *++p; 3540bbfda8aSnia } 3550bbfda8aSnia p++; 3560bbfda8aSnia } 3570bbfda8aSnia if(range_start < range_end) { 3580bbfda8aSnia if(*t >= range_start && *t <= range_end) { 3590bbfda8aSnia member_match = TRUE; 3600bbfda8aSnia loop = FALSE; 3610bbfda8aSnia } 3620bbfda8aSnia } 3630bbfda8aSnia else { 3640bbfda8aSnia if(*t >= range_end && *t <= range_start) { 3650bbfda8aSnia member_match = TRUE; 3660bbfda8aSnia loop = FALSE; 3670bbfda8aSnia } 3680bbfda8aSnia } 3690bbfda8aSnia } 3700bbfda8aSnia if((invert && member_match) || !(invert || member_match)) { 3710bbfda8aSnia return (FALSE); 3720bbfda8aSnia } 3730bbfda8aSnia if(member_match) { 3740bbfda8aSnia while(*p != ']') { 3750bbfda8aSnia if(!*p) { 3760bbfda8aSnia return (ABORT); 3770bbfda8aSnia } 3780bbfda8aSnia if(*p == '\\') { 3790bbfda8aSnia p++; 3800bbfda8aSnia } 3810bbfda8aSnia p++; 3820bbfda8aSnia } 3830bbfda8aSnia } 3840bbfda8aSnia break; 385645f5050Syouri } 3860bbfda8aSnia case '\\': 3870bbfda8aSnia p++; 388645f5050Syouri 3890bbfda8aSnia default: 3900bbfda8aSnia if(*p != *t) { 3910bbfda8aSnia return (FALSE); 3920bbfda8aSnia } 3930bbfda8aSnia } 394645f5050Syouri } 3950bbfda8aSnia return (!*t); 396645f5050Syouri} 397645f5050Syouri 3980bbfda8aSniaint regex_match_after_star(const char *p, const char *t) 399645f5050Syouri{ 4000bbfda8aSnia int mat; 4010bbfda8aSnia int nextp; 402645f5050Syouri 4030bbfda8aSnia while((*p == '?') || (*p == '*')) { 4040bbfda8aSnia if(*p == '?') { 4050bbfda8aSnia if(!*t++) { 4060bbfda8aSnia return ABORT; 4070bbfda8aSnia } 4080bbfda8aSnia } 4090bbfda8aSnia p++; 410645f5050Syouri } 4110bbfda8aSnia if(!*p) { 4120bbfda8aSnia return TRUE; 4130bbfda8aSnia } 4140bbfda8aSnia 4150bbfda8aSnia nextp = *p; 4160bbfda8aSnia if(nextp == '\\') { 4170bbfda8aSnia nextp = p[1]; 4180bbfda8aSnia } 4190bbfda8aSnia 4200bbfda8aSnia mat = FALSE; 4210bbfda8aSnia while(mat == FALSE) { 4220bbfda8aSnia if(nextp == *t || nextp == '[') { 4230bbfda8aSnia mat = regex_match(p, t); 4240bbfda8aSnia } 4250bbfda8aSnia if(!*t++) { 4260bbfda8aSnia mat = ABORT; 4270bbfda8aSnia } 4280bbfda8aSnia } 4290bbfda8aSnia return (mat); 430645f5050Syouri} 431645f5050Syouri 4320bbfda8aSniaint match(const char *p, const char *t) 433645f5050Syouri{ 4340bbfda8aSnia if((p == NULL) || (t == NULL)) { 4350bbfda8aSnia return (FALSE); 4360bbfda8aSnia } 4370bbfda8aSnia return ((regex_match(p, t) == TRUE) ? TRUE : FALSE); 438645f5050Syouri} 439645f5050Syouri 440645f5050Syouri#endif 441645f5050Syouri 442645f5050Syouri 443645f5050Syouri 444645f5050Syouri 445