input.o: inputtype.h
main.o: arith.h
main.o: file_info.h
+main.o: idf.h
main.o: idfsize.h
+main.o: macro.h
options.o: class.h
options.o: idf.h
options.o: idfsize.h
int nestlevel = -1;
int svnestlevel[30] = {-1};
int nestcount;
+extern int do_preprocess;
char *
GetIdentifier(skiponerr)
inctable[0] = WorkingDir;
if (filenm) {
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
- error("cannot open include file \"%s\"", filenm);
+ if (do_preprocess) error("cannot open include file \"%s\"", filenm);
+ else warning("cannot open include file \"%s\"", filenm);
+ add_dependency(filenm);
}
else {
- if (filenm != result) free(filenm);
+ add_dependency(result);
WorkingDir = getwdir(result);
svnestlevel[++nestcount] = nestlevel;
FileName = result;
*/
/* $Header$ */
struct id_usr {
- struct macro *idu_macro;
+ union {
+ struct macro *idu_macro;
+ struct idf *idu_file;
+ } idu_x;
int idu_resmac;
};
#define IDF_TYPE struct id_usr
#define IDF_HSIZE 6
-#define id_macro id_user.idu_macro
+#define id_macro id_user.idu_x.idu_macro
+#define id_file id_user.idu_x.idu_file
#define id_resmac id_user.idu_resmac
#include <idf_pkg.spec>
#define K_LINE 10
#define K_PRAGMA 11
#define K_UNDEF 12
+#define K_FILE 100 /* for dependency generator */
/* MAIN PROGRAM */
#include <alloc.h>
+#include <assert.h>
#include <system.h>
#include "arith.h"
#include "file_info.h"
#include "idfsize.h"
+#include "idf.h"
+#include "macro.h"
extern char *symbol2str();
extern char *getwdir();
extern int err_occurred;
+extern int do_dependencies;
+extern char *dep_file;
int idfsize = IDFSIZE;
+extern char options[];
+static File *dep_fd = STDOUT;
arith ifval;
source ? source : "stdin");
if (source) WorkingDir = getwdir(dummy);
preprocess(source);
+ if (do_dependencies) list_dependencies(source);
+}
+
+struct idf *file_head;
+extern char *strrindex();
+
+list_dependencies(source)
+ char *source;
+{
+ register struct idf *p = file_head;
+
+ if (source) {
+ register char *s = strrindex(source, '.');
+
+ if (s && *(s+1)) {
+ s++;
+ *s++ = 'o';
+ *s = '\0';
+ /* the source may be in another directory than the
+ * object generated, so don't include the pathname
+ * leading to it.
+ */
+ if (s = strrindex(source, '/')) {
+ source = s + 1;
+ }
+ }
+ else source = 0;
+ }
+ if (dep_file && !sys_open(dep_file, OP_WRITE, &dep_fd)) {
+ fatal("could not open %s", dep_file);
+ }
+ while (p) {
+ assert(p->id_resmac == K_FILE);
+ dependency(p->id_text, source);
+ p = p->id_file;
+ }
+}
+
+add_dependency(s)
+ char *s;
+{
+ register struct idf *p = str2idf(s, 0);
+
+ if (! p->id_resmac) {
+ p->id_resmac = K_FILE;
+ p->id_file = file_head;
+ file_head = p;
+ }
+}
+
+dependency(s, source)
+ char *s, *source;
+{
+ if (options['i'] && !strncmp(s, "/usr/include/", 13)) {
+ return;
+ }
+ if (options['m'] && source) {
+ fprint(dep_fd, "%s: %s\n", source, s);
+ }
+ else fprint(dep_fd, "%s\n", s);
}
No_Mem() /* called by alloc package */
.IP -\fBM\fIn\fR
set maximum identifier length to
.IR n .
+.IP -\fBd\fR[\fIfile\fR]
+.br
+if \fIfile\fR is not given, do not preprocess, but instead generate a list
+of makefile dependencies and write them to the standard output.
+If \fIfile\fP is given, generate preprocessor output on standard output,
+and generate the list of makefile dependencies on file \fIfile\fP.
+.IP -\fBA\fR[\fIfile\fR]
+identical to the -d option.
+.IP -\fBi\fR
+when generating makefile dependencies, do not include files from
+/usr/include.
+.IP -\fBm\fR
+when generating makefile dependencies, generate them in the following format:
+.RS
+.IP "file.o: file1.h"
+.RE
+.IP ""
+where "file.o" is derived from the source file name. Normally, only a list
+of files included is generated.
+.IP -\fBundef\fR
+.br
+this flag is silently ignored, for compatibility with other preprocessors.
.PP
The following names are always available. They cannot be the subject of a
-U command line option or a #undef directive.
int inc_pos = 1; /* place where next -I goes */
int inc_max;
int inc_total;
-int debug;
+int do_preprocess = 1;
+int do_dependencies = 0;
char **inctable;
+char *dep_file = 0;
extern int idfsize;
int txt2int();
case '-':
options[*text] = 1;
break;
+ case 'u':
+ if (! strcmp(text, "ndef")) {
+ /* ignore -undef */
+ break;
+ }
+ /* fall through */
default:
error("illegal option: %c", text[-1]);
break;
- case 'o': /* ignore garbage after #else or #endif */
- options['o'] = 1;
+ case 'A' : /* for Amake */
+ case 'd' : /* dependency generation */
+ do_dependencies = 1;
+ if (*text) {
+ dep_file = text;
+ }
+ else {
+ do_preprocess = 0;
+ }
break;
+ case 'i':
+ case 'm':
+ case 'o': /* ignore garbage after #else or #endif */
case 'C' : /* comment output */
- options['C'] = 1;
+ options[*(text-1)] = 1;
break;
case 'D' : /* -Dname : predefine name */
{