mauro@netcom.COM (Mauro DePalma) (04/14/91)
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.