1 /****************************************************************
2 Copyright 1990 by AT&T Bell Laboratories and Bellcore.
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.
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
22 ****************************************************************/
30 /* Names generated by the translator are guaranteed to be unique from the
31 Fortan names because Fortran does not allow underscores in identifiers,
32 and all of the system generated names do have underscores. The various
33 naming conventions are outlined below:
36 ----------------------------------------------------------------------
37 io_# temporaries generated by IO calls; these will
38 contain the device number (e.g. 5, 6, 0)
39 ret_val function return value, required for complex and
41 ret_val_len length of the return value in character functions
43 ssss_len length of character argument "ssss"
45 c_# member of the literal pool, where # is an
46 arbitrary label assigned by the system
47 cs_# short integer constant in the literal pool
48 t_# expression temporary, # is the depth of arguments
50 L# label "#", given by user in the Fortran program.
51 This is unique because Fortran labels are numeric
52 pad_# label on an init field required for alignment
53 xxx_init label on a common block union, if a block data
54 requires a separate declaration
57 /* generate variable references */
59 char *c_type_decl (type, is_extern)
62 static char buff[100];
65 case TYADDR: strcpy (buff, "address"); break;
66 case TYSHORT: strcpy (buff, "shortint"); break;
67 case TYLONG: strcpy (buff, "integer"); break;
68 case TYREAL: if (!is_extern || !forcedouble)
69 { strcpy (buff, "real");break; }
70 case TYDREAL: strcpy (buff, "doublereal"); break;
71 case TYCOMPLEX: if (is_extern)
72 strcpy (buff, Ansi ? "/* Complex */ VOID"
73 : "/* Complex */ int");
75 strcpy (buff, "complex");
77 case TYDCOMPLEX:if (is_extern)
78 strcpy (buff, Ansi ? "/* Double Complex */ VOID"
79 : "/* Double Complex */ int");
81 strcpy (buff, "doublecomplex");
83 case TYLOGICAL: strcpy(buff, typename[TYLOGICAL]);
85 case TYCHAR: if (is_extern)
86 strcpy (buff, Ansi ? "/* Character */ VOID"
87 : "/* Character */ int");
89 strcpy (buff, "char");
92 case TYUNKNOWN: strcpy (buff, "UNKNOWN");
94 /* If a procedure's type is unknown, assume it's a subroutine */
99 /* Subroutines must return an INT, because they might return a label
100 value. Even if one doesn't, the caller will EXPECT it to. */
102 case TYSUBR: strcpy (buff, "/* Subroutine */ int");
104 case TYERROR: strcpy (buff, "ERROR"); break;
105 case TYVOID: strcpy (buff, "void"); break;
106 case TYCILIST: strcpy (buff, "cilist"); break;
107 case TYICILIST: strcpy (buff, "icilist"); break;
108 case TYOLIST: strcpy (buff, "olist"); break;
109 case TYCLLIST: strcpy (buff, "cllist"); break;
110 case TYALIST: strcpy (buff, "alist"); break;
111 case TYINLIST: strcpy (buff, "inlist"); break;
112 case TYFTNLEN: strcpy (buff, "ftnlen"); break;
113 default: sprintf (buff, "BAD DECL '%d'", type);
121 char *new_func_length()
122 { return "ret_val_len"; }
124 char *new_arg_length(arg)
128 sprintf (buf, "%s_len", arg->fvarname);
131 } /* new_arg_length */
134 /* declare_new_addr -- Add a new local variable to the function, given a
135 pointer to an Addrblock structure (which must have the uname_tag set)
136 This list of idents will be printed in reverse (i.e., chronological)
140 declare_new_addr (addrp)
141 struct Addrblock *addrp;
143 extern chainp new_vars;
145 new_vars = mkchain((char *)cpexpr((expptr)addrp), new_vars);
146 } /* declare_new_addr */
149 wr_nv_ident_help (outfile, addrp)
151 struct Addrblock *addrp;
155 if (addrp == (struct Addrblock *) NULL)
158 if (addrp -> isarray) {
159 frexpr (addrp -> memoffset);
160 addrp -> memoffset = ICON(0);
161 eltcount = addrp -> ntempelt;
162 addrp -> ntempelt = 0;
163 addrp -> isarray = 0;
165 out_addr (outfile, addrp);
167 nice_printf (outfile, "[%d]", eltcount);
168 } /* wr_nv_ident_help */
170 int nv_type_help (addrp)
171 struct Addrblock *addrp;
173 if (addrp == (struct Addrblock *) NULL)
176 return addrp -> vtype;
180 /* lit_name -- returns a unique identifier for the given literal. Make
181 the label useful, when possible. For example:
183 1 -> c_1 (constant 1)
184 2 -> c_2 (constant 2)
185 1000 -> c_1000 (constant 1000)
186 1000000 -> c_b<memno> (big constant number)
187 1.2 -> c_1_2 (constant 1.2)
188 1.234345 -> c_b<memno> (big constant number)
189 -1 -> c_n1 (constant -1)
190 -1.0 -> c_n1_0 (constant -1.0)
191 .true. -> c_true (constant true)
192 .false. -> c_false (constant false)
193 default -> c_b<memno> (default label)
196 char *lit_name (litp)
197 struct Literal *litp;
199 static char buf[CONST_IDENT_MAX];
201 if (litp == (struct Literal *) NULL)
204 switch (litp -> littype) {
206 if (litp -> litval.litival < 32768 &&
207 litp -> litval.litival > -32769) {
208 ftnint val = litp -> litval.litival;
211 sprintf (buf, "cs_n%ld", -val);
213 sprintf (buf, "cs__%ld", val);
215 sprintf (buf, "c_b%d", litp -> litnum);
218 if (litp -> litval.litival < 100000 &&
219 litp -> litval.litival > -10000) {
220 ftnint val = litp -> litval.litival;
223 sprintf (buf, "c_n%ld", -val);
225 sprintf (buf, "c__%ld", val);
227 sprintf (buf, "c_b%d", litp -> litnum);
230 sprintf (buf, "c_%s", (litp -> litval.litival ? "true" : "false"));
234 /* Given a limit of 6 or 8 character on external names, */
235 /* few f.p. values can be meaningfully encoded in the */
236 /* constant name. Just going with the default cb_# */
237 /* seems to be the best course for floating-point */
240 /* Shouldn't be any of these */
246 sprintf (buf, "c_b%d", litp -> litnum);
255 comm_union_name(count)
260 sprintf(buf, "%d", count);
267 /* wr_globals -- after every function has been translated, we need to
268 output the global declarations, such as the static table of constant
274 struct Literal *litp, *lastlit;
276 extern char *lit_name();
279 struct Constblock cb;
285 lastlit = litpool + nliterals;
287 for (litp = litpool; litp < lastlit; litp++) {
290 litname = lit_name(litp);
292 margin_printf(outfile, "/* Table of constant values */\n\n");
295 cb.vtype = litp->littype;
296 if (litp->littype == TYCHAR) {
297 x = litp->litval.litival2[0] + litp->litval.litival2[1];
300 "static struct { %s fill; char val[%ld+1];", halign, x);
302 nice_printf(outfile, " char fill2[%ld];", hsize - y);
303 nice_printf(outfile, " } %s_st = { 0,", litname);
304 cb.vleng = ICON(litp->litval.litival2[0]);
305 cb.Const.ccp = litp->cds[0];
306 cb.Const.ccp1.blanks = litp->litval.litival2[1];
308 out_const(outfile, &cb);
310 nice_printf(outfile, " };\n");
311 nice_printf(outfile, "#define %s %s_st.val\n", litname, litname);
314 nice_printf(outfile, "static %s %s = ",
315 c_type_decl(litp->littype,0), litname);
318 if (ONEOF(t, MSKREAL|MSKCOMPLEX)) {
320 cb.Const.cds[0] = litp->cds[0];
321 cb.Const.cds[1] = litp->cds[1];
324 memcpy((char *)&cb.Const, (char *)&litp->litval,
328 out_const(outfile, &cb);
330 nice_printf (outfile, ";\n");
333 nice_printf (outfile, "\n");
347 v = (Namep)vl->datap;
350 size = v->vleng->constblock.Const.ci;
352 size = typesize[type];
353 if ((t = v->vdim) && ISCONST(t->nelt))
354 size *= t->nelt->constblock.Const.ci;
355 return size + v->voffset;
358 static void /* Pad common block if an EQUIVALENCE extended it. */
367 int szshort = typesize[TYSHORT];
369 for(cvl = c->allextp; cvl; cvl = cvl->nextp)
370 if (commlen((chainp)cvl->datap) >= L)
372 v = ALLOC(Nameblock);
373 v->vtype = type = L % szshort ? TYCHAR
374 : type_choice[L/szshort % 4];
378 v->vdim = t = ALLOC(Dimblock);
380 t->dims[0].dimsize = ICON(L / typesize[type]);
381 v->fvarname = v->cvarname = "eqv_pad";
382 c->allextp = mkchain((char *)mkchain((char *)v, CHNULL), c->allextp);
386 /* wr_common_decls -- outputs the common declarations in one of three
387 formats. If all references to a common block look the same (field
388 names and types agree), only one actual declaration will appear.
389 Otherwise, the same block will require many structs. If there is no
390 block data, these structs will be union'ed together (so the linker
391 knows the size of the largest one). If there IS a block data, only
392 that version will be associated with the variable, others will only be
393 defined as types, so the pointer can be cast to it. e.g.
396 ----------------------------------------------------------------------
397 common /com1/ a, b, c struct { real a, b, c; } com1_;
399 common /com1/ a, b, c union {
400 common /com1/ i, j, k struct { real a, b, c; } _1;
401 struct { integer i, j, k; } _2;
404 common /com1/ a, b, c struct com1_1_ { real a, b, c; };
405 block data struct { integer i, j, k; } com1_ =
406 common /com1/ i, j, k { 1, 2, 3 };
407 data i/1/, j/2/, k/3/
410 All of these versions will be followed by #defines, since the code in
411 the function bodies can't know ahead of time which of these options
414 /* Macros for deciding the output type */
417 #define UNION_STRUCT 2
418 #define INIT_STRUCT 3
420 wr_common_decls(outfile)
425 static char *Extern[4] = {"", "Extern ", "extern "};
426 char *E, *E0 = Extern[extcomm];
429 for (ext = extsymtab; ext < nextext; ext++) {
430 if (ext -> extstg == STGCOMMON && ext->allextp) {
433 int which; /* which display to use;
434 ONE_STRUCT, UNION or INIT */
437 nice_printf (outfile, "/* Common Block Declarations */\n\n");
441 /* Construct the proper, condensed list of structs; eliminate duplicates
442 from the initial list ext -> allextp */
444 comm = ext->allextp = revchain(ext->allextp);
448 else if (comm->nextp) {
449 which = UNION_STRUCT;
450 nice_printf (outfile, "%sunion {\n", E0);
459 for (; comm; comm = comm -> nextp, count++) {
461 if (which == INIT_STRUCT)
462 nice_printf (outfile, "struct %s%d_ {\n",
463 ext->cextname, count);
465 nice_printf (outfile, "%sstruct {\n", E);
469 wr_struct (outfile, (chainp) comm -> datap);
472 if (which == UNION_STRUCT)
473 nice_printf (outfile, "} _%d;\n", count);
474 else if (which == ONE_STRUCT)
475 nice_printf (outfile, "} %s;\n", ext->cextname);
477 nice_printf (outfile, "};\n");
480 if (which == UNION_STRUCT) {
482 nice_printf (outfile, "} %s;\n", ext->cextname);
485 nice_printf (outfile, "\n");
487 for (count = 1, comm = ext -> allextp; comm;
488 comm = comm -> nextp, count++) {
489 def_start(outfile, ext->cextname,
490 comm_union_name(count), "");
493 extern_out (outfile, ext);
496 nice_printf (outfile, "(");
497 extern_out (outfile, ext);
498 nice_printf(outfile, "._%d)", count);
501 nice_printf (outfile, "(*(struct ");
502 extern_out (outfile, ext);
503 nice_printf (outfile, "%d_ *) &", count);
504 extern_out (outfile, ext);
505 nice_printf (outfile, ")");
508 nice_printf (outfile, "\n");
509 } /* for count = 1, comm = ext -> allextp */
510 nice_printf (outfile, "\n");
511 } /* if ext -> extstg == STGCOMMON */
512 } /* for ext = extsymtab */
513 } /* wr_common_decls */
516 wr_struct (outfile, var_list)
524 for (this_var = var_list; this_var; this_var = this_var -> nextp) {
525 Namep var = (Namep) this_var -> datap;
527 char *comment = NULL, *wr_ardecls ();
529 if (var == (Namep) NULL)
530 err ("wr_struct: null variable");
531 else if (var -> tag != TNAME)
532 erri ("wr_struct: bad tag on variable '%d'",
537 if (last_type == type && did_one)
538 nice_printf (outfile, ", ");
541 nice_printf (outfile, ";\n");
542 nice_printf (outfile, "%s ",
543 c_type_decl (type, var -> vclass == CLPROC));
546 /* Character type is really a string type. Put out a '*' for parameters
547 with unknown length and functions returning character */
549 if (var -> vtype == TYCHAR && (!ISICON ((var -> vleng))
550 || var -> vclass == CLPROC))
551 nice_printf (outfile, "*");
553 var -> vstg = STGAUTO;
554 out_name (outfile, var);
555 if (var -> vclass == CLPROC)
556 nice_printf (outfile, "()");
557 else if (var -> vdim)
558 comment = wr_ardecls(outfile, var->vdim,
559 var->vtype == TYCHAR && ISICON(var->vleng)
560 ? var->vleng->constblock.Const.ci : 1L);
561 else if (var -> vtype == TYCHAR && var -> vclass != CLPROC &&
562 ISICON ((var -> vleng)))
563 nice_printf (outfile, "[%ld]",
564 var -> vleng -> constblock.Const.ci);
567 nice_printf (outfile, "%s", comment);
573 nice_printf (outfile, ";\n");
577 char *user_label(stateno)
580 static char buf[USER_LABEL_MAX + 1];
581 static char *Lfmt[2] = { "L_%ld", "L%ld" };
584 sprintf(buf, Lfmt[shiftcase], stateno);
586 sprintf(buf, "L_%s", extsymtab[-1-stateno].fextname);
591 char *temp_name (starter, num, storage)
596 static char buf[IDENT_LEN];
603 if (starter && *starter)
606 sprintf (pointer, "%s__%d", prefix, num);
611 char *equiv_name (memno, store)
615 static char buf[IDENT_LEN];
621 sprintf (pointer, "%s_%d", EQUIV_INIT_NAME, memno);
630 int c, onefile, Union;
638 fprintf(of, "/*>>>'/dev/null'<<<*/\n\
639 #ifdef Define_COMMONs\n\
640 /*<<</dev/null>>>*/\n");
644 for(ext = extsymtab; ext < nextext; ext++)
645 if (ext->extstg == STGCOMMON
646 && !ext->extinit && (comm = ext->allextp)) {
647 sprintf(buf, "%scom.c", ext->cextname);
649 fprintf(of, "/*>>>'%s'<<<*/\n",
652 c_file = of = fopen(buf,textwrite);
654 fatalstr("can't open %s", buf);
656 fprintf(of, "#include \"f2c.h\"\n");
659 nice_printf(of, "union {\n");
664 for(c = 1; comm; comm = comm->nextp) {
665 nice_printf(of, "struct {\n");
667 wr_struct(of, (chainp)comm->datap);
670 nice_printf(of, "} _%d;\n", c++);
674 nice_printf(of, "} %s;\n", ext->cextname);
676 fprintf(of, "/*<<<%s>>>*/\n", buf);
681 fprintf(of, "/*>>>'/dev/null'<<<*/\n#endif\n\
682 /*<<</dev/null>>>*/\n");
685 /* C Language keywords. Needed to filter unwanted fortran identifiers like
686 * "int", etc. Source: Kernighan & Ritchie, eds. 1 and 2; Stroustrup.
687 * Also includes C++ keywords and types used for I/O in f2c.h .
688 * These keywords must be in alphabetical order (as defined by strcmp()).
691 char *c_keywords[] = {
692 "Long", "Multitype", "Namelist", "Vardesc",
693 "abs", "acos", "address", "alist", "asin", "asm",
694 "atan", "atan2", "auto", "break",
695 "case", "catch", "char", "cilist", "class", "cllist",
696 "complex", "const", "continue", "cos", "cosh",
697 "dabs", "default", "defined", "delete",
698 "dmax", "dmin", "do", "double", "doublecomplex", "doublereal",
699 "else", "entry", "enum", "exp", "extern",
700 "flag", "float", "for", "friend", "ftnint", "ftnlen", "goto",
701 "icilist", "if", "include", "inline", "inlist", "int", "integer",
702 "log", "logical", "long", "max", "min", "new",
703 "olist", "operator", "overload", "private", "protected", "public",
704 "real", "register", "return",
705 "short", "shortint", "shortlogical", "signed", "sin", "sinh",
706 "sizeof", "sqrt", "static", "struct", "switch",
707 "tan", "tanh", "template", "this", "try", "typedef",
708 "union", "unsigned", "virtual", "void", "volatile", "while"
711 int n_keywords = sizeof(c_keywords)/sizeof(char *);