rsalz@uunet.uu.net (Rich Salz) (03/27/90)
Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu> Posting-number: Volume 21, Issue 53 Archive-name: p2c/part08 #! /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 8 (of 32)." # Contents: src/parse.c.3 src/sys.p2crc.2 # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:32 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/parse.c.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/parse.c.3'\" else echo shar: Extracting \"'src/parse.c.3'\" \(25765 characters\) sed "s/^X//" >'src/parse.c.3' <<'END_OF_FILE' X mp->isreturn) { /* the was-#defined flag */ X if (!anywords) X outsection(minorspace); X anywords++; X output(format_s("#undef %s\n", mp->name)); X sym = findsymbol(mp->name); X sym->flags &= ~AVOIDNAME; X } X } X } X if (conserve_mem) { X free_stmt((Stmt *)func->val.i); /* is this safe? */ X func->val.i = 0; X forget_ctx(func, 0); X } X outsection(spacing); X} X X X X Xvoid movetoend(mp) XMeaning *mp; X{ X Meaning **mpp; X X if (mp->ctx != curctx) { X intwarning("movetoend", "curctx is wrong [268]"); X } else { X mpp = &mp->ctx->cbase; /* move a meaning to end of its parent context */ X while (*mpp != mp) { X if (!*mpp) { X intwarning("movetoend", "meaning not on its context list [269]"); X return; X } X mpp = &(*mpp)->cnext; X } X *mpp = mp->cnext; /* Remove from present position in list */ X while (*mpp) X mpp = &(*mpp)->cnext; X *mpp = mp; /* Insert at end of list */ X mp->cnext = NULL; X curctxlast = mp; X } X} X X X XStatic void scanfwdparams(mp) XMeaning *mp; X{ X Symbol *sym; X X mp = mp->type->fbase; X while (mp) { X sym = findsymbol(mp->name); X sym->flags |= FWDPARAM; X mp = mp->xnext; X } X} X X X XStatic void p_function(isfunc) Xint isfunc; X{ X Meaning *func; X Type *type; X Stmt *sp; X Strlist *sl, *comments, *savecmt; X int initializeattr = 0, isinline = 0; X X if ((sl = strlist_find(attrlist, "INITIALIZE")) != NULL) { X initializeattr = 1; X strlist_delete(&attrlist, sl); X } X if ((sl = strlist_find(attrlist, "OPTIMIZE")) != NULL && X sl->value != -1 && X !strcmp((char *)(sl->value), "INLINE")) { X isinline = 1; X strlist_delete(&attrlist, sl); X } X ignore_attributes(); X comments = extractcomment(&curcomments, -1, curserial); X changecomments(comments, -1, -1, -1, 0); X if (curctx->kind == MK_FUNCTION) { /* sub-procedure */ X savecmt = curcomments; X } else { X savecmt = NULL; X flushcomments(&curcomments, -1, -1); X } X curcomments = comments; X curserial = serialcount = 1; X gettok(); X if (!wexpecttok(TOK_IDENT)) X skiptotoken(TOK_IDENT); X if (curtokmeaning && curtokmeaning->ctx == curctx && X curtokmeaning->kind == MK_FUNCTION) { X func = curtokmeaning; X if (!func->isforward || func->val.i) X warning(format_s("Redeclaration of function %s [270]", func->name)); X skiptotoken(TOK_SEMI); X movetoend(func); X pushctx(func); X type = func->type; X } else { X func = addmeaning(curtoksym, MK_FUNCTION); X gettok(); X func->val.i = 0; X pushctx(func); X func->type = type = p_funcdecl(&isfunc, 0); X func->isfunction = isfunc; X func->namedfile = isinline; X type->meaning = func; X } X wneedtok(TOK_SEMI); X if (initializeattr) { X sl = strlist_append(&initialcalls, format_s("%s()", func->name)); X sl->value = 1; X } X if (curtok == TOK_IDENT && !strcmp(curtokbuf, "C")) { X gettok(); X wneedtok(TOK_SEMI); X } X if (blockkind == TOK_IMPORT) { X strlist_empty(&curcomments); X if (curtok == TOK_IDENT && X (!strcicmp(curtokbuf, "FORWARD") || X strlist_cifind(externwords, curtokbuf))) { X gettok(); X while (curtok == TOK_IDENT) X gettok(); X wneedtok(TOK_SEMI); X } X /* do nothing more */ X } else if (blockkind == TOK_EXPORT) { X func->isforward = 1; X scanfwdparams(func); X flushcomments(NULL, -1, -1); X forward_decl(func, 1); X } else { X checkkeyword(TOK_INTERRUPT); X checkkeyword(TOK_INLINE); X if (curtok == TOK_INTERRUPT) { X note("Ignoring INTERRUPT keyword [258]"); X gettok(); X wneedtok(TOK_SEMI); X } X if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "FORWARD")) { X func->isforward = 1; X scanfwdparams(func); X gettok(); X if (func->ctx->kind != MK_FUNCTION) { X outsection(minorspace); X flushcomments(NULL, -1, -1); X forward_decl(func, 0); X outsection(minorspace); X } X } else if (curtok == TOK_IDENT && X (strlist_cifind(externwords, curtokbuf) || X strlist_cifind(cexternwords, curtokbuf))) { X if (*externalias && my_strchr(externalias, '%')) { X strchange(&func->name, format_s(externalias, func->name)); X } else if (strlist_cifind(cexternwords, curtokbuf)) { X if (func->name[0] == '_') X strchange(&func->name, func->name + 1); X if (func->name[strlen(func->name)-1] == '_') X func->name[strlen(func->name)-1] = 0; X } X func->isforward = 1; /* for Oregon Software Pascal-2 */ X func->exported = 1; X gettok(); X while (curtok == TOK_IDENT) X gettok(); X outsection(minorspace); X flushcomments(NULL, -1, -1); X scanfwdparams(func); X forward_decl(func, 1); X outsection(minorspace); X } else if (curtok == TOK_IDENT) { X wexpecttok(TOK_BEGIN); /* print warning */ X gettok(); X outsection(minorspace); X flushcomments(NULL, -1, -1); X scanfwdparams(func); X forward_decl(func, 1); X outsection(minorspace); X } else { X if (func->ctx->kind == MK_FUNCTION) X func->ctx->needvarstruct = 1; X func->comments = curcomments; X curcomments = NULL; X p_block(TOK_FUNCTION); X echoprocname(func); X changecomments(curcomments, -1, curserial, -1, 10000); X sp = p_body(); X func->ctx->needvarstruct = 0; X func->val.i = (long)sp; X strlist_mix(&func->comments, curcomments); X curcomments = NULL; X if (func->ctx->kind != MK_FUNCTION || !collectnest) { X out_function(func); /* output top-level procedures immediately */ X } /* (sub-procedures are output later) */ X } X if (!wneedtok(TOK_SEMI)) X skippasttoken(TOK_SEMI); X } X strlist_mix(&curcomments, savecmt); X popctx(); X} X X X XStatic void out_include(name, quoted) Xchar *name; Xint quoted; X{ X if (quoted) X output(format_s("#include \"%s\"\n", name)); X else X output(format_s("#include <%s>\n", name)); X} X X XStatic void cleanheadername(dest, name) Xchar *dest, *name; X{ X char *cp; X int len; X X if (*name == '<' || *name == '"') X name++; X cp = my_strrchr(name, '/'); X if (cp) X cp++; X else X cp = name; X strcpy(dest, cp); X len = strlen(dest); X if (dest[len-1] == '>' || dest[len-1] == '"') X dest[len-1] = 0; X} X X X X XStatic int tryimport(sym, fname, ext, need) XSymbol *sym; Xchar *fname, *ext; Xint need; X{ X int found = 0; X Meaning *savectx, *savectxlast; X X savectx = curctx; X savectxlast = curctxlast; X curctx = nullctx; X curctxlast = curctx->cbase; X while (curctxlast && curctxlast->cnext) X curctxlast = curctxlast->cnext; X if (p_search(fname, ext, need)) { X curtokmeaning = sym->mbase; X while (curtokmeaning && !curtokmeaning->isactive) X curtokmeaning = curtokmeaning->snext; X if (curtokmeaning) X found = 1; X } X curctx = savectx; X curctxlast = savectxlast; X return found; X} X X X XStatic void p_import(inheader) Xint inheader; X{ X Strlist *sl; X Symbol *sym; X char *name; X int found, isfrom = (curtok == TOK_FROM); X X outsection(minorspace); X do { X gettok(); X if (!wexpecttok(TOK_IDENT)) { X skiptotoken(TOK_SEMI); X break; X } X sym = curtoksym; X if (curtokmeaning && curtokmeaning->kind == MK_MODULE) { X found = 1; X } else if (strlist_cifind(permimports, sym->name)) { X found = 2; /* built-in module, there already! */ X } else { X found = 0; X sl = strlist_cifind(importfrom, sym->name); X name = (sl) ? format_none((char *)sl->value) : NULL; X if (name) { X if (tryimport(sym, name, "pas", 1)) X found = 1; X } else { X for (sl = importdirs; sl && !found; sl = sl->next) { X if (tryimport(sym, format_s(sl->s, curtokcase), NULL, 0)) X found = 1; X } X } X } X if (found == 1) { X if (!inheader) { X sl = strlist_cifind(includefrom, curtokmeaning->name); X name = (sl) ? (char *)sl->value : X format_ss(*headerfnfmt2 ? headerfnfmt2 : headerfnfmt, X infname, curtokmeaning->name); X if (name && !strlist_find(includedfiles, name)) { X strlist_insert(&includedfiles, name); X if (*name_HSYMBOL) X output(format_s("#ifndef %s\n", format_s(name_HSYMBOL, sym->name))); X if (*name == '"' || *name == '<') X output(format_s("#include %s\n", name)); X else X out_include(name, quoteincludes); X if (*name_HSYMBOL) X output("#endif\n"); X outsection(minorspace); X } X } X import_ctx(curtokmeaning); X } else if (curtokmeaning) { X /* Modula-2, importing a single ident */ X /* Ignored for now, since we always import whole modules */ X } else if (found == 0) { X warning(format_s("Could not find module %s [271]", sym->name)); X if (!inheader) { X out_include(format_ss(*headerfnfmt2?headerfnfmt2:headerfnfmt, X sym->name, sym->name), X quoteincludes); X } X } X gettok(); X } while (curtok == TOK_COMMA); X if (isfrom) { X checkkeyword(TOK_IMPORT); X if (wneedtok(TOK_IMPORT)) { X do { X gettok(); X if (curtok == TOK_IDENT) X gettok(); X } while (curtok == TOK_COMMA); X } X } X if (!wneedtok(TOK_SEMI)) X skippasttoken(TOK_SEMI); X outsection(minorspace); X} X X X X Xvoid do_include(blkind) XToken blkind; X{ X FILE *oldfile = outf; X int savelnum = outf_lnum; X char fname[256]; X X outsection(majorspace); X strcpy(fname, curtokbuf); X removesuffix(fname); X strcat(fname, ".c"); X if (!strcmp(fname, codefname)) { X warning("Include file name conflict! [272]"); X badinclude(); X return; X } X saveoldfile(fname); X outf = fopen(fname, "w"); X if (!outf) { X outf = oldfile; X perror(fname); X badinclude(); X return; X } X outf_lnum = 1; X output(format_ss("\n/* Include file %s from %s */\n\n", fname, codefname)); X if (blkind == TOK_END) X gettok(); X else X curtok = blkind; X p_block(blockkind); X output("\n\n/* End. */\n\n"); X fclose(outf); X outf = oldfile; X outf_lnum = savelnum; X if (curtok != TOK_EOF) { X warning("Junk at end of include file ignored [273]"); X } X outsection(majorspace); X if (*includefnfmt) X out_include(format_s(includefnfmt, fname), 1); X else X out_include(fname, 1); X outsection(majorspace); X pop_input(); X getline(); X gettok(); X} X X X X X/* blockkind is one of: X TOK_PROGRAM: Global declarations of a program X TOK_FUNCTION: Declarations local to a procedure or function X TOK_IMPORT: Import text read from a module X TOK_EXPORT: Export section of a module X TOK_IMPLEMENT: Implementation section of a module X TOK_END: None of the above X*/ X Xvoid p_block(blkind) XToken blkind; X{ X Token saveblockkind = blockkind; X Token lastblockkind = TOK_END; X X blockkind = blkind; X for (;;) { X while (curtok == TOK_INTFONLY) { X include_as_import(); X gettok(); X } X if (curtok == TOK_CONST || curtok == TOK_TYPE || X curtok == TOK_VAR || curtok == TOK_VALUE) { X while (curtok == TOK_CONST || curtok == TOK_TYPE || X curtok == TOK_VAR || curtok == TOK_VALUE) { X lastblockkind = curtok; X switch (curtok) { X X case TOK_CONST: X p_constdecl(); X break; X X case TOK_TYPE: X p_typedecl(); X break; X X case TOK_VAR: X p_vardecl(); X break; X X case TOK_VALUE: X p_valuedecl(); X break; X X default: X break; X } X } X if ((blkind == TOK_PROGRAM || X blkind == TOK_EXPORT || X blkind == TOK_IMPLEMENT) && X (curtok != TOK_BEGIN || !mainlocals)) { X outsection(majorspace); X if (declarevars(curctx, 0)) X outsection(majorspace); X } X } else { X checkmodulewords(); X checkkeyword(TOK_SEGMENT); X if (curtok == TOK_SEGMENT) { X note("SEGMENT or OVERLAY keyword ignored [259]"); X gettok(); X } X p_attributes(); X switch (curtok) { X X case TOK_LABEL: X p_labeldecl(); X break; X X case TOK_IMPORT: X case TOK_FROM: X p_import(0); X break; X X case TOK_EXPORT: X do { X gettok(); X checkkeyword(TOK_QUALIFIED); X if (curtok == TOK_QUALIFIED) X gettok(); X wneedtok(TOK_IDENT); X } while (curtok == TOK_COMMA); X if (!wneedtok(TOK_SEMI)) X skippasttoken(TOK_SEMI); X break; X X case TOK_MODULE: X p_nested_module(); X break; X X case TOK_PROCEDURE: X p_function(0); X break; X X case TOK_FUNCTION: X p_function(1); X break; X X case TOK_INCLUDE: X if (blockkind == TOK_PROGRAM || X blockkind == TOK_IMPLEMENT || X (blockkind == TOK_FUNCTION && !collectnest)) { X do_include(lastblockkind); X } else { X badinclude(); X } X break; X X default: X if (curtok == TOK_BEGIN && blockkind == TOK_IMPORT) { X warning("BEGIN encountered in interface text [274]"); X skipparens(); X if (curtok == TOK_SEMI) X gettok(); X break; X } X blockkind = saveblockkind; X return; X } X lastblockkind = TOK_END; X } X } X} X X X X XStatic void skipunitheader() X{ X if (curtok == TOK_LPAR || curtok == TOK_LBR) { X skipparens(); X } X} X X XStatic void skiptomodule() X{ X skipping_module++; X while (curtok != TOK_MODULE) { X if (curtok == TOK_END) { X gettok(); X if (curtok == TOK_DOT) X break; X } else X gettok(); X } X skipping_module--; X} X X X XStatic void p_moduleinit(mod) XMeaning *mod; X{ X Stmt *sp; X Strlist *sl; X X if (curtok != TOK_BEGIN && curtok != TOK_END) { X wexpecttok(TOK_END); X skiptotoken2(TOK_BEGIN, TOK_END); X } X if (curtok == TOK_BEGIN || initialcalls) { X echoprocname(mod); X sp = p_body(); X strlist_mix(&mod->comments, curcomments); X curcomments = NULL; X if (ansiC != 0) X output("void "); X output(format_s(name_UNITINIT, mod->name)); X if (void_args) X output("(void)\n"); X else X output("()\n"); X outcontext = mod; X out_block(sp, BR_FUNCTION, 10000); X free_stmt(sp); X /* The following must come after out_block! */ X sl = strlist_append(&initialcalls, X format_s("%s()", X format_s(name_UNITINIT, mod->name))); X sl->value = 1; X } else X wneedtok(TOK_END); X} X X X XStatic void p_nested_module() X{ X Meaning *mp; X X if (!modula2) { X note("Ignoring nested module [260]"); X p_module(1, 0); X return; X } X note("Nested modules not fully supported [261]"); X checkmodulewords(); X wneedtok(TOK_MODULE); X wexpecttok(TOK_IDENT); X mp = addmeaning(curtoksym, MK_MODULE); X mp->anyvarflag = 0; X gettok(); X skipunitheader(); X wneedtok(TOK_SEMI); X p_block(TOK_IMPLEMENT); X p_moduleinit(mp); X if (curtok == TOK_IDENT) X gettok(); X wneedtok(TOK_SEMI); X} X X X XStatic int p_module(ignoreit, isdefn) Xint ignoreit; Xint isdefn; /* Modula-2: 0=local module, 1=DEFINITION, 2=IMPLEMENTATION */ X{ X Meaning *mod, *mp; X Strlist *sl; X int kind; X char *cp; X X checkmodulewords(); X wneedtok(TOK_MODULE); X wexpecttok(TOK_IDENT); X if (curtokmeaning && curtokmeaning->kind == MK_MODULE && isdefn == 2) { X mod = curtokmeaning; X import_ctx(mod); X for (mp = mod->cbase; mp; mp = mp->cnext) X if (mp->kind == MK_FUNCTION) X mp->isforward = 1; X } else { X mod = addmeaning(curtoksym, MK_MODULE); X } X mod->anyvarflag = 0; X pushctx(mod); X gettok(); X skipunitheader(); X wneedtok(TOK_SEMI); X if (ignoreit || X (requested_module && strcicmp(requested_module, mod->name))) { X if (!quietmode) X if (outf == stdout) X fprintf(stderr, "Skipping over module \"%s\"\n", mod->name); X else X printf("Skipping over module \"%s\"\n", mod->name); X checkmodulewords(); X while (curtok == TOK_IMPORT || curtok == TOK_FROM) X p_import(1); X checkmodulewords(); X if (curtok == TOK_EXPORT) X gettok(); X strlist_empty(&curcomments); X p_block(TOK_IMPORT); X setup_module(mod->sym->name, 0); X checkmodulewords(); X if (curtok == TOK_IMPLEMENT) { X skiptomodule(); X } else { X if (!wneedtok(TOK_END)) X skippasttoken(TOK_END); X if (curtok == TOK_SEMI) X gettok(); X } X popctx(); X strlist_empty(&curcomments); X return 0; X } X found_module = 1; X if (isdefn != 2) { X if (!*hdrfname) { X sl = strlist_cifind(includefrom, mod->name); X if (sl) X cleanheadername(hdrfname, (char *)sl->value); X else X strcpy(hdrfname, format_ss(headerfnfmt, infname, mod->name)); X } X saveoldfile(hdrfname); X hdrf = fopen(hdrfname, "w"); X if (!hdrf) { X perror(hdrfname); X error("Could not open output file for header"); X } X outsection(majorspace); X if (usevextern && my_strchr(name_GSYMBOL, '%')) X output(format_s("#define %s\n", format_s(name_GSYMBOL, mod->sym->name))); X out_include(hdrfname, quoteincludes); X outsection(majorspace); X select_outfile(hdrf); X output(format_s("/* Header for module %s, generated by p2c */\n", mod->name)); X if (*name_HSYMBOL) { X cp = format_s(name_HSYMBOL, mod->sym->name); X output(format_ss("#ifndef %s\n#define %s\n", cp, cp)); X } X outsection(majorspace); X checkmodulewords(); X while (curtok == TOK_IMPORT || curtok == TOK_FROM) X p_import(0); X checkmodulewords(); X if (curtok == TOK_EXPORT) X gettok(); X checkmodulewords(); X while (curtok == TOK_IMPORT || curtok == TOK_FROM) X p_import(0); X outsection(majorspace); X if (usevextern) { X output(format_s("#ifdef %s\n# define vextern\n#else\n", X format_s(name_GSYMBOL, mod->sym->name))); X output("# define vextern extern\n#endif\n"); X } X checkmodulewords(); X p_block(TOK_EXPORT); X setup_module(mod->sym->name, 1); X outsection(majorspace); X if (usevextern) X output("#undef vextern\n"); X outsection(minorspace); X if (*name_HSYMBOL) X output(format_s("#endif /*%s*/\n", format_s(name_HSYMBOL, mod->sym->name))); X output("\n/* End. */\n\n"); X select_outfile(codef); X fclose(hdrf); X *hdrfname = 0; X redeclarevars(mod); X declarevars(mod, 0); X } X checkmodulewords(); X if (curtok != TOK_END) { X if (!modula2 && !implementationmodules) X wneedtok(TOK_IMPLEMENT); X import_ctx(mod); X p_block(TOK_IMPLEMENT); X flushcomments(NULL, -1, -1); X p_moduleinit(mod); X kind = 1; X } else { X kind = 0; X if (!wneedtok(TOK_END)) X skippasttoken(TOK_END); X } X if (curtok == TOK_IDENT) X gettok(); X if (curtok == TOK_SEMI) X gettok(); X popctx(); X return kind; X} X X X X Xint p_search(fname, ext, need) Xchar *fname, *ext; Xint need; X{ X char infnbuf[300]; X FILE *fp; X Meaning *mod; X int savesysprog, savecopysource; X int outerimportmark, importmark, mypermflag; X X strcpy(infnbuf, fname); X fixfname(infnbuf, ext); X fp = fopen(infnbuf, "r"); X if (!fp) { X if (need) X perror(infnbuf); X if (logf) X fprintf(logf, "(Unable to open search file \"%s\")\n", infnbuf); X return 0; X } X flushcomments(NULL, -1, -1); X ignore_directives++; X savesysprog = sysprog_flag; X sysprog_flag |= 3; X savecopysource = copysource; X copysource = 0; X outerimportmark = numimports; /*obsolete*/ X importmark = push_imports(); X clearprogress(); X push_input_file(fp, infnbuf, 0); X do { X strlist_empty(&curcomments); X checkmodulewords(); X permflag = 0; X if (curtok == TOK_DEFINITION) { X gettok(); X checkmodulewords(); X } else if (curtok == TOK_IMPLEMENT && modula2) { X gettok(); X checkmodulewords(); X warning("IMPLEMENTATION module in search text! [275]"); X } X if (!wneedtok(TOK_MODULE)) X break; X if (!wexpecttok(TOK_IDENT)) X break; X mod = addmeaning(curtoksym, MK_MODULE); X mod->anyvarflag = 0; X if (!quietmode && !showprogress) X if (outf == stdout) X fprintf(stderr, "Reading import text for \"%s\"\n", mod->name); X else X printf("Reading import text for \"%s\"\n", mod->name); X if (verbose) X fprintf(logf, "%s, %d/%d: Reading import text for \"%s\"\n", X infname, inf_lnum, outf_lnum, mod->name); X pushctx(mod); X gettok(); X skipunitheader(); X wneedtok(TOK_SEMI); X mypermflag = permflag; X if (debug>0) printf("Found module %s\n", mod->name); X checkmodulewords(); X while (curtok == TOK_IMPORT || curtok == TOK_FROM) X p_import(1); X checkmodulewords(); X if (curtok == TOK_EXPORT) X gettok(); X strlist_empty(&curcomments); X p_block(TOK_IMPORT); X setup_module(mod->sym->name, 0); X if (mypermflag) { X strlist_add(&permimports, mod->sym->name)->value = (long)mod; X perm_import(mod); X } X checkmodulewords(); X if (curtok == TOK_END) { X gettok(); X if (curtok == TOK_SEMI) X gettok(); X } else { X wexpecttok(TOK_IMPLEMENT); X if (importall) { X skiptomodule(); X } X } X popctx(); X } while (curtok == TOK_MODULE); X pop_imports(importmark); X unimport(outerimportmark); X sysprog_flag = savesysprog; X copysource = savecopysource; X ignore_directives--; X pop_input(); X strlist_empty(&curcomments); X clearprogress(); X return 1; X} X X X X Xvoid p_program() X{ X Meaning *prog; X Stmt *sp; X int nummods, isdefn = 0; X X flushcomments(NULL, -1, -1); X output(format_s("\n#include %s\n", p2c_h_name)); X outsection(majorspace); X p_attributes(); X ignore_attributes(); X checkmodulewords(); X if (modula2) { X if (curtok == TOK_MODULE) { X curtok = TOK_PROGRAM; X } else { X if (curtok == TOK_DEFINITION) { X isdefn = 1; X gettok(); X checkmodulewords(); X } else if (curtok == TOK_IMPLEMENT) { X isdefn = 2; X gettok(); X checkmodulewords(); X } X } X } X switch (curtok) { X X case TOK_MODULE: X if (implementationmodules) X isdefn = 2; X nummods = 0; X while (curtok == TOK_MODULE) { X if (p_module(0, isdefn)) { X nummods++; X if (nummods == 2 && !requested_module) X warning("Multiple modules in one source file may not work correctly [276]"); X } X } X wneedtok(TOK_DOT); X break; X X default: X if (curtok == TOK_PROGRAM) { X gettok(); X if (!wexpecttok(TOK_IDENT)) X skiptotoken(TOK_IDENT); X prog = addmeaning(curtoksym, MK_MODULE); X gettok(); X if (curtok == TOK_LPAR) { X while (curtok != TOK_RPAR) { X if (curtok == TOK_IDENT && X strcicmp(curtokbuf, "INPUT") && X strcicmp(curtokbuf, "OUTPUT") && X strcicmp(curtokbuf, "KEYBOARD") && X strcicmp(curtokbuf, "LISTING")) { X if (literalfilesflag == 2) { X strlist_add(&literalfiles, curtokbuf); X } else X note(format_s("Unexpected name \"%s\" in program header [262]", X curtokcase)); X } X gettok(); X } X gettok(); X } X if (curtok == TOK_LBR) X skipparens(); X wneedtok(TOK_SEMI); X } else { X prog = addmeaning(findsymbol("program"), MK_MODULE); X } X prog->anyvarflag = 1; X if (requested_module && strcicmp(requested_module, prog->name) && X strcicmp(requested_module, "program")) { X for (;;) { X skiptomodule(); X if (curtok == TOK_DOT) X break; X (void)p_module(0, 2); X } X gettok(); X break; X } X pushctx(prog); X p_block(TOK_PROGRAM); X echoprocname(prog); X flushcomments(NULL, -1, -1); X if (curtok != TOK_EOF) { X sp = p_body(); X strlist_mix(&prog->comments, curcomments); X curcomments = NULL; X if (fullprototyping > 0) { X output(format_s("main(int argc, %s *argv[])", charname)); X } else { X output("main(argc, argv)\n"); X singleindent(argindent); X output("int argc;\n"); X singleindent(argindent); X output(format_s("%s *argv[];\n", charname)); X } X outcontext = prog; X out_block(sp, BR_FUNCTION, 10000); X free_stmt(sp); X popctx(); X if (curtok == TOK_SEMI) X gettok(); X else X wneedtok(TOK_DOT); X } X break; X X } X if (curtok != TOK_EOF) { X warning("Junk at end of input file ignored [277]"); X } X} X X X X X X/* End. */ X X END_OF_FILE if test 25765 -ne `wc -c <'src/parse.c.3'`; then echo shar: \"'src/parse.c.3'\" unpacked with wrong size! fi # end of 'src/parse.c.3' fi if test -f 'src/sys.p2crc.2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/sys.p2crc.2'\" else echo shar: Extracting \"'src/sys.p2crc.2'\" \(26809 characters\) sed "s/^X//" >'src/sys.p2crc.2' <<'END_OF_FILE' X # %S=name of parent module or procedure. X XConstFormat # Format for #define names derived from X # Pascal consts. (Often used: %^s) X XModuleFormat # Format for program and module names. X XFunctionFormat # Format for procedure and function names. X XVarFormat # Format for variable names. X XTypeFormat # Format for typedef names. X XFieldFormat # Format for fields of records; %S=record type. X XEnumFormat # Format for enumeration constants; X # %s=enum type name. If not specified, X # default is ConstFormat, else SymbolFormat. X XReturnValueName Result # Return value holding variable; [%s=func name] XUnitInitName _%s_init # Turbo Pascal unit initializer; %s=unit name XHSymbolName %s_H # Name of "_H" symbol, if any; %s=unit name XGSymbolName %s_G # Name of "_G" symbol; [%s=unit name] XStringMaxName MAX_%s # VAR STRING hidden variable; %s=param name XArrayMinName %s_LOW # Lower bound hidden variable; %s=param name XArrayMaxName %s_HIGH # Upper bound hidden variable; %s=param name XCopyParName %s_ # Alternate name for parameter %s XStaticLinkName LINK # Static link parameter name; [%s=func name] XLocalVarsStruct LOC_%s # Name of struct type for locals; %s=func name XLocalVarsName V # Name of struct var for locals; [%s=func name] XFwdStructName %s # Name of forward-used structs; %s=type name X # (may simply be %s if you don't mind confusion) XEnumListName %s_NAMES # Name of array to hold names for enum %s XUnionName UU # Name of variant union XUnionPartName %s # Name of variant element; %s=tag value name XFakeStructName _REC_%s # Name of "temporary" structs; %s=base name XLabelName _L%s # Name of GOTO label; %s=label name XLabelVarName _JL%s # Name of GOTO label jmp_buf variable; %s=label XTempName TEMP%s # Name of general temporary vars; %s=unique id XDummyName DUMMY%s # Name of throwaway "dummy" vars; %s=unique id XWithName WITH%s # Name of WITH statement temp ptr; %s=unique id XForName FORLIM%s # Name of FOR statement temp limit; %s=unique id XPtrName PTR%s # Name of NIL-checking temp ptr; %s=unique id XStringName STR%s # Name of temporary string vars; %s=unique id XSetName SET%s # Name of temporary set vars; %s=unique id XFNVarName %s_NAME # Name of file-name vars; %s=file var XFNSizeName _FNSIZE # Maximum length of file name (macro or integer) X XAlternateName1 %s_ # Way to produce a second C symbol for a Pascal X # symbol, where original symbol was %s. Default X # is to use AlternateName with %d=1. X XAlternateName2 # A second alternate for %s. X XAlternateName # A %d'th name for %s. %s and %d may appear in X # either order. Default is %d applications of X # AlternateName1. X XExportSymbol # Name of exported symbol %s. E.g.: "P_%s" X # Default=%s, i.e., don't mess with the name. X # %s is Pascal symbol name; %S is module name. X XExport_Symbol # Exported-symbol format to be used when the X # symbol %s contains an '_'. Default=use X # ExportSymbol format for every symbol. X XAlias # Name of external proc or var; default="%s". X # If does not contain a "%s", this simply X # renames the next defined symbol of any kind. X XSynonym # Format: Synonym name = newname XSynonym # Treat the word "name" in the input file XSynonym # exactly the same as the keyword or identifier XSynonym # "newname". If "newname" is omitted, ignore XSynonym # the word "name" in the input. For example: XSynonym # "Synonym andthen = and" creates a keyword; XSynonym # "Synonym allocmem = getmem" simulates a XSynonym # built-in function "allocmem" which acts like XSynonym # Turbo's "getmem"; "Synonym segment" ignores XSynonym # the word "segment" in the input. X XNameOf # Format: NameOf name = newname XNameOf # Rename the specified symbol. The name may XNameOf # be of the form "modulename.name" or XNameOf # "procname.name"; otherwise, all usages of XNameOf # the symbol are renamed. X XVarMacro # Format: VarMacro varname = C-expression XVarMacro # Must come before the declaration of variable XVarMacro # "varname". Causes all references to the XVarMacro # variable to use the C expression instead. XVarMacro # In the expr, all C operators are supported; XVarMacro # all identifier names are used verbatim. XVarMacro # Also works for Turbo Pascal typed-constants. XVarMacro # Suppresses declaration of variable unless XVarMacro # "varname" appears in the C expression. XVarMacro # Simple algebra is used for assignments to XVarMacro # vars with expr definitions: if X -> 2*V+1, XVarMacro # then "X:=Y" translates to "V=(Y-1)/2". X XConstMacro # Analogous to VarMacro, but for constants and XConstMacro # enumeration constants. In an enum constant, XConstMacro # if the C-expression is a single name the XConstMacro # result is equivalent to Alias or NameOf. X XFieldMacro # Format: FieldMacro rec.field = C-expression XFieldMacro # where "rec" is a record type name which XFieldMacro # also appears in the C-expression. For XFieldMacro # example: FieldMacro obj.foo = bar(obj) causes XFieldMacro # the field "foo" of record type "obj" to be XFieldMacro # referenced through the function or macro XFieldMacro # "bar", rather than using dot notation. X XFuncMacro # Format: FuncMacro foo(a,b,c) = C-expression XFuncMacro # where "a", "b", "c" are arbitrary arg names XFuncMacro # also appearing in the C-expression. "Foo" XFuncMacro # is a procedure or function defined or to be XFuncMacro # defined in the code, or predefined in Pascal. XFuncMacro # E.g.: FuncMacro PtInRect(p,r) = PtInRect(p,&r) XFuncMacro # causes "r" to be treated as a VAR param even XFuncMacro # though otherwise it would be passed by value. X XWarnMacros # 1=warn if Var/Const/Field/FuncMacro not used X # 0 or default=don't care. X XSpecialMalloc # Format: SpecialMalloc x.y.z = funcname XSpecialMalloc # where x is a type name, and y and z are XSpecialMalloc # optional variant tags for records. The XSpecialMalloc # statement "new(p,y,z)" where p is a pointer XSpecialMalloc # to x is converted to p = funcname(). X XSpecialFree # Like SpecialMalloc, but defines a special XSpecialFree # function for freeing things of a given type. X XSpecialSizeOf # Like SpecialMalloc, but defines a name or XSpecialSizeOf # other integer-valued C expression which is XSpecialSizeOf # the size of an object of the given type. X XAvoidName getc # If any of these names appear in the code, XAvoidName putc # use an alternate name so as to avoid XAvoidName getchar # library conflicts. XAvoidName putchar XAvoidName feof # These are typically macro names whose use XAvoidName ferror # would be disasterous under any XAvoidName clearerr # circumstances. XAvoidName fileno XAvoidName BUFSIZ NULL EOF XAvoidName stdin stdout stderr XAvoidName true false assert XAvoidName Anyptr Void Char PP PV XAvoidName Signed Const Volatile Register Static Local Inline XAvoidName cdecl far near huge XAvoidName isalpha isupper islower isdigit isxdigit isspace ispunct XAvoidName isalnum isprint isgraph iscntrl isascii toascii XAvoidName toupper tolower XAvoidName LINK SEXT X XAvoidGlobalName fopen # These names should be avoided in global XAvoidGlobalName fclose # contexts, but they are okay as local names. XAvoidGlobalName fseek XAvoidGlobalName exit main XAvoidGlobalName strcpy strcat XAvoidGlobalName printf fprintf sprintf XAvoidGlobalName scanf fscanf sscanf XAvoidGlobalName malloc realloc free XAvoidGlobalName y0 y1 yn j0 j1 jn # from math.h -- urghhh! X # ... we should define lots more of these! X XWarnName # A similar list of names to leave alone, but XWarnName # generate warnings for if they are defined. X XWarnNames # 1=All vars, consts, types, procs, fields X # defined after this point should generate X # warnings if used. X # 0 or default=no warnings for future names X XWarnLibrary # A list of C functions, any calls to which XWarnLibrary # should generate warnings. X X X X X X# TARGET LIBRARY X XQuoteIncludes # 1 or default=write #include "foo.h" X # 0=write #include <foo.h> X XIncludeFrom # Names of modules which need special XIncludeFrom # #include file names. Formats: XIncludeFrom # IncludeFrom foo bar.h => #include <bar.h> XIncludeFrom # if QuoteIncludes=0 else #include "bar.h" XIncludeFrom # IncludeFrom foo <bar.h> => #include <bar.h> XIncludeFrom # IncludeFrom foo "bar.h" => #include "bar.h" XIncludeFrom # IncludeFrom foo => no #include at all XIncludeFrom iodeclarations <p2c/iodecl.h> XIncludeFrom system XIncludeFrom printer XIncludeFrom dos XIncludeFrom crt X XImportFrom # Names of modules whose import text XImportFrom # resides in the specified files. XImportFrom # E.g.: ImportFrom mymod /usr/me/mymod.imp XImportFrom # These are the Turbo Pascal standard units XImportFrom system %H/turbo.imp XImportFrom printer %H/turbo.imp XImportFrom dos %H/turbo.imp XImportFrom crt %H/turbo.imp XImportFrom graph %H/turbo.imp X XImportDir %_s.pas # Search list of other places to look for XImportDir %_s.text # the module named %s. XImportDir %H/%_s.imp X XIncludeDir %_s # Search list of places to look for the XIncludeDir %_s.pas # Pascal include file %s. XIncludeDir %_s.text XIncludeDir %H/%_s.pas X XLibraryFile %H/system.imp # Names of import-text files to search XLibraryFile # always (as if "-s name" were used). X XStructFunction sprintf # Names of "structured functions". XStructFunction memcpy memmove XStructFunction strcpy strsub strrtrim strrpt XStructFunction P_addset P_addsetr P_remset X XStrlapFunction P_setunion # Names of "structured functions" which XStrlapFunction P_setint # allow duplication of their arguments. XStrlapFunction P_setdiff XStrlapFunction P_setxor XStrlapFunction P_expset strlower strupper strpad X XNoSideEffects strcmp memcmp # Names of functions which have absolutely XNoSideEffects # no side effects on their arguments or XNoSideEffects # other global state of the program. X XDeterministic abs sin cos # Names of functions which satisfy all XDeterministic # requirements for NoSideEffects, and XDeterministic # additionally compute their result XDeterministic # deterministically (and quickly), without XDeterministic # any sort of hidden dependencies. X # (need many more in this list!) X XLeaveAlone # Names of library functions which should XLeaveAlone # be left alone, rather than translated XLeaveAlone # into C equivalents. (For example, prevents XLeaveAlone # converting fwritebytes into C fwrite.) X XHeaderName <p2c/p2c.h> # Name of standard p2c header file X XUCharName uchar # Name of a typedef for "unsigned char"; X # default="char" or "unsigned char". X XSCharName schar # Name of a typedef for "signed char"; X # default="char" or "signed char". X XBooleanName boolean # Name of a typedef for booleans; default=char. X XTrueName true # Name of a boolean "true" constant (optional) XFalseName false # Name of a boolean "false" constant (opt.) X XNullName NULL # Name of a NULL pointer constant X XProcTypeName _PROCEDURE # Name of procedure-pointer typedef X XEscapeCodeName P_escapecode # Names of error-handling variables XIOResultName P_ioresult X XArgCName P_argc # Name of global copy of argc XArgVName P_argv # Name of global copy of argv X XMainName PASCAL_MAIN # Name of program setup function X XEscapeName _Escape # Name of error-generation function X XEscIOName _EscIO # Name of I/O-error-generation function X XCheckIOName _CHKIO # Name of I/O-error-checking function X XSetIOName _SETIO # Name of I/O-error-setting function X XFileNotFoundName FileNotFound # Name or number of "File Not Found" ioresult X XFileNotOpenName FileNotOpen # Name or number of "File Not Open" ioresult X XFileWriteErrorName FileWriteError # Name of num of "File Write Error" ioresult X XBadInputFormatName BadInputFormat # Name or num of "Bad Input Format" ioresult X XEndOfFileName EndOfFile # Name or number of "End of File" ioresult X XOutMemName _OutMem # Name of out-of-memory error function X XCaseCheckName _CaseCheck # Name of case-out-of-range error function X XNilCheckName _NilCheck # Name of nil-pointer error function X XSetBitsName # Name of macro defined equal to SetBits X # default=compile SetBits in-line X XSprintfValue # 1=sprintf() returns its first argument X # 0=sprintf() returns a character count X # default=don't know (unless AnsiC=1) X # -2=don't know regardless of AnsiC X # 2=don't use sprintf in expressions X XSprintfName # If SprintfValue != 1, this is the name X # of a sprintf-like function which returns X # its first argument. Default=no such X # function exists. X XMemCpyName # Methods known: "memcpy", "bcopy" X # default=according to Target, default "memcpy" X XRoundName # Name of function or macro for rounding X # a real to an integer. Precede name with X # a '*' if it is a macro that evaluates its X # arguments more than once. Default=do it X # by hand. X XDivName # Name of function or macro for Pascal integer X # division where numerator may be negative. X # Use '*' if macro; default=use regular '/'. X XModName # Name of function or macro for Pascal integer X # modulo where numerator may be negative. X # Use '*' if macro; default=use regular '%'. X XRemName # Name of function or macro for VAX Pascal X # REM where numerator or denominator may be X # negative. Use '*' if macro; default=use MOD. X XAbsName labs # Name of function for computing ABS of a X # "long" value. Precede with '*' if a X # macro. Default=by hand, or "labs" in AnsiC. X XOddName # Name of a macro for computing ODD of an X # integer. Default=x&1. X XEvenName # Name of a macro for computing NOT ODD of X # an integer. Default=!odd(x). X XSwapName _swap # Name of Turbo-like swap() function. X XStrCpyLeft # 1 or default=strcpy(s1,s2) works even if X # s1 and s2 overlap, provided s1 <= s2. X # 0=strcpy(s1,s2) does not allow overlap. X XStrCICmpName strcicmp # Name of a strcicmp-like function; no default XStrSubName strsub # Name of a strsub-like function; no default XStrPosName strpos2 # Name of a strpos2-like function; no default XStrDeleteName strdelete # Name of a strdelete-like function; no default XStrInsertName strinsert # Name of a strinsert-like function; no default XStrMoveName strmove # Name of a strmove-like function; no default XStrLTrimName strltrim # Name of a strltrim-like function; no default XStrRTrimName strrtrim # Name of a strrtrim-like function; no default XStrRptName strrpt # Name of a strrpt-like function; no default XStrPadName strpad # Name of a pad-like function; no default X XMallocName Malloc # Name of a malloc-like function; default=malloc XFreeName Free # Name of a dispose-like function; default=free XFreeRvalueName FreeR # Name of a free-like function; default=free X XRandRealName _randreal # Name of a Turbo "random" function; no default XRandIntName _randint # Name of a Turbo "random()" function; no def XRandomizeName _randomize # Name of a Turbo "randomize" procedure X XSkipSpaceName _skipspaces # Name of a Turbo seekeof/seekeoln skipper X XReadlnName # Name of function or macro to skip past eoln. X # Special names: fgets=use fgets with dummy var X # scanf=use scanf/fscanf X # Default=use whichever method works out best X XFreopenName # Name of function or macro that acts like X # freopen(n,m,f), but if f==NULL acts like X # fopen(n,m). Default=do it by hand. X # "fopen"=assume not reopening files. X # "fclose"=fclose first, then fopen. X XEofName P_eof # Name of "feof" with Pascal semantics. XEolnName P_eoln # Name of "eoln" function. XFilePosName ftell # Name of "filepos" function. XMaxPosName P_maxpos # Name of "maxpos" function. X XSetUnionName P_setunion # Name of a set "+" function; no default XSetIntName P_setint # Name of a set "*" function; no default XSetDiffName P_setdiff # Name of a set "-" function; no default XSetXorName P_setxor # Name of a set "/" function; no default XSetInName P_inset # Name of a set "IN" function; no default XSetAddName P_addset # Name of a set "a:=a+[x]" function; no default XSetAddRangeName P_addsetr # Name of a set "a:=a+[x..y]" function; no def XSetRemName P_remset # Name of a set "a:=a-[x]" function; no default XSetEqualName P_setequal # Name of a set "=" function; no default XSubSetName P_subset # Name of a set "<=" function; no default XSetCopyName P_setcpy # Name of a set ":=" function; no default XSetExpandName P_expset # Name of small-set-to-set expander; no default XSetPackName P_packset # Name of set-to-small-set packer; no default X XSignExtendName SEXT # Name of macro to sign-extend a number. X XGetBitsName *P_getbits_%s # Name of family of array-unpacking functions. X # Precede name with '*' if a macro. %s will X # expand to S (for signed) or U (for unsigned), X # followed by B (big array) or S (small array). X XPutBitsName *P_putbits_%s # Name of family of functions which 'OR' a X # value into an element of a packed array. X # %s expands to S or U, followed by B or S. X # Use '*' if macro. Default=use StoreBits. X XClrBitsName *P_clrbits_%s # Name of family of functions which zero an X # element of a packed array. %s expands X # to B or S only. Use '*' if macro. X # Default=use StoreBits. X XStoreBitsName # Name of a family of functions or macros X # which act just like PutBits, but overwrite X # the array element rather than OR'ing. X # Default=use ClrBits followed by PutBits. X # At least StoreBits or both PutBits and X # ClrBits must be defined. X XDeclBufName FILEBUF # Name of a macro for declaring the file X # buffer for a file using GET and PUT. X XDeclBufNCName # Name of a DeclBufName-like macro with two X # arguments (no storage class), in case your X # compiler can't handle null macro arguments. X XBufferedFile # Names of file variables that use GET/PUT/^ XBufferedFile # notation instead of READ/WRITE notation. XBufferedFile # Mostly useful for globals; locals are XBufferedFile # detected automatically. May be a var name, XBufferedFile # field name, proc.var, type.field, or XBufferedFile # "1"=use buffers for all files. X XUnBufferedFile # Names of files that will not be buffered, XUnBufferedFile # even if they would otherwise be. Syntax XUnBufferedFile # same as for BufferedFile. X XResetBufName RESETBUF # Name of a macro for setting up a file X # buffer in "read" mode. (For RESET.) X XSetupBufName SETUPBUF # Name of a macro for setting up a file X # buffer in read/write mode. (For OPEN, SEEK.) X XGetFBufName GETFBUF # Name of a macro for accessing a file X # buffer using "file^" notation. X XGetName GET # Name of a macro for advancing X # to the next element of an input file. X XPutFBufName PUTFBUF # Name of a macro for storing an element X # of a file using "file^" notation. X XPutName PUT # Name of a macro for advancing X # to the next element of an output file. X XCharGetFBufName P_peek # A special GetFBuf for text and files of char. X XCharGetName getc # A special Get for text and files of char. X XCharPutFBufName CPUTFBUF # A special PutFBuf for text and files of char. X XCharPutName CPUT # A special Put for text and files of char. X XArrayGetFBufName AGETFBUF # A special GetFBuf for files of arrays. X XArrayGetName # A special Get for files of arrays. X XArrayPutFBufName APUTFBUF # A special PutFBuf for files of arrays. X XArrayPutName # A special Put for files of arrays. X X X X# CHECKING X XCaseCheck # 1=check CASE statements without OTHERWISE X # 0 or default=skip CASE stmt if out of range X # 2=according to $range$ directives X XArrayCheck # 1=check array bounds X # 0 or default=do not check array bounds X # 2=according to $range$ directives X # (not yet implemented) X XNilCheck # check pointer dereferences (0, 1, or 2) X XRangeCheck # enable other range checking (0, 1, or 2): X # string indexing, ...? X # (not yet implemented) X XMallocCheck # 1=check if malloc returns NULL X # 0 or default=assume malloc never returns NULL X # (often used with MallocName; see above) X XCheckFileOpen # 1 or default=check for errors during open, X # 0=assume file opens successfully X # 2=check only when $iocheck off$ or {$I-} X XCheckFileIsOpen # 1=check for "file not open" error, X # 0 or default=eof, etc., assume file is open X # 2=check only when $iocheck off$ or {$I-} X XCheckFileWrite # 1=check for errors during write X # 0=ignore write errors X # 2 or default=only when $iocheck off$ or {$I-} X XCheckReadFormat # 1=check for "bad format" errors during read X # 0=ignore read format errors X # 2 or default=only when $iocheck off$ or {$I-} X XCheckFileEOF # 1=check for "past EOF" errors reading files X # 0=ignore file EOF errors X # 2 or default=only when $iocheck off$ or {$I-} X XCheckStdinEOF # 1=check for "past EOF" errors reading stdin X # 0=ignore stdin EOF errors X # 2 or default=only when $iocheck off$ or {$I-} X XCheckFileSeek # 1=check for errors during seek X # 0=ignore seek errors X # 2 or default=only when $iocheck off$ or {$I-} X X X X XInclude %H/loc.p2crc # Include any local modifications to this file. X X X X# End of p2crc END_OF_FILE if test 26809 -ne `wc -c <'src/sys.p2crc.2'`; then echo shar: \"'src/sys.p2crc.2'\" unpacked with wrong size! fi # end of 'src/sys.p2crc.2' fi echo shar: End of archive 8 \(of 32\). cp /dev/null ark8isdone 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.