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 32df1c27a6Snia#include "ctwm_shutdown.h" 33645f5050Syouri#include "screen.h" 34645f5050Syouri#include "list.h" 35645f5050Syouri#include "util.h" 360bbfda8aSnia#include "parse.h" 37645f5050Syouri 380bbfda8aSnia#ifdef USE_SYS_REGEX 39645f5050Syouri# include <regex.h> 400bbfda8aSnia#endif /* USE_SYS_REGEX */ 41645f5050Syouri 42645f5050Syouri 43645f5050Syouri 44645f5050Syouri/*********************************************************************** 45645f5050Syouri * 46645f5050Syouri * Procedure: 470bbfda8aSnia * AddToList - add a window name to the appropriate list 48645f5050Syouri * 49645f5050Syouri * Inputs: 500bbfda8aSnia * list - the address of the pointer to the head of a list 510bbfda8aSnia * name - a pointer to the name of the window 520bbfda8aSnia * ptr - pointer to list dependent data 53645f5050Syouri * 54645f5050Syouri * Special Considerations 550bbfda8aSnia * If the list does not use the ptr value, a non-null value 560bbfda8aSnia * should be placed in it. LookInList returns this ptr value 570bbfda8aSnia * and procedures calling LookInList will check for a non-null 580bbfda8aSnia * return value as an indication of success. 59645f5050Syouri * 60645f5050Syouri *********************************************************************** 61645f5050Syouri */ 62645f5050Syouri 630bbfda8aSniavoid AddToList(name_list **list_head, const char *name, void *ptr) 64645f5050Syouri{ 650bbfda8aSnia name_list *nptr; 660bbfda8aSnia 670bbfda8aSnia if(!list_head) { 680bbfda8aSnia return; /* ignore empty inserts */ 690bbfda8aSnia } 700bbfda8aSnia 710bbfda8aSnia nptr = malloc(sizeof(name_list)); 720bbfda8aSnia if(nptr == NULL) { 730bbfda8aSnia fprintf(stderr, "unable to allocate %lu bytes for name_list\n", 740bbfda8aSnia (unsigned long) sizeof(name_list)); 75df1c27a6Snia DoShutdown(); 760bbfda8aSnia } 770bbfda8aSnia 780bbfda8aSnia nptr->next = *list_head; 790bbfda8aSnia nptr->name = strdup(name); 800bbfda8aSnia nptr->ptr = (ptr == NULL) ? (char *)1 : ptr; 810bbfda8aSnia *list_head = nptr; 820bbfda8aSnia} 83645f5050Syouri 84645f5050Syouri/*********************************************************************** 85645f5050Syouri * 86645f5050Syouri * Procedure: 870bbfda8aSnia * LookInList - look through a list for a window name, or class 88645f5050Syouri * 89645f5050Syouri * Returned Value: 900bbfda8aSnia * the ptr field of the list structure or NULL if the name 910bbfda8aSnia * or class was not found in the list 92645f5050Syouri * 93645f5050Syouri * Inputs: 940bbfda8aSnia * list - a pointer to the head of a list 950bbfda8aSnia * name - a pointer to the name to look for 960bbfda8aSnia * class - a pointer to the class to look for 97645f5050Syouri * 98645f5050Syouri *********************************************************************** 99645f5050Syouri */ 100645f5050Syouri 1010bbfda8aSniavoid *LookInList(name_list *list_head, const char *name, XClassHint *class) 1020bbfda8aSnia{ 1030bbfda8aSnia name_list *nptr; 1040bbfda8aSnia 1050bbfda8aSnia /* look for the name first */ 1060bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1070bbfda8aSnia if(match(nptr->name, name)) { 1080bbfda8aSnia return (nptr->ptr); 1090bbfda8aSnia } 1100bbfda8aSnia } 1110bbfda8aSnia 1120bbfda8aSnia if(class) { 1130bbfda8aSnia /* look for the res_name next */ 1140bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1150bbfda8aSnia if(match(nptr->name, class->res_name)) { 1160bbfda8aSnia return (nptr->ptr); 1170bbfda8aSnia } 1180bbfda8aSnia } 1190bbfda8aSnia 1200bbfda8aSnia /* finally look for the res_class */ 1210bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) { 1220bbfda8aSnia if(match(nptr->name, class->res_class)) { 1230bbfda8aSnia return (nptr->ptr); 1240bbfda8aSnia } 1250bbfda8aSnia } 1260bbfda8aSnia } 1270bbfda8aSnia return (NULL); 1280bbfda8aSnia} 1290bbfda8aSnia 1300bbfda8aSniavoid *LookInNameList(name_list *list_head, const char *name) 131645f5050Syouri{ 1320bbfda8aSnia return (LookInList(list_head, name, NULL)); 133645f5050Syouri} 134645f5050Syouri 1350bbfda8aSniavoid *LookInListWin(name_list *list_head, TwmWindow *twin) 136645f5050Syouri{ 1370bbfda8aSnia return LookInList(list_head, twin->name, &(twin->class)); 138645f5050Syouri} 139645f5050Syouri 1400bbfda8aSniabool IsInList(name_list *list_head, TwmWindow *twin) 141645f5050Syouri{ 1420bbfda8aSnia return (bool)LookInList(list_head, twin->name, &(twin->class)); 143645f5050Syouri} 144645f5050Syouri 1450bbfda8aSniavoid *LookPatternInList(name_list *list_head, const char *name, 1460bbfda8aSnia XClassHint *class) 147645f5050Syouri{ 1480bbfda8aSnia name_list *nptr; 1490bbfda8aSnia 1500bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1510bbfda8aSnia if(match(nptr->name, name)) { 1520bbfda8aSnia return (nptr->name); 1530bbfda8aSnia } 1540bbfda8aSnia 1550bbfda8aSnia if(class) { 1560bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1570bbfda8aSnia if(match(nptr->name, class->res_name)) { 1580bbfda8aSnia return (nptr->name); 1590bbfda8aSnia } 1600bbfda8aSnia 1610bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 1620bbfda8aSnia if(match(nptr->name, class->res_class)) { 1630bbfda8aSnia return (nptr->name); 1640bbfda8aSnia } 1650bbfda8aSnia } 1660bbfda8aSnia return (NULL); 1670bbfda8aSnia} 1680bbfda8aSnia 1690bbfda8aSniavoid *LookPatternInNameList(name_list *list_head, const char *name) 1700bbfda8aSnia{ 1710bbfda8aSnia return (LookPatternInList(list_head, name, NULL)); 172645f5050Syouri} 173645f5050Syouri 174645f5050Syouri/*********************************************************************** 175645f5050Syouri * 176645f5050Syouri * Procedure: 1770bbfda8aSnia * GetColorFromList - look through a list for a window name, or class 178645f5050Syouri * 179645f5050Syouri * Returned Value: 1800bbfda8aSnia * true if the name was found 1810bbfda8aSnia * false if the name was not found 182645f5050Syouri * 183645f5050Syouri * Inputs: 1840bbfda8aSnia * list - a pointer to the head of a list 1850bbfda8aSnia * name - a pointer to the name to look for 1860bbfda8aSnia * class - a pointer to the class to look for 187645f5050Syouri * 188645f5050Syouri * Outputs: 1890bbfda8aSnia * ptr - fill in the list value if the name was found 190645f5050Syouri * 191645f5050Syouri *********************************************************************** 192645f5050Syouri */ 193645f5050Syouri 1940bbfda8aSniabool GetColorFromList(name_list *list_head, char *name, 1950bbfda8aSnia XClassHint *class, Pixel *ptr) 196645f5050Syouri{ 1970bbfda8aSnia bool save; 1980bbfda8aSnia name_list *nptr; 1990bbfda8aSnia 2000bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2010bbfda8aSnia if(match(nptr->name, name)) { 2020bbfda8aSnia save = Scr->FirstTime; 2030bbfda8aSnia Scr->FirstTime = true; 2040bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2050bbfda8aSnia Scr->FirstTime = save; 2060bbfda8aSnia return true; 2070bbfda8aSnia } 208645f5050Syouri 2090bbfda8aSnia if(class) { 2100bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2110bbfda8aSnia if(match(nptr->name, class->res_name)) { 2120bbfda8aSnia save = Scr->FirstTime; 2130bbfda8aSnia Scr->FirstTime = true; 2140bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2150bbfda8aSnia Scr->FirstTime = save; 2160bbfda8aSnia return true; 2170bbfda8aSnia } 2180bbfda8aSnia 2190bbfda8aSnia for(nptr = list_head; nptr != NULL; nptr = nptr->next) 2200bbfda8aSnia if(match(nptr->name, class->res_class)) { 2210bbfda8aSnia save = Scr->FirstTime; 2220bbfda8aSnia Scr->FirstTime = true; 2230bbfda8aSnia GetColor(Scr->Monochrome, ptr, nptr->ptr); 2240bbfda8aSnia Scr->FirstTime = save; 2250bbfda8aSnia return true; 2260bbfda8aSnia } 2270bbfda8aSnia } 2280bbfda8aSnia return false; 229645f5050Syouri} 230645f5050Syouri 231645f5050Syouri/*********************************************************************** 232645f5050Syouri * 233645f5050Syouri * Procedure: 2340bbfda8aSnia * FreeList - free up a list 235645f5050Syouri * 236645f5050Syouri *********************************************************************** 237645f5050Syouri */ 238645f5050Syouri 239645f5050Syourivoid FreeList(name_list **list) 240645f5050Syouri{ 2410bbfda8aSnia name_list *nptr; 2420bbfda8aSnia name_list *tmp; 2430bbfda8aSnia 2440bbfda8aSnia for(nptr = *list; nptr != NULL;) { 2450bbfda8aSnia tmp = nptr->next; 2460bbfda8aSnia free(nptr->name); 2470bbfda8aSnia free(nptr); 2480bbfda8aSnia nptr = tmp; 2490bbfda8aSnia } 2500bbfda8aSnia *list = NULL; 251645f5050Syouri} 252645f5050Syouri 2530bbfda8aSnia#ifdef USE_SYS_REGEX 254645f5050Syouri 2550bbfda8aSniabool match(const char *pattern, const char *string) 256645f5050Syouri{ 2570bbfda8aSnia regex_t preg; 2580bbfda8aSnia int error; 2590bbfda8aSnia 2600bbfda8aSnia if((pattern == NULL) || (string == NULL)) { 2610bbfda8aSnia return false; 2620bbfda8aSnia } 2630bbfda8aSnia error = regcomp(&preg, pattern, REG_EXTENDED | REG_NOSUB); 2640bbfda8aSnia if(error != 0) { 2650bbfda8aSnia char buf [256]; 2660bbfda8aSnia regerror(error, &preg, buf, sizeof buf); 2670bbfda8aSnia fprintf(stderr, "%s : %s\n", buf, pattern); 2680bbfda8aSnia return false; 2690bbfda8aSnia } 2700bbfda8aSnia error = regexec(&preg, string, 5, 0, 0); 2710bbfda8aSnia regfree(&preg); 2720bbfda8aSnia if(error == 0) { 2730bbfda8aSnia return true; 2740bbfda8aSnia } 2750bbfda8aSnia return false; 276645f5050Syouri} 277645f5050Syouri 278645f5050Syouri#else 279645f5050Syouri 280645f5050Syouri 281645f5050Syouri 2820bbfda8aSniaint regex_match(const char *p, const char *t); 2830bbfda8aSniaint regex_match_after_star(const char *p, const char *t); 284645f5050Syouri 2850bbfda8aSnia#if 0 /* appears not to be used anywhere */ 2860bbfda8aSniastatic int is_pattern(char *p) 287645f5050Syouri{ 2880bbfda8aSnia while(*p) { 2890bbfda8aSnia switch(*p++) { 2900bbfda8aSnia case '?': 2910bbfda8aSnia case '*': 2920bbfda8aSnia case '[': 2930bbfda8aSnia return TRUE; 2940bbfda8aSnia case '\\': 2950bbfda8aSnia if(!*p++) { 2960bbfda8aSnia return FALSE; 2970bbfda8aSnia } 2980bbfda8aSnia } 299645f5050Syouri } 3000bbfda8aSnia return FALSE; 301645f5050Syouri} 302645f5050Syouri#endif 303645f5050Syouri 304645f5050Syouri#define ABORT 2 305645f5050Syouri 3060bbfda8aSniaint regex_match(const char *p, const char *t) 307645f5050Syouri{ 3080bbfda8aSnia char range_start, range_end; 3090bbfda8aSnia int invert; 3100bbfda8aSnia int member_match; 3110bbfda8aSnia int loop; 3120bbfda8aSnia 3130bbfda8aSnia for(; *p; p++, t++) { 3140bbfda8aSnia if(!*t) { 3150bbfda8aSnia return (*p == '*' && *++p == '\0') ? TRUE : ABORT; 316645f5050Syouri } 3170bbfda8aSnia switch(*p) { 3180bbfda8aSnia case '?': 3190bbfda8aSnia break; 3200bbfda8aSnia case '*': 3210bbfda8aSnia return regex_match_after_star(p, t); 3220bbfda8aSnia case '[': { 3230bbfda8aSnia p++; 3240bbfda8aSnia invert = FALSE; 3250bbfda8aSnia if(*p == '!' || *p == '^') { 3260bbfda8aSnia invert = TRUE; 3270bbfda8aSnia p++; 3280bbfda8aSnia } 3290bbfda8aSnia if(*p == ']') { 3300bbfda8aSnia return ABORT; 3310bbfda8aSnia } 3320bbfda8aSnia member_match = FALSE; 3330bbfda8aSnia loop = TRUE; 3340bbfda8aSnia while(loop) { 3350bbfda8aSnia if(*p == ']') { 3360bbfda8aSnia loop = FALSE; 3370bbfda8aSnia continue; 3380bbfda8aSnia } 3390bbfda8aSnia if(*p == '\\') { 3400bbfda8aSnia range_start = range_end = *++p; 3410bbfda8aSnia } 3420bbfda8aSnia else { 3430bbfda8aSnia range_start = range_end = *p; 3440bbfda8aSnia } 3450bbfda8aSnia if(!range_start) { 3460bbfda8aSnia return ABORT; 3470bbfda8aSnia } 3480bbfda8aSnia if(*++p == '-') { 3490bbfda8aSnia range_end = *++p; 3500bbfda8aSnia if(range_end == '\0' || range_end == ']') { 3510bbfda8aSnia return ABORT; 3520bbfda8aSnia } 3530bbfda8aSnia if(range_end == '\\') { 3540bbfda8aSnia range_end = *++p; 3550bbfda8aSnia } 3560bbfda8aSnia p++; 3570bbfda8aSnia } 3580bbfda8aSnia if(range_start < range_end) { 3590bbfda8aSnia if(*t >= range_start && *t <= range_end) { 3600bbfda8aSnia member_match = TRUE; 3610bbfda8aSnia loop = FALSE; 3620bbfda8aSnia } 3630bbfda8aSnia } 3640bbfda8aSnia else { 3650bbfda8aSnia if(*t >= range_end && *t <= range_start) { 3660bbfda8aSnia member_match = TRUE; 3670bbfda8aSnia loop = FALSE; 3680bbfda8aSnia } 3690bbfda8aSnia } 3700bbfda8aSnia } 3710bbfda8aSnia if((invert && member_match) || !(invert || member_match)) { 3720bbfda8aSnia return (FALSE); 3730bbfda8aSnia } 3740bbfda8aSnia if(member_match) { 3750bbfda8aSnia while(*p != ']') { 3760bbfda8aSnia if(!*p) { 3770bbfda8aSnia return (ABORT); 3780bbfda8aSnia } 3790bbfda8aSnia if(*p == '\\') { 3800bbfda8aSnia p++; 3810bbfda8aSnia } 3820bbfda8aSnia p++; 3830bbfda8aSnia } 3840bbfda8aSnia } 3850bbfda8aSnia break; 386645f5050Syouri } 3870bbfda8aSnia case '\\': 3880bbfda8aSnia p++; 389645f5050Syouri 3900bbfda8aSnia default: 3910bbfda8aSnia if(*p != *t) { 3920bbfda8aSnia return (FALSE); 3930bbfda8aSnia } 3940bbfda8aSnia } 395645f5050Syouri } 3960bbfda8aSnia return (!*t); 397645f5050Syouri} 398645f5050Syouri 3990bbfda8aSniaint regex_match_after_star(const char *p, const char *t) 400645f5050Syouri{ 4010bbfda8aSnia int mat; 4020bbfda8aSnia int nextp; 403645f5050Syouri 4040bbfda8aSnia while((*p == '?') || (*p == '*')) { 4050bbfda8aSnia if(*p == '?') { 4060bbfda8aSnia if(!*t++) { 4070bbfda8aSnia return ABORT; 4080bbfda8aSnia } 4090bbfda8aSnia } 4100bbfda8aSnia p++; 411645f5050Syouri } 4120bbfda8aSnia if(!*p) { 4130bbfda8aSnia return TRUE; 4140bbfda8aSnia } 4150bbfda8aSnia 4160bbfda8aSnia nextp = *p; 4170bbfda8aSnia if(nextp == '\\') { 4180bbfda8aSnia nextp = p[1]; 4190bbfda8aSnia } 4200bbfda8aSnia 4210bbfda8aSnia mat = FALSE; 4220bbfda8aSnia while(mat == FALSE) { 4230bbfda8aSnia if(nextp == *t || nextp == '[') { 4240bbfda8aSnia mat = regex_match(p, t); 4250bbfda8aSnia } 4260bbfda8aSnia if(!*t++) { 4270bbfda8aSnia mat = ABORT; 4280bbfda8aSnia } 4290bbfda8aSnia } 4300bbfda8aSnia return (mat); 431645f5050Syouri} 432645f5050Syouri 4330bbfda8aSniaint match(const char *p, const char *t) 434645f5050Syouri{ 4350bbfda8aSnia if((p == NULL) || (t == NULL)) { 4360bbfda8aSnia return (FALSE); 4370bbfda8aSnia } 4380bbfda8aSnia return ((regex_match(p, t) == TRUE) ? TRUE : FALSE); 439645f5050Syouri} 440645f5050Syouri 441645f5050Syouri#endif 442645f5050Syouri 443645f5050Syouri 444645f5050Syouri 445645f5050Syouri 446