rsalz@uunet.uu.net (Rich Salz) (03/28/90)
Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu> Posting-number: Volume 21, Issue 56 Archive-name: p2c/part11 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 11 (of 32)." # Contents: src/NOTES # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:35 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/NOTES' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/NOTES'\" else echo shar: Extracting \"'src/NOTES'\" \(33044 characters\) sed "s/^X//" >'src/NOTES' <<'END_OF_FILE' X XTHE GRAND P2C NOTES FILE: X XThis file contains notes to myself recording bugs, flaws, and suggested Ximprovements to p2c. They have roughly been separated into "old", "older", Xand "oldest" groups. I can't guarantee I'll do any of these. If you do, Xplease mail me the diffs so I can incorporate them into the next release. XThanks! X -- Dave Gillespie X daveg@csvax.caltech.edu X X----------------------------------------------------------------------------- X X The Pascal declaration X X type foo = set of (one, two); X X does not ever write out an "enum { one, two }" declaration in C! X X----------------------------------------------------------------------------- X X Handling of comments that trail the ELSE clause of an IF statement X could use some work. X X----------------------------------------------------------------------------- X X Technically speaking, "for byte := min to max do" is legal even X if min > 255, i.e., the limits only need to be in range if the X body of the loop executes. Thus, FOR loops should really use a X shadow parameter not just when max is the constant 255, but X whenever min or max are not provably in byte range. X X----------------------------------------------------------------------------- X X Have a "-M"-like mode in which FREE is suppressed altogether, useful X in case p2c crashes because bugs have corrupted malloc's free list. X X----------------------------------------------------------------------------- X X For expressions building small-sets whose maximum element is <= 15, X use "1 << x" instead of "1L << x". X X----------------------------------------------------------------------------- X X Handle VAX Pascal VARYING OF CHARs used as the arguments of WITH X statements. X X----------------------------------------------------------------------------- X X Have a p2crc feature which identifies a given named constant as X being a character, not a string of length 1. Have an option in X which this is the default interpretation. X X----------------------------------------------------------------------------- X X StringTruncLimit would be helped by expr.c:strmax() interpreting X sprintf control strings. For %s, use strmax of the corresponding X argument. For %d, use 11, etc. For %.10s, use min(10, strmax(arg)). X For %.*s, just use strmax(arg), I guess. X X Have a mode in which such assignments are automatically truncated. X X Perform truncation testing for non-VAR procedure arguments, too. X X----------------------------------------------------------------------------- X X In cref.p, the "strappend(buf,#0)" statement translates into X "strcpy(STR1,buf); strcpy(buf,STR1)" with a warning about a null X character in a sprintf control string! X X----------------------------------------------------------------------------- X X Still having problems where the opening comment of an imported X module's interface text is copied into the program. X X----------------------------------------------------------------------------- X X VAX Pascal features not yet handled: X X [UNSAFE] attribute is only implemented in a few situations. X [UNBOUND] attribute on a procedure says it doesn't need a static link. X [TRUNCATE] attribute on a parameter allows optional params w/no default. X [LIST] attribute on a parameter is like &rest in Lisp. X Support types like, e.g., [LONG] BOOLEAN. X Can assign "structurally compatible" but different record types. X File intrinsics need serious work, especially OPEN. X If a copy param is [READONLY], don't need to copy it. X If a procedure is [ASYNCHRONOUS], make all its variables volatile. X If a procedure is [NOOPTIMIZE], make all its variables volatile. X Provide a real implementation of BIN function and :BIN read format. X BIT_OFFSET and CARD intrinsics are not supported. X X----------------------------------------------------------------------------- X X Modula-2 features not yet handled: X X Local modules are faked up in a pretty superficial way. X WORD is compatible with both pointers and CARDINALs. X WORD parameters are compatible with any word-sized object. X ARRAY OF WORD parameters are compatible with absolutely anything. X Improve treatment of character strings. X Find manuals for real implementations of Modula-2 and implement X any common language extensions. X Fix p2c to read system.m2 instead of system.imp automatically. X X----------------------------------------------------------------------------- X X Oregon Software Pascal features not yet handled: X X procedure noioerror(var f:file); X Built-in. Sets a flag on an already-open file so that X I/O errors record an error code rather than crashing. X Each file has its own error code. X X function ioerror(var f:file) : boolean; X True if an error has occurred in the file. X X function iostatus(var f:file) : integer; X The error code, when ioerror was true. X X reset and rewrite ignore the third parameter, and allow a fourth X param which is an integer variable that receives a status code. X Without this param, open errors are fatal. An optional param X may be omitted as in reset(f,'foo',,v); X X----------------------------------------------------------------------------- X X In p_search, if a file contains const/var/type/procedure/function X declarations without any module declaration, surround the entire X file with an implicit "module <generated-name>; {PERMANENT}" ... "end.". X This would help the Oregon Software dialect considerably. X X----------------------------------------------------------------------------- X X Provide an explicit IncludeFrom syntax for "no include file". X E.g., "IncludeFrom dos 0". X X----------------------------------------------------------------------------- X X In docast, smallsets are converted to large sets of the requested type. X Wouldn't it be better to convert to a set of 0..31 of the base type? X This would keep foo([]), where the argument is "set of char", from X allocating a full 256-bit array for the temporary. X X----------------------------------------------------------------------------- X X When initializing a constant variant record or array of same in which X non-first variants are initialized, create a function to do the X initialization, plus, for modules w/o initializers, a note to call X this function. Another possibility: Initialize the array as well as X possible, but leave zeros in the variant parts. Then the function X has only to fix up the non-first variant fields. X X----------------------------------------------------------------------------- X X Figure out some way to initialize packed array constants, e.g., a short X macro PACK4(x,y)=(((x)<<4)+(y)) which is used inside the C initializer. X Alternatively, implement initializer functions as above and use those. X X----------------------------------------------------------------------------- X X How about declaring Volatile any variables local to a function which X are used after the first RECOVER? GNU also suggests writing the X statement: "&foo;" which will have no side effect except to make X foo essentially volatile, without relying on ANSI features. X X----------------------------------------------------------------------------- X X Test the macros for GET, PUT, etc. X X----------------------------------------------------------------------------- X X Can the #if 0'd code for strinsert in funcs.c be changed to test X strcpyleft? X X----------------------------------------------------------------------------- X X Even in Ansi mode, p2c seems to be casting Anyptrs into other pointer X types explicitly. This is an automatic conversion in Ansi C. X X----------------------------------------------------------------------------- X X A Turbo typed constant or VAX initialized variable with a VarMacro X loses its initializer! X X----------------------------------------------------------------------------- X X Test the ability of the parser to recover from common problems such X as too many/few arguments to a procedure, missing/extra semicolon, etc. X One major problem has been with undeclared identifiers being used as X type names. X X----------------------------------------------------------------------------- X X Line breaker still needs considerable tuning! X X----------------------------------------------------------------------------- X X How about indenting trailing comments analogously to the code: X Try to indent to column C+(X-Y), where C=original column number, X X=output indentation, Y=original input indentation. X X Even fancier would be to study all the comment indentations in the X function or struct decl to discover if most comments are at the same X absolute indentation; if so, compute the average or minimum amount of X space preceding the comments and indent the C comments to an analogous X position. X X----------------------------------------------------------------------------- X X After "type foo = bar;" variables declared as type foo are translated X as type bar. Ought to assume the user has two names for a reason, X and copy the distinction into the C code. X X----------------------------------------------------------------------------- X X Warn if address is taken of an arithmetic expression like "v1+1". X Allow user to declare certain bicalls as l-values, e.g., so that X LSC's topLeft and botRight macros won't generate complaints. X X----------------------------------------------------------------------------- X X Consider changing the "language" modes into a set of p2crc files X which can be included to support the various modes. X X----------------------------------------------------------------------------- X X If we exchange the THEN and ELSE parts of an IF statement, be sure X to exchange their comments as well! X X----------------------------------------------------------------------------- X X How about checking for a ".p2crc" file in the user's home directory. X X----------------------------------------------------------------------------- X X Store comments in the following situations: X On the first line of a record decl. X On the default clause of a CASE statement X (use same trick as for ELSE clauses). X On the "end" of a CASE statement. X On null statements. X Use stealcomments for, e.g., decl_comments and others. X X----------------------------------------------------------------------------- X X Think of other formatting options for format_gen to support. X X----------------------------------------------------------------------------- X X Consider converting gratuitous BEGIN/END pairs into gratuitous X { } pairs. X X----------------------------------------------------------------------------- X X The construction "s := copy(s, 1, 3)" converts to a big mess that X could be simplified to "s[3] = 0". X X----------------------------------------------------------------------------- X X Have a mode (and make it the default!) in which declarations are mixed X if and only if the original Pascal decls were mixed. Simply store X a flag in each meaning to mark "mixed-with-preceding-meaning". X X----------------------------------------------------------------------------- X X Have a column number at which to put names in variable and typedef X declarations. Have another option to choose whether a '*' preceding X a name should be left- or right-justified within the skipped space: X int *foo; or X int * foo; X X----------------------------------------------------------------------------- X X Support the /* X * X */ form for multi-line comments. X X----------------------------------------------------------------------------- X X Have an indentation parameter for the word "else" by itself on a line. X X----------------------------------------------------------------------------- X X Have an option to use C++'s "//" comments when possible. X (0=never, 1=always, def=only for trailing comments.) X X----------------------------------------------------------------------------- X X Allow real comments to come before top-of-file comments like {Language}. X X----------------------------------------------------------------------------- X X Teach the line breaker to remove spaces around innermost operators X if in a crunch. X X----------------------------------------------------------------------------- X X Is it possible that the line breaker is losing counts? A line that X included lots of invisible parens converted to visible ones was X allowed to be suspiciously long. X X----------------------------------------------------------------------------- X X The notation t^ where t is a text file should convert \n's to X spaces if necessary. X X----------------------------------------------------------------------------- X X The assignment and type cast "f4 := tf4(i)" where type X "tf4 = function (i, j : integer) : str255" X generates something really weird. X X----------------------------------------------------------------------------- X X The conditional expression strsub(s,1,4) = 'Spam' X could be translated as strncmp(s, "Spam", 4) X X----------------------------------------------------------------------------- X X Consider an option which generates a "file.p2c" or "module.p2c" X file, that will in the future be read in by p2c as another p2crc X type of file, both when the module is re-translated later and when X it is imported. This file would contain commands like "NoSideEffects" X for functions which are found to have this property, etc. X X----------------------------------------------------------------------------- X X Extend the "file.log" or "module.log" file to contain a more detailed X account of the translation, including all notes and warnings which were X even considered. For example, ALL calls to na_lsl with non-constant X shifts would be noted, even if regular notes in this case were not X requested. Also, funny transformations along the lines of X "str[0] := chr(len)" and "ch >= #128" should be mentioned in the log. X How about a summary of non-default p2crc options and command-line args? X X----------------------------------------------------------------------------- X X Create a TypeMacro analogous to FuncMacro, VarMacro, and ConstMacro. X Should the definition be expressed in C or Pascal notation? (Yuck---not X a C type parser!) X X----------------------------------------------------------------------------- X X In argument type promotions, should "unsigned char" be promoted to X "unsigned int"? X X----------------------------------------------------------------------------- X X Turbo's FExpand translation is really weird. X X----------------------------------------------------------------------------- X X Can we translate Erase(x) to unlink(x)? (This could just be a FuncMacro.) X X----------------------------------------------------------------------------- X X There should be an option that causes a type to be explicitly named, X even if it would not otherwise have had a typedef name. Have a mode X that does this for all pointer types. X X----------------------------------------------------------------------------- X X Make sure that the construction: if blah then {comment} else other X does not rewrite to if (!blah) other; i.e., a comment in this situation X should generate an actual placeholder statement. Or perhaps, a null X statement written explicitly by the Pascal programmer should always X produce a placeholder. X X----------------------------------------------------------------------------- X X Allow the line breaker to treat a \003 as if it were a \010. The penalty X should be enough less than SameIndentPenalty that same-indent cases will X cause the introduction of parentheses. X X----------------------------------------------------------------------------- X X A comment of the form "{------}" where the whole comment is 78, 79 or 80 X columns wide, should be reduced by two to take the larger C comment X brackets into account. Also, "{*****}", etc. X X----------------------------------------------------------------------------- X X There should be a mode that translates "halt" as "exit(0)", and another X that translates it as "exit(1)". X X----------------------------------------------------------------------------- X X There should be a mode in which strread's "j" parameter is completely X ignored. Also, in this mode, don't make a copy of the string being X read. X X----------------------------------------------------------------------------- X X Is there an option that generates an fflush(stdout) after every write X (not writeln) statement? It should be easy to do---the code is already X there to support the prompt statement. X X----------------------------------------------------------------------------- X X Check out the Size_T_Long option; size_t appears to be int on most X machines, not long. X X----------------------------------------------------------------------------- X X The type "size_t" should really be made into a separate type, with a X function to cast to type "size_t". This function would always do X the cast unless sizeof(int) == sizeof(long), or unless the expression X only involves constants and objects or functions of type "size_t". X X----------------------------------------------------------------------------- X X Finish the Turbo Pascal features (in the file turbo.imp). X X----------------------------------------------------------------------------- X X Are there any ways to take advantage of "x ?: y" in GCC? X Is it worth using GCC constructor expressions for procedure variables? X How about generating "volatile" and "const" for suitable functions? X (doing this in the .h file would be very difficult...) X Use the "asm" notation of 5.17 to implement var x ['y'] declarations. X X----------------------------------------------------------------------------- X X Recognize GCC extensions in pc_expr(). (By the way, remember X to implement += and friends in pc_expr(), too!) X X----------------------------------------------------------------------------- X X Lightspeed C can't handle "typedef char foo[];" which arises from a X MAXINT-sized array type declaration. X X----------------------------------------------------------------------------- X X "Return" and friends are only introduced once. In code of the form: X X if (!done) { foo(); } if (!done) { bar(); } X X p2c should, after patching up bar(), check if the foo() branch is X now also ripe for rearranging. X X----------------------------------------------------------------------------- X X Have a global "paranoia" flag. Default=use current defaults for other X options. 1=conservative defaults for other options. 0=sloppy defaults X for other options. X X----------------------------------------------------------------------------- X X Rather than just generating a note, have writes of attribute characters X convert into calls to a "set attribute" procedure, such as nc_sethighlight. X Is there any way of generalizing this into something useful for X non-HP-Pascal-workstation users? X X----------------------------------------------------------------------------- X X Warn when character constants which are control codes are produced. X (E.g., arrow keys, etc.) Also, have an option which deletes all X highlighting codes from strings being output. X X----------------------------------------------------------------------------- X X Think how nice things would be if the arithmetic routines actually X maintained the distinction between tp_int and tp_integer themselves, X so that makeexpr_longcast didn't have to second-guess them. X X----------------------------------------------------------------------------- X X Importing FS *still* copies its "file support" comment into the importing X program! X X----------------------------------------------------------------------------- X X Should parameterize those last few hard-wired names, such as "P_eoln", X "LONG_MAX", ... ? X X----------------------------------------------------------------------------- X X Check if we need to cache away any more options' values, as we did for X VarStrings. How about FoldConstants, SetBits, CopyStructs? X X X============================================================================= X X X Support the "CSignif" option (by not generating C identifiers which X would not be unique if only that many characters were significant). X X----------------------------------------------------------------------------- X X What if a procedure accesses strmax of a var-string parameter of a X parent procedure? (Right now this generates a note.) X X----------------------------------------------------------------------------- X X Handle full constructors for strings. X Handle small-array constants. X X----------------------------------------------------------------------------- X X Have an option that causes ANYVAR's to be translated to void *'s. In X this mode, all uses of ANYVAR variables will need to be cast to the X proper type, in the function body rather than in calls to the function. X X----------------------------------------------------------------------------- X X Handle reading enums. Add full error checking for reading booleans. X (And integer subranges?) X X----------------------------------------------------------------------------- X X Support the "BigSetConst" option by creating constant arrays just as the X Pascal compiler does. X X----------------------------------------------------------------------------- X X The 2^(N+1) - 2^M method for generating [M..N] is not safe if N is 31. X If the small-sets we are dealing with encompass the value 31 (== setbits-1) X then we must use the bitwise construction instead. (Currently, the X translator just issues a note.) X X (If N is 31, 2^32 will most likely evaluate to 0 on most machines, which X is the correct value. So this is only a minor problem.) X X----------------------------------------------------------------------------- X X Big-set constants right now are always folded. Provide a mechanism X for defined set constants, say by having a #define with an argument X which is the name of the temporary variable to use for the set. X X----------------------------------------------------------------------------- X X Should we convert NA_LONGWORD-type variants into C casts? X X----------------------------------------------------------------------------- X X Are there implementations of strcpy that do not return their first X argument? If so, should have an option that says so. X X----------------------------------------------------------------------------- X X Handle absolute-addressed variables better. For var a[12345]:integer, X create an initialized int *. For var a['foo']:integer, create an int * X which is initialized to NULL and accessed by a macro which locates the X symbol the first time the variable is used. X X----------------------------------------------------------------------------- X X Handle the idiom, "reset(f, name); open(f);" X X----------------------------------------------------------------------------- X X Should have an option that lowercases all file names used in "reset", X "fixfname", etc. This should be on by default. X X----------------------------------------------------------------------------- X X Add more complete support for conformant arrays. Specifically, support X non-GNU compilers by converting variable-sized array declarations into X pointer declarations with calls to alloca or malloc/free (what if the X function uses free and contains return statements)? Also convert X variable-array references into explicit index arithmetic. X X----------------------------------------------------------------------------- X X Have a mode in which the body of a TRY-RECOVER is moved out into X a sub-procedure all its own, communicating with the parent through X varstructs as usual, so that the ANSI C warning about what longjmp X can do to the local variables is avoided. Alternatively, have an X option in which all necessary locals are declared volatile when X setjmps are present. X X----------------------------------------------------------------------------- X X If a sub-procedure refers to a parent's variable with the VAX Pascal X [STATIC] attribute, that variable is declared "static" inside the X varstruct! Need to convert it into a varref to a static variable in X the parent. X X----------------------------------------------------------------------------- X X When comparing records and arrays a la UCSD Pascal, should expand X into an "&&" expression comparing each field individually. (What about X variants? Maybe just compare the first variant, or the tagged X variant.) Probably best to write a struct-comparison function the X first time a given type of struct is compared; that way, the function X can include a complete if tree or switch statement in the case of X tagged unions. X X----------------------------------------------------------------------------- X X In the checkvarchanged code, take aliasing of VAR parameters into account. X For example, in "procedure p(s1 : string; var s2 : string)" p2c now avoids X copying s1 if s1 is not changed within p, but probably should also require X that s2 not change, or at least that s1 have been read and used before s2 X is changed. X X----------------------------------------------------------------------------- X X Provide an option that tells the code generator to provide helpful X comments of its own when generated code may be obscure. X X X============================================================================= X X X Compact the various data structures. In particular, typical runs X show the majority of memory is used by Meanings and Symbols for X global and imported objects. X X----------------------------------------------------------------------------- X X The program wastes memory. Find ways to reduce memory usage, and to X avoid leaving dead records on the heap. (Garbage collection? Yuck!) X (Maybe GC between each function declaration would be okay.) X X----------------------------------------------------------------------------- X X Assign better names to temporaries. Also, could avoid making redundant X temporaries by generating a unique temporary every time one is needed, X then crunching them down at the end just before the declarations are X written out. Each temporary would maintain a list of all the other X temporaries (of the same type) with which it would conflict. (This X would avoid the current method's waste when several temps are created, X then most are cancelled.) Also, note that char STR1[10], STR2[20] can X be considered type-compatible and merged into STR[20]. X X----------------------------------------------------------------------------- X X Don't generate _STR_xxx structure names if they aren't forward-referenced. X X----------------------------------------------------------------------------- X X Can optimize, e.g., "strpos(a,b) = 0" to a call to strstr() or strchr(), X even though these ANSI functions are not Pascal-like enough to use in X the general case. X X----------------------------------------------------------------------------- X X Complete the handling of "usecommas=0" mode. X X----------------------------------------------------------------------------- X X Optimize "s := strltrim(s)", "s := strrtrim(s)", and both together. X X----------------------------------------------------------------------------- X X Convert "(ch < 'a') or (ch > 'z')" to "!islower(ch)", and so on. X Also do "!islower(ch) && !isupper(ch)" => "!isalpha(ch)", etc. X X----------------------------------------------------------------------------- X X Find other cases in which to call mixassignments(). X X----------------------------------------------------------------------------- X X The sequence: sprintf(buf + strlen(buf), "...", ...); X sprintf(buf + strlen(buf), "...", ...); X could be changed to a single sprintf. X Also, "sprintf(temp, "...%s", ..., buf); strcpy(buf, temp); (above);" X could be crunched down. (This comes from strinsert, then strappend.) X X----------------------------------------------------------------------------- X X If there is only one assignment to a structured function's return X variable, and that assignment is at the very end and assigns a local X variable to the return variable, then merge the variables. X (Example: name_list in netcmp's datastruct module. RET_name_list X should be renamed to namestr.) X X----------------------------------------------------------------------------- X X Have an option that causes if-then-else's to be replaced by ? :'s in X certain cases. If the branches of the if are either both returns or X both assignments to the same variable, which has no side effects, and X if the whole conditional will be simple enough to fit on one line when X printed, then the ? : transformation is okay. X X----------------------------------------------------------------------------- X X Have an option that makes limited use of variable initialization. X If the first statement of a function is an assignment of a constant X to a local variable, then the assignment is changed to an initialization. X (Non-constant initializers are probably too hard to check for safety.) X Should variables with initializers still be mixed? X (Example: valid_node_class in netcmp's datastructs module.) X File variable initialization is an especially good application for this. X X----------------------------------------------------------------------------- X X Have an option that finds cases of multiple assignment. For example: X a := x; b := x; => a = b = x; X a := x; b := a; => a = b = x; X (provided the objects in question have the same type). X X----------------------------------------------------------------------------- X X Need an option that causes $if$'s to change to #if's, instead of being X evaluated at translation-time. (This is *really hard* in general; X do it for some common cases, such as entire statements being commented X out, or fields being commented out of records.) X X----------------------------------------------------------------------------- X X Have an option that prevents generation and inclusion of .h files for X modules; instead, each module would contain extern declarations for X the things it imports. (Only declare names that are actually used--- X this means the declarations will have to be emitted on a procedure-by- X procedure basis.) X X----------------------------------------------------------------------------- X X Extend the ExpandIncludes option to compile include files as separate X stand-alone C modules. The hard part is warning when the new module X uses a procedure which was declared static in an earlier C module. X Remember to re-emit all the proper #include's at the beginning. X Anything else? X X----------------------------------------------------------------------------- X X Consider an option where the variables in a varStruct are made into X globals instead, or into parameters if there are few of them. X X----------------------------------------------------------------------------- X X Perform a flow analysis after everything else is done; use this to X eliminate redundant checks, e.g., for nil pointers or non-open or X already-open files. Also eliminate redundant "j" variables for X strwrite statements. X X----------------------------------------------------------------------------- X X Need a method for simple pattern matching predicates in FuncMacros. X For example, allow special translations of functions where a given X argument is a known constant, or known to be positive, or two X arguments are the same, etc. X X----------------------------------------------------------------------------- X X Have some way to provide run-time templates for fixblock/fixexpr-like X applications. The user enters two C expressions A and B, possibly including X Prolog-like logical variables. If fixexpr sees an expression matching A, X it rewrites it into the form of B. X X----------------------------------------------------------------------------- X X Have an option to cause selected Pascal procedures or functions to be X expanded in-line. Do this either by generating the keyword "inline", X or by doing the expansion in the translator. X X----------------------------------------------------------------------------- X X Technically speaking, strcmp shouldn't be used to compute < and > for X strings on a machine with signed chars. Should we care? X X----------------------------------------------------------------------------- X X Have an option for creating a "display" of LINK pointers local to a X function. Should only create such pointers for static levels which are X referred to in the function body. X X----------------------------------------------------------------------------- X X END_OF_FILE if test 33044 -ne `wc -c <'src/NOTES'`; then echo shar: \"'src/NOTES'\" unpacked with wrong size! fi # end of 'src/NOTES' fi echo shar: End of archive 11 \(of 32\). cp /dev/null ark11isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 32 archives. echo "Now see PACKNOTES and the README" rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.