home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume27 / clc / part12 < prev    next >
Encoding:
Text File  |  1993-11-28  |  27.1 KB  |  1,091 lines

  1. Newsgroups: comp.sources.unix
  2. From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v27i118: clc - C Libraries Collection, Part12/20
  4. References: <1.754527080.23891@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  9. Posting-Number: Volume 27, Issue 118
  10. Archive-Name: clc/part12
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 12 (of 20)."
  19. # Contents:  libs/src/dict/Makefile libs/src/dict/rbt.c
  20. #   libs/src/fsma/fsma.c libs/src/xlog/filelog.c
  21. # Wrapped by panos@eclipse on Sun Nov 28 14:48:16 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'libs/src/dict/Makefile' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'libs/src/dict/Makefile'\"
  25. else
  26. echo shar: Extracting \"'libs/src/dict/Makefile'\" \(5819 characters\)
  27. sed "s/^X//" >'libs/src/dict/Makefile' <<'END_OF_FILE'
  28. X# (c) Copyright 1993 by Panagiotis Tsirigotis
  29. X# All rights reserved.  The file named COPYRIGHT specifies the terms 
  30. X# and conditions for redistribution.
  31. X
  32. X#
  33. X# $Id: Makefile,v 3.8 93/11/19 20:04:23 panos Exp $
  34. X#
  35. X# Based on Library makefile template: *Revision: 1.15 *
  36. X#
  37. X
  38. X# 
  39. X# Available entries:
  40. X#         lib             --> creates the library
  41. X#        install        --> installs the library (archive, man page(s), header(s))
  42. X#        uninstall    --> uninstall the library
  43. X#        clean            --> removes all .o and .a files
  44. X#        spotless        --> clean + uninstall
  45. X#         lint            --> lints a file (usage: make lint MODULE=foo.c)
  46. X#        tags            --> creates a tags file (from the SOURCES and HEADERS)
  47. X#        checkout     --> checkout all files
  48. X#        dist            --> distribution support
  49. X#
  50. X
  51. XNAME                = dict
  52. XVERSION            = 1.2.4
  53. X
  54. X#
  55. X# Double-Linked-List implementation
  56. X#
  57. XDLL_INCLUDES    = dll.h
  58. XDLL_HEADERS        = $(DLL_INCLUDES) dllimpl.h
  59. XDLL_SOURCES        = dll.c
  60. XDLL_OBJECTS        = dll.o
  61. XDLL_MANFILES    = dll.3
  62. X
  63. X#
  64. X# Hash-Table implementation
  65. X#
  66. XHT_INCLUDES        = ht.h
  67. XHT_HEADERS        = $(HT_INCLUDES) htimpl.h
  68. XHT_SOURCES        = ht.c
  69. XHT_OBJECTS        = ht.o
  70. XHT_MANFILES        = ht.3
  71. X
  72. X#
  73. X# Binary search tree implementation
  74. X#
  75. XBST_INCLUDES    = bst.h
  76. XBST_HEADERS        = $(BST_INCLUDES) bstimpl.h
  77. XBST_SOURCES        = bst.c rbt.c
  78. XBST_OBJECTS        = bst.o rbt.o
  79. XBST_MANFILES    = bst.3
  80. X
  81. XHEADERS            = dictimpl.h dict.h \
  82. X                            $(DLL_HEADERS) $(HT_HEADERS) $(BST_HEADERS)
  83. XSOURCES            = dict.c \
  84. X                            $(DLL_SOURCES) $(HT_SOURCES) $(BST_SOURCES)
  85. XOBJECTS            = dict.o \
  86. X                            $(DLL_OBJECTS) $(HT_OBJECTS) $(BST_OBJECTS)
  87. X
  88. XMANFILES            = dict.3 \
  89. X                            $(DLL_MANFILES) $(HT_MANFILES) \
  90. X                            $(BST_MANFILES)
  91. XINCLUDEFILES    = dict.h \
  92. X                            $(DLL_INCLUDES) $(HT_INCLUDES) \
  93. X                            $(BST_INCLUDES)
  94. X
  95. XTESTPROGS        = dlltest htest bsttest bstcomp
  96. X
  97. X# The following variables are used by the 'install' entry and
  98. X# should be customized:
  99. X#     LIBDIR:     where the library will be placed
  100. X#     INCUDEDIR:  where the include files will be placed
  101. X#     MANDIR:     where the man pages will be placed
  102. X#
  103. XLIBDIR            = $(HOME)/.links/libraries/$(ARCH)
  104. XMANDIR            = $(HOME)/.links/manpages/man3
  105. XINCLUDEDIR        = $(HOME)/.links/includes
  106. X
  107. X#
  108. X# -DBST_DEBUG    :    enables 2 debugging functions: bst_getdepth and bst_traverse
  109. X#                        bst_getdepth() returns the maximum and minimum depth of the
  110. X#                        tree. In the case of a red-black tree, it verifies that
  111. X#                        the balancing property holds for every subtree. It prints
  112. X#                        a message for each unbalanced subtree it finds.
  113. X#                        bst_traverse() does preorder/inorder/postorder traversals
  114. X#                        of the tree and applies a user-provided function to each
  115. X#                        node.
  116. X#                        In order for these functions to be available, the BST_DEBUG
  117. X#                        flag must be set, both when compiling the library and when
  118. X#                        when compiling programs that use the library, since the
  119. X#                        bst.h header file defines data types that are used by
  120. X#                        these functions.
  121. X#
  122. X# -DDEBUG_RBT    :    enables code that verifies that left/right rotations do
  123. X#                        not involve the anchor of the tree. If the assertion fails,
  124. X#                        the program will be terminated.
  125. X#
  126. XDEFS                = -DBST_DEBUG -DDEBUG_RBT
  127. XDEBUG                = -g            # -g or -O
  128. XVERSION_DEF        = -DVERSION=\"DICT\ Version\ $(VERSION)\"
  129. X
  130. XCPP_DEFS            = -I$(INCLUDEDIR) $(VERSION_DEF) $(DEFS)
  131. X
  132. X#
  133. X# The following variables shouldn't need to be changed
  134. X#
  135. XLINT_FLAGS        = -hbux
  136. XCPP_FLAGS        = $(CPP_DEFS)
  137. XCC_FLAGS            = $(DEBUG)
  138. XCFLAGS            = $(CPP_FLAGS) $(CC_FLAGS)
  139. X
  140. XINSTALL            = install -c
  141. XFMODE                = -m 640            # used by install
  142. XRANLIB            = ranlib
  143. X
  144. XPAGER                = less
  145. X
  146. X
  147. XLIBNAME            = lib$(NAME).a
  148. X
  149. Xlib: $(LIBNAME)
  150. X
  151. Xlibopt: clean
  152. X    make DEBUG=-O "DEFS=$(DEFS)" lib
  153. X    $(INSTALL) $(FMODE) $(LIBNAME) $(LIBDIR)-O
  154. X
  155. X$(LIBNAME): $(OBJECTS)
  156. X    ar r $@ $?
  157. X    $(RANLIB) $@
  158. X
  159. Xlint:
  160. X    lint $(CPP_FLAGS) $(LINT_FLAGS) $(MODULE) 2>&1 | egrep -v "possible pointer alignment|RCSid" | $(PAGER)
  161. X
  162. Xinstall: $(LIBNAME)
  163. X    @if test "$(LIBDIR)" -a "$(INCLUDEDIR)" -a "$(MANDIR)" ;\
  164. X    then \
  165. X        $(INSTALL) $(FMODE) $(LIBNAME) $(LIBDIR) ;\
  166. X        echo "Installed $(LIBNAME) to $(LIBDIR)" ;\
  167. X        for i in $(INCLUDEFILES); do $(INSTALL) $(FMODE) $$i $(INCLUDEDIR) ; done ;\
  168. X        echo Installed $(INCLUDEFILES) to $(INCLUDEDIR) ;\
  169. X        for i in $(MANFILES) ; do $(INSTALL) $(FMODE) $$i $(MANDIR) ; done ;\
  170. X        echo Installed $(MANFILES) to $(MANDIR) ;\
  171. X    else \
  172. X        echo "You forgot to set one of the following variables: LIBDIR,INCLUDEDIR,MANDIR" ;\
  173. X    fi
  174. X
  175. Xuninstall:
  176. X    a=`pwd` ; cd $(INCLUDEDIR) ;\
  177. X    if test $$a != `pwd` ; then rm -f $(INCLUDEFILES) ; fi
  178. X    a=`pwd` ; cd $(LIBDIR) ;\
  179. X    if test $$a != `pwd` ; then rm -f $(LIBNAME) ; fi
  180. X    a=`pwd` ; cd $(MANDIR) ;\
  181. X    if test $$a != `pwd` ; then rm -f $(MANFILES) ; fi
  182. X
  183. Xclean:
  184. X    rm -f $(OBJECTS) $(LIBNAME) core $(TESTPROGS)
  185. X
  186. Xspotless: clean uninstall
  187. X
  188. Xtags: $(SOURCES) $(HEADERS)
  189. X    ctags -w $(SOURCES) $(HEADERS)
  190. X
  191. Xcheckout:
  192. X    co $(SOURCES) $(HEADERS) $(MANFILES)
  193. X
  194. X#
  195. X# Distribution section
  196. X# This section contains the 2 targets for distribution support: dist, dirs
  197. X# "dist" checks out all files to be distributed
  198. X# "dirs" prints a list of directories to be included in the distribution.
  199. X# These directories should have a Makefile with a "dist" target
  200. X#
  201. XDISTRIBUTION_FILES    = $(SOURCES) $(HEADERS) $(MANFILES) COPYRIGHT README \
  202. X                                dlltest.c htest.c bsttest.c bstcomp.c \
  203. X                                dlltest.out htest.out bsttest.out
  204. X
  205. XDIRS                        =
  206. X
  207. Xdist:
  208. X    -co -q $(DISTRIBUTION_FILES)
  209. X
  210. Xdirs:
  211. X    @echo $(DIRS)
  212. X
  213. X#
  214. X# PUT HERE THE RULES TO MAKE THE OBJECT FILES
  215. X#
  216. Xdll.o:        dll.h dllimpl.h dict.h dictimpl.h
  217. Xht.o:            ht.h htimpl.h dict.h dictimpl.h
  218. Xbst.o:        bst.h bstimpl.h dict.h dictimpl.h
  219. Xrbt.o:        bstimpl.h dict.h dictimpl.h
  220. Xdict.o:        dictimpl.h dict.h
  221. X
  222. Xdlltest: dlltest.c $(LIBNAME)
  223. X    cc $(CFLAGS) dlltest.c -o $@ $(LIBNAME) -L$(LIBDIR) -lfsma
  224. X
  225. Xhtest: htest.c $(LIBNAME)
  226. X    cc $(CFLAGS) -o $@ htest.c $(LIBNAME) -L$(LIBDIR) -lfsma
  227. X
  228. Xbsttest: bsttest.c $(LIBNAME)
  229. X    cc $(CFLAGS) -o $@ bsttest.c $(LIBNAME) -L$(LIBDIR) -lfsma
  230. X
  231. Xbstcomp: bstcomp.c $(LIBNAME)
  232. X    cc $(CFLAGS) -o $@ bstcomp.c $(LIBNAME) -L$(LIBDIR) -lfsma
  233. X
  234. END_OF_FILE
  235. if test 5819 -ne `wc -c <'libs/src/dict/Makefile'`; then
  236.     echo shar: \"'libs/src/dict/Makefile'\" unpacked with wrong size!
  237. fi
  238. # end of 'libs/src/dict/Makefile'
  239. fi
  240. if test -f 'libs/src/dict/rbt.c' -a "${1}" != "-c" ; then 
  241.   echo shar: Will not clobber existing file \"'libs/src/dict/rbt.c'\"
  242. else
  243. echo shar: Extracting \"'libs/src/dict/rbt.c'\" \(5816 characters\)
  244. sed "s/^X//" >'libs/src/dict/rbt.c' <<'END_OF_FILE'
  245. X/*
  246. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  247. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  248. X * and conditions for redistribution.
  249. X */
  250. X
  251. Xstatic char RCSid[] = "$Id: rbt.c,v 3.2 93/09/28 21:05:20 panos Exp $" ;
  252. X
  253. X#include "bstimpl.h"
  254. X
  255. X/*
  256. X * Transformation:
  257. X *
  258. X *        x                    y
  259. X *       / \                  / \
  260. X *      y   c     ===>       a   x
  261. X *     / \                      / \
  262. X *    a   b                    b   c
  263. X */
  264. XPRIVATE void right_rotate( hp, x )
  265. X    header_s        *hp ;
  266. X    tnode_s        *x ;
  267. X{
  268. X    tnode_s        *y        = LEFT( x ) ;
  269. X    tnode_s        *px    = PARENT( x ) ;
  270. X    tnode_s        *b        = RIGHT( y ) ;
  271. X
  272. X#ifdef DEBUG_RBT
  273. X    if ( x == ANCHOR( hp ) )
  274. X        __dict_terminate( "RBT right_rotate", "x is the tree anchor" ) ;
  275. X#endif
  276. X
  277. X    /*
  278. X     * First fix 'y' and the tree above it. We need to:
  279. X     *        a. Make x the right child of y
  280. X     *        b. Determine if x was a left or right child and update the
  281. X     *            corresponding field in x's parent.
  282. X     */
  283. X    RIGHT( y ) = x ;
  284. X    PARENT( y ) = px ;
  285. X    if ( x == LEFT( px ) )
  286. X        LEFT( px ) = y ;
  287. X    else
  288. X        RIGHT( px ) = y ;
  289. X    
  290. X    /*
  291. X     * Now fix the tree below 'y'. We need to:
  292. X     *        a. Fix the parent of 'x'
  293. X     *        b. Change the left child of 'x' to 'b'
  294. X     *        c. Change the parent of 'b' to 'x'
  295. X     */
  296. X    PARENT( x ) = y ;
  297. X    LEFT( x ) = b ;
  298. X    PARENT( b ) = x ;
  299. X}
  300. X
  301. X
  302. X
  303. X/*
  304. X * Transformation:
  305. X *
  306. X *        x                  y
  307. X *       / \                / \
  308. X *      a   y     ===>     x   c
  309. X *         / \            / \
  310. X *        b   c          a   b
  311. X */
  312. XPRIVATE void left_rotate( hp, x )
  313. X    header_s        *hp ;
  314. X    tnode_s        *x ;
  315. X{
  316. X    tnode_s        *y        = RIGHT( x ) ;
  317. X    tnode_s        *px    = PARENT( x ) ;
  318. X    tnode_s        *b        = LEFT( y ) ;
  319. X
  320. X
  321. X#ifdef DEBUG_RBT
  322. X    if ( x == ANCHOR( hp ) )
  323. X        __dict_terminate( "RBT left_rotate", "x is the tree anchor" ) ;
  324. X#endif
  325. X
  326. X    /*
  327. X     * First fix 'y' and the tree above it. We need to:
  328. X     *        a. Make x the left child of y
  329. X     *        b. Determine if x was a left or right child and update the
  330. X     *            corresponding field in x's parent.
  331. X     */
  332. X    LEFT( y ) = x ;
  333. X    PARENT( y ) = px ;
  334. X    if ( x == LEFT( px ) )
  335. X        LEFT( px ) = y ;
  336. X    else
  337. X        RIGHT( px ) = y ;
  338. X    
  339. X    /*
  340. X     * Now fix the tree below 'y'. We need to:
  341. X     *    a. Fix the parent of 'x'
  342. X     *    b. Change the right child of 'x' to 'b'
  343. X     *    c. Change the parent of 'b' to 'x'
  344. X     */
  345. X    PARENT( x ) = y ;
  346. X    RIGHT( x ) = b ;
  347. X    PARENT( b ) = x ;
  348. X}
  349. X
  350. X
  351. X/*
  352. X * This function is called after node 'new' is inserted in the tree.
  353. X * The function makes sure that the red-black properties of the tree
  354. X * are not violated by the insertion
  355. X */
  356. Xvoid __dict_rbt_insfix( hp, new )
  357. X    header_s        *hp ;
  358. X    tnode_s        *new ;
  359. X{
  360. X    register tnode_s    *x, *y ;
  361. X    register tnode_s    *px ;
  362. X    tnode_s                *ppx ;
  363. X
  364. X    x = new ;
  365. X    COLOR( x ) = RED ;
  366. X
  367. X    /*
  368. X     * Note that the color of the anchor is BLACK so the loop will
  369. X     * always stop there with x equal to the root of the tree.
  370. X     */
  371. X    while ( COLOR( px = PARENT( x ) ) == RED )
  372. X    {
  373. X        ppx = PARENT( px ) ;
  374. X        if ( px == LEFT( ppx ) )
  375. X        {
  376. X            y = RIGHT( ppx ) ;                    /* y is px's sibling and x's uncle */
  377. X            if ( COLOR( y ) == RED )            /* both px and y are red */
  378. X            {
  379. X                COLOR( px ) = BLACK ;
  380. X                COLOR( y ) = BLACK ;
  381. X                COLOR( ppx ) = RED ;                /* grandparent of x gets red */
  382. X                x = ppx ;                            /* advance x to its grandparent */
  383. X            }
  384. X            else
  385. X            {
  386. X                if ( x == RIGHT( px ) )
  387. X                    left_rotate( hp, x = px ) ;    /* notice the assignment */
  388. X                /*
  389. X                 * px cannot be used anymore because of the possible left rotation
  390. X                 * ppx however is still valid
  391. X                 */
  392. X                COLOR( PARENT( x ) ) = BLACK ;
  393. X                COLOR( ppx ) = RED ;
  394. X                right_rotate( hp, ppx ) ;
  395. X            }
  396. X        }
  397. X        else        /* px == RIGHT( ppx ) */
  398. X        {
  399. X            /*
  400. X             * XXX:    The else clause is symmetrical with the 'then' clause
  401. X             *        (RIGHT is replaced by LEFT and vice versa). We should
  402. X             *         be able to use the same code.
  403. X             */
  404. X            y = LEFT( ppx ) ;
  405. X            if ( COLOR( y ) == RED )
  406. X            {
  407. X                COLOR( px ) = BLACK ;
  408. X                COLOR( y ) = BLACK ;
  409. X                COLOR( ppx ) = RED ;
  410. X                x = ppx ;
  411. X            }
  412. X            else
  413. X            {
  414. X                if ( x == LEFT( px ) )
  415. X                    right_rotate( hp, x = px ) ;
  416. X                COLOR( PARENT( x ) ) = BLACK ;
  417. X                COLOR( ppx ) = RED ;
  418. X                left_rotate( hp, ppx ) ;
  419. X            }
  420. X        }
  421. X    }
  422. X    COLOR( ROOT( hp ) ) = BLACK ;
  423. X}
  424. X
  425. X
  426. Xvoid __dict_rbt_delfix( hp, x )
  427. X    header_s        *hp ;
  428. X    tnode_s        *x ;
  429. X{
  430. X    tnode_s        *px ;            /* parent of x */
  431. X    tnode_s        *sx ;            /* sibling of x */
  432. X
  433. X    /*
  434. X     * On exit from the loop x will be either the ROOT or a RED node
  435. X     */
  436. X    while ( x != ROOT( hp ) && COLOR( x ) == BLACK )
  437. X    {
  438. X        px = PARENT( x ) ;
  439. X        if ( x == LEFT( px ) )
  440. X        {
  441. X            sx = RIGHT( px ) ;
  442. X            if ( COLOR( sx ) == RED )
  443. X            {
  444. X                COLOR( sx ) = BLACK ;
  445. X                COLOR( px ) = RED ;
  446. X                left_rotate( hp, px ) ;
  447. X                sx = RIGHT( px ) ;
  448. X            }
  449. X
  450. X            /*
  451. X             * Now sx is BLACK
  452. X             */
  453. X            if ( COLOR( LEFT( sx ) ) == BLACK && COLOR( RIGHT( sx ) ) == BLACK )
  454. X            {
  455. X                COLOR( sx ) = RED ;
  456. X                x = px ;                                        /* move up the tree */
  457. X            }
  458. X            else
  459. X            {
  460. X                if ( COLOR( RIGHT( sx ) ) == BLACK )
  461. X                {
  462. X                    COLOR( LEFT( sx ) ) = BLACK ;        /* was RED */
  463. X                    COLOR( sx ) = RED ;
  464. X                    right_rotate( hp, sx ) ;
  465. X                    sx = RIGHT( px ) ;
  466. X                }
  467. X
  468. X                /*
  469. X                 * Now RIGHT( sx ) is RED and sx is BLACK
  470. X                 */
  471. X                COLOR( sx ) = COLOR( px ) ;
  472. X                COLOR( px ) = BLACK ;
  473. X                COLOR( RIGHT( sx ) ) = BLACK ;
  474. X                left_rotate( hp, px ) ;
  475. X                x = ROOT( hp ) ;                        /* exit the loop */
  476. X            }
  477. X        }
  478. X        else
  479. X        {
  480. X            sx = LEFT( px ) ;
  481. X            if ( COLOR( sx ) == RED )
  482. X            {
  483. X                COLOR( sx ) = BLACK ;
  484. X                COLOR( px ) = RED ;
  485. X                right_rotate( hp, px ) ;
  486. X                sx = LEFT( px ) ;
  487. X            }
  488. X
  489. X            if ( COLOR( LEFT( sx ) ) == BLACK && COLOR( RIGHT( sx ) ) == BLACK )
  490. X            {
  491. X                COLOR( sx ) = RED ;
  492. X                x = px ;
  493. X            }
  494. X            else
  495. X            {
  496. X                if ( COLOR( LEFT( sx ) ) == BLACK )
  497. X                {
  498. X                    COLOR( RIGHT( sx ) ) = BLACK ;
  499. X                    COLOR( sx ) = RED ;
  500. X                    left_rotate( hp, sx ) ;
  501. X                    sx = LEFT( px ) ;
  502. X                }
  503. X
  504. X                COLOR( sx ) = COLOR( px ) ;
  505. X                COLOR( px ) = BLACK ;
  506. X                COLOR( LEFT( sx ) ) = BLACK ;
  507. X                right_rotate( hp, px ) ;
  508. X                x = ROOT( hp ) ;
  509. X            }
  510. X        }
  511. X    }
  512. X    COLOR( x ) = BLACK ;
  513. X}
  514. X
  515. END_OF_FILE
  516. if test 5816 -ne `wc -c <'libs/src/dict/rbt.c'`; then
  517.     echo shar: \"'libs/src/dict/rbt.c'\" unpacked with wrong size!
  518. fi
  519. # end of 'libs/src/dict/rbt.c'
  520. fi
  521. if test -f 'libs/src/fsma/fsma.c' -a "${1}" != "-c" ; then 
  522.   echo shar: Will not clobber existing file \"'libs/src/fsma/fsma.c'\"
  523. else
  524. echo shar: Extracting \"'libs/src/fsma/fsma.c'\" \(6107 characters\)
  525. sed "s/^X//" >'libs/src/fsma/fsma.c' <<'END_OF_FILE'
  526. X/*
  527. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  528. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  529. X * and conditions for redistribution.
  530. X */
  531. X
  532. Xstatic char RCSid[] = "$Id: fsma.c,v 5.2 1993/09/16 22:13:12 panos Exp $" ;
  533. Xstatic char *version = VERSION ;
  534. X
  535. X#include "fsma.h"
  536. X#include "impl.h"
  537. X
  538. X#ifdef DEBUG
  539. X#include <stdio.h>
  540. X#endif
  541. X
  542. X/*
  543. X * We assume that memory handed by malloc is suitably aligned for any
  544. X * machine data type (for example, if the CPU wants double's aligned
  545. X * at an 8-byte boundary, the memory provided by malloc will be so aligned).
  546. X */
  547. Xchar *malloc() ;
  548. Xint free() ;
  549. X
  550. X
  551. XPRIVATE void init_free_list __ARGS( ( unsigned, unsigned, char * ) ) ;
  552. XPRIVATE void terminate __ARGS( ( char * ) ) ;
  553. X
  554. X
  555. X/*
  556. X * An allocator manages a linked list of chunks:
  557. X *
  558. X *        ______________            ______________            ______________
  559. X *        |   HEADER     |------>|                 |------>|                 |
  560. X *        |____________|            |____________|            |____________|
  561. X *        |                  |            |                  |            |                  |
  562. X *        |                  |            |                  |            |                  |
  563. X *        |                  |            |                  |            |                  |
  564. X *        |                  |            |                  |            |                  |
  565. X *        |     SLOTS     |            |                  |            |                  |
  566. X *        |                  |            |                  |            |                  |
  567. X *        |                  |            |                  |            |                  |
  568. X *        |                  |            |                  |            |                  |
  569. X *        |                  |            |                  |            |                  |
  570. X *        |____________|            |____________|            |____________|
  571. X *
  572. X *
  573. X * The SLOTS sections are organized as a linked list of slots whose
  574. X * size is determined by the object size specified in fsm_create
  575. X */
  576. X
  577. Xfsma_h fsm_create( object_size, slots_per_chunk, flags )
  578. X    unsigned        object_size ;
  579. X    unsigned        slots_per_chunk ;
  580. X    int            flags ;
  581. X{
  582. X    register fsma_h                fp ;
  583. X    union __fsma_chunk_header    *chp ;
  584. X    char                                *slots ;
  585. X    unsigned                            nslots ;
  586. X    unsigned                            chunk_size ;
  587. X    unsigned                            slot_size ;
  588. X    int                                header_inlined ;
  589. X
  590. X    nslots = ( slots_per_chunk == 0 ) ? SLOTS_PER_CHUNK : slots_per_chunk ;
  591. X    slot_size = ( object_size < MINSIZE ) ? MINSIZE : object_size ;
  592. X
  593. X    /*
  594. X     * Make sure that the slot_size is a multiple of the pointer size
  595. X     */
  596. X    if ( slot_size % sizeof( __fsma_pointer ) != 0 )
  597. X        slot_size += sizeof( __fsma_pointer ) -
  598. X                                slot_size % sizeof( __fsma_pointer ) ;
  599. X
  600. X    chunk_size = sizeof( union __fsma_chunk_header ) + nslots * slot_size ;
  601. X
  602. X    chp = CHUNK_HEADER( malloc( chunk_size ) ) ;
  603. X    if ( chp == NULL )
  604. X        if ( flags & FSM_RETURN_ERROR )
  605. X            return( NULL ) ;
  606. X        else
  607. X            terminate( "FSMA fsm_create: malloc failed\n" ) ;
  608. X
  609. X    slots = (char *) &chp[ 1 ] ;
  610. X    init_free_list( nslots, slot_size, slots ) ;
  611. X
  612. X#ifdef DEBUG
  613. X    {
  614. X        int i ;
  615. X
  616. X        fprintf( stderr, "Size = %d, nslots = %d\n", slot_size, nslots ) ;
  617. X        for ( i = 0 ; i < nslots+1 ; i++ )
  618. X            fprintf( stderr, "slot[ %d ] = %p\n",
  619. X                            i, (*(char **) (slots + i * slot_size ))) ;
  620. X    }
  621. X#endif
  622. X
  623. X    /*
  624. X     * Check if we can fit the header in an object slot
  625. X     */
  626. X    if ( slot_size >= sizeof( struct __fsma_header ) )
  627. X    {
  628. X        /*
  629. X         * We can do it.
  630. X         * Allocate the first slot
  631. X         */
  632. X        fp = (fsma_h) slots ;
  633. X        slots = *(POINTER *) slots ;
  634. X        header_inlined = TRUE ;
  635. X    }
  636. X    else
  637. X    {
  638. X        fp = (fsma_h) malloc( sizeof( struct __fsma_header ) ) ;
  639. X        if ( fp == NULL )
  640. X            if ( flags & FSM_RETURN_ERROR )
  641. X            {
  642. X                free( (char *) chp ) ;
  643. X                return( NULL ) ;
  644. X            }
  645. X            else
  646. X                terminate( "FSMA fsm_create: malloc of header failed\n" ) ;
  647. X        header_inlined = FALSE ;
  648. X    }
  649. X
  650. X    chp->next_chunk = NULL ;
  651. X
  652. X    fp->next_free = (POINTER) slots ;
  653. X    fp->chunk_chain = chp ;
  654. X    fp->slots_in_chunk = nslots ;
  655. X    fp->slot_size = slot_size ;
  656. X    fp->chunk_size = chunk_size ;
  657. X    fp->flags = flags ;
  658. X    fp->is_inlined = header_inlined ;
  659. X
  660. X#ifdef DEBUG
  661. X    fprintf( stderr, "Slots/chunk = %d\n", nslots ) ;
  662. X    fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
  663. X#endif
  664. X    
  665. X    return( (fsma_h) fp ) ;
  666. X}
  667. X
  668. X
  669. X
  670. Xvoid fsm_destroy( fp )
  671. X    register fsma_h fp ;
  672. X{
  673. X    int header_inlined = fp->is_inlined ;
  674. X    register union __fsma_chunk_header *chp, *next_chunk ;
  675. X    register int zero_memory = fp->flags & FSM_ZERO_DESTROY ;
  676. X    register chunk_size = fp->chunk_size ;
  677. X
  678. X    /*
  679. X     * Free all chunks in the chunk chain
  680. X     */
  681. X    for ( chp = fp->chunk_chain ; chp != NULL ; chp = next_chunk )
  682. X    {
  683. X        next_chunk = chp->next_chunk ;
  684. X        if ( zero_memory )
  685. X            (void) memset( (char *)chp, 0, chunk_size ) ;
  686. X
  687. X#ifdef DEBUG
  688. X        fprintf( stderr, "Freeing chunk %p\n", chp ) ;
  689. X#endif
  690. X        free( (char *)chp ) ;
  691. X    }
  692. X
  693. X    /*
  694. X     * If fp->inlined is NO, we have to free the handle.
  695. X     * Note that we copied fp->inlined in case it is YES.
  696. X     */
  697. X    if ( ! header_inlined )
  698. X        free( (char *)fp ) ;
  699. X}
  700. X
  701. X
  702. Xchar *_fsm_alloc( fp )
  703. X    register fsma_h fp ;
  704. X{
  705. X    register POINTER object ;
  706. X
  707. X    /*
  708. X     * Check if there are any slots on the free list
  709. X     */
  710. X    if ( fp->next_free == NULL )
  711. X    {
  712. X        /*
  713. X         * Free list exhausted; allocate a new chunk
  714. X         */
  715. X        char *slots ;
  716. X        union __fsma_chunk_header *chp ;
  717. X
  718. X        chp = CHUNK_HEADER( malloc( fp->chunk_size ) ) ;
  719. X        if ( chp == NULL )
  720. X            if ( fp->flags & FSM_RETURN_ERROR )
  721. X                return( NULL ) ;
  722. X            else
  723. X                terminate( "FSMA fsm_alloc: malloc failed\n" ) ;
  724. X
  725. X#ifdef DEBUG
  726. X        fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
  727. X#endif
  728. X        /*
  729. X         * Put the slots in this chunk in a linked list
  730. X         * and add this list to the free list
  731. X         */
  732. X        slots = (char *) &chp[ 1 ] ;
  733. X        init_free_list( fp->slots_in_chunk, fp->slot_size, slots ) ;
  734. X        fp->next_free = (POINTER) slots ;
  735. X
  736. X        /*
  737. X         * Put this chunk at the head of the chunk chain
  738. X         */
  739. X        chp->next_chunk = fp->chunk_chain ;
  740. X        fp->chunk_chain = chp ;
  741. X    }
  742. X
  743. X    object = fp->next_free ;
  744. X    fp->next_free = *(POINTER *)object ;
  745. X
  746. X    if ( fp->flags & FSM_ZERO_ALLOC )
  747. X        (void) memset( object, 0, fp->slot_size ) ;
  748. X
  749. X    return( object ) ;
  750. X}
  751. X
  752. X
  753. Xvoid _fsm_free( fp, object )
  754. X    fsma_h fp ;
  755. X    char *object ;
  756. X{
  757. X    if ( fp->flags & FSM_ZERO_FREE )
  758. X        (void) memset( object, 0, fp->slot_size ) ;
  759. X
  760. X    *(POINTER *)object = fp->next_free ;
  761. X    fp->next_free = object ;
  762. X}
  763. X
  764. X
  765. XPRIVATE void terminate( s )
  766. X    char *s ;
  767. X{
  768. X    write( 2, s, strlen( s ) ) ;
  769. X    abort() ;
  770. X    exit( 1 ) ;
  771. X}
  772. X
  773. X
  774. XPRIVATE void init_free_list( nslots, size, slots )
  775. X    unsigned nslots ;
  776. X    register unsigned size ;
  777. X    char *slots ;
  778. X{
  779. X    register int i ;
  780. X    register char *next ;
  781. X    register POINTER current ;
  782. X
  783. X    for ( i = 0, current = slots, next = slots + size ; i < nslots - 1 ;
  784. X                                                        i++, current = next, next += size )
  785. X        *(POINTER *)current = next ;
  786. X    *(POINTER *)current = NULL ;
  787. X}
  788. X
  789. END_OF_FILE
  790. if test 6107 -ne `wc -c <'libs/src/fsma/fsma.c'`; then
  791.     echo shar: \"'libs/src/fsma/fsma.c'\" unpacked with wrong size!
  792. fi
  793. # end of 'libs/src/fsma/fsma.c'
  794. fi
  795. if test -f 'libs/src/xlog/filelog.c' -a "${1}" != "-c" ; then 
  796.   echo shar: Will not clobber existing file \"'libs/src/xlog/filelog.c'\"
  797. else
  798. echo shar: Extracting \"'libs/src/xlog/filelog.c'\" \(5820 characters\)
  799. sed "s/^X//" >'libs/src/xlog/filelog.c' <<'END_OF_FILE'
  800. X/*
  801. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  802. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  803. X * and conditions for redistribution.
  804. X */
  805. X
  806. Xstatic char RCSid[] = "$Id: filelog.c,v 2.3 1993/10/28 01:35:39 panos Exp $" ;
  807. X
  808. X#include <sys/types.h>
  809. X#include <sys/stat.h>
  810. X#include <varargs.h>
  811. X#include <fcntl.h>
  812. X#include <time.h>
  813. X#ifndef NO_SYSLOG
  814. X#include <syslog.h>
  815. X#else
  816. X#define LOG_ALERT                0
  817. X#endif
  818. X
  819. X#include "sio.h"
  820. X
  821. X#include "xlog.h"
  822. X#include "impl.h"
  823. X#include "filelog.h"
  824. X
  825. XPRIVATE int filelog_init() ;
  826. XPRIVATE void filelog_fini() ;
  827. XPRIVATE int filelog_control() ;
  828. XPRIVATE int filelog_write() ;
  829. XPRIVATE int filelog_parms() ;
  830. XPRIVATE int limit_checks() ;
  831. X
  832. Xstruct xlog_ops __xlog_filelog_ops = 
  833. X    {
  834. X        filelog_init,
  835. X        filelog_fini,
  836. X        filelog_write,
  837. X        filelog_control,
  838. X        filelog_parms
  839. X    } ;
  840. X
  841. X
  842. XPRIVATE int filelog_init( xp, ap )
  843. X    xlog_s    *xp ;
  844. X    va_list    ap ;
  845. X{
  846. X    int                fd ;
  847. X    struct filelog *flp ;
  848. X    char                *filename    = va_arg( ap, char * ) ;
  849. X    int                flags            = va_arg( ap, int ) ;
  850. X
  851. X    flp = NEW( struct filelog ) ;
  852. X    if ( flp == NULL )
  853. X        return( XLOG_ENOMEM ) ;
  854. X
  855. X    if ( flags & O_CREAT )
  856. X        fd = open( filename, flags, va_arg( ap, int ) ) ;
  857. X    else
  858. X        fd = open( filename, flags ) ;
  859. X
  860. X    if ( fd == -1 )
  861. X    {
  862. X        FREE( flp ) ;
  863. X        return( XLOG_EOPEN ) ;
  864. X    }
  865. X    
  866. X    FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  867. X    (void) Sbuftype( fd, SIO_LINEBUF ) ;
  868. X    flp->fl_fd = fd ;
  869. X    flp->fl_state = FL_OPEN ;
  870. X    xp->xl_data = flp ;
  871. X    return( XLOG_ENOERROR ) ;
  872. X}
  873. X
  874. X
  875. XPRIVATE void filelog_fini( xp )
  876. X    xlog_s *xp ;
  877. X{
  878. X    struct filelog *flp = FILELOG( xp ) ;
  879. X
  880. X    if ( flp->fl_state != FL_CLOSED )
  881. X    {
  882. X        (void) close( flp->fl_fd ) ;
  883. X        flp->fl_state = FL_CLOSED ;
  884. X    }
  885. X    FREE( flp ) ;
  886. X    xp->xl_data = NULL ;
  887. X}
  888. X
  889. X
  890. X
  891. XPRIVATE int filelog_control( xp, cmd, ap )
  892. X    xlog_s        *xp ;
  893. X    xlog_cmd_e    cmd ;
  894. X    va_list        ap ;
  895. X{
  896. X    struct stat        st ;
  897. X    struct filelog *flp        = FILELOG( xp ) ;
  898. X    int                status    = XLOG_ENOERROR ;
  899. X
  900. X    if ( flp->fl_state == FL_ERROR )
  901. X        return( flp->fl_error ) ;
  902. X
  903. X    switch ( cmd )
  904. X    {
  905. X        case XLOG_GETFD:
  906. X            if ( flp->fl_state == FL_OPEN )
  907. X                *va_arg( ap, int * ) = flp->fl_fd ;
  908. X            else
  909. X                status = XLOG_ENOERROR ;
  910. X            break ;
  911. X
  912. X        case XLOG_LIMITS:
  913. X            flp->fl_soft_limit = va_arg( ap, unsigned ) ;
  914. X            flp->fl_hard_limit = va_arg( ap, unsigned ) ;
  915. X            flp->fl_issued_warning = FALSE ;
  916. X            FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
  917. X            flp->fl_state = FL_OPEN ;
  918. X            /* FALL THROUGH */
  919. X
  920. X        case XLOG_SIZECHECK:
  921. X            if ( ! FILELOG_SIZE_CONTROL( flp ) )
  922. X                break ;
  923. X            if ( fstat( flp->fl_fd, &st ) == -1 )
  924. X            {
  925. X                FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  926. X                flp->fl_state = FL_ERROR ;
  927. X                flp->fl_error = status = XLOG_EFSTAT ;
  928. X            }
  929. X            else
  930. X            {
  931. X                flp->fl_size = st.st_size ;
  932. X                if ( flp->fl_size > flp->fl_soft_limit )
  933. X                    status = limit_checks( xp ) ;
  934. X            }
  935. X            break ;
  936. X    }
  937. X    return( status ) ;
  938. X}
  939. X
  940. X
  941. XPRIVATE int limit_checks( xp )
  942. X    xlog_s *xp ;
  943. X{
  944. X    struct filelog *flp = FILELOG( xp ) ;
  945. X    char buf[ 100 ] ;
  946. X
  947. X    if ( ! flp->fl_issued_warning )
  948. X    {
  949. X        if ( xp->xl_use != NULL )
  950. X            xlog_write( (xlog_h) xp->xl_use, buf,
  951. X                strx_nprint( buf, sizeof( buf ),
  952. X                                    "soft limit exceeded on '%s'", xp->xl_id ),
  953. X                    XLOG_NOFLAGS, LOG_ALERT ) ;
  954. X        flp->fl_issued_warning = TRUE ;
  955. X    }
  956. X
  957. X    if ( flp->fl_size <= flp->fl_hard_limit )
  958. X        return( XLOG_ENOERROR ) ;
  959. X    
  960. X    if ( xp->xl_use != NULL )
  961. X        xlog_write( (xlog_h) xp->xl_use, buf,
  962. X            strx_nprint( buf, sizeof( buf ),
  963. X                        "hard limit exceeded on '%s'; log closed", xp->xl_id ),
  964. X                XLOG_NOFLAGS, LOG_ALERT ) ;
  965. X    flp->fl_state = FL_ERROR ;
  966. X    return( XLOG_ESIZE ) ;
  967. X}
  968. X
  969. X
  970. XPRIVATE int filelog_write( xp, buf, len, flags, ap )
  971. X    xlog_s    *xp ;
  972. X    char        buf[] ;
  973. X    int        len ;
  974. X    int        flags ;
  975. X    va_list    ap ;
  976. X{
  977. X    struct filelog    *flp                = FILELOG( xp ) ;
  978. X    int                 action_flags    = ( xp->xl_flags | flags ) ;
  979. X    int                msglen            = 0 ;
  980. X    char                *percent_m_pos ;
  981. X    int                cc ;
  982. X    int                status ;
  983. X    time_t             current_time ;
  984. X    struct tm        *tmp ;
  985. X    time_t            time() ;
  986. X
  987. X    if ( flp->fl_state != FL_OPEN )
  988. X        return( flp->fl_error ) ;
  989. X
  990. X    (void) time( ¤t_time ) ;
  991. X    tmp = localtime( ¤t_time ) ;
  992. X    cc = Sprint( flp->fl_fd, "%d/%d/%d@%02d:%02d:%02d",
  993. X                            tmp->tm_year, tmp->tm_mon+1, tmp->tm_mday,
  994. X                            tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
  995. X    msglen += cc ;
  996. X
  997. X    if ( action_flags & XLOG_PRINT_ID )
  998. X    {
  999. X        cc = Sprint( flp->fl_fd, " %s", xp->xl_id ) ;
  1000. X        msglen += cc ;
  1001. X    }
  1002. X
  1003. X    if ( action_flags & XLOG_PRINT_PID )
  1004. X    {
  1005. X        cc = Sprint( flp->fl_fd, "[%d]", getpid() ) ;
  1006. X        msglen += cc ;
  1007. X    }
  1008. X
  1009. X    cc = Sprint( flp->fl_fd, ": " ) ;
  1010. X    msglen += cc ;
  1011. X
  1012. X    if ( ( action_flags & XLOG_NO_ERRNO ) ||
  1013. X                        ( percent_m_pos = __xlog_add_errno( buf, len ) ) == NULL )
  1014. X    {
  1015. X        cc = Swrite( flp->fl_fd, buf, len ) ;
  1016. X        msglen += cc ;
  1017. X    }
  1018. X    else
  1019. X    {
  1020. X        char errno_buf[ 100 ] ;
  1021. X        unsigned size = sizeof( errno_buf ) ;
  1022. X        int cc_before_errno = percent_m_pos - buf ;
  1023. X        char *ep ;
  1024. X
  1025. X        /*
  1026. X         * XXX:    The reason for the repetition of "msglen += cc ;" is that in 
  1027. X         *            the future we may want to check cc for SIO_ERR
  1028. X         */
  1029. X        ep = __xlog_explain_errno( errno_buf, &size ) ;
  1030. X        cc = Swrite( flp->fl_fd, buf, cc_before_errno ) ;
  1031. X        msglen += cc ;
  1032. X        cc = Swrite( flp->fl_fd, ep, (int)size ) ;
  1033. X        msglen += cc ;
  1034. X        cc = Swrite( flp->fl_fd, percent_m_pos+2, len-cc_before_errno-2 ) ;
  1035. X        msglen += cc ;
  1036. X    }
  1037. X    /*
  1038. X     * Writing a newline will cause a buffer flush since we asked for
  1039. X     * line-buffered output
  1040. X     */
  1041. X    Sputchar( flp->fl_fd, '\n' ) ;
  1042. X    msglen++ ;
  1043. X
  1044. X    /*
  1045. X     * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->xl_flags
  1046. X     *            because size control is off by default and in order to
  1047. X     *            be enabled XLOG_LIMITS must be used which overrides xp->xl_flags
  1048. X     */
  1049. X    if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
  1050. X        return( XLOG_ENOERROR ) ;
  1051. X
  1052. X    flp->fl_size += msglen ;
  1053. X    if ( flp->fl_size <= flp->fl_soft_limit || 
  1054. X                    ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
  1055. X        return( XLOG_ENOERROR ) ;
  1056. X    
  1057. X    flp->fl_state = FL_SIZE ;
  1058. X    return( status ) ;
  1059. X}
  1060. X
  1061. X
  1062. XPRIVATE int filelog_parms( ap )
  1063. X    va_list ap ;
  1064. X{
  1065. X    return( XLOG_ENOERROR ) ;
  1066. X}
  1067. X
  1068. END_OF_FILE
  1069. if test 5820 -ne `wc -c <'libs/src/xlog/filelog.c'`; then
  1070.     echo shar: \"'libs/src/xlog/filelog.c'\" unpacked with wrong size!
  1071. fi
  1072. # end of 'libs/src/xlog/filelog.c'
  1073. fi
  1074. echo shar: End of archive 12 \(of 20\).
  1075. cp /dev/null ark12isdone
  1076. MISSING=""
  1077. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  1078.     if test ! -f ark${I}isdone ; then
  1079.     MISSING="${MISSING} ${I}"
  1080.     fi
  1081. done
  1082. if test "${MISSING}" = "" ; then
  1083.     echo You have unpacked all 20 archives.
  1084.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1085. else
  1086.     echo You still need to unpack the following archives:
  1087.     echo "        " ${MISSING}
  1088. fi
  1089. ##  End of shell archive.
  1090. exit 0
  1091.