1 /****************************************************************
2 Copyright 1990, 1991 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 ****************************************************************/
24 extern char F2C_version[];
29 int complex_seen, dcomplex_seen;
31 LOCAL int Max_ftn_files;
34 int current_ftn_file = 0;
39 flag no66flag = NO; /* Must also set noextflag to this
41 flag zflag = YES; /* recognize double complex intrinsics */
43 flag onetripflag = NO;
50 int tycomplex = TYCOMPLEX;
51 extern void r8fix(), read_Pfiles();
53 int maxregvar = MAXREGVAR; /* if maxregvar > MAXREGVAR, error */
54 int maxequiv = MAXEQUIV;
56 int maxstno = MAXSTNO;
58 int maxhash = MAXHASH;
59 int maxliterals = MAXLITERALS;
60 int extcomm, ext1comm, useauto;
61 int can_include = YES; /* so we can disable includes for netlib */
63 static char *def_i2 = "";
65 static int useshortints = NO; /* YES => tyint = TYSHORT */
66 static int uselongints = NO; /* YES => tyint = TYLONG */
67 int addftnsrc = NO; /* Include ftn source in output */
68 int usedefsforcommon = NO; /* Use #defines for common reference */
69 int forcedouble = YES; /* force real functions to double */
74 int inqmask = M(TYLONG)|M(TYLOGICAL);
77 static int skipC, skipversion;
78 char *filename0, *parens;
80 static int typedefs = 0;
81 int chars_per_wd, gflag, protostatus;
83 char used_rets[TYSUBR+1];
85 static int h0align = 0;
86 char *halign, *ohalign;
88 int hsize; /* for padding under -h */
89 int htype; /* for wr_equiv_init under -h */
91 #define f2c_entry(swit,count,type,store,size) \
92 p_entry ("-", swit, 0, count, type, store, size)
94 static arg_info table[] = {
95 f2c_entry ("w66", P_NO_ARGS, P_INT, &ftn66flag, YES),
96 f2c_entry ("w", P_NO_ARGS, P_INT, &nowarnflag, YES),
97 f2c_entry ("66", P_NO_ARGS, P_INT, &no66flag, YES),
98 f2c_entry ("d", P_ONE_ARG, P_INT, &debugflag, YES),
99 f2c_entry ("1", P_NO_ARGS, P_INT, &onetripflag, YES),
100 f2c_entry ("onetrip", P_NO_ARGS, P_INT, &onetripflag, YES),
101 f2c_entry ("I2", P_NO_ARGS, P_INT, &useshortints, YES),
102 f2c_entry ("I4", P_NO_ARGS, P_INT, &uselongints, YES),
103 f2c_entry ("U", P_NO_ARGS, P_INT, &shiftcase, NO),
104 f2c_entry ("u", P_NO_ARGS, P_INT, &undeftype, YES),
105 f2c_entry ("O", P_ONE_ARG, P_INT, &maxregvar, 0),
106 f2c_entry ("C", P_NO_ARGS, P_INT, &checksubs, YES),
107 f2c_entry ("Nq", P_ONE_ARG, P_INT, &maxequiv, 0),
108 f2c_entry ("Nx", P_ONE_ARG, P_INT, &maxext, 0),
109 f2c_entry ("Ns", P_ONE_ARG, P_INT, &maxstno, 0),
110 f2c_entry ("Nc", P_ONE_ARG, P_INT, &maxctl, 0),
111 f2c_entry ("Nn", P_ONE_ARG, P_INT, &maxhash, 0),
112 f2c_entry ("NL", P_ONE_ARG, P_INT, &maxliterals, 0),
113 f2c_entry ("c", P_NO_ARGS, P_INT, &addftnsrc, YES),
114 f2c_entry ("p", P_NO_ARGS, P_INT, &usedefsforcommon, YES),
115 f2c_entry ("R", P_NO_ARGS, P_INT, &forcedouble, NO),
116 f2c_entry ("!R", P_NO_ARGS, P_INT, &forcedouble, YES),
117 f2c_entry ("A", P_NO_ARGS, P_INT, &Ansi, YES),
118 f2c_entry ("ext", P_NO_ARGS, P_INT, &noextflag, YES),
119 f2c_entry ("z", P_NO_ARGS, P_INT, &zflag, NO),
120 f2c_entry ("a", P_NO_ARGS, P_INT, &useauto, YES),
121 f2c_entry ("r8", P_NO_ARGS, P_INT, &r8flag, YES),
122 f2c_entry ("i2", P_NO_ARGS, P_INT, &tyioint, NO),
123 f2c_entry ("w8", P_NO_ARGS, P_INT, &wordalign, YES),
124 f2c_entry ("!I", P_NO_ARGS, P_INT, &can_include, NO),
125 f2c_entry ("W", P_ONE_ARG, P_INT, &chars_per_wd, 0),
126 f2c_entry ("g", P_NO_ARGS, P_INT, &gflag, YES),
127 f2c_entry ("T", P_ONE_ARG, P_STRING, &tmpdir, 0),
128 f2c_entry ("E", P_NO_ARGS, P_INT, &extcomm, 1),
129 f2c_entry ("e1c", P_NO_ARGS, P_INT, &ext1comm, 1),
130 f2c_entry ("ec", P_NO_ARGS, P_INT, &ext1comm, 2),
131 f2c_entry ("C++", P_NO_ARGS, P_INT, &Ansi, 2),
132 f2c_entry ("P", P_NO_ARGS, P_INT, &Castargs, 3),
133 f2c_entry ("Ps", P_NO_ARGS, P_INT, &protostatus, 1),
134 f2c_entry ("!P", P_NO_ARGS, P_INT, &Castargs, 0),
135 f2c_entry ("!c", P_NO_ARGS, P_INT, &skipC, 1),
136 f2c_entry ("!it", P_NO_ARGS, P_INT, &infertypes, 0),
137 f2c_entry ("h", P_NO_ARGS, P_INT, &h0align, 1),
138 f2c_entry ("hd", P_NO_ARGS, P_INT, &h0align, 2),
139 f2c_entry ("kr", P_NO_ARGS, P_INT, &krparens, 1),
140 f2c_entry ("krd", P_NO_ARGS, P_INT, &krparens, 2),
141 f2c_entry ("!bs", P_NO_ARGS, P_INT, &use_bs, NO),
142 f2c_entry ("r", P_NO_ARGS, P_INT, &forcereal, YES),
144 /* options omitted from man pages */
146 /* -ev ==> implement equivalence with initialized pointers */
147 f2c_entry ("ev", P_NO_ARGS, P_INT, &def_equivs, NO),
149 /* -!it used to be the default when -it was more agressive */
151 f2c_entry ("it", P_NO_ARGS, P_INT, &infertypes, 1),
153 /* -Pd is similar to -P, but omits :ref: lines */
154 f2c_entry ("Pd", P_NO_ARGS, P_INT, &Castargs, 2),
156 /* -t ==> emit typedefs (under -A or -C++) for procedure
157 argument types used. This is meant for netlib's
158 f2c service, so -A and -C++ will work with older
161 f2c_entry ("t", P_NO_ARGS, P_INT, &typedefs, 1),
163 /* -!V ==> omit version msg (to facilitate using diff in
166 f2c_entry ("!V", P_NO_ARGS, P_INT, &skipversion, 1)
170 extern char *c_functions; /* "c_functions" */
171 extern char *coutput; /* "c_output" */
172 extern char *initfname; /* "raw_data" */
173 extern char *blkdfname; /* "block_data" */
174 extern char *p1_file; /* "p1_file" */
175 extern char *p1_bakfile; /* "p1_file.BAK" */
176 extern char *sortfname; /* "init_file" */
177 static char *proto_fname; /* "proto_file" */
180 extern void list_init_data(), set_tmp_names(), sigcatch(), Un_link_all();
181 extern char *c_name();
186 static char *hset[3] = { 0, "integer", "doublereal" };
188 /* Adjust the global flags according to the command line parameters */
190 if (chars_per_wd > 0) {
191 typesize[TYADDR] = typesize[TYLONG] = typesize[TYREAL] =
192 typesize[TYLOGICAL] = chars_per_wd;
193 typesize[TYDREAL] = typesize[TYCOMPLEX] = chars_per_wd << 1;
194 typesize[TYDCOMPLEX] = chars_per_wd << 2;
195 typesize[TYSHORT] = chars_per_wd >> 1;
196 typesize[TYCILIST] = 5*chars_per_wd;
197 typesize[TYICILIST] = 6*chars_per_wd;
198 typesize[TYOLIST] = 9*chars_per_wd;
199 typesize[TYCLLIST] = 3*chars_per_wd;
200 typesize[TYALIST] = 2*chars_per_wd;
201 typesize[TYINLIST] = 26*chars_per_wd;
205 typealign[TYDREAL] = typealign[TYDCOMPLEX] = typealign[TYREAL];
208 szleng = typesize[TYSHORT];
209 def_i2 = "#define f2c_i2 1\n";
210 inqmask = M(TYSHORT)|M(TYLOGICAL);
214 szleng = typesize[TYLONG];
218 protorettypes[TYLOGICAL] = typename[TYLOGICAL] = "shortlogical";
219 typesize[TYLOGICAL] = typesize[TYSHORT];
220 casttypes[TYLOGICAL] = "K_fp";
222 err ("Can't use both long and short ints");
224 tyint = tylogical = TYSHORT;
226 else if (uselongints)
230 if (tyint == TYLONG && wordalign)
232 ohalign = halign = hset[h0align];
233 htype = h0align == 1 ? tyint : TYDREAL;
234 hsize = typesize[htype];
238 noextflag = no66flag;
244 tycomplex = TYDCOMPLEX;
248 protorettypes[TYREAL] = "E_f";
249 casttypes[TYREAL] = "E_fp";
252 if (maxregvar > MAXREGVAR) {
253 warni("-O%d: too many register variables", maxregvar);
254 maxregvar = MAXREGVAR;
255 } /* if maxregvar > MAXREGVAR */
257 /* Check the list of input files */
260 int bad, i, cur_max = Max_ftn_files;
262 for (i = bad = 0; i < cur_max && ftn_files[i]; i++)
263 if (ftn_files[i][0] == '-') {
264 errstr ("Invalid flag '%s'", ftn_files[i]);
279 for(ext = extsymtab; ext < nextext; ext++)
280 if (ext->extstg == STGCOMMON && !ext->extinit)
286 write_typedefs(outfile)
290 register char *s, *p = 0;
291 static char st[4] = { TYREAL, TYCOMPLEX, TYDCOMPLEX, TYCHAR };
292 static char stl[4] = { 'E', 'C', 'Z', 'H' };
294 for(i = 0; i <= TYSUBR; i++)
295 if (s = usedcasts[i]) {
297 p = Ansi == 1 ? "()" : "(...)";
299 "/* Types for casting procedure arguments: */\
300 \n\n#ifndef F2C_proc_par_types\n");
303 "typedef int /* Unknown procedure type */ (*%s)%s;\n",
308 nice_printf(outfile, "typedef %s (*%s)%s;\n",
309 c_type_decl(i,1), s, p);
311 for(i = !forcedouble; i < 4; i++)
312 if (used_rets[st[i]])
314 "typedef %s %c_f; /* %s function */\n",
315 p = i ? "VOID" : "doublereal",
316 stl[i], ftn_types[st[i]]);
318 nice_printf(outfile, "#endif\n\n");
322 commonprotos(outfile)
323 register FILE *outfile;
325 register Extsym *e, *ee;
326 register Argtypes *at;
329 extern int proc_protochanges;
333 for (e = extsymtab, ee = nextext; e < ee; e++)
334 if (e->extstg == STGCOMMON && e->allextp)
335 nice_printf(outfile, "/* comlen %s %ld */\n",
336 e->cextname, e->maxleng);
340 /* -Pr: special comments conveying current knowledge
341 of external references */
343 k = proc_protochanges;
344 for (e = extsymtab, ee = nextext; e < ee; e++)
345 if (e->extstg == STGEXT
346 && e->cextname != e->fextname) /* not a library function */
347 if (at = e->arginfo) {
348 if ((!e->extinit || at->changes & 1)
349 /* not defined here or
350 changed since definition */
352 nice_printf(outfile, "/*:ref: %s %d %d",
353 e->cextname, e->extype, at->nargs);
355 for(ae = a + at->nargs; a < ae; a++)
356 nice_printf(outfile, " %d", a->type);
357 nice_printf(outfile, " */\n");
363 /* typed external, never invoked */
364 nice_printf(outfile, "/*:ref: %s %d :*/\n",
365 e->cextname, e->extype);
368 "/* Rerunning f2c -P may change prototypes or declarations. */\n");
373 if (protofile != stdout) {
375 "Rerunning \"f2c -P ... %s %s\" may change prototypes or declarations.\n",
376 filename0, proto_fname);
390 char *filename, *cdfilename;
391 static char stderrbuf[BUFSIZ];
392 extern void def_commons();
393 extern char **dfltproc, *dflt1proc[];
394 extern char link_msg[];
397 setbuf(stderr, stderrbuf); /* arrange for fast error msgs */
399 Max_ftn_files = argc - 1;
400 ftn_files = (char **)ckalloc((argc+1)*sizeof(char *));
402 parse_args (argc, argv, table, sizeof(table)/sizeof(arg_info),
403 ftn_files, Max_ftn_files);
404 if (!can_include && ext1comm == 2)
406 if (ext1comm && !extcomm)
410 else if (Castargs == 1 && !Ansi)
412 if (Castargs >= 2 && !Ansi)
418 parens = Ansi == 1 ? "()" : "(...)";
420 dfltproc = dflt1proc;
424 read_Pfiles(ftn_files);
426 for(k = 1; ftn_files[k]; k++)
429 filename0 = filename = ftn_files[current_ftn_file = k - 1];
434 c_file = opf(c_functions, textwrite);
435 pass1_file=opf(p1_file, binwrite);
437 if (filename && *filename) {
438 if (debugflag != 1) {
439 coutput = c_name(filename,'c');
441 proto_fname = c_name(filename,'P');
443 cdfilename = coutput;
446 else if (!(c_output = fopen(coutput, textwrite))) {
448 coutput = 0; /* don't delete read-only .c file */
449 fatalstr("can't open %.86s", filename);
453 && !(protofile = fopen(proto_fname, textwrite)))
454 fatalstr("Can't open %.84s\n", proto_fname);
458 cdfilename = "f2c_out.c";
464 printf("#ifdef P_R_O_T_O_T_Y_P_E_S\n");
468 if(inilex( copys(filename) ))
471 fprintf(diagfile, "%s:\n", filename);
478 fprintf(diagfile, "Bad parse, return code %d\n", k);
482 commonprotos(protofile);
483 if (protofile == stdout && !skipC)
484 printf("#endif\n\n");
490 /* Write out the declarations which are global to this file */
492 if ((c2d = comm2dcl()) == 1)
493 nice_printf(c_output, "/*>>>'/dev/null'<<<*/\n\n\
494 /* Split this into several files by piping it through\n\n\
495 sed \"s/^\\/\\*>>>'\\(.*\\)'<<<\\*\\/\\$/cat >'\\1' <<'\\/*<<<\\1>>>*\\/'/\" | /bin/sh\n\
497 /*<<</dev/null>>>*/\n\
498 /*>>>'%s'<<<*/\n", cdfilename);
500 nice_printf (c_output, "/* %s -- translated by f2c ", filename);
501 nice_printf (c_output, "(version of %s).\n", F2C_version);
502 nice_printf (c_output,
503 " You must link the resulting object file with the libraries:\n\
504 %s (in that order)\n*/\n\n", link_msg);
507 nice_printf(c_output,
508 "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
509 nice_printf (c_output, "%s#include \"f2c.h\"\n\n", def_i2);
510 if (Castargs && typedefs)
511 write_typedefs(c_output);
512 nice_printf (c_file, "\n");
514 c_file = c_output; /* HACK to get the next indenting
516 wr_common_decls (c_output);
518 list_init_data(&blkdfile, blkdfname, c_output);
519 wr_globals (c_output);
520 if ((c_file = fopen (c_functions, textread)) == (FILE *) NULL)
521 Fatal("main - couldn't reopen c_functions");
522 ffilecopy (c_file, c_output);
524 nice_printf (c_output, "/* Main program alias */ ");
525 nice_printf (c_output, "int %s () { MAIN__ (); }\n",
529 nice_printf(c_output,
530 "#ifdef __cplusplus\n\t}\n#endif\n");
533 fprintf(c_output, "/*<<<%s>>>*/\n", cdfilename);
536 def_commons(c_output);
542 if(parstate != OUTSIDE)
544 warn("missing final end statement");
555 if( fp = fopen(fn, mode) )
558 fatalstr("cannot open intermediate file %s", fn);
559 /* NOT REACHED */ return 0;
568 if(p!=NULL && *p!=NULL && *p!=stdout)
571 fprintf(stderr, "I/O error on %s\n", what);
585 clf(&initfile, "initfile", 0);
586 clf(&c_file, "c_file", 0);
587 clf(&pass1_file, "pass1_file", 0);