mirror of
https://github.com/Stichting-MINIX-Research-Foundation/xsrc.git
synced 2025-09-22 19:19:29 -04:00
451 lines
12 KiB
C
451 lines
12 KiB
C
/*****************************************************************************/
|
|
/** 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 <stdio.h>
|
|
#ifdef VMS
|
|
#include <string.h>
|
|
#endif
|
|
#include "twm.h"
|
|
#include "screen.h"
|
|
#include "gram.tab.h"
|
|
#include "list.h"
|
|
#include "util.h"
|
|
|
|
#ifdef USE_GNU_REGEX
|
|
# include <regex.h>
|
|
#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
|
|
|
|
|
|
|
|
|