Annotation of researchv10no/cmd/f2c/format.c, revision 1.1

1.1     ! root        1: /****************************************************************
        !             2: Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
        !             3: 
        !             4: Permission to use, copy, modify, and distribute this software
        !             5: and its documentation for any purpose and without fee is hereby
        !             6: granted, provided that the above copyright notice appear in all
        !             7: copies and that both that the copyright notice and this
        !             8: permission notice and warranty disclaimer appear in supporting
        !             9: documentation, and that the names of AT&T Bell Laboratories or
        !            10: Bellcore or any of their entities not be used in advertising or
        !            11: publicity pertaining to distribution of the software without
        !            12: specific, written prior permission.
        !            13: 
        !            14: AT&T and Bellcore disclaim all warranties with regard to this
        !            15: software, including all implied warranties of merchantability
        !            16: and fitness.  In no event shall AT&T or Bellcore be liable for
        !            17: any special, indirect or consequential damages or any damages
        !            18: whatsoever resulting from loss of use, data or profits, whether
        !            19: in an action of contract, negligence or other tortious action,
        !            20: arising out of or in connection with the use or performance of
        !            21: this software.
        !            22: ****************************************************************/
        !            23: 
        !            24: /* Format.c -- this file takes an intermediate file (generated by pass 1
        !            25:    of the translator) and some state information about the contents of that
        !            26:    file, and generates C program text. */
        !            27: 
        !            28: #include "defs.h"
        !            29: #include "p1defs.h"
        !            30: #include "format.h"
        !            31: #include "output.h"
        !            32: #include "names.h"
        !            33: #include "iob.h"
        !            34: 
        !            35: int c_output_line_length = DEF_C_LINE_LENGTH;
        !            36: 
        !            37: int last_was_label;    /* Boolean used to generate semicolons
        !            38:                                   when a label terminates a block */
        !            39: static char this_proc_name[52];        /* Name of the current procedure.  This is
        !            40:                                   probably too simplistic to handle
        !            41:                                   multiple entry points */
        !            42: 
        !            43: static int p1getd(), p1gets(), p1getf(), get_p1_token();
        !            44: static int p1get_const(), p1getn();
        !            45: static expptr do_format(), do_p1_name_pointer(), do_p1_const();
        !            46: static expptr do_p1_expr(), do_p1_ident(), do_p1_charp(), do_p1_extern();
        !            47: static expptr do_p1_head(), do_p1_list(), do_p1_literal();
        !            48: static void do_p1_label(), do_p1_asgoto(), do_p1_goto();
        !            49: static void do_p1_if(), do_p1_else(), do_p1_elif(), do_p1_endif();
        !            50: static void do_p1_endelse(), do_p1_subr_ret(), do_p1_comp_goto();
        !            51: static void do_p1_for(), do_p1_end_for(), do_p1_fortran();
        !            52: static void do_p1_1while(), do_p1_2while(), do_p1_elseifstart();
        !            53: static void do_p1_comment(), do_p1_set_line();
        !            54: static expptr do_p1_addr();
        !            55: static void proto();
        !            56: void list_arg_types();
        !            57: chainp length_comp();
        !            58: void listargs();
        !            59: extern chainp assigned_fmts;
        !            60: static char filename[P1_FILENAME_MAX];
        !            61: extern int gflag;
        !            62: int gflag1;
        !            63: extern char *parens;
        !            64: 
        !            65: start_formatting ()
        !            66: {
        !            67:     FILE *infile;
        !            68:     static int wrote_one = 0;
        !            69:     extern int usedefsforcommon;
        !            70:     extern char *p1_file, *p1_bakfile;
        !            71: 
        !            72:     this_proc_name[0] = '\0';
        !            73:     last_was_label = 0;
        !            74:     ei_next = ei_first;
        !            75:     wh_next = wh_first;
        !            76: 
        !            77:     (void) fclose (pass1_file);
        !            78:     if ((infile = fopen (p1_file, binread)) == NULL)
        !            79:        Fatal("start_formatting:  couldn't open the intermediate file\n");
        !            80: 
        !            81:     if (wrote_one)
        !            82:        nice_printf (c_file, "\n");
        !            83: 
        !            84:     while (!feof (infile)) {
        !            85:        expptr this_expr;
        !            86: 
        !            87:        this_expr = do_format (infile, c_file);
        !            88:        if (this_expr) {
        !            89:            out_and_free_statement (c_file, this_expr);
        !            90:        } /* if this_expr */
        !            91:     } /* while !feof infile */
        !            92: 
        !            93:     (void) fclose (infile);
        !            94: 
        !            95:     if (last_was_label)
        !            96:        nice_printf (c_file, ";\n");
        !            97: 
        !            98:     prev_tab (c_file);
        !            99:     gflag1 = 0;
        !           100:     if (this_proc_name[0])
        !           101:        nice_printf (c_file, "} /* %s */\n", this_proc_name);
        !           102: 
        !           103: 
        !           104: /* Write the #undefs for common variable reference */
        !           105: 
        !           106:     if (usedefsforcommon) {
        !           107:        Extsym *ext;
        !           108:        int did_one = 0;
        !           109: 
        !           110:        for (ext = extsymtab; ext < nextext; ext++)
        !           111:            if (ext -> extstg == STGCOMMON && ext -> used_here) {
        !           112:                ext -> used_here = 0;
        !           113:                if (!did_one)
        !           114:                    nice_printf (c_file, "\n");
        !           115:                wr_abbrevs(c_file, 0, ext->extp);
        !           116:                did_one = 1;
        !           117:                ext -> extp = CHNULL;
        !           118:            } /* if */
        !           119: 
        !           120:        if (did_one)
        !           121:            nice_printf (c_file, "\n");
        !           122:     } /* if usedefsforcommon */
        !           123: 
        !           124:     other_undefs(c_file);
        !           125: 
        !           126:     wrote_one = 1;
        !           127: 
        !           128: /* For debugging only */
        !           129: 
        !           130:     if (debugflag && (pass1_file = fopen (p1_bakfile, binwrite)))
        !           131:        if (infile = fopen (p1_file, binread)) {
        !           132:            ffilecopy (infile, pass1_file);
        !           133:            fclose (infile);
        !           134:            fclose (pass1_file);
        !           135:        } /* if infile */
        !           136: 
        !           137: /* End of "debugging only" */
        !           138: 
        !           139:     scrub(p1_file);    /* optionally unlink */
        !           140: 
        !           141:     if ((pass1_file = fopen (p1_file, binwrite)) == NULL)
        !           142:        err ("start_formatting:  couldn't reopen the pass1 file");
        !           143: 
        !           144: } /* start_formatting */
        !           145: 
        !           146: 
        !           147:  static void
        !           148: put_semi(outfile)
        !           149:  FILE *outfile;
        !           150: {
        !           151:        nice_printf (outfile, ";\n");
        !           152:        last_was_label = 0;
        !           153:        }
        !           154: 
        !           155: #define SEM_CHECK(x) if (last_was_label) put_semi(x)
        !           156: 
        !           157: /* do_format -- takes an input stream (a file in pass1 format) and writes
        !           158:    the appropriate C code to   outfile   when possible.  When reading an
        !           159:    expression, the expression tree is returned instead. */
        !           160: 
        !           161: static expptr do_format (infile, outfile)
        !           162: FILE *infile, *outfile;
        !           163: {
        !           164:     int token_type, was_c_token;
        !           165:     expptr retval = ENULL;
        !           166: 
        !           167:     token_type = get_p1_token (infile);
        !           168:     was_c_token = 1;
        !           169:     switch (token_type) {
        !           170:        case P1_COMMENT:
        !           171:            do_p1_comment (infile, outfile);
        !           172:            was_c_token = 0;
        !           173:            break;
        !           174:        case P1_SET_LINE:
        !           175:            do_p1_set_line (infile);
        !           176:            was_c_token = 0;
        !           177:            break;
        !           178:        case P1_FILENAME:
        !           179:            p1gets(infile, filename, P1_FILENAME_MAX);
        !           180:            was_c_token = 0;
        !           181:            break;
        !           182:        case P1_NAME_POINTER:
        !           183:            retval = do_p1_name_pointer (infile);
        !           184:            break;
        !           185:        case P1_CONST:
        !           186:            retval = do_p1_const (infile);
        !           187:            break;
        !           188:        case P1_EXPR:
        !           189:            retval = do_p1_expr (infile, outfile);
        !           190:            break;
        !           191:        case P1_IDENT:
        !           192:            retval = do_p1_ident(infile);
        !           193:            break;
        !           194:        case P1_CHARP:
        !           195:                retval = do_p1_charp(infile);
        !           196:                break;
        !           197:        case P1_EXTERN:
        !           198:            retval = do_p1_extern (infile);
        !           199:            break;
        !           200:        case P1_HEAD:
        !           201:            gflag1 = 0;
        !           202:            retval = do_p1_head (infile, outfile);
        !           203:            gflag1 = gflag;
        !           204:            break;
        !           205:        case P1_LIST:
        !           206:            retval = do_p1_list (infile, outfile);
        !           207:            break;
        !           208:        case P1_LITERAL:
        !           209:            retval = do_p1_literal (infile);
        !           210:            break;
        !           211:        case P1_LABEL:
        !           212:            do_p1_label (infile, outfile);
        !           213:            /* last_was_label = 1; -- now set in do_p1_label */
        !           214:            was_c_token = 0;
        !           215:            break;
        !           216:        case P1_ASGOTO:
        !           217:            do_p1_asgoto (infile, outfile);
        !           218:            break;
        !           219:        case P1_GOTO:
        !           220:            do_p1_goto (infile, outfile);
        !           221:            break;
        !           222:        case P1_IF:
        !           223:            do_p1_if (infile, outfile);
        !           224:            break;
        !           225:        case P1_ELSE:
        !           226:            SEM_CHECK(outfile);
        !           227:            do_p1_else (outfile);
        !           228:            break;
        !           229:        case P1_ELIF:
        !           230:            SEM_CHECK(outfile);
        !           231:            do_p1_elif (infile, outfile);
        !           232:            break;
        !           233:        case P1_ENDIF:
        !           234:            SEM_CHECK(outfile);
        !           235:            do_p1_endif (outfile);
        !           236:            break;
        !           237:        case P1_ENDELSE:
        !           238:            SEM_CHECK(outfile);
        !           239:            do_p1_endelse (outfile);
        !           240:            break;
        !           241:        case P1_ADDR:
        !           242:            retval = do_p1_addr (infile, outfile);
        !           243:            break;
        !           244:        case P1_SUBR_RET:
        !           245:            do_p1_subr_ret (infile, outfile);
        !           246:            break;
        !           247:        case P1_COMP_GOTO:
        !           248:            do_p1_comp_goto (infile, outfile);
        !           249:            break;
        !           250:        case P1_FOR:
        !           251:            do_p1_for (infile, outfile);
        !           252:            break;
        !           253:        case P1_ENDFOR:
        !           254:            SEM_CHECK(outfile);
        !           255:            do_p1_end_for (outfile);
        !           256:            break;
        !           257:        case P1_WHILE1START:
        !           258:                do_p1_1while(outfile);
        !           259:                break;
        !           260:        case P1_WHILE2START:
        !           261:                do_p1_2while(infile, outfile);
        !           262:                break;
        !           263:        case P1_PROCODE:
        !           264:                procode(outfile);
        !           265:                break;
        !           266:        case P1_ELSEIFSTART:
        !           267:                SEM_CHECK(outfile);
        !           268:                do_p1_elseifstart(outfile);
        !           269:                break;
        !           270:        case P1_FORTRAN:
        !           271:                do_p1_fortran(infile, outfile);
        !           272:                /* no break; */
        !           273:        case P1_EOF:
        !           274:            was_c_token = 0;
        !           275:            break;
        !           276:        case P1_UNKNOWN:
        !           277:            Fatal("do_format:  Unknown token type in intermediate file");
        !           278:            break;
        !           279:        default:
        !           280:            Fatal("do_format:  Bad token type in intermediate file");
        !           281:            break;
        !           282:    } /* switch */
        !           283: 
        !           284:     if (was_c_token)
        !           285:        last_was_label = 0;
        !           286:     return retval;
        !           287: } /* do_format */
        !           288: 
        !           289: 
        !           290:  static void
        !           291: do_p1_comment (infile, outfile)
        !           292: FILE *infile, *outfile;
        !           293: {
        !           294:     extern int c_output_line_length, in_comment;
        !           295: 
        !           296:     char storage[COMMENT_BUFFER_SIZE + 1];
        !           297:     int length;
        !           298: 
        !           299:     if (!p1gets(infile, storage, COMMENT_BUFFER_SIZE + 1))
        !           300:        return;
        !           301: 
        !           302:     length = strlen (storage);
        !           303: 
        !           304:     gflag1 = 0;
        !           305:     in_comment = 1;
        !           306:     if (length > c_output_line_length - 6)
        !           307:        margin_printf (outfile, "/*%s*/\n", storage);
        !           308:     else
        !           309:        margin_printf (outfile, length ? "/* %s */\n" : "\n", storage);
        !           310:     in_comment = 0;
        !           311:     gflag1 = gflag;
        !           312: } /* do_p1_comment */
        !           313: 
        !           314:  static void
        !           315: do_p1_set_line (infile)
        !           316: FILE *infile;
        !           317: {
        !           318:     int status;
        !           319:     long new_line_number = -1;
        !           320: 
        !           321:     status = p1getd (infile, &new_line_number);
        !           322: 
        !           323:     if (status == EOF)
        !           324:        err ("do_p1_set_line:  Missing line number at end of file\n");
        !           325:     else if (status == 0 || new_line_number == -1)
        !           326:        errl("do_p1_set_line:  Illegal line number in intermediate file: %ld\n",
        !           327:                new_line_number);
        !           328:     else {
        !           329:        lineno = new_line_number;
        !           330:        }
        !           331: } /* do_p1_set_line */
        !           332: 
        !           333: 
        !           334: static expptr do_p1_name_pointer (infile)
        !           335: FILE *infile;
        !           336: {
        !           337:     Namep namep = (Namep) NULL;
        !           338:     int status;
        !           339: 
        !           340:     status = p1getd (infile, (long *) &namep);
        !           341: 
        !           342:     if (status == EOF)
        !           343:        err ("do_p1_name_pointer:  Missing pointer at end of file\n");
        !           344:     else if (status == 0 || namep == (Namep) NULL)
        !           345:        erri ("do_p1_name_pointer:  Illegal name pointer in p1 file: '%x'\n",
        !           346:                (int) namep);
        !           347: 
        !           348:     return (expptr) namep;
        !           349: } /* do_p1_name_pointer */
        !           350: 
        !           351: 
        !           352: 
        !           353: static expptr do_p1_const (infile)
        !           354: FILE *infile;
        !           355: {
        !           356:     struct Constblock *c = (struct Constblock *) NULL;
        !           357:     long type = -1;
        !           358:     int status;
        !           359: 
        !           360:     status = p1getd (infile, &type);
        !           361: 
        !           362:     if (status == EOF)
        !           363:        err ("do_p1_const:  Missing constant type at end of file\n");
        !           364:     else if (status == 0)
        !           365:        errl("do_p1_const:  Illegal constant type in p1 file: %ld\n", type);
        !           366:     else {
        !           367:        status = p1get_const (infile, (int)type, &c);
        !           368: 
        !           369:        if (status == EOF) {
        !           370:            err ("do_p1_const:  Missing constant value at end of file\n");
        !           371:            c = (struct Constblock *) NULL;
        !           372:        } else if (status == 0) {
        !           373:            err ("do_p1_const:  Illegal constant value in p1 file\n");
        !           374:            c = (struct Constblock *) NULL;
        !           375:        } /* else */
        !           376:     } /* else */
        !           377:     return (expptr) c;
        !           378: } /* do_p1_const */
        !           379: 
        !           380: 
        !           381: static expptr do_p1_literal (infile)
        !           382: FILE *infile;
        !           383: {
        !           384:     int status;
        !           385:     long memno;
        !           386:     Addrp addrp;
        !           387: 
        !           388:     status = p1getd (infile, &memno);
        !           389: 
        !           390:     if (status == EOF)
        !           391:        err ("do_p1_literal:  Missing memno at end of file");
        !           392:     else if (status == 0)
        !           393:        err ("do_p1_literal:  Missing memno in p1 file");
        !           394:     else {
        !           395:        struct Literal *litp, *lastlit;
        !           396: 
        !           397:        addrp = ALLOC (Addrblock);
        !           398:        addrp -> tag = TADDR;
        !           399:        addrp -> vtype = TYUNKNOWN;
        !           400:        addrp -> Field = NULL;
        !           401: 
        !           402:        lastlit = litpool + nliterals;
        !           403:        for (litp = litpool; litp < lastlit; litp++)
        !           404:            if (litp -> litnum == memno) {
        !           405:                addrp -> vtype = litp -> littype;
        !           406:                *((union Constant *) &(addrp -> user)) =
        !           407:                        *((union Constant *) &(litp -> litval));
        !           408:                break;
        !           409:            } /* if litp -> litnum == memno */
        !           410: 
        !           411:        addrp -> memno = memno;
        !           412:        addrp -> vstg = STGMEMNO;
        !           413:        addrp -> uname_tag = UNAM_CONST;
        !           414:     } /* else */
        !           415: 
        !           416:     return (expptr) addrp;
        !           417: } /* do_p1_literal */
        !           418: 
        !           419: 
        !           420: static void do_p1_label (infile, outfile)
        !           421: FILE *infile, *outfile;
        !           422: {
        !           423:     int status;
        !           424:     ftnint stateno;
        !           425:     char *user_label ();
        !           426:     struct Labelblock *L;
        !           427:     char *fmt;
        !           428: 
        !           429:     status = p1getd (infile, &stateno);
        !           430: 
        !           431:     if (status == EOF)
        !           432:        err ("do_p1_label:  Missing label at end of file");
        !           433:     else if (status == 0)
        !           434:        err ("do_p1_label:  Missing label in p1 file ");
        !           435:     else if (stateno < 0) {    /* entry */
        !           436:        margin_printf(outfile, "\n%s:\n", user_label(stateno));
        !           437:        last_was_label = 1;
        !           438:        }
        !           439:     else {
        !           440:        L = labeltab + stateno;
        !           441:        if (L->labused) {
        !           442:                fmt = "%s:\n";
        !           443:                last_was_label = 1;
        !           444:                }
        !           445:        else
        !           446:                fmt = "/* %s: */\n";
        !           447:        margin_printf(outfile, fmt, user_label(L->stateno));
        !           448:     } /* else */
        !           449: } /* do_p1_label */
        !           450: 
        !           451: 
        !           452: 
        !           453: static void do_p1_asgoto (infile, outfile)
        !           454: FILE *infile, *outfile;
        !           455: {
        !           456:     expptr expr;
        !           457: 
        !           458:     expr = do_format (infile, outfile);
        !           459:     out_asgoto (outfile, expr);
        !           460: 
        !           461: } /* do_p1_asgoto */
        !           462: 
        !           463: 
        !           464: static void do_p1_goto (infile, outfile)
        !           465: FILE *infile, *outfile;
        !           466: {
        !           467:     int status;
        !           468:     long stateno;
        !           469:     char *user_label ();
        !           470: 
        !           471:     status = p1getd (infile, &stateno);
        !           472: 
        !           473:     if (status == EOF)
        !           474:        err ("do_p1_goto:  Missing goto label at end of file");
        !           475:     else if (status == 0)
        !           476:        err ("do_p1_goto:  Missing goto label in p1 file");
        !           477:     else {
        !           478:        nice_printf (outfile, "goto %s;\n", user_label (stateno));
        !           479:     } /* else */
        !           480: } /* do_p1_goto */
        !           481: 
        !           482: 
        !           483: static void do_p1_if (infile, outfile)
        !           484: FILE *infile, *outfile;
        !           485: {
        !           486:     expptr cond;
        !           487: 
        !           488:     do {
        !           489:         cond = do_format (infile, outfile);
        !           490:     } while (cond == ENULL);
        !           491: 
        !           492:     out_if (outfile, cond);
        !           493: } /* do_p1_if */
        !           494: 
        !           495: 
        !           496: static void do_p1_else (outfile)
        !           497: FILE *outfile;
        !           498: {
        !           499:     out_else (outfile);
        !           500: } /* do_p1_else */
        !           501: 
        !           502: 
        !           503: static void do_p1_elif (infile, outfile)
        !           504: FILE *infile, *outfile;
        !           505: {
        !           506:     expptr cond;
        !           507: 
        !           508:     do {
        !           509:         cond = do_format (infile, outfile);
        !           510:     } while (cond == ENULL);
        !           511: 
        !           512:     elif_out (outfile, cond);
        !           513: } /* do_p1_elif */
        !           514: 
        !           515: static void do_p1_endif (outfile)
        !           516: FILE *outfile;
        !           517: {
        !           518:     endif_out (outfile);
        !           519: } /* do_p1_endif */
        !           520: 
        !           521: 
        !           522: static void do_p1_endelse (outfile)
        !           523: FILE *outfile;
        !           524: {
        !           525:     end_else_out (outfile);
        !           526: } /* do_p1_endelse */
        !           527: 
        !           528: 
        !           529: static expptr do_p1_addr (infile, outfile)
        !           530: FILE *infile, *outfile;
        !           531: {
        !           532:     Addrp addrp = (Addrp) NULL;
        !           533:     int status;
        !           534: 
        !           535:     status = p1getn (infile, (int)sizeof(struct Addrblock), (char **) &addrp);
        !           536: 
        !           537:     if (status == EOF)
        !           538:        err ("do_p1_addr:  Missing Addrp at end of file");
        !           539:     else if (status == 0)
        !           540:        err ("do_p1_addr:  Missing Addrp in p1 file");
        !           541:     else if (addrp == (Addrp) NULL)
        !           542:        err ("do_p1_addr:  Null addrp in p1 file");
        !           543:     else if (addrp -> tag != TADDR)
        !           544:        erri ("do_p1_addr: bad tag in p1 file '%d'", addrp -> tag);
        !           545:     else {
        !           546:        addrp -> vleng = do_format (infile, outfile);
        !           547:        addrp -> memoffset = do_format (infile, outfile);
        !           548:     }
        !           549: 
        !           550:     return (expptr) addrp;
        !           551: } /* do_p1_addr */
        !           552: 
        !           553: 
        !           554: 
        !           555: static void do_p1_subr_ret (infile, outfile)
        !           556: FILE *infile, *outfile;
        !           557: {
        !           558:     expptr retval;
        !           559: 
        !           560:     nice_printf (outfile, "return ");
        !           561:     retval = do_format (infile, outfile);
        !           562:     if (!multitype)
        !           563:        if (retval)
        !           564:                expr_out (outfile, retval);
        !           565: 
        !           566:     nice_printf (outfile, ";\n");
        !           567: } /* do_p1_subr_ret */
        !           568: 
        !           569: 
        !           570: 
        !           571: static void do_p1_comp_goto (infile, outfile)
        !           572: FILE *infile, *outfile;
        !           573: {
        !           574:     expptr index;
        !           575:     expptr labels;
        !           576: 
        !           577:     index = do_format (infile, outfile);
        !           578: 
        !           579:     if (index == ENULL) {
        !           580:        err ("do_p1_comp_goto:  no expression for computed goto");
        !           581:        return;
        !           582:     } /* if index == ENULL */
        !           583: 
        !           584:     labels = do_format (infile, outfile);
        !           585: 
        !           586:     if (labels && labels -> tag != TLIST)
        !           587:        erri ("do_p1_comp_goto:  expected list, got tag '%d'", labels -> tag);
        !           588:     else
        !           589:        compgoto_out (outfile, index, labels);
        !           590: } /* do_p1_comp_goto */
        !           591: 
        !           592: 
        !           593: static void do_p1_for (infile, outfile)
        !           594: FILE *infile, *outfile;
        !           595: {
        !           596:     expptr init, test, inc;
        !           597: 
        !           598:     init = do_format (infile, outfile);
        !           599:     test = do_format (infile, outfile);
        !           600:     inc = do_format (infile, outfile);
        !           601: 
        !           602:     out_for (outfile, init, test, inc);
        !           603: } /* do_p1_for */
        !           604: 
        !           605: static void do_p1_end_for (outfile)
        !           606: FILE *outfile;
        !           607: {
        !           608:     out_end_for (outfile);
        !           609: } /* do_p1_end_for */
        !           610: 
        !           611: 
        !           612:  static void
        !           613: do_p1_fortran(infile, outfile)
        !           614:  FILE *infile, *outfile;
        !           615: {
        !           616:        char buf[P1_STMTBUFSIZE];
        !           617:        if (!p1gets(infile, buf, P1_STMTBUFSIZE))
        !           618:                return;
        !           619:        /* bypass nice_printf nonsense */
        !           620:        fprintf(outfile, "/*< %s >*/\n", buf+1);        /* + 1 to skip by '$' */
        !           621:        }
        !           622: 
        !           623: 
        !           624: static expptr do_p1_expr (infile, outfile)
        !           625: FILE *infile, *outfile;
        !           626: {
        !           627:     int status;
        !           628:     long opcode, type;
        !           629:     struct Exprblock *result = (struct Exprblock *) NULL;
        !           630: 
        !           631:     status = p1getd (infile, &opcode);
        !           632: 
        !           633:     if (status == EOF)
        !           634:        err ("do_p1_expr:  Missing expr opcode at end of file");
        !           635:     else if (status == 0)
        !           636:        err ("do_p1_expr:  Missing expr opcode in p1 file");
        !           637:     else {
        !           638: 
        !           639:        status = p1getd (infile, &type);
        !           640: 
        !           641:        if (status == EOF)
        !           642:            err ("do_p1_expr:  Missing expr type at end of file");
        !           643:        else if (status == 0)
        !           644:            err ("do_p1_expr:  Missing expr type in p1 file");
        !           645:        else if (opcode == 0)
        !           646:            return ENULL;
        !           647:        else {
        !           648:            result = ALLOC (Exprblock);
        !           649: 
        !           650:            result -> tag = TEXPR;
        !           651:            result -> vtype = type;
        !           652:            result -> opcode = opcode;
        !           653:            result -> vleng = do_format (infile, outfile);
        !           654: 
        !           655:            if (is_unary_op (opcode))
        !           656:                result -> leftp = do_format (infile, outfile);
        !           657:            else if (is_binary_op (opcode)) {
        !           658:                result -> leftp = do_format (infile, outfile);
        !           659:                result -> rightp = do_format (infile, outfile);
        !           660:            } else
        !           661:                errl("do_p1_expr:  Illegal opcode %ld", opcode);
        !           662:        } /* else */
        !           663:     } /* else */
        !           664: 
        !           665:     return (expptr) result;
        !           666: } /* do_p1_expr */
        !           667: 
        !           668: 
        !           669: static expptr do_p1_ident(infile)
        !           670: FILE *infile;
        !           671: {
        !           672:        Addrp addrp;
        !           673:        int status;
        !           674:        long vtype, vstg;
        !           675: 
        !           676:        addrp = ALLOC (Addrblock);
        !           677:        addrp -> tag = TADDR;
        !           678: 
        !           679:        status = p1getd (infile, &vtype);
        !           680:        if (status == EOF)
        !           681:            err ("do_p1_ident:  Missing identifier type at end of file\n");
        !           682:        else if (status == 0 || vtype < 0 || vtype >= NTYPES)
        !           683:            errl("do_p1_ident:  Bad type in intermediate file: %ld\n", vtype);
        !           684:        else
        !           685:            addrp -> vtype = vtype;
        !           686: 
        !           687:        status = p1getd (infile, &vstg);
        !           688:        if (status == EOF)
        !           689:            err ("do_p1_ident:  Missing identifier storage at end of file\n");
        !           690:        else if (status == 0 || vstg < 0 || vstg > STGNULL)
        !           691:            errl("do_p1_ident:  Bad storage in intermediate file: %ld\n", vtype);
        !           692:        else
        !           693:            addrp -> vstg = vstg;
        !           694: 
        !           695:        status = p1gets(infile, addrp->user.ident, IDENT_LEN);
        !           696: 
        !           697:        if (status == EOF)
        !           698:            err ("do_p1_ident:  Missing ident string at end of file");
        !           699:        else if (status == 0)
        !           700:            err ("do_p1_ident:  Missing ident string in intermediate file");
        !           701:        addrp->uname_tag = UNAM_IDENT;
        !           702:        return (expptr) addrp;
        !           703: } /* do_p1_ident */
        !           704: 
        !           705: static expptr do_p1_charp(infile)
        !           706: FILE *infile;
        !           707: {
        !           708:        Addrp addrp;
        !           709:        int status;
        !           710:        long vtype, vstg;
        !           711:        char buf[64];
        !           712: 
        !           713:        addrp = ALLOC (Addrblock);
        !           714:        addrp -> tag = TADDR;
        !           715: 
        !           716:        status = p1getd (infile, &vtype);
        !           717:        if (status == EOF)
        !           718:            err ("do_p1_ident:  Missing identifier type at end of file\n");
        !           719:        else if (status == 0 || vtype < 0 || vtype >= NTYPES)
        !           720:            errl("do_p1_ident:  Bad type in intermediate file: %ld\n", vtype);
        !           721:        else
        !           722:            addrp -> vtype = vtype;
        !           723: 
        !           724:        status = p1getd (infile, &vstg);
        !           725:        if (status == EOF)
        !           726:            err ("do_p1_ident:  Missing identifier storage at end of file\n");
        !           727:        else if (status == 0 || vstg < 0 || vstg > STGNULL)
        !           728:            errl("do_p1_ident:  Bad storage in intermediate file: %ld\n", vtype);
        !           729:        else
        !           730:            addrp -> vstg = vstg;
        !           731: 
        !           732:        status = p1gets(infile, buf, (int)sizeof(buf));
        !           733: 
        !           734:        if (status == EOF)
        !           735:            err ("do_p1_ident:  Missing charp ident string at end of file");
        !           736:        else if (status == 0)
        !           737:            err ("do_p1_ident:  Missing charp ident string in intermediate file");
        !           738:        addrp->uname_tag = UNAM_CHARP;
        !           739:        addrp->user.Charp = strcpy(mem(strlen(buf)+1,0), buf);
        !           740:        return (expptr) addrp;
        !           741: }
        !           742: 
        !           743: 
        !           744: static expptr do_p1_extern (infile)
        !           745: FILE *infile;
        !           746: {
        !           747:     Addrp addrp;
        !           748: 
        !           749:     addrp = ALLOC (Addrblock);
        !           750:     if (addrp) {
        !           751:        int status;
        !           752: 
        !           753:        addrp->tag = TADDR;
        !           754:        addrp->vstg = STGEXT;
        !           755:        addrp->uname_tag = UNAM_EXTERN;
        !           756:        status = p1getd (infile, &(addrp -> memno));
        !           757:        if (status == EOF)
        !           758:            err ("do_p1_extern:  Missing memno at end of file");
        !           759:        else if (status == 0)
        !           760:            err ("do_p1_extern:  Missing memno in intermediate file");
        !           761:        if (addrp->vtype = extsymtab[addrp->memno].extype)
        !           762:                addrp->vclass = CLPROC;
        !           763:     } /* if addrp */
        !           764: 
        !           765:     return (expptr) addrp;
        !           766: } /* do_p1_extern */
        !           767: 
        !           768: 
        !           769: 
        !           770: static expptr do_p1_head (infile, outfile)
        !           771: FILE *infile, *outfile;
        !           772: {
        !           773:     int status;
        !           774:     int add_n_;
        !           775:     long class;
        !           776:     char storage[256];
        !           777: 
        !           778:     status = p1getd (infile, &class);
        !           779:     if (status == EOF)
        !           780:        err ("do_p1_head:  missing header class at end of file");
        !           781:     else if (status == 0)
        !           782:        err ("do_p1_head:  missing header class in p1 file");
        !           783:     else {
        !           784:        status = p1gets (infile, storage, (int)sizeof(storage));
        !           785:        if (status == EOF || status == 0)
        !           786:            storage[0] = '\0';
        !           787:     } /* else */
        !           788: 
        !           789:     if (class == CLPROC || class == CLMAIN) {
        !           790:        chainp lengths;
        !           791: 
        !           792:        add_n_ = nentry > 1;
        !           793:        lengths = length_comp(entries, add_n_);
        !           794: 
        !           795:        if (!add_n_ && protofile && class != CLMAIN)
        !           796:                protowrite(protofile, proctype, storage, entries, lengths);
        !           797: 
        !           798:        if (class == CLMAIN)
        !           799:            nice_printf (outfile, "/* Main program */ ");
        !           800:        else
        !           801:            nice_printf(outfile, "%s ", multitype ? "VOID"
        !           802:                        : c_type_decl(proctype, 1));
        !           803: 
        !           804:        nice_printf(outfile, add_n_ ? "%s0_" : "%s", storage);
        !           805:        if (!Ansi) {
        !           806:                listargs(outfile, entries, add_n_, lengths);
        !           807:                nice_printf (outfile, "\n");
        !           808:                }
        !           809:        list_arg_types (outfile, entries, lengths, add_n_, "\n");
        !           810:        nice_printf (outfile, "{\n");
        !           811:        frchain(&lengths);
        !           812:        next_tab (outfile);
        !           813:        strcpy(this_proc_name, storage);
        !           814:        list_decls (outfile);
        !           815: 
        !           816:     } else if (class == CLBLOCK)
        !           817:         next_tab (outfile);
        !           818:     else
        !           819:        errl("do_p1_head: got class %ld", class);
        !           820: 
        !           821:     return NULL;
        !           822: } /* do_p1_head */
        !           823: 
        !           824: 
        !           825: static expptr do_p1_list (infile, outfile)
        !           826: FILE *infile, *outfile;
        !           827: {
        !           828:     long tag, type, count;
        !           829:     int status;
        !           830:     expptr result;
        !           831: 
        !           832:     status = p1getd (infile, &tag);
        !           833:     if (status == EOF)
        !           834:        err ("do_p1_list:  missing list tag at end of file");
        !           835:     else if (status == 0)
        !           836:        err ("do_p1_list:  missing list tag in p1 file");
        !           837:     else {
        !           838:        status = p1getd (infile, &type);
        !           839:        if (status == EOF)
        !           840:            err ("do_p1_list:  missing list type at end of file");
        !           841:        else if (status == 0)
        !           842:            err ("do_p1_list:  missing list type in p1 file");
        !           843:        else {
        !           844:            status = p1getd (infile, &count);
        !           845:            if (status == EOF)
        !           846:                err ("do_p1_list:  missing count at end of file");
        !           847:            else if (status == 0)
        !           848:                err ("do_p1_list:  missing count in p1 file");
        !           849:        } /* else */
        !           850:     } /* else */
        !           851: 
        !           852:     result = (expptr) ALLOC (Listblock);
        !           853:     if (result) {
        !           854:        chainp pointer;
        !           855: 
        !           856:        result -> tag = tag;
        !           857:        result -> listblock.vtype = type;
        !           858: 
        !           859: /* Assume there will be enough data */
        !           860: 
        !           861:        if (count--) {
        !           862:            pointer = result->listblock.listp =
        !           863:                mkchain((char *)do_format(infile, outfile), CHNULL);
        !           864:            while (count--) {
        !           865:                pointer -> nextp =
        !           866:                        mkchain((char *)do_format(infile, outfile), CHNULL);
        !           867:                pointer = pointer -> nextp;
        !           868:            } /* while (count--) */
        !           869:        } /* if (count) */
        !           870:     } /* if (result) */
        !           871: 
        !           872:     return result;
        !           873: } /* do_p1_list */
        !           874: 
        !           875: 
        !           876: chainp length_comp(e, add_n)   /* get lengths of characters args */
        !           877:  struct Entrypoint *e;
        !           878:  int add_n;
        !           879: {
        !           880:        chainp lengths;
        !           881:        chainp args, args1;
        !           882:        Namep arg, np;
        !           883:        int nchargs;
        !           884:        Argtypes *at;
        !           885:        Atype *a;
        !           886:        extern int init_ac[TYSUBR+1];
        !           887: 
        !           888:        if (!e)
        !           889:                return 0;       /* possible only with errors */
        !           890:        args = args1 = add_n ? allargs : e->arglist;
        !           891:        nchargs = 0;
        !           892:        for (lengths = NULL; args; args = args -> nextp)
        !           893:                if (arg = (Namep)args->datap) {
        !           894:                        if (arg->vclass == CLUNKNOWN)
        !           895:                                arg->vclass = CLVAR;
        !           896:                        if (arg->vtype == TYCHAR && arg->vclass != CLPROC) {
        !           897:                                lengths = mkchain((char *)arg, lengths);
        !           898:                                nchargs++;
        !           899:                                }
        !           900:                        }
        !           901:        if (!add_n && (np = e->enamep)) {
        !           902:                /* one last check -- by now we know all we ever will
        !           903:                 * about external args...
        !           904:                 */
        !           905:                save_argtypes(e->arglist, &e->entryname->arginfo,
        !           906:                        &np->arginfo, 0, np->fvarname, STGEXT, nchargs,
        !           907:                        np->vtype, 1);
        !           908:                at = e->entryname->arginfo;
        !           909:                a = at->atypes + init_ac[np->vtype];
        !           910:                for(; args1; a++, args1 = args1->nextp) {
        !           911:                        frchain(&a->cp);
        !           912:                        if (arg = (Namep)args1->datap)
        !           913:                            switch(arg->vclass) {
        !           914:                                case CLPROC:
        !           915:                                        if (arg->vimpltype
        !           916:                                        && a->type >= 300)
        !           917:                                                a->type = TYUNKNOWN + 200;
        !           918:                                        break;
        !           919:                                case CLUNKNOWN:
        !           920:                                        a->type %= 100;
        !           921:                                }
        !           922:                        }
        !           923:                }
        !           924:        return revchain(lengths);
        !           925:        }
        !           926: 
        !           927: void listargs(outfile, entryp, add_n_, lengths)
        !           928:  FILE *outfile;
        !           929:  struct Entrypoint *entryp;
        !           930:  int add_n_;
        !           931:  chainp lengths;
        !           932: {
        !           933:        chainp args;
        !           934:        char *s;
        !           935:        Namep arg;
        !           936:        int did_one = 0;
        !           937: 
        !           938:        nice_printf (outfile, "(");
        !           939: 
        !           940:        if (add_n_) {
        !           941:                nice_printf(outfile, "n__");
        !           942:                did_one = 1;
        !           943:                args = allargs;
        !           944:                }
        !           945:        else {
        !           946:                if (!entryp)
        !           947:                        return; /* possible only with errors */
        !           948:                args = entryp->arglist;
        !           949:                }
        !           950: 
        !           951:        if (multitype)
        !           952:                {
        !           953:                nice_printf(outfile, ", ret_val");
        !           954:                did_one = 1;
        !           955:                args = allargs;
        !           956:                }
        !           957:        else if (ONEOF(proctype, MSKCOMPLEX|MSKCHAR))
        !           958:                {
        !           959:                s = xretslot[proctype]->user.ident;
        !           960:                nice_printf(outfile, did_one ? ", %s" : "%s",
        !           961:                        *s == '(' /*)*/ ? "r_v" : s);
        !           962:                did_one = 1;
        !           963:                if (proctype == TYCHAR)
        !           964:                        nice_printf (outfile, ", ret_val_len");
        !           965:                }
        !           966:        for (; args; args = args -> nextp)
        !           967:                if (arg = (Namep)args->datap) {
        !           968:                        nice_printf (outfile, "%s", did_one ? ", " : "");
        !           969:                        out_name (outfile, arg);
        !           970:                        did_one = 1;
        !           971:                        }
        !           972: 
        !           973:        for (args = lengths; args; args = args -> nextp)
        !           974:                nice_printf(outfile, ", %s",
        !           975:                        new_arg_length((Namep)args->datap));
        !           976:        nice_printf (outfile, ")");
        !           977: } /* listargs */
        !           978: 
        !           979: 
        !           980: void list_arg_types(outfile, entryp, lengths, add_n_, finalnl)
        !           981: FILE *outfile;
        !           982: struct Entrypoint *entryp;
        !           983: chainp lengths;
        !           984: int add_n_;
        !           985: char *finalnl;
        !           986: {
        !           987:     chainp args;
        !           988:     int last_type = -1, last_class = -1;
        !           989:     int did_one = 0, done_one, is_ext;
        !           990:     char *s, *sep = "", *sep1;
        !           991: 
        !           992:     if (outfile == (FILE *) NULL) {
        !           993:        err ("list_arg_types:  null output file");
        !           994:        return;
        !           995:     } else if (entryp == (struct Entrypoint *) NULL) {
        !           996:        err ("list_arg_types:  null procedure entry pointer");
        !           997:        return;
        !           998:     } /* else */
        !           999: 
        !          1000:     if (Ansi) {
        !          1001:        done_one = 0;
        !          1002:        sep1 = ", ";
        !          1003:        nice_printf(outfile, "(" /*)*/);
        !          1004:        }
        !          1005:     else {
        !          1006:        done_one = 1;
        !          1007:        sep1 = ";\n";
        !          1008:        }
        !          1009:     args = entryp->arglist;
        !          1010:     if (add_n_) {
        !          1011:        nice_printf(outfile, "int n__");
        !          1012:        did_one = done_one;
        !          1013:        sep = sep1;
        !          1014:        args = allargs;
        !          1015:        }
        !          1016:     if (multitype) {
        !          1017:        nice_printf(outfile, "%sMultitype *ret_val", sep);
        !          1018:        did_one = done_one;
        !          1019:        sep = sep1;
        !          1020:        }
        !          1021:     else if (ONEOF (proctype, MSKCOMPLEX|MSKCHAR)) {
        !          1022:        s = xretslot[proctype]->user.ident;
        !          1023:        nice_printf(outfile, "%s%s *%s", sep, c_type_decl(proctype, 0),
        !          1024:                        *s == '(' /*)*/ ? "r_v" : s);
        !          1025:        did_one = done_one;
        !          1026:        sep = sep1;
        !          1027:        if (proctype == TYCHAR)
        !          1028:            nice_printf (outfile, "%sftnlen ret_val_len", sep);
        !          1029:     } /* if ONEOF proctype */
        !          1030:     for (; args; args = args -> nextp) {
        !          1031:        Namep arg = (Namep) args->datap;
        !          1032: 
        !          1033: /* Scalars are passed by reference, and arrays will have their lower bound
        !          1034:    adjusted, so nearly everything is printed with a star in front.  The
        !          1035:    exception is character lengths, which are passed by value. */
        !          1036: 
        !          1037:        if (arg) {
        !          1038:            int type = arg -> vtype, class = arg -> vclass;
        !          1039: 
        !          1040:            if (class == CLPROC)
        !          1041:                if (arg->vimpltype)
        !          1042:                        type = Castargs ? TYUNKNOWN : TYSUBR;
        !          1043:                else if (type == TYREAL && forcedouble && !Castargs)
        !          1044:                        type = TYDREAL;
        !          1045: 
        !          1046:            if (type == last_type && class == last_class && did_one)
        !          1047:                nice_printf (outfile, ", ");
        !          1048:            else
        !          1049:                if ((is_ext = class == CLPROC) && Castargs)
        !          1050:                        nice_printf(outfile, "%s%s ", sep,
        !          1051:                                usedcasts[type] = casttypes[type]);
        !          1052:                else
        !          1053:                        nice_printf(outfile, "%s%s ", sep,
        !          1054:                                c_type_decl(type, is_ext));
        !          1055:            if (class == CLPROC)
        !          1056:                if (Castargs)
        !          1057:                        out_name(outfile, arg);
        !          1058:                else {
        !          1059:                        nice_printf(outfile, "(*");
        !          1060:                        out_name(outfile, arg);
        !          1061:                        nice_printf(outfile, ") %s", parens);
        !          1062:                        }
        !          1063:            else {
        !          1064:                nice_printf (outfile, "*");
        !          1065:                out_name (outfile, arg);
        !          1066:                }
        !          1067: 
        !          1068:            last_type = type;
        !          1069:            last_class = class;
        !          1070:            did_one = done_one;
        !          1071:            sep = sep1;
        !          1072:        } /* if (arg) */
        !          1073:     } /* for args = entryp -> arglist */
        !          1074: 
        !          1075:     for (args = lengths; args; args = args -> nextp)
        !          1076:        nice_printf(outfile, "%sftnlen %s", sep,
        !          1077:                        new_arg_length((Namep)args->datap));
        !          1078:     if (did_one)
        !          1079:        nice_printf (outfile, ";\n");
        !          1080:     else if (Ansi)
        !          1081:        nice_printf(outfile,
        !          1082:                /*((*/ sep != sep1 && Ansi == 1 ? "void)%s" : ")%s",
        !          1083:                finalnl);
        !          1084: } /* list_arg_types */
        !          1085: 
        !          1086:  static void
        !          1087: write_formats(outfile)
        !          1088:  FILE *outfile;
        !          1089: {
        !          1090:        register struct Labelblock *lp;
        !          1091:        int first = 1;
        !          1092:        char *fs;
        !          1093: 
        !          1094:        for(lp = labeltab ; lp < highlabtab ; ++lp)
        !          1095:                if (lp->fmtlabused) {
        !          1096:                        if (first) {
        !          1097:                                first = 0;
        !          1098:                                nice_printf(outfile, "/* Format strings */\n");
        !          1099:                                }
        !          1100:                        nice_printf(outfile, "static char fmt_%ld[] = \"",
        !          1101:                                lp->stateno);
        !          1102:                        if (!(fs = lp->fmtstring))
        !          1103:                                fs = "";
        !          1104:                        nice_printf(outfile, "%s\";\n", fs);
        !          1105:                        }
        !          1106:        if (!first)
        !          1107:                nice_printf(outfile, "\n");
        !          1108:        }
        !          1109: 
        !          1110:  static void
        !          1111: write_ioblocks(outfile)
        !          1112:  FILE *outfile;
        !          1113: {
        !          1114:        register iob_data *L;
        !          1115:        register char *f, **s, *sep;
        !          1116: 
        !          1117:        nice_printf(outfile, "/* Fortran I/O blocks */\n");
        !          1118:        L = iob_list = (iob_data *)revchain((chainp)iob_list);
        !          1119:        do {
        !          1120:                nice_printf(outfile, "static %s %s = { ",
        !          1121:                        L->type, L->name);
        !          1122:                sep = 0;
        !          1123:                for(s = L->fields; f = *s; s++) {
        !          1124:                        if (sep)
        !          1125:                                nice_printf(outfile, sep);
        !          1126:                        sep = ", ";
        !          1127:                        if (*f == '"') {        /* kludge */
        !          1128:                                nice_printf(outfile, "\"");
        !          1129:                                nice_printf(outfile, "%s\"", f+1);
        !          1130:                                }
        !          1131:                        else
        !          1132:                                nice_printf(outfile, "%s", f);
        !          1133:                        }
        !          1134:                nice_printf(outfile, " };\n");
        !          1135:                }
        !          1136:                while(L = L->next);
        !          1137:        nice_printf(outfile, "\n\n");
        !          1138:        }
        !          1139: 
        !          1140:  static void
        !          1141: write_assigned_fmts(outfile)
        !          1142:  FILE *outfile;
        !          1143: {
        !          1144:        register chainp cp;
        !          1145:        Namep np;
        !          1146:        int did_one = 0;
        !          1147: 
        !          1148:        cp = assigned_fmts = revchain(assigned_fmts);
        !          1149:        nice_printf(outfile, "/* Assigned format variables */\nchar ");
        !          1150:        do {
        !          1151:                np = (Namep)cp->datap;
        !          1152:                if (did_one)
        !          1153:                        nice_printf(outfile, ", ");
        !          1154:                did_one = 1;
        !          1155:                nice_printf(outfile, "*%s_fmt", np->fvarname);
        !          1156:                }
        !          1157:                while(cp = cp->nextp);
        !          1158:        nice_printf(outfile, ";\n\n");
        !          1159:        }
        !          1160: 
        !          1161:  static char *
        !          1162: to_upper(s)
        !          1163:  register char *s;
        !          1164: {
        !          1165:        static char buf[64];
        !          1166:        register char *t = buf;
        !          1167:        register int c;
        !          1168:        while(*t++ = (c = *s++) >= 'a' && c <= 'z' ? c + 'A' - 'a' : c);
        !          1169:        return buf;
        !          1170:        }
        !          1171: 
        !          1172: 
        !          1173: /* This routine creates static structures representing a namelist.
        !          1174:    Declarations of the namelist and related structures are:
        !          1175: 
        !          1176:        struct Vardesc {
        !          1177:                char *name;
        !          1178:                char *addr;
        !          1179:                ftnlen *dims;   /* laid out as struct dimensions below *//*
        !          1180:                int  type;
        !          1181:                };
        !          1182:        typedef struct Vardesc Vardesc;
        !          1183: 
        !          1184:        struct Namelist {
        !          1185:                char *name;
        !          1186:                Vardesc **vars;
        !          1187:                int nvars;
        !          1188:                };
        !          1189: 
        !          1190:        struct dimensions
        !          1191:                {
        !          1192:                ftnlen numberofdimensions;
        !          1193:                ftnlen numberofelements
        !          1194:                ftnlen baseoffset;
        !          1195:                ftnlen span[numberofdimensions-1];
        !          1196:                };
        !          1197: 
        !          1198:    If dims is not null, then the corner element of the array is at
        !          1199:    addr.  However,  the element with subscripts (i1,...,in) is at
        !          1200:    addr + sizeoftype * (i1+span[0]*(i2+span[1]*...) - dimp->baseoffset)
        !          1201: */
        !          1202: 
        !          1203:  static void
        !          1204: write_namelists(nmch, outfile)
        !          1205:  chainp nmch;
        !          1206:  FILE *outfile;
        !          1207: {
        !          1208:        Namep var;
        !          1209:        struct Hashentry *entry;
        !          1210:        struct Dimblock *dimp;
        !          1211:        int i, nd, type;
        !          1212:        char *comma, *name;
        !          1213:        register chainp q;
        !          1214:        register Namep v;
        !          1215:        extern int typeconv[];
        !          1216: 
        !          1217:        nice_printf(outfile, "/* Namelist stuff */\n\n");
        !          1218:        for (entry = hashtab; entry < lasthash; ++entry) {
        !          1219:                if (!(v = entry->varp) || !v->vnamelist)
        !          1220:                        continue;
        !          1221:                type = v->vtype;
        !          1222:                name = v->cvarname;
        !          1223:                if (dimp = v->vdim) {
        !          1224:                        nd = dimp->ndim;
        !          1225:                        nice_printf(outfile,
        !          1226:                                "static ftnlen %s_dims[] = { %d, %ld, %ld",
        !          1227:                                name, nd,
        !          1228:                                dimp->nelt->constblock.Const.ci,
        !          1229:                                dimp->baseoffset->constblock.Const.ci);
        !          1230:                        for(i = 0, --nd; i < nd; i++)
        !          1231:                                nice_printf(outfile, ", %ld",
        !          1232:                                  dimp->dims[i].dimsize->constblock.Const.ci);
        !          1233:                        nice_printf(outfile, " };\n");
        !          1234:                        }
        !          1235:                nice_printf(outfile, "static Vardesc %s_dv = { \"%s\", %s",
        !          1236:                        name, to_upper(v->fvarname),
        !          1237:                        type == TYCHAR ? ""
        !          1238:                                : (dimp || oneof_stg(v,v->vstg,
        !          1239:                                        M(STGEQUIV)|M(STGCOMMON)))
        !          1240:                                ? "(char *)" : "(char *)&");
        !          1241:                out_name(outfile, v);
        !          1242:                nice_printf(outfile, dimp ? ", %s_dims" : ", (ftnlen *)0", name);
        !          1243:                nice_printf(outfile, ", %ld };\n",
        !          1244:                        type != TYCHAR  ? (long)typeconv[type]
        !          1245:                                        : -v->vleng->constblock.Const.ci);
        !          1246:                }
        !          1247: 
        !          1248:        do {
        !          1249:                var = (Namep)nmch->datap;
        !          1250:                name = var->cvarname;
        !          1251:                nice_printf(outfile, "\nstatic Vardesc *%s_vl[] = ", name);
        !          1252:                comma = "{";
        !          1253:                i = 0;
        !          1254:                for(q = var->varxptr.namelist ; q ; q = q->nextp) {
        !          1255:                        v = (Namep)q->datap;
        !          1256:                        if (!v->vnamelist)
        !          1257:                                continue;
        !          1258:                        i++;
        !          1259:                        nice_printf(outfile, "%s &%s_dv", comma, v->cvarname);
        !          1260:                        comma = ",";
        !          1261:                        }
        !          1262:                nice_printf(outfile, " };\n");
        !          1263:                nice_printf(outfile,
        !          1264:                        "static Namelist %s = { \"%s\", %s_vl, %d };\n",
        !          1265:                        name, to_upper(var->fvarname), name, i);
        !          1266:                }
        !          1267:                while(nmch = nmch->nextp);
        !          1268:        nice_printf(outfile, "\n");
        !          1269:        }
        !          1270: 
        !          1271: /* fixextype tries to infer from usage in previous procedures
        !          1272:    the type of an external procedure declared
        !          1273:    external and passed as an argument but never typed or invoked.
        !          1274:  */
        !          1275: 
        !          1276:  static int
        !          1277: fixexttype(var)
        !          1278:  Namep var;
        !          1279: {
        !          1280:        Extsym *e;
        !          1281:        int type, type1;
        !          1282:        extern void changedtype();
        !          1283: 
        !          1284:        type = var->vtype;
        !          1285:        e = &extsymtab[var->vardesc.varno];
        !          1286:        if ((type1 = e->extype) && type == TYUNKNOWN)
        !          1287:                return var->vtype = type1;
        !          1288:        if (var->visused) {
        !          1289:                if (e->exused && type != type1)
        !          1290:                        changedtype(var);
        !          1291:                e->exused = 1;
        !          1292:                e->extype = type;
        !          1293:                }
        !          1294:        return type;
        !          1295:        }
        !          1296: 
        !          1297:  static void
        !          1298: ref_defs(outfile, refdefs) FILE *outfile; chainp refdefs;
        !          1299: {
        !          1300:        chainp cp;
        !          1301:        int eb, i, j, n;
        !          1302:        struct Dimblock *dimp;
        !          1303:        long L;
        !          1304:        expptr b, vl;
        !          1305:        Namep var;
        !          1306:        char *amp, *comma;
        !          1307: 
        !          1308:        ind_printf(0, outfile, "\n");
        !          1309:        for(cp = refdefs = revchain(refdefs); cp; cp = cp->nextp) {
        !          1310:                var = (Namep)cp->datap;
        !          1311:                cp->datap = 0;
        !          1312:                amp = "_subscr";
        !          1313:                if (!(eb = var->vsubscrused)) {
        !          1314:                        var->vrefused = 0;
        !          1315:                        if (!ISCOMPLEX(var->vtype))
        !          1316:                                amp = "_ref";
        !          1317:                        }
        !          1318:                def_start(outfile, var->cvarname, amp, CNULL);
        !          1319:                dimp = var->vdim;
        !          1320:                vl = 0;
        !          1321:                comma = "(";
        !          1322:                amp = "";
        !          1323:                if (var->vtype == TYCHAR) {
        !          1324:                        amp = "&";
        !          1325:                        vl = var->vleng;
        !          1326:                        if (ISCONST(vl) && vl->constblock.Const.ci == 1)
        !          1327:                                vl = 0;
        !          1328:                        nice_printf(outfile, "%sa_0", comma);
        !          1329:                        comma = ",";
        !          1330:                        }
        !          1331:                n = dimp->ndim;
        !          1332:                for(i = 1; i <= n; i++, comma = ",")
        !          1333:                        nice_printf(outfile, "%sa_%d", comma, i);
        !          1334:                nice_printf(outfile, ") %s", amp);
        !          1335:                if (var->vsubscrused)
        !          1336:                        var->vsubscrused = 0;
        !          1337:                else if (!ISCOMPLEX(var->vtype)) {
        !          1338:                        out_name(outfile, var);
        !          1339:                        nice_printf(outfile, "[%s", vl ? "(" : "");
        !          1340:                        }
        !          1341:                for(j = 2; j < n; j++)
        !          1342:                        nice_printf(outfile, "(");
        !          1343:                while(--i > 1) {
        !          1344:                        nice_printf(outfile, "(a_%d)%s*", i, i == n ? "" : ")");
        !          1345:                        expr_out(outfile, cpexpr(dimp->dims[i-2].dimsize));
        !          1346:                        nice_printf(outfile, " + ");
        !          1347:                        }
        !          1348:                nice_printf(outfile, "a_1");
        !          1349:                if (var->vtype == TYCHAR) {
        !          1350:                        if (vl) {
        !          1351:                                nice_printf(outfile, ")*");
        !          1352:                                expr_out(outfile, cpexpr(vl));
        !          1353:                                }
        !          1354:                        nice_printf(outfile, " + a_0");
        !          1355:                        }
        !          1356:                if (var->vstg != STGARG && (b = dimp->baseoffset)) {
        !          1357:                        b = cpexpr(b);
        !          1358:                        if (var->vtype == TYCHAR)
        !          1359:                                b = mkexpr(OPSTAR, cpexpr(var->vleng), b);
        !          1360:                        nice_printf(outfile, " - ");
        !          1361:                        expr_out(outfile, b);
        !          1362:                        }
        !          1363:                if (ISCOMPLEX(var->vtype)) {
        !          1364:                        ind_printf(0, outfile, "\n");
        !          1365:                        def_start(outfile, var->cvarname, "_ref", CNULL);
        !          1366:                        comma = "(";
        !          1367:                        for(i = 1; i <= n; i++, comma = ",")
        !          1368:                                nice_printf(outfile, "%sa_%d", comma, i);
        !          1369:                        nice_printf(outfile, ") %s[%s_subscr",
        !          1370:                                var->cvarname, var->cvarname);
        !          1371:                        comma = "(";
        !          1372:                        for(i = 1; i <= n; i++, comma = ",")
        !          1373:                                nice_printf(outfile, "%sa_%d", comma, i);
        !          1374:                        nice_printf(outfile, ")");
        !          1375:                        }
        !          1376:                ind_printf(0, outfile, "]\n" + eb);
        !          1377:                }
        !          1378:        nice_printf(outfile, "\n");
        !          1379:        frchain(refdefs);
        !          1380:        }
        !          1381: 
        !          1382: list_decls (outfile)
        !          1383: FILE *outfile;
        !          1384: {
        !          1385:     extern chainp used_builtins;
        !          1386:     extern struct Hashentry *hashtab;
        !          1387:     extern ftnint wr_char_len();
        !          1388:     struct Hashentry *entry;
        !          1389:     int write_header = 1;
        !          1390:     int last_class = -1, last_stg = -1;
        !          1391:     Namep var;
        !          1392:     int Alias, Define, did_one, last_type, type;
        !          1393:     extern int def_equivs, useauto;
        !          1394:     extern chainp new_vars;    /* Compiler-generated locals */
        !          1395:     chainp namelists = 0, refdefs = 0;
        !          1396:     char *ctype;
        !          1397:     int useauto1 = useauto && !saveall;
        !          1398:     long x;
        !          1399:     extern int hsize;
        !          1400: 
        !          1401: /* First write out the statically initialized data */
        !          1402: 
        !          1403:     if (initfile)
        !          1404:        list_init_data(&initfile, initfname, outfile);
        !          1405: 
        !          1406: /* Next come formats */
        !          1407:     write_formats(outfile);
        !          1408: 
        !          1409: /* Now write out the system-generated identifiers */
        !          1410: 
        !          1411:     if (new_vars || nequiv) {
        !          1412:        chainp args, next_var, this_var;
        !          1413:        chainp nv[TYVOID], nv1[TYVOID];
        !          1414:        int i, j;
        !          1415:        Addrp Var;
        !          1416:        Namep arg;
        !          1417: 
        !          1418:        /* zap unused dimension variables */
        !          1419: 
        !          1420:        for(args = allargs; args; args = args->nextp) {
        !          1421:                arg = (Namep)args->datap;
        !          1422:                if (this_var = arg->vlastdim) {
        !          1423:                        frexpr((tagptr)this_var->datap);
        !          1424:                        this_var->datap = 0;
        !          1425:                        }
        !          1426:                }
        !          1427: 
        !          1428:        /* sort new_vars by type, skipping entries just zapped */
        !          1429: 
        !          1430:        for(i = TYADDR; i < TYVOID; i++)
        !          1431:                nv[i] = 0;
        !          1432:        for(this_var = new_vars; this_var; this_var = next_var) {
        !          1433:                next_var = this_var->nextp;
        !          1434:                if (Var = (Addrp)this_var->datap) {
        !          1435:                        if (!(this_var->nextp = nv[j = Var->vtype]))
        !          1436:                                nv1[j] = this_var;
        !          1437:                        nv[j] = this_var;
        !          1438:                        }
        !          1439:                else {
        !          1440:                        this_var->nextp = 0;
        !          1441:                        frchain(&this_var);
        !          1442:                        }
        !          1443:                }
        !          1444:        new_vars = 0;
        !          1445:        for(i = TYVOID; --i >= TYADDR;)
        !          1446:                if (this_var = nv[i]) {
        !          1447:                        nv1[i]->nextp = new_vars;
        !          1448:                        new_vars = this_var;
        !          1449:                        }
        !          1450: 
        !          1451:        /* write the declarations */
        !          1452: 
        !          1453:        did_one = 0;
        !          1454:        last_type = -1;
        !          1455: 
        !          1456:        for (this_var = new_vars; this_var; this_var = this_var -> nextp) {
        !          1457:            Var = (Addrp) this_var->datap;
        !          1458: 
        !          1459:            if (Var == (Addrp) NULL)
        !          1460:                err ("list_decls:  null variable");
        !          1461:            else if (Var -> tag != TADDR)
        !          1462:                erri ("list_decls:  bad tag on new variable '%d'",
        !          1463:                        Var -> tag);
        !          1464: 
        !          1465:            type = nv_type (Var);
        !          1466:            if (Var->vstg == STGINIT
        !          1467:            ||  Var->uname_tag == UNAM_IDENT
        !          1468:                        && *Var->user.ident == ' '
        !          1469:                        && multitype)
        !          1470:                continue;
        !          1471:            if (!did_one)
        !          1472:                nice_printf (outfile, "/* System generated locals */\n");
        !          1473: 
        !          1474:            if (last_type == type && did_one)
        !          1475:                nice_printf (outfile, ", ");
        !          1476:            else {
        !          1477:                if (did_one)
        !          1478:                    nice_printf (outfile, ";\n");
        !          1479:                nice_printf (outfile, "%s ",
        !          1480:                        c_type_decl (type, Var -> vclass == CLPROC));
        !          1481:            } /* else */
        !          1482: 
        !          1483: /* Character type is really a string type.  Put out a '*' for parameters
        !          1484:    with unknown length and functions returning character */
        !          1485: 
        !          1486:            if (Var -> vtype == TYCHAR && (!ISICON ((Var -> vleng))
        !          1487:                    || Var -> vclass == CLPROC))
        !          1488:                nice_printf (outfile, "*");
        !          1489: 
        !          1490:            write_nv_ident(outfile, (Addrp)this_var->datap);
        !          1491:            if (Var -> vtype == TYCHAR && Var->vclass != CLPROC &&
        !          1492:                    ISICON((Var -> vleng))
        !          1493:                        && (i = Var->vleng->constblock.Const.ci) > 0)
        !          1494:                nice_printf (outfile, "[%d]", i);
        !          1495: 
        !          1496:            did_one = 1;
        !          1497:            last_type = nv_type (Var);
        !          1498:        } /* for this_var */
        !          1499: 
        !          1500: /* Handle the uninitialized equivalences */
        !          1501: 
        !          1502:        do_uninit_equivs (outfile, &did_one);
        !          1503: 
        !          1504:        if (did_one)
        !          1505:            nice_printf (outfile, ";\n\n");
        !          1506:     } /* if new_vars */
        !          1507: 
        !          1508: /* Write out builtin declarations */
        !          1509: 
        !          1510:     if (used_builtins) {
        !          1511:        chainp cp;
        !          1512:        Extsym *es;
        !          1513: 
        !          1514:        last_type = -1;
        !          1515:        did_one = 0;
        !          1516: 
        !          1517:        nice_printf (outfile, "/* Builtin functions */");
        !          1518: 
        !          1519:        for (cp = used_builtins; cp; cp = cp -> nextp) {
        !          1520:            Addrp e = (Addrp)cp->datap;
        !          1521: 
        !          1522:            switch(type = e->vtype) {
        !          1523:                case TYDREAL:
        !          1524:                case TYREAL:
        !          1525:                        /* if (forcedouble || e->dbl_builtin) */
        !          1526:                        /* libF77 currently assumes everything double */
        !          1527:                        type = TYDREAL;
        !          1528:                        ctype = "double";
        !          1529:                        break;
        !          1530:                case TYCOMPLEX:
        !          1531:                case TYDCOMPLEX:
        !          1532:                        type = TYVOID;
        !          1533:                        /* no break */
        !          1534:                default:
        !          1535:                        ctype = c_type_decl(type, 0);
        !          1536:                }
        !          1537: 
        !          1538:            if (did_one && last_type == type)
        !          1539:                nice_printf(outfile, ", ");
        !          1540:            else
        !          1541:                nice_printf(outfile, "%s\n%s ", did_one ? ";" : "", ctype);
        !          1542: 
        !          1543:            extern_out(outfile, es = &extsymtab[e -> memno]);
        !          1544:            proto(outfile, es->arginfo, es->fextname);
        !          1545:            last_type = type;
        !          1546:            did_one = 1;
        !          1547:        } /* for cp = used_builtins */
        !          1548: 
        !          1549:        nice_printf (outfile, ";\n\n");
        !          1550:     } /* if used_builtins */
        !          1551: 
        !          1552:     last_type = -1;
        !          1553:     for (entry = hashtab; entry < lasthash; ++entry) {
        !          1554:        var = entry -> varp;
        !          1555: 
        !          1556:        if (var) {
        !          1557:            int procclass = var -> vprocclass;
        !          1558:            char *comment = NULL;
        !          1559:            int stg = var -> vstg;
        !          1560:            int class = var -> vclass;
        !          1561:            type = var -> vtype;
        !          1562: 
        !          1563:            if (var->vrefused)
        !          1564:                refdefs = mkchain((char *)var, refdefs);
        !          1565:            if (var->vsubscrused)
        !          1566:                if (ISCOMPLEX(var->vtype))
        !          1567:                        var->vsubscrused = 0;
        !          1568:                else
        !          1569:                        refdefs = mkchain((char *)var, refdefs);
        !          1570:            if (ONEOF(stg, M(STGARG)|M(STGLENG)|M(STGINIT)))
        !          1571:                continue;
        !          1572: 
        !          1573:            if (useauto1 && stg == STGBSS && !var->vsave)
        !          1574:                stg = STGAUTO;
        !          1575: 
        !          1576:            switch (class) {
        !          1577:                case CLVAR:
        !          1578:                    break;
        !          1579:                case CLPROC:
        !          1580:                    switch(procclass) {
        !          1581:                        case PTHISPROC:
        !          1582:                                extsymtab[var->vardesc.varno].extype = type;
        !          1583:                                continue;
        !          1584:                        case PSTFUNCT:
        !          1585:                        case PINTRINSIC:
        !          1586:                                continue;
        !          1587:                        case PUNKNOWN:
        !          1588:                                err ("list_decls:  unknown procedure class");
        !          1589:                                continue;
        !          1590:                        case PEXTERNAL:
        !          1591:                                if (stg == STGUNKNOWN) {
        !          1592:                                        warn1(
        !          1593:                                        "%.64s declared EXTERNAL but never used.",
        !          1594:                                                var->fvarname);
        !          1595:                                        /* to retain names declared EXTERNAL */
        !          1596:                                        /* but not referenced, change
        !          1597:                                        /* "continue" to "stg = STGEXT" */
        !          1598:                                        continue;
        !          1599:                                        }
        !          1600:                                else
        !          1601:                                        type = fixexttype(var);
        !          1602:                        }
        !          1603:                    break;
        !          1604:                case CLUNKNOWN:
        !          1605:                        /* declared but never used */
        !          1606:                        continue;
        !          1607:                case CLPARAM:
        !          1608:                        continue;
        !          1609:                case CLNAMELIST:
        !          1610:                        if (var->visused)
        !          1611:                                namelists = mkchain((char *)var, namelists);
        !          1612:                        continue;
        !          1613:                default:
        !          1614:                    erri("list_decls:  can't handle class '%d' yet",
        !          1615:                            class);
        !          1616:                    Fatal(var->fvarname);
        !          1617:                    continue;
        !          1618:            } /* switch */
        !          1619: 
        !          1620:            /* Might be equivalenced to a common.  If not, don't process */
        !          1621:            if (stg == STGCOMMON && !var->vcommequiv)
        !          1622:                continue;
        !          1623: 
        !          1624: /* Only write the header if system-generated locals, builtins, or
        !          1625:    uninitialized equivs were already output */
        !          1626: 
        !          1627:            if (write_header == 1 && (new_vars || nequiv || used_builtins)
        !          1628:                    && oneof_stg ( var, stg,
        !          1629:                    M(STGBSS)|M(STGEXT)|M(STGAUTO)|M(STGCOMMON)|M(STGEQUIV))) {
        !          1630:                nice_printf (outfile, "/* Local variables */\n");
        !          1631:                write_header = 2;
        !          1632:                }
        !          1633: 
        !          1634: 
        !          1635:            Alias = oneof_stg(var, stg, M(STGEQUIV)|M(STGCOMMON));
        !          1636:            if (Define = (Alias && def_equivs)) {
        !          1637:                if (!write_header)
        !          1638:                        nice_printf(outfile, ";\n");
        !          1639:                def_start(outfile, var->cvarname, CNULL, "(");
        !          1640:                goto Alias1;
        !          1641:                }
        !          1642:            else if (type == last_type && class == last_class &&
        !          1643:                    stg == last_stg && !write_header)
        !          1644:                nice_printf (outfile, ", ");
        !          1645:            else {
        !          1646:                if (!write_header && ONEOF(stg, M(STGBSS)|
        !          1647:                    M(STGEXT)|M(STGAUTO)|M(STGEQUIV)|M(STGCOMMON)))
        !          1648:                    nice_printf (outfile, ";\n");
        !          1649: 
        !          1650:                switch (stg) {
        !          1651:                    case STGARG:
        !          1652:                    case STGLENG:
        !          1653:                        /* Part of the argument list, don't write them out
        !          1654:                           again */
        !          1655:                        continue;           /* Go back to top of the loop */
        !          1656:                    case STGBSS:
        !          1657:                    case STGEQUIV:
        !          1658:                    case STGCOMMON:
        !          1659:                        nice_printf (outfile, "static ");
        !          1660:                        break;
        !          1661:                    case STGEXT:
        !          1662:                        nice_printf (outfile, "extern ");
        !          1663:                        break;
        !          1664:                    case STGAUTO:
        !          1665:                        break;
        !          1666:                    case STGINIT:
        !          1667:                    case STGUNKNOWN:
        !          1668:                        /* Don't want to touch the initialized data, that will
        !          1669:                           be handled elsewhere.  Unknown data have
        !          1670:                           already been complained about, so skip them */
        !          1671:                        continue;
        !          1672:                    default:
        !          1673:                        erri("list_decls:  can't handle storage class %d",
        !          1674:                                stg);
        !          1675:                        continue;
        !          1676:                } /* switch */
        !          1677: 
        !          1678:                if (type == TYCHAR && halign && class != CLPROC
        !          1679:                && ISICON(var->vleng)) {
        !          1680:                        nice_printf(outfile, "struct { %s fill; char val",
        !          1681:                                halign);
        !          1682:                        x = wr_char_len(outfile, var->vdim,
        !          1683:                                var->vleng->constblock.Const.ci, 1);
        !          1684:                        if (x %= hsize)
        !          1685:                                nice_printf(outfile, "; char fill2[%ld]",
        !          1686:                                        hsize - x);
        !          1687:                        nice_printf(outfile, "; } %s_st;\n", var->cvarname);
        !          1688:                        def_start(outfile, var->cvarname, CNULL, var->cvarname);
        !          1689:                        ind_printf(0, outfile, "_st.val\n");
        !          1690:                        last_type = -1;
        !          1691:                        write_header = 2;
        !          1692:                        continue;
        !          1693:                        }
        !          1694:                nice_printf(outfile, "%s ",
        !          1695:                        c_type_decl(type, class == CLPROC));
        !          1696:            } /* else */
        !          1697: 
        !          1698: /* Character type is really a string type.  Put out a '*' for variable
        !          1699:    length strings, and also for equivalences */
        !          1700: 
        !          1701:            if (type == TYCHAR && class != CLPROC
        !          1702:                    && (!var->vleng || !ISICON (var -> vleng))
        !          1703:            || oneof_stg(var, stg, M(STGEQUIV)|M(STGCOMMON)))
        !          1704:                nice_printf (outfile, "*%s", var->cvarname);
        !          1705:            else {
        !          1706:                nice_printf (outfile, "%s", var->cvarname);
        !          1707:                if (class == CLPROC) {
        !          1708:                        Argtypes *at;
        !          1709:                        if (!(at = var->arginfo)
        !          1710:                         && var->vprocclass == PEXTERNAL)
        !          1711:                                at = extsymtab[var->vardesc.varno].arginfo;
        !          1712:                        proto(outfile, at, var->fvarname);
        !          1713:                        }
        !          1714:                else if (type == TYCHAR && ISICON ((var -> vleng)))
        !          1715:                        wr_char_len(outfile, var->vdim,
        !          1716:                                (int)var->vleng->constblock.Const.ci, 0);
        !          1717:                else if (var -> vdim &&
        !          1718:                    !oneof_stg (var, stg, M(STGEQUIV)|M(STGCOMMON)))
        !          1719:                        comment = wr_ardecls(outfile, var->vdim, 1L);
        !          1720:                }
        !          1721: 
        !          1722:            if (comment)
        !          1723:                nice_printf (outfile, "%s", comment);
        !          1724:  Alias1:
        !          1725:            if (Alias) {
        !          1726:                char *amp, *lp, *name, *rp;
        !          1727:                char *equiv_name ();
        !          1728:                ftnint voff = var -> voffset;
        !          1729:                int et0, expr_type, k;
        !          1730:                Extsym *E;
        !          1731:                struct Equivblock *eb;
        !          1732:                char buf[16];
        !          1733: 
        !          1734: /* We DON'T want to use oneof_stg here, because we need to distinguish
        !          1735:    between them */
        !          1736: 
        !          1737:                if (stg == STGEQUIV) {
        !          1738:                        name = equiv_name(k = var->vardesc.varno, CNULL);
        !          1739:                        eb = eqvclass + k;
        !          1740:                        if (eb->eqvinit) {
        !          1741:                                amp = "&";
        !          1742:                                et0 = TYERROR;
        !          1743:                                }
        !          1744:                        else {
        !          1745:                                amp = "";
        !          1746:                                et0 = eb->eqvtype;
        !          1747:                                }
        !          1748:                        expr_type = et0;
        !          1749:                    }
        !          1750:                else {
        !          1751:                        E = &extsymtab[var->vardesc.varno];
        !          1752:                        sprintf(name = buf, "%s%d", E->cextname, E->curno);
        !          1753:                        expr_type = type;
        !          1754:                        et0 = -1;
        !          1755:                        amp = "&";
        !          1756:                } /* else */
        !          1757: 
        !          1758:                if (!Define)
        !          1759:                        nice_printf (outfile, " = ");
        !          1760:                if (voff) {
        !          1761:                        k = typesize[type];
        !          1762:                        switch((int)(voff % k)) {
        !          1763:                                case 0:
        !          1764:                                        voff /= k;
        !          1765:                                        expr_type = type;
        !          1766:                                        break;
        !          1767:                                case SZSHORT:
        !          1768:                                case SZSHORT+SZLONG:
        !          1769:                                        expr_type = TYSHORT;
        !          1770:                                        voff /= SZSHORT;
        !          1771:                                        break;
        !          1772:                                case SZLONG:
        !          1773:                                        expr_type = TYLONG;
        !          1774:                                        voff /= SZLONG;
        !          1775:                                        break;
        !          1776:                                default:
        !          1777:                                        expr_type = TYCHAR;
        !          1778:                                }
        !          1779:                        }
        !          1780: 
        !          1781:                if (expr_type == type) {
        !          1782:                        lp = rp = "";
        !          1783:                        if (et0 == -1 && !voff)
        !          1784:                                goto cast;
        !          1785:                        }
        !          1786:                else {
        !          1787:                        lp = "(";
        !          1788:                        rp = ")";
        !          1789:  cast:
        !          1790:                        nice_printf(outfile, "(%s *)", c_type_decl(type, 0));
        !          1791:                        }
        !          1792: 
        !          1793: /* Now worry about computing the offset */
        !          1794: 
        !          1795:                if (voff) {
        !          1796:                    if (expr_type == et0)
        !          1797:                        nice_printf (outfile, "%s%s + %ld%s",
        !          1798:                                lp, name, voff, rp);
        !          1799:                    else
        !          1800:                        nice_printf(outfile, "%s(%s *)%s%s + %ld%s", lp,
        !          1801:                                c_type_decl (expr_type, 0), amp,
        !          1802:                                name, voff, rp);
        !          1803:                } else
        !          1804:                    nice_printf(outfile, "%s%s", amp, name);
        !          1805: /* Always put these at the end of the line */
        !          1806:                last_type = last_class = last_stg = -1;
        !          1807:                write_header = 0;
        !          1808:                if (Define) {
        !          1809:                        ind_printf(0, outfile, ")\n");
        !          1810:                        write_header = 2;
        !          1811:                        }
        !          1812:                continue;
        !          1813:                }
        !          1814:            write_header = 0;
        !          1815:            last_type = type;
        !          1816:            last_class = class;
        !          1817:            last_stg = stg;
        !          1818:        } /* if (var) */
        !          1819:     } /* for (entry = hashtab */
        !          1820: 
        !          1821:     if (!write_header)
        !          1822:        nice_printf (outfile, ";\n\n");
        !          1823:     else if (write_header == 2)
        !          1824:        nice_printf(outfile, "\n");
        !          1825: 
        !          1826: /* Next, namelists, which may reference equivs */
        !          1827: 
        !          1828:     if (namelists) {
        !          1829:        write_namelists(namelists = revchain(namelists), outfile);
        !          1830:        frchain(&namelists);
        !          1831:        }
        !          1832: 
        !          1833: /* Finally, ioblocks (which may reference equivs and namelists) */
        !          1834:     if (iob_list)
        !          1835:        write_ioblocks(outfile);
        !          1836:     if (assigned_fmts)
        !          1837:        write_assigned_fmts(outfile);
        !          1838: 
        !          1839:     if (refdefs)
        !          1840:        ref_defs(outfile, refdefs);
        !          1841: 
        !          1842: } /* list_decls */
        !          1843: 
        !          1844: do_uninit_equivs (outfile, did_one)
        !          1845: FILE *outfile;
        !          1846: int *did_one;
        !          1847: {
        !          1848:     extern int nequiv;
        !          1849:     struct Equivblock *eqv, *lasteqv = eqvclass + nequiv;
        !          1850:     int k, last_type = -1, t;
        !          1851: 
        !          1852:     for (eqv = eqvclass; eqv < lasteqv; eqv++)
        !          1853:        if (!eqv -> eqvinit && eqv -> eqvtop != eqv -> eqvbottom) {
        !          1854:            if (!*did_one)
        !          1855:                nice_printf (outfile, "/* System generated locals */\n");
        !          1856:            t = eqv->eqvtype;
        !          1857:            if (last_type == t)
        !          1858:                nice_printf (outfile, ", ");
        !          1859:            else {
        !          1860:                if (*did_one)
        !          1861:                    nice_printf (outfile, ";\n");
        !          1862:                nice_printf (outfile, "static %s ", c_type_decl(t, 0));
        !          1863:                k = typesize[t];
        !          1864:            } /* else */
        !          1865:            nice_printf(outfile, "%s", equiv_name((int)(eqv - eqvclass), CNULL));
        !          1866:            nice_printf(outfile, "[%ld]",
        !          1867:                (eqv->eqvtop - eqv->eqvbottom + k - 1) / k);
        !          1868:            last_type = t;
        !          1869:            *did_one = 1;
        !          1870:        } /* if !eqv -> eqvinit */
        !          1871: } /* do_uninit_equivs */
        !          1872: 
        !          1873: 
        !          1874: /* wr_ardecls -- Writes the brackets and size for an array
        !          1875:    declaration.  Because of the inner workings of the compiler,
        !          1876:    multi-dimensional arrays get mapped directly into a one-dimensional
        !          1877:    array, so we have to compute the size of the array here.  When the
        !          1878:    dimension is greater than 1, a string comment about the original size
        !          1879:    is returned */
        !          1880: 
        !          1881: char *wr_ardecls(outfile, dimp, size)
        !          1882: FILE *outfile;
        !          1883: struct Dimblock *dimp;
        !          1884: long size;
        !          1885: {
        !          1886:     int i, k;
        !          1887:     static char buf[1000];
        !          1888: 
        !          1889:     if (dimp == (struct Dimblock *) NULL)
        !          1890:        return NULL;
        !          1891: 
        !          1892:     sprintf(buf, "\t/* was "); /* would like to say  k = sprintf(...), but */
        !          1893:     k = strlen(buf);           /* BSD doesn't return char transmitted count */
        !          1894: 
        !          1895:     for (i = 0; i < dimp -> ndim; i++) {
        !          1896:        expptr this_size = dimp -> dims[i].dimsize;
        !          1897: 
        !          1898:        if (!ISICON (this_size))
        !          1899:            err ("wr_ardecls:  nonconstant array size");
        !          1900:        else {
        !          1901:            size *= this_size -> constblock.Const.ci;
        !          1902:            sprintf(buf+k, "[%ld]", this_size -> constblock.Const.ci);
        !          1903:            k += strlen(buf+k); /* BSD prevents combining this with prev stmt */
        !          1904:        } /* else */
        !          1905:     } /* for i = 0 */
        !          1906: 
        !          1907:     nice_printf (outfile, "[%ld]", size);
        !          1908:     strcat(buf+k, " */");
        !          1909: 
        !          1910:     return (i > 1) ? buf : NULL;
        !          1911: } /* wr_ardecls */
        !          1912: 
        !          1913: 
        !          1914: 
        !          1915: /* ----------------------------------------------------------------------
        !          1916: 
        !          1917:        The following routines read from the p1 intermediate file.  If
        !          1918:    that format changes, only these routines need be changed
        !          1919: 
        !          1920:    ---------------------------------------------------------------------- */
        !          1921: 
        !          1922: static int get_p1_token (infile)
        !          1923: FILE *infile;
        !          1924: {
        !          1925:     int token = P1_UNKNOWN;
        !          1926: 
        !          1927: /* NOT PORTABLE!! */
        !          1928: 
        !          1929:     if (fscanf (infile, "%d", &token) == EOF)
        !          1930:        return P1_EOF;
        !          1931: 
        !          1932: /* Skip over the ": " */
        !          1933: 
        !          1934:     if (getc (infile) != '\n')
        !          1935:        getc (infile);
        !          1936: 
        !          1937:     return token;
        !          1938: } /* get_p1_token */
        !          1939: 
        !          1940: 
        !          1941: 
        !          1942: /* Returns a (null terminated) string from the input file */
        !          1943: 
        !          1944: static int p1gets (fp, str, size)
        !          1945: FILE *fp;
        !          1946: char *str;
        !          1947: int size;
        !          1948: {
        !          1949:     char *fgets ();
        !          1950:     char c;
        !          1951: 
        !          1952:     if (str == NULL)
        !          1953:        return 0;
        !          1954: 
        !          1955:     if ((c = getc (fp)) != ' ')
        !          1956:        ungetc (c, fp);
        !          1957: 
        !          1958:     if (fgets (str, size, fp)) {
        !          1959:        int length;
        !          1960: 
        !          1961:        str[size - 1] = '\0';
        !          1962:        length = strlen (str);
        !          1963: 
        !          1964: /* Get rid of the newline */
        !          1965: 
        !          1966:        if (str[length - 1] == '\n')
        !          1967:            str[length - 1] = '\0';
        !          1968:        return 1;
        !          1969: 
        !          1970:     } else if (feof (fp))
        !          1971:        return EOF;
        !          1972:     else
        !          1973:        return 0;
        !          1974: } /* p1gets */
        !          1975: 
        !          1976: 
        !          1977: static int p1get_const (infile, type, resultp)
        !          1978: FILE *infile;
        !          1979: int type;
        !          1980: struct Constblock **resultp;
        !          1981: {
        !          1982:     int status;
        !          1983:     struct Constblock *result;
        !          1984: 
        !          1985:        if (type != TYCHAR) {
        !          1986:                *resultp = result = ALLOC(Constblock);
        !          1987:                result -> tag = TCONST;
        !          1988:                result -> vtype = type;
        !          1989:                }
        !          1990: 
        !          1991:     switch (type) {
        !          1992:        case TYINT1:
        !          1993:         case TYSHORT:
        !          1994:        case TYLONG:
        !          1995:        case TYLOGICAL:
        !          1996: #ifdef TYQUAD
        !          1997:        case TYQUAD:
        !          1998: #endif
        !          1999:        case TYLOGICAL1:
        !          2000:        case TYLOGICAL2:
        !          2001:            status = p1getd (infile, &(result -> Const.ci));
        !          2002:            break;
        !          2003:        case TYREAL:
        !          2004:        case TYDREAL:
        !          2005:            status = p1getf(infile, &result->Const.cds[0]);
        !          2006:            result->vstg = 1;
        !          2007:            break;
        !          2008:        case TYCOMPLEX:
        !          2009:        case TYDCOMPLEX:
        !          2010:            status = p1getf(infile, &result->Const.cds[0]);
        !          2011:            if (status && status != EOF)
        !          2012:                status = p1getf(infile, &result->Const.cds[1]);
        !          2013:            result->vstg = 1;
        !          2014:            break;
        !          2015:        case TYCHAR:
        !          2016:            status = fscanf(infile, "%lx", resultp);
        !          2017:            break;
        !          2018:        default:
        !          2019:            erri ("p1get_const:  bad constant type '%d'", type);
        !          2020:            status = 0;
        !          2021:            break;
        !          2022:     } /* switch */
        !          2023: 
        !          2024:     return status;
        !          2025: } /* p1get_const */
        !          2026: 
        !          2027: static int p1getd (infile, result)
        !          2028: FILE *infile;
        !          2029: long *result;
        !          2030: {
        !          2031:     return fscanf (infile, "%ld", result);
        !          2032: } /* p1getd */
        !          2033: 
        !          2034:  static int
        !          2035: p1getf(infile, result)
        !          2036:  FILE *infile;
        !          2037:  char **result;
        !          2038: {
        !          2039: 
        !          2040:        char buf[1324];
        !          2041:        register int k;
        !          2042: 
        !          2043:        k = fscanf (infile, "%s", buf);
        !          2044:        if (k < 1)
        !          2045:                k = EOF;
        !          2046:        else
        !          2047:                strcpy(*result = mem(strlen(buf)+1,0), buf);
        !          2048:        return k;
        !          2049: }
        !          2050: 
        !          2051: static int p1getn (infile, count, result)
        !          2052: FILE *infile;
        !          2053: int count;
        !          2054: char **result;
        !          2055: {
        !          2056: 
        !          2057:     char *bufptr;
        !          2058:     extern ptr ckalloc ();
        !          2059: 
        !          2060:     bufptr = (char *) ckalloc (count);
        !          2061: 
        !          2062:     if (result)
        !          2063:        *result = bufptr;
        !          2064: 
        !          2065:     for (; !feof (infile) && count > 0; count--)
        !          2066:        *bufptr++ = getc (infile);
        !          2067: 
        !          2068:     return feof (infile) ? EOF : 1;
        !          2069: } /* p1getn */
        !          2070: 
        !          2071:  static void
        !          2072: proto(outfile, at, fname)
        !          2073:  FILE *outfile;
        !          2074:  Argtypes *at;
        !          2075:  char *fname;
        !          2076: {
        !          2077:        int i, j, k, n;
        !          2078:        char *comma;
        !          2079:        Atype *atypes;
        !          2080:        Namep np;
        !          2081:        chainp cp;
        !          2082:        extern void bad_atypes();
        !          2083: 
        !          2084:        if (at) {
        !          2085:                /* Correct types that we learn on the fly, e.g.
        !          2086:                        subroutine gotcha(foo)
        !          2087:                        external foo
        !          2088:                        call zap(...,foo,...)
        !          2089:                        call foo(...)
        !          2090:                */
        !          2091:                atypes = at->atypes;
        !          2092:                n = at->defined ? at->dnargs : at->nargs;
        !          2093:                for(i = 0; i++ < n; atypes++) {
        !          2094:                        if (!(cp = atypes->cp))
        !          2095:                                continue;
        !          2096:                        j = atypes->type;
        !          2097:                        do {
        !          2098:                                np = (Namep)cp->datap;
        !          2099:                                k = np->vtype;
        !          2100:                                if (np->vclass == CLPROC) {
        !          2101:                                        if (!np->vimpltype && k)
        !          2102:                                                k += 200;
        !          2103:                                        else {
        !          2104:                                                if (j >= 300)
        !          2105:                                                        j = TYUNKNOWN + 200;
        !          2106:                                                continue;
        !          2107:                                                }
        !          2108:                                        }
        !          2109:                                if (j == k)
        !          2110:                                        continue;
        !          2111:                                if (j >= 300
        !          2112:                                ||  j == 200 && k >= 200)
        !          2113:                                        j = k;
        !          2114:                                else {
        !          2115:                                        if (at->nargs >= 0)
        !          2116:                                           bad_atypes(at,fname,i,j,k,""," and");
        !          2117:                                        goto break2;
        !          2118:                                        }
        !          2119:                                }
        !          2120:                                while(cp = cp->nextp);
        !          2121:                        atypes->type = j;
        !          2122:                        frchain(&atypes->cp);
        !          2123:                        }
        !          2124:                }
        !          2125:  break2:
        !          2126:        if (parens) {
        !          2127:                nice_printf(outfile, parens);
        !          2128:                return;
        !          2129:                }
        !          2130: 
        !          2131:        if (!at || (n = at-> defined ? at->dnargs : at->nargs) < 0) {
        !          2132:                nice_printf(outfile, Ansi == 1 ? "()" : "(...)");
        !          2133:                return;
        !          2134:                }
        !          2135: 
        !          2136:        if (n == 0) {
        !          2137:                nice_printf(outfile, Ansi == 1 ? "(void)" : "()");
        !          2138:                return;
        !          2139:                }
        !          2140: 
        !          2141:        atypes = at->atypes;
        !          2142:        nice_printf(outfile, "(");
        !          2143:        comma = "";
        !          2144:        for(; --n >= 0; atypes++) {
        !          2145:                k = atypes->type;
        !          2146:                if (k == TYADDR)
        !          2147:                        nice_printf(outfile, "%schar **", comma);
        !          2148:                else if (k >= 200) {
        !          2149:                        k -= 200;
        !          2150:                        nice_printf(outfile, "%s%s", comma,
        !          2151:                                usedcasts[k] = casttypes[k]);
        !          2152:                        }
        !          2153:                else if (k >= 100)
        !          2154:                        nice_printf(outfile,
        !          2155:                                        k == TYCHAR + 100 ? "%s%s *" : "%s%s",
        !          2156:                                        comma, c_type_decl(k-100, 0));
        !          2157:                else
        !          2158:                        nice_printf(outfile, "%s%s *", comma,
        !          2159:                                        c_type_decl(k, 0));
        !          2160:                comma = ", ";
        !          2161:                }
        !          2162:        nice_printf(outfile, ")");
        !          2163:        }
        !          2164: 
        !          2165:  void
        !          2166: protowrite(protofile, type, name, e, lengths)
        !          2167:  FILE *protofile;
        !          2168:  char *name;
        !          2169:  struct Entrypoint *e;
        !          2170:  chainp lengths;
        !          2171: {
        !          2172:        extern char used_rets[];
        !          2173:        int asave;
        !          2174: 
        !          2175:        if (!(asave = Ansi))
        !          2176:                Castargs = Ansi = 1;
        !          2177:        nice_printf(protofile, "extern %s %s", protorettypes[type], name);
        !          2178:        list_arg_types(protofile, e, lengths, 0, ";\n");
        !          2179:        used_rets[type] = 1;
        !          2180:        if (!(Ansi = asave))
        !          2181:                Castargs = 0;
        !          2182:        }
        !          2183: 
        !          2184:  static void
        !          2185: do_p1_1while(outfile)
        !          2186:  FILE *outfile;
        !          2187: {
        !          2188:        if (*wh_next) {
        !          2189:                nice_printf(outfile,
        !          2190:                        "for(;;) { /* while(complicated condition) */\n" /*}*/ );
        !          2191:                next_tab(outfile);
        !          2192:                }
        !          2193:        else
        !          2194:                nice_printf(outfile, "while(" /*)*/ );
        !          2195:        }
        !          2196: 
        !          2197:  static void
        !          2198: do_p1_2while(infile, outfile)
        !          2199:  FILE *infile, *outfile;
        !          2200: {
        !          2201:        expptr test;
        !          2202: 
        !          2203:        test = do_format(infile, outfile);
        !          2204:        if (*wh_next)
        !          2205:                nice_printf(outfile, "if (!(");
        !          2206:        expr_out(outfile, test);
        !          2207:        if (*wh_next++)
        !          2208:                nice_printf(outfile, "))\n\tbreak;\n");
        !          2209:        else {
        !          2210:                nice_printf(outfile, /*(*/ ") {\n");
        !          2211:                next_tab(outfile);
        !          2212:                }
        !          2213:        }
        !          2214: 
        !          2215:  static void
        !          2216: do_p1_elseifstart(outfile)
        !          2217:  FILE *outfile;
        !          2218: {
        !          2219:        if (*ei_next++) {
        !          2220:                prev_tab(outfile);
        !          2221:                nice_printf(outfile, /*{*/
        !          2222:                        "} else /* if(complicated condition) */ {\n" /*}*/ );
        !          2223:                next_tab(outfile);
        !          2224:                }
        !          2225:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.