home *** CD-ROM | disk | FTP | other *** search
- From: mauro@netcom.COM (Mauro DePalma)
- Newsgroups: comp.sources.misc
- Subject: v18i017: cdl - COFF Dynamic Loader, Part01/02
- Message-ID: <1991Apr13.212554.15918@sparky.IMD.Sterling.COM>
- Date: 13 Apr 91 21:25:54 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 7a0b046a ac59c20c d330bc8d ba0d9a03
-
- Submitted-by: Mauro DePalma <mauro@netcom.COM>
- Posting-number: Volume 18, Issue 17
- Archive-name: cdl/part01
-
- This package is a COFF Dynamic Loader for System V.3
- object files. See README file for more details.
-
- Mauro
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is CDL -1.2, a shell archive (shar 3.24)
- # made 02/11/1991 02:45 UTC by mauro@olympus
- # Source directory /u/mauro/src/craft
- #
- # existing files WILL be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 505 -rw-r--r-- Makefile
- # 3783 -r--r--r-- README
- # 13681 -r--r--r-- avl.c
- # 1993 -r--r--r-- avl.h
- # 6945 -r--r--r-- craft.c
- # 4500 -r--r--r-- craft.h
- # 4789 -r--r--r-- llist.c
- # 417 -r--r--r-- llist.h
- # 797 -rw-r--r-- load.c
- # 21155 -r--r--r-- loader.c
- # 4799 -r--r--r-- loader.h
- # 676 -rw-r--r-- simple.c
- #
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= Makefile ==============
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X#
- X# Dynamic Loader project makefile
- X#
- X
- X CC = gcc
- X GCFLAGS = -fstrength-reduce -fpcc-struct-return -g -pipe
- X CFLAGS = -DDEBUG -O $(GCFLAGS)
- X LFLAGS = #-x
- X LIBS = -lld
- X OBJS = load.o loader.o avl.o craft.o llist.o
- X RM = rm -f
- X
- Xload : $(OBJS)
- X $(CC) $(LFLAGS) -o $@ $(OBJS) $(LIBS)
- X
- Xclean :
- X $(RM) load core $(OBJS)
- X
- X# DO NOT DELETE
- X
- Xload.o : load.c craft.h
- Xloader.o : loader.c craft.h loader.h
- Xavl.o : avl.c craft.h avl.h
- Xcraft.o : craft.c craft.h
- Xllist.o : llist.c craft.h llist.h
- SHAR_EOF
- $TOUCH -am 0206004391 Makefile &&
- chmod 0644 Makefile ||
- echo "restore of Makefile failed"
- set `wc -c Makefile`;Wc_c=$1
- if test "$Wc_c" != "505"; then
- echo original size 505, current size $Wc_c
- fi
- # ============= README ==============
- echo "x - extracting README (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README &&
- X +----------------------------------------------------------------------------+
- X | Permission to use, copy, modify, distribute, and sell this software and its|
- X | documentation for any purpose is hereby granted without fee, provided that |
- X | credit is given to the original author. |
- X | |
- X | DePalma SoftCraft DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
- X | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
- X | EVENT SHALL DePalma SoftCraft BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
- X | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,|
- X | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
- X | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
- X | PERFORMANCE OF THIS SOFTWARE. |
- X | |
- X | |
- X | Mauro DePalma (mauro@netcom.COM or apple!netcom!mauro) |
- X | |
- X | DePalma SoftCraft (UNIX System V/386 GNU, X11R4, InterViews) |
- X | 2923 Cohansey Drive |
- X | San Jose, CA 95132 |
- X | |
- X | (408) 259-4789 |
- X +----------------------------------------------------------------------------+
- X
- X
- X COFF Dynamic Loader (CDL) 1.2 consists of the following:
- X
- X file version date comment
- X --------------------------------------------------------
- X avl.c 1.3 1/13/91 by DePalma SoftCraft
- X avl.h 1.3 1/13/91 by DePalma SoftCraft
- X craft.c 1.4 1/18/91 by DePalma SoftCraft
- X craft.h 1.4 1/17/91 by DePalma SoftCraft
- X llist.c 1.2 1/18/91 by DePalma SoftCraft
- X llist.h 1.2 1/17/91 by DePalma SoftCraft
- X loader.c 1.5 1/18/91 by DePalma SoftCraft
- X loader.h 1.5 1/18/91 by DePalma SoftCraft
- X
- X Additionally a 'Makefile', this README file, 'simple.c', and 'load.c'
- X are included.
- X
- X The simplest test case can be accomplished by first creating the driver
- X program 'load' by entering 'make'; simple.c needs to be manually compiled
- X to produce simple.o which can be used to exercise the 'load' CDL driver
- X as follows:
- X
- X $ load simple.o:voyage
- X
- X
- X
- X CDL 1.2 1/18/91
- X
- X
- X The public interface consists of the following routines:
- X
- X int load(char* object) // an object file or an archive of object files
- X void* symbol(char* name) // either an entry point or global data
- X int unload(char* module) // an object file or archive member
- X
- X all are declared in 'craft.h' header file; the library libld.a is needed
- X during the linking phase.
- X
- X When an archive of object files is given to load(3L) every member of
- X the archive is examined thus, symbols used by one member can be referenced
- X by others.
- X
- X At present unload(3L) can only handle an object file or a member of an
- X archive identified by, "<archive>[<member]". For example if we wish to
- X unload member 'debt.o' from archive 'national.a' we'd use:
- X
- X int status = unload("national.a[debt.o]");
- X
- X Note: unload(3L) indiscriminately removes all symbols without regard
- X where they're being referenced.
- SHAR_EOF
- $TOUCH -am 0210174891 README &&
- chmod 0444 README ||
- echo "restore of README failed"
- set `wc -c README`;Wc_c=$1
- if test "$Wc_c" != "3783"; then
- echo original size 3783, current size $Wc_c
- fi
- # ============= avl.c ==============
- echo "x - extracting avl.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > avl.c &&
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) avl.c 1.3 1/13/91 by DePalma SoftCraft";
- X#endif
- X
- X/* Adelson-Velskii and Landis (AVL) balanced binary tree routines.
- X*/
- X#include "craft.h"
- X#include "avl.h"
- X
- X
- X/*
- X NAME
- X AVLdispose -- AVL Tree disposal.
- X
- X SYNOPSIS
- X*/
- X void AVLdispose(seed, destruct)
- X caddr_t seed;
- X agent_t destruct;
- X/*
- X DESCRIPTION
- X*/
- X{
- X AVLnode_t tree = (AVLnode_t) seed;
- X
- X if (tree)
- X {
- X AVLdispose((caddr_t) tree->left, destruct);
- X AVLdispose((caddr_t) tree->right, destruct);
- X
- X if (destruct)
- X (*destruct)(tree->key, tree->item);
- X
- X deallocate((caddr_t) tree);
- X }
- X} /* AVLdispose */
- X
- X
- X
- X/*
- X NAME
- X AVLdump -- AVL Tree dump.
- X
- X SYNOPSIS
- X*/
- X void AVLdump(seed, routine, ark)
- X caddr_t seed;
- X agent_t routine;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Wrapper for the recursive 'AVLtree()'.
- X
- X SEE ALSO
- X AVLtree.
- X*/
- X{
- X AVLtree((AVLnode_t) seed, routine, 0, ark);
- X} /* AVLdump */
- X
- X
- X
- X/*
- X NAME
- X AVLinsert -- AVL Tree insertion.
- X
- X SYNOPSIS
- X*/
- X int AVLinsert(root, key, item, compare)
- X caddr_t * root;
- X caddr_t key;
- X caddr_t item;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X*/
- X{
- X struct _AVLagent client;
- X AVLagent_t agent = &client;
- X boolean_t height;
- X
- X agent->request = INSERT;
- X agent->key = key;
- X agent->item = item;
- X height = False;
- X
- X return AVLtraverse((AVLnode_t *) root, agent, &height, compare);
- X} /* AVLinsert */
- X
- X
- X
- X/*
- X NAME
- X AVLremove -- AVL Tree node removal.
- X
- X SYNOPSIS
- X*/
- X int AVLremove(root, key, compare, destruct)
- X caddr_t * root;
- X caddr_t key;
- X agent_t compare;
- X agent_t destruct;
- X/*
- X DESCRIPTION
- X*/
- X{
- X struct _AVLagent client;
- X AVLagent_t agent = &client;
- X boolean_t height;
- X int result;
- X
- X agent->request = DELETE;
- X agent->key = key;
- X agent->item = (caddr_t) 0;
- X height = False;
- X
- X result = AVLtraverse((AVLnode_t *) root, agent, &height, compare);
- X
- X if (result == SUCCESS && destruct)
- X (*destruct)(agent->key, agent->item);
- X
- X return result;
- X} /* AVLremove */
- X
- X
- X
- X/*
- X NAME
- X AVLreplace -- AVL Tree replacement.
- X
- X SYNOPSIS
- X*/
- X int AVLreplace(seed, key, item, compare)
- X caddr_t seed;
- X caddr_t key;
- X caddr_t item;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X*/
- X{
- X struct _AVLagent client;
- X AVLagent_t agent = &client;
- X
- X agent->request = REPLACE;
- X agent->key = key;
- X agent->item = item;
- X
- X return AVLtravel((AVLnode_t) seed, agent, compare);
- X} /* AVLreplace */
- X
- X
- X
- X/*
- X NAME
- X AVLsearch -- AVL Tree search.
- X
- X SYNOPSIS
- X*/
- X int AVLsearch(seed, key, situs, compare)
- X caddr_t seed;
- X caddr_t key;
- X caddr_t * situs;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X*/
- X{
- X struct _AVLagent client;
- X AVLagent_t agent = &client;
- X int result;
- X
- X agent->request = SEARCH;
- X agent->key = key;
- X agent->item = (caddr_t) 0;
- X
- X result = AVLtravel((AVLnode_t) seed, agent, compare);
- X
- X if (result == SUCCESS && situs)
- X *situs = agent->item;
- X
- X return result;
- X} /* AVLsearch */
- X
- X
- X
- X
- X/*
- X NAME
- X AVLwalk -- walk the tree executing a given routine.
- X
- X SYNOPSIS
- X*/
- X void AVLwalk(seed, routine, ark)
- X caddr_t seed;
- X agent_t routine;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Recursive routine which provides preorder traversal of an AVL tree
- X invoking the 'routine' given with 'ark' upon visit of the root.
- X*/
- X{
- X AVLnode_t node = (AVLnode_t) seed;
- X
- X if (node)
- X {
- X AVLwalk((caddr_t) node->left, routine, ark);
- X (*routine)(node->key, node->item, ark);
- X AVLwalk((caddr_t) node->right, routine, ark);
- X }
- X} /* AVLwalk */
- X
- X
- X
- X/*
- X NAME
- X AVLdelete -- AVL Tree delete.
- X
- X SYNOPSIS
- X*/
- X static void AVLdelete(root, node, change)
- X AVLnode_t * root;
- X AVLnode_t node;
- X boolean_t * change;
- X/*
- X DESCRIPTION
- X*/
- X{
- X if (node)
- X {
- X if (node->right == (AVLnode_t) 0)
- X {
- X *root = node->left;
- X *change = True;
- X deallocate((caddr_t) node);
- X }
- X else if (node->left == (AVLnode_t) 0)
- X {
- X *root = node->right;
- X *change = True;
- X deallocate((caddr_t) node);
- X }
- X else
- X {
- X AVLerase(&(node->left), node, change);
- X
- X if (*change == True)
- X AVLrightBalance(root, change, DELETE);
- X }
- X }
- X} /* AVLdelete */
- X
- X
- X
- X/*
- X NAME
- X AVLerase -- AVL Tree delete (supplemental).
- X
- X SYNOPSIS
- X*/
- X static void AVLerase(root, link, change)
- X AVLnode_t * root;
- X AVLnode_t link;
- X boolean_t * change;
- X/*
- X DESCRIPTION
- X*/
- X{
- X AVLnode_t node = *root;
- X
- X if (node->right)
- X {
- X AVLerase(&(node->right), link, change);
- X
- X if (*change == True)
- X AVLleftBalance(root, change, DELETE);
- X }
- X else
- X {
- X link->key = node->key;
- X link->item = node->item;
- X *root = node->left;
- X *change = True;
- X deallocate((caddr_t) node);
- X }
- X} /* AVLerase */
- X
- X
- X
- X/*
- X NAME
- X AVLleftBalance -- AVL Tree left balance.
- X
- X SYNOPSIS
- X*/
- X static void AVLleftBalance(root, change, reason)
- X AVLnode_t * root;
- X boolean_t * change;
- X AVLrequest_t reason;
- X/*
- X DESCRIPTION
- X*/
- X{
- X AVLnode_t child;
- X AVLnode_t link;
- X AVLnode_t node = *root;
- X AVLadjust_t scale;
- X
- X switch (node->balance)
- X {
- X case LEFT: /* rebalance */
- X child = node->left;
- X scale = child->balance;
- X
- X if (scale == LEFT || (scale == CENTER && reason == DELETE))
- X { /* single LL rotation */
- X node->left = child->right;
- X child->right = node;
- X
- X AVLsideBalance(node, child, change,
- X (reason == DELETE) ? LEFT : CENTER);
- X node = child;
- X }
- X else
- X { /* double LR rotation */
- X link = child->right;
- X child->right = link->left;
- X link->left = child;
- X node->left = link->right;
- X link->right = node;
- X node->balance = (link->balance == LEFT) ? RIGHT : CENTER;
- X child->balance = (link->balance == RIGHT) ? LEFT : CENTER;
- X node = link;
- X
- X if (reason == DELETE)
- X link->balance = CENTER;
- X }
- X
- X if (reason != DELETE)
- X {
- X node->balance = CENTER;
- X *change = False;
- X }
- X
- X *root = node;
- X break;
- X
- X case CENTER:
- X node->balance = LEFT;
- X
- X if (reason == DELETE)
- X *change = False;
- X break;
- X
- X case RIGHT:
- X node->balance = CENTER;
- X
- X if (reason != DELETE)
- X *change = False;
- X break;
- X }
- X} /* AVLleftBalance */
- X
- X
- X
- X/*
- X NAME
- X AVLrightBalance -- AVL Tree right balance.
- X
- X SYNOPSIS
- X*/
- X static void AVLrightBalance(root, change, reason)
- X AVLnode_t * root;
- X boolean_t * change;
- X AVLrequest_t reason;
- X/*
- X DESCRIPTION
- X*/
- X{
- X AVLnode_t child;
- X AVLnode_t link;
- X AVLnode_t node = *root;
- X AVLadjust_t scale;
- X
- X switch (node->balance)
- X {
- X case LEFT:
- X node->balance = CENTER;
- X
- X if (reason != DELETE)
- X *change = False;
- X break;
- X
- X case CENTER:
- X node->balance = RIGHT;
- X
- X if (reason == DELETE)
- X *change = False;
- X break;
- X
- X case RIGHT: /* rebalance */
- X child = node->right;
- X scale = child->balance;
- X
- X if (scale == RIGHT || (scale == CENTER && reason == DELETE))
- X { /* single RR rotation */
- X node->right = child->left;
- X child->left = node;
- X
- X AVLsideBalance(node, child, change,
- X (reason == DELETE) ? RIGHT : CENTER);
- X node = child;
- X }
- X else
- X { /* double RL rotation */
- X link = child->left;
- X child->left = link->right;
- X link->right = child;
- X node->right = link->left;
- X link->left = node;
- X node->balance = (link->balance == RIGHT) ? LEFT : CENTER;
- X child->balance = (link->balance == LEFT) ? RIGHT : CENTER;
- X node = link;
- X
- X if (reason == DELETE)
- X link->balance = CENTER;
- X }
- X
- X if (reason != DELETE)
- X {
- X node->balance = CENTER;
- X *change = False;
- X }
- X
- X *root = node;
- X break;
- X }
- X} /* AVLrightBalance */
- X
- X
- X
- X/*
- X NAME
- X AVLsideBalance -- AVL Tree height balance.
- X
- X SYNOPSIS
- X*/
- X static void AVLsideBalance(node, child, change, side)
- X AVLnode_t node;
- X AVLnode_t child;
- X boolean_t * change;
- X AVLadjust_t side;
- X/*
- X DESCRIPTION
- X*/
- X{
- X switch (side)
- X {
- X case LEFT: /* AVL Tree Deletion */
- X case RIGHT:
- X if (child->balance == CENTER)
- X {
- X node->balance = side;
- X child->balance = (side == RIGHT) ? LEFT : RIGHT;
- X *change = False;
- X }
- X else
- X {
- X node->balance = CENTER;
- X child->balance = CENTER;
- X }
- X break;
- X
- X default: /* AVL Tree Insertion */
- X node->balance = CENTER;
- X }
- X} /* AVLsideBalance */
- X
- X
- X
- X/*
- X NAME
- X AVLtravel -- readonly AVL Tree traversal.
- X
- X SYNOPSIS
- X*/
- X static int AVLtravel(node, agent, compare)
- X AVLnode_t node;
- X AVLagent_t agent;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X Routine used for REPLACE and SEARCH operations.
- X*/
- X{
- X AVLnode_t link;
- X int comparison;
- X int result;
- X
- X if (node) /* search */
- X {
- X if ((comparison = (*compare)(agent->key, node->key)) < 0)
- X {
- X result = AVLtravel(node->left, agent, compare);
- X }
- X else if (comparison > 0)
- X {
- X result = AVLtravel(node->right, agent, compare);
- X }
- X else /* found a match */
- X {
- X if (agent->request == REPLACE)
- X node->item = agent->item;
- X else
- X agent->item = node->item;
- X
- X result = SUCCESS;
- X }
- X }
- X else /* search exhausted */
- X {
- X result = EAVLNOKEY;
- X }
- X
- X return result;
- X} /* AVLtravel */
- X
- X
- X
- X/*
- X NAME
- X AVLtraverse -- read/write AVL Tree traversal.
- X
- X SYNOPSIS
- X*/
- X static int AVLtraverse(root, agent, change, compare)
- X AVLnode_t * root;
- X AVLagent_t agent;
- X boolean_t * change;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X Routine used for DELETE and INSERT operations.
- X*/
- X{
- X AVLnode_t link;
- X AVLnode_t node = *root;
- X int comparison;
- X int result;
- X
- X if (node) /* search */
- X {
- X if ((comparison = (*compare)(agent->key, node->key)) < 0)
- X {
- X result = AVLtraverse(&(node->left), agent, change, compare);
- X
- X if (*change == True)
- X if (agent->request == DELETE)
- X AVLrightBalance(root, change, agent->request);
- X else
- X AVLleftBalance(root, change, agent->request);
- X }
- X else if (comparison > 0)
- X {
- X result = AVLtraverse(&(node->right), agent, change, compare);
- X
- X if (*change == True)
- X if (agent->request == DELETE)
- X AVLleftBalance(root, change, agent->request);
- X else
- X AVLrightBalance(root, change, agent->request);
- X }
- X else /* found a match */
- X {
- X if (agent->request == DELETE)
- X {
- X AVLdelete(root, node, change);
- X
- X agent->key = node->key;
- X agent->item = node->item;
- X
- X result = SUCCESS;
- X }
- X else
- X {
- X result = EAVLDUPKEY;
- X }
- X }
- X }
- X else /* search exhausted */
- X {
- X if (agent->request == DELETE)
- X {
- X result = EAVLNOKEY;
- X }
- X else
- X {
- X if (link = (AVLnode_t) allocate(NIL, sizeof(struct _AVLnode)))
- X {
- X link->balance = CENTER;
- X link->key = agent->key;
- X link->item = agent->item;
- X link->left = (AVLnode_t) 0;
- X link->right = (AVLnode_t) 0;
- X
- X *change = True;
- X *root = link;
- X
- X result = SUCCESS;
- X }
- X else
- X {
- X result = EAVLNOMEM;
- X }
- X }
- X }
- X
- X return result;
- X} /* AVLtraverse */
- X
- X
- X
- X/*
- X NAME
- X AVLtree -- AVL Tree dump.
- X
- X SYNOPSIS
- X*/
- X static void AVLtree(node, routine, nest, ark)
- X AVLnode_t node;
- X agent_t routine;
- X int nest;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X Recursive routine which provides traversal of an AVL tree in
- X natural order invoking the 'routine' given with nesting level
- X and 'ark' (client data) upon visit of the root.
- X*/
- X{
- X if (node)
- X {
- X AVLtree(node->right, routine, ++nest, ark);
- X (*routine)(node->key, node->item, nest, ark);
- X AVLtree(node->left, routine, nest, ark);
- X }
- X} /* AVLtree */
- X
- SHAR_EOF
- $TOUCH -am 0113170391 avl.c &&
- chmod 0444 avl.c ||
- echo "restore of avl.c failed"
- set `wc -c avl.c`;Wc_c=$1
- if test "$Wc_c" != "13681"; then
- echo original size 13681, current size $Wc_c
- fi
- # ============= avl.h ==============
- echo "x - extracting avl.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > avl.h &&
- X
- X/* @(#)avl.h 1.3 1/13/91 by DePalma SoftCraft
- X
- X Adelson-Velskii and Landis (AVL) balanced binary tree header file.
- X*/
- X
- X#ifndef __AVL_H__ /* guard against multiple includes */
- X#define __AVL_H__
- X
- Xtypedef enum /* possible sort of balance required */
- X {
- X LEFT,
- X CENTER,
- X RIGHT
- X } AVLadjust_t;
- X
- Xtypedef enum /* various operation requests */
- X {
- X DELETE,
- X INSERT,
- X REPLACE,
- X SEARCH
- X } AVLrequest_t;
- X
- Xtypedef struct _AVLnode /* structure of a node in the tree */
- X {
- X caddr_t key;
- X caddr_t item;
- X AVLadjust_t balance;
- X struct _AVLnode * left;
- X struct _AVLnode * right;
- X } *AVLnode_t;
- X
- Xtypedef struct _AVLagent /* convenience structure for traversal */
- X {
- X AVLrequest_t request;
- X caddr_t key;
- X caddr_t item;
- X } *AVLagent_t;
- X
- X
- X/* AVL Specific Errors (should be read from a message file)
- X*/
- Xstatic char *avlErrorList[] =
- X {
- X "",
- X "An attempt was made to insert a duplicate key",
- X "Can't allocate enough memory to create a new AVL node",
- X "Search failure, can't locate the specified key",
- X 0
- X };
- X
- X#define EAVLDUPKEY ERROR(avlErrorList, 1)
- X#define EAVLNOMEM ERROR(avlErrorList, 2)
- X#define EAVLNOKEY ERROR(avlErrorList, 3)
- X
- X
- X/* AVL Private
- X*/
- Xstatic void AVLdelete(AVLnode_t *, AVLnode_t, boolean_t *);
- Xstatic void AVLerase(AVLnode_t *, AVLnode_t, boolean_t *);
- Xstatic void AVLleftBalance(AVLnode_t *, boolean_t *, AVLrequest_t);
- Xstatic void AVLrightBalance(AVLnode_t *, boolean_t *, AVLrequest_t);
- Xstatic void AVLsideBalance(AVLnode_t, AVLnode_t, boolean_t *, AVLadjust_t);
- Xstatic int AVLtravel(AVLnode_t, AVLagent_t, agent_t);
- Xstatic int AVLtraverse(AVLnode_t *, AVLagent_t, boolean_t *, agent_t);
- Xstatic void AVLtree(AVLnode_t, agent_t, int, caddr_t);
- X#endif /* not __AVL_H__ */
- SHAR_EOF
- $TOUCH -am 0117230191 avl.h &&
- chmod 0444 avl.h ||
- echo "restore of avl.h failed"
- set `wc -c avl.h`;Wc_c=$1
- if test "$Wc_c" != "1993"; then
- echo original size 1993, current size $Wc_c
- fi
- # ============= craft.c ==============
- echo "x - extracting craft.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > craft.c &&
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) craft.c 1.4 1/18/91 by DePalma SoftCraft";
- X#endif
- X
- X/* Base routines for SoftCraft library.
- X*/
- X
- X#include "craft.h"
- X
- X#define ErrorClass(mask) ((mask & 0xffff0000) >> 16)
- X#define ErrorIndex(mask) (mask & 0xffff)
- X#define ErrorMask(class, code) ((class << 16) | code)
- X
- Xstatic agent_t Displayer = (agent_t) scribe;
- Xstatic assoc_t Diagnosis = (assoc_t) 0;
- X
- X
- X
- X/*
- X NAME
- X allocate -- memory allocation.
- X
- X SYNOPSIS
- X*/
- X caddr_t allocate(memory, bytes)
- X caddr_t memory;
- X size_t bytes;
- X/*
- X DESCRIPTION
- X Changes the size of a previously allocated memory block or
- X allocates and clears a new one when none is specified.
- X*/
- X{
- X caddr_t saga;
- X
- X if (memory)
- X {
- X saga = (caddr_t) realloc((void *) memory, bytes);
- X }
- X else
- X {
- X if (saga = (caddr_t) malloc(bytes))
- X (void) memset((void *) saga, (char) 0, bytes);
- X }
- X
- X return saga;
- X} /* allocate */
- X
- X
- X
- X/*
- X NAME
- X deallocate -- memory deallocation.
- X
- X SYNOPSIS
- X*/
- X void deallocate(memory)
- X caddr_t memory;
- X/*
- X DESCRIPTION
- X*/
- X{
- X if (memory)
- X {
- X (void) free((void *) memory);
- X }
- X} /* deallocate */
- X
- X
- X
- X/*
- X NAME
- X error(3L) -- output error message.
- X
- X SYNOPSIS
- X*/
- X void error(code)
- X int code;
- X/*
- X DESCRIPTION
- X The 'code' argument is a 32 bit quantity which contains a
- X unique error class (ex.: sys_errlist) in the upper 16 bits
- X and an index (starting at 1) into the list of error messages
- X in the lower 16 bits.
- X
- X ERRMSG is a special 'code' which allows for using only
- X optional arguments in the formation of the error message.
- X
- X SEE ALSO
- X errorCode(3L).
- X*/
- X{
- X static char buffer[BLOCK]; /* Watch: may not be large enough */
- X
- X va_list args;
- X va_start(args, code);
- X
- X if (code == FAILURE || code == SUCCESS || !Displayer)
- X return;
- X
- X if (code == ERRMSG)
- X {
- X char* format = va_arg(args, char*);
- X
- X (void) vsprintf(buffer, format, args);
- X }
- X else
- X {
- X caddr_t key;
- X ushort cast = ErrorClass(code);
- X ushort mark = ErrorIndex(code);
- X
- X if (LLvisit(Diagnosis->key, &key, (caddr_t) cast, minus) == SUCCESS)
- X {
- X (void) vsprintf(buffer, ((char**)key)[mark], args);
- X
- X if (Diagnosis->item)
- X (void) strcat(buffer, Diagnosis->item);
- X }
- X else
- X {
- X (void) strcpy(buffer, form("in error (code=%x)", code));
- X (void) strcpy(buffer, DANGER(buffer));
- X }
- X }
- X
- X (*Displayer)(buffer); /* project: allow client to change 'Displayer' */
- X va_end(args);
- X} /* error */
- X
- X
- X/*
- X NAME
- X errorCode(3L) -- generation of error codes.
- X
- X SYNOPSIS
- X*/
- X int errorCode(module, line, list, code)
- X char * module;
- X int line;
- X char ** list;
- X int code;
- X/*
- X DESCRIPTION
- X Beyond yielding the correct error code errorCode(3L)
- X generates unique error classes for different error
- X message 'list's given.
- X*/
- X{
- X static boolean_t debug;
- X static int increment = 100;
- X static int sequence = 0;
- X
- X caddr_t item;
- X int cast;
- X
- X
- X if (Diagnosis == (assoc_t) 0)
- X {
- X Diagnosis = (assoc_t) allocate(NIL, sizeof(struct _assoc));
- X
- X if (debug = (boolean_t) getenv("DEBUG"))
- X Diagnosis->item = allocate(NIL, BLOCK * sizeof(char));
- X }
- X
- X if (LLsearch(Diagnosis->key, (caddr_t) list, &item, minus) != SUCCESS)
- X {
- X item = (caddr_t) sequence + increment;
- X
- X if (LLinsert(&(Diagnosis->key), (caddr_t) list, item) == SUCCESS)
- X {
- X sequence += increment;
- X cast = sequence;
- X }
- X else
- X {
- X (void) puts(DANGER("internal error"));
- X return FAILURE;
- X }
- X }
- X else
- X {
- X cast = (int) item;
- X }
- X
- X if (debug)
- X (void) sprintf((char *) Diagnosis->item, " (%s line %d)", module, line);
- X
- X return ErrorMask(cast, code);
- X} /* errorCode */
- X
- X
- X
- X/*
- X NAME
- X errorNote(3L) -- change error message.
- X
- X SYNOPSIS
- X*/
- X int errorNote(module, line, code)
- X char * module;
- X int line;
- X int code;
- X/*
- X DESCRIPTION
- X When DEBUG environment variable is set the error message generated
- X includes the file name and line number. The purpose of this routine
- X is to update this information with the current file name and line
- X number.
- X
- X SEE ALSO
- X errorCode(3L).
- X*/
- X{
- X if (Diagnosis)
- X if (Diagnosis->item)
- X (void) sprintf((char *) Diagnosis->item, " (%s line %d)", module, line);
- X
- X return code;
- X} /* errorNote */
- X
- X
- X/*
- X NAME
- X form -- simple displayer.
- X
- X SYNOPSIS
- X*/
- X char * form(rule)
- X char * rule;
- X/*
- X DESCRIPTION
- X*/
- X{
- X static char buffer[BLOCK];
- X
- X va_list args;
- X va_start(args, rule);
- X
- X (void) vsprintf(buffer, rule, args);
- X va_end(args);
- X
- X return buffer;
- X} /* form */
- X
- X
- X
- X/*
- X NAME
- X minus -- difference between two numbers.
- X
- X SYNOPSIS
- X*/
- X int minus(left, right)
- X int left;
- X int right;
- X/*
- X DESCRIPTION
- X Comparison routine for two numbers.
- X
- X SEE ALSO
- X AVLinsert(3L), AVLsearch(3L).
- X*/
- X{
- X return (left - right);
- X} /* minus */
- X
- X
- X/*
- X NAME
- X scribe -- simple displayer.
- X
- X SYNOPSIS
- X*/
- X int scribe(message)
- X char* message;
- X/*
- X DESCRIPTION
- X*/
- X{
- X return puts(message);
- X} /* scribe */
- X
- X
- X
- X/*
- X NAME
- X which - locate a program file.
- X
- X SYNOPSIS
- X*/
- X char * which(name)
- X char * name;
- X
- X/*
- X DESCRIPTION
- X Which looks for the file which be executed had the given
- X 'name' been issued as a command.
- X*/
- X{
- X static boolean_t stub;
- X static char* home;
- X static char* path = (char*) 0;
- X static char string[BLOCK];
- X
- X char buffer[BLOCK];
- X char* token;
- X ushort mark;
- X
- X if (name[0] == '.' || name[0] == '/') /* trivial: absolute path */
- X return name;
- X
- X if (path == (char*) 0) /* once: save environment */
- X {
- X home = getenv("HOME");
- X path = getenv("PATH");
- X stub = (boolean_t) (path[strlen(path) - 1] == ':');
- X }
- X
- X if (stub) /* check special case */
- X {
- X (void) sprintf(string, "./%s", name);
- X
- X if (access(string, 0) == 0)
- X return string;
- X }
- X
- X (void) strcpy(buffer, path); /* always make a copy */
- X mark = 0; /* initialize 'path' marker */
- X
- X for (token = strtok(buffer, ":"); token; token = strtok((char*) 0, ":"))
- X {
- X if (path[mark] == ':')
- X {
- X (void) sprintf(string, "./%s", name);
- X
- X if (access(string, 0) == 0)
- X break;
- X }
- X
- X if (token[0] == '~')
- X (void) sprintf(string, "%s%s%s", home, &token[1], name);
- X else
- X (void) sprintf(string, "%s/%s", token, name);
- X
- X if (access(string, 0) == 0)
- X break;
- X
- X mark += strlen(token) + 1;
- X }
- X
- X return ((token) ? string : (char*) 0);
- X} /* which */
- SHAR_EOF
- $TOUCH -am 0118000591 craft.c &&
- chmod 0444 craft.c ||
- echo "restore of craft.c failed"
- set `wc -c craft.c`;Wc_c=$1
- if test "$Wc_c" != "6945"; then
- echo original size 6945, current size $Wc_c
- fi
- # ============= craft.h ==============
- echo "x - extracting craft.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > craft.h &&
- X
- X/* Utility library header file.
- X
- X @(#) craft.h 1.4 1/17/91 by DePalma SoftCraft
- X*/
- X
- X#ifndef __CRAFT__ /* guard against multiple includes */
- X#define __CRAFT__
- X
- X#include <stdarg.h> /* found in 'LIBDIR/gcc-include' */
- X#include <sys/types.h>
- X
- X#ifndef CTRL
- X# define CTRL(c) ('c' & 037)
- X#endif
- X
- X#define DANGER(msg) form("panic: %s (%s line %d)", msg,__FILE__,__LINE__)
- X#define DUBIOUS(code) errorNote(__FILE__, __LINE__, code)
- X
- X#define ERRMSG 0x10000
- X#define ERROR(list, code) errorCode(__FILE__, __LINE__, list, code)
- X
- X#ifndef False
- X# define False 0
- X# define True 1
- X#endif
- X
- X#ifndef FAILURE
- X# define FAILURE 0
- X# define SUCCESS 1
- X#endif
- X
- X#ifndef max
- X# define max(a, b) (((a) > (b)) ? (a) : (b))
- X# define min(a, b) (((a) < (b)) ? (a) : (b))
- X#endif
- X
- X#define NIL (void *) 0
- X
- X#define BACKSPACE '\010'
- X#define ESCAPE '\033'
- X#define RETURN '\015'
- X#define SPACE '\040'
- X
- X#define BLOCK 512
- X#define MEGACYCLE 1000000L
- X#define TERMINATOR '\200'
- X
- X/* SoftCraft Types
- X*/
- Xtypedef int (*agent_t)(); /* entry point for a procedure */
- X
- Xtypedef struct _assoc /* generic association structure */
- X {
- X caddr_t key; /* named (search) key */
- X caddr_t item; /* associated item */
- X } *assoc_t;
- X
- Xtypedef unsigned char boolean_t; /* boolean type (True or False) */
- X
- Xtypedef struct _buffer /* generic buffer structure */
- X {
- X char * base; /* .. base address */
- X long mark; /* .. a marker (ex: number of entries) */
- X } *buffer_t;
- X
- X
- X
- X/* Key Definitions
- X*/
- X#define KEY_DOWN 0402 /* Sent by terminal down arrow key. */
- X#define KEY_UP 0403 /* Sent by terminal up arrow key. */
- X#define KEY_LEFT 0404 /* Sent by terminal left arrow key. */
- X#define KEY_RIGHT 0405 /* Sent by terminal right arrow key. */
- X#define KEY_HOME 0406 /* Sent by home key. */
- X#define KEY_BACKSPACE 0407 /* Sent by backspace key. */
- X#define KEY_F0 0410 /* function key f0. */
- X#define KEY_F(n) (KEY_F0+(n)) /* Reserve space for 64 function keys. */
- X#define KEY_DC 0512 /* Sent by delete character key. */
- X#define KEY_IC 0513 /* Sent by ins char/enter ins mode key. */
- X#define KEY_PGDN 0522 /* Sent by next-page key. */
- X#define KEY_PGUP 0523 /* Sent by previous-page key. */
- X#define KEY_PRINT 0532 /* Print or copy key. */
- X#define KEY_END 0550 /* End key */
- X
- X
- X
- X/* SoftCraft Public Library
- X
- X avl.o
- X*/
- Xvoid AVLdispose(caddr_t, agent_t);
- Xvoid AVLdump(caddr_t, agent_t, caddr_t);
- Xint AVLinsert(caddr_t *, caddr_t, caddr_t, agent_t);
- Xint AVLremove(caddr_t *, caddr_t, agent_t, agent_t);
- Xint AVLreplace(caddr_t, caddr_t, caddr_t, agent_t);
- Xint AVLsearch(caddr_t, caddr_t, caddr_t *, agent_t);
- Xvoid AVLwalk(caddr_t, agent_t, caddr_t);
- X
- X/* craft.o
- X*/
- Xcaddr_t allocate(caddr_t, size_t);
- Xvoid deallocate(caddr_t);
- Xvoid error(int, ...);
- Xint errorCode(char *, int, char **, int);
- Xint errorNote(char *, int, int);
- Xchar * form(char *, ...);
- Xint minus(int, int);
- Xint scribe(char *);
- Xchar * which(char *);
- X
- X/* llist.o
- X*/
- Xvoid LLdispose(caddr_t, agent_t);
- Xint LLinsert(caddr_t *, caddr_t, caddr_t);
- Xint LLremove(caddr_t *, caddr_t, agent_t, agent_t);
- Xint LLsearch(caddr_t, caddr_t, caddr_t *, agent_t);
- Xint LLvisit(caddr_t, caddr_t *, caddr_t, agent_t);
- Xvoid LLwalk(caddr_t, agent_t, caddr_t);
- Xcaddr_t Stack(caddr_t *, caddr_t);
- X
- X/* loader.o
- X*/
- Xint load(char *);
- Xvoid * symbol(char *);
- Xint unload(char *);
- X
- X
- X/* Symbols used from standard libraries.
- X*/
- Xextern char * ctime(time_t *);
- Xextern char * getenv(char *);
- X
- Xextern int strcmp(char *, char *);
- Xextern char * strdup(char *);
- Xextern char * strchr(char *, int);
- Xextern char * strrchr(char *, int);
- Xextern char * strtok(char *, char *);
- X
- Xextern char * optarg;
- Xextern int optind;
- X
- Xextern char * sys_errlist[];
- X#endif /* not __CRAFT__ */
- SHAR_EOF
- $TOUCH -am 0117225991 craft.h &&
- chmod 0444 craft.h ||
- echo "restore of craft.h failed"
- set `wc -c craft.h`;Wc_c=$1
- if test "$Wc_c" != "4500"; then
- echo original size 4500, current size $Wc_c
- fi
- # ============= llist.c ==============
- echo "x - extracting llist.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > llist.c &&
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) llist.c 1.2 1/18/91 by DePalma SoftCraft";
- X#endif
- X
- X/* Linear Lists (LL) routines.
- X
- X ** DANGER **
- X Since these routines are used for error class registration,
- X introducing an error class for the LL module would result
- X in infinite recursion.
- X*/
- X
- X#include "craft.h"
- X#include "llist.h"
- X
- X
- X/*
- X NAME
- X LLdispose -- list disposal.
- X
- X SYNOPSIS
- X*/
- X void LLdispose(seed, destruct)
- X caddr_t seed;
- X agent_t destruct;
- X/*
- X DESCRIPTION
- X*/
- X{
- X llist_t chain = (llist_t) seed;
- X llist_t link;
- X
- X while (chain)
- X {
- X link = chain->next;
- X
- X if (destruct)
- X (*destruct)(chain->key, chain->item);
- X
- X deallocate((caddr_t) chain);
- X
- X chain = link;
- X }
- X} /* LLdispose */
- X
- X
- X
- X/*
- X NAME
- X LLinsert -- link list insert.
- X
- X SYNOPSIS
- X*/
- X int LLinsert(head, key, item)
- X caddr_t * head;
- X caddr_t key;
- X caddr_t item;
- X/*
- X DESCRIPTION
- X*/
- X{
- X llist_t chain = (llist_t) *head;
- X llist_t link;
- X
- X if (link = (llist_t) allocate(NIL, sizeof(struct _llist)))
- X {
- X link->key = key;
- X link->item = item;
- X link->next = (llist_t) 0;
- X
- X if (chain) /* add another 'link' an existing 'chain' */
- X {
- X while (chain->next) chain = chain->next;
- X chain->next = link;
- X }
- X else /* start a new 'chain' (linear list) */
- X {
- X *head = (caddr_t) link;
- X }
- X }
- X
- X return ((link) ? SUCCESS : FAILURE);
- X} /* LLinsert */
- X
- X
- X
- X/*
- X NAME
- X LLremove -- remove an item from a list.
- X
- X SYNOPSIS
- X*/
- X int LLremove(head, key, compare, destruct)
- X caddr_t * head;
- X caddr_t key;
- X agent_t compare;
- X agent_t destruct;
- X/*
- X DESCRIPTION
- X*/
- X{
- X llist_t chain = (llist_t) *head;
- X llist_t link;
- X llist_t node;
- X
- X for (link = chain, node = chain; link; link = link->next)
- X {
- X if ((*compare)(link->key, key) == 0)
- X {
- X if (link == chain) /* match found at head of the list */
- X {
- X node = chain->next;
- X
- X if (destruct)
- X (*destruct)(chain->key, chain->item);
- X
- X deallocate((caddr_t) chain);
- X *head = (caddr_t)node;
- X }
- X else
- X {
- X node->next = link->next;
- X
- X if (destruct)
- X (*destruct)(link->key, link->item);
- X
- X deallocate((caddr_t) link);
- X }
- X
- X break;
- X }
- X
- X node = link;
- X }
- X
- X return ((link) ? SUCCESS : FAILURE);
- X} /* LLremove */
- X
- X
- X
- X/*
- X NAME
- X LLsearch -- list search for a key.
- X
- X SYNOPSIS
- X*/
- X int LLsearch(seed, key, situs, compare)
- X caddr_t seed;
- X caddr_t key;
- X caddr_t * situs;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X*/
- X{
- X register llist_t link;
- X
- X for (link = (llist_t) seed; link; link = link->next)
- X if ((*compare)(link->key, key) == 0)
- X {
- X *situs = link->item;
- X break;
- X }
- X
- X return ((link) ? SUCCESS : FAILURE);
- X} /* LLsearch */
- X
- X
- X
- X/*
- X NAME
- X LLvisit -- list search for an item.
- X
- X SYNOPSIS
- X*/
- X int LLvisit(seed, situs, item, compare)
- X caddr_t seed;
- X caddr_t * situs;
- X caddr_t item;
- X agent_t compare;
- X/*
- X DESCRIPTION
- X*/
- X{
- X register llist_t link;
- X
- X for (link = (llist_t) seed; link; link = link->next)
- X if ((*compare)(link->item, item) == 0)
- X {
- X *situs = link->key;
- X break;
- X }
- X
- X return ((link) ? SUCCESS : FAILURE);
- X} /* LLvisit */
- X
- X
- X
- X/*
- X NAME
- X LLwalk -- walk through a list executing a given routine.
- X
- X SYNOPSIS
- X*/
- X void LLwalk(seed, routine, ark)
- X caddr_t seed;
- X agent_t routine;
- X caddr_t ark;
- X/*
- X DESCRIPTION
- X*/
- X{
- X register llist_t link;
- X
- X for (link = (llist_t) seed; link; link = link->next)
- X (*routine)(link->key, link->item, ark);
- X} /* LLwalk */
- X
- X
- X
- X/*
- X NAME
- X Stack -- stack operations.
- X
- X SYNOPSIS
- X*/
- X caddr_t Stack(seed, item)
- X caddr_t * seed;
- X caddr_t item;
- X/*
- X DESCRIPTION
- X*/
- X{
- X caddr_t epic = (caddr_t) 0;
- X stack_t head = (stack_t) *seed;
- X stack_t node = (stack_t) 0;
- X
- X if (item) /* push operation */
- X {
- X if (node = (stack_t) allocate(NIL, sizeof(struct _stack)))
- X {
- X node->item = item;
- X node->next = head;
- X epic = item; /* confirms success of operation */
- X }
- X }
- X else /* pop operation */
- X {
- X if (head)
- X {
- X epic = head->item;
- X node = head->next;
- X
- X deallocate((caddr_t) head);
- X }
- X }
- X
- X *seed = (caddr_t) node; /* always: establish top of stack */
- X
- X return epic;
- X} /* Stack */
- SHAR_EOF
- $TOUCH -am 0118091491 llist.c &&
- chmod 0444 llist.c ||
- echo "restore of llist.c failed"
- set `wc -c llist.c`;Wc_c=$1
- if test "$Wc_c" != "4789"; then
- echo original size 4789, current size $Wc_c
- fi
- # ============= llist.h ==============
- echo "x - extracting llist.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > llist.h &&
- X
- X/* Linear Lists (LL) routines header file.
- X
- X @(#) llist.h 1.2 1/17/91 by DePalma SoftCraft
- X*/
- X
- Xtypedef struct _llist /* linear list structure */
- X {
- X caddr_t key;
- X caddr_t item;
- X struct _llist * next;
- X} *llist_t;
- X
- Xtypedef struct _stack /* stack data structure */
- X {
- X caddr_t item;
- X struct _stack * next;
- X} *stack_t;
- X
- SHAR_EOF
- $TOUCH -am 0117231791 llist.h &&
- chmod 0444 llist.h ||
- echo "restore of llist.h failed"
- set `wc -c llist.h`;Wc_c=$1
- if test "$Wc_c" != "417"; then
- echo original size 417, current size $Wc_c
- fi
- # ============= load.c ==============
- echo "x - extracting load.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > load.c &&
- X
- X#include <stdio.h>
- X#include "craft.h"
- X
- Xextern int printf();
- X
- Xstatic agent_t reference[] = {
- X printf,
- X 0
- X};
- X
- X
- Xint main(argc, argv, envp)
- Xunsigned int argc;
- Xchar ** argv;
- Xchar ** envp;
- X{
- X agent_t reagent;
- X char module[BUFSIZ];
- X char * scan;
- X int status = SUCCESS;
- X
- X while (*++argv)
- X {
- X (void) strcpy(module, *argv);
- X
- X if (module[0] == '-')
- X {
- X status = unload(&module[1]);
- X error(status);
- X continue;
- X }
- X
- X if (scan = strchr(module, ':'))
- X {
- X *scan = (char) 0;
- X ++scan;
- X }
- X
- X if ((status = load(module)) == SUCCESS)
- X if (reagent = (agent_t) symbol(scan))
- X (*reagent)("CDL Test Driver");
- X
- X error(status);
- X }
- X
- X return (status == SUCCESS) ? 0 : status;
- X}
- SHAR_EOF
- $TOUCH -am 0118102091 load.c &&
- chmod 0644 load.c ||
- echo "restore of load.c failed"
- set `wc -c load.c`;Wc_c=$1
- if test "$Wc_c" != "797"; then
- echo original size 797, current size $Wc_c
- fi
- echo "End of part 1, continue with part 2"
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-