parse.c.3
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:25k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. mp->isreturn) {    /* the was-#defined flag */
  2. if (!anywords)
  3.     outsection(minorspace);
  4. anywords++;
  5. output(format_s("#undef %sn", mp->name));
  6. sym = findsymbol(mp->name);
  7. sym->flags &= ~AVOIDNAME;
  8.     }
  9. }
  10.     }
  11.     if (conserve_mem) {
  12. free_stmt((Stmt *)func->val.i);   /* is this safe? */
  13. func->val.i = 0;
  14. forget_ctx(func, 0);
  15.     }
  16.     outsection(spacing);
  17. }
  18. void movetoend(mp)
  19. Meaning *mp;
  20. {
  21.     Meaning **mpp;
  22.     if (mp->ctx != curctx) {
  23.         intwarning("movetoend", "curctx is wrong [268]");
  24.     } else {
  25.         mpp = &mp->ctx->cbase;     /* move a meaning to end of its parent context */
  26.         while (*mpp != mp) {
  27.     if (!*mpp) {
  28. intwarning("movetoend", "meaning not on its context list [269]");
  29. return;
  30.     }
  31.             mpp = &(*mpp)->cnext;
  32. }
  33.         *mpp = mp->cnext;    /* Remove from present position in list */
  34.         while (*mpp)
  35.             mpp = &(*mpp)->cnext;
  36.         *mpp = mp;           /* Insert at end of list */
  37.         mp->cnext = NULL;
  38.         curctxlast = mp;
  39.     }
  40. }
  41. Static void scanfwdparams(mp)
  42. Meaning *mp;
  43. {
  44.     Symbol *sym;
  45.     mp = mp->type->fbase;
  46.     while (mp) {
  47. sym = findsymbol(mp->name);
  48. sym->flags |= FWDPARAM;
  49. mp = mp->xnext;
  50.     }
  51. }
  52. Static void p_function(isfunc)
  53. int isfunc;
  54. {
  55.     Meaning *func;
  56.     Type *type;
  57.     Stmt *sp;
  58.     Strlist *sl, *comments, *savecmt;
  59.     int initializeattr = 0, isinline = 0;
  60.     if ((sl = strlist_find(attrlist, "INITIALIZE")) != NULL) {
  61. initializeattr = 1;
  62. strlist_delete(&attrlist, sl);
  63.     }
  64.     if ((sl = strlist_find(attrlist, "OPTIMIZE")) != NULL &&
  65. sl->value != -1 &&
  66. !strcmp((char *)(sl->value), "INLINE")) {
  67. isinline = 1;
  68. strlist_delete(&attrlist, sl);
  69.     }
  70.     ignore_attributes();
  71.     comments = extractcomment(&curcomments, -1, curserial);
  72.     changecomments(comments, -1, -1, -1, 0);
  73.     if (curctx->kind == MK_FUNCTION) {    /* sub-procedure */
  74. savecmt = curcomments;
  75.     } else {
  76. savecmt = NULL;
  77. flushcomments(&curcomments, -1, -1);
  78.     }
  79.     curcomments = comments;
  80.     curserial = serialcount = 1;
  81.     gettok();
  82.     if (!wexpecttok(TOK_IDENT))
  83. skiptotoken(TOK_IDENT);
  84.     if (curtokmeaning && curtokmeaning->ctx == curctx &&
  85.         curtokmeaning->kind == MK_FUNCTION) {
  86.         func = curtokmeaning;
  87.         if (!func->isforward || func->val.i)
  88.             warning(format_s("Redeclaration of function %s [270]", func->name));
  89. skiptotoken(TOK_SEMI);
  90.         movetoend(func);
  91.         pushctx(func);
  92.         type = func->type;
  93.     } else {
  94.         func = addmeaning(curtoksym, MK_FUNCTION);
  95.         gettok();
  96.         func->val.i = 0;
  97.         pushctx(func);
  98.         func->type = type = p_funcdecl(&isfunc, 0);
  99.         func->isfunction = isfunc;
  100. func->namedfile = isinline;
  101.         type->meaning = func;
  102.     }
  103.     wneedtok(TOK_SEMI);
  104.     if (initializeattr) {
  105. sl = strlist_append(&initialcalls, format_s("%s()", func->name));
  106. sl->value = 1;
  107.     }
  108.     if (curtok == TOK_IDENT && !strcmp(curtokbuf, "C")) {
  109. gettok();
  110. wneedtok(TOK_SEMI);
  111.     }
  112.     if (blockkind == TOK_IMPORT) {
  113. strlist_empty(&curcomments);
  114. if (curtok == TOK_IDENT &&
  115.     (!strcicmp(curtokbuf, "FORWARD") ||
  116.      strlist_cifind(externwords, curtokbuf))) {
  117.     gettok();
  118.     while (curtok == TOK_IDENT)
  119. gettok();
  120.     wneedtok(TOK_SEMI);
  121. }
  122.         /* do nothing more */
  123.     } else if (blockkind == TOK_EXPORT) {
  124.         func->isforward = 1;
  125. scanfwdparams(func);
  126. flushcomments(NULL, -1, -1);
  127.         forward_decl(func, 1);
  128.     } else {
  129. checkkeyword(TOK_INTERRUPT);
  130. checkkeyword(TOK_INLINE);
  131.         if (curtok == TOK_INTERRUPT) {
  132.             note("Ignoring INTERRUPT keyword [258]");
  133.             gettok();
  134.             wneedtok(TOK_SEMI);
  135.         }
  136.         if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "FORWARD")) {
  137.             func->isforward = 1;
  138.     scanfwdparams(func);
  139.             gettok();
  140.             if (func->ctx->kind != MK_FUNCTION) {
  141.                 outsection(minorspace);
  142. flushcomments(NULL, -1, -1);
  143.                 forward_decl(func, 0);
  144.                 outsection(minorspace);
  145.             }
  146.         } else if (curtok == TOK_IDENT &&
  147.    (strlist_cifind(externwords, curtokbuf) ||
  148.     strlist_cifind(cexternwords, curtokbuf))) {
  149.             if (*externalias && my_strchr(externalias, '%')) {
  150.                 strchange(&func->name, format_s(externalias, func->name));
  151.             } else if (strlist_cifind(cexternwords, curtokbuf)) {
  152. if (func->name[0] == '_')
  153.     strchange(&func->name, func->name + 1);
  154. if (func->name[strlen(func->name)-1] == '_')
  155.     func->name[strlen(func->name)-1] = 0;
  156.     }
  157.     func->isforward = 1;    /* for Oregon Software Pascal-2 */
  158.     func->exported = 1;
  159.             gettok();
  160.     while (curtok == TOK_IDENT)
  161. gettok();
  162.             outsection(minorspace);
  163.     flushcomments(NULL, -1, -1);
  164.     scanfwdparams(func);
  165.             forward_decl(func, 1);
  166.             outsection(minorspace);
  167. } else if (curtok == TOK_IDENT) {
  168.     wexpecttok(TOK_BEGIN);   /* print warning */
  169.     gettok();
  170.             outsection(minorspace);
  171.     flushcomments(NULL, -1, -1);
  172.     scanfwdparams(func);
  173.             forward_decl(func, 1);
  174.             outsection(minorspace);
  175.         } else {
  176.             if (func->ctx->kind == MK_FUNCTION)
  177.                 func->ctx->needvarstruct = 1;
  178.     func->comments = curcomments;
  179.     curcomments = NULL;
  180.             p_block(TOK_FUNCTION);
  181.             echoprocname(func);
  182.     changecomments(curcomments, -1, curserial, -1, 10000);
  183.             sp = p_body();
  184.             func->ctx->needvarstruct = 0;
  185.             func->val.i = (long)sp;
  186.     strlist_mix(&func->comments, curcomments);
  187.     curcomments = NULL;
  188.             if (func->ctx->kind != MK_FUNCTION || !collectnest) {
  189.                 out_function(func);    /* output top-level procedures immediately */
  190.             }                          /*  (sub-procedures are output later) */
  191.         }
  192.         if (!wneedtok(TOK_SEMI))
  193.     skippasttoken(TOK_SEMI);
  194.     }
  195.     strlist_mix(&curcomments, savecmt);
  196.     popctx();
  197. }
  198. Static void out_include(name, quoted)
  199. char *name;
  200. int quoted;
  201. {
  202.     if (quoted)
  203.         output(format_s("#include "%s"n", name));
  204.     else
  205.         output(format_s("#include <%s>n", name));
  206. }
  207. Static void cleanheadername(dest, name)
  208. char *dest, *name;
  209. {
  210.     char *cp;
  211.     int len;
  212.     if (*name == '<' || *name == '"')
  213. name++;
  214.     cp = my_strrchr(name, '/');
  215.     if (cp)
  216. cp++;
  217.     else
  218. cp = name;
  219.     strcpy(dest, cp);
  220.     len = strlen(dest);
  221.     if (dest[len-1] == '>' || dest[len-1] == '"')
  222. dest[len-1] = 0;
  223. }
  224. Static int tryimport(sym, fname, ext, need)
  225. Symbol *sym;
  226. char *fname, *ext;
  227. int need;
  228. {
  229.     int found = 0;
  230.     Meaning *savectx, *savectxlast;
  231.     savectx = curctx;
  232.     savectxlast = curctxlast;
  233.     curctx = nullctx;
  234.     curctxlast = curctx->cbase;
  235.     while (curctxlast && curctxlast->cnext)
  236.         curctxlast = curctxlast->cnext;
  237.     if (p_search(fname, ext, need)) {
  238.         curtokmeaning = sym->mbase;
  239.         while (curtokmeaning && !curtokmeaning->isactive)
  240.             curtokmeaning = curtokmeaning->snext;
  241.         if (curtokmeaning)
  242.             found = 1;
  243.     }
  244.     curctx = savectx;
  245.     curctxlast = savectxlast;
  246.     return found;
  247. }
  248. Static void p_import(inheader)
  249. int inheader;
  250. {
  251.     Strlist *sl;
  252.     Symbol *sym;
  253.     char *name;
  254.     int found, isfrom = (curtok == TOK_FROM);
  255.     outsection(minorspace);
  256.     do {
  257.         gettok();
  258.         if (!wexpecttok(TOK_IDENT)) {
  259.     skiptotoken(TOK_SEMI);
  260.     break;
  261. }
  262.         sym = curtoksym;
  263.         if (curtokmeaning && curtokmeaning->kind == MK_MODULE) {
  264.             found = 1;
  265. } else if (strlist_cifind(permimports, sym->name)) {
  266.             found = 2;   /* built-in module, there already! */
  267.         } else {
  268.             found = 0;
  269.             sl = strlist_cifind(importfrom, sym->name);
  270.             name = (sl) ? format_none((char *)sl->value) : NULL;
  271.             if (name) {
  272.                 if (tryimport(sym, name, "pas", 1))
  273.                     found = 1;
  274.             } else {
  275.                 for (sl = importdirs; sl && !found; sl = sl->next) {
  276.                     if (tryimport(sym, format_s(sl->s, curtokcase), NULL, 0))
  277.                         found = 1;
  278.                 }
  279.             }
  280.         }
  281.         if (found == 1) {
  282.             if (!inheader) {
  283.                 sl = strlist_cifind(includefrom, curtokmeaning->name);
  284.                 name = (sl) ? (char *)sl->value :
  285.     format_ss(*headerfnfmt2 ? headerfnfmt2 : headerfnfmt,
  286.       infname, curtokmeaning->name);
  287.                 if (name && !strlist_find(includedfiles, name)) {
  288.                     strlist_insert(&includedfiles, name);
  289.                     if (*name_HSYMBOL)
  290.                         output(format_s("#ifndef %sn", format_s(name_HSYMBOL, sym->name)));
  291.                     if (*name == '"' || *name == '<')
  292.                         output(format_s("#include %sn", name));
  293.                     else
  294.                         out_include(name, quoteincludes);
  295.                     if (*name_HSYMBOL)
  296.                         output("#endifn");
  297.                     outsection(minorspace);
  298.                 }
  299.             }
  300.             import_ctx(curtokmeaning);
  301. } else if (curtokmeaning) {
  302.     /* Modula-2, importing a single ident */
  303.     /* Ignored for now, since we always import whole modules */
  304.         } else if (found == 0) {
  305.             warning(format_s("Could not find module %s [271]", sym->name));
  306.             if (!inheader) {
  307.                 out_include(format_ss(*headerfnfmt2?headerfnfmt2:headerfnfmt,
  308.       sym->name, sym->name),
  309.     quoteincludes);
  310.             }
  311.         }
  312.         gettok();
  313.     } while (curtok == TOK_COMMA);
  314.     if (isfrom) {
  315. checkkeyword(TOK_IMPORT);
  316. if (wneedtok(TOK_IMPORT)) {
  317.     do {
  318. gettok();
  319. if (curtok == TOK_IDENT)
  320.     gettok();
  321.     } while (curtok == TOK_COMMA);
  322. }
  323.     }
  324.     if (!wneedtok(TOK_SEMI))
  325. skippasttoken(TOK_SEMI);
  326.     outsection(minorspace);
  327. }
  328. void do_include(blkind)
  329. Token blkind;
  330. {
  331.     FILE *oldfile = outf;
  332.     int savelnum = outf_lnum;
  333.     char fname[256];
  334.     outsection(majorspace);
  335.     strcpy(fname, curtokbuf);
  336.     removesuffix(fname);
  337.     strcat(fname, ".c");
  338.     if (!strcmp(fname, codefname)) {
  339.         warning("Include file name conflict! [272]");
  340.         badinclude();
  341.         return;
  342.     }
  343.     saveoldfile(fname);
  344.     outf = fopen(fname, "w");
  345.     if (!outf) {
  346.         outf = oldfile;
  347.         perror(fname);
  348.         badinclude();
  349.         return;
  350.     }
  351.     outf_lnum = 1;
  352.     output(format_ss("n/* Include file %s from %s */nn", fname, codefname));
  353.     if (blkind == TOK_END)
  354.         gettok();
  355.     else
  356.         curtok = blkind;
  357.     p_block(blockkind);
  358.     output("nn/* End. */nn");
  359.     fclose(outf);
  360.     outf = oldfile;
  361.     outf_lnum = savelnum;
  362.     if (curtok != TOK_EOF) {
  363.         warning("Junk at end of include file ignored [273]");
  364.     }
  365.     outsection(majorspace);
  366.     if (*includefnfmt)
  367. out_include(format_s(includefnfmt, fname), 1);
  368.     else
  369. out_include(fname, 1);
  370.     outsection(majorspace);
  371.     pop_input();
  372.     getline();
  373.     gettok();
  374. }
  375. /* blockkind is one of:
  376.        TOK_PROGRAM:     Global declarations of a program
  377.        TOK_FUNCTION:    Declarations local to a procedure or function
  378.        TOK_IMPORT:      Import text read from a module
  379.        TOK_EXPORT:      Export section of a module
  380.        TOK_IMPLEMENT:   Implementation section of a module
  381.        TOK_END:         None of the above
  382. */
  383. void p_block(blkind)
  384. Token blkind;
  385. {
  386.     Token saveblockkind = blockkind;
  387.     Token lastblockkind = TOK_END;
  388.     blockkind = blkind;
  389.     for (;;) {
  390. while (curtok == TOK_INTFONLY) {
  391.     include_as_import();
  392.     gettok();
  393. }
  394.         if (curtok == TOK_CONST || curtok == TOK_TYPE ||
  395.     curtok == TOK_VAR || curtok == TOK_VALUE) {
  396.             while (curtok == TOK_CONST || curtok == TOK_TYPE ||
  397.    curtok == TOK_VAR || curtok == TOK_VALUE) {
  398.                 lastblockkind = curtok;
  399.                 switch (curtok) {
  400.                     case TOK_CONST:
  401.                         p_constdecl();
  402.                         break;
  403.                     case TOK_TYPE:
  404.                         p_typedecl();
  405.                         break;
  406.                     case TOK_VAR:
  407.                         p_vardecl();
  408.                         break;
  409.     case TOK_VALUE:
  410. p_valuedecl();
  411. break;
  412.     default:
  413. break;
  414.                 }
  415.             }
  416.             if ((blkind == TOK_PROGRAM ||
  417.                  blkind == TOK_EXPORT ||
  418.                  blkind == TOK_IMPLEMENT) &&
  419.                 (curtok != TOK_BEGIN || !mainlocals)) {
  420.                 outsection(majorspace);
  421.                 if (declarevars(curctx, 0))
  422.                     outsection(majorspace);
  423.             }
  424.         } else {
  425.     checkmodulewords();
  426.     checkkeyword(TOK_SEGMENT);
  427.     if (curtok == TOK_SEGMENT) {
  428. note("SEGMENT or OVERLAY keyword ignored [259]");
  429. gettok();
  430.     }
  431.     p_attributes();
  432.             switch (curtok) {
  433.                 case TOK_LABEL:
  434.                     p_labeldecl();
  435.                     break;
  436.                 case TOK_IMPORT:
  437.                 case TOK_FROM:
  438.                     p_import(0);
  439.                     break;
  440. case TOK_EXPORT:
  441.     do {
  442. gettok();
  443. checkkeyword(TOK_QUALIFIED);
  444. if (curtok == TOK_QUALIFIED)
  445.     gettok();
  446. wneedtok(TOK_IDENT);
  447.     } while (curtok == TOK_COMMA);
  448.     if (!wneedtok(TOK_SEMI))
  449. skippasttoken(TOK_SEMI);
  450.     break;
  451.                 case TOK_MODULE:
  452.     p_nested_module();
  453.                     break;
  454.                 case TOK_PROCEDURE:
  455.                     p_function(0);
  456.                     break;
  457.                 case TOK_FUNCTION:
  458.                     p_function(1);
  459.                     break;
  460.                 case TOK_INCLUDE:
  461.                     if (blockkind == TOK_PROGRAM ||
  462.                         blockkind == TOK_IMPLEMENT ||
  463. (blockkind == TOK_FUNCTION && !collectnest)) {
  464.                         do_include(lastblockkind);
  465.                     } else {
  466.                         badinclude();
  467.                     }
  468.                     break;
  469.                 default:
  470.     if (curtok == TOK_BEGIN && blockkind == TOK_IMPORT) {
  471. warning("BEGIN encountered in interface text [274]");
  472. skipparens();
  473. if (curtok == TOK_SEMI)
  474.     gettok();
  475. break;
  476.     }
  477.                     blockkind = saveblockkind;
  478.                     return;
  479.             }
  480.             lastblockkind = TOK_END;
  481.         }
  482.     }
  483. }
  484. Static void skipunitheader()
  485. {
  486.     if (curtok == TOK_LPAR || curtok == TOK_LBR) {
  487. skipparens();
  488.     }
  489. }
  490. Static void skiptomodule()
  491. {
  492.     skipping_module++;
  493.     while (curtok != TOK_MODULE) {
  494.         if (curtok == TOK_END) {
  495.             gettok();
  496.             if (curtok == TOK_DOT)
  497.                 break;
  498.         } else
  499.             gettok();
  500.     }
  501.     skipping_module--;
  502. }
  503. Static void p_moduleinit(mod)
  504. Meaning *mod;
  505. {
  506.     Stmt *sp;
  507.     Strlist *sl;
  508.     if (curtok != TOK_BEGIN && curtok != TOK_END) {
  509. wexpecttok(TOK_END);
  510. skiptotoken2(TOK_BEGIN, TOK_END);
  511.     }
  512.     if (curtok == TOK_BEGIN || initialcalls) {
  513. echoprocname(mod);
  514. sp = p_body();
  515. strlist_mix(&mod->comments, curcomments);
  516. curcomments = NULL;
  517. if (ansiC != 0)
  518.     output("void ");
  519. output(format_s(name_UNITINIT, mod->name));
  520. if (void_args)
  521.     output("(void)n");
  522. else
  523.     output("()n");
  524. outcontext = mod;
  525. out_block(sp, BR_FUNCTION, 10000);
  526. free_stmt(sp);
  527. /* The following must come after out_block! */
  528. sl = strlist_append(&initialcalls,
  529.     format_s("%s()",
  530.      format_s(name_UNITINIT, mod->name)));
  531. sl->value = 1;
  532.     } else
  533. wneedtok(TOK_END);
  534. }
  535. Static void p_nested_module()
  536. {
  537.     Meaning *mp;
  538.     if (!modula2) {
  539. note("Ignoring nested module [260]");
  540. p_module(1, 0);
  541. return;
  542.     }
  543.     note("Nested modules not fully supported [261]");
  544.     checkmodulewords();
  545.     wneedtok(TOK_MODULE);
  546.     wexpecttok(TOK_IDENT);
  547.     mp = addmeaning(curtoksym, MK_MODULE);
  548.     mp->anyvarflag = 0;
  549.     gettok();
  550.     skipunitheader();
  551.     wneedtok(TOK_SEMI);
  552.     p_block(TOK_IMPLEMENT);
  553.     p_moduleinit(mp);
  554.     if (curtok == TOK_IDENT)
  555. gettok();
  556.     wneedtok(TOK_SEMI);
  557. }
  558. Static int p_module(ignoreit, isdefn)
  559. int ignoreit;
  560. int isdefn;    /* Modula-2: 0=local module, 1=DEFINITION, 2=IMPLEMENTATION */
  561. {
  562.     Meaning *mod, *mp;
  563.     Strlist *sl;
  564.     int kind;
  565.     char *cp;
  566.     checkmodulewords();
  567.     wneedtok(TOK_MODULE);
  568.     wexpecttok(TOK_IDENT);
  569.     if (curtokmeaning && curtokmeaning->kind == MK_MODULE && isdefn == 2) {
  570. mod = curtokmeaning;
  571. import_ctx(mod);
  572. for (mp = mod->cbase; mp; mp = mp->cnext)
  573.     if (mp->kind == MK_FUNCTION)
  574. mp->isforward = 1;
  575.     } else {
  576. mod = addmeaning(curtoksym, MK_MODULE);
  577.     }
  578.     mod->anyvarflag = 0;
  579.     pushctx(mod);
  580.     gettok();
  581.     skipunitheader();
  582.     wneedtok(TOK_SEMI);
  583.     if (ignoreit || 
  584.         (requested_module && strcicmp(requested_module, mod->name))) {
  585.         if (!quietmode)
  586.     if (outf == stdout)
  587. fprintf(stderr, "Skipping over module "%s"n", mod->name);
  588.     else
  589. printf("Skipping over module "%s"n", mod->name);
  590. checkmodulewords();
  591.         while (curtok == TOK_IMPORT || curtok == TOK_FROM)
  592.             p_import(1);
  593. checkmodulewords();
  594. if (curtok == TOK_EXPORT)
  595.     gettok();
  596.         strlist_empty(&curcomments);
  597.         p_block(TOK_IMPORT);
  598.         setup_module(mod->sym->name, 0);
  599. checkmodulewords();
  600.         if (curtok == TOK_IMPLEMENT) {
  601.             skiptomodule();
  602.         } else {
  603.             if (!wneedtok(TOK_END))
  604. skippasttoken(TOK_END);
  605.             if (curtok == TOK_SEMI)
  606.                 gettok();
  607.         }
  608.         popctx();
  609.         strlist_empty(&curcomments);
  610.         return 0;
  611.     }
  612.     found_module = 1;
  613.     if (isdefn != 2) {
  614. if (!*hdrfname) {
  615.     sl = strlist_cifind(includefrom, mod->name);
  616.     if (sl)
  617. cleanheadername(hdrfname, (char *)sl->value);
  618.     else
  619. strcpy(hdrfname, format_ss(headerfnfmt, infname, mod->name));
  620. }
  621. saveoldfile(hdrfname);
  622. hdrf = fopen(hdrfname, "w");
  623. if (!hdrf) {
  624.     perror(hdrfname);
  625.     error("Could not open output file for header");
  626. }
  627. outsection(majorspace);
  628. if (usevextern && my_strchr(name_GSYMBOL, '%'))
  629.     output(format_s("#define %sn", format_s(name_GSYMBOL, mod->sym->name)));
  630. out_include(hdrfname, quoteincludes);
  631. outsection(majorspace);
  632. select_outfile(hdrf);
  633. output(format_s("/* Header for module %s, generated by p2c */n", mod->name));
  634. if (*name_HSYMBOL) {
  635.     cp = format_s(name_HSYMBOL, mod->sym->name);
  636.     output(format_ss("#ifndef %sn#define %sn", cp, cp));
  637. }
  638. outsection(majorspace);
  639. checkmodulewords();
  640. while (curtok == TOK_IMPORT || curtok == TOK_FROM)
  641.     p_import(0);
  642. checkmodulewords();
  643. if (curtok == TOK_EXPORT)
  644.     gettok();
  645. checkmodulewords();
  646. while (curtok == TOK_IMPORT || curtok == TOK_FROM)
  647.     p_import(0);
  648. outsection(majorspace);
  649. if (usevextern) {
  650.     output(format_s("#ifdef %sn# define vexternn#elsen",
  651.     format_s(name_GSYMBOL, mod->sym->name)));
  652.     output("# define vextern externn#endifn");
  653. }
  654. checkmodulewords();
  655. p_block(TOK_EXPORT);
  656. setup_module(mod->sym->name, 1);
  657. outsection(majorspace);
  658. if (usevextern)
  659.     output("#undef vexternn");
  660. outsection(minorspace);
  661. if (*name_HSYMBOL)
  662.     output(format_s("#endif /*%s*/n", format_s(name_HSYMBOL, mod->sym->name)));
  663. output("n/* End. */nn");
  664. select_outfile(codef);
  665. fclose(hdrf);
  666. *hdrfname = 0;
  667. redeclarevars(mod);
  668. declarevars(mod, 0);
  669.     }
  670.     checkmodulewords();
  671.     if (curtok != TOK_END) {
  672. if (!modula2 && !implementationmodules)
  673.     wneedtok(TOK_IMPLEMENT);
  674. import_ctx(mod);
  675.         p_block(TOK_IMPLEMENT);
  676. flushcomments(NULL, -1, -1);
  677. p_moduleinit(mod);
  678.         kind = 1;
  679.     } else {
  680.         kind = 0;
  681.         if (!wneedtok(TOK_END))
  682.     skippasttoken(TOK_END);
  683.     }
  684.     if (curtok == TOK_IDENT)
  685. gettok();
  686.     if (curtok == TOK_SEMI)
  687.         gettok();
  688.     popctx();
  689.     return kind;
  690. }
  691. int p_search(fname, ext, need)
  692. char *fname, *ext;
  693. int need;
  694. {
  695.     char infnbuf[300];
  696.     FILE *fp;
  697.     Meaning *mod;
  698.     int savesysprog, savecopysource;
  699.     int outerimportmark, importmark, mypermflag;
  700.     strcpy(infnbuf, fname);
  701.     fixfname(infnbuf, ext);
  702.     fp = fopen(infnbuf, "r");
  703.     if (!fp) {
  704.         if (need)
  705.             perror(infnbuf);
  706. if (logf)
  707.     fprintf(logf, "(Unable to open search file "%s")n", infnbuf);
  708.         return 0;
  709.     }
  710.     flushcomments(NULL, -1, -1);
  711.     ignore_directives++;
  712.     savesysprog = sysprog_flag;
  713.     sysprog_flag |= 3;
  714.     savecopysource = copysource;
  715.     copysource = 0;
  716.     outerimportmark = numimports;   /*obsolete*/
  717.     importmark = push_imports();
  718.     clearprogress();
  719.     push_input_file(fp, infnbuf, 0);
  720.     do {
  721. strlist_empty(&curcomments);
  722. checkmodulewords();
  723. permflag = 0;
  724. if (curtok == TOK_DEFINITION) {
  725.     gettok();
  726.     checkmodulewords();
  727. } else if (curtok == TOK_IMPLEMENT && modula2) {
  728.     gettok();
  729.     checkmodulewords();
  730.     warning("IMPLEMENTATION module in search text! [275]");
  731. }
  732.         if (!wneedtok(TOK_MODULE))
  733.     break;
  734.         if (!wexpecttok(TOK_IDENT))
  735.     break;
  736.         mod = addmeaning(curtoksym, MK_MODULE);
  737.         mod->anyvarflag = 0;
  738.         if (!quietmode && !showprogress)
  739.     if (outf == stdout)
  740. fprintf(stderr, "Reading import text for "%s"n", mod->name);
  741.     else
  742. printf("Reading import text for "%s"n", mod->name);
  743. if (verbose)
  744.     fprintf(logf, "%s, %d/%d: Reading import text for "%s"n",
  745.     infname, inf_lnum, outf_lnum, mod->name);
  746.         pushctx(mod);
  747.         gettok();
  748.         skipunitheader();
  749.         wneedtok(TOK_SEMI);
  750. mypermflag = permflag;
  751.         if (debug>0) printf("Found module %sn", mod->name);
  752. checkmodulewords();
  753.         while (curtok == TOK_IMPORT || curtok == TOK_FROM)
  754.             p_import(1);
  755. checkmodulewords();
  756. if (curtok == TOK_EXPORT)
  757.     gettok();
  758.         strlist_empty(&curcomments);
  759.         p_block(TOK_IMPORT);
  760.         setup_module(mod->sym->name, 0);
  761. if (mypermflag) {
  762.     strlist_add(&permimports, mod->sym->name)->value = (long)mod;
  763.     perm_import(mod);
  764. }
  765. checkmodulewords();
  766. if (curtok == TOK_END) {
  767.     gettok();
  768.     if (curtok == TOK_SEMI)
  769. gettok();
  770. } else {
  771.     wexpecttok(TOK_IMPLEMENT);
  772.     if (importall) {
  773. skiptomodule();
  774.             }
  775.         }
  776.         popctx();
  777.     } while (curtok == TOK_MODULE);
  778.     pop_imports(importmark);
  779.     unimport(outerimportmark);
  780.     sysprog_flag = savesysprog;
  781.     copysource = savecopysource;
  782.     ignore_directives--;
  783.     pop_input();
  784.     strlist_empty(&curcomments);
  785.     clearprogress();
  786.     return 1;
  787. }
  788. void p_program()
  789. {
  790.     Meaning *prog;
  791.     Stmt *sp;
  792.     int nummods, isdefn = 0;
  793.     flushcomments(NULL, -1, -1);
  794.     output(format_s("n#include %sn", p2c_h_name));
  795.     outsection(majorspace);
  796.     p_attributes();
  797.     ignore_attributes();
  798.     checkmodulewords();
  799.     if (modula2) {
  800. if (curtok == TOK_MODULE) {
  801.     curtok = TOK_PROGRAM;
  802. } else {
  803.     if (curtok == TOK_DEFINITION) {
  804. isdefn = 1;
  805. gettok();
  806. checkmodulewords();
  807.     } else if (curtok == TOK_IMPLEMENT) {
  808. isdefn = 2;
  809. gettok();
  810. checkmodulewords();
  811.     }
  812. }
  813.     }
  814.     switch (curtok) {
  815.         case TOK_MODULE:
  816.     if (implementationmodules)
  817. isdefn = 2;
  818.             nummods = 0;
  819.             while (curtok == TOK_MODULE) {
  820.                 if (p_module(0, isdefn)) {
  821.                     nummods++;
  822.                     if (nummods == 2 && !requested_module)
  823.                         warning("Multiple modules in one source file may not work correctly [276]");
  824.                 }
  825.             }
  826.     wneedtok(TOK_DOT);
  827.             break;
  828.         default:
  829.             if (curtok == TOK_PROGRAM) {
  830.                 gettok();
  831.                 if (!wexpecttok(TOK_IDENT))
  832.     skiptotoken(TOK_IDENT);
  833.                 prog = addmeaning(curtoksym, MK_MODULE);
  834.                 gettok();
  835.                 if (curtok == TOK_LPAR) {
  836.                     while (curtok != TOK_RPAR) {
  837.                         if (curtok == TOK_IDENT &&
  838.                             strcicmp(curtokbuf, "INPUT") &&
  839.                             strcicmp(curtokbuf, "OUTPUT") &&
  840.     strcicmp(curtokbuf, "KEYBOARD") &&
  841.     strcicmp(curtokbuf, "LISTING")) {
  842.     if (literalfilesflag == 2) {
  843. strlist_add(&literalfiles, curtokbuf);
  844.     } else
  845. note(format_s("Unexpected name "%s" in program header [262]",
  846.       curtokcase));
  847.                         }
  848.                         gettok();
  849.                     }
  850.                     gettok();
  851.                 }
  852. if (curtok == TOK_LBR)
  853.     skipparens();
  854.                 wneedtok(TOK_SEMI);
  855.             } else {
  856.                 prog = addmeaning(findsymbol("program"), MK_MODULE);
  857.             }
  858.             prog->anyvarflag = 1;
  859.             if (requested_module && strcicmp(requested_module, prog->name) &&
  860.                                     strcicmp(requested_module, "program")) {
  861.                 for (;;) {
  862.                     skiptomodule();
  863.                     if (curtok == TOK_DOT)
  864.                         break;
  865.                      (void)p_module(0, 2);
  866.                 }
  867. gettok();
  868.                 break;
  869.             }
  870.             pushctx(prog);
  871.             p_block(TOK_PROGRAM);
  872.             echoprocname(prog);
  873.     flushcomments(NULL, -1, -1);
  874.     if (curtok != TOK_EOF) {
  875. sp = p_body();
  876. strlist_mix(&prog->comments, curcomments);
  877. curcomments = NULL;
  878. if (fullprototyping > 0) {
  879.     output(format_s("main(int argc, %s *argv[])", charname));
  880. } else {
  881.     output("main(argc, argv)n");
  882.     singleindent(argindent);
  883.     output("int argc;n");
  884.     singleindent(argindent);
  885.     output(format_s("%s *argv[];n", charname));
  886. }
  887. outcontext = prog;
  888. out_block(sp, BR_FUNCTION, 10000);
  889. free_stmt(sp);
  890. popctx();
  891. if (curtok == TOK_SEMI)
  892.     gettok();
  893. else 
  894.     wneedtok(TOK_DOT);
  895.     }
  896.             break;
  897.     }
  898.     if (curtok != TOK_EOF) {
  899.         warning("Junk at end of input file ignored [277]");
  900.     }
  901. }
  902. /* End. */