home *** CD-ROM | disk | FTP | other *** search
- /* See the file Distribution for distribution terms.
- (c) Copyright 1994 Ari Halberstadt */
-
- /* §Patch Library
-
- Patch Library is used to manage patches to traps. Installing and removing
- patches is simpler than using the Toolbox routines NSetTrapAddress and
- NGetTrapAddress. In addition, macros are provided that setup and restore
- the environment for the patch routine. C source code is provided. */
-
- #include <Memory.h>
- #include "PatchLib.h"
-
- /* list of patches */
- static PatchType gPatches;
-
- /* GetTrapType returns the type of the trap (ToolBox or Operating System). */
- static TrapType GetTrapType(short trap)
- {
- return((trap & 0x0800) > 0 ? ToolTrap : OSTrap);
- }
-
- /* PatchInsert inserts the patch into the list of patches, and returns the
- new head of the list. */
- static PatchType PatchInsert(PatchType list, PatchType patch)
- {
- patch->next = list;
- return(patch);
- }
-
- /* PatchDelete removes the patch from the list of patches, and returns the
- new head of the list. */
- static PatchType PatchDelete(PatchType list, PatchType patch)
- {
- PatchType p, prev;
-
- prev = NULL;
- for (p = list; p && p != patch; p = p->next)
- prev = p;
- if (p) {
- if (prev)
- prev->next = p->next;
- else
- list = p->next;
- }
- return(list);
- }
-
- /* ƒPatchInstall installs the patch. */
- void PatchInstall(PatchType patch)
- {
- if (! patch->installed) {
- NSetTrapAddress(patch->addr, patch->number, patch->type);
- patch->installed = true;
- }
- }
-
- /* ƒPatchRemove removes the patch. */
- void PatchRemove(PatchType patch)
- {
- if (patch->installed) {
- NSetTrapAddress(patch->trap, patch->number, patch->type);
- patch->installed = false;
- }
- }
-
- /* ƒPatchRemoveAll removes all patches. */
- void PatchRemoveAll(void)
- {
- PatchType patch;
-
- for (patch = gPatches; patch; patch = patch->next)
- PatchRemove(patch);
- }
-
- /* ƒPatchBegin creates and installs a patch, and returns a pointer to the
- patch structure, or NULL if the patch couldn't be created. */
- PatchType PatchBegin(UniversalProcPtr addr, short number)
- {
- PatchType patch;
-
- patch = (PatchType) NewPtrClear(sizeof(PatchStructure));
- if (patch) {
- patch->number = number;
- patch->type = GetTrapType(patch->number);
- patch->addr = addr;
- patch->trap = NGetTrapAddress(patch->number, patch->type);
- gPatches = PatchInsert(gPatches, patch);
- PatchInstall(patch);
- }
- return(patch);
- }
-
- /* ƒPatchEnd removes and disposes of the patch. */
- void PatchEnd(PatchType patch)
- {
- if (patch) {
- gPatches = PatchDelete(gPatches, patch);
- PatchRemove(patch);
- DisposePtr((Ptr) patch);
- }
- }
-
- /* ƒPatchEndAll removes and disposes of all patches. */
- void PatchEndAll(void)
- {
- while (gPatches)
- PatchEnd(gPatches);
- }
-