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

  1. Newsgroups: comp.sources.unix
  2. From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v27i117: clc - C Libraries Collection, Part11/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 117
  10. Archive-Name: clc/part11
  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 11 (of 20)."
  19. # Contents:  libs/src/pq/hpq.c libs/src/pset/pset.3
  20. #   libs/src/sio/Sprint.3 libs/src/sio/impl.h libs/src/timer/timer.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/pq/hpq.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'libs/src/pq/hpq.c'\"
  25. else
  26. echo shar: Extracting \"'libs/src/pq/hpq.c'\" \(5510 characters\)
  27. sed "s/^X//" >'libs/src/pq/hpq.c' <<'END_OF_FILE'
  28. X/*
  29. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  30. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  31. X * and conditions for redistribution.
  32. X */
  33. X
  34. Xstatic char RCSid[] = "$Id: hpq.c,v 1.3 1993/04/01 02:15:46 panos Exp $" ;
  35. Xstatic char version[] = VERSION ;
  36. X
  37. X#include "pq.h"
  38. X#include "hpqimpl.h"
  39. X
  40. X#define PRIVATE            static
  41. X
  42. X#ifndef NULL
  43. X#define NULL 0
  44. X#endif
  45. X
  46. X#define PARENT( i )        ( i >> 1 )
  47. X#define LEFT( i )            ( i << 1 )
  48. X#define RIGHT( i )        ( LEFT( i ) + 1 )
  49. X
  50. Xint pq_errno ;
  51. X
  52. X#define INITIAL_ARRAY_SIZE                100                /* entries */
  53. X
  54. X
  55. Xpq_h __hpq_create( func, flags, errnop )
  56. X    int (*func)() ;
  57. X    int flags ;
  58. X    int *errnop ;
  59. X{
  60. X    register header_s *hp ;
  61. X    int *errp = ( errnop == NULL ) ? &pq_errno : errnop ;
  62. X    char *malloc() ;
  63. X
  64. X    /*
  65. X     * Check if the user has provided the necessary comparison functions
  66. X     */
  67. X    if ( func == NULL )
  68. X        HANDLE_ERROR( flags, NULL, errp, PQ_ENOFUNC,
  69. X                "HPQ __hpq_create: missing object-object comparator\n" ) ;
  70. X
  71. X    hp = HHP( malloc( sizeof( header_s ) ) ) ;
  72. X    if ( hp == NULL )
  73. X        HANDLE_ERROR( flags, NULL, errp, PQ_ENOMEM,
  74. X                                                "HPQ __hpq_create: malloc failed\n" ) ;
  75. X    
  76. X    /*
  77. X     * Allocate object array
  78. X     */
  79. X    hp->objects = (pq_obj *) malloc( INITIAL_ARRAY_SIZE * sizeof( pq_obj ) ) ;
  80. X    if ( hp->objects == NULL )
  81. X    {
  82. X        free( (char *)hp ) ;
  83. X        HANDLE_ERROR( flags, NULL, errp, PQ_ENOMEM, 
  84. X                                                "HPQ __hpq_create: malloc failed\n" ) ;
  85. X    }
  86. X
  87. X    /*
  88. X     * Initialize the header
  89. X     */
  90. X    hp->is_better = func ;
  91. X    hp->errnop = errp ;
  92. X    hp->flags = flags ;
  93. X    hp->max_size = INITIAL_ARRAY_SIZE ;
  94. X    hp->cur_size = 0 ;
  95. X    return( (pq_h) hp ) ;
  96. X}
  97. X
  98. X
  99. Xvoid __hpq_destroy( handle )
  100. X    pq_h handle ;
  101. X{
  102. X    header_s *hp = HHP( handle ) ;
  103. X
  104. X    free( (char *) hp->objects ) ;
  105. X    free( (char *)hp ) ;
  106. X}
  107. X
  108. X
  109. Xint __hpq_insert( handle, object )
  110. X    pq_h handle ;
  111. X    pq_obj object ;
  112. X{
  113. X    register header_s *hp = HHP( handle ) ;
  114. X    register unsigned i, parent ;
  115. X
  116. X    if ( object == NULL )
  117. X        HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENULLOBJECT,
  118. X                                            "HPQ __hpq_insert: NULL object\n" ) ;
  119. X
  120. X    /*
  121. X     * Make sure there is room to store the object
  122. X     */
  123. X    if ( hp->cur_size >= hp->max_size && grow( hp ) == PQ_ERR )
  124. X        return( PQ_ERR ) ;
  125. X
  126. X    i = hp->cur_size++ ;
  127. X    parent = PARENT( i ) ;
  128. X    while ( i > 0 && (*hp->is_better)( object, hp->objects[ parent ] ) )
  129. X    {
  130. X        hp->objects[ i ] = hp->objects[ parent ] ;
  131. X        i = parent ;
  132. X        parent = PARENT( i ) ;
  133. X    }
  134. X    hp->objects[ i ] = object ;
  135. X    return( PQ_OK ) ;
  136. X}
  137. X
  138. X
  139. X#define CUTOFF                                (INITIAL_ARRAY_SIZE * 128)
  140. X#define INCREMENT                            CUTOFF
  141. X
  142. X/*
  143. X * Grow the table.
  144. X * Algorithm:
  145. X *            while the table_size is less than CUTOFF, double the size.
  146. X *         if it grows greater than CUTOFF, increase the size by INCREMENT
  147. X *            (these number are in entries, not bytes)
  148. X */
  149. XPRIVATE int grow( hp )
  150. X    header_s *hp ;
  151. X{
  152. X    unsigned new_size ;
  153. X    char *new_objects ;
  154. X    char *realloc() ;
  155. X
  156. X    if ( hp->max_size < CUTOFF )
  157. X        new_size = hp->max_size * 2 ;
  158. X    else
  159. X        new_size = hp->max_size + INCREMENT ;
  160. X
  161. X    new_objects = realloc( (char *)hp->objects, new_size * sizeof( pq_obj ) ) ;
  162. X    if ( new_objects == NULL )
  163. X        HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENOMEM,
  164. X                                        "HPQ grow: out of memory\n" ) ;
  165. X    
  166. X    hp->max_size = new_size ;
  167. X    hp->objects = (pq_obj *) new_objects ;
  168. X    return( PQ_OK ) ;
  169. X}
  170. X
  171. X
  172. Xpq_obj __hpq_extract_head( handle )
  173. X    pq_h handle ;
  174. X{
  175. X    register header_s *hp = HHP( handle ) ;
  176. X    pq_obj object ;
  177. X    void restore_heap() ;
  178. X
  179. X    if ( hp->cur_size == 0 )
  180. X        return( NULL ) ;
  181. X    
  182. X    object = hp->objects[ 0 ] ;
  183. X    hp->objects[ 0 ] = hp->objects[ --hp->cur_size ] ;
  184. X    restore_heap( hp, 0 ) ;
  185. X    return( object ) ;
  186. X}
  187. X
  188. X
  189. X#define EXISTS( hp, i )                ( i < hp->cur_size )
  190. X#define IS_BETTER( hp, i, j )        \
  191. X            ( (*hp->is_better)( hp->objects[ i ], hp->objects[ j ] ) )
  192. X#define SWAP( hp, i, j )                                \
  193. X        {                                                        \
  194. X            pq_obj t = hp->objects[ i ] ;                \
  195. X            hp->objects[ i ] = hp->objects[ j ] ;    \
  196. X            hp->objects[ j ] = t ;                        \
  197. X        }
  198. X
  199. XPRIVATE void restore_heap( hp, start )
  200. X    register header_s *hp ;
  201. X    unsigned start ;
  202. X{
  203. X    register unsigned current = start ;
  204. X    register unsigned better = current ;
  205. X
  206. X    for ( ;; )
  207. X    {
  208. X        register unsigned left = LEFT( current ) ;
  209. X        register unsigned right = RIGHT( current ) ;
  210. X
  211. X        /*
  212. X         * Meaning of variables:
  213. X         *
  214. X         *        current:        the current tree node
  215. X         *        left:            its left child
  216. X         *        right:        its right child
  217. X         *        better:         the best of current,left,right
  218. X         *
  219. X         * We start the loop with better == current
  220. X         *
  221. X         * The code takes advantage of the fact that the existence of
  222. X         * the right child implies the existence of the left child.
  223. X         * It works by finding the better of the two children (and puts
  224. X         * that in better) and comparing that against current.
  225. X         */
  226. X        if ( EXISTS( hp, right ) )
  227. X            better = IS_BETTER( hp, left, right ) ? left : right ;
  228. X        else if ( EXISTS( hp, left ) )
  229. X            better = left ;
  230. X
  231. X        if ( better == current || IS_BETTER( hp, current, better ) )
  232. X            break ;
  233. X        else 
  234. X        {
  235. X            SWAP( hp, current, better ) ;
  236. X            current = better ;
  237. X        }
  238. X    }
  239. X}
  240. X
  241. X
  242. Xint __hpq_delete( handle, object )
  243. X    pq_h handle ;
  244. X    register pq_obj object ;
  245. X{
  246. X    register header_s *hp = HHP( handle ) ;
  247. X    register unsigned i ;
  248. X
  249. X    if ( object == NULL )
  250. X        HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENULLOBJECT,
  251. X                                            "HPQ __hpq_delete: NULL object\n" ) ;
  252. X
  253. X    /*
  254. X     * First find it
  255. X     */
  256. X    for ( i = 0 ;; i++ )
  257. X    {
  258. X        if ( i < hp->cur_size )
  259. X            if ( object == hp->objects[ i ] )
  260. X                break ;
  261. X            else
  262. X                continue ;
  263. X        else
  264. X            HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENOTFOUND,
  265. X                    "HPQ __hpq_delete: object not found\n" ) ;
  266. X    }
  267. X
  268. X    hp->objects[ i ] = hp->objects[ --hp->cur_size ] ;
  269. X    restore_heap( hp, i ) ;
  270. X    return( PQ_OK ) ;
  271. X}
  272. X
  273. END_OF_FILE
  274. if test 5510 -ne `wc -c <'libs/src/pq/hpq.c'`; then
  275.     echo shar: \"'libs/src/pq/hpq.c'\" unpacked with wrong size!
  276. fi
  277. # end of 'libs/src/pq/hpq.c'
  278. fi
  279. if test -f 'libs/src/pset/pset.3' -a "${1}" != "-c" ; then 
  280.   echo shar: Will not clobber existing file \"'libs/src/pset/pset.3'\"
  281. else
  282. echo shar: Extracting \"'libs/src/pset/pset.3'\" \(5592 characters\)
  283. sed "s/^X//" >'libs/src/pset/pset.3' <<'END_OF_FILE'
  284. X.\"(c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  285. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  286. X.\"and conditions for redistribution.
  287. X.\"
  288. X.\" $Id: pset.3,v 3.5 93/11/23 19:46:44 panos Exp $
  289. X.TH PSET 3X "23 April 1993"
  290. X.SH NAME
  291. Xpset_create, pset_destroy, pset_add, pset_insert, pset_remove, pset_delete, pset_remove_index, pset_clear, pset_count, pset_pointer, pset_compact, pset_sort, pset_apply - routines that handle pointer sets
  292. X.SH SYNOPSIS
  293. X.LP
  294. X.nf
  295. X.ft B
  296. X#include "pset.h"
  297. X.LP
  298. X.ft B
  299. Xpset_h pset_create( alloc_start, alloc_step )
  300. Xunsigned alloc_start, alloc_step ;
  301. X.LP
  302. X.ft B
  303. Xvoid pset_destroy( pset )
  304. Xpset_h pset ;
  305. X.LP
  306. X.ft B
  307. XANY_TYPE *pset_add( pset, ptr )
  308. Xpset_h pset ;
  309. XANY_TYPE *ptr ;
  310. X.LP
  311. X.ft B
  312. Xvoid *pset_insert( pset, ptr )
  313. Xpset_h pset ;
  314. Xvoid *ptr ;
  315. X.LP
  316. X.ft B
  317. Xvoid pset_remove( pset, ptr )
  318. Xpset_h pset ;
  319. XANY_TYPE *ptr ;
  320. X.LP
  321. X.ft B
  322. Xvoid pset_delete( pset, ptr )
  323. Xpset_h pset ;
  324. Xvoid *ptr ;
  325. X.LP
  326. X.ft B
  327. Xvoid pset_remove_index( pset, index )
  328. Xpset_h pset ;
  329. Xunsigned index ;
  330. X.LP
  331. X.ft B
  332. Xvoid pset_clear( pset )
  333. Xpset_h pset ;
  334. X.LP
  335. X.ft B
  336. Xunsigned pset_count( pset )
  337. Xpset_h pset ;
  338. X.LP
  339. X.ft B
  340. Xvoid *pset_pointer( pset, index )
  341. Xpset_h pset ;
  342. Xunsigned index ;
  343. X.LP
  344. X.ft B
  345. Xvoid pset_compact( pset )
  346. Xpset_h pset ;
  347. X.LP
  348. X.ft B
  349. Xvoid pset_sort( pset, compfunc )
  350. Xpset_h pset ;
  351. Xint (*compfunc)() ;
  352. X.LP
  353. X.ft B
  354. Xvoid pset_apply( pset, func, arg )
  355. Xpset_h pset ;
  356. Xvoid (*func)() ;
  357. Xvoid *arg ;
  358. X.SH DESCRIPTION
  359. XThis library provides functions that handle sets of pointers. Pointers
  360. Xcan be inserted and deleted from sets and the sets can be enumerated.
  361. XPointers are inserted in sets in no particular order. However it is 
  362. Xguaranteed
  363. Xthat a sequence of insertions will result in a set which if enumerated
  364. Xwill provide the pointers in the same order in which they were inserted
  365. X(assuming no intervening deletions).
  366. X.LP
  367. X.B pset_create()
  368. Xcreates a pointer set.
  369. XIt will allocate space for
  370. X.I alloc_start
  371. Xpointers before returning.
  372. X.I alloc_step
  373. Xdetermines the amount by which the set size is increased in case of
  374. Xoverflow. If any of these parameters is 0, a default value is used.
  375. X.LP
  376. X.B pset_destroy()
  377. Xdestroys the specified pointer set.
  378. X.LP
  379. X.B pset_add()
  380. Xis a macro that adds a pointer to the specified set.
  381. XThe pointer can be of any type.
  382. X.LP
  383. X.B pset_insert()
  384. Xinserts a pointer to the specified set.
  385. XThis is the same operation as
  386. X.B pset_add().
  387. X.LP
  388. X.B pset_remove()
  389. Xremoves a pointer from the specified set.
  390. X.LP
  391. X.B pset_delete()
  392. Xdeletes a pointer from the specified set.
  393. XThis is the same operation as
  394. X.B pset_remove().
  395. X.LP
  396. X.B pset_remove_index()
  397. Xremoves the pointer that is at position
  398. X.I index
  399. Xin the set.
  400. X.I index
  401. Xshould be in the range [0, \fBpset_count(pset)\fP) (but there is no
  402. Xcheck to enforce this).
  403. XAfter this operation, the
  404. X.I index
  405. Xposition will be occupied by another pointer (unless it was the last one).
  406. XNote that this call is a macro, and it may evaluate the
  407. X.I index
  408. Xargument more than once.
  409. X.LP
  410. X.B pset_clear()
  411. Xremoves all pointers from the specified set.
  412. X.LP
  413. X.B pset_count()
  414. Xreturns the number of pointers in the specified set.
  415. X.LP
  416. X.B pset_pointer()
  417. Xreturns the pointer at position
  418. X.I index
  419. Xin the specified set.
  420. X.I index
  421. Xmust be between 0 and
  422. X.B "pset_count(pset)."
  423. X.B pset_pointer()
  424. Xis a macro and it can also be used in the left-hand side of assignments.
  425. X.LP
  426. X.B pset_compact()
  427. Xremoves all NULL pointers from
  428. X.I pset.
  429. X.LP
  430. X.B pset_sort()
  431. Xsorts the pointers in
  432. X.I pset
  433. Xusing the specified function.
  434. X.I compfunc
  435. Xis invoked with 2 arguments that are pointers pointing to pointers stored in 
  436. X.I pset.
  437. XFor example, if the pset holds pointers to objects of type T, then
  438. Xthe function F whose address is in
  439. X.I compfunc
  440. Xshould be defined as:
  441. XF( T **p1, T **p2 ).
  442. X.br
  443. X.I compfunc 
  444. Xshould return a negative, zero or positive value 
  445. Xif its first argument is less than, equal to, or greater than its
  446. Xsecond argument.
  447. X.LP
  448. X.B pset_apply()
  449. Xapplies
  450. X.I func
  451. Xto all pointers in
  452. X.I pset.
  453. XIf 
  454. X.I arg
  455. Xis not
  456. X.SM NULL
  457. Xthe function is invoked as:
  458. X.RS
  459. X(*func)( arg, p )
  460. X.RE
  461. Xwhere
  462. X.I p
  463. Xis a pset pointer.  If 
  464. X.I arg
  465. Xis
  466. X.SM NULL
  467. Xthe function is invoked as:
  468. X.RS
  469. X(*func)( p )
  470. X.RE
  471. X.SH EXAMPLE
  472. XThe following code fragment reads lines from standard input
  473. Xand places them in a pset. Then it sorts the pset, prints the
  474. Xsorted contents to standard output and then it eliminates duplicate
  475. Xlines (which it also prints to standard output).
  476. X.RS
  477. X.sp 1
  478. X.ft B
  479. X.nf
  480. Xpset_h ph ;
  481. Xchar buf[ 80 ] ;
  482. Xunsigned u ;
  483. Xint compstr() ;
  484. Xvoid printstr() ;
  485. X.sp 1
  486. Xph = pset_create( 0, 0 ) ;
  487. Xwhile ( gets( buf ) )
  488. X.RS
  489. Xpset_add( strcpy( malloc( strlen( buf ) + 1 ), buf ) ) ;
  490. X.RE
  491. Xpset_sort( ph, compstr ) ;
  492. Xfor ( u = 0 ; u < pset_count( ph ) ; u++ )
  493. X.RS
  494. Xprintf( "%s\\n", (char *) pset_pointer( ph, u ) ) ;
  495. X.RE
  496. X.RE
  497. X.fi
  498. X.ft R
  499. X.LP
  500. XThe function
  501. X.I compstr()
  502. Xfollows:
  503. X.sp 1
  504. X.RS
  505. X.ft B
  506. X.nf
  507. Xint compstr( p1, p2 )
  508. X.RS
  509. Xchar **p1, **p2 ;
  510. X.RE
  511. X{
  512. X.RS
  513. Xreturn( strcmp( *p1, *p2 ) ) ;
  514. X.RE
  515. X}
  516. X.RE
  517. X.SH "RETURN VALUES"
  518. X.LP
  519. X.I pset_h
  520. Xis a pointer type. Functions that return
  521. X.I pset_h
  522. Xwill return
  523. X.SM NULL
  524. Xto indicate an error.
  525. X.LP
  526. X.B pset_create()
  527. Xreturns a pointer set handle or
  528. X.SM NULL
  529. Xif it fails.
  530. X.LP
  531. X.B pset_add()
  532. Xreturns its second argument if successful or
  533. X.SM NULL
  534. Xif it fails.
  535. X.LP
  536. X.B pset_insert()
  537. Xreturns its second argument if successful or
  538. X.SM NULL
  539. Xif it fails.
  540. X.LP
  541. X.B pset_count()
  542. Xalways returns the number of pointers in the set.
  543. X.LP
  544. X.B pset_pointer()
  545. Xalways returns a pointer. There is no check if the specified index is within
  546. Xrange.
  547. X.SH BUGS
  548. X.LP
  549. X.B pset_add(),
  550. X.B pset_remove(),
  551. X.B pset_remove_index(),
  552. X.B pset_count(),
  553. X.B pset_clear(),
  554. X.B pset_pointer()
  555. Xand 
  556. X.B pset_sort()
  557. Xare macros, therefore the \fI&\fR operator cannot be applied to them.
  558. END_OF_FILE
  559. if test 5592 -ne `wc -c <'libs/src/pset/pset.3'`; then
  560.     echo shar: \"'libs/src/pset/pset.3'\" unpacked with wrong size!
  561. fi
  562. # end of 'libs/src/pset/pset.3'
  563. fi
  564. if test -f 'libs/src/sio/Sprint.3' -a "${1}" != "-c" ; then 
  565.   echo shar: Will not clobber existing file \"'libs/src/sio/Sprint.3'\"
  566. else
  567. echo shar: Extracting \"'libs/src/sio/Sprint.3'\" \(5277 characters\)
  568. sed "s/^X//" >'libs/src/sio/Sprint.3' <<'END_OF_FILE'
  569. X.\"(c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  570. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  571. X.\"and conditions for redistribution.
  572. X.\"
  573. X.\" $Id: Sprint.3,v 8.1 1993/03/13 01:15:34 panos Exp $
  574. X.TH Sprint 3X "29 May 1992"
  575. X.SH NAME
  576. XSprint -- formatted stream output
  577. X.SH SYNOPSIS
  578. X.LP
  579. X.nf
  580. X.ft B
  581. Xint Sprint( fd, format [ , ... ] )
  582. Xint fd ;
  583. Xchar *format ;
  584. X.SH DESCRIPTION
  585. X\fBSprint()\fR provides formatted output conversion. The formatting is
  586. Xcontrolled by the \fIformat\fR argument. All characters in
  587. X\fIformat\fR that do not specify a conversion are printed. A conversion
  588. Xis specified by a '%' followed by a string that ends with a
  589. Xconversion type character. The string may contain flags, a field width,
  590. Xa precision, and a modifier.
  591. X.LP
  592. XPossible flags (more that one can be specified and they can be in any order)
  593. Xinclude:
  594. X.TP 10
  595. X.B \'-'
  596. Xspecifies left adjustment of the converted argument. The default
  597. Xis right adjustment. This flag is meaningful only if a field width
  598. Xis specified.
  599. X.TP
  600. X.B \'+'
  601. Xspecifies that a number will always have a sign as a prefix (this
  602. Xforces a '+' sign to appear if the number is positive).
  603. X.TP
  604. X.B \' '
  605. Xprefixes a \fIspace\fR to the number if the number has not a sign
  606. X(therefore the '+' flag overrides this flag).
  607. X.TP
  608. X.B \'#'
  609. XThe meaning of '#' depends on the conversion type character: for \fBo\fR 
  610. Xconversions the first digit will be 0; for \fBx\fR or \fBX\fR conversions
  611. X\fB0x\fR or \fB0X\fR respectively will be prefixed to the number (if it
  612. Xis not zero); for \fBe\fR, \fBE\fR, \fBf\fR, \fBg\fR, and \fBG\fR conversions
  613. Xthe number will always have a decimal point.
  614. X.TP
  615. X.B \'0'
  616. Xspecifies padding with zeros instead of spaces.
  617. X.LP
  618. XThe field width is specified by a number. This number indicates the
  619. X\fIminimum\fR width for the field. A '*' may be used instead of the number.
  620. XIn that case the width is the value of the next argument which should
  621. Xbe an \fBint\fR. 
  622. XA negative width value specifies left adjustment with a width equal
  623. Xto the absolute width value.
  624. X.LP
  625. XA precision is specified by a '.' followed by a number. The meaning of
  626. Xthe precision depends on the type conversion character. For a string
  627. Xconversion, precision determines how many characters are printed from
  628. Xthe string. For integer conversions, precision determines the 
  629. Xnumber of digits used to print the number (zero padding is done if
  630. Xthe precision exceeds the length of the number). For floating point
  631. Xconversions, precision determines the number of digits after the
  632. Xdecimal point (\fBe\fR, \fBE\fR, \fBf\fR) or the number of
  633. Xsignificant digits (\fBg\fR, \fBG\fR).
  634. XA '*' may be used instead of a number to specify the precision. In that
  635. Xcase the precision is the value of the next argument which should
  636. Xbe an \fBint\fR.
  637. XThe behavior of \fBSprint()\fR is undefined if the precision is negative.
  638. X.LP
  639. XThe length modifier is \fBl\fR and indicates that the argument is
  640. Xa \fBlong\fR integer.
  641. X.LP
  642. XThe type conversion characters are:
  643. X\fBd, i, o, x, X, u, c, s, f, e, E, g, G, p, n, %\fR.
  644. XFor floating point conversions the argument should be of type \fIdouble\fR.
  645. X.TP 10
  646. X.B d,i
  647. Xspecify signed decimal conversion.
  648. X.TP
  649. X.B u
  650. Xspecifies unsigned decimal conversion.
  651. X.TP
  652. X.B o
  653. Xspecifies octal conversion.
  654. X.TP
  655. X.B x,X
  656. Xspecify hexadecimal conversion. For 
  657. X.B x
  658. Xthe hex digits used are 0123456789abcdef. For
  659. X.B X
  660. Xthe hex digits used are 0123456789ABCDEF.
  661. XThere is no leading
  662. X.B 0x
  663. Xor
  664. X.B 0X
  665. X(use the '#' flag for that).
  666. X.TP
  667. X.B c
  668. Xspecifies character conversion; the argument should be of type
  669. X\fIchar\fR.
  670. X.TP
  671. X.B s
  672. Xspecifies string conversion; the argument should be of type
  673. X\fIchar *\fR.
  674. X.TP
  675. X.B f
  676. Xspecifies conversion to the form [-]ddd.dddd. The number
  677. Xof digits after the decimal point depends on precision; the default is 6.
  678. XIf the precision is 0, the decimal point is not printed (this can
  679. Xbe overriden with the '#' flag).
  680. X.B e,E
  681. Xspecify conversion to the form [-]ddd.dddd[eE][+-]ddd.
  682. XThe number of digits after the decimal point depends on precision;
  683. Xthe default is 6. If the precision is 0, the decimal point is not printed
  684. X(this can be overriden with the '#' flag).
  685. XThe exponent is at least 2 digit wide.
  686. X.TP
  687. X.B g,G
  688. Xspecify a conversion using the
  689. X.B e,E
  690. Xformat respectively if the
  691. Xexponent is less than -4 or greater than or equal to the precision;
  692. Xotherwise the 
  693. X.B f
  694. Xformat is used.
  695. X.TP
  696. X.B p
  697. Xis used to print pointers (type \fIvoid *\fR,
  698. Xor \fIchar *\fR if the compiler does not support the former).
  699. X.TP
  700. X.B n
  701. Xexpects a \fIint *\fR argument and puts in that integer 
  702. Xthe number of characters already printed by this call.
  703. X.TP
  704. X.B %
  705. Xis used to print a \fI%\fR.
  706. X.LP
  707. XIf an unknown conversion character is specified, the percent sign
  708. Xfollowed by that character will be printed.
  709. X.SH RETURN VALUE
  710. X.LP
  711. XIf no error occured, \fBSprint()\fR returns the number of characters
  712. Xprinted. In case of error, it returns \fBSIO_ERR\fR.
  713. X.SH BUGS
  714. X.LP
  715. XThis is a list of differences between \fBSprint()\fR and the ANSI C Standard
  716. X\fBprintf()\fR:
  717. X.LP
  718. X\fBSprint()\fR does not support non-removal of trailing zeroes for
  719. X\fBg\fR and \fBG\fR conversions when the '#' flag is used.
  720. X.LP
  721. X\fBSprint()\fR does not support the h and L modifiers.
  722. X.LP
  723. XThe current implementation assumes that \fIsizeof(int)==sizeof(long)\fR.
  724. X.LP
  725. X\fBSprint()\fR supports "%p" only if \fIsizeof(pointer)<=sizeof(int)\fR.
  726. END_OF_FILE
  727. if test 5277 -ne `wc -c <'libs/src/sio/Sprint.3'`; then
  728.     echo shar: \"'libs/src/sio/Sprint.3'\" unpacked with wrong size!
  729. fi
  730. # end of 'libs/src/sio/Sprint.3'
  731. fi
  732. if test -f 'libs/src/sio/impl.h' -a "${1}" != "-c" ; then 
  733.   echo shar: Will not clobber existing file \"'libs/src/sio/impl.h'\"
  734. else
  735. echo shar: Extracting \"'libs/src/sio/impl.h'\" \(5528 characters\)
  736. sed "s/^X//" >'libs/src/sio/impl.h' <<'END_OF_FILE'
  737. X/*
  738. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  739. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  740. X * and conditions for redistribution.
  741. X */
  742. X
  743. X/*
  744. X * $Id: impl.h,v 8.1 1993/03/13 01:15:06 panos Exp $
  745. X */
  746. X
  747. X#ifndef SIO_BUFFER_SIZE
  748. X
  749. X#include "sioconf.h"
  750. X
  751. X#ifdef HAS_MMAP
  752. X#include <sys/types.h>
  753. X
  754. X
  755. X/*
  756. X * A struct map_unit describes a memory mapped area of a file.
  757. X *
  758. X * addr is the address where the file is mapped. If addr is NULL
  759. X * the other fields are meaningless.
  760. X * valid_bytes indicates how many bytes are _valid_ in that unit
  761. X * mapped_bytes of a unit is how many bytes are mapped in that
  762. X * unit ( valid <= mapped ).
  763. X * Normally mapped_bytes will be equal to valid_bytes until
  764. X * we reach the end of the file. Then if the file size is not a multiple
  765. X * of the unit size, only the rest of the file will be mapped at the
  766. X * unit, leaving part of what was mapped at the unit before still
  767. X * visible (this happens because I chose not to unmap a unit before
  768. X * remapping it). In that case valid_bytes shows the size of the "new"
  769. X * mapping and mapped_bytes shows how many bytes are really mapped.
  770. X * mapped_bytes is used in Sdone() to unmap the units.
  771. X */
  772. Xstruct map_unit
  773. X{
  774. X    caddr_t addr ;
  775. X    size_t valid_bytes ;
  776. X    size_t mapped_bytes ;
  777. X} ;
  778. X
  779. X
  780. X/*
  781. X * Meaning of fields used when memory mapping:
  782. X *
  783. X *    file_offset:      it is the offset in the file where the next
  784. X *                      mapping should be done
  785. X *
  786. X *    file_size:        size of the file (obtained from stat(2))
  787. X */
  788. Xstruct mmap_descriptor
  789. X{
  790. X   off_t file_offset ;
  791. X   off_t file_size ;
  792. X    struct map_unit first_unit ;
  793. X    struct map_unit second_unit ;
  794. X} ;
  795. X
  796. Xtypedef struct mmap_descriptor mapd_s ;
  797. X
  798. X#endif /* HAS_MMAP */
  799. X
  800. Xtypedef enum { FAILURE, SUCCESS } status_e ;
  801. X
  802. X/*
  803. X * Descriptor management: convert a descriptor pointer to an input or
  804. X * output descriptor pointer
  805. X */
  806. X#define IDP( dp )                        (&(dp)->descriptor.input_descriptor)
  807. X#define ODP( dp )                        (&(dp)->descriptor.output_descriptor)
  808. X
  809. X#define DESCRIPTOR_INITIALIZED( dp )    ((dp)->initialized)
  810. X
  811. X/*
  812. X * Internal constants
  813. X */
  814. X#define SIO_BUFFER_SIZE           8192
  815. X#define SIO_NO_TIED_FD                (-1)
  816. X
  817. Xtypedef enum { NO = 0, YES = 1 } boolean_e ;
  818. X
  819. X#ifndef FALSE
  820. X#define FALSE            0
  821. X#define TRUE            1
  822. X#endif
  823. X
  824. X#ifndef NULL
  825. X#define NULL            0
  826. X#endif
  827. X
  828. X#ifdef MIN
  829. X#undef MIN
  830. X#endif
  831. X#define MIN( a, b )                    ( (a) < (b) ? (a) : (b) )
  832. X
  833. X#define NUL                                '\0'
  834. X
  835. X#define PRIVATE                        static
  836. X
  837. X#ifdef DEBUG
  838. X
  839. Xstatic char *itoa( num )
  840. X    unsigned num ;
  841. X{
  842. X#define NUMBUF_SIZE        15
  843. X    static char numbuf[ NUMBUF_SIZE ] ;
  844. X    register char *p = &numbuf[ NUMBUF_SIZE ] ;
  845. X
  846. X    *--p = '\0' ;
  847. X    do
  848. X    {
  849. X        *--p = num % 10 + '0' ;
  850. X        num /= 10 ;
  851. X    }
  852. X    while ( num ) ;
  853. X    return( p ) ;
  854. X}
  855. X
  856. X#    define ASSERT( expr )                                                        \
  857. X        if ( ! (expr) )                                                            \
  858. X        {                                                                                \
  859. X            char *s1 = "SIO assertion << expr >> failed: File: " ;    \
  860. X            char *s2 = __FILE__ ;                                                \
  861. X            char *s3 = ", line: " ;                                                \
  862. X            char *s4 = itoa( __LINE__ ) ;                                        \
  863. X            char *s5 = "\n" ;                                                        \
  864. X            (void) write( 2, s1, strlen( s1 ) ) ;                            \
  865. X            (void) write( 2, s2, strlen( s2 ) ) ;                            \
  866. X            (void) write( 2, s3, strlen( s3 ) ) ;                            \
  867. X            (void) write( 2, s4, strlen( s4 ) ) ;                            \
  868. X            (void) write( 2, s5, strlen( s5 ) ) ;                            \
  869. X            exit ( 1 ) ;                                                            \
  870. X        }
  871. X#else
  872. X#    define ASSERT( expr )
  873. X#endif
  874. X
  875. X
  876. X#include <errno.h>
  877. Xextern int errno ;
  878. X
  879. X/*
  880. X * IO_SETUP initializes a descriptor if it is not already initialized.
  881. X * It checks if the stream is of the right type (input or output).
  882. X * CONTROL_SETUP checks if the descriptor is initialized and if the
  883. X * stream is of the right type (input or output). 
  884. X *
  885. X *     fd: file descriptor
  886. X *     dp: descriptor pointer
  887. X *     op: operation
  888. X *     ev: error value (if __sio_init fails; __sio_init should set errno) 
  889. X *
  890. X * IO_SETUP will call __sio_init if the descriptor is not initialized.
  891. X * Possible errors:
  892. X *        1. Using CONTROL_SETUP on an uninitialized descriptor.
  893. X *        2. The operation is not appropriate for the descriptor (e.g.
  894. X *            a read operation on an descriptor used for writing). 
  895. X * Both errors set errno to EBADF.
  896. X */
  897. X#define CONTROL_SETUP( dp, type, ev )                                                        \
  898. X            {                                                                                            \
  899. X                if ( ! DESCRIPTOR_INITIALIZED( dp ) || dp->stream_type != type )    \
  900. X                {                                                                                        \
  901. X                    errno = EBADF ;                                                                \
  902. X                    return( ev ) ;                                                                    \
  903. X                }                                                                                        \
  904. X            }
  905. X
  906. X
  907. X#define IO_SETUP( fd, dp, type, ev )                                                        \
  908. X            {                                                                                            \
  909. X                if ( DESCRIPTOR_INITIALIZED( dp ) )                                         \
  910. X                {                                                                                        \
  911. X                    if ( dp->stream_type != type )                                            \
  912. X                    {                                                                                    \
  913. X                        errno = EBADF ;                                                            \
  914. X                        return( ev ) ;                                                                \
  915. X                    }                                                                                    \
  916. X                }                                                                                        \
  917. X                else if ( __sio_init( dp, fd, type ) == SIO_ERR )                        \
  918. X                    return( ev ) ;                                                                    \
  919. X            }
  920. X
  921. X
  922. X/*
  923. X * Internal functions that are visible
  924. X */
  925. Xint __sio_readf(), __sio_writef(), __sio_pwritef() ;
  926. Xint __sio_extend_buffer(), __sio_init(), __sio_converter(), __sio_more() ;
  927. Xstatus_e __sio_switch() ;
  928. X
  929. X
  930. X#ifdef HAS_MEMOPS
  931. X#include <memory.h>
  932. X#define sio_memcopy( from, to, nbytes )       (void) memcpy( to, from, nbytes )
  933. X#define sio_memscan( from, nbytes, ch )      memchr( from, ch, nbytes )
  934. X#endif
  935. X
  936. X#ifdef HAS_BCOPY
  937. X#define sio_memcopy( from, to, nbytes )      (void) bcopy( from, to, nbytes )
  938. X#endif
  939. X
  940. X#ifndef sio_memcopy
  941. X#define sio_memcopy        __sio_memcopy
  942. X#define NEED_MEMCOPY
  943. Xvoid __sio_memcopy() ;
  944. X#endif
  945. X
  946. X#ifndef sio_memscan
  947. Xchar *sio_memscan() ;
  948. X#endif
  949. X
  950. X#endif /* SIO_BUFFER_SIZE */
  951. X
  952. END_OF_FILE
  953. if test 5528 -ne `wc -c <'libs/src/sio/impl.h'`; then
  954.     echo shar: \"'libs/src/sio/impl.h'\" unpacked with wrong size!
  955. fi
  956. # end of 'libs/src/sio/impl.h'
  957. fi
  958. if test -f 'libs/src/timer/timer.c' -a "${1}" != "-c" ; then 
  959.   echo shar: Will not clobber existing file \"'libs/src/timer/timer.c'\"
  960. else
  961. echo shar: Extracting \"'libs/src/timer/timer.c'\" \(5559 characters\)
  962. sed "s/^X//" >'libs/src/timer/timer.c' <<'END_OF_FILE'
  963. X/*
  964. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  965. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  966. X * and conditions for redistribution.
  967. X */
  968. X
  969. Xstatic char RCSid[] = "$Id: timer.c,v 5.1 93/11/26 12:16:33 panos Exp $" ;
  970. Xstatic char *version = VERSION ;
  971. X
  972. X#include "timemacros.h"
  973. X#include "impl.h"
  974. X#include "defs.h"
  975. X
  976. X#define TIMER_H_NULL                    ((timer_h)NULL)
  977. X
  978. X
  979. Xint timer_errno ;
  980. X
  981. X
  982. X
  983. X/*
  984. X * Create a timer of the specified type.
  985. X * Returns a timer handle
  986. X */
  987. Xtimer_h timer_create( type, flags, errnop )
  988. X    enum timer_types    type ;
  989. X    int                    flags ;
  990. X    int                    *errnop ;
  991. X{
  992. X    int        *errp = ( errnop != NULL ) ? errnop : &timer_errno ;
  993. X    timer_s    *tp ;
  994. X
  995. X    if ( type != TIMER_REAL && type != TIMER_VIRTUAL && type != TIMER_PROF )
  996. X            HANDLE_ERROR( flags, TIMER_H_NULL, errp, TIMER_EBADTYPE,
  997. X                            "TIMER timer_create: bad timer type\n" ) ;
  998. X            
  999. X    tp = TIMER_ALLOC() ;
  1000. X    if ( tp == NULL )
  1001. X    {
  1002. X        *errp = TIMER_ENOMEM ;
  1003. X        return( TIMER_H_NULL ) ;
  1004. X    }
  1005. X    
  1006. X    tp->t_state = INACTIVE ;
  1007. X    tp->t_act = IDLE ;
  1008. X    tp->t_blocked = FALSE ;
  1009. X
  1010. X    tp->t_errnop = errp ;
  1011. X    tp->t_flags = flags & TIMER_CREATE_FLAGS ;
  1012. X    tp->t_action.ta_func = NULL ;
  1013. X    tp->t_action.ta_arg = NULL ;
  1014. X    tp->t_action.ta_flags = TIMER_NOFLAGS ;
  1015. X    if ( __ostimer_newtimer( tp, type ) == TIMER_ERR )
  1016. X    {
  1017. X        TIMER_FREE( tp ) ;
  1018. X        return( TIMER_H_NULL ) ;
  1019. X    }
  1020. X    return( (timer_h) tp ) ;
  1021. X}
  1022. X
  1023. X
  1024. Xvoid timer_destroy( handle )
  1025. X    timer_h    handle ;
  1026. X{
  1027. X    timer_s    *tp = TP( handle ) ;
  1028. X
  1029. X    __ostimer_blockall() ;
  1030. X
  1031. X    if ( tp->t_state == TICKING )
  1032. X    {
  1033. X        __ostimer_remove( tp->t_ostimer, tp ) ;
  1034. X        tp->t_state = DESTROYED ;
  1035. X    }
  1036. X    
  1037. X    if ( tp->t_act == IDLE || tp->t_act == PENDING )
  1038. X        TIMER_FREE( tp ) ;
  1039. X
  1040. X    __ostimer_unblockall() ;
  1041. X}
  1042. X
  1043. X
  1044. Xint timer_start( handle, itvp, time_type, ap )
  1045. X    timer_h                    handle ;
  1046. X    struct itimerval        *itvp ;
  1047. X    enum timer_timetypes time_type ;
  1048. X    struct timer_action    *ap ;
  1049. X{
  1050. X    int                    result ;
  1051. X    int                    ok_to_start ;
  1052. X    timer_s                *tp    = TP( handle ) ;
  1053. X    struct os_timer    *otp    = tp->t_ostimer ;
  1054. X
  1055. X    __ostimer_blockall() ;
  1056. X
  1057. X    /*
  1058. X     * We allow invoking timer_start from within the user-specified action
  1059. X     * after the timer has expired. However, we do not allow this for
  1060. X     * timers that have a t_interval (these timers stay at the TICKING state).
  1061. X     */
  1062. X    ok_to_start = tp->t_state == INACTIVE &&
  1063. X                            ( tp->t_act == IDLE || tp->t_act == INVOKED ) ;
  1064. X
  1065. X    if ( ! ok_to_start )
  1066. X    {
  1067. X        __ostimer_unblockall() ;
  1068. X        HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADSTATE,
  1069. X            "TIMER timer_start: timer state does not allow this operation\n" ) ;
  1070. X    }
  1071. X
  1072. X    if ( itvp->it_value.tv_sec < 0 || itvp->it_value.tv_usec < 0 )
  1073. X    {
  1074. X        __ostimer_unblockall() ;
  1075. X        HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADTIME,
  1076. X            "TIMER timer_start: neg time value)\n" ) ;
  1077. X    }
  1078. X
  1079. X    tp->t_action = *ap ;
  1080. X    tp->t_action.ta_flags &= TIMER_START_FLAGS ;
  1081. X
  1082. X    result = __ostimer_add( otp, tp, itvp, time_type ) ;
  1083. X    __ostimer_unblockall() ;
  1084. X    return( result ) ;
  1085. X}
  1086. X
  1087. X
  1088. Xvoid timer_stop( handle )
  1089. X    timer_h handle ;
  1090. X{
  1091. X    timer_s *tp = TP( handle ) ;
  1092. X
  1093. X    __ostimer_blockall() ;
  1094. X
  1095. X    if ( tp->t_state == TICKING )
  1096. X    {
  1097. X        __ostimer_remove( tp->t_ostimer, tp ) ;
  1098. X        tp->t_state = INACTIVE ;
  1099. X    }
  1100. X
  1101. X    if ( tp->t_act == SCHEDULED )
  1102. X        tp->t_act = INVOKED ;        /* to avoid the invocation */
  1103. X    else if ( tp->t_act == PENDING )
  1104. X        tp->t_act = IDLE ;
  1105. X
  1106. X    tp->t_blocked = FALSE ;
  1107. X    
  1108. X    __ostimer_unblockall() ;
  1109. X}
  1110. X
  1111. X
  1112. Xvoid timer_block( handle )
  1113. X    timer_h handle ;
  1114. X{
  1115. X    timer_s *tp = TP( handle ) ;
  1116. X
  1117. X    __ostimer_blockall() ;
  1118. X
  1119. X    if ( tp->t_state == TICKING || 
  1120. X            tp->t_state == INACTIVE && 
  1121. X                ( tp->t_act == PENDING || tp->t_act == SCHEDULED ) )
  1122. X        tp->t_blocked = TRUE ;
  1123. X
  1124. X    __ostimer_unblockall() ;
  1125. X}
  1126. X
  1127. X
  1128. Xvoid timer_unblock( handle )
  1129. X    timer_h handle ;
  1130. X{
  1131. X    timer_s *tp = TP( handle ) ;
  1132. X
  1133. X    __ostimer_blockall() ;
  1134. X
  1135. X    if ( tp->t_blocked )
  1136. X    {
  1137. X        tp->t_blocked = FALSE ;
  1138. X        if ( tp->t_act == PENDING )
  1139. X        {
  1140. X            tp->t_act = SCHEDULED ;
  1141. X            (void) __timer_invoke( tp ) ;
  1142. X        }
  1143. X    }
  1144. X    
  1145. X    __ostimer_unblockall() ;
  1146. X}
  1147. X
  1148. X
  1149. Xunsigned timer_expirations( handle )
  1150. X    timer_h handle ;
  1151. X{
  1152. X    return( TP( handle )->t_count ) ;
  1153. X}
  1154. X
  1155. X
  1156. X
  1157. X/*
  1158. X * Invoke the action of the specified timer
  1159. X * All timer interrupts should be blocked when this function is invoked
  1160. X * Returns TRUE if 
  1161. X */
  1162. Xenum timer_state __timer_invoke( tp )
  1163. X    register timer_s *tp ;
  1164. X{
  1165. X    enum timer_state state ;
  1166. X
  1167. X    /*
  1168. X     * The reason for the infinite loop is that the timer may reexpire
  1169. X     * while its function is being invoked.
  1170. X     */
  1171. X    for ( ;; )
  1172. X    {
  1173. X        /*
  1174. X         * This is the INVOKE part
  1175. X         */
  1176. X        if ( tp->t_blocked )
  1177. X            tp->t_act = PENDING ;
  1178. X        else
  1179. X        {
  1180. X            if ( tp->t_state != DESTROYED && tp->t_act == SCHEDULED )
  1181. X            {
  1182. X                void    (*func)()    = tp->t_action.ta_func ;
  1183. X                void    *arg            = tp->t_action.ta_arg ;
  1184. X                int    flags         = tp->t_action.ta_flags ;
  1185. X
  1186. X                tp->t_act = INVOKED ;
  1187. X                tp->t_expirations = tp->t_count ;
  1188. X                tp->t_count = 0 ;
  1189. X                if ( func != NULL )
  1190. X                {
  1191. X                    int unblock_all_intrs = ! ( flags & TIMER_BLOCK_ALL ) ;
  1192. X                    int unblock_all_but_same_intr = ! ( flags & TIMER_BLOCK_SAME ) ;
  1193. X                    
  1194. X                    if ( unblock_all_intrs )
  1195. X                        __ostimer_unblockall() ;
  1196. X                    else if ( unblock_all_but_same_intr )
  1197. X                        __ostimer_unblockall_except( tp->t_ostimer ) ;
  1198. X
  1199. X                    (*func)( tp, arg ) ;
  1200. X
  1201. X                    if ( unblock_all_intrs || unblock_all_but_same_intr )
  1202. X                        __ostimer_blockall() ;
  1203. X                }
  1204. X                else if ( arg != NULL )
  1205. X                {
  1206. X                    int *ip = (int *) arg ;
  1207. X
  1208. X                    if ( flags & TIMER_INC_VAR )
  1209. X                        *ip += tp->t_expirations ;
  1210. X                    else
  1211. X                        *ip = 1 ;
  1212. X                }
  1213. X            }
  1214. X        }
  1215. X
  1216. X        state = tp->t_state ;
  1217. X
  1218. X        /*
  1219. X         * This is the RETURN part
  1220. X         */
  1221. X        if ( tp->t_state == DESTROYED )
  1222. X            TIMER_FREE( tp ) ;
  1223. X        else
  1224. X        {
  1225. X            if ( tp->t_act == INVOKED )
  1226. X                tp->t_act = IDLE ;
  1227. X            else if ( tp->t_act == SCHEDULED )
  1228. X                continue ;
  1229. X        }
  1230. X        break ;
  1231. X    }
  1232. X    return( state ) ;
  1233. X}
  1234. X
  1235. END_OF_FILE
  1236. if test 5559 -ne `wc -c <'libs/src/timer/timer.c'`; then
  1237.     echo shar: \"'libs/src/timer/timer.c'\" unpacked with wrong size!
  1238. fi
  1239. # end of 'libs/src/timer/timer.c'
  1240. fi
  1241. echo shar: End of archive 11 \(of 20\).
  1242. cp /dev/null ark11isdone
  1243. MISSING=""
  1244. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  1245.     if test ! -f ark${I}isdone ; then
  1246.     MISSING="${MISSING} ${I}"
  1247.     fi
  1248. done
  1249. if test "${MISSING}" = "" ; then
  1250.     echo You have unpacked all 20 archives.
  1251.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1252. else
  1253.     echo You still need to unpack the following archives:
  1254.     echo "        " ${MISSING}
  1255. fi
  1256. ##  End of shell archive.
  1257. exit 0
  1258.