home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume23 / lome / part05 < prev    next >
Encoding:
Internet Message Format  |  1991-01-08  |  19.6 KB

  1. Path: j.cc.purdue.edu!mentor.cc.purdue.edu!purdue!bu.edu!snorkelwacker.mit.edu!apple!usc!julius.cs.uiuc.edu!wuarchive!uunet!papaya.bbn.com!rsalz
  2. From: rsalz@bbn.com (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v23i055:  Line oriented macro processor, Part05/09
  5. Message-ID: <3030@litchi.bbn.com>
  6. Date: 29 Nov 90 17:43:38 GMT
  7. Organization: BBN Systems and Technologies, Cambridge MA
  8. Lines: 563
  9. Approved: rsalz@uunet.UU.NET
  10.  
  11. Submitted-by: Darren New <new@ee.udel.edu>
  12. Posting-number: Volume 23, Issue 55
  13. Archive-name: lome/part05
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 8 (of 9)."
  22. # Contents:  PPL/PPLUnix.h
  23. # Wrapped by new@estelle.ee.udel.edu on Tue Aug 14 16:10:03 1990
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'PPL/PPLUnix.h' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'PPL/PPLUnix.h'\"
  27. else
  28. echo shar: Extracting \"'PPL/PPLUnix.h'\" \(17468 characters\)
  29. sed "s/^X//" >'PPL/PPLUnix.h' <<'END_OF_FILE'
  30. X/*
  31. X * PPLUnix.h
  32. X * Portable Programmer's Library General Host Parameters
  33. X * Copyright 1988,1990 Darren New.  All Rights Reserved.
  34. X * Unix version (SunOS 4.x with GCC)
  35. X *
  36. X * Started 19-Feb-88 DHN
  37. X * LastMod 19-Jul-90 DHN
  38. X *
  39. X */
  40. X
  41. X#ifndef PPL_h
  42. X#define PPL_h
  43. X
  44. X
  45. X/*****************************************************************
  46. X *
  47. X * This file gets included into every PPL source file.
  48. X * This one of the few include files that the host programmer
  49. X * should be changing.
  50. X *
  51. X */
  52. X
  53. X/*****************************************************************
  54. X *
  55. X * Include whatever files you need here to supply
  56. X *  strlen, strcpy, strncmp, strcmp, strchr
  57. X *  toupper, tolower
  58. X *  isalnum, isaplha, isdigit, isupper, islower, isspace
  59. X *  fault, assert, bomb
  60. X *
  61. X *  Note that assert can be compiled out, fault can always return
  62. X *  false, and bomb can call PLExit(PLsev_bomb).
  63. X *
  64. X */
  65. X
  66. X#include "stdio.h"
  67. X#include "stdlib.h"
  68. X#include "string.h"
  69. X#include "ctype.h"
  70. X#include "errno.h"
  71. X#include "unistd.h"
  72. X
  73. X#undef TRUE
  74. X#undef FALSE
  75. X#undef BITSPERLONG
  76. X#undef NULL
  77. X
  78. X
  79. X#define USE_ASSERT 1
  80. X
  81. X#include "Fault.h"
  82. X
  83. X/*****************************************************************
  84. X *
  85. X * These parameters describe your C compiler:
  86. X *
  87. X */
  88. X
  89. X/* First, some raw, low-level information advantage of which should
  90. X * probably never be taken.
  91. X */
  92. X#define BITSPERCHAR    8
  93. X#define BITSPERSHORT  (BITSPERCHAR*sizeof(short))
  94. X#define BITSPERLONG   (BITSPERCHAR*sizeof(long))
  95. X#define BITSPERFLOAT  (BITSPERCHAR*sizeof(float))
  96. X#define BITSPERDOUBLE (BITSPERCHAR*sizeof(double))
  97. X
  98. X/* To account for character-set differences, this macro (or function)
  99. X * must accept a digit and return an integer from 0 to 9.
  100. X * The other macro goes the other direction.
  101. X */
  102. X#define PLToInt(a) (a - '0')
  103. X#define PLToDig(a) (a + '0')
  104. X
  105. X/* Set this to the most efficient small integer value for your compiler.
  106. X * You may include "register" and "unsigned" without ill effect.
  107. X * Vars of this type are never passed as parameters and are usually
  108. X * loop indicies or array subscripts.
  109. X */
  110. Xtypedef unsigned short inx;
  111. X
  112. X/* Set this to a "generic pointer" (either void * or char *).
  113. X */
  114. Xtypedef void * ptr;
  115. X
  116. X/* Set this to a "boolean". This is not used for arrays, so faster
  117. X * over smaller is better. Do not make it "register".
  118. X */
  119. Xtypedef short bool;
  120. X
  121. X/* Set this to the proper value for your computer.
  122. X */
  123. X#ifndef NULL
  124. X#define NULL ((ptr)0)
  125. X#endif
  126. X
  127. X/* Set this to the size of the longest legal file name under the native
  128. X * operating system calls.
  129. X * Note that this MUST be declared as a LONG literal.
  130. X */
  131. X#define BIGFNAME 512L
  132. X
  133. X/* Set this to the largest piece of contiguous memory that can be
  134. X * allocated and accessed. I.e., this is the sizeof the largest
  135. X * character array that PLallocmem can return. E.g., IBM PC = 64K.
  136. X * This limits PLfillmem, PLallocmem, and other functions that
  137. X * access large chunks of contiguous memory.
  138. X * Note that this MUST be declared as a LONG literal.
  139. X */
  140. X#define BIGMEM 65530L
  141. X
  142. X/* Set this to the largest piece of contiguous I/O request that
  143. X * can be I/O'ed in one call. E.g., IBM PC = 31K.
  144. X * Note that this MUST be declared as a LONG literal.
  145. X */
  146. X#define BIGIO 32760L
  147. X
  148. X/* Set this to the smaller of BIGMEM and BIGIO
  149. X */
  150. X#define BIGBUF BIGIO
  151. X
  152. X/* Set this to the longest line reasonably returnable by the
  153. X * line-oriented I/O functions. I.e., this is the size of buffers
  154. X * allocated for GetLine and so on. This needn't be bigger that about 250.
  155. X */
  156. X#define BIGLINE 250
  157. X
  158. X/* Set this to 1 if you have structure assignment.
  159. X * Set this to 0 to use PLmemcpy.
  160. X * (note that PPL never passes structures by value)
  161. X */
  162. X#define STRUCT_ASSIGN 1
  163. X
  164. X/* Set this to 1 if you have prototype arguments for external functions.
  165. X * Set this to 0 to declare functions without prototype arguments.
  166. X */
  167. X#define PROTOTYPES 1
  168. X
  169. X/* Set this to 1 if you have ANSI-style function definition headings.
  170. X * Set this to 0 if you have PCC-style    function definition headings.
  171. X */
  172. X#define ANSIHEADERS 1
  173. X
  174. X/* Set this to 1 if HIDDEN functions need prototype declarations.
  175. X * Set this to 0 if you don't want them.
  176. X */
  177. X#define HIDPROTS 1
  178. X
  179. X/* Set this to 1 if you want to check arguments to library functions.
  180. X * Set this to 0 once your programs are debugged.
  181. X */
  182. X#define CHKARGS 1
  183. X
  184. X
  185. X
  186. X
  187. X/*****************************************************************
  188. X *
  189. X * These parameters are utility macros. Do not change them!
  190. X *
  191. X */
  192. Xtypedef char * str;    /* '\0' terminated string */
  193. X#define EOS '\0'
  194. X
  195. X#define loop while(1)   /* like other langs */
  196. X
  197. X#define HIDDEN static    /* hidden objects go away (can be changed to comment for stupid debuggers) */
  198. X
  199. X/* Use this macro to assign structures */
  200. X#if STRUCT_ASSIGN
  201. X#define SASGN(a, b) (a = b)
  202. X#else
  203. X#define SASGN(a, b) PLCopyMem(&a, &b, sizeof(a))
  204. X#endif
  205. X
  206. X/* Use this macro to declare arguments on function declarations */
  207. X#if PROTOTYPES
  208. X#define ARGS(a) a
  209. X#else
  210. X#define ARGS(a) ()
  211. X#endif
  212. X
  213. X/* Use this macro to define formals of function definitions */
  214. X#if ANSIHEADERS
  215. X#define ARGS0() ()
  216. X#define ARGS1(a,b) (a b)
  217. X#define ARGS2(a,b,c,d) (a b, c d)
  218. X#define ARGS3(a,b,c,d,e,f) (a b, c d, e f)
  219. X#define ARGS4(a,b,c,d,e,f,g,h) (a b, c d, e f, g h)
  220. X#define ARGS5(a,b,c,d,e,f,g,h,i,j) (a b, c d, e f, g h, i j)
  221. X#define ARGS6(a,b,c,d,e,f,g,h,i,j,k,l) (a b, c d, e f, g h, i j, k l)
  222. X#define ARGS7(a,b,c,d,e,f,g,h,i,j,k,l,m,n) (a b, c d, e f, g h, i j, k l, m n)
  223. X#define ARGS8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) (a b, c d, e f, g h, i j, k l, m n, o p)
  224. X#else
  225. X#define ARGS0() ()
  226. X#define ARGS1(a,b) (b)a b;
  227. X#define ARGS2(a,b,c,d) (b,d)a b; c d;
  228. X#define ARGS3(a,b,c,d,e,f) (b,d,f)a b;c d;e f;
  229. X#define ARGS4(a,b,c,d,e,f,g,h) (b,d,f,h)a b;c d;e f;g h;
  230. X#define ARGS5(a,b,c,d,e,f,g,h,i,j) (b,d,f,h,j)a b;c d;e f;g h;i j;
  231. X#define ARGS6(a,b,c,d,e,f,g,h,i,j,k,l) (b,d,f,h,j,l)a b;c d;e f;g h;i j;k l;
  232. X#define ARGS7(a,b,c,d,e,f,g,h,i,j,k,l,m,n) (b,d,f,h,j,l,n)a b;c d;e f;g h;i j;k l;m n;
  233. X#define ARGS8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) (b,d,f,h,j,l,n,p)a b;c d;e f;g h;i j;k l;m n;o p;
  234. X#endif
  235. X
  236. X/* This allows constant paramters passed to a short formal to by typecast
  237. X * easily. It is kind of like a trailing L on an integer. Use new ANSI
  238. X * stuff instead.
  239. X */
  240. X#define S (short)
  241. X
  242. X#define TRUE ((bool) 1)
  243. X#define FALSE ((bool) 0)
  244. X
  245. X
  246. X/*****************************************************************
  247. X *
  248. X * These declare the startup and termination routines.
  249. X * Do NOT change these!
  250. X *
  251. X */
  252. X
  253. X/* This is to be called by the main() of the host program.
  254. X * It returns the exit severity.
  255. X */
  256. Xextern short DoIt ARGS((void));
  257. X
  258. X/* This is called by the application when an unrecoverable error
  259. X * has occured. The severity is passed as the argument.
  260. X * The host should clean up if possible.
  261. X */
  262. Xextern void PLExit ARGS((short severity));
  263. X
  264. X/* These are the severities:
  265. X */
  266. X#define PLsev_normal    0   /* no error - just exit normally */
  267. X#define PLsev_badarg    1   /* command line arguments bad or wrong config */
  268. X#define PLsev_error    2   /* some other kind of error */
  269. X#define PLsev_userbreak 3   /* user requested unclean interrupt */
  270. X#define PLsev_oores    4   /* out of required resource */
  271. X#define PLsev_nfres    5   /* required resource not found at all */
  272. X#define PLsev_badform    6   /* input or file in wrong format */
  273. X#define PLsev_fault    7   /* user req to not recov from recov error */
  274. X#define PLsev_bomb    8   /* program detected unrecov error */
  275. X#define PLsev_assert    9   /* assertion failed */
  276. X#define PLsev_crash    10  /* program (and probably machine) crashed */
  277. X
  278. X
  279. X/*****************************************************************
  280. X *
  281. X * These declare the memory allocation / access primatives
  282. X *
  283. X */
  284. X
  285. X/* This allocates dynamic memory. The first argument is a LONG
  286. X * specifying how much memory (in bytes) needs to be allocated.
  287. X * The second is an INT containing various flags (two so far).
  288. X * If (flags & PLalloc_die) this will bomb("Out of Memory")
  289. X * if the allocation fails; otherwise it will return NULL if the
  290. X * allocation fails.
  291. X * You will fail the allocation or bomb("Memory request too large")
  292. X * if more memory than BIGMEM is requested. This retains the length
  293. X * for the PLfreemem function.
  294. X * If (flags & PLalloc_zero) this will clear the allocated memory to
  295. X * all binary zeros if the allocation succeeds; otherwise, the memory
  296. X * will be uninitialized.
  297. X */
  298. X#define PLalloc_die  1    /* bomb if out of memory */
  299. X#define PLalloc_zero 2    /* clear new mem to zeros */
  300. Xptr PLAllocMem ARGS((long size, int flags));
  301. X
  302. X/* This frees dynamic memory. The argument is a previously-allocated
  303. X * pointer to memory as returned by PLAllocMem(). The application is
  304. X * responsible for deallocating all memory it allocates before returning
  305. X * normally from DoIt(). If possible, the application should deallocate
  306. X * all memory before calling PLExit. The host programmer may wish to
  307. X * check that memory is freed exactly once.
  308. X */
  309. Xvoid PLFreeMem ARGS((ptr where));
  310. X
  311. X/* This allocates enough memory to hold the given string, then copies
  312. X * the string into that memory. It passes PLalloc_die=true to the
  313. X * PLallocmem call.
  314. X */
  315. Xstr PLStrDup ARGS((str s));
  316. X
  317. X/* This copies memory from src to dest for siz bytes. The host function
  318. X * will handle copying in the correct direction if the areas overlap.
  319. X * This should be as efficient as possible.
  320. X */
  321. Xvoid PLCopyMem ARGS((ptr to, ptr from, long siz));
  322. X
  323. X/* This assigns a constant byte to a region of memory.
  324. X * Again, this should be as efficient as possible.
  325. X */
  326. Xvoid PLFillMem ARGS((ptr where, long siz, char chr));
  327. X
  328. X/* This looks for a specific character within a range of memory.
  329. X * It returns NULL if not found, or a pointer to the matching character
  330. X * if found.
  331. X */
  332. Xptr PLFindMem ARGS((ptr where, long siz, char chr));
  333. X
  334. X
  335. X/*****************************************************************
  336. X *
  337. X * These declare the error routines
  338. X *
  339. X */
  340. X
  341. X/* This is the type of an error value
  342. X */
  343. Xtypedef short PLerr_enum;
  344. X#define PLerr_none    0   /* no error occured */
  345. X#define PLerr_opsysR    1   /* otherwise unknown error - retry */
  346. X#define PLerr_opsysW    2   /* otherwise unknown error - wait then retry */
  347. X#define PLerr_opsysU    3   /* otherwise unknown error - ask user to fix */
  348. X#define PLerr_opsysF    4   /* otherwise unknown error - unrecoverable failure */
  349. X#define PLerr_fault    5   /* program-detected error */
  350. X#define PLerr_eod    6   /* end of data (during read) */
  351. X#define PLerr_oores    7   /* out of some resource (during write/create) */
  352. X#define PLerr_again    8   /* multiple errors occured without being cleared */
  353. X#define PLerr_exist    9   /* access to non-existant item */
  354. X#define PLerr_already    10  /* can't create because item already there */
  355. X#define PLerr_permit    11  /* "owner" disallows that access to you */
  356. X#define PLerr_unsup    12  /* unsuported in this instance */
  357. X#define PLerr_busy    13  /* item exits but is busy */
  358. X#define PLerr_param    14  /* argument to function cannot be parsed */
  359. X#define PLerr_notyet    15  /* something not yet implemented */
  360. X#define PLerr_never    16  /* something that cannot be implemented */
  361. X#define PLerr_badarg    17  /* argument to function semantically invalid */
  362. X#define PLerr_overflow    18  /* overflow error */
  363. X#define PLerr_underflow 19  /* underflow error */
  364. X#define PLerr_userbreak 20  /* user break or interrupted system call */
  365. X#define PLerr_last    21  /* largest error number + 1 */
  366. X
  367. X/* The PL error number */
  368. Xextern PLerr_enum PLerr;
  369. X
  370. X/* The OS error number (whatever you need, if anything) */
  371. Xextern int OSerr;   /* may be changed by HostPgrmr */
  372. X
  373. X/* The file and line of the last error (mainly for debugging) */
  374. Xextern str PLerr_file;
  375. Xextern long PLerr_line;
  376. X
  377. X/* This sets the error number.
  378. X */
  379. X#ifdef DEBUG
  380. X#define PLErrSet(e) ((PLerr_file=__FILE__),(PLerr_line=__LINE__),\
  381. XPLerr=((PLerr!=PLerr_none)?PLerr_again:(e)))
  382. X#else
  383. X#define PLErrSet(e) (PLerr = ((PLerr != PLerr_none) ? PLerr_again : (e)))
  384. X#endif
  385. X
  386. X/* This clears the error number.
  387. X * (This may be a void function if your compiler doesn't like empty args)
  388. X */
  389. X#define PLErrClr() (OSerr=0,PLerr=PLerr_none)
  390. X
  391. X/* This returns a string, suitable for user viewing, describing the
  392. X * most recent error as indicated by PLerr.
  393. X * The string should be static.
  394. X */
  395. Xstr PLErrText ARGS((void));
  396. X
  397. X/* This returns a string, suitable for user viewing, describing the
  398. X * most recent error in the HOST terminology. Used when PLopsys?
  399. X * returned or for additional information.
  400. X * The string should be static.
  401. X */
  402. Xstr PLOSErrText ARGS((void));
  403. X
  404. X/*****************************************************************
  405. X *
  406. X * These declare the status message routines
  407. X *   (Note that delay and beep are included here only due to their
  408. X *    typical usage.)
  409. X *
  410. X */
  411. X
  412. X/* This displays a status message for utilities. The display should
  413. X * be suppressed if PLstatuslevel <= level. PLstatuslevel should be
  414. X * initialized before calling DoIt(), and is intended to be
  415. X * changable by the user. It should default to a value of 6 (giving
  416. X * status messages in the range 0-6).
  417. X * level == 5 should be used for normal status messages, including
  418. X * initial copyright messages, final summaries, and so on;
  419. X * level == 6 should be used for progress reports;
  420. X * level == 7 should be used to echo parameters; level == 3 should be
  421. X * use for warnings and level == 2 should be used for non-fatal errors.
  422. X * Obviously, use level == 0 (which can't be disabled) for fatal errors.
  423. X */
  424. Xextern short PLstatuslevel;
  425. Xvoid PLStatus ARGS((short level, str message));
  426. X
  427. X/* This function will delay for the indicated number of seconds in the
  428. X * most efficient way possible. (Of course, on a single-tasking
  429. X * machine, you may wait as inefficiently as you like.)
  430. X */
  431. Xextern void PLDelay ARGS((short secs));
  432. X
  433. X/* This function is used to draw the user's attention to the computer.
  434. X * If passed a zero, it should make a quiet, pleasant beep or chime,
  435. X * or simply flash the screen if possible. This option will be used
  436. X * to indicate that a minor error (like an illegal keystroke) has
  437. X * occured.
  438. X * If passed a one, it should make an audible tone, loud enough to be
  439. X * heard even if not listened for. This should be used to indicate that
  440. X * a lengthy process (during which the user has started working on
  441. X * back paperwork or something) has completed. It should never be used
  442. X * to indicate that an error has occured.
  443. X * If passed a two or greater, it should give a rude audible indicator
  444. X * of problems. This will be used only when the user is about to do
  445. X * something that it is quite unlikely he wants to do.
  446. X */
  447. Xextern void PLBeep ARGS((short how));
  448. X
  449. X
  450. X/*****************************************************************
  451. X *
  452. X * These declare basic standard input/output functions
  453. X *
  454. X * Do not use these in sophisticated applications.
  455. X * Do not use these in place of the PLstatus routine.
  456. X */
  457. X
  458. X
  459. X/* This should return an integer from 0 to 255, representing the ASCII
  460. X * of the next character read from the "standard input" or -1 for EOF or
  461. X * -2 for some other I/O error. Newline must be returned as '\n', and
  462. X * space as ' ' and tab as '\t'. It is assumed that redirection might
  463. X * occur on this stream -- see also PLResetInput().
  464. X * This may be changed to a macro by the host programmer.
  465. X */
  466. Xextern int fgetc(FILE *);
  467. X#define PLGetChar() fgetc(stdin)
  468. X
  469. X/* This should send the indicated character to the "standard output".
  470. X * The output characters may include '\n' for newline. It is assumed
  471. X * that redirection may occur on this stream -- see also PLResetOutput().
  472. X * This may be changed to a macro by the host programmer.
  473. X */
  474. Xextern int fputc(char, FILE *);
  475. X#define PLPutChar(ch) ((void)(fputc((ch),stdout),fflush(stdout)))
  476. X
  477. X/* When this is called, further calls to PLgetchar() should take
  478. X * their input from the user terminal.
  479. X * This may be changed to a macro by the host programmer.
  480. X */
  481. X#define PLResetInput() ((void)freopen("/dev/tty", "r", stdin))
  482. X
  483. X/* When this is called, further calls to PLputchar() should send
  484. X * their output to the user terminal.
  485. X * This may be changed to a macro by the host programmer.
  486. X */
  487. X#define PLResetOutput() ((void)freopen("/dev/tty","a",stdout))
  488. X
  489. X    /* For testing only! Do not call printf except while debugging! */
  490. X    extern void printf(char *, ...);
  491. X
  492. X
  493. X/*****************************************************************
  494. X *
  495. X * These declare command-line argument functions
  496. X *
  497. X */
  498. X
  499. X/* This gives the name of the executable file, if available.
  500. X * Otherwise, this will be NULL.
  501. X */
  502. Xextern str PLcmdname;
  503. X
  504. X/* This gives the host-syntax filename for the executable file now running,
  505. X * if available.
  506. X * Otherwise, this will be NULL.
  507. X */
  508. Xextern str PLcmdfile;
  509. X
  510. X/* This tells how many command-line arguments there were, EXCLUDING
  511. X * the command name.
  512. X */
  513. Xextern short PLargcnt;
  514. X
  515. X/* This is the array of command-line argument strings, EXCLUDING the
  516. X * command name.
  517. X */
  518. Xextern str PLarglist[];
  519. X
  520. X/* These are the flags describing the command-line parameters.
  521. X */
  522. Xextern long PLargflags;
  523. X#define PLaf_hostwc 1    /* use host wildcards instead of portable wc's */
  524. X#define PLaf_hostex 2    /* host already has expanded wildcards */
  525. X
  526. X
  527. X/**********  These are here because this assumes GCC with non-ANSI
  528. X         header files (SunOS 4.1, to be precise) **********************/
  529. X
  530. X/* these should be in stdio.h for ANSI compilers, but aren't on the Sun */
  531. Xextern int fprintf ARGS((FILE *, char *, ...));
  532. Xextern void exit ARGS((int));
  533. Xextern void fflush ARGS((FILE *));
  534. X/* these should be in stdlib.h for ANSI compilers, but aren't on the Sun */
  535. Xextern void * malloc ARGS((long));
  536. Xextern void free ARGS((void *));
  537. X/* these should be in ctype.h for ANSI compilers (I think), but aren't on the Sun */
  538. Xextern int toupper ARGS((int));
  539. Xextern int tolower ARGS((int));
  540. X
  541. X
  542. X#endif /* PPL_h */
  543. X
  544. END_OF_FILE
  545. if test 17468 -ne `wc -c <'PPL/PPLUnix.h'`; then
  546.     echo shar: \"'PPL/PPLUnix.h'\" unpacked with wrong size!
  547. fi
  548. # end of 'PPL/PPLUnix.h'
  549. fi
  550. echo shar: End of archive 8 \(of 9\).
  551. cp /dev/null ark8isdone
  552. MISSING=""
  553. for I in 1 2 3 4 5 6 7 8 9 ; do
  554.     if test ! -f ark${I}isdone ; then
  555.     MISSING="${MISSING} ${I}"
  556.     fi
  557. done
  558. if test "${MISSING}" = "" ; then
  559.     echo You have unpacked all 9 archives.
  560.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  561. else
  562.     echo You still need to unpack the following archives:
  563.     echo "        " ${MISSING}
  564. fi
  565. ##  End of shell archive.
  566. exit 0
  567. -- 
  568. --- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
  569.  
  570. exit 0 # Just in case...
  571. -- 
  572. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  573. Use a domain-based address or give alternate paths, or you may lose out.
  574.