home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
379a.lha
/
p2c1_13a
/
src
/
src.zoo
/
parse4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-11
|
35KB
|
1,289 lines
/* "p2c", a Pascal to C translator.
Copyright (C) 1989 David Gillespie.
Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (any version).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define PROTO_PARSE4_C
#include "trans.h"
extern Stmt bogusreturn;
extern Meaning *outcontext;
extern Strlist *includedfiles;
#define addstmt(kind) \
*spp = sp = makestmt(kind), \
spp = &(sp->next)
#define SF_FUNC 0x1
#define BR_NEVER 0x1 /* never use braces */
#define BR_FUNCTION 0x2 /* function body */
#define BR_THENPART 0x4 /* before an "else" */
#define BR_ALWAYS 0x8 /* always use braces */
#define BR_REPEAT 0x10 /* "do-while" loop */
#define BR_TRY 0x20 /* in a recover block */
#define BR_ELSEPART 0x40 /* after an "else" */
#define BR_CASE 0x80 /* case of a switch stmt */
void initfilevars(mp, sppp, exbase)
Meaning *mp;
Stmt ***sppp;
Expr *exbase;
{
Stmt *sp;
Type *tp;
Expr *ex;
while (mp) {
if ((mp->kind == MK_VAR && mp->refcount > 0 && !mp->istemporary) ||
mp->kind == MK_FIELD) {
tp = mp->type;
if (isfiletype(tp)) {
mp->refcount++;
sp = makestmt(SK_ASSIGN);
sp->next = **sppp;
**sppp = sp;
if (exbase)
ex = makeexpr_dot(copyexpr(exbase), mp);
else
ex = makeexpr_var(mp);
sp->exp1 = makeexpr_assign(copyexpr(ex), makeexpr_nil());
} else if (tp->kind == TK_RECORD) {
if (exbase)
ex = makeexpr_dot(copyexpr(exbase), mp);
else
ex = makeexpr_var(mp);
initfilevars(tp->fbase, sppp, ex);
freeexpr(ex);
} else if (tp->kind == TK_ARRAY) {
while (tp->kind == TK_ARRAY)
tp = tp->basetype;
if (isfiletype(tp))
note(format_s("Array of files %s should be initialized [257]",
mp->name));
}
}
mp = mp->cnext;
}
}
Static Stmt *p_body()
{
Stmt *sp, **spp, *spbody, **sppbody, *spbase, *thereturn;
Meaning *mp;
Expr *ex;
int haspostamble;
long saveserial;
if (verbose)
fprintf(logf, "%s, %d/%d: Translating %s (in %s)\n",
infname, inf_lnum, outf_lnum,
curctx->name, curctx->ctx->name);
notephase = 1;
spp = &spbase;
addstmt(SK_HEADER);
sp->exp1 = makeexpr_var(curctx);
checkkeyword(TOK_INLINE);
if (curtok != TOK_END && curtok != TOK_BEGIN && curtok != TOK_INLINE) {
if (curctx->kind == MK_FUNCTION || curctx->anyvarflag)
wexpecttok(TOK_BEGIN);
else
wexpecttok(TOK_END);
skiptotoken2(TOK_BEGIN, TOK_END);
}
if (curtok == TOK_END) {
gettok();
spbody = NULL;
} else {
spbody = p_stmt(NULL, SF_FUNC); /* parse the procedure/program body */
}
if (curtok == TOK_IDENT && curtokmeaning == curctx) {
gettok(); /* Modula-2 */
}
notephase = 2;
saveserial = curserial;
curserial = 10000;
if (curctx->kind == MK_FUNCTION) { /* handle copy parameters */
for (mp = curctx->type->fbase; mp; mp = mp->xnext) {
if (!mp->othername && mp->varstructflag) {
mp->othername = stralloc(format_s(name_COPYPAR, mp->name));
mp->rectype = mp->type;
addstmt(SK_ASSIGN);
sp->exp1 = makeexpr_assign(makeexpr_var(mp),
makeexpr_name(mp->othername, mp->rectype));
mp->refcount++;
} else if (mp->othername) {
if (checkvarchanged(spbody, mp)) {
addstmt(SK_ASSIGN);
sp->exp1 = makeexpr_assign(makeexpr_var(mp),
makeexpr_hat(makeexpr_name(mp->othername,
mp->rectype), 0));
mp->refcount++;
} else { /* don't need to copy it after all */
strchange(&mp->othername, mp->name);
ex = makeexpr_var(mp);
ex->val.type = mp->rectype;
replaceexpr(spbody, makeexpr_var(mp), makeexpr_hat(ex, 0));
}
}
}
}
for (mp = curctx->cbase; mp; mp = mp->cnext) {
if (mp->kind == MK_LABEL && mp->val.i) {
addstmt(SK_IF);
sp->exp1 = makeexpr_bicall_1("setjmp", tp_int,
makeexpr_var(mp->xnext));
sp->stm1 = makestmt(SK_GOTO);
sp->stm1->exp1 = makeexpr_name(format_s(name_LABEL, mp->name),
tp_integer);
}
}
*spp = spbody;
sppbody = spp;
while (*spp)
spp = &((*spp)->next);
haspostamble = 0;
initfilevars(curctx->cbase, &sppbody, NULL);
for (mp = curctx->cbase; mp; mp = mp->cnext) {
if (mp->kind == MK_VAR && mp->refcount > 0 && isfiletype(mp->type) &&
!mp->istemporary) {
if (curctx->kind != MK_MODULE || curctx->anyvarflag) {
addstmt(SK_IF); /* close file variables */
sp->exp1 = makeexpr_rel(EK_NE, makeexpr_var(mp), makeexpr_nil());
sp->stm1 = makestmt(SK_ASSIGN);
sp->stm1->exp1 = makeexpr_bicall_1("fclose", tp_void, makeexpr_var(mp));
}
haspostamble = 1;
}
}
thereturn = &bogusreturn;
if (curctx->kind == MK_FUNCTION && curctx->type->basetype != tp_void) {
if ((haspostamble || !checkreturns(&spbase, 1)) &&
curctx->cbase->refcount > 0) { /* add function return code */
addstmt(SK_RETURN);
sp->exp1 = makeexpr_var(curctx->cbase);
}
thereturn = NULL;
} else if (curctx->kind == MK_MODULE && curctx->anyvarflag) {
addstmt(SK_ASSIGN);
sp->exp1 = makeexpr_bicall_1("exit", tp_void, makeexpr_long(0));
thereturn = NULL;
}
if (debug>2) { fprintf(outf, "calling fixblock/usecommas on:\n"); dumpstmt(spbase, 5); }
curserial = saveserial;
sp = makestmt(SK_BODY);
sp->stm1 = spbase;
fixblock(&sp, thereturn); /* finishing touches to statements and expressions */
spbase = sp->stm1;
FREE(sp);
if (usecommas != 1)
checkcommas(&spbase); /* unroll ugly EK_COMMA and EK_COND expressions */
if (debug>1) { fprintf(outf, "p_body returns:\n"); dumpstmt(spbase, 5); }
notephase = 0;
return spbase;
}
#define checkWord() if (anywords) output(" "); anywords = 1
Static void out_function(func)
Meaning *func;
{
Meaning *mp;
Symbol *sym;
int opts, anywords, spacing, saveindent;
if (func->varstructflag) {
makevarstruct(func);
}
if (collectnest) {
for (mp = func->cbase; mp; mp = mp->cnext) {
if (mp->kind == MK_FUNCTION && mp->isforward) {
forward_decl(mp, 0);
}
}
for (mp = func->cbase; mp; mp = mp->cnext) {
if (mp->kind == MK_FUNCTION && mp->type) {
pushctx(mp);
out_function(mp); /* generate the sub-procedures first */
popctx();
}
}
}
spacing = functionspace;
for (mp = func; mp->ctx->kind == MK_FUNCTION; mp = mp->ctx) {
if (spacing > minfuncspace)
spacing--;
}
outsection(spacing);
flushcomments(&func->comments, -1, 0);
if (usePPMacros == 1) {
forward_decl(func, 0);
outsection(minorspace);
}
opts = ODECL_HEADER;
anywords = 0;
if (func->namedfile) {
checkWord();
if (useAnyptrMacros || ansiC < 2)
output("Inline");
else
output("inline");
}
if (!func->exported) {
if (func->ctx->kind == MK_FUNCTION) {
if (useAnyptrMacros) {
checkWord();
output("Local");
} else if (use_static) {
checkWord();
output("static");
}
} else if ((findsymbol(func->name)->flags & NEEDSTATIC) ||
(use_static != 0 && !useAnyptrMacros)) {
checkWord();
output("static");
} else if (useAnyptrMacros) {
checkWord();
output("Static");
}
}
if (func->type->basetype != tp_void || ansiC != 0) {
checkWord();
outbasetype(func->type, 0);
}
if (anywords) {
if (newlinefunctions)
opts |= ODECL_FUNCTION;
else
output(" ");
}
outdeclarator(func->type, func->name, opts);
if (fullprototyping == 0) {
saveindent = outindent;
moreindent(argindent);
out_argdecls(func->type);
outindent = saveindent;
}
for (mp = func->type->fbase; mp; mp = mp->xnext) {
if (mp->othername && strcmp(mp->name, mp->othername))
mp->wasdeclared = 0; /* make sure we also declare the copy */
}
func->wasdeclared = 1;
outcontext = func;
out_block((Stmt *)func->val.i, BR_FUNCTION, 10000);
if (useundef) {
anywords = 0;
for (mp = func->cbase; mp; mp = mp->cnext) {
if (mp->kind == MK_CONST &&
mp->isreturn) { /* the was-#defined flag */
if (!anywords)
outsection(minorspace);
anywords++;
output(format_s("#undef %s\n", mp->name));
sym = findsymbol(mp->name);
sym->flags &= ~AVOIDNAME;
}
}
}
if (conserve_mem) {
free_stmt((Stmt *)func->val.i); /* is this safe? */
func->val.i = 0;
forget_ctx(func, 0);
}
outsection(spacing);
}
void movetoend(mp)
Meaning *mp;
{
Meaning **mpp;
if (mp->ctx != curctx) {
intwarning("movetoend", "curctx is wrong [268]");
} else {
mpp = &mp->ctx->cbase; /* move a meaning to end of its parent context */
while (*mpp != mp) {
if (!*mpp) {
intwarning("movetoend", "meaning not on its context list [269]");
return;
}
mpp = &(*mpp)->cnext;
}
*mpp = mp->cnext; /* Remove from present position in list */
while (*mpp)
mpp = &(*mpp)->cnext;
*mpp = mp; /* Insert at end of list */
mp->cnext = NULL;
curctxlast = mp;
}
}
Static void scanfwdparams(mp)
Meaning *mp;
{
Symbol *sym;
mp = mp->type->fbase;
while (mp) {
sym = findsymbol(mp->name);
sym->flags |= FWDPARAM;
mp = mp->xnext;
}
}
Static void p_function(isfunc)
int isfunc;
{
Meaning *func;
Type *type;
Stmt *sp;
Strlist *sl, *comments, *savecmt;
int initializeattr = 0, isinline = 0;
if ((sl = strlist_find(attrlist, "INITIALIZE")) != NULL) {
initializeattr = 1;
strlist_delete(&attrlist, sl);
}
if ((sl = strlist_find(attrlist, "OPTIMIZE")) != NULL &&
sl->value != -1 &&
!strcmp((char *)(sl->value), "INLINE")) {
isinline = 1;
strlist_delete(&attrlist, sl);
}
ignore_attributes();
comments = extractcomment(&curcomments, -1, curserial);
changecomments(comments, -1, -1, -1, 0);
if (curctx->kind == MK_FUNCTION) { /* sub-procedure */
savecmt = curcomments;
} else {
savecmt = NULL;
flushcomments(&curcomments, -1, -1);
}
curcomments = comments;
curserial = serialcount = 1;
gettok();
if (!wexpecttok(TOK_IDENT))
skiptotoken(TOK_IDENT);
if (curtokmeaning && curtokmeaning->ctx == curctx &&
curtokmeaning->kind == MK_FUNCTION) {
func = curtokmeaning;
if (!func->isforward || func->val.i)
warning(format_s("Redeclaration of function %s [270]", func->name));
skiptotoken(TOK_SEMI);
movetoend(func);
pushctx(func);
type = func->type;
} else {
func = addmeaning(curtoksym, MK_FUNCTION);
gettok();
func->val.i = 0;
pushctx(func);
func->type = type = p_funcdecl(&isfunc, 0);
func->isfunction = isfunc;
func->namedfile = isinline;
type->meaning = func;
}
wneedtok(TOK_SEMI);
if (initializeattr) {
sl = strlist_append(&initialcalls, format_s("%s()", func->name));
sl->value = 1;
}
if (curtok == TOK_IDENT && !strcmp(curtokbuf, "C")) {
gettok();
wneedtok(TOK_SEMI);
}
if (blockkind == TOK_IMPORT) {
strlist_empty(&curcomments);
if (curtok == TOK_IDENT &&
(!strcicmp(curtokbuf, "FORWARD") ||
strlist_cifind(externwords, curtokbuf))) {
gettok();
while (curtok == TOK_IDENT)
gettok();
wneedtok(TOK_SEMI);
}
/* do nothing more */
} else if (blockkind == TOK_EXPORT) {
func->isforward = 1;
scanfwdparams(func);
flushcomments(NULL, -1, -1);
forward_decl(func, 1);
} else {
checkkeyword(TOK_INTERRUPT);
checkkeyword(TOK_INLINE);
if (curtok == TOK_INTERRUPT) {
note("Ignoring INTERRUPT keyword [258]");
gettok();
wneedtok(TOK_SEMI);
}
if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "FORWARD")) {
func->isforward = 1;
scanfwdparams(func);
gettok();
if (func->ctx->kind != MK_FUNCTION) {
outsection(minorspace);
flushcomments(NULL, -1, -1);
forward_decl(func, 0);
outsection(minorspace);
}
} else if (curtok == TOK_IDENT &&
(strlist_cifind(externwords, curtokbuf) ||
strlist_cifind(cexternwords, curtokbuf))) {
if (*externalias && my_strchr(externalias, '%')) {
strchange(&func->name, format_s(externalias, func->name));
} else if (strlist_cifind(cexternwords, curtokbuf)) {
if (func->name[0] == '_')
strchange(&func->name, func->name + 1);
if (func->name[strlen(func->name)-1] == '_')
func->name[strlen(func->name)-1] = 0;
}
func->isforward = 1; /* for Oregon Software Pascal-2 */
func->exported = 1;
gettok();
while (curtok == TOK_IDENT)
gettok();
outsection(minorspace);
flushcomments(NULL, -1, -1);
scanfwdparams(func);
forward_decl(func, 1);
outsection(minorspace);
} else if (curtok == TOK_IDENT) {
wexpecttok(TOK_BEGIN); /* print warning */
gettok();
outsection(minorspace);
flushcomments(NULL, -1, -1);
scanfwdparams(func);
forward_decl(func, 1);
outsection(minorspace);
} else {
if (func->ctx->kind == MK_FUNCTION)
func->ctx->needvarstruct = 1;
func->comments = curcomments;
curcomments = NULL;
p_block(TOK_FUNCTION);
echoprocname(func);
changecomments(curcomments, -1, curserial, -1, 10000);
sp = p_body();
func->ctx->needvarstruct = 0;
func->val.i = (long)sp;
strlist_mix(&func->comments, curcomments);
curcomments = NULL;
if (func->ctx->kind != MK_FUNCTION || !collectnest) {
out_function(func); /* output top-level procedures immediately */
} /* (sub-procedures are output later) */
}
if (!wneedtok(TOK_SEMI))
skippasttoken(TOK_SEMI);
}
strlist_mix(&curcomments, savecmt);
popctx();
}
Static void out_include(name, quoted)
char *name;
int quoted;
{
if (quoted)
output(format_s("#include \"%s\"\n", name));
else
output(format_s("#include <%s>\n", name));
}
Static void cleanheadername(dest, name)
char *dest, *name;
{
char *cp;
int len;
if (*name == '<' || *name == '"')
name++;
cp = my_strrchr(name, '/');
if (cp)
cp++;
else
cp = name;
strcpy(dest, cp);
len = strlen(dest);
if (dest[len-1] == '>' || dest[len-1] == '"')
dest[len-1] = 0;
}
Static int tryimport(sym, fname, ext, need)
Symbol *sym;
char *fname, *ext;
int need;
{
int found = 0;
Meaning *savectx, *savectxlast;
savectx = curctx;
savectxlast = curctxlast;
curctx = nullctx;
curctxlast = curctx->cbase;
while (curctxlast && curctxlast->cnext)
curctxlast = curctxlast->cnext;
if (p_search(fname, ext, need)) {
curtokmeaning = sym->mbase;
while (curtokmeaning && !curtokmeaning->isactive)
curtokmeaning = curtokmeaning->snext;
if (curtokmeaning)
found = 1;
}
curctx = savectx;
curctxlast = savectxlast;
return found;
}
Static void p_import(inheader)
int inheader;
{
Strlist *sl;
Symbol *sym;
char *name;
int found, isfrom = (curtok == TOK_FROM);
outsection(minorspace);
do {
gettok();
if (!wexpecttok(TOK_IDENT)) {
skiptotoken(TOK_SEMI);
break;
}
sym = curtoksym;
if (curtokmeaning && curtokmeaning->kind == MK_MODULE) {
found = 1;
} else if (strlist_cifind(permimports, sym->name)) {
found = 2; /* built-in module, there already! */
} else {
found = 0;
sl = strlist_cifind(importfrom, sym->name);
name = (sl) ? format_none((char *)sl->value) : NULL;
if (name) {
if (tryimport(sym, name, "pas", 1))
found = 1;
} else {
for (sl = importdirs; sl && !found; sl = sl->next) {
if (tryimport(sym, format_s(sl->s, curtokcase), NULL, 0))
found = 1;
}
}
}
if (found == 1) {
if (!inheader) {
sl = strlist_cifind(includefrom, curtokmeaning->name);
name = (sl) ? (char *)sl->value :
format_ss(*headerfnfmt2 ? headerfnfmt2 : headerfnfmt,
infname, curtokmeaning->name);
if (name && !strlist_find(includedfiles, name)) {
strlist_insert(&includedfiles, name);
if (*name_HSYMBOL)
output(format_s("#ifndef %s\n", format_s(name_HSYMBOL, sym->name)));
if (*name == '"' || *name == '<')
output(format_s("#include %s\n", name));
else
out_include(name, quoteincludes);
if (*name_HSYMBOL)
output("#endif\n");
outsection(minorspace);
}
}
import_ctx(curtokmeaning);
} else if (curtokmeaning) {
/* Modula-2, importing a single ident */
/* Ignored for now, since we always import whole modules */
} else if (found == 0) {
warning(format_s("Could not find module %s [271]", sym->name));
if (!inheader) {
out_include(format_ss(*headerfnfmt2?headerfnfmt2:headerfnfmt,
sym->name, sym->name),
quoteincludes);
}
}
gettok();
} while (curtok == TOK_COMMA);
if (isfrom) {
checkkeyword(TOK_IMPORT);
if (wneedtok(TOK_IMPORT)) {
do {
gettok();
if (curtok == TOK_IDENT)
gettok();
} while (curtok == TOK_COMMA);
}
}
if (!wneedtok(TOK_SEMI))
skippasttoken(TOK_SEMI);
outsection(minorspace);
}
void do_include(blkind)
Token blkind;
{
FILE *oldfile = outf;
int savelnum = outf_lnum;
char fname[256];
outsection(majorspace);
strcpy(fname, curtokbuf);
removesuffix(fname);
strcat(fname, ".c");
if (!strcmp(fname, codefname)) {
warning("Include file name conflict! [272]");
badinclude();
return;
}
saveoldfile(fname);
outf = fopen(fname, "w");
if (!outf) {
outf = oldfile;
perror(fname);
badinclude();
return;
}
outf_lnum = 1;
output(format_ss("\n/* Include file %s from %s */\n\n", fname, codefname));
if (blkind == TOK_END)
gettok();
else
curtok = blkind;
p_block(blockkind);
output("\n\n/* End. */\n\n");
fclose(outf);
outf = oldfile;
outf_lnum = savelnum;
if (curtok != TOK_EOF) {
warning("Junk at end of include file ignored [273]");
}
outsection(majorspace);
if (*includefnfmt)
out_include(format_s(includefnfmt, fname), 1);
else
out_include(fname, 1);
outsection(majorspace);
pop_input();
getline();
gettok();
}
/* blockkind is one of:
TOK_PROGRAM: Global declarations of a program
TOK_FUNCTION: Declarations local to a procedure or function
TOK_IMPORT: Import text read from a module
TOK_EXPORT: Export section of a module
TOK_IMPLEMENT: Implementation section of a module
TOK_END: None of the above
*/
void p_block(blkind)
Token blkind;
{
Token saveblockkind = blockkind;
Token lastblockkind = TOK_END;
blockkind = blkind;
for (;;) {
while (curtok == TOK_INTFONLY) {
include_as_import();
gettok();
}
if (curtok == TOK_CONST || curtok == TOK_TYPE ||
curtok == TOK_VAR || curtok == TOK_VALUE) {
while (curtok == TOK_CONST || curtok == TOK_TYPE ||
curtok == TOK_VAR || curtok == TOK_VALUE) {
lastblockkind = curtok;
switch (curtok) {
case TOK_CONST:
p_constdecl();
break;
case TOK_TYPE:
p_typedecl();
break;
case TOK_VAR:
p_vardecl();
break;
case TOK_VALUE:
p_valuedecl();
break;
default:
break;
}
}
if ((blkind == TOK_PROGRAM ||
blkind == TOK_EXPORT ||
blkind == TOK_IMPLEMENT) &&
(curtok != TOK_BEGIN || !mainlocals)) {
outsection(majorspace);
if (declarevars(curctx, 0))
outsection(majorspace);
}
} else {
checkmodulewords();
checkkeyword(TOK_SEGMENT);
if (curtok == TOK_SEGMENT) {
note("SEGMENT or OVERLAY keyword ignored [259]");
gettok();
}
p_attributes();
switch (curtok) {
case TOK_LABEL:
p_labeldecl();
break;
case TOK_IMPORT:
case TOK_FROM:
p_import(0);
break;
case TOK_EXPORT:
do {
gettok();
checkkeyword(TOK_QUALIFIED);
if (curtok == TOK_QUALIFIED)
gettok();
wneedtok(TOK_IDENT);
} while (curtok == TOK_COMMA);
if (!wneedtok(TOK_SEMI))
skippasttoken(TOK_SEMI);
break;
case TOK_MODULE:
p_nested_module();
break;
case TOK_PROCEDURE:
p_function(0);
break;
case TOK_FUNCTION:
p_function(1);
break;
case TOK_INCLUDE:
if (blockkind == TOK_PROGRAM ||
blockkind == TOK_IMPLEMENT ||
(blockkind == TOK_FUNCTION && !collectnest)) {
do_include(lastblockkind);
} else {
badinclude();
}
break;
default:
if (curtok == TOK_BEGIN && blockkind == TOK_IMPORT) {
warning("BEGIN encountered in interface text [274]");
skipparens();
if (curtok == TOK_SEMI)
gettok();
break;
}
blockkind = saveblockkind;
return;
}
lastblockkind = TOK_END;
}
}
}
Static void skipunitheader()
{
if (curtok == TOK_LPAR || curtok == TOK_LBR) {
skipparens();
}
}
Static void skiptomodule()
{
skipping_module++;
while (curtok != TOK_MODULE) {
if (curtok == TOK_END) {
gettok();
if (curtok == TOK_DOT)
break;
} else
gettok();
}
skipping_module--;
}
Static void p_moduleinit(mod)
Meaning *mod;
{
Stmt *sp;
Strlist *sl;
if (curtok != TOK_BEGIN && curtok != TOK_END) {
wexpecttok(TOK_END);
skiptotoken2(TOK_BEGIN, TOK_END);
}
if (curtok == TOK_BEGIN || initialcalls) {
echoprocname(mod);
sp = p_body();
strlist_mix(&mod->comments, curcomments);
curcomments = NULL;
if (ansiC != 0)
output("void ");
output(format_s(name_UNITINIT, mod->name));
if (void_args)
output("(void)\n");
else
output("()\n");
outcontext = mod;
out_block(sp, BR_FUNCTION, 10000);
free_stmt(sp);
/* The following must come after out_block! */
sl = strlist_append(&initialcalls,
format_s("%s()",
format_s(name_UNITINIT, mod->name)));
sl->value = 1;
} else
wneedtok(TOK_END);
}
Static void p_nested_module()
{
Meaning *mp;
if (!modula2) {
note("Ignoring nested module [260]");
p_module(1, 0);
return;
}
note("Nested modules not fully supported [261]");
checkmodulewords();
wneedtok(TOK_MODULE);
wexpecttok(TOK_IDENT);
mp = addmeaning(curtoksym, MK_MODULE);
mp->anyvarflag = 0;
gettok();
skipunitheader();
wneedtok(TOK_SEMI);
p_block(TOK_IMPLEMENT);
p_moduleinit(mp);
if (curtok == TOK_IDENT)
gettok();
wneedtok(TOK_SEMI);
}
Static int p_module(ignoreit, isdefn)
int ignoreit;
int isdefn; /* Modula-2: 0=local module, 1=DEFINITION, 2=IMPLEMENTATION */
{
Meaning *mod, *mp;
Strlist *sl;
int kind;
char *cp;
checkmodulewords();
wneedtok(TOK_MODULE);
wexpecttok(TOK_IDENT);
if (curtokmeaning && curtokmeaning->kind == MK_MODULE && isdefn == 2) {
mod = curtokmeaning;
import_ctx(mod);
for (mp = mod->cbase; mp; mp = mp->cnext)
if (mp->kind == MK_FUNCTION)
mp->isforward = 1;
} else {
mod = addmeaning(curtoksym, MK_MODULE);
}
mod->anyvarflag = 0;
pushctx(mod);
gettok();
skipunitheader();
wneedtok(TOK_SEMI);
if (ignoreit ||
(requested_module && strcicmp(requested_module, mod->name))) {
if (!quietmode)
if (outf == stdout)
fprintf(stderr, "Skipping over module \"%s\"\n", mod->name);
else
printf("Skipping over module \"%s\"\n", mod->name);
checkmodulewords();
while (curtok == TOK_IMPORT || curtok == TOK_FROM)
p_import(1);
checkmodulewords();
if (curtok == TOK_EXPORT)
gettok();
strlist_empty(&curcomments);
p_block(TOK_IMPORT);
setup_module(mod->sym->name, 0);
checkmodulewords();
if (curtok == TOK_IMPLEMENT) {
skiptomodule();
} else {
if (!wneedtok(TOK_END))
skippasttoken(TOK_END);
if (curtok == TOK_SEMI)
gettok();
}
popctx();
strlist_empty(&curcomments);
return 0;
}
found_module = 1;
if (isdefn != 2) {
if (!*hdrfname) {
sl = strlist_cifind(includefrom, mod->name);
if (sl)
cleanheadername(hdrfname, (char *)sl->value);
else
strcpy(hdrfname, format_ss(headerfnfmt, infname, mod->name));
}
saveoldfile(hdrfname);
hdrf = fopen(hdrfname, "w");
if (!hdrf) {
perror(hdrfname);
error("Could not open output file for header");
}
outsection(majorspace);
if (usevextern && my_strchr(name_GSYMBOL, '%'))
output(format_s("#define %s\n", format_s(name_GSYMBOL, mod->sym->name)));
out_include(hdrfname, quoteincludes);
outsection(majorspace);
select_outfile(hdrf);
output(format_s("/* Header for module %s, generated by p2c */\n", mod->name));
if (*name_HSYMBOL) {
cp = format_s(name_HSYMBOL, mod->sym->name);
output(format_ss("#ifndef %s\n#define %s\n", cp, cp));
}
outsection(majorspace);
checkmodulewords();
while (curtok == TOK_IMPORT || curtok == TOK_FROM)
p_import(0);
checkmodulewords();
if (curtok == TOK_EXPORT)
gettok();
checkmodulewords();
while (curtok == TOK_IMPORT || curtok == TOK_FROM)
p_import(0);
outsection(majorspace);
if (usevextern) {
output(format_s("#ifdef %s\n# define vextern\n#else\n",
format_s(name_GSYMBOL, mod->sym->name)));
output("# define vextern extern\n#endif\n");
}
checkmodulewords();
p_block(TOK_EXPORT);
setup_module(mod->sym->name, 1);
outsection(majorspace);
if (usevextern)
output("#undef vextern\n");
outsection(minorspace);
if (*name_HSYMBOL)
output(format_s("#endif /*%s*/\n", format_s(name_HSYMBOL, mod->sym->name)));
output("\n/* End. */\n\n");
select_outfile(codef);
fclose(hdrf);
*hdrfname = 0;
redeclarevars(mod);
declarevars(mod, 0);
}
checkmodulewords();
if (curtok != TOK_END) {
if (!modula2 && !implementationmodules)
wneedtok(TOK_IMPLEMENT);
import_ctx(mod);
p_block(TOK_IMPLEMENT);
flushcomments(NULL, -1, -1);
p_moduleinit(mod);
kind = 1;
} else {
kind = 0;
if (!wneedtok(TOK_END))
skippasttoken(TOK_END);
}
if (curtok == TOK_IDENT)
gettok();
if (curtok == TOK_SEMI)
gettok();
popctx();
return kind;
}
int p_search(fname, ext, need)
char *fname, *ext;
int need;
{
char infnbuf[300];
FILE *fp;
Meaning *mod;
int savesysprog, savecopysource;
int outerimportmark, importmark, mypermflag;
strcpy(infnbuf, fname);
fixfname(infnbuf, ext);
fp = fopen(infnbuf, "r");
if (!fp) {
if (need)
perror(infnbuf);
if (logf)
fprintf(logf, "(Unable to open search file \"%s\")\n", infnbuf);
return 0;
}
flushcomments(NULL, -1, -1);
ignore_directives++;
savesysprog = sysprog_flag;
sysprog_flag |= 3;
savecopysource = copysource;
copysource = 0;
outerimportmark = numimports; /*obsolete*/
importmark = push_imports();
clearprogress();
push_input_file(fp, infnbuf, 0);
do {
strlist_empty(&curcomments);
checkmodulewords();
permflag = 0;
if (curtok == TOK_DEFINITION) {
gettok();
checkmodulewords();
} else if (curtok == TOK_IMPLEMENT && modula2) {
gettok();
checkmodulewords();
warning("IMPLEMENTATION module in search text! [275]");
}
if (!wneedtok(TOK_MODULE))
break;
if (!wexpecttok(TOK_IDENT))
break;
mod = addmeaning(curtoksym, MK_MODULE);
mod->anyvarflag = 0;
if (!quietmode && !showprogress)
if (outf == stdout)
fprintf(stderr, "Reading import text for \"%s\"\n", mod->name);
else
printf("Reading import text for \"%s\"\n", mod->name);
if (verbose)
fprintf(logf, "%s, %d/%d: Reading import text for \"%s\"\n",
infname, inf_lnum, outf_lnum, mod->name);
pushctx(mod);
gettok();
skipunitheader();
wneedtok(TOK_SEMI);
mypermflag = permflag;
if (debug>0) printf("Found module %s\n", mod->name);
checkmodulewords();
while (curtok == TOK_IMPORT || curtok == TOK_FROM)
p_import(1);
checkmodulewords();
if (curtok == TOK_EXPORT)
gettok();
strlist_empty(&curcomments);
p_block(TOK_IMPORT);
setup_module(mod->sym->name, 0);
if (mypermflag) {
strlist_add(&permimports, mod->sym->name)->value = (long)mod;
perm_import(mod);
}
checkmodulewords();
if (curtok == TOK_END) {
gettok();
if (curtok == TOK_SEMI)
gettok();
} else {
wexpecttok(TOK_IMPLEMENT);
if (importall) {
skiptomodule();
}
}
popctx();
} while (curtok == TOK_MODULE);
pop_imports(importmark);
unimport(outerimportmark);
sysprog_flag = savesysprog;
copysource = savecopysource;
ignore_directives--;
pop_input();
strlist_empty(&curcomments);
clearprogress();
return 1;
}
void p_program()
{
Meaning *prog;
Stmt *sp;
int nummods, isdefn = 0;
flushcomments(NULL, -1, -1);
output(format_s("\n#include %s\n", p2c_h_name));
outsection(majorspace);
p_attributes();
ignore_attributes();
checkmodulewords();
if (modula2) {
if (curtok == TOK_MODULE) {
curtok = TOK_PROGRAM;
} else {
if (curtok == TOK_DEFINITION) {
isdefn = 1;
gettok();
checkmodulewords();
} else if (curtok == TOK_IMPLEMENT) {
isdefn = 2;
gettok();
checkmodulewords();
}
}
}
switch (curtok) {
case TOK_MODULE:
if (implementationmodules)
isdefn = 2;
nummods = 0;
while (curtok == TOK_MODULE) {
if (p_module(0, isdefn)) {
nummods++;
if (nummods == 2 && !requested_module)
warning("Multiple modules in one source file may not work correctly [276]");
}
}
wneedtok(TOK_DOT);
break;
default:
if (curtok == TOK_PROGRAM) {
gettok();
if (!wexpecttok(TOK_IDENT))
skiptotoken(TOK_IDENT);
prog = addmeaning(curtoksym, MK_MODULE);
gettok();
if (curtok == TOK_LPAR) {
while (curtok != TOK_RPAR) {
if (curtok == TOK_IDENT &&
strcicmp(curtokbuf, "INPUT") &&
strcicmp(curtokbuf, "OUTPUT") &&
strcicmp(curtokbuf, "KEYBOARD") &&
strcicmp(curtokbuf, "LISTING")) {
if (literalfilesflag == 2) {
strlist_add(&literalfiles, curtokbuf);
} else
note(format_s("Unexpected name \"%s\" in program header [262]",
curtokcase));
}
gettok();
}
gettok();
}
if (curtok == TOK_LBR)
skipparens();
wneedtok(TOK_SEMI);
} else {
prog = addmeaning(findsymbol("program"), MK_MODULE);
}
prog->anyvarflag = 1;
if (requested_module && strcicmp(requested_module, prog->name) &&
strcicmp(requested_module, "program")) {
for (;;) {
skiptomodule();
if (curtok == TOK_DOT)
break;
(void)p_module(0, 2);
}
gettok();
break;
}
pushctx(prog);
p_block(TOK_PROGRAM);
echoprocname(prog);
flushcomments(NULL, -1, -1);
if (curtok != TOK_EOF) {
sp = p_body();
strlist_mix(&prog->comments, curcomments);
curcomments = NULL;
if (fullprototyping > 0) {
output(format_s("main(int argc, %s *argv[])", charname));
} else {
output("main(argc, argv)\n");
singleindent(argindent);
output("int argc;\n");
singleindent(argindent);
output(format_s("%s *argv[];\n", charname));
}
outcontext = prog;
out_block(sp, BR_FUNCTION, 10000);
free_stmt(sp);
popctx();
if (curtok == TOK_SEMI)
gettok();
else
wneedtok(TOK_DOT);
}
break;
}
if (curtok != TOK_EOF) {
warning("Junk at end of input file ignored [277]");
}
}
/* End. */