2015-10-15 21:39:42 +02:00

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