home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / cdl / part01 next >
Internet Message Format  |  1991-04-14  |  44KB

  1. From: mauro@netcom.COM (Mauro DePalma)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i017:  cdl - COFF Dynamic Loader, Part01/02
  4. Message-ID: <1991Apr13.212554.15918@sparky.IMD.Sterling.COM>
  5. Date: 13 Apr 91 21:25:54 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 7a0b046a ac59c20c d330bc8d ba0d9a03
  8.  
  9. Submitted-by: Mauro DePalma <mauro@netcom.COM>
  10. Posting-number: Volume 18, Issue 17
  11. Archive-name: cdl/part01
  12.  
  13. This package is a COFF Dynamic Loader for System V.3 
  14. object files.  See README file for more details.
  15.  
  16. Mauro
  17. ---- Cut Here and unpack ----
  18. #!/bin/sh
  19. # This is CDL -1.2, a shell archive (shar 3.24)
  20. # made 02/11/1991 02:45 UTC by mauro@olympus
  21. # Source directory /u/mauro/src/craft
  22. #
  23. # existing files WILL be overwritten
  24. #
  25. # This shar contains:
  26. # length  mode       name
  27. # ------ ---------- ------------------------------------------
  28. #    505 -rw-r--r-- Makefile
  29. #   3783 -r--r--r-- README
  30. #  13681 -r--r--r-- avl.c
  31. #   1993 -r--r--r-- avl.h
  32. #   6945 -r--r--r-- craft.c
  33. #   4500 -r--r--r-- craft.h
  34. #   4789 -r--r--r-- llist.c
  35. #    417 -r--r--r-- llist.h
  36. #    797 -rw-r--r-- load.c
  37. #  21155 -r--r--r-- loader.c
  38. #   4799 -r--r--r-- loader.h
  39. #    676 -rw-r--r-- simple.c
  40. #
  41. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  42.  then TOUCH=touch
  43.  else TOUCH=true
  44. fi
  45. # ============= Makefile ==============
  46. echo "x - extracting Makefile (Text)"
  47. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  48. X#
  49. X# Dynamic Loader project makefile
  50. X#
  51. X
  52. X      CC = gcc
  53. X GCFLAGS = -fstrength-reduce -fpcc-struct-return -g -pipe
  54. X  CFLAGS = -DDEBUG -O $(GCFLAGS)
  55. X  LFLAGS = #-x
  56. X    LIBS = -lld
  57. X    OBJS = load.o loader.o avl.o craft.o llist.o
  58. X      RM = rm -f
  59. X
  60. Xload : $(OBJS)
  61. X    $(CC) $(LFLAGS) -o $@ $(OBJS) $(LIBS)
  62. X
  63. Xclean :
  64. X    $(RM) load core $(OBJS)
  65. X
  66. X# DO NOT DELETE
  67. X
  68. Xload.o   : load.c craft.h
  69. Xloader.o : loader.c craft.h loader.h
  70. Xavl.o    : avl.c craft.h avl.h
  71. Xcraft.o  : craft.c craft.h
  72. Xllist.o  : llist.c craft.h llist.h
  73. SHAR_EOF
  74. $TOUCH -am 0206004391 Makefile &&
  75. chmod 0644 Makefile ||
  76. echo "restore of Makefile failed"
  77. set `wc -c Makefile`;Wc_c=$1
  78. if test "$Wc_c" != "505"; then
  79.     echo original size 505, current size $Wc_c
  80. fi
  81. # ============= README ==============
  82. echo "x - extracting README (Text)"
  83. sed 's/^X//' << 'SHAR_EOF' > README &&
  84. X +----------------------------------------------------------------------------+
  85. X | Permission to use, copy, modify, distribute, and sell this software and its|
  86. X | documentation for any purpose is hereby granted without fee, provided that |
  87. X | credit is given to the original author.                                    |
  88. X |                                                                            |
  89. X | DePalma SoftCraft DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,   |
  90. X | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO     |
  91. X | EVENT SHALL DePalma SoftCraft BE LIABLE FOR ANY SPECIAL, INDIRECT OR       |
  92. X | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,|
  93. X | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER     |
  94. X | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR           |
  95. X | PERFORMANCE OF THIS SOFTWARE.                                              |
  96. X |                                                                            |
  97. X |                                                                            |
  98. X | Mauro DePalma           (mauro@netcom.COM or apple!netcom!mauro)           |
  99. X |                                                                            |
  100. X | DePalma SoftCraft      (UNIX System V/386 GNU, X11R4, InterViews)          |
  101. X | 2923 Cohansey Drive                                                        |
  102. X | San Jose, CA 95132                                                         |
  103. X |                                                                            |
  104. X | (408) 259-4789                                                             |
  105. X +----------------------------------------------------------------------------+
  106. X
  107. X
  108. X COFF Dynamic Loader (CDL) 1.2 consists of the following:
  109. X
  110. X      file       version  date       comment
  111. X      --------------------------------------------------------
  112. X      avl.c      1.3      1/13/91    by DePalma SoftCraft
  113. X      avl.h      1.3      1/13/91    by DePalma SoftCraft
  114. X      craft.c    1.4      1/18/91    by DePalma SoftCraft
  115. X      craft.h    1.4      1/17/91    by DePalma SoftCraft
  116. X      llist.c    1.2      1/18/91    by DePalma SoftCraft
  117. X      llist.h    1.2      1/17/91    by DePalma SoftCraft
  118. X      loader.c   1.5      1/18/91    by DePalma SoftCraft
  119. X      loader.h   1.5      1/18/91    by DePalma SoftCraft
  120. X
  121. X  Additionally a 'Makefile', this README file, 'simple.c', and 'load.c'
  122. X  are included.
  123. X
  124. X    The simplest test case can be accomplished by first creating the driver
  125. X  program 'load' by entering 'make'; simple.c needs to be manually compiled
  126. X  to produce simple.o which can be used to exercise the 'load' CDL driver
  127. X  as follows:
  128. X
  129. X                $ load simple.o:voyage
  130. X
  131. X
  132. X
  133. X  CDL 1.2                                                         1/18/91
  134. X
  135. X
  136. X   The public interface consists of the following routines:
  137. X
  138. X    int   load(char* object)   // an object file or an archive of object files
  139. X    void* symbol(char* name)   // either an entry point or global data
  140. X    int   unload(char* module) // an object file or archive member
  141. X
  142. X   all are declared in 'craft.h' header file; the library libld.a is needed
  143. X   during the linking phase.
  144. X
  145. X     When an archive of object files is given to load(3L) every member of
  146. X   the archive is examined thus, symbols used by one member can be referenced
  147. X   by others.
  148. X
  149. X    At present unload(3L) can only handle an object file or a member of an
  150. X    archive identified by, "<archive>[<member]". For example if we wish to
  151. X    unload member 'debt.o' from archive 'national.a' we'd use:
  152. X
  153. X             int status = unload("national.a[debt.o]");
  154. X
  155. X     Note: unload(3L) indiscriminately removes all symbols without regard
  156. X           where they're being referenced.
  157. SHAR_EOF
  158. $TOUCH -am 0210174891 README &&
  159. chmod 0444 README ||
  160. echo "restore of README failed"
  161. set `wc -c README`;Wc_c=$1
  162. if test "$Wc_c" != "3783"; then
  163.     echo original size 3783, current size $Wc_c
  164. fi
  165. # ============= avl.c ==============
  166. echo "x - extracting avl.c (Text)"
  167. sed 's/^X//' << 'SHAR_EOF' > avl.c &&
  168. X
  169. X#ifndef lint
  170. Xstatic char sccsid[] = "@(#) avl.c 1.3 1/13/91 by DePalma SoftCraft";
  171. X#endif
  172. X
  173. X/* Adelson-Velskii and Landis (AVL) balanced binary tree routines.
  174. X*/
  175. X#include "craft.h"
  176. X#include "avl.h"
  177. X
  178. X
  179. X/*
  180. X   NAME
  181. X       AVLdispose -- AVL Tree disposal.
  182. X
  183. X   SYNOPSIS
  184. X*/
  185. X       void AVLdispose(seed, destruct)
  186. X       caddr_t  seed;
  187. X       agent_t  destruct;
  188. X/*
  189. X   DESCRIPTION
  190. X*/
  191. X{
  192. X  AVLnode_t tree = (AVLnode_t) seed;
  193. X
  194. X  if (tree)
  195. X    {
  196. X      AVLdispose((caddr_t) tree->left,  destruct);
  197. X      AVLdispose((caddr_t) tree->right, destruct);
  198. X
  199. X      if (destruct)
  200. X        (*destruct)(tree->key, tree->item);
  201. X
  202. X      deallocate((caddr_t) tree);
  203. X    }
  204. X} /* AVLdispose */
  205. X
  206. X
  207. X
  208. X/*
  209. X   NAME
  210. X       AVLdump -- AVL Tree dump.
  211. X
  212. X   SYNOPSIS
  213. X*/
  214. X       void AVLdump(seed, routine, ark)
  215. X       caddr_t  seed;
  216. X       agent_t  routine;
  217. X       caddr_t  ark;
  218. X/*
  219. X   DESCRIPTION
  220. X       Wrapper for the recursive 'AVLtree()'.
  221. X
  222. X   SEE ALSO
  223. X       AVLtree.
  224. X*/
  225. X{
  226. X  AVLtree((AVLnode_t) seed, routine, 0, ark);
  227. X} /* AVLdump */
  228. X
  229. X
  230. X
  231. X/*
  232. X   NAME
  233. X       AVLinsert -- AVL Tree insertion.
  234. X
  235. X   SYNOPSIS
  236. X*/
  237. X       int AVLinsert(root, key, item, compare)
  238. X       caddr_t *  root;
  239. X       caddr_t    key;
  240. X       caddr_t    item;
  241. X       agent_t    compare;
  242. X/*
  243. X   DESCRIPTION
  244. X*/
  245. X{
  246. X  struct _AVLagent client;
  247. X  AVLagent_t       agent = &client;
  248. X  boolean_t        height;
  249. X
  250. X  agent->request = INSERT;
  251. X  agent->key     = key;
  252. X  agent->item    = item;
  253. X  height         = False;
  254. X  
  255. X  return AVLtraverse((AVLnode_t *) root, agent, &height, compare);
  256. X} /* AVLinsert */
  257. X
  258. X
  259. X
  260. X/*
  261. X   NAME
  262. X       AVLremove -- AVL Tree node removal.
  263. X
  264. X   SYNOPSIS
  265. X*/
  266. X       int AVLremove(root, key, compare, destruct)
  267. X       caddr_t *  root;
  268. X       caddr_t    key;
  269. X       agent_t    compare;
  270. X       agent_t    destruct;
  271. X/*
  272. X   DESCRIPTION
  273. X*/
  274. X{
  275. X  struct _AVLagent  client;
  276. X  AVLagent_t        agent = &client;
  277. X  boolean_t         height;
  278. X  int               result;
  279. X
  280. X  agent->request = DELETE;
  281. X  agent->key     = key;
  282. X  agent->item    = (caddr_t) 0;
  283. X  height         = False;
  284. X
  285. X  result = AVLtraverse((AVLnode_t *) root, agent, &height, compare);
  286. X
  287. X  if (result == SUCCESS && destruct)
  288. X    (*destruct)(agent->key, agent->item);
  289. X
  290. X  return result;
  291. X} /* AVLremove */
  292. X
  293. X
  294. X
  295. X/*
  296. X   NAME
  297. X       AVLreplace -- AVL Tree replacement.
  298. X
  299. X   SYNOPSIS
  300. X*/
  301. X       int AVLreplace(seed, key, item, compare)
  302. X       caddr_t    seed;
  303. X       caddr_t    key;
  304. X       caddr_t    item;
  305. X       agent_t    compare;
  306. X/*
  307. X   DESCRIPTION
  308. X*/
  309. X{
  310. X  struct _AVLagent client;
  311. X  AVLagent_t       agent = &client;
  312. X
  313. X  agent->request = REPLACE;
  314. X  agent->key     = key;
  315. X  agent->item    = item;
  316. X
  317. X  return AVLtravel((AVLnode_t) seed, agent, compare);
  318. X} /* AVLreplace */
  319. X
  320. X
  321. X
  322. X/*
  323. X   NAME
  324. X       AVLsearch -- AVL Tree search.
  325. X
  326. X   SYNOPSIS
  327. X*/
  328. X       int AVLsearch(seed, key, situs, compare)
  329. X       caddr_t    seed;
  330. X       caddr_t    key;
  331. X       caddr_t *  situs;
  332. X       agent_t    compare;
  333. X/*
  334. X   DESCRIPTION
  335. X*/
  336. X{
  337. X  struct _AVLagent client;
  338. X  AVLagent_t       agent = &client;
  339. X  int              result;
  340. X
  341. X  agent->request = SEARCH;
  342. X  agent->key     = key;
  343. X  agent->item    = (caddr_t) 0;
  344. X
  345. X  result = AVLtravel((AVLnode_t) seed, agent, compare);
  346. X
  347. X  if (result == SUCCESS && situs)
  348. X    *situs = agent->item;
  349. X
  350. X  return result;
  351. X} /* AVLsearch */
  352. X
  353. X
  354. X
  355. X
  356. X/*
  357. X   NAME
  358. X       AVLwalk -- walk the tree executing a given routine.
  359. X
  360. X   SYNOPSIS
  361. X*/
  362. X       void AVLwalk(seed, routine, ark)
  363. X       caddr_t  seed;
  364. X       agent_t  routine;
  365. X       caddr_t  ark;
  366. X/*
  367. X   DESCRIPTION
  368. X       Recursive routine which provides preorder traversal of an AVL tree
  369. X       invoking the 'routine' given with 'ark' upon visit of the root.
  370. X*/
  371. X{
  372. X  AVLnode_t  node = (AVLnode_t) seed;
  373. X
  374. X  if (node)
  375. X    {
  376. X      AVLwalk((caddr_t) node->left, routine, ark);
  377. X      (*routine)(node->key, node->item, ark);
  378. X      AVLwalk((caddr_t) node->right, routine, ark);
  379. X    }
  380. X} /* AVLwalk */
  381. X
  382. X
  383. X
  384. X/*
  385. X   NAME
  386. X       AVLdelete -- AVL Tree delete.
  387. X
  388. X   SYNOPSIS
  389. X*/
  390. X       static void AVLdelete(root, node, change)
  391. X       AVLnode_t *  root;
  392. X       AVLnode_t    node;
  393. X       boolean_t *  change;
  394. X/*
  395. X   DESCRIPTION
  396. X*/
  397. X{
  398. X  if (node)
  399. X    {
  400. X      if (node->right == (AVLnode_t) 0)
  401. X        {
  402. X          *root   = node->left;
  403. X          *change = True;
  404. X          deallocate((caddr_t) node);
  405. X        }
  406. X      else if (node->left == (AVLnode_t) 0)
  407. X        {
  408. X          *root   = node->right;
  409. X          *change = True;
  410. X          deallocate((caddr_t) node);
  411. X        }
  412. X      else
  413. X        {
  414. X          AVLerase(&(node->left), node, change);
  415. X
  416. X          if (*change == True)
  417. X            AVLrightBalance(root, change, DELETE);
  418. X        }
  419. X    }
  420. X} /* AVLdelete */
  421. X
  422. X
  423. X
  424. X/*
  425. X   NAME
  426. X       AVLerase -- AVL Tree delete (supplemental).
  427. X
  428. X   SYNOPSIS
  429. X*/
  430. X       static void AVLerase(root, link, change)
  431. X       AVLnode_t * root;
  432. X       AVLnode_t   link;
  433. X       boolean_t * change;
  434. X/*
  435. X   DESCRIPTION
  436. X*/
  437. X{
  438. X  AVLnode_t node = *root;
  439. X
  440. X  if (node->right)
  441. X    {
  442. X      AVLerase(&(node->right), link, change);
  443. X
  444. X      if (*change == True)
  445. X        AVLleftBalance(root, change, DELETE);
  446. X    }
  447. X  else
  448. X    {
  449. X      link->key  = node->key;
  450. X      link->item = node->item;
  451. X      *root      = node->left;
  452. X      *change    = True;
  453. X      deallocate((caddr_t) node);
  454. X    }
  455. X} /* AVLerase */
  456. X
  457. X
  458. X
  459. X/*
  460. X   NAME
  461. X       AVLleftBalance -- AVL Tree left balance.
  462. X
  463. X   SYNOPSIS
  464. X*/
  465. X       static void AVLleftBalance(root, change, reason)
  466. X       AVLnode_t *   root;
  467. X       boolean_t *   change;
  468. X       AVLrequest_t  reason;
  469. X/*
  470. X   DESCRIPTION
  471. X*/
  472. X{
  473. X  AVLnode_t    child;
  474. X  AVLnode_t    link;
  475. X  AVLnode_t    node = *root;
  476. X  AVLadjust_t  scale;
  477. X
  478. X  switch (node->balance)
  479. X    {
  480. X      case LEFT:                                  /* rebalance          */
  481. X        child = node->left;
  482. X        scale = child->balance;
  483. X
  484. X        if (scale == LEFT || (scale == CENTER && reason == DELETE))
  485. X          {                                       /* single LL rotation */
  486. X            node->left   = child->right;
  487. X            child->right = node;
  488. X
  489. X            AVLsideBalance(node, child, change,
  490. X                            (reason == DELETE) ? LEFT : CENTER);
  491. X            node = child;
  492. X          }
  493. X        else
  494. X          {                                       /* double LR rotation */
  495. X            link           = child->right;
  496. X            child->right   = link->left;
  497. X            link->left     = child;
  498. X            node->left     = link->right;
  499. X            link->right    = node;
  500. X            node->balance  = (link->balance == LEFT) ? RIGHT : CENTER;
  501. X            child->balance = (link->balance == RIGHT) ? LEFT : CENTER;
  502. X            node           = link;
  503. X
  504. X            if (reason == DELETE)
  505. X              link->balance = CENTER;
  506. X          }
  507. X
  508. X        if (reason != DELETE)
  509. X          {
  510. X            node->balance = CENTER;
  511. X            *change       = False;
  512. X          }
  513. X
  514. X        *root = node;
  515. X      break;
  516. X
  517. X      case CENTER:
  518. X        node->balance = LEFT;
  519. X
  520. X        if (reason == DELETE)
  521. X          *change = False;
  522. X      break;
  523. X
  524. X      case RIGHT:
  525. X        node->balance = CENTER;
  526. X
  527. X        if (reason != DELETE)
  528. X          *change = False;
  529. X      break;
  530. X    }
  531. X} /* AVLleftBalance */
  532. X
  533. X
  534. X
  535. X/*
  536. X   NAME
  537. X       AVLrightBalance -- AVL Tree right balance.
  538. X
  539. X   SYNOPSIS
  540. X*/
  541. X       static void AVLrightBalance(root, change, reason)
  542. X       AVLnode_t *   root;
  543. X       boolean_t *   change;
  544. X       AVLrequest_t  reason;
  545. X/*
  546. X   DESCRIPTION
  547. X*/
  548. X{
  549. X  AVLnode_t    child;
  550. X  AVLnode_t    link;
  551. X  AVLnode_t    node = *root;
  552. X  AVLadjust_t  scale;
  553. X
  554. X  switch (node->balance)
  555. X    {
  556. X      case LEFT:
  557. X        node->balance = CENTER;
  558. X
  559. X        if (reason != DELETE)
  560. X          *change = False;
  561. X      break;
  562. X
  563. X      case CENTER:
  564. X        node->balance = RIGHT;
  565. X
  566. X        if (reason == DELETE)
  567. X          *change = False;
  568. X      break;
  569. X
  570. X      case RIGHT:                                 /* rebalance          */
  571. X        child = node->right;
  572. X        scale = child->balance;
  573. X
  574. X        if (scale == RIGHT || (scale == CENTER && reason == DELETE))
  575. X          {                                       /* single RR rotation */
  576. X            node->right = child->left;
  577. X            child->left = node;
  578. X
  579. X            AVLsideBalance(node, child, change,
  580. X                            (reason == DELETE) ? RIGHT : CENTER);
  581. X            node = child;
  582. X          }
  583. X        else
  584. X          {                                       /* double RL rotation */
  585. X            link           = child->left;
  586. X            child->left    = link->right;
  587. X            link->right    = child;
  588. X            node->right    = link->left;
  589. X            link->left     = node;
  590. X            node->balance  = (link->balance == RIGHT) ? LEFT : CENTER;
  591. X            child->balance = (link->balance == LEFT) ? RIGHT : CENTER;
  592. X            node           = link;
  593. X
  594. X            if (reason == DELETE)
  595. X              link->balance = CENTER;
  596. X          }
  597. X
  598. X        if (reason != DELETE)
  599. X          {
  600. X            node->balance = CENTER;
  601. X            *change       = False;
  602. X          }
  603. X
  604. X        *root = node;
  605. X      break;
  606. X    }    
  607. X} /* AVLrightBalance */
  608. X
  609. X
  610. X
  611. X/*
  612. X   NAME
  613. X       AVLsideBalance -- AVL Tree height balance.
  614. X
  615. X   SYNOPSIS
  616. X*/
  617. X       static void AVLsideBalance(node, child, change, side)
  618. X       AVLnode_t    node;
  619. X       AVLnode_t    child;
  620. X       boolean_t *  change;
  621. X       AVLadjust_t  side;
  622. X/*
  623. X   DESCRIPTION
  624. X*/
  625. X{
  626. X  switch (side)
  627. X    {
  628. X      case LEFT:                          /* AVL Tree Deletion  */
  629. X      case RIGHT:
  630. X        if (child->balance == CENTER)
  631. X          {
  632. X            node->balance  = side;
  633. X            child->balance = (side == RIGHT) ? LEFT : RIGHT;
  634. X            *change        = False;
  635. X          }
  636. X        else
  637. X          {
  638. X            node->balance  = CENTER;
  639. X            child->balance = CENTER;
  640. X          }
  641. X      break;
  642. X
  643. X      default:                            /* AVL Tree Insertion */
  644. X        node->balance = CENTER;
  645. X    }
  646. X} /* AVLsideBalance */
  647. X
  648. X
  649. X
  650. X/*
  651. X   NAME
  652. X       AVLtravel -- readonly AVL Tree traversal.
  653. X
  654. X   SYNOPSIS
  655. X*/
  656. X       static int AVLtravel(node, agent, compare)
  657. X       AVLnode_t    node;
  658. X       AVLagent_t   agent;
  659. X       agent_t      compare;
  660. X/*
  661. X   DESCRIPTION
  662. X       Routine used for REPLACE and SEARCH operations.
  663. X*/
  664. X{
  665. X  AVLnode_t    link;
  666. X  int          comparison;
  667. X  int          result;
  668. X
  669. X  if (node)                           /* search           */
  670. X    {
  671. X      if ((comparison = (*compare)(agent->key, node->key)) < 0)
  672. X        {
  673. X          result = AVLtravel(node->left, agent, compare);
  674. X        }
  675. X      else if (comparison > 0)
  676. X        {
  677. X          result = AVLtravel(node->right, agent, compare);
  678. X        }
  679. X      else                            /* found a match    */
  680. X        {
  681. X          if (agent->request == REPLACE)
  682. X            node->item = agent->item;
  683. X          else
  684. X            agent->item = node->item;
  685. X
  686. X          result = SUCCESS;
  687. X        }
  688. X    }
  689. X  else                                /* search exhausted */
  690. X    {
  691. X       result = EAVLNOKEY;
  692. X    }
  693. X
  694. X  return result;
  695. X} /* AVLtravel */
  696. X
  697. X
  698. X
  699. X/*
  700. X   NAME
  701. X       AVLtraverse -- read/write AVL Tree traversal.
  702. X
  703. X   SYNOPSIS
  704. X*/
  705. X       static int AVLtraverse(root, agent, change, compare)
  706. X       AVLnode_t *  root;
  707. X       AVLagent_t   agent;
  708. X       boolean_t *  change;
  709. X       agent_t      compare;
  710. X/*
  711. X   DESCRIPTION
  712. X       Routine used for DELETE and INSERT operations.
  713. X*/
  714. X{
  715. X  AVLnode_t    link;
  716. X  AVLnode_t    node = *root;
  717. X  int          comparison;
  718. X  int          result;
  719. X
  720. X  if (node)                           /* search           */
  721. X    {
  722. X      if ((comparison = (*compare)(agent->key, node->key)) < 0)
  723. X        {
  724. X          result = AVLtraverse(&(node->left), agent, change, compare);
  725. X
  726. X          if (*change == True)
  727. X            if (agent->request == DELETE)
  728. X              AVLrightBalance(root, change, agent->request);
  729. X            else
  730. X              AVLleftBalance(root, change, agent->request);
  731. X        }
  732. X      else if (comparison > 0)
  733. X        {
  734. X          result = AVLtraverse(&(node->right), agent, change, compare);
  735. X
  736. X          if (*change == True)
  737. X            if (agent->request == DELETE)
  738. X              AVLleftBalance(root, change, agent->request);
  739. X            else
  740. X              AVLrightBalance(root, change, agent->request);
  741. X        }
  742. X      else                            /* found a match    */
  743. X        {
  744. X          if (agent->request == DELETE)
  745. X            {
  746. X              AVLdelete(root, node, change);
  747. X
  748. X              agent->key  = node->key;
  749. X              agent->item = node->item;
  750. X
  751. X              result = SUCCESS;
  752. X            }
  753. X          else
  754. X            {
  755. X              result = EAVLDUPKEY;
  756. X            }
  757. X        }
  758. X    }
  759. X  else                                /* search exhausted */
  760. X    {
  761. X      if (agent->request == DELETE)
  762. X        {
  763. X          result = EAVLNOKEY;
  764. X        }
  765. X      else
  766. X        {
  767. X          if (link = (AVLnode_t) allocate(NIL, sizeof(struct _AVLnode)))
  768. X            {
  769. X              link->balance = CENTER;
  770. X              link->key     = agent->key;
  771. X              link->item    = agent->item;
  772. X              link->left    = (AVLnode_t) 0;
  773. X              link->right   = (AVLnode_t) 0;
  774. X
  775. X              *change       = True;
  776. X              *root         = link;
  777. X
  778. X              result = SUCCESS;
  779. X            }
  780. X           else
  781. X            {
  782. X              result = EAVLNOMEM;
  783. X            }
  784. X        }
  785. X    }
  786. X
  787. X  return result;
  788. X} /* AVLtraverse */
  789. X
  790. X
  791. X
  792. X/*
  793. X   NAME
  794. X       AVLtree -- AVL Tree dump.
  795. X
  796. X   SYNOPSIS
  797. X*/
  798. X       static void AVLtree(node, routine, nest, ark)
  799. X       AVLnode_t  node;
  800. X       agent_t    routine;
  801. X       int        nest;
  802. X       caddr_t    ark;
  803. X/*
  804. X   DESCRIPTION
  805. X       Recursive routine which provides traversal of an AVL tree in
  806. X       natural order invoking the 'routine' given with nesting level
  807. X       and 'ark' (client data) upon visit of the root.
  808. X*/
  809. X{
  810. X  if (node)
  811. X    {
  812. X      AVLtree(node->right, routine, ++nest, ark);
  813. X      (*routine)(node->key, node->item, nest, ark);
  814. X      AVLtree(node->left, routine, nest, ark);
  815. X    }
  816. X} /* AVLtree */
  817. X
  818. SHAR_EOF
  819. $TOUCH -am 0113170391 avl.c &&
  820. chmod 0444 avl.c ||
  821. echo "restore of avl.c failed"
  822. set `wc -c avl.c`;Wc_c=$1
  823. if test "$Wc_c" != "13681"; then
  824.     echo original size 13681, current size $Wc_c
  825. fi
  826. # ============= avl.h ==============
  827. echo "x - extracting avl.h (Text)"
  828. sed 's/^X//' << 'SHAR_EOF' > avl.h &&
  829. X
  830. X/* @(#)avl.h 1.3 1/13/91 by DePalma SoftCraft
  831. X
  832. X   Adelson-Velskii and Landis (AVL) balanced binary tree header file.
  833. X*/
  834. X
  835. X#ifndef __AVL_H__                   /* guard against multiple includes     */
  836. X#define __AVL_H__
  837. X
  838. Xtypedef enum                        /* possible sort of balance required  */
  839. X  {
  840. X          LEFT,
  841. X          CENTER,
  842. X          RIGHT
  843. X  } AVLadjust_t;
  844. X
  845. Xtypedef enum                        /* various operation requests          */
  846. X  {
  847. X          DELETE,
  848. X          INSERT,
  849. X          REPLACE,
  850. X          SEARCH
  851. X  } AVLrequest_t;
  852. X
  853. Xtypedef struct _AVLnode             /* structure of a node in the tree     */
  854. X  {
  855. X          caddr_t           key;
  856. X          caddr_t           item;
  857. X          AVLadjust_t       balance;
  858. X          struct _AVLnode * left;
  859. X          struct _AVLnode * right;
  860. X  } *AVLnode_t;
  861. X
  862. Xtypedef struct _AVLagent            /* convenience structure for traversal */
  863. X  {
  864. X          AVLrequest_t      request;
  865. X          caddr_t           key;
  866. X          caddr_t           item;
  867. X  } *AVLagent_t;
  868. X
  869. X
  870. X/* AVL Specific Errors (should be read from a message file)
  871. X*/
  872. Xstatic char *avlErrorList[] =
  873. X  {
  874. X    "",
  875. X    "An attempt was made to insert a duplicate key",
  876. X    "Can't allocate enough memory to create a new AVL node",
  877. X    "Search failure, can't locate the specified key",
  878. X    0
  879. X  };
  880. X
  881. X#define EAVLDUPKEY  ERROR(avlErrorList, 1)
  882. X#define EAVLNOMEM   ERROR(avlErrorList, 2)
  883. X#define EAVLNOKEY   ERROR(avlErrorList, 3)
  884. X
  885. X
  886. X/* AVL Private
  887. X*/
  888. Xstatic void AVLdelete(AVLnode_t *, AVLnode_t, boolean_t *);
  889. Xstatic void AVLerase(AVLnode_t *, AVLnode_t, boolean_t *);
  890. Xstatic void AVLleftBalance(AVLnode_t *, boolean_t *, AVLrequest_t);
  891. Xstatic void AVLrightBalance(AVLnode_t *, boolean_t *, AVLrequest_t);
  892. Xstatic void AVLsideBalance(AVLnode_t, AVLnode_t, boolean_t *, AVLadjust_t);
  893. Xstatic int  AVLtravel(AVLnode_t, AVLagent_t, agent_t);
  894. Xstatic int  AVLtraverse(AVLnode_t *, AVLagent_t, boolean_t *, agent_t);
  895. Xstatic void AVLtree(AVLnode_t, agent_t, int, caddr_t);
  896. X#endif /* not __AVL_H__ */
  897. SHAR_EOF
  898. $TOUCH -am 0117230191 avl.h &&
  899. chmod 0444 avl.h ||
  900. echo "restore of avl.h failed"
  901. set `wc -c avl.h`;Wc_c=$1
  902. if test "$Wc_c" != "1993"; then
  903.     echo original size 1993, current size $Wc_c
  904. fi
  905. # ============= craft.c ==============
  906. echo "x - extracting craft.c (Text)"
  907. sed 's/^X//' << 'SHAR_EOF' > craft.c &&
  908. X
  909. X#ifndef lint
  910. Xstatic char sccsid[] = "@(#) craft.c 1.4 1/18/91 by DePalma SoftCraft";
  911. X#endif
  912. X
  913. X/* Base routines for SoftCraft library.
  914. X*/
  915. X
  916. X#include "craft.h"
  917. X
  918. X#define ErrorClass(mask)       ((mask & 0xffff0000) >> 16)
  919. X#define ErrorIndex(mask)       (mask & 0xffff)
  920. X#define ErrorMask(class, code) ((class << 16) | code)
  921. X
  922. Xstatic agent_t Displayer = (agent_t) scribe;
  923. Xstatic assoc_t Diagnosis = (assoc_t) 0;
  924. X
  925. X
  926. X
  927. X/*
  928. X   NAME
  929. X       allocate -- memory allocation.
  930. X
  931. X   SYNOPSIS
  932. X*/
  933. X       caddr_t  allocate(memory, bytes)
  934. X       caddr_t  memory;
  935. X       size_t   bytes;
  936. X/*
  937. X   DESCRIPTION
  938. X       Changes the size of a previously allocated memory block or
  939. X       allocates and clears a new one when none is specified.
  940. X*/
  941. X{
  942. X  caddr_t  saga;
  943. X
  944. X  if (memory)
  945. X    {
  946. X      saga = (caddr_t) realloc((void *) memory, bytes);
  947. X    }
  948. X  else
  949. X    {
  950. X      if (saga = (caddr_t) malloc(bytes))
  951. X        (void) memset((void *) saga, (char) 0, bytes);
  952. X    }
  953. X
  954. X  return saga;
  955. X} /* allocate */
  956. X
  957. X
  958. X
  959. X/*
  960. X   NAME
  961. X       deallocate -- memory deallocation.
  962. X
  963. X   SYNOPSIS
  964. X*/
  965. X       void deallocate(memory)
  966. X       caddr_t  memory;
  967. X/*
  968. X   DESCRIPTION
  969. X*/
  970. X{
  971. X  if (memory)
  972. X    {
  973. X      (void) free((void *) memory);
  974. X    }
  975. X} /* deallocate */
  976. X
  977. X
  978. X
  979. X/*
  980. X   NAME
  981. X       error(3L) -- output error message.
  982. X
  983. X   SYNOPSIS
  984. X*/
  985. X       void error(code)
  986. X       int code;
  987. X/*
  988. X   DESCRIPTION
  989. X       The 'code' argument is a 32 bit quantity which contains a
  990. X       unique error class (ex.: sys_errlist) in the upper 16 bits
  991. X       and an index (starting at 1) into the list of error messages
  992. X       in the lower 16 bits.
  993. X
  994. X       ERRMSG is a special 'code' which allows for using only
  995. X       optional arguments in the formation of the error message.
  996. X
  997. X   SEE ALSO
  998. X       errorCode(3L).
  999. X*/
  1000. X{
  1001. X  static char buffer[BLOCK];         /* Watch: may not be large enough */
  1002. X
  1003. X  va_list  args;
  1004. X  va_start(args, code);
  1005. X
  1006. X  if (code == FAILURE || code == SUCCESS || !Displayer)
  1007. X    return;
  1008. X
  1009. X  if (code == ERRMSG)
  1010. X    {
  1011. X      char* format = va_arg(args, char*);
  1012. X
  1013. X      (void) vsprintf(buffer, format, args);
  1014. X    }
  1015. X  else
  1016. X    {
  1017. X      caddr_t  key;
  1018. X      ushort   cast = ErrorClass(code);
  1019. X      ushort   mark = ErrorIndex(code);
  1020. X
  1021. X      if (LLvisit(Diagnosis->key, &key, (caddr_t) cast, minus) == SUCCESS)
  1022. X        {
  1023. X          (void) vsprintf(buffer, ((char**)key)[mark], args);
  1024. X
  1025. X          if (Diagnosis->item)
  1026. X            (void) strcat(buffer, Diagnosis->item);
  1027. X        }
  1028. X      else
  1029. X        {
  1030. X          (void) strcpy(buffer, form("in error (code=%x)", code));
  1031. X          (void) strcpy(buffer, DANGER(buffer));
  1032. X        }
  1033. X    }
  1034. X
  1035. X  (*Displayer)(buffer);    /* project: allow client to change 'Displayer' */
  1036. X  va_end(args);
  1037. X} /* error */
  1038. X
  1039. X
  1040. X/*
  1041. X   NAME
  1042. X       errorCode(3L) -- generation of error codes.
  1043. X
  1044. X   SYNOPSIS
  1045. X*/
  1046. X       int errorCode(module, line, list, code)
  1047. X       char *  module;
  1048. X       int     line;
  1049. X       char ** list;
  1050. X       int     code;
  1051. X/*
  1052. X   DESCRIPTION
  1053. X       Beyond yielding the correct error code errorCode(3L)
  1054. X       generates unique error classes for different error
  1055. X       message 'list's given.
  1056. X*/
  1057. X{
  1058. X  static boolean_t debug;
  1059. X  static int       increment = 100;
  1060. X  static int       sequence  = 0;
  1061. X
  1062. X  caddr_t  item;
  1063. X  int      cast;
  1064. X
  1065. X
  1066. X  if (Diagnosis == (assoc_t) 0)
  1067. X    { 
  1068. X      Diagnosis = (assoc_t) allocate(NIL, sizeof(struct _assoc));
  1069. X
  1070. X      if (debug = (boolean_t) getenv("DEBUG"))
  1071. X        Diagnosis->item = allocate(NIL, BLOCK * sizeof(char));
  1072. X    }
  1073. X
  1074. X  if (LLsearch(Diagnosis->key, (caddr_t) list, &item, minus) != SUCCESS)
  1075. X    {
  1076. X      item = (caddr_t) sequence + increment;
  1077. X
  1078. X      if (LLinsert(&(Diagnosis->key), (caddr_t) list, item) == SUCCESS)
  1079. X        {
  1080. X          sequence += increment;
  1081. X          cast = sequence;
  1082. X        }
  1083. X      else
  1084. X        {
  1085. X          (void) puts(DANGER("internal error"));
  1086. X          return FAILURE;
  1087. X        }
  1088. X    }
  1089. X  else
  1090. X    {
  1091. X      cast = (int) item;
  1092. X    }
  1093. X
  1094. X  if (debug)
  1095. X    (void) sprintf((char *) Diagnosis->item, " (%s line %d)", module, line);
  1096. X
  1097. X  return ErrorMask(cast, code);
  1098. X} /* errorCode */
  1099. X
  1100. X
  1101. X
  1102. X/*
  1103. X   NAME
  1104. X       errorNote(3L) -- change error message.
  1105. X
  1106. X   SYNOPSIS
  1107. X*/
  1108. X       int errorNote(module, line, code)
  1109. X       char *  module;
  1110. X       int     line;
  1111. X       int     code;
  1112. X/*
  1113. X   DESCRIPTION
  1114. X       When DEBUG environment variable is set the error message generated
  1115. X       includes the file name and line number. The purpose of this routine
  1116. X       is to update this information with the current file name and line
  1117. X       number.
  1118. X
  1119. X   SEE ALSO
  1120. X       errorCode(3L).
  1121. X*/
  1122. X{
  1123. X  if (Diagnosis)
  1124. X    if (Diagnosis->item)
  1125. X      (void) sprintf((char *) Diagnosis->item, " (%s line %d)", module, line);
  1126. X
  1127. X  return code;
  1128. X} /* errorNote */
  1129. X
  1130. X
  1131. X/*
  1132. X   NAME
  1133. X       form -- simple displayer.
  1134. X
  1135. X   SYNOPSIS
  1136. X*/
  1137. X       char * form(rule)
  1138. X       char * rule;
  1139. X/*
  1140. X   DESCRIPTION
  1141. X*/
  1142. X{
  1143. X  static char buffer[BLOCK];
  1144. X
  1145. X  va_list args;
  1146. X  va_start(args, rule);
  1147. X
  1148. X  (void) vsprintf(buffer, rule, args);
  1149. X  va_end(args);
  1150. X
  1151. X  return buffer;
  1152. X} /* form */
  1153. X
  1154. X
  1155. X
  1156. X/*
  1157. X   NAME
  1158. X       minus -- difference between two numbers.
  1159. X
  1160. X   SYNOPSIS
  1161. X*/
  1162. X       int minus(left, right)
  1163. X       int  left;
  1164. X       int  right;
  1165. X/*
  1166. X   DESCRIPTION
  1167. X       Comparison routine for two numbers.
  1168. X
  1169. X   SEE ALSO
  1170. X       AVLinsert(3L), AVLsearch(3L).
  1171. X*/
  1172. X{
  1173. X  return (left - right);
  1174. X} /* minus */
  1175. X
  1176. X
  1177. X/*
  1178. X   NAME
  1179. X       scribe -- simple displayer.
  1180. X
  1181. X   SYNOPSIS
  1182. X*/
  1183. X       int scribe(message)
  1184. X       char* message;
  1185. X/*
  1186. X   DESCRIPTION
  1187. X*/
  1188. X{ 
  1189. X  return puts(message);
  1190. X} /* scribe */
  1191. X
  1192. X
  1193. X
  1194. X/*
  1195. X   NAME
  1196. X       which - locate a program file.
  1197. X
  1198. X   SYNOPSIS
  1199. X*/
  1200. X       char * which(name)
  1201. X       char * name;
  1202. X
  1203. X/*
  1204. X   DESCRIPTION
  1205. X       Which looks for the file which be executed had the given
  1206. X       'name' been issued as a command.
  1207. X*/
  1208. X{
  1209. X  static boolean_t stub;
  1210. X  static char*     home;
  1211. X  static char*     path = (char*) 0;
  1212. X  static char      string[BLOCK];
  1213. X
  1214. X  char   buffer[BLOCK];
  1215. X  char*  token;
  1216. X  ushort mark;
  1217. X
  1218. X  if (name[0] == '.' || name[0] == '/')   /* trivial: absolute path   */
  1219. X    return name;
  1220. X
  1221. X  if (path == (char*) 0)                  /* once: save environment   */
  1222. X    {
  1223. X      home = getenv("HOME");
  1224. X      path = getenv("PATH");
  1225. X      stub = (boolean_t) (path[strlen(path) - 1] == ':');
  1226. X    }
  1227. X
  1228. X  if (stub)                               /* check special case       */
  1229. X    {
  1230. X      (void) sprintf(string, "./%s", name);
  1231. X
  1232. X      if (access(string, 0) == 0)
  1233. X        return string;
  1234. X    }
  1235. X
  1236. X  (void) strcpy(buffer, path);            /* always make a copy       */
  1237. X  mark = 0;                               /* initialize 'path' marker */
  1238. X
  1239. X  for (token = strtok(buffer, ":"); token; token = strtok((char*) 0, ":"))
  1240. X    {
  1241. X      if (path[mark] == ':')
  1242. X        {
  1243. X          (void) sprintf(string, "./%s", name);
  1244. X
  1245. X          if (access(string, 0) == 0)
  1246. X            break;
  1247. X        }
  1248. X
  1249. X      if (token[0] == '~')
  1250. X        (void) sprintf(string, "%s%s%s", home, &token[1], name);
  1251. X      else
  1252. X        (void) sprintf(string, "%s/%s", token, name);
  1253. X
  1254. X      if (access(string, 0) == 0)
  1255. X        break;
  1256. X
  1257. X      mark += strlen(token) + 1;
  1258. X    }
  1259. X
  1260. X  return ((token) ? string : (char*) 0);
  1261. X} /* which */
  1262. SHAR_EOF
  1263. $TOUCH -am 0118000591 craft.c &&
  1264. chmod 0444 craft.c ||
  1265. echo "restore of craft.c failed"
  1266. set `wc -c craft.c`;Wc_c=$1
  1267. if test "$Wc_c" != "6945"; then
  1268.     echo original size 6945, current size $Wc_c
  1269. fi
  1270. # ============= craft.h ==============
  1271. echo "x - extracting craft.h (Text)"
  1272. sed 's/^X//' << 'SHAR_EOF' > craft.h &&
  1273. X
  1274. X/* Utility library header file.
  1275. X
  1276. X   @(#) craft.h 1.4 1/17/91 by DePalma SoftCraft
  1277. X*/
  1278. X
  1279. X#ifndef __CRAFT__                   /* guard against multiple includes      */
  1280. X#define __CRAFT__
  1281. X
  1282. X#include <stdarg.h>                 /* found in 'LIBDIR/gcc-include'        */
  1283. X#include <sys/types.h>
  1284. X
  1285. X#ifndef CTRL
  1286. X#  define CTRL(c)         ('c' & 037)
  1287. X#endif
  1288. X
  1289. X#define DANGER(msg)       form("panic: %s (%s line %d)", msg,__FILE__,__LINE__)
  1290. X#define DUBIOUS(code)     errorNote(__FILE__, __LINE__, code)
  1291. X
  1292. X#define ERRMSG            0x10000
  1293. X#define ERROR(list, code) errorCode(__FILE__, __LINE__, list, code)
  1294. X
  1295. X#ifndef False
  1296. X#  define False           0
  1297. X#  define True            1
  1298. X#endif
  1299. X
  1300. X#ifndef FAILURE
  1301. X#  define FAILURE         0
  1302. X#  define SUCCESS         1
  1303. X#endif
  1304. X
  1305. X#ifndef max
  1306. X#  define max(a, b)       (((a) > (b)) ? (a) : (b))
  1307. X#  define min(a, b)       (((a) < (b)) ? (a) : (b))
  1308. X#endif
  1309. X
  1310. X#define  NIL              (void *) 0
  1311. X
  1312. X#define  BACKSPACE        '\010'
  1313. X#define  ESCAPE           '\033'
  1314. X#define  RETURN           '\015'
  1315. X#define  SPACE            '\040'
  1316. X
  1317. X#define  BLOCK            512
  1318. X#define  MEGACYCLE        1000000L
  1319. X#define  TERMINATOR       '\200'
  1320. X
  1321. X/* SoftCraft Types
  1322. X*/
  1323. Xtypedef int (*agent_t)();           /* entry point for a procedure         */
  1324. X
  1325. Xtypedef struct _assoc               /* generic association structure       */
  1326. X  {
  1327. X          caddr_t key;              /* named (search) key                  */
  1328. X          caddr_t item;             /* associated item                     */
  1329. X  } *assoc_t;
  1330. X
  1331. Xtypedef unsigned char boolean_t;    /* boolean type (True or False)        */
  1332. X
  1333. Xtypedef struct _buffer              /* generic buffer structure            */
  1334. X  {
  1335. X          char *  base;             /* .. base address                     */
  1336. X          long    mark;             /* .. a marker (ex: number of entries) */
  1337. X  } *buffer_t;
  1338. X
  1339. X
  1340. X
  1341. X/* Key Definitions
  1342. X*/
  1343. X#define KEY_DOWN      0402          /* Sent by terminal down arrow key.     */
  1344. X#define KEY_UP        0403          /* Sent by terminal up arrow key.       */
  1345. X#define KEY_LEFT      0404          /* Sent by terminal left arrow key.     */
  1346. X#define KEY_RIGHT     0405          /* Sent by terminal right arrow key.    */
  1347. X#define KEY_HOME      0406          /* Sent by home key.                    */
  1348. X#define KEY_BACKSPACE 0407          /* Sent by backspace key.               */
  1349. X#define KEY_F0        0410          /* function key f0.                     */
  1350. X#define KEY_F(n)      (KEY_F0+(n))  /* Reserve space for 64 function keys.  */
  1351. X#define KEY_DC        0512          /* Sent by delete character key.        */
  1352. X#define KEY_IC        0513          /* Sent by ins char/enter ins mode key. */
  1353. X#define KEY_PGDN      0522          /* Sent by next-page key.               */
  1354. X#define KEY_PGUP      0523          /* Sent by previous-page key.           */
  1355. X#define KEY_PRINT     0532          /* Print or copy key.                   */
  1356. X#define KEY_END       0550          /* End key                              */
  1357. X
  1358. X
  1359. X
  1360. X/* SoftCraft Public Library
  1361. X
  1362. X   avl.o
  1363. X*/
  1364. Xvoid     AVLdispose(caddr_t, agent_t);
  1365. Xvoid     AVLdump(caddr_t, agent_t, caddr_t);
  1366. Xint      AVLinsert(caddr_t *, caddr_t, caddr_t, agent_t);
  1367. Xint      AVLremove(caddr_t *, caddr_t, agent_t, agent_t);
  1368. Xint      AVLreplace(caddr_t, caddr_t, caddr_t, agent_t);
  1369. Xint      AVLsearch(caddr_t, caddr_t, caddr_t *, agent_t);
  1370. Xvoid     AVLwalk(caddr_t, agent_t, caddr_t);
  1371. X
  1372. X/* craft.o
  1373. X*/
  1374. Xcaddr_t  allocate(caddr_t, size_t);
  1375. Xvoid     deallocate(caddr_t);
  1376. Xvoid     error(int, ...);
  1377. Xint      errorCode(char *, int, char **, int);
  1378. Xint      errorNote(char *, int, int);
  1379. Xchar *   form(char *, ...);
  1380. Xint      minus(int, int);
  1381. Xint      scribe(char *);
  1382. Xchar *   which(char *);
  1383. X
  1384. X/* llist.o
  1385. X*/
  1386. Xvoid     LLdispose(caddr_t, agent_t);
  1387. Xint      LLinsert(caddr_t *, caddr_t, caddr_t);
  1388. Xint      LLremove(caddr_t *, caddr_t, agent_t, agent_t);
  1389. Xint      LLsearch(caddr_t, caddr_t, caddr_t *, agent_t);
  1390. Xint      LLvisit(caddr_t, caddr_t *, caddr_t, agent_t);
  1391. Xvoid     LLwalk(caddr_t, agent_t, caddr_t);
  1392. Xcaddr_t  Stack(caddr_t *, caddr_t);
  1393. X
  1394. X/* loader.o
  1395. X*/
  1396. Xint      load(char *);
  1397. Xvoid *   symbol(char *);
  1398. Xint      unload(char *);
  1399. X
  1400. X
  1401. X/* Symbols used from standard libraries.
  1402. X*/
  1403. Xextern char *  ctime(time_t *);
  1404. Xextern char *  getenv(char *);
  1405. X
  1406. Xextern int     strcmp(char *, char *);
  1407. Xextern char *  strdup(char *);
  1408. Xextern char *  strchr(char *, int);
  1409. Xextern char *  strrchr(char *, int);
  1410. Xextern char *  strtok(char *, char *);
  1411. X
  1412. Xextern char *  optarg;
  1413. Xextern int     optind;
  1414. X
  1415. Xextern char *  sys_errlist[];
  1416. X#endif /* not __CRAFT__ */
  1417. SHAR_EOF
  1418. $TOUCH -am 0117225991 craft.h &&
  1419. chmod 0444 craft.h ||
  1420. echo "restore of craft.h failed"
  1421. set `wc -c craft.h`;Wc_c=$1
  1422. if test "$Wc_c" != "4500"; then
  1423.     echo original size 4500, current size $Wc_c
  1424. fi
  1425. # ============= llist.c ==============
  1426. echo "x - extracting llist.c (Text)"
  1427. sed 's/^X//' << 'SHAR_EOF' > llist.c &&
  1428. X
  1429. X#ifndef lint
  1430. Xstatic char sccsid[] = "@(#) llist.c 1.2 1/18/91 by DePalma SoftCraft";
  1431. X#endif
  1432. X
  1433. X/* Linear Lists (LL) routines.
  1434. X
  1435. X   ** DANGER **
  1436. X   Since these routines are used for error class registration,
  1437. X   introducing an error class for the LL module would result
  1438. X   in infinite recursion.
  1439. X*/
  1440. X
  1441. X#include "craft.h"
  1442. X#include "llist.h"
  1443. X
  1444. X
  1445. X/*
  1446. X   NAME
  1447. X       LLdispose -- list disposal.
  1448. X
  1449. X   SYNOPSIS
  1450. X*/
  1451. X       void LLdispose(seed, destruct)
  1452. X       caddr_t  seed;
  1453. X       agent_t  destruct;
  1454. X/*
  1455. X   DESCRIPTION
  1456. X*/
  1457. X{
  1458. X  llist_t  chain = (llist_t) seed;
  1459. X  llist_t  link;
  1460. X
  1461. X  while (chain)
  1462. X    {
  1463. X      link = chain->next;
  1464. X
  1465. X      if (destruct)
  1466. X        (*destruct)(chain->key, chain->item);
  1467. X
  1468. X      deallocate((caddr_t) chain);
  1469. X
  1470. X      chain = link;
  1471. X    }
  1472. X} /* LLdispose */
  1473. X
  1474. X
  1475. X
  1476. X/*
  1477. X   NAME
  1478. X       LLinsert -- link list insert.
  1479. X
  1480. X   SYNOPSIS
  1481. X*/
  1482. X       int LLinsert(head, key, item)
  1483. X       caddr_t *  head;
  1484. X       caddr_t    key;
  1485. X       caddr_t    item;
  1486. X/*
  1487. X   DESCRIPTION
  1488. X*/
  1489. X{
  1490. X  llist_t  chain = (llist_t) *head;
  1491. X  llist_t  link;
  1492. X
  1493. X  if (link = (llist_t) allocate(NIL, sizeof(struct _llist)))
  1494. X    {
  1495. X      link->key  = key;
  1496. X      link->item = item;
  1497. X      link->next = (llist_t) 0;
  1498. X
  1499. X      if (chain)             /* add another 'link' an existing 'chain' */
  1500. X        {
  1501. X          while (chain->next) chain = chain->next;
  1502. X          chain->next = link;
  1503. X        }
  1504. X      else                   /* start a new 'chain' (linear list)      */
  1505. X        {
  1506. X          *head = (caddr_t) link;
  1507. X        }
  1508. X    }
  1509. X
  1510. X  return ((link) ? SUCCESS : FAILURE);
  1511. X} /* LLinsert */
  1512. X
  1513. X
  1514. X
  1515. X/*
  1516. X   NAME
  1517. X       LLremove -- remove an item from a list.
  1518. X
  1519. X   SYNOPSIS
  1520. X*/
  1521. X       int LLremove(head, key, compare, destruct)
  1522. X       caddr_t * head;
  1523. X       caddr_t   key;
  1524. X       agent_t   compare;
  1525. X       agent_t   destruct;
  1526. X/*
  1527. X   DESCRIPTION
  1528. X*/
  1529. X{
  1530. X  llist_t  chain = (llist_t) *head;
  1531. X  llist_t  link;
  1532. X  llist_t  node;
  1533. X
  1534. X  for (link = chain, node = chain; link; link = link->next)
  1535. X    {
  1536. X      if ((*compare)(link->key, key) == 0)
  1537. X        {
  1538. X          if (link == chain)       /* match found at head of the list */
  1539. X            {
  1540. X              node = chain->next;
  1541. X
  1542. X              if (destruct)
  1543. X                (*destruct)(chain->key, chain->item);
  1544. X
  1545. X              deallocate((caddr_t) chain);
  1546. X              *head = (caddr_t)node;
  1547. X            }
  1548. X          else
  1549. X            {
  1550. X              node->next = link->next;
  1551. X
  1552. X              if (destruct)
  1553. X                (*destruct)(link->key, link->item);
  1554. X
  1555. X              deallocate((caddr_t) link);
  1556. X            }
  1557. X
  1558. X          break;
  1559. X        }
  1560. X
  1561. X      node = link;
  1562. X    }
  1563. X
  1564. X  return ((link) ? SUCCESS : FAILURE);
  1565. X} /* LLremove */
  1566. X
  1567. X
  1568. X
  1569. X/*
  1570. X   NAME
  1571. X       LLsearch -- list search for a key.
  1572. X
  1573. X   SYNOPSIS
  1574. X*/
  1575. X       int LLsearch(seed, key, situs, compare)
  1576. X       caddr_t    seed;
  1577. X       caddr_t    key;
  1578. X       caddr_t *  situs;
  1579. X       agent_t    compare;
  1580. X/*
  1581. X   DESCRIPTION
  1582. X*/
  1583. X{
  1584. X  register llist_t link;
  1585. X
  1586. X  for (link = (llist_t) seed; link; link = link->next)
  1587. X    if ((*compare)(link->key, key) == 0)
  1588. X      {
  1589. X        *situs = link->item;
  1590. X        break;
  1591. X      }
  1592. X
  1593. X  return ((link) ? SUCCESS : FAILURE);
  1594. X} /* LLsearch */
  1595. X
  1596. X
  1597. X
  1598. X/*
  1599. X   NAME
  1600. X       LLvisit -- list search for an item.
  1601. X
  1602. X   SYNOPSIS
  1603. X*/
  1604. X       int LLvisit(seed, situs, item, compare)
  1605. X       caddr_t    seed;
  1606. X       caddr_t *  situs;
  1607. X       caddr_t    item;
  1608. X       agent_t    compare;
  1609. X/*
  1610. X   DESCRIPTION
  1611. X*/
  1612. X{
  1613. X  register llist_t link;
  1614. X
  1615. X  for (link = (llist_t) seed; link; link = link->next)
  1616. X    if ((*compare)(link->item, item) == 0)
  1617. X      {
  1618. X        *situs = link->key;
  1619. X        break;
  1620. X      }
  1621. X
  1622. X  return ((link) ? SUCCESS : FAILURE);
  1623. X} /* LLvisit */
  1624. X
  1625. X
  1626. X
  1627. X/*
  1628. X   NAME
  1629. X       LLwalk -- walk through a list executing a given routine.
  1630. X
  1631. X   SYNOPSIS
  1632. X*/
  1633. X       void LLwalk(seed, routine, ark)
  1634. X       caddr_t  seed;
  1635. X       agent_t  routine;
  1636. X       caddr_t  ark;
  1637. X/*
  1638. X   DESCRIPTION
  1639. X*/
  1640. X{
  1641. X  register llist_t link;
  1642. X
  1643. X  for (link = (llist_t) seed; link; link = link->next)
  1644. X    (*routine)(link->key, link->item, ark);
  1645. X} /* LLwalk */
  1646. X
  1647. X
  1648. X
  1649. X/*
  1650. X   NAME
  1651. X       Stack -- stack operations.
  1652. X
  1653. X   SYNOPSIS
  1654. X*/
  1655. X       caddr_t Stack(seed, item)
  1656. X       caddr_t * seed;
  1657. X       caddr_t   item;
  1658. X/*
  1659. X   DESCRIPTION
  1660. X*/
  1661. X{
  1662. X  caddr_t epic = (caddr_t) 0;
  1663. X  stack_t head = (stack_t) *seed;
  1664. X  stack_t node = (stack_t) 0;
  1665. X
  1666. X  if (item)                        /* push operation                 */
  1667. X    {
  1668. X      if (node = (stack_t) allocate(NIL, sizeof(struct _stack)))
  1669. X        {
  1670. X          node->item = item;
  1671. X          node->next = head;
  1672. X          epic = item;             /* confirms success of operation  */
  1673. X        }
  1674. X    }
  1675. X  else                             /* pop operation                  */
  1676. X    {
  1677. X      if (head)
  1678. X        {
  1679. X          epic = head->item;
  1680. X          node = head->next;
  1681. X
  1682. X          deallocate((caddr_t) head);
  1683. X        }
  1684. X    }
  1685. X
  1686. X  *seed = (caddr_t) node;          /* always: establish top of stack */
  1687. X
  1688. X  return epic;
  1689. X} /* Stack */
  1690. SHAR_EOF
  1691. $TOUCH -am 0118091491 llist.c &&
  1692. chmod 0444 llist.c ||
  1693. echo "restore of llist.c failed"
  1694. set `wc -c llist.c`;Wc_c=$1
  1695. if test "$Wc_c" != "4789"; then
  1696.     echo original size 4789, current size $Wc_c
  1697. fi
  1698. # ============= llist.h ==============
  1699. echo "x - extracting llist.h (Text)"
  1700. sed 's/^X//' << 'SHAR_EOF' > llist.h &&
  1701. X
  1702. X/* Linear Lists (LL) routines header file.
  1703. X
  1704. X   @(#) llist.h 1.2 1/17/91 by DePalma SoftCraft
  1705. X*/
  1706. X
  1707. Xtypedef struct _llist              /* linear list structure */
  1708. X  {
  1709. X          caddr_t         key;
  1710. X          caddr_t         item;
  1711. X          struct _llist * next;
  1712. X} *llist_t;
  1713. X
  1714. Xtypedef struct _stack              /* stack data structure  */
  1715. X  {
  1716. X          caddr_t         item;
  1717. X          struct _stack * next;
  1718. X} *stack_t;
  1719. X
  1720. SHAR_EOF
  1721. $TOUCH -am 0117231791 llist.h &&
  1722. chmod 0444 llist.h ||
  1723. echo "restore of llist.h failed"
  1724. set `wc -c llist.h`;Wc_c=$1
  1725. if test "$Wc_c" != "417"; then
  1726.     echo original size 417, current size $Wc_c
  1727. fi
  1728. # ============= load.c ==============
  1729. echo "x - extracting load.c (Text)"
  1730. sed 's/^X//' << 'SHAR_EOF' > load.c &&
  1731. X
  1732. X#include <stdio.h>
  1733. X#include "craft.h"
  1734. X
  1735. Xextern int printf();
  1736. X
  1737. Xstatic agent_t reference[] = {
  1738. X  printf,
  1739. X  0
  1740. X};
  1741. X
  1742. X
  1743. Xint main(argc, argv, envp)
  1744. Xunsigned int  argc;
  1745. Xchar **       argv;
  1746. Xchar **       envp;
  1747. X{
  1748. X  agent_t reagent;
  1749. X  char    module[BUFSIZ];
  1750. X  char *  scan;
  1751. X  int     status = SUCCESS;
  1752. X
  1753. X  while (*++argv)
  1754. X    {
  1755. X      (void) strcpy(module, *argv);
  1756. X
  1757. X      if (module[0] == '-')
  1758. X        {
  1759. X          status = unload(&module[1]);
  1760. X          error(status);
  1761. X          continue;
  1762. X        }
  1763. X
  1764. X      if (scan = strchr(module, ':'))
  1765. X        {
  1766. X          *scan = (char) 0;
  1767. X          ++scan;
  1768. X        }
  1769. X
  1770. X      if ((status = load(module)) == SUCCESS)
  1771. X        if (reagent = (agent_t) symbol(scan))
  1772. X          (*reagent)("CDL Test Driver");
  1773. X
  1774. X      error(status);
  1775. X    }
  1776. X
  1777. X  return (status == SUCCESS) ? 0 : status;
  1778. X}
  1779. SHAR_EOF
  1780. $TOUCH -am 0118102091 load.c &&
  1781. chmod 0644 load.c ||
  1782. echo "restore of load.c failed"
  1783. set `wc -c load.c`;Wc_c=$1
  1784. if test "$Wc_c" != "797"; then
  1785.     echo original size 797, current size $Wc_c
  1786. fi
  1787. echo "End of part 1, continue with part 2"
  1788. exit 0
  1789.  
  1790. exit 0 # Just in case...
  1791. -- 
  1792. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1793. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1794. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1795. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1796.