home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: filter.c 1.4 1998/04/12 18:06:58 olsen Exp olsen $
- *
- * :ts=4
- *
- * Wipeout -- Traces and munges memory and detects memory trashing
- *
- * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
- * Public Domain
- */
-
- #ifndef _GLOBAL_H
- #include "global.h"
- #endif /* _GLOBAL_H */
-
- /******************************************************************************/
-
- STATIC struct MinList ForbidList;
- STATIC struct MinList PermitList;
- STATIC BOOL ListsInitialized;
- STATIC BOOL ForbidAll;
- STATIC BOOL PermitAll;
-
- /******************************************************************************/
-
- STATIC VOID
- ClearList(struct MinList * list)
- {
- struct MinNode * node;
- struct MinNode * next;
-
- /* return the contents of a list to the
- * public memory list.
- */
- for(node = list->mlh_Head ;
- (next = node->mln_Succ) != NULL ;
- node = next)
- {
- PrivateFreeVec(node);
- }
-
- /* leave an empty list behind */
- NewList((struct List *)list);
- }
-
- STATIC VOID
- MoveList(struct MinList * source,struct MinList * destination)
- {
- struct MinNode * node;
- struct MinNode * next;
-
- /* move the contents of one list to another */
- for(node = source->mlh_Head ;
- (next = node->mln_Succ) != NULL ;
- node = next)
- {
- AddTail((struct List *)destination,(struct Node *)node);
- }
-
- /* leave an empty source list behind */
- NewList((struct List *)source);
- }
-
- /******************************************************************************/
-
- VOID
- ClearFilterList(VOID)
- {
- /* clear both filter lists, but only if they
- * have been initialized before.
- */
- if(ListsInitialized)
- {
- ClearList(&ForbidList);
- ClearList(&PermitList);
- }
- }
-
- VOID
- InitFilterList(VOID)
- {
- /* initialize the filter lists and assume
- * defaults (track all memory allocations)
- */
- if(NOT ListsInitialized)
- {
- NewList((struct List *)&ForbidList);
- NewList((struct List *)&PermitList);
-
- ListsInitialized = TRUE;
-
- ForbidAll = FALSE;
- PermitAll = TRUE;
- }
- }
-
- /******************************************************************************/
-
- STATIC BOOL
- GetNextName(
- STRPTR * keyPtr,
- STRPTR name,
- LONG nameLen)
- {
- STRPTR start;
- STRPTR stop;
- BOOL result = FALSE;
-
- /* scan the "key" string for the next following name;
- * names are separated by "|" characters
- */
-
- ASSERT(keyPtr != NULL && name != NULL && nameLen > 0);
-
- start = (*keyPtr);
- while((*start) != '\0' && (*start) == '|')
- start++;
-
- stop = start;
-
- while((*stop) != '\0')
- {
- if((*stop) == '\\')
- {
- if(stop[1] != '\0')
- {
- stop += 2;
- }
- else
- {
- break;
- }
- }
- else
- {
- if((*stop) == '|')
- {
- break;
- }
- else
- {
- stop++;
- }
- }
- }
-
- if(start != stop)
- {
- LONG keyLen = (LONG)stop - (LONG)start + 1;
- LONG len;
- LONG i;
-
- len = 0;
-
- for(i = 0 ; i < keyLen ; i++)
- {
- if(start[i] == '|' || len == nameLen)
- break;
-
- if(start[i] == '\\')
- {
- name[len++] = start[++i];
- }
- else
- {
- name[len++] = start[i];
- }
- }
-
- name[len] = '\0';
-
- if((*stop) == '|')
- {
- (*keyPtr) = stop+1;
- }
- else
- {
- (*keyPtr) = stop;
- }
-
- result = TRUE;
- }
-
- /* return TRUE if there is another name to follow,
- * FALSE otherwise (= finished processing the key
- * string)
- */
-
- return(result);
- }
-
- /******************************************************************************/
-
- BOOL
- UpdateFilter(const STRPTR filterString)
- {
- STRPTR string = (STRPTR)filterString;
- struct MinList forbidList;
- struct MinList permitList;
- UBYTE taskName[MAX_FILENAME_LEN];
- STRPTR name;
- BOOL forbidAll;
- BOOL permitAll;
- BOOL success = TRUE;
-
- /* assume defaults */
- NewList((struct List *)&forbidList);
- NewList((struct List *)&permitList);
-
- forbidAll = FALSE;
- permitAll = TRUE;
-
- /* process the filter string */
- while(GetNextName(&string,taskName,sizeof(taskName)))
- {
- /* exclude a name from the list? */
- if(taskName[0] == '!')
- {
- name = &taskName[1];
-
- /* "ALL" means that no allocation should be
- * excluded from being watched
- */
- if(Stricmp(name,"ALL") == SAME)
- {
- forbidAll = TRUE;
-
- ClearList(&forbidList);
- }
- else
- {
- struct Node * node;
-
- /* remember the name of the task whose name
- * should be used in the exclusion list
- */
- node = PrivateAllocVec(sizeof(*node) + strlen(name)+1,MEMF_ANY);
- if(node != NULL)
- {
- node->ln_Name = (char *)(node + 1);
-
- strcpy(node->ln_Name,name);
- AddTail((struct List *)&forbidList,node);
-
- forbidAll = FALSE;
- }
- else
- {
- success = FAILURE;
- break;
- }
- }
- }
- else
- {
- name = taskName;
-
- /* "ALL" means that all allocations should be
- * watched
- */
- if(Stricmp(name,"ALL") == SAME)
- {
- permitAll = TRUE;
-
- ClearList(&permitList);
- }
- else
- {
- struct Node * node;
-
- /* remember the name of the task whose name
- * should be used in the inclusion list
- */
- node = PrivateAllocVec(sizeof(*node) + strlen(name)+1,MEMF_ANY);
- if(node != NULL)
- {
- node->ln_Name = (char *)(node + 1);
-
- strcpy(node->ln_Name,name);
- AddTail((struct List *)&permitList,node);
-
- permitAll = FALSE;
- }
- else
- {
- success = FAILURE;
- break;
- }
- }
- }
- }
-
- /* did we succeed in splitting the filter string
- * into list nodes?
- */
- if(success)
- {
- Forbid();
-
- /* get rid of all the old filter list entries */
- ClearList(&ForbidList);
- ClearList(&PermitList);
-
- /* use the new list entries */
- MoveList(&forbidList,&ForbidList);
- MoveList(&permitList,&PermitList);
-
- /* and the new options */
- ForbidAll = forbidAll;
- PermitAll = permitAll;
-
- Permit();
- }
- else
- {
- ClearList(&forbidList);
- ClearList(&permitList);
- }
-
- return(success);
- }
-
- /******************************************************************************/
-
- BOOL
- CanAllocate(VOID)
- {
- BOOL result = TRUE;
-
- /* check whether the current task should be allowed to
- * make a memory allocation to be watched
- */
- if(GetTaskName(NULL,GlobalNameBuffer,sizeof(GlobalNameBuffer)))
- {
- if(ForbidAll)
- {
- /* should the allocations not be watched? */
- if(CANNOT FindIName((struct List *)&PermitList,GlobalNameBuffer))
- result = FALSE;
- }
- else if (PermitAll)
- {
- /* should the allocations not be watched? */
- if(FindIName((struct List *)&ForbidList,GlobalNameBuffer))
- result = FALSE;
- }
- else
- {
- result = FALSE;
-
- /* should the allocations be watched? */
- if( FindIName((struct List *)&PermitList,GlobalNameBuffer) &&
- CANNOT FindIName((struct List *)&ForbidList,GlobalNameBuffer))
- {
- result = TRUE;
- }
- }
- }
-
- return(result);
- }
-
- /******************************************************************************/
-
- VOID
- CheckFilter(VOID)
- {
- /* print the contents of the two watch lists */
-
- Forbid();
-
- if(NOT IsListEmpty((struct List *)&PermitList))
- {
- struct Node * node;
-
- DPrintf("\nMemory allocations done by the following task(s) are being watched:\n");
-
- for(node = (struct Node *)PermitList.mlh_Head ;
- node->ln_Succ != NULL ;
- node = node->ln_Succ)
- {
- DPrintf("\t\"%s\"\n",node->ln_Name);
- }
- }
-
- if(NOT IsListEmpty((struct List *)&ForbidList))
- {
- struct Node * node;
-
- DPrintf("\nMemory allocations done by the following task(s) are NOT being watched:\n");
-
- for(node = (struct Node *)ForbidList.mlh_Head ;
- node->ln_Succ != NULL ;
- node = node->ln_Succ)
- {
- DPrintf("\t\"%s\"\n",node->ln_Name);
- }
- }
-
- Permit();
- }
-