home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / pst / part02 < prev    next >
Encoding:
Text File  |  1993-11-26  |  54.4 KB  |  2,227 lines

  1. Newsgroups: comp.sources.misc
  2. From: Panos Tsirigotis (panos@cs.colorado.edu)
  3. Subject: v40i173:  pst - extract text from a postscript file, Part02/06
  4. Message-ID: <1993Nov26.170637.6397@sparky.sterling.com>
  5. X-Md4-Signature: fc69f70b650e62f06cbde4110ed57ef4
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 26 Nov 1993 17:06:37 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: Panos Tsirigotis (panos@cs.colorado.edu)
  12. Posting-number: Volume 40, Issue 173
  13. Archive-name: pst/part02
  14. Environment: BSD, SUNOS, ULTRIX, SYSVR4, SYSVR3, POSIX
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  libs/src/sio/sio.3 libs/src/sio/sio.c libs/src/sio/sio.h
  21. #   libs/src/sio/suite/print.c libs/src/str/strs.c
  22. # Wrapped by kent@sparky on Fri Nov 26 11:02:45 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 2 (of 6)."'
  26. if test -f 'libs/src/sio/sio.3' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.3'\"
  28. else
  29.   echo shar: Extracting \"'libs/src/sio/sio.3'\" \(13341 characters\)
  30.   sed "s/^X//" >'libs/src/sio/sio.3' <<'END_OF_FILE'
  31. X.\"(c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  32. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  33. X.\"and conditions for redistribution.
  34. X.\"
  35. X.\" $Id: sio.3,v 8.2 1993/11/22 19:00:24 panos Exp $
  36. X.TH SIO 3X "29 May 1992"
  37. X.SH NAME
  38. XSread, Sgetc, Srdline, Sfetch, Swrite, Sputc, Sprint, Sprintv, Sdone, Sundo, Stie, Suntie, Sflush, Sclose, Sbuftype, Smorefds, Sgetchar, Sputchar, SIOLINELEN, SIOMAXLINELEN - fast stream I/O
  39. X.SH SYNOPSIS
  40. X.LP
  41. X.nf
  42. X.ft B
  43. X#include "sio.h"
  44. X.LP
  45. X.ft B
  46. Xint Sread( fd, buf, nbytes )
  47. Xint fd ;
  48. Xchar *buf ;
  49. Xint nbytes ;
  50. X.LP
  51. X.ft B
  52. Xint Sgetc( fd )
  53. Xint fd ;
  54. X.LP
  55. X.ft B
  56. Xchar *Srdline( fd )
  57. Xint fd ;
  58. X.LP
  59. X.ft B
  60. Xchar *Sfetch( fd, length )
  61. Xint fd ;
  62. Xlong *length ;
  63. X.LP
  64. X.ft B
  65. Xint Swrite( fd, buf, nbytes )
  66. Xint fd ;
  67. Xchar *buf ;
  68. Xint nbytes ;
  69. X.LP
  70. X.ft B
  71. Xint Sputc( fd, c )
  72. Xint fd ;
  73. Xchar c ;
  74. X.LP
  75. X.ft B
  76. Xint Sprint( fd, format [ , ... ] )
  77. Xint fd ;
  78. Xchar *format ;
  79. X.LP
  80. X.ft B
  81. Xint Sprintv( fd, format, ap )
  82. Xint fd ;
  83. Xchar *format ;
  84. Xva_list ap ;
  85. X.LP
  86. X.ft B
  87. Xint Sdone( fd )
  88. Xint fd ;
  89. X.LP
  90. X.ft B
  91. Xint Sundo( fd, type )
  92. Xint fd ;
  93. Xint type ;
  94. X.LP
  95. X.ft B
  96. Xint Stie( ifd, ofd )
  97. Xint ifd, ofd ;
  98. X.LP
  99. X.ft B
  100. Xint Suntie( fd )
  101. Xint fd ;
  102. X.LP
  103. X.ft B
  104. Xint Sbuftype( fd, type )
  105. Xint fd, type ;
  106. X.LP
  107. X.ft B
  108. Xint Smorefds()
  109. X.LP
  110. X.ft B
  111. Xint Sflush( fd )
  112. Xint fd ;
  113. X.LP
  114. X.ft B
  115. Xint Sclose( fd )
  116. Xint fd ;
  117. X.LP
  118. X.ft B
  119. Xint Sgetchar( fd )
  120. Xint fd ;
  121. X.LP
  122. X.ft B
  123. Xint Sputchar( fd, c )
  124. Xint fd;
  125. Xchar c ;
  126. X.LP
  127. X.ft B
  128. Xint SIOLINELEN( fd )
  129. Xint fd ;
  130. X.LP
  131. X.ft B
  132. Xint SIOMAXLINELEN( fd )
  133. Xint fd ;
  134. X.SH DESCRIPTION
  135. XThe \fISIO\fR library provides support
  136. Xfor \fIstream\fR I/O on file descriptors.
  137. XThe first argument of every function
  138. Xor macro is a file descriptor. The file descriptor may be used either for
  139. Xinput or for output, but not both. Attempting to use a descriptor for
  140. Xboth input and output will cause the call for the latter use to fail.
  141. XWhen you are
  142. Xdone with using a file descriptor, you should inform \fISIO\fR
  143. Xby invoking \fBSdone()\fR (unless the program is about to 
  144. Xcall \fIexit(3)\fR).
  145. XYou can also use \fBSdone()\fR if
  146. Xyou want to perform a different type of operation on the same
  147. Xfile descriptor (e.g. first you were reading data from the file
  148. Xdescriptor and then you want to write some data).
  149. XAnother possibility is to do stream I/O at different file offsets
  150. Xby using \fBSdone()\fR before using \fBlseek(2)\fR to move to a
  151. Xnew file offset.
  152. X.LP
  153. XI/O operations on different file descriptors do not interfere
  154. X(unless the file descriptors refer to the same file, in which case
  155. Xthe results are undefined).
  156. X.LP
  157. XFor disk files, I/O always starts at the current file offset.
  158. XIf that offset is not a multiple of the preferred block size for file
  159. Xsystem I/O, performance will not be optimal
  160. X(the preferred block size is determined from the
  161. X\fIst_blksize\fR field in \fIstruct stat\fR).
  162. XFor optimal performance, it is recommended that no I/O operations
  163. X(like \fIread(2)\fR or \fIwrite(2)\fR)
  164. Xare applied to the file descriptor if it is to be used by \fISIO\fR.
  165. X.LP
  166. XRead I/O is either buffered, or is done using memory mapping whenever
  167. Xthat is possible and appropriate.
  168. X.LP
  169. XThe library functions that do stream I/O resemble system calls
  170. X(for example \fBSread()\fR resembles \fIread(2)\fR) so that modifying
  171. Xa program that uses the system calls to use the \fISIO\fR functions
  172. Xis easy (e.g. just replace \fIread(2)\fR with \fBSread()\fR; the function
  173. Xsignatures as well as the return values are exactly the same; also make
  174. Xsure to replace calls to \fIclose(2)\fP with \fBSclose()\fP).
  175. X.LP
  176. X\fISIO\fR uses the underlying system calls \fIread(2)\fR and \fIwrite(2)\fR
  177. Xto do I/O (except when reading files using memory mapping).
  178. XThese calls may be interrupted (i.e. they may return -1 with
  179. X.I errno
  180. Xset to EINTR). Such interruptions are ignored by \fISIO\fR which
  181. Xsimply reissues the system call
  182. X(this means that a \fISIO\fP call will never fail because the
  183. Xunderlying I/O system call was interrupted).
  184. X.LP
  185. X.B Sread()
  186. Xreads \fInbytes\fR bytes from the stream associated with file 
  187. Xdescriptor \fIfd\fR into the buffer pointed to by \fIbuf\fR.
  188. X.LP
  189. X.B Sgetc()
  190. Xreads a character from the stream
  191. Xassociated with file descriptor \fIfd\fR.
  192. XIt returns \fBSIO_EOF\fR if the end of file has been reached.
  193. X.LP
  194. X.B Sgetchar()
  195. X(a macro) performs exactly the same function as \fBSgetc()\fR but
  196. Xit is much faster.
  197. X.LP
  198. X.B Srdline()
  199. Xreads a line from the stream
  200. Xassociated with file descriptor \fIfd\fR.
  201. XThe newline at the end of the line is replaced by a NUL byte. Lines
  202. Xlonger than the maximum line length supported by \fISIO\fR will
  203. Xhave characters deleted.
  204. X.LP
  205. X.B SIOLINELEN()
  206. X(a macro) returns the length of
  207. Xthe line returned by the last call to \fBSrdline()\fR
  208. X(the value returned by \fBSIOLINELEN()\fR is valid only after
  209. X\fBSrdline()\fR and as long as no other 
  210. X\fISIO\fR calls are performed on that file descriptor).
  211. X.LP
  212. X.B SIOMAXLINELEN()
  213. X(a macro) returns
  214. Xthe maximul line length supported by \fISIO\fR for the file
  215. Xdescriptor. As a side-effect it initializes \fIfd\fR for input.
  216. X.LP
  217. X.B Sfetch()
  218. Xreturns a pointer to data coming from the stream
  219. Xassociated with file
  220. Xdescriptor \fIfd\fR. The amount of data available is indicated
  221. Xby the \fIlength\fR argument. One possible use for this function
  222. Xis to copy files.
  223. X.LP
  224. X.B Swrite()
  225. Xwrites \fInbytes\fR bytes to the stream associated with file
  226. Xdescriptor \fIfd\fR from the buffer pointed to by \fIbuf\fR.
  227. X.LP
  228. X.B Sputc()
  229. Xwrites a single character to the stream
  230. Xassociated with file descriptor \fIfd\fR.
  231. X.LP
  232. X.B Sputchar()
  233. X(a macro) performs exactly the same function as \fBSputc()\fR
  234. Xbut it is much faster.
  235. X.LP
  236. X.B Sprint()
  237. Ximitates the behavior of printf(3) as defined in the
  238. XANSI C Standard. There are some limitations. Check the \fBSprint()\fR
  239. Xman page for more information.
  240. X.LP
  241. X.B Sprintv()
  242. Xis the same as \fBSprint()\fR except that it uses a
  243. X\fIvarargs\fR argument list.
  244. X.LP
  245. X.B Sundo()
  246. Xreturns the characters returned by the last call to
  247. X\fBSrdline()\fR, \fBSgetc()\fR or \fBSgetchar()\fR to the stream
  248. Xso that they can be reread. The \fItype\fR argument to \fBSundo()\fR
  249. Xcan be \fBSIO_UNDO_LINE\fR or \fBSIO_UNDO_CHAR\fR depending
  250. Xon whether the call whose effect needs to be undone was
  251. X\fBSrdline()\fR or \fBSgetc()\fR/\fBSgetchar()\fR respectively.
  252. XThere is no check on
  253. Xwhether the last function invoked on \fIfd\fR was one of the above
  254. Xand the results are undefined if there is no correspondence
  255. Xbetween the \fItype\fR and the last operation on \fIfd\fR.
  256. X(i.e. the result is undefined if you try \fBSIO_UNDO_CHAR\fR 
  257. Xand the last operation was not \fBSgetchar()\fR or \fBSgetc()\fR).
  258. X.LP
  259. X.B Stie()
  260. Xties the file descriptor \fIifd\fR to the file descriptor \fIofd\fR.
  261. XThis means that whenever a \fIread(2)\fR is done on \fIifd\fR, it is
  262. Xpreceded by a \fIwrite(2)\fR on \fIofd\fR.
  263. XFor filters it is useful to do \fIStie( 0, 1 )\fR to maximize concurrency.
  264. XIt is also useful to do the same thing when you issue prompts to the
  265. Xuser and you want the user reply to appear on the same line with the
  266. Xprompt.
  267. X\fIifd\fR, \fIofd\fR  will be initialized for input, output respectively
  268. X(if any of them is initialized, it must be for the appropriate
  269. Xstream type (input or output)).
  270. XIf \fIifd\fR was tied to another file descriptor, the old tie is broken.
  271. X.LP
  272. X.B Suntie()
  273. Xundoes the effect of \fBStie()\fR for the specified input file descriptor.
  274. X.LP
  275. X.B Sbuftype()
  276. Xdetermines the buffering type for the output stream associated with
  277. Xfile descriptor \fIfd\fR.
  278. XBy default output directed to terminals is line buffered, output
  279. Xdirected to file descriptor 2 (standard error) is unbuffered and
  280. Xeverything else is fully buffered.
  281. XPossible values for the \fItype\fR argument are
  282. X.RS
  283. X.TP 15
  284. X.SB SIO_FULLBUF
  285. Xfor full buffering
  286. X.TP
  287. X.SB SIO_LINEBUF
  288. Xfor line buffering
  289. X.TP
  290. X.SB SIO_NOBUF
  291. Xfor no buffering
  292. X.RE
  293. X.LP
  294. X.B Smorefds()
  295. Xshould be used to inform \fBSIO\fR that the number of available file
  296. Xdescriptors has been increased. \fBSIO\fR uses an array of internal
  297. Xstream descriptors which are indexed by the file descriptor number. Some
  298. Xoperating systems (ex. SunOS 4.1[.x]) allow the number of available
  299. Xfile descriptors to vary. If that number is increased beyond its initial
  300. Xvalue \fBSIO\fR needs to know in order to allocate more stream descriptors.
  301. X.LP
  302. X.B Sdone()
  303. Xflushes any buffered output for \fIfd\fR 
  304. Xand releases the \fISIO\fR resources used. \fBSdone()\fR 
  305. Xis useful in case the program needs to reprocess the
  306. Xdata of a file descriptor (assuming the file descriptor corresponds
  307. Xto a file).  The program can call \fBSdone()\fR,
  308. X\fIlseek(2)\fR to the beginning of the file
  309. Xand then proceed to reread the file.
  310. X.LP
  311. X.B Sflush()
  312. Xcauses any buffered stream output to be written to the
  313. Xfile descriptor. If its argument is the special value \fBSIO_FLUSH_ALL\fR
  314. Xthen all output streams will be flushed.
  315. X.LP
  316. X.B Sclose()
  317. Xcloses a file descriptor used for stream I/O, flushes
  318. Xany buffered output and releases the \fISIO\fR resources used.
  319. X.SH EXAMPLES
  320. X.LP
  321. XThe following code implements a (poor) substitute for the tee command
  322. X(it copies standard input to a file as well as to standard output).
  323. X.ne 10
  324. X.RS
  325. X.nf
  326. X.ft B
  327. X#include "sio.h"
  328. X.sp .5
  329. Xmain( argc, argv )
  330. X    int argc ;
  331. X    char *argv[] ;
  332. X{
  333. X    char *file = (argc > 1) ? argv[ 1 ] : "tee.file" ;
  334. X    int fd = creat( file, 0644 ) ;
  335. X    long length ;
  336. X    char *s ;
  337. X.sp .5
  338. X    while ( s = Sfetch( 0, &length ) )
  339. X    {
  340. X        Swrite( 1, s, length ) ;
  341. X        Swrite( fd, s, length ) ;
  342. X    }
  343. X    exit( 0 ) ;
  344. X}
  345. X.fi
  346. X.ft R
  347. X.RE
  348. X.SH RETURN VALUES
  349. X.LP
  350. X.B Sread()
  351. Xreturns the number of bytes read on success
  352. X(0 means end-of-file)
  353. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  354. X.LP
  355. X.B Sgetc()
  356. Xreturns the character read on success,
  357. XSIO_EOF when the end-of-file is reached,
  358. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  359. X.LP
  360. X.B Srdline()
  361. Xreturns a pointer to the next line on success.
  362. XOn failure or when the end-of-file is reached it returns
  363. X.SM NULL.
  364. XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
  365. Xthe error.
  366. X.LP
  367. X.B Sfetch()
  368. Xreturns a pointer to file data on success.
  369. X(the \fIlength\fR argument indicates how many bytes
  370. Xare available).
  371. XOn failure or when the end-of-file is reached it returns
  372. X.SM NULL.
  373. XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
  374. Xthe error.
  375. X.LP
  376. X.B Swrite()
  377. Xreturns the number of bytes written on success
  378. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  379. X.LP
  380. X.B Sputc()
  381. Xreturns the character it was given as an argument on success
  382. X.B Sprint()
  383. Xreturns the number of characters printed on success
  384. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  385. X.LP
  386. X.B Sdone()
  387. Xreturns \fB0\fR on success
  388. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  389. X.LP
  390. X.B Sundo()
  391. Xreturns \fB0\fR on success
  392. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  393. X.LP
  394. X.B Stie()
  395. Xreturns \fB0\fR on success
  396. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  397. X.LP
  398. X.B Suntie()
  399. Xreturns \fB0\fR on success
  400. Xor \fBSIO_ERR\fR on failure
  401. X(\fIerrno\fR is set to \fBEBADF\fR if there
  402. Xwas no tied file descriptor).
  403. X.LP
  404. X.B Sbuftype()
  405. Xreturns \fB0\fR on success
  406. Xor \fBSIO_ERR\fR on failure
  407. X(\fIerrno\fR is set to \fBEBADF\fR if this is not an output stream
  408. Xor to \fBEINVAL\fR if an unknown \fItype\fR is specified).
  409. X.LP
  410. X.B Smorefds()
  411. Xreturns \fB0\fR on success
  412. Xor \fBSIO_ERR\fR on failure (because of lack of memory).
  413. X.LP
  414. X.B Sflush()
  415. Xreturns \fB0\fR on success
  416. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  417. X.LP
  418. X.B Sclose()
  419. Xreturns \fB0\fR on success
  420. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  421. X.LP
  422. X.B Sgetchar()
  423. Xreturns the character read on success,
  424. XSIO_EOF when the end-of-file is reached,
  425. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  426. X.LP
  427. X.B Sputchar()
  428. Xreturns the character it was given as an argument on success
  429. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  430. X.LP
  431. X.B SIOLINELEN()
  432. Xreturns the length of the last line read by \fBSrdline()\fR.
  433. X.LP
  434. X.B SIOMAXLINELEN()
  435. Xreturns the length of the longest line supported by \fISIO\fR on success
  436. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  437. X.LP
  438. XAttempting a read operation on a descriptor opened for writing or vice
  439. Xversa will cause the operation to fail with \fIerrno\fR set to \fBEBADF\fR.
  440. X.LP
  441. XThe first \fISIO\fR operation on a descriptor must be a read or write
  442. Xoperation. It cannot be a control operation (like \fBSflush()\fR). Such
  443. Xan operation will fail with \fIerrno\fR set to \fBEBADF\fR.
  444. X.LP
  445. X.IP "\fBNOTE 1:\fR" 15
  446. X\fBStie()\fR is an input/output operation for the
  447. Xrespective file descriptors, not a control operation. \fBSuntie()\fR
  448. Xis a control operation.
  449. X.IP "\fBNOTE 2:\fR"
  450. X\fBSIO_ERR\fR is defined to be \fB-1\fR.
  451. X.SH "SEE ALSO"
  452. X.LP
  453. XSprint(3)
  454. X.SH BUGS
  455. X.LP
  456. XIf the operating system does not provide for invocation of a
  457. Xfinalization function upon exit, the program will have to
  458. Xexplicitly flush all output streams.
  459. XThe following operating systems provide such a facility:
  460. XSunOS 4.x, Ultrix 4.x, SunOS 5.x
  461. X.LP
  462. XSocket file descriptors can be used for input as well as output but
  463. X\fBSIO\fR does not support this.
  464. X.LP
  465. XThe current implementation will not try to use memory mapping to
  466. Xread a file if the file offset is not 0 (it will use buffered I/O instead).
  467. X.LP
  468. XPointers returned by \fBSfetch()\fR point to read-only memory.
  469. XAttempting to modify this memory will result in a segmentation
  470. Xviolation.
  471. END_OF_FILE
  472.   if test 13341 -ne `wc -c <'libs/src/sio/sio.3'`; then
  473.     echo shar: \"'libs/src/sio/sio.3'\" unpacked with wrong size!
  474.   fi
  475.   # end of 'libs/src/sio/sio.3'
  476. fi
  477. if test -f 'libs/src/sio/sio.c' -a "${1}" != "-c" ; then 
  478.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.c'\"
  479. else
  480.   echo shar: Extracting \"'libs/src/sio/sio.c'\" \(15212 characters\)
  481.   sed "s/^X//" >'libs/src/sio/sio.c' <<'END_OF_FILE'
  482. X/*
  483. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  484. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  485. X * and conditions for redistribution.
  486. X */
  487. X
  488. Xstatic char RCSid[] = "$Id: sio.c,v 8.1 1993/03/13 01:15:55 panos Exp $" ;
  489. Xstatic char sio_version[] = VERSION ;
  490. X
  491. X#include <sys/types.h>
  492. X#include <sys/stat.h>
  493. X
  494. X#include "sio.h"
  495. X#include "impl.h"
  496. X
  497. X#ifdef EVENTS
  498. X#include "events.h"
  499. X#endif
  500. X
  501. X/*
  502. X * SIO WRITE FUNCTIONS: Swrite, Sputc
  503. X */
  504. X
  505. X/*
  506. X * Stream write call: arguments same as those of write(2)
  507. X */
  508. Xint Swrite( fd, addr, nbytes )
  509. X    int fd ;
  510. X    register char *addr ;
  511. X    register int nbytes ;
  512. X{
  513. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  514. X    register __sio_od_t *odp = ODP( dp ) ;
  515. X    register int b_transferred ;
  516. X    register int b_avail ;
  517. X    int total_b_transferred ;
  518. X    int b_written ;
  519. X    int b_in_buffer ;
  520. X
  521. X#ifdef EVENTS
  522. X    EVENT( fd, EV_SWRITE ) ;
  523. X#endif
  524. X
  525. X    IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
  526. X    ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;
  527. X
  528. X    b_avail = odp->buf_end - odp->nextb ;
  529. X    b_transferred = MIN( nbytes, b_avail ) ;
  530. X    sio_memcopy( addr, odp->nextb, b_transferred ) ;
  531. X    odp->nextb += b_transferred ;
  532. X
  533. X    /*
  534. X     * check if we are done
  535. X     */
  536. X    if ( b_transferred == nbytes )
  537. X        return( b_transferred ) ;
  538. X
  539. X    /*
  540. X     * at this point we know that the buffer is full
  541. X     */
  542. X    b_in_buffer = odp->buf_end - odp->start ;
  543. X    b_written = __sio_writef( odp, fd ) ;
  544. X    if ( b_written != b_in_buffer )
  545. X        return( (b_written >= nbytes) ? nbytes : b_written ) ;
  546. X    
  547. X    total_b_transferred = b_transferred ;
  548. X    addr += b_transferred ;
  549. X    nbytes -= b_transferred ;
  550. X
  551. X    for ( ;; )
  552. X    {
  553. X        b_transferred = MIN( nbytes, odp->buffer_size ) ;
  554. X        sio_memcopy( addr, odp->nextb, b_transferred ) ;
  555. X        odp->nextb += b_transferred ;
  556. X        nbytes -= b_transferred ;
  557. X        if ( nbytes == 0 )
  558. X        {
  559. X            total_b_transferred += b_transferred ;
  560. X            break ;
  561. X        }
  562. X        /*
  563. X         * the buffer is full
  564. X         */
  565. X        b_written = __sio_writef( odp, fd ) ;
  566. X        if ( b_written != odp->buffer_size )
  567. X        {
  568. X            if ( b_written != SIO_ERR )
  569. X            {
  570. X                total_b_transferred += b_written ;
  571. X                odp->nextb += b_written ;
  572. X            }
  573. X            break ;
  574. X        }
  575. X        /*
  576. X         * everything is ok
  577. X         */
  578. X        total_b_transferred += b_transferred ;
  579. X        addr += b_transferred ;
  580. X    }
  581. X    return( total_b_transferred ) ;
  582. X}
  583. X
  584. X
  585. X/*
  586. X * Add a character to a file
  587. X */
  588. Xint Sputc( fd, c )
  589. X    int fd ;
  590. X    char c ;
  591. X{
  592. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  593. X    register __sio_od_t *odp = ODP( dp ) ;
  594. X
  595. X#ifdef EVENTS
  596. X    EVENT( fd, EV_SPUTC ) ;
  597. X#endif
  598. X    
  599. X    IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
  600. X    ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;
  601. X
  602. X    /*
  603. X     * The following is a weak check since we should really be
  604. X     * checking that nextb == buf_end (it would be an error for
  605. X     * nextb to exceed buf_end; btw, the assertion above, when
  606. X     * enabled makes sure this does not occur).
  607. X     *
  608. X     * NOTE: __sio_writef NEVER uses data beyond the end of buffer.
  609. X     */
  610. X    if ( odp->nextb >= odp->buf_end )
  611. X    {
  612. X        int b_in_buffer = odp->buf_end - odp->start ;
  613. X
  614. X        /*
  615. X         * There is nothing we can do if __sio_writef does not manage
  616. X         * to write the whole buffer
  617. X         */
  618. X        if ( __sio_writef( odp, fd ) != b_in_buffer )
  619. X            return( SIO_ERR ) ;
  620. X    }
  621. X    *odp->nextb++ = c ;
  622. X    if ( __SIO_MUST_FLUSH( *odp, c ) && __sio_writef( odp, fd ) == SIO_ERR )
  623. X        return( SIO_ERR ) ;
  624. X    return ( c ) ;
  625. X}
  626. X
  627. X
  628. X
  629. X/*
  630. X * SIO READ FUNCTIONS
  631. X */
  632. X
  633. X/*
  634. X * Stream read call: arguments same as those of read(2)
  635. X */
  636. Xint Sread( fd, addr, nbytes )
  637. X    int fd ;
  638. X    char *addr ;
  639. X    int nbytes ;
  640. X{
  641. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  642. X    register __sio_id_t *idp = IDP( dp ) ;
  643. X    register int b_transferred ;
  644. X    int b_read ;
  645. X    int total_b_transferred ;
  646. X    int b_left ;
  647. X
  648. X#ifdef EVENTS
  649. X    EVENT( fd, EV_SREAD ) ;
  650. X#endif
  651. X
  652. X    IO_SETUP( fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
  653. X    ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  654. X
  655. X    b_left = idp->end - idp->nextb ;
  656. X    b_transferred = MIN( b_left, nbytes ) ;
  657. X    sio_memcopy( idp->nextb, addr, b_transferred ) ;
  658. X    idp->nextb += b_transferred ;
  659. X    if ( b_transferred == nbytes )
  660. X        return( b_transferred ) ;
  661. X    
  662. X    nbytes -= b_transferred ;
  663. X    total_b_transferred = b_transferred ;
  664. X    addr += b_transferred ;
  665. X
  666. X    do
  667. X    {
  668. X        b_read = __sio_readf( idp, fd ) ;
  669. X        switch ( b_read )
  670. X        {
  671. X            case SIO_ERR:
  672. X                if ( total_b_transferred == 0 )
  673. X                    return( SIO_ERR ) ;
  674. X                /* FALL THROUGH */
  675. X            
  676. X            case 0:
  677. X                return( total_b_transferred ) ;
  678. X        }
  679. X            
  680. X        b_transferred = MIN( b_read, nbytes ) ;
  681. X        sio_memcopy( idp->nextb, addr, b_transferred ) ;
  682. X        addr += b_transferred ;
  683. X        idp->nextb += b_transferred ;
  684. X        total_b_transferred += b_transferred ;
  685. X        nbytes -= b_transferred ;
  686. X    }
  687. X    while ( nbytes && b_read == idp->buffer_size ) ;
  688. X    return( total_b_transferred ) ;
  689. X}
  690. X
  691. X
  692. X
  693. X/*
  694. X * Read a line from a file
  695. X * Returns a pointer to the beginning of the line or NULL
  696. X */
  697. Xchar *Srdline( fd )
  698. X    int fd ;
  699. X{
  700. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  701. X    register __sio_id_t *idp = IDP( dp ) ;
  702. X    register char *cp ;
  703. X    register char *line_start ;
  704. X    register int b_left ;
  705. X    register int extension ;
  706. X
  707. X#ifdef EVENTS
  708. X    EVENT( fd, EV_SRDLINE ) ;
  709. X#endif
  710. X
  711. X    IO_SETUP( fd, dp, __SIO_INPUT_STREAM, NULL ) ;
  712. X    ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  713. X
  714. X#ifdef HAS_MMAP
  715. X    if ( idp->memory_mapped && __sio_switch( idp, fd ) == FAILURE )
  716. X        return( NULL ) ;
  717. X#endif
  718. X
  719. X    b_left = idp->end - idp->nextb ;
  720. X    /*
  721. X     * Look for a '\n'. If the search fails, extend the buffer
  722. X     * and search again (the extension is performed by copying the
  723. X     * bytes that were searched to the auxiliary buffer and reading 
  724. X     * new input in the main buffer).
  725. X     * If the new input still does not contain a '\n' and there is
  726. X     * more space in the main buffer (this can happen with network
  727. X     * connections), read more input until either the buffer is full
  728. X     * or a '\n' is found.
  729. X     * Finally, set cp to point to the '\n', and line_start to
  730. X     * the beginning of the line
  731. X     */
  732. X    if ( b_left && ( cp = sio_memscan( idp->nextb, b_left, '\n' ) ) != NULL )
  733. X    {
  734. X        line_start = idp->nextb ;
  735. X        idp->nextb = cp + 1 ;
  736. X    }
  737. X    else
  738. X    {
  739. X        extension = __sio_extend_buffer( idp, fd, b_left ) ;
  740. X        if ( extension > 0 )
  741. X        {
  742. X            ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  743. X
  744. X            line_start = idp->start ;
  745. X            cp = sio_memscan( idp->nextb, extension, '\n' ) ;
  746. X            if ( cp != NULL )
  747. X                idp->nextb = cp + 1 ;
  748. X            else
  749. X                for ( ;; )
  750. X                {
  751. X                    idp->nextb = idp->end ;
  752. X                    extension = __sio_more( idp, fd ) ;
  753. X                    if ( extension > 0 )
  754. X                    {
  755. X                        cp = sio_memscan( idp->nextb, extension, '\n' ) ;
  756. X                        if ( cp == NULL )
  757. X                            continue ;
  758. X                        idp->nextb = cp + 1 ;
  759. X                        break ;
  760. X                    }
  761. X                    else
  762. X                    {
  763. X                        /*
  764. X                         * If there is spare room in the buffer avoid trashing
  765. X                         * the last character
  766. X                         */
  767. X                        if ( idp->end < &idp->buf[ idp->buffer_size ] )
  768. X                            cp = idp->end ;
  769. X                        else
  770. X                            cp = &idp->buf[ idp->buffer_size - 1 ] ;
  771. X                        break ;
  772. X                    }
  773. X                }
  774. X        }
  775. X        else                    /* buffer could not be extended */
  776. X            if ( b_left == 0 )
  777. X            {
  778. X                /*
  779. X                 * Set errno to 0 if EOF has been reached
  780. X                 */
  781. X                if ( extension == 0 )
  782. X                    errno = 0 ;
  783. X                return( NULL ) ;
  784. X            }
  785. X            else
  786. X            {
  787. X                line_start = idp->start ;
  788. X                cp = idp->end ;
  789. X                /*
  790. X                 * By setting idp->nextb to be equal to idp->end,
  791. X                 * subsequent calls to Srdline will return NULL because
  792. X                 * __sio_extend_buffer will be invoked and it will return 0.
  793. X                 */
  794. X                idp->nextb = idp->end ;
  795. X            }
  796. X    }
  797. X    *cp = NUL ;
  798. X    idp->line_length = cp - line_start ;
  799. X    return( line_start ) ;
  800. X}
  801. X
  802. X
  803. X/*
  804. X * Get a character from a file
  805. X */
  806. Xint Sgetc( fd )
  807. X    int fd ;
  808. X{
  809. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  810. X    register __sio_id_t *idp = IDP( dp ) ;
  811. X
  812. X#ifdef EVENTS
  813. X    EVENT( fd, EV_SGETC ) ;
  814. X#endif
  815. X
  816. X    IO_SETUP( fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
  817. X    ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  818. X    if ( idp->nextb >= idp->end )
  819. X    {
  820. X        register int b_read = __sio_readf( idp, fd ) ;
  821. X
  822. X        if ( b_read == 0 )
  823. X            return( SIO_EOF ) ;
  824. X        else if ( b_read == SIO_ERR )
  825. X            return( SIO_ERR ) ;
  826. X    }
  827. X    return( (int) *idp->nextb++ ) ;
  828. X}
  829. X
  830. X
  831. Xchar *Sfetch( fd, lenp )
  832. X    int fd ;
  833. X    long *lenp ;
  834. X{
  835. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  836. X    register __sio_id_t *idp = IDP( dp ) ;
  837. X    register int b_read ;
  838. X    register char *p ;
  839. X
  840. X#ifdef EVENTS
  841. X    EVENT( fd, EV_SFETCH ) ;
  842. X#endif
  843. X
  844. X    IO_SETUP( fd, dp, __SIO_INPUT_STREAM, NULL ) ;
  845. X    ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  846. X    if ( idp->nextb >= idp->end )
  847. X    {
  848. X        b_read = __sio_readf( idp, fd ) ;
  849. X        if ( b_read == SIO_ERR )
  850. X            return( NULL ) ;
  851. X        if ( b_read == 0 )
  852. X        {
  853. X            errno = 0 ;
  854. X            return( NULL ) ;
  855. X        }
  856. X    }
  857. X    *lenp = idp->end - idp->nextb ;
  858. X    p = idp->nextb ;
  859. X    idp->nextb = idp->end ;
  860. X    return( p ) ;
  861. X}
  862. X
  863. X
  864. X
  865. X/*
  866. X * SIO CONTROL FUNCTIONS
  867. X */
  868. X
  869. X/*
  870. X * Undo the last Srdline or Sgetc
  871. X */
  872. Xint Sundo( fd, type )
  873. X    int fd ;
  874. X    int type ;
  875. X{
  876. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ; 
  877. X    register __sio_id_t *idp = IDP( dp ) ;
  878. X    int retval = 0 ;
  879. X
  880. X#ifdef EVENTS
  881. X    EVENT( fd, EV_SUNDO ) ;
  882. X#endif
  883. X
  884. X    CONTROL_SETUP( dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
  885. X
  886. X    /*
  887. X     * Undo works only for fd's used for input
  888. X     */
  889. X    if ( dp->stream_type != __SIO_INPUT_STREAM )
  890. X        return( SIO_ERR ) ;
  891. X
  892. X    /*
  893. X     * Check if the operation makes sense; if so, do it, otherwise ignore it
  894. X     */
  895. X    switch ( type )
  896. X    {
  897. X        case SIO_UNDO_LINE:
  898. X            if ( idp->nextb - idp->line_length > idp->start )
  899. X            {
  900. X                *--idp->nextb = '\n' ;
  901. X                idp->nextb -= idp->line_length ;
  902. X            }
  903. X            ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  904. X            break ;
  905. X        
  906. X        case SIO_UNDO_CHAR:
  907. X            if ( idp->nextb > idp->start )
  908. X                idp->nextb-- ;
  909. X            ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
  910. X            break ;
  911. X        
  912. X        default:
  913. X            retval = SIO_ERR ;
  914. X            break ;
  915. X    }
  916. X    return( retval ) ;
  917. X}
  918. X
  919. X
  920. X/*
  921. X * Flush the buffer associated with the given file descriptor
  922. X * The special value, SIO_FLUSH_ALL flushes all buffers
  923. X *
  924. X * Return value:
  925. X *            0 :  if fd is SIO_FLUSH_ALL or if the flush is successful
  926. X *        SIO_ERR: if fd is not SIO_FLUSH_ALL and
  927. X *                                the flush is unsuccessful
  928. X *                            or the descriptor is not initialized or it is not 
  929. X *                                an output descriptor
  930. X */
  931. Xint Sflush( fd )
  932. X    int fd ;
  933. X{
  934. X   register __sio_descriptor_t *dp ;
  935. X   int b_in_buffer ;
  936. X
  937. X#ifdef EVENTS
  938. X    EVENT( fd, EV_SFLUSH ) ;
  939. X#endif
  940. X
  941. X   if ( fd == SIO_FLUSH_ALL )
  942. X   {
  943. X      for ( fd = 0, dp = __sio_descriptors ;
  944. X                fd < N_SIO_DESCRIPTORS ;
  945. X                dp++, fd++ )
  946. X         if ( DESCRIPTOR_INITIALIZED( dp ) &&
  947. X                            dp->stream_type == __SIO_OUTPUT_STREAM )
  948. X            (void) __sio_writef( ODP( dp ), fd ) ;
  949. X      return( 0 ) ;
  950. X   }
  951. X   else
  952. X   {
  953. X      dp = &__sio_descriptors[ fd ] ;
  954. X
  955. X        CONTROL_SETUP( dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
  956. X      b_in_buffer = ODP( dp )->nextb - ODP( dp )->start ;
  957. X      if ( __sio_writef( ODP( dp ), fd ) != b_in_buffer )
  958. X         return( SIO_ERR ) ;
  959. X      else
  960. X         return( 0 ) ;
  961. X   }
  962. X}
  963. X
  964. X
  965. X/*
  966. X * Close the file descriptor. This call is provided because
  967. X * a file descriptor may be closed and then reopened. There is
  968. X * no easy way for SIO to identify such a situation, so Sclose
  969. X * must be used.
  970. X *
  971. X * Sclose invokes Sdone which finalizes the buffer.
  972. X * There is no SIO_CLOSE_ALL value for fd because such a thing
  973. X * would imply that the program will exit very soon, therefore
  974. X * the closing of all file descriptors will be done in the kernel
  975. X * (and the finalization will be done by the finalization function
  976. X * NOTE: not true if the OS does not support a finalization function)
  977. X *
  978. X * There is no need to invoke SETUP; Sdone will do it.
  979. X */
  980. Xint Sclose( fd )
  981. X    int fd ;
  982. X{
  983. X#ifdef EVENTS
  984. X    EVENT( fd, EV_SCLOSE ) ;
  985. X#endif
  986. X
  987. X    if ( __SIO_FD_INITIALIZED( fd ) )
  988. X        if ( Sdone( fd ) == SIO_ERR )
  989. X            return( SIO_ERR ) ;
  990. X    return( close( fd ) ) ;
  991. X}
  992. X
  993. X
  994. X
  995. X/*
  996. X * Tie the file descriptor in_fd to the file descriptor out_fd
  997. X * This means that whenever a read(2) is done on in_fd, it is
  998. X * preceded by a write(2) on out_fd.
  999. X * Why this is nice to have:
  1000. X *     1) When used in filters it maximizes concurrency
  1001. X *        2) When the program prompts the user for something it forces
  1002. X *            the prompt string to be displayed even if it does not
  1003. X *            end with a '\n' (which would cause a flush).
  1004. X * In this implementation, out_fd cannot be a regular file.
  1005. X * This is done to avoid non-block-size write's.
  1006. X * The file descriptors are initialized if that has not been done
  1007. X * already. If any of them is initialized, it must be for the appropriate
  1008. X * stream type (input or output).
  1009. X *
  1010. X * NOTE: the code handles correctly the case when in_fd == out_fd
  1011. X */
  1012. Xint Stie( in_fd, out_fd )
  1013. X    int in_fd, out_fd ;
  1014. X{
  1015. X    struct stat st ;
  1016. X    register __sio_descriptor_t *dp ;
  1017. X    int was_initialized ;
  1018. X    boolean_e failed = NO ;
  1019. X
  1020. X#ifdef EVENTS
  1021. X    EVENT( in_fd, EV_STIE ) ;
  1022. X#endif
  1023. X
  1024. X    /*
  1025. X     * Check if the out_fd is open
  1026. X     */
  1027. X    if ( fstat( out_fd, &st ) == -1 )
  1028. X        return( SIO_ERR ) ;
  1029. X
  1030. X    /*
  1031. X     * If the out_fd refers to a regular file, the request is silently ignored
  1032. X     */
  1033. X    if ( ( st.st_mode & S_IFMT ) == S_IFREG )
  1034. X        return( 0 ) ;
  1035. X    
  1036. X    dp = &__sio_descriptors[ in_fd ] ;
  1037. X    was_initialized = dp->initialized ;        /* remember if it was initialized */
  1038. X    IO_SETUP( in_fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
  1039. X
  1040. X    /*
  1041. X     * Perform manual initialization of out_fd to avoid leaving in_fd
  1042. X     * initialized if the initialization of out_fd fails.
  1043. X     * If out_fd is initialized, check if it is used for output.
  1044. X     * If it is not initialized, initialize it for output.
  1045. X     */
  1046. X    dp = &__sio_descriptors[ out_fd ] ;
  1047. X    if ( DESCRIPTOR_INITIALIZED( dp ) )
  1048. X    {
  1049. X        if ( dp->stream_type != __SIO_OUTPUT_STREAM )
  1050. X        {
  1051. X            failed = YES ;
  1052. X            errno = EBADF ;
  1053. X        }
  1054. X    }
  1055. X    else
  1056. X        if ( __sio_init( dp, out_fd, __SIO_OUTPUT_STREAM ) == SIO_ERR )
  1057. X            failed = YES ;
  1058. X
  1059. X    if ( failed == NO )
  1060. X    {
  1061. X        __SIO_ID( in_fd ).tied_fd = out_fd ;
  1062. X        return( 0 ) ;
  1063. X    }
  1064. X    else
  1065. X    {
  1066. X        /*
  1067. X         * We failed. If we did any initialization, undo it
  1068. X         */
  1069. X        if ( ! was_initialized )
  1070. X        {
  1071. X            int save_errno = errno ;
  1072. X
  1073. X            (void) Sdone( in_fd ) ;
  1074. X            errno = save_errno ;
  1075. X        }
  1076. X        return( SIO_ERR ) ;
  1077. X    }
  1078. X}
  1079. X
  1080. X
  1081. X/*
  1082. X * Untie a file descriptor
  1083. X */
  1084. Xint Suntie( fd )
  1085. X    int fd ;
  1086. X{
  1087. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  1088. X
  1089. X#ifdef EVENTS
  1090. X    EVENT( fd, EV_SUNTIE ) ;
  1091. X#endif
  1092. X
  1093. X    CONTROL_SETUP( dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
  1094. X    
  1095. X    if ( IDP( dp )->tied_fd != SIO_NO_TIED_FD )
  1096. X    {
  1097. X        IDP( dp )->tied_fd = SIO_NO_TIED_FD ;
  1098. X        return( 0 ) ;
  1099. X    }
  1100. X    else
  1101. X    {
  1102. X        errno = EBADF ;
  1103. X        return( SIO_ERR ) ;
  1104. X    }
  1105. X}
  1106. X
  1107. X
  1108. X/*
  1109. X * Changes the type of buffering on the specified descriptor.
  1110. X * As a side-effect, it initializes the descriptor as an output stream.
  1111. X */
  1112. Xint Sbuftype( fd, type )
  1113. X    int fd, type ;
  1114. X{
  1115. X    register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
  1116. X
  1117. X#ifdef EVENTS
  1118. X    EVENT( fd, EV_SBUFTYPE ) ;
  1119. X#endif
  1120. X
  1121. X    /*
  1122. X     * Check for a valid type
  1123. X     */
  1124. X    if ( type != SIO_LINEBUF && type != SIO_FULLBUF && type != SIO_NOBUF )
  1125. X    {
  1126. X        errno = EINVAL ;
  1127. X        return( SIO_ERR ) ;
  1128. X    }
  1129. X
  1130. X    IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
  1131. X    ODP( dp )->buftype = type ;
  1132. X    return( 0 ) ;
  1133. X}
  1134. X
  1135. X
  1136. X#ifndef sio_memscan
  1137. X
  1138. XPRIVATE char *sio_memscan( from, how_many, ch )
  1139. X   char *from ;
  1140. X   int how_many ;
  1141. X   register char ch ;
  1142. X{
  1143. X   register char *p ;
  1144. X   register char *last = from + how_many ;
  1145. X
  1146. X   for ( p = from ; p < last ; p++ )
  1147. X      if ( *p == ch )
  1148. X         return( p ) ;
  1149. X      return( 0 ) ;
  1150. X}
  1151. X
  1152. X#endif    /* sio_memscan */
  1153. X
  1154. X
  1155. X#ifdef NEED_MEMCOPY
  1156. X
  1157. Xvoid __sio_memcopy( from, to, nbytes )
  1158. X   register char *from, *to ;
  1159. X   register int nbytes ;
  1160. X{
  1161. X   while ( nbytes-- )
  1162. X      *to++ = *from++ ;
  1163. X}
  1164. X
  1165. X#endif /* NEED_MEMCOPY */
  1166. X
  1167. X
  1168. END_OF_FILE
  1169.   if test 15212 -ne `wc -c <'libs/src/sio/sio.c'`; then
  1170.     echo shar: \"'libs/src/sio/sio.c'\" unpacked with wrong size!
  1171.   fi
  1172.   # end of 'libs/src/sio/sio.c'
  1173. fi
  1174. if test -f 'libs/src/sio/sio.h' -a "${1}" != "-c" ; then 
  1175.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.h'\"
  1176. else
  1177.   echo shar: Extracting \"'libs/src/sio/sio.h'\" \(6642 characters\)
  1178.   sed "s/^X//" >'libs/src/sio/sio.h' <<'END_OF_FILE'
  1179. X/*
  1180. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  1181. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  1182. X * and conditions for redistribution.
  1183. X */
  1184. X
  1185. X/*
  1186. X * $Id: sio.h,v 8.1 1993/03/13 01:13:58 panos Exp $
  1187. X */
  1188. X
  1189. X#ifndef __SIO_H
  1190. X#define __SIO_H
  1191. X
  1192. X#include <errno.h>
  1193. X#include <varargs.h>
  1194. X
  1195. X/*
  1196. X * Naming conventions:
  1197. X *        1) SIO functions and macros have names starting with a capital S
  1198. X *        2) SIO constants meant to be used by user programs have 
  1199. X *            names starting with SIO_
  1200. X *        3) Internal functions, struct identifiers, enum identifiers 
  1201. X *            etc. have names starting with __sio
  1202. X *        4) Internal constants and macros have names starting with __SIO
  1203. X */
  1204. X
  1205. X
  1206. X/*
  1207. X * external constants
  1208. X *
  1209. X * SIO_FLUSH_ALL: flush all output streams
  1210. X * SIO_EOF:    eof on stream
  1211. X * SIO_ERR: operation failed
  1212. X */
  1213. X#define SIO_FLUSH_ALL                (-1)
  1214. X#define SIO_EOF                        (-2)
  1215. X#define SIO_ERR                        (-1)
  1216. X
  1217. X/*
  1218. X * Undo types
  1219. X */
  1220. X#define SIO_UNDO_LINE        0
  1221. X#define SIO_UNDO_CHAR        1
  1222. X
  1223. X/*
  1224. X * Buffering types
  1225. X */
  1226. X#define SIO_FULLBUF            0
  1227. X#define SIO_LINEBUF            1
  1228. X#define SIO_NOBUF                2
  1229. X
  1230. X/*
  1231. X * Descriptor for an input stream
  1232. X */
  1233. Xstruct __sio_input_descriptor
  1234. X{
  1235. X    /*
  1236. X     * buf:        points to the buffer area.
  1237. X     *                When doing memory mapping, it is equal to the unit 
  1238. X     *                from which we are reading. When doing buffered I/O
  1239. X     *                it points to the primary buffer.
  1240. X     */
  1241. X    char *buf ;
  1242. X    unsigned buffer_size ;
  1243. X
  1244. X    char *start ;                 /* start of valid buffer contents       */
  1245. X    char *end ;                   /* end of valid buffer contents + 1     */
  1246. X    char *nextb ;                 /* pointer to next byte to read/write     */
  1247. X                                            /* Always:  start <= nextb < end            */
  1248. X
  1249. X    unsigned line_length ;
  1250. X    int max_line_length ;
  1251. X    int tied_fd ;
  1252. X
  1253. X    int memory_mapped ;                /* flag to denote if we use                */
  1254. X                                            /* memory mapping                                */
  1255. X} ;
  1256. X
  1257. Xtypedef struct __sio_input_descriptor __sio_id_t ;
  1258. X
  1259. X
  1260. X/*
  1261. X * Descriptor for an output stream
  1262. X */
  1263. Xstruct __sio_output_descriptor
  1264. X{
  1265. X    /*
  1266. X     * buf:        points to the buffer area.
  1267. X     * buf_end: is equal to buf + buffer_size
  1268. X     */
  1269. X    char *buf ;
  1270. X    char *buf_end ;
  1271. X
  1272. X    unsigned buffer_size ;
  1273. X
  1274. X    char *start ;                 /* start of valid buffer contents       */
  1275. X                                            /* (used by the R and W functions)         */
  1276. X    char *nextb ;                 /* pointer to next byte to read/write  */
  1277. X                                            /* Always:  start <= nextb < buf_end    */
  1278. X    int buftype ;                        /* type of buffering                         */
  1279. X} ;
  1280. X
  1281. Xtypedef struct __sio_output_descriptor __sio_od_t ;
  1282. X
  1283. X
  1284. X
  1285. X/*
  1286. X * Stream types
  1287. X */
  1288. Xenum __sio_stream { __SIO_INPUT_STREAM, __SIO_OUTPUT_STREAM } ;
  1289. X
  1290. X
  1291. X/*
  1292. X * General descriptor
  1293. X */
  1294. Xstruct __sio_descriptor
  1295. X{
  1296. X    union
  1297. X    {
  1298. X        __sio_id_t input_descriptor ;
  1299. X        __sio_od_t output_descriptor ;
  1300. X    } descriptor ;
  1301. X    enum __sio_stream stream_type ;
  1302. X    int initialized ;
  1303. X} ;
  1304. X
  1305. Xtypedef struct __sio_descriptor __sio_descriptor_t ;
  1306. X
  1307. X
  1308. X/*
  1309. X * The array of descriptors (as many as available file descriptors)
  1310. X */
  1311. Xextern __sio_descriptor_t *__sio_descriptors ;
  1312. X
  1313. Xextern int errno ;
  1314. X
  1315. X
  1316. X/*
  1317. X * Internally used macros
  1318. X */
  1319. X#define __SIO_FD_INITIALIZED( fd )        (__sio_descriptors[ fd ].initialized)
  1320. X#define __SIO_ID( fd )    (__sio_descriptors[ fd ].descriptor.input_descriptor)
  1321. X#define __SIO_OD( fd )    (__sio_descriptors[ fd ].descriptor.output_descriptor)
  1322. X#define __SIO_MUST_FLUSH( od, ch )                                                    \
  1323. X                    ( (od).buftype != SIO_FULLBUF &&                                    \
  1324. X                        ( (od).buftype == SIO_NOBUF || ch == '\n' ) )
  1325. X
  1326. X
  1327. X/*
  1328. X * SIO Macros:
  1329. X *
  1330. X *        SIOLINELEN( fd )
  1331. X *        SIOMAXLINELEN( fd )
  1332. X *        Sputchar( fd, c )
  1333. X *        Sgetchar( fd )
  1334. X *
  1335. X * NOTE: The maximum line size depends on whether the descriptor
  1336. X *            was originally memory mapped. If it was, then the maximum
  1337. X *            line size will be the map_unit_size (a function of the system
  1338. X *            page size and PAGES_MAPPED). Otherwise, it will be either the
  1339. X *            optimal block size as reported by stat(2) or SIO_BUFFER_SIZE.
  1340. X */
  1341. X
  1342. X#define SIOLINELEN( fd )      __SIO_ID( fd ).line_length
  1343. X#define SIOMAXLINELEN( fd )                                                                    \
  1344. X    (                                                                                                    \
  1345. X        __SIO_FD_INITIALIZED( fd )                                                                \
  1346. X            ? (                                                                                         \
  1347. X                 (__sio_descriptors[ fd ].stream_type == __SIO_INPUT_STREAM)        \
  1348. X                    ? __SIO_ID( fd ).max_line_length                                            \
  1349. X                    : ( errno = EBADF, SIO_ERR )                                                \
  1350. X              )                                                                                        \
  1351. X            : (        /* not initialized; initialize it for input */                    \
  1352. X                 (__sio_init( &__sio_descriptors[ fd ], fd, __SIO_INPUT_STREAM )    \
  1353. X                                                                                    == SIO_ERR)        \
  1354. X                    ? SIO_ERR                                                                        \
  1355. X                    : __SIO_ID( fd ).max_line_length                                            \
  1356. X              )                                                                                        \
  1357. X    )
  1358. X
  1359. X
  1360. X
  1361. X/*
  1362. X * Adds a character to a buffer, returns the character or SIO_ERR
  1363. X */
  1364. X#define  __SIO_ADDCHAR( od, fd, c )                                  \
  1365. X     ( od.buftype == SIO_FULLBUF )                                   \
  1366. X         ? (int) ( *(od.nextb)++ = (unsigned char) (c) )             \
  1367. X         : ( od.buftype == SIO_LINEBUF )                             \
  1368. X               ? ( ( *(od.nextb) = (unsigned char) (c) ) != '\n' )   \
  1369. X                     ? (int) *(od.nextb)++                           \
  1370. X                     : Sputc( fd, *(od.nextb) )                      \
  1371. X               : Sputc( fd, c )
  1372. X
  1373. X
  1374. X/*
  1375. X * The Sgetchar/Sputchar macros depend on the fact that the fields 
  1376. X *                 nextb, buf_end, end
  1377. X * are 0 if a stream descriptor is not being used or has not yet been
  1378. X * initialized.
  1379. X * This is true initially because of the static allocation of the
  1380. X * descriptor array, and Sdone must make sure that it is true
  1381. X * after I/O on a descriptor is over.
  1382. X */
  1383. X#define Sputchar( fd, c )                                                        \
  1384. X        (                                                                                \
  1385. X            ( __SIO_OD( fd ).nextb < __SIO_OD( fd ).buf_end )            \
  1386. X                ? ( __SIO_ADDCHAR( __SIO_OD( fd ), fd, c ) )                \
  1387. X                : Sputc( fd, c )                                                    \
  1388. X        )
  1389. X
  1390. X#define Sgetchar( fd )                                                    \
  1391. X        (                                                                        \
  1392. X            ( __SIO_ID( fd ).nextb < __SIO_ID( fd ).end )        \
  1393. X                ? (int) *__SIO_ID( fd ).nextb++                         \
  1394. X                : Sgetc( fd )                                                \
  1395. X        )
  1396. X
  1397. X
  1398. X#ifdef __ARGS
  1399. X#undef __ARGS
  1400. X#endif
  1401. X
  1402. X#ifdef PROTOTYPES
  1403. X#    define __ARGS( s )                    s
  1404. X#else
  1405. X#    define __ARGS( s )                    ()
  1406. X#endif
  1407. X
  1408. X/*
  1409. X * The Read functions
  1410. X */
  1411. Xint Sread __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  1412. Xint Sgetc __ARGS( ( int fd ) ) ;
  1413. Xchar *Srdline __ARGS( ( int fd ) ) ;
  1414. Xchar *Sfetch __ARGS( ( int fd, long *length ) ) ;
  1415. X
  1416. X/*
  1417. X * The Write functions
  1418. X */
  1419. Xint Swrite __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  1420. Xint Sputc __ARGS( ( int fd, char c ) ) ;
  1421. Xint Sprint __ARGS( ( int fd, char *format, ... ) ) ;
  1422. Xint Sprintv __ARGS( ( int fd, char *format, va_list ) ) ;
  1423. X
  1424. X/*
  1425. X * other functions
  1426. X */
  1427. Xint Sdone __ARGS( ( int fd ) ) ;
  1428. Xint Sundo __ARGS( ( int fd, int type ) ) ;
  1429. Xint Sflush __ARGS( ( int fd ) ) ;
  1430. Xint Sclose __ARGS( ( int fd ) ) ;
  1431. Xint Sbuftype __ARGS( ( int fd, int type ) ) ;
  1432. X
  1433. X#endif /* __SIO_H */
  1434. X
  1435. END_OF_FILE
  1436.   if test 6642 -ne `wc -c <'libs/src/sio/sio.h'`; then
  1437.     echo shar: \"'libs/src/sio/sio.h'\" unpacked with wrong size!
  1438.   fi
  1439.   # end of 'libs/src/sio/sio.h'
  1440. fi
  1441. if test -f 'libs/src/sio/suite/print.c' -a "${1}" != "-c" ; then 
  1442.   echo shar: Will not clobber existing file \"'libs/src/sio/suite/print.c'\"
  1443. else
  1444.   echo shar: Extracting \"'libs/src/sio/suite/print.c'\" \(8243 characters\)
  1445.   sed "s/^X//" >'libs/src/sio/suite/print.c' <<'END_OF_FILE'
  1446. X/*
  1447. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  1448. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  1449. X * and conditions for redistribution.
  1450. X */
  1451. X
  1452. Xstatic char RCSid[] = "$Id: print.c,v 8.1 1993/03/13 01:21:48 panos Exp $" ;
  1453. X
  1454. X#include <stdio.h>
  1455. X#include <math.h>
  1456. X#include <values.h>
  1457. X#include <string.h>
  1458. X
  1459. X#include "sio.h"
  1460. X
  1461. X#define FLUSH()            fflush( stdout ) ; Sflush( 1 )
  1462. X#define COMPARE( printf_count, sprint_count )                                        \
  1463. X                            if ( printf_count != sprint_count )                            \
  1464. X                                printf( "printf_count = %d, sprint_count = %d\n",    \
  1465. X                                            printf_count, sprint_count )
  1466. X
  1467. Xenum bool { NO = 0, YES = 1 } ;
  1468. X
  1469. Xenum test_flag
  1470. X{
  1471. X    DECIMAL, HEX, CAP_HEX, OCTAL, UNSIGNED,
  1472. X    F_FLOAT, G_FLOAT, E_FLOAT, CAP_E_FLOAT, CAP_G_FLOAT,
  1473. X    CHAR, STRING,
  1474. X    POINTER,
  1475. X    BOUND,
  1476. X    N_FLAGS
  1477. X} ;
  1478. X
  1479. Xtypedef enum test_flag FLAG ;
  1480. X
  1481. X#define CHECK( f )                if ( ! flags[ f ] ) return
  1482. X
  1483. X/*
  1484. X * Flags
  1485. X */
  1486. Xenum bool flags[ N_FLAGS ] ;
  1487. X
  1488. Xchar *precision ;
  1489. Xchar *width ;
  1490. Xchar *print_flags ;
  1491. X
  1492. Xint i_begin = 123456 ;
  1493. Xint i_end = 123470 ;
  1494. Xint i_step = 1 ;
  1495. X
  1496. Xdouble f_begin = 1.234567654312 ;
  1497. Xdouble f_end = 2.0 ;
  1498. Xdouble f_step = 0.011 ;
  1499. X
  1500. X#define LEN( s )                    ( s ? strlen( s ) : 0 )
  1501. X
  1502. Xchar *format( f )
  1503. X    char *f ;
  1504. X{
  1505. X    char *malloc() ;
  1506. X    static char *newfmt ;
  1507. X
  1508. X    if ( newfmt )
  1509. X        free( newfmt ) ;
  1510. X
  1511. X    newfmt = malloc( strlen( f )
  1512. X                + LEN( precision ) + LEN( width ) + LEN( print_flags ) + 2 ) ;
  1513. X    (void) strcpy( newfmt, "%" ) ;
  1514. X    if ( print_flags )
  1515. X        (void) strcat( newfmt, print_flags ) ;
  1516. X    if ( width )
  1517. X        (void) strcat( newfmt, width ) ;
  1518. X    if ( precision )
  1519. X        (void) strcat( strcat( newfmt, "." ), precision ) ;
  1520. X    (void) strcat( newfmt, &f[1] ) ;
  1521. X    return( newfmt ) ;
  1522. X}
  1523. X
  1524. X#define decimal_test()            integer_test( "%d %d\n", DECIMAL )
  1525. X#define hex_test()                integer_test( "%x %x\n", HEX )
  1526. X#define cap_hex_test()            integer_test( "%X %X\n", CAP_HEX )
  1527. X#define octal_test()                integer_test( "%o %o\n", OCTAL )
  1528. X#define unsigned_test()            integer_test( "%u %u\n", UNSIGNED )
  1529. X
  1530. Xvoid integer_test( fmt, flag )
  1531. X    char *fmt ;
  1532. X    FLAG flag ;
  1533. X{
  1534. X    int i ;
  1535. X    int ccs, ccp ;
  1536. X
  1537. X    CHECK( flag ) ;
  1538. X    fmt = format( fmt ) ;
  1539. X
  1540. X    for ( i = i_begin ; i < i_end ; i += i_step )
  1541. X    {
  1542. X        ccp = printf( fmt, -i, i ) ;
  1543. X        ccs = Sprint( 2, fmt, -i, i ) ;
  1544. X        FLUSH() ;
  1545. X        COMPARE( ccp, ccs ) ;
  1546. X    }
  1547. X}
  1548. X
  1549. X
  1550. X#define f_float_test()            fp_test( "%f\n", F_FLOAT )
  1551. X#define g_float_test()            fp_test( "%g\n", G_FLOAT )
  1552. X#define e_float_test()            fp_test( "%e\n", E_FLOAT )
  1553. X#define cap_e_float_test()        fp_test( "%E\n", CAP_E_FLOAT )            
  1554. X#define cap_g_float_test()        fp_test( "%G\n", CAP_G_FLOAT )
  1555. X
  1556. Xvoid fp_test( fmt, flag )
  1557. X    char *fmt ;
  1558. X    FLAG flag ;
  1559. X{
  1560. X    double d ;
  1561. X    double step ;
  1562. X    int ccs, ccp ;
  1563. X
  1564. X    CHECK( flag ) ;
  1565. X    fmt = format( fmt ) ;
  1566. X    
  1567. X    for ( d = f_begin, step = f_step ; d < f_end ; d += step, step += step )
  1568. X    {
  1569. X
  1570. X        ccp = printf( fmt, d ) ;
  1571. X        ccs = Sprint( 2, fmt, d ) ;
  1572. X        FLUSH() ;
  1573. X        COMPARE( ccp, ccs ) ;
  1574. X    }
  1575. X}
  1576. X
  1577. X
  1578. Xvoid char_test()
  1579. X{
  1580. X    char *s = "foobar" ;
  1581. X    int len = strlen( s ) ;
  1582. X    int i ;
  1583. X    char *fmt = "%c\n" ;
  1584. X    int ccs, ccp ;
  1585. X
  1586. X    CHECK( CHAR ) ;
  1587. X    fmt = format( fmt ) ;
  1588. X
  1589. X    for ( i = 0 ; i < len ; i++ )
  1590. X    {
  1591. X        ccp = printf( fmt, s[ i ] ) ;
  1592. X        ccs = Sprint( 2, fmt, s[ i ] ) ;
  1593. X        FLUSH() ;
  1594. X        COMPARE( ccp, ccs ) ;
  1595. X    }
  1596. X}
  1597. X
  1598. X
  1599. Xvoid string_test()
  1600. X{
  1601. X    static char *list[] = 
  1602. X    {
  1603. X        "foobar",
  1604. X        "hello",
  1605. X        "world",
  1606. X        "this is a very long string, a really long string, really, true, honest",
  1607. X        "i am getting tired of this",
  1608. X        "SO THIS IS THE END",
  1609. X        0
  1610. X    } ;
  1611. X    char *fmt = "%s\n" ;
  1612. X    char **p ;
  1613. X    int ccp, ccs ;
  1614. X
  1615. X    CHECK( STRING ) ;
  1616. X    fmt = format( fmt ) ;
  1617. X
  1618. X    for ( p = &list[ 0 ] ; *p ; p++ )
  1619. X    {
  1620. X        ccp = printf( fmt, *p ) ;
  1621. X        ccs = Sprint( 2, fmt, *p ) ;
  1622. X        FLUSH() ;
  1623. X        COMPARE( ccp, ccs ) ;
  1624. X    }
  1625. X}
  1626. X
  1627. X
  1628. Xvoid pointer_test()
  1629. X{
  1630. X    struct foo
  1631. X    {
  1632. X        char bar1 ;
  1633. X        short bar2 ;
  1634. X        int bar3 ;
  1635. X        long bar4 ;
  1636. X        char *bar5 ;
  1637. X    } foo, *end = &foo, *p ;
  1638. X    char *fmt = "%p\n" ;
  1639. X    int ccp, ccs ;
  1640. X
  1641. X    CHECK( POINTER ) ;
  1642. X    fmt = format( fmt ) ;
  1643. X
  1644. X    end += 10 ;
  1645. X    for ( p = &foo ; p < end ; p++ )
  1646. X    {
  1647. X        ccp = printf( fmt, p ) ;
  1648. X        ccs = Sprint( 2, fmt, p ) ;
  1649. X        FLUSH() ;
  1650. X    }
  1651. X}
  1652. X
  1653. X
  1654. X/* 
  1655. X * bound_test is only available on SunOS 4.x
  1656. X */
  1657. X#if defined( sun )
  1658. X
  1659. Xvoid bound_test()
  1660. X{
  1661. X    char *fmt ;
  1662. X    double bound_values[ 10 ] ;
  1663. X    static char *bound_names[] =
  1664. X    {
  1665. X        "min_subnormal",
  1666. X        "max_subnormal",
  1667. X        "min_normal",
  1668. X        "max_normal",
  1669. X        "infinity",
  1670. X        "quiet_nan",
  1671. X        "signaling_nan"
  1672. X    } ;
  1673. X    int n_values ;
  1674. X    int i ;
  1675. X    int ccp, ccs ;
  1676. X
  1677. X    bound_values[ 0 ] = min_subnormal() ;
  1678. X    bound_values[ 1 ] = max_subnormal() ;
  1679. X    bound_values[ 2 ] = min_normal() ;
  1680. X    bound_values[ 3 ] = max_normal() ;
  1681. X    bound_values[ 4 ] = infinity() ;
  1682. X    bound_values[ 5 ] = quiet_nan( 7L ) ;
  1683. X    bound_values[ 6 ] = signaling_nan( 7L ) ;
  1684. X    n_values = 7 ;
  1685. X
  1686. X    CHECK( BOUND ) ;
  1687. X
  1688. X    for ( i = 0 ; i < n_values ; i++ )
  1689. X    {
  1690. X        double d = bound_values[ i ] ;
  1691. X        char *name = bound_names[ i ] ;
  1692. X
  1693. X        fmt = format( "%f (%s)\n" ) ;
  1694. X        ccp = printf( fmt, d, name ) ;
  1695. X        ccs = Sprint( 2, fmt, d, name ) ;
  1696. X        FLUSH() ;
  1697. X        COMPARE( ccp, ccs ) ;
  1698. X
  1699. X        fmt = format( "%e (%s)\n" ) ;
  1700. X        ccp = printf( fmt, d, name ) ;
  1701. X        ccs = Sprint( 2, fmt, d, name ) ;
  1702. X        FLUSH() ;
  1703. X        COMPARE( ccp, ccs ) ;
  1704. X
  1705. X        fmt = format( "%g (%s)\n" ) ;
  1706. X        ccp = printf( fmt, d, name ) ;
  1707. X        ccs = Sprint( 2, fmt, d, name ) ;
  1708. X        FLUSH() ;
  1709. X        COMPARE( ccp, ccs ) ;
  1710. X    }
  1711. X
  1712. X    fmt = format( "%d (MININT)\n" ) ;
  1713. X    ccp = printf( fmt, -MAXINT-1 ) ;
  1714. X    ccs = Sprint( 2, fmt, -MAXINT-1 ) ;
  1715. X    COMPARE( ccp, ccs ) ;
  1716. X}
  1717. X#else
  1718. Xvoid bound_test()
  1719. X{
  1720. X}
  1721. X#endif
  1722. X
  1723. X
  1724. Xint get_options( argc, argv )
  1725. X    int argc ;
  1726. X    char *argv[] ;
  1727. X{
  1728. X    int arg_index = 1 ;
  1729. X    char *p ;
  1730. X    double atof() ;
  1731. X
  1732. X    for ( arg_index = 1 ;
  1733. X            arg_index < argc && argv[ arg_index ][ 0 ] == '-' ; arg_index++ )
  1734. X    {
  1735. X        switch ( argv[ arg_index ][ 1 ] )
  1736. X        {
  1737. X            case 'd':
  1738. X                flags[ DECIMAL ] = YES ;
  1739. X                break ;
  1740. X            
  1741. X            case 'x':
  1742. X                flags[ HEX ] = YES ;
  1743. X                break ;
  1744. X            
  1745. X            case 'X':
  1746. X                flags[ CAP_HEX ] = YES ;
  1747. X                break ;
  1748. X            
  1749. X            case 'o':
  1750. X                flags[ OCTAL ] = YES ;
  1751. X                break ;
  1752. X            
  1753. X            case 'u':
  1754. X                flags[ UNSIGNED ] = YES ;
  1755. X                break ;
  1756. X
  1757. X            case 'f':
  1758. X                flags[ F_FLOAT ] = YES ;
  1759. X                break ;
  1760. X            
  1761. X            case 'g':
  1762. X                flags[ G_FLOAT ] = YES ;
  1763. X                break ;
  1764. X            
  1765. X            case 'e':
  1766. X                flags[ E_FLOAT ] = YES ;
  1767. X                break ;
  1768. X            
  1769. X            case 'E':
  1770. X                flags[ CAP_E_FLOAT ] = YES ;
  1771. X                break ;
  1772. X            
  1773. X            case 'G':
  1774. X                flags[ CAP_G_FLOAT ] = YES ;
  1775. X                break ;
  1776. X
  1777. X            case 'c':
  1778. X                flags[ CHAR ] = YES ;
  1779. X                break ;
  1780. X            
  1781. X            case 's':
  1782. X                flags[ STRING ] = YES ;
  1783. X                break ;
  1784. X            
  1785. X            case 'p':
  1786. X                flags[ POINTER ] = YES ;
  1787. X                break ;
  1788. X            
  1789. X            case 'b':        /* this is for checking bounds in fp formats */
  1790. X                flags[ BOUND ] = YES ;
  1791. X                break ;
  1792. X                
  1793. X            case 'P':    /* precision, must be followed by a number, e.g. -P10 */
  1794. X                precision = &argv[ arg_index ][ 2 ] ;
  1795. X                break ;
  1796. X            
  1797. X            case 'W':    /* width, must be followed by a number, e.g. -w10 */
  1798. X                width = &argv[ arg_index ][ 2 ] ;
  1799. X                break ;
  1800. X            
  1801. X            case 'F':    /* flags, whatever is after the F */
  1802. X                print_flags = &argv[ arg_index ][ 2 ] ;
  1803. X                break ;
  1804. X            
  1805. X            /*
  1806. X             * Options recognized in this case:    -Vf, -Vi
  1807. X             * Usage: -V[if] start end step
  1808. X             */
  1809. X            case 'V':
  1810. X                /*
  1811. X                 * Check if we have enough extra arguments
  1812. X                 */
  1813. X                if ( argc - ( arg_index + 1 ) < 3 )
  1814. X                {
  1815. X                    fprintf( stderr, "Insufficient # of args after V option\n" ) ;
  1816. X                    exit( 1 ) ;
  1817. X                }
  1818. X                switch ( argv[ arg_index ][ 2 ] )
  1819. X                {
  1820. X                    case 'f':
  1821. X                        f_begin = atof( argv[ arg_index+1 ] ) ;
  1822. X                        f_end   = atof( argv[ arg_index+2 ] ) ;
  1823. X                        f_step  = atof( argv[ arg_index+3 ] ) ;
  1824. X                        break ;
  1825. X                    
  1826. X                    case 'i':
  1827. X                        i_begin = atoi( argv[ arg_index+1 ] ) ;
  1828. X                        i_end   = atoi( argv[ arg_index+2 ] ) ;
  1829. X                        i_step  = atoi( argv[ arg_index+3 ] ) ;
  1830. X                        break ;
  1831. X                }
  1832. X                arg_index += 3 ;
  1833. X                break ;
  1834. X
  1835. X            case 'S':
  1836. X                f_step = atof( &argv[ arg_index ][ 2 ] ) ;
  1837. X                break ;
  1838. X        }
  1839. X    }
  1840. X    return( arg_index ) ;
  1841. X}
  1842. X
  1843. X
  1844. X#define EQ( s1, s2 )                ( strcmp( s1, s2 ) == 0 )
  1845. X
  1846. X
  1847. Xint main( argc, argv )
  1848. X    int argc ;
  1849. X    char *argv[] ;
  1850. X{
  1851. X
  1852. X    if ( Sbuftype( 2, SIO_LINEBUF ) == SIO_ERR )
  1853. X    {
  1854. X        char *msg = "Sbuftype failed\n" ;
  1855. X
  1856. X        write( 2, msg, strlen( msg ) ) ;
  1857. X        exit( 1 ) ;
  1858. X    }
  1859. X
  1860. X    if ( argc == 1 || argc == 2 && EQ( argv[ 1 ], "ALL" ) )
  1861. X    {
  1862. X        /* perform all tests */
  1863. X        int i ;
  1864. X
  1865. X        for ( i = 0 ; i < N_FLAGS ; i++ )
  1866. X            flags[ i ] = YES ;
  1867. X    }
  1868. X    else
  1869. X        (void) get_options( argc, argv ) ;
  1870. X
  1871. X    decimal_test() ;
  1872. X    hex_test() ;
  1873. X    cap_hex_test() ;
  1874. X    octal_test() ;
  1875. X    unsigned_test() ;
  1876. X
  1877. X    f_float_test() ;
  1878. X    g_float_test() ;
  1879. X    e_float_test() ;
  1880. X    cap_g_float_test() ;
  1881. X    cap_e_float_test() ;
  1882. X
  1883. X    string_test() ;
  1884. X    char_test() ;
  1885. X    pointer_test() ;
  1886. X    bound_test() ;
  1887. X    exit( 0 ) ;
  1888. X}
  1889. END_OF_FILE
  1890.   if test 8243 -ne `wc -c <'libs/src/sio/suite/print.c'`; then
  1891.     echo shar: \"'libs/src/sio/suite/print.c'\" unpacked with wrong size!
  1892.   fi
  1893.   # end of 'libs/src/sio/suite/print.c'
  1894. fi
  1895. if test -f 'libs/src/str/strs.c' -a "${1}" != "-c" ; then 
  1896.   echo shar: Will not clobber existing file \"'libs/src/str/strs.c'\"
  1897. else
  1898.   echo shar: Extracting \"'libs/src/str/strs.c'\" \(6391 characters\)
  1899.   sed "s/^X//" >'libs/src/str/strs.c' <<'END_OF_FILE'
  1900. X/*
  1901. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  1902. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  1903. X * and conditions for redistribution.
  1904. X */
  1905. X
  1906. Xstatic char RCSid[] = "$Id: strs.c,v 3.1 1993/06/13 02:50:39 panos Exp $" ;
  1907. X
  1908. X#include <ctype.h>
  1909. X#include <memory.h>
  1910. X#include <varargs.h>
  1911. X
  1912. Xchar *malloc() ;
  1913. X
  1914. X#include "ss_impl.h"
  1915. X
  1916. X/*
  1917. X * NOTE: The brute force method (with the __strs_bfops) must be always 
  1918. X *         available so that we can switch to it if another method fails.
  1919. X */
  1920. Xextern struct ss_ops __strs_bfops ;
  1921. Xextern struct ss_ops __strs_rkops ;
  1922. Xextern struct ss_ops __strs_kmpops ;
  1923. Xextern struct ss_ops __strs_sbmops ;
  1924. Xextern struct ss_ops __strs_bmhops ;
  1925. Xextern struct ss_ops __strs_soops ;
  1926. X
  1927. X/*
  1928. X * NOTE: This table is arranged according to increasing method number.
  1929. X *            This allows quick indexing into it using the user-provided
  1930. X *            method as a hint:
  1931. X *                if ( selection_table[ user_method ].method == user_method )
  1932. X *                    FOUND
  1933. X *                else
  1934. X *                    DO SEQUENTIAL SEARCH
  1935. X *            This allows both quick access and a change of method numbers
  1936. X *            in the future without requiring recompilation of programs in
  1937. X *            order to work with new versions of the library.
  1938. X */
  1939. Xstatic struct ss_select selection_table[] =
  1940. X    {
  1941. X        { STRS_BF,                    &__strs_bfops        },
  1942. X        { STRS_RK,                    &__strs_rkops        },
  1943. X        { STRS_KMP,                    &__strs_kmpops        },
  1944. X        { STRS_SBM,                    &__strs_sbmops        },
  1945. X        { STRS_BMH,                    &__strs_bmhops        },
  1946. X        { STRS_SO,                    &__strs_soops        },
  1947. X        { 0,                            0                        }
  1948. X    } ;
  1949. X
  1950. Xstatic char identity_map[ ALPHABET_SIZE ] ;
  1951. Xstatic char upper_to_lower_map[ ALPHABET_SIZE ] ;
  1952. X
  1953. Xstatic int tables_initialized ;
  1954. X
  1955. X/*
  1956. X * This header is returned when an empty pattern is given to strs_setup.
  1957. X * The rest of the functions check ss_patlen and do nothing if that is zero.
  1958. X * ss_patlen in this header will be initialized to zero.
  1959. X */
  1960. Xstatic header_s empty_pattern_header ;
  1961. X
  1962. X
  1963. XPRIVATE void initialize_tables()
  1964. X{
  1965. X    int i ;
  1966. X
  1967. X    for ( i = 0 ; i < sizeof( upper_to_lower_map ) ; i++ )
  1968. X    {
  1969. X        if ( isascii( i ) && isupper( i ) )
  1970. X            upper_to_lower_map[ i ] = i + 'a' - 'A' ;
  1971. X        else
  1972. X            upper_to_lower_map[ i ] = i ;
  1973. X        identity_map[ i ] = i ;
  1974. X    }
  1975. X}
  1976. X
  1977. X
  1978. X/*
  1979. X * Initializes header
  1980. X *
  1981. X * Note that 'pattern' does not need to be a NUL-terminated string.
  1982. X */
  1983. XPRIVATE int init( hp, flags, pattern, patlen )
  1984. X    register header_s        *hp ;
  1985. X    int                        flags ;
  1986. X    char                        *pattern ;
  1987. X    int                        patlen ;
  1988. X{
  1989. X    int requested_method = SS_GETMETHOD( flags ) ;
  1990. X    register struct ss_select *selp ;
  1991. X
  1992. X    if ( ! tables_initialized )
  1993. X    {
  1994. X        initialize_tables() ;
  1995. X        tables_initialized = TRUE ;
  1996. X    }
  1997. X
  1998. X    /*
  1999. X     * Initialize header fields
  2000. X     */
  2001. X    SS_FLAGS( hp ) = SS_GETFLAGS( flags ) ;
  2002. X    SS_PATLEN( hp ) = patlen ;
  2003. X    if ( SS_SWITCH( hp ) && patlen < 4 )
  2004. X        SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  2005. X    else
  2006. X    {
  2007. X        /*
  2008. X         * Determine ops
  2009. X         */
  2010. X        if ( selection_table[ requested_method ].sel_method == requested_method )
  2011. X            selp = &selection_table[ requested_method ] ;
  2012. X        else
  2013. X            for ( selp = &selection_table[ 0 ] ; selp->sel_ops ; selp++ )
  2014. X                if ( requested_method == selp->sel_method )
  2015. X                    break ;
  2016. X        if ( selp->sel_ops )
  2017. X            SS_OPS( hp ) = selp->sel_ops ;
  2018. X        else if ( SS_SWITCH( hp ) )
  2019. X            SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  2020. X        else
  2021. X            return( SS_ERR ) ;
  2022. X    }
  2023. X
  2024. X    if ( SS_MALLOC( hp ) )
  2025. X    {
  2026. X        SS_PATTERN( hp ) = malloc( (unsigned)SS_PATLEN( hp ) ) ;
  2027. X        if ( SS_PATTERN( hp ) == CHAR_NULL )
  2028. X        {
  2029. X            (void) free( (char *)hp ) ;
  2030. X            return( SS_ERR ) ;
  2031. X        }
  2032. X        (void) memcpy( SS_PATTERN( hp ), pattern, (int)SS_PATLEN( hp ) ) ;
  2033. X    }
  2034. X    else
  2035. X        SS_PATTERN( hp ) = pattern ;
  2036. X
  2037. X    /*
  2038. X     * If the user asked for case-insensitive search, we create our own
  2039. X     * copy of the pattern in lower case. If the pattern is malloc'ed
  2040. X     * we overwrite, otherwise we malloc some memory and clear the
  2041. X     * STRS_NOMALLOC flag.
  2042. X     */
  2043. X    if ( SS_IGNCASE( hp ) )
  2044. X    {
  2045. X        char *new_pattern ;
  2046. X        register int i ;
  2047. X
  2048. X        SS_SETMAP( hp, upper_to_lower_map ) ;
  2049. X
  2050. X        if ( SS_MALLOC( hp ) )
  2051. X            new_pattern = SS_PATTERN( hp ) ;
  2052. X        else
  2053. X        {
  2054. X            new_pattern = malloc( (unsigned)SS_PATLEN( hp ) + 1 ) ;
  2055. X            if ( new_pattern == CHAR_NULL )
  2056. X                return( SS_ERR ) ;
  2057. X            SS_SETMALLOC( hp ) ;            /* clears the STRS_NOMALLOC flag */
  2058. X        }
  2059. X        for ( i = 0 ; i < SS_PATLEN( hp ) ; i++ )
  2060. X            new_pattern[ i ] = SS_MAP( hp, SS_PATTERN( hp )[ i ] ) ;
  2061. X        SS_PATTERN( hp ) = new_pattern ;
  2062. X    }
  2063. X    else
  2064. X        SS_SETMAP( hp, identity_map ) ;
  2065. X
  2066. X    for ( ;; )
  2067. X    {
  2068. X        if ( SS_SETUP( hp ) == SS_OK )
  2069. X            return( SS_OK ) ;
  2070. X        else
  2071. X        {
  2072. X            if ( ! SS_SWITCH( hp ) || SS_OPS( hp ) == &__strs_bfops )
  2073. X            {
  2074. X                if ( SS_MALLOC( hp ) )
  2075. X                    (void) free( (char *)hp ) ;
  2076. X                return( SS_ERR ) ;
  2077. X            }
  2078. X            SS_OPS( hp ) = &__strs_bfops ;
  2079. X        }
  2080. X    }
  2081. X}
  2082. X
  2083. X
  2084. X/*
  2085. X * Finalize header
  2086. X */
  2087. XPRIVATE void fini( hp )
  2088. X    header_s *hp ;
  2089. X{
  2090. X    SS_DONE( hp ) ;
  2091. X    if ( SS_MALLOC( hp ) )
  2092. X        (void) free( SS_PATTERN( hp ) ) ;
  2093. X}
  2094. X
  2095. X
  2096. X/*
  2097. X * Create a search handle
  2098. X */
  2099. Xstrs_h strs_setup( flags, pattern, va_alist )
  2100. X    int    flags ;
  2101. X    char    *pattern ;
  2102. X    va_dcl
  2103. X{
  2104. X    header_s        *hp ;
  2105. X    int            patlen ;
  2106. X    va_list        ap ;
  2107. X
  2108. X    hp = HP( malloc( sizeof( *hp ) ) ) ;
  2109. X    if ( hp == NULL )
  2110. X        return( NULL_HANDLE ) ;
  2111. X    
  2112. X    if ( flags & STRS_PATLEN )
  2113. X    {
  2114. X        va_start( ap ) ;
  2115. X        patlen = va_arg( ap, int ) ;
  2116. X        va_end( ap ) ;
  2117. X    }
  2118. X    else
  2119. X        patlen = strlen( pattern ) ;
  2120. X
  2121. X    if ( patlen == 0 )
  2122. X        return( (strs_h) &empty_pattern_header ) ;
  2123. X
  2124. X    if ( init( hp, flags, pattern, patlen ) == SS_OK )
  2125. X        return( (strs_h)hp ) ;
  2126. X    else
  2127. X    {
  2128. X        free( (char *)hp ) ;
  2129. X        return( NULL_HANDLE ) ;
  2130. X    }
  2131. X}
  2132. X
  2133. X
  2134. X/*
  2135. X * Destroy a search handle
  2136. X */
  2137. Xvoid strs_done( handle )
  2138. X    strs_h handle ;
  2139. X{
  2140. X    header_s *hp = HP( handle ) ;
  2141. X
  2142. X    if ( SS_PATLEN( hp ) != 0 )
  2143. X    {
  2144. X        fini( hp ) ;
  2145. X        (void) free( (char *) handle ) ;
  2146. X    }
  2147. X}
  2148. X
  2149. X
  2150. Xchar *strs_match( handle, str, len )
  2151. X    strs_h    handle ;
  2152. X    char        *str ;
  2153. X    int        len ;
  2154. X{
  2155. X    register header_s *hp = HP( handle ) ;
  2156. X
  2157. X    if ( SS_PATLEN( hp ) == 0 )
  2158. X        return( str ) ;
  2159. X    if ( SS_PATLEN( hp ) > len )
  2160. X        return( CHAR_NULL ) ;
  2161. X    return( SS_MATCH( hp, str, len ) ) ;
  2162. X}
  2163. X
  2164. X
  2165. X
  2166. Xchar *strs_search( flags, str, len, pattern, va_alist )
  2167. X    int    flags ;
  2168. X    char    *str ;
  2169. X    int    len ;
  2170. X    char    *pattern ;            /* NUL-terminated */
  2171. X    va_dcl
  2172. X{
  2173. X    header_s        t_header ;
  2174. X    char            *p ;
  2175. X    int            patlen ;
  2176. X    va_list        ap ;
  2177. X
  2178. X    if ( flags & STRS_PATLEN )
  2179. X    {
  2180. X        va_start( ap ) ;
  2181. X        patlen = va_arg( ap, int ) ;
  2182. X        va_end( ap ) ;
  2183. X    }
  2184. X    else
  2185. X        patlen = strlen( pattern ) ;
  2186. X
  2187. X    if ( patlen == 0 )
  2188. X        return( str ) ;
  2189. X
  2190. X    if ( patlen > len )
  2191. X        return( CHAR_NULL ) ;
  2192. X
  2193. X    if ( init( &t_header, flags | STRS_NOMALLOC, pattern, patlen ) == SS_OK )
  2194. X    {
  2195. X        p = SS_MATCH( &t_header, str, len ) ;
  2196. X        fini( &t_header ) ;
  2197. X        return( p ) ;
  2198. X    }
  2199. X    else
  2200. X        return( CHAR_NULL ) ;
  2201. X}
  2202. X
  2203. X
  2204. END_OF_FILE
  2205.   if test 6391 -ne `wc -c <'libs/src/str/strs.c'`; then
  2206.     echo shar: \"'libs/src/str/strs.c'\" unpacked with wrong size!
  2207.   fi
  2208.   # end of 'libs/src/str/strs.c'
  2209. fi
  2210. echo shar: End of archive 2 \(of 6\).
  2211. cp /dev/null ark2isdone
  2212. MISSING=""
  2213. for I in 1 2 3 4 5 6 ; do
  2214.     if test ! -f ark${I}isdone ; then
  2215.     MISSING="${MISSING} ${I}"
  2216.     fi
  2217. done
  2218. if test "${MISSING}" = "" ; then
  2219.     echo You have unpacked all 6 archives.
  2220.     rm -f ark[1-9]isdone
  2221. else
  2222.     echo You still must unpack the following archives:
  2223.     echo "        " ${MISSING}
  2224. fi
  2225. exit 0
  2226. exit 0 # Just in case...
  2227.