/* * trans.c - main control of the translation process. */ #include "..\h\config.h" #include "general.h" #include "tproto.h" #include "..\h\version.h" #include "globals.h" #include "trans.h" #include "tsym.h" #include "tree.h" #include "token.h" /* * Prototypes. */ hidden FILE *preprocess Params((char *filename)); hidden novalue trans1 Params((char *filename)); char *comfile = NULL; int tfatals; /* total number of fatal errors */ int nocode; /* non-zero to suppress code generation */ int in_line; /* current input line number */ int incol; /* current input column number */ int peekc; /* one-character look ahead */ FILE *srcfile; /* current input file */ FILE *codefile; /* current ucode output file */ FILE *globfile; /* current global table output file */ /* * translate a number of files, returning an error count */ int trans(ifiles) char **ifiles; { tmalloc(); /* allocate memory for translation */ #ifdef MultipleRuns yylexinit(); /* initialize lexical analyser */ tcodeinit(); /* initialize code generator */ #endif /* Multiple Runs */ while (*ifiles) trans1(*ifiles++); /* translate each file in turn */ tmfree(); /* free memory used for translation */ /* * Report information about errors and warnings and be correct about it. */ if (tfatals == 1) fprintf(stderr, "1 error\n"); else if (tfatals > 1) fprintf(stderr, "%d errors\n", tfatals); else if (!silent) fprintf(stderr, "No errors\n"); return tfatals; } /* * translate one file. */ static novalue trans1(filename) char *filename; { char oname[MaxFileName]; /* buffer for constructing file names */ comfile = filename; tfatals = 0; /* reset error counts */ nocode = 0; /* allow code generation/* in_line = 1; /* start with line 1, column 0 */ incol = 0; peekc = 0; /* clear character lookahead */ if (m4pre) srcfile = preprocess(filename); else if (strcmp(filename,"-") == 0) { srcfile = stdin; filename = "stdin"; } else srcfile = fopen(filename,ReadText); if (srcfile == NULL) quitf("cannot open %s",filename); if (!silent) fprintf(stderr, "%s:\n",filename); #ifndef VarTran /* * Form names for the .u1 and .u2 files and open them. * Write the ucode version number to the .u2 file. */ makename(oname, TargetDir, filename, U1Suffix); #if MVS || VM /* * Even though the ucode data is all reasonable text characters, use * of text I/O may cause problems if a line is larger than LRECL. * This is likely to be true with any compiler, though the precise * disaster which results may vary. */ codefile = fopen(oname, WriteBinary); /* avoid line splits */ #else /* MVS || VM */ codefile = fopen(oname, WriteText); #endif /* MVS || VM */ if (codefile == NULL) quitf("cannot create %s", oname); makename(oname, TargetDir, filename, U2Suffix); #if MVS || VM globfile = fopen(oname, WriteBinary); #else /* MVS || VM */ globfile = fopen(oname, WriteText); #endif /* MVS || VM */ if (globfile == NULL) quitf("cannot create %s", oname); writecheck(fprintf(globfile,"version\t%s\n",UVersion)); #endif /* VarTran */ tok_loc.n_file = filename; in_line = 1; tminit(); /* Initialize data structures */ yyparse(); /* Parse the input */ /* * Close the output files and the input file. */ #ifndef VarTran if (fclose(codefile) != 0 || fclose(globfile) != 0) quit("cannot close ucode file"); #endif /* VarTran */ if (!m4pre) fclose(srcfile); /* "else" is below in conditional */ #if UNIX else if (pclose(srcfile) != 0) quit("m4 terminated abnormally"); #endif /* UNIX */ } /* * writecheck - check the return code from a stdio output operation */ novalue writecheck(rc) { if (rc < 0) quit("cannot write to ucode file"); } /* * open a pipe to the preprocessor. */ static FILE *preprocess(filename) char *filename; { #if MACINTOSH #if MPW /* #pragma unused(filename) */ return NULL; /* to prevent compiler warning */ #endif /* MPW */ #endif /* MACINTOSH */ #if UNIX { FILE *f, *popen(); char *s = alloc((unsigned int)(4+strlen(filename))); sprintf(s,"m4 %s",filename); f = popen(s,ReadText); free(s); return f; } #endif /* UNIX */ }