/* cpp.c */
/* front end processor for /lib/cpp */
/* ccc -Bstatic -g -o cpp cpp.c */
/* it's job is to teach cpp about tioga files: */
/* parses the cpp command line */
/* figures out the name of the file being compiled */
/* creates a stripped version of the file being compiled */
/* prepends the appropriate #file directive to that file */
/* invokes /lib/cpp on this temp file */
/* this "cpp" is normally invoked from ccc */
/* Notes: Eduardo wrote a cpp program which simply stopped scanning */
/* when the first null was encountered. The downside to this approach is */
/* it requires us to patch cpp's on each release. The other downside is that */
/* we've lost the sources of his patches. This is a replacement, but it isn't */
/* as functional as his original. In particular there isn't a way to support */
/* tioga formatting in .h files without reimplementing cpp. */
#include <stdio.h>
#include <string.h>
#include <sys/stdtypes.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "/usr/5include/malloc.h"
extern void exit();
static void error(s)
char *s;
{
if (s != NULL) (void)fprintf(stderr, "cedar cpp: %s\n", s);
exit(-1);
}
main(argc, argv)
int argc;
char **argv;
{
unsigned i, len, sourceFileIndex = 0;
size←t totlen = 0;
char c;
char *realcpp = "/lib/cpp";
char *arg = NULL, *tempinfilename = NULL;
FILE *tmpinfp, *cfile;
/* parse the command line */
for (i = 1; i < argc; i++) {
arg = argv[i];
len = strlen(arg);
totlen = len + totlen;
if (len > 2) {
if (arg[len-2] == '.' && (arg[len-1] == 'c' || arg[len-1] == 'S')) {
/* two source file files? ignore second one */
if (sourceFileIndex == 0) sourceFileIndex = i;
}
}
}
if (sourceFileIndex == 0) error("didn't find a source file to process");
/* open the source file */
if ((cfile = fopen(argv[sourceFileIndex], "r")) == NULL)
error("couldn't open the source file");
/* open the temp file */
tempinfilename = tempnam(P←tmpdir, "ccppi");
tmpinfp = fopen(tempinfilename, "w");
if (tmpinfp == NULL) {
(void)fclose(cfile);
error("couldn't open the in temp file");
};
/* stream the source file into the temp in file with mods */
if (fprintf(tmpinfp, "\#\ 1 \"%s\"\n", argv[sourceFileIndex]) == EOF)
error("fprintf failed");
while ((c = getc(cfile)) != EOF && c != '\0' ) {
if (c == '\015') c = '\012';
if (putc(c, tmpinfp) == EOF) error("fputc failed");
}
(void)fclose(cfile);
(void)fclose(tmpinfp);
/* prepend the correct # line directive */
if (printf("\#\ 1 \"%s\"\n", argv[sourceFileIndex]) == EOF)
error("printf failed");
if (fflush(stdout) == EOF)
error("fflush failed");
/* build the new command line */
argv[sourceFileIndex] = tempinfilename;
argv[0] = realcpp;
if (fork() == 0) {/* child */
/* invoke the real cpp */
(void)execvp(realcpp, argv);
return(-1);
}
else { /* parent */
int statusp = 0;
/* wait for the real cpp to finish */
(void)wait(&statusp);
if (unlink(tempinfilename) == -1) error("unlink failed");
free((void *)tempinfilename);
return(WEXITSTATUS(statusp));
}
}