aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--lib.c86
-rw-r--r--pre-process.c10
-rw-r--r--symbol.c2
-rw-r--r--token.h7
-rw-r--r--tokenize.c14
-rw-r--r--validation/cast-kinds-check.c1
6 files changed, 103 insertions, 17 deletions
diff --git a/lib.c b/lib.c
index 4e8d7b45..dcbbb5b3 100644
--- a/lib.c
+++ b/lib.c
@@ -49,22 +49,98 @@
#include "version.h"
#include "bits.h"
+static int prettify(const char **fnamep)
+{
+ const char *name = *fnamep;
+ int len = strlen(name);
+
+ if (len > 2 && !memcmp(name, "./", 2)) {
+ name += 2;
+ len -= 2;
+ }
+
+ *fnamep = name;
+ return len;
+}
+
+static const char *show_include_chain(int stream, const char *base)
+{
+ static char buffer[200];
+ int len = 0;
+
+ while ((stream = stream_prev(stream)) >= 0) {
+ const char *p = stream_name(stream);
+ int pretty_len;
+
+ if (p == base)
+ break;
+
+ pretty_len = prettify(&p);
+ if (pretty_len <= 0)
+ break;
+
+ /*
+ * At worst, we'll need " (through %s, ...)" in addition to the
+ * new filename
+ */
+ if (pretty_len + len + 20 > sizeof(buffer)) {
+ if (!len)
+ return "";
+ memcpy(buffer+len, ", ...", 5);
+ len += 5;
+ break;
+ }
+
+ if (!len) {
+ memcpy(buffer, " (through ", 10);
+ len = 10;
+ } else {
+ buffer[len++] = ',';
+ buffer[len++] = ' ';
+ }
+
+ memcpy(buffer+len, p, pretty_len);
+ len += pretty_len;
+ }
+ if (!len)
+ return "";
+
+ buffer[len] = ')';
+ buffer[len+1] = 0;
+ return buffer;
+}
+
+static const char *show_stream_name(struct position pos)
+{
+ const char *name = stream_name(pos.stream);
+ static const char *last;
+
+ if (name == base_filename)
+ return name;
+ if (name == last)
+ return name;
+ last = name;
+
+ fprintf(stderr, "%s: note: in included file%s:\n",
+ base_filename,
+ show_include_chain(pos.stream, base_filename));
+ return name;
+}
static void do_warn(const char *type, struct position pos, const char * fmt, va_list args)
{
static char buffer[512];
- const char *name;
/* Shut up warnings if position is bad_token.pos */
if (pos.type == TOKEN_BAD)
return;
vsprintf(buffer, fmt, args);
- name = stream_name(pos.stream);
-
+
fflush(stdout);
fprintf(stderr, "%s:%d:%d: %s%s%s\n",
- name, pos.line, pos.pos, diag_prefix, type, buffer);
+ show_stream_name(pos), pos.line, pos.pos,
+ diag_prefix, type, buffer);
}
static int show_info = 1;
@@ -275,7 +351,7 @@ static struct symbol_list *sparse_file(const char *filename)
base_filename = filename;
// Tokenize the input stream
- token = tokenize(filename, fd, NULL, includepath);
+ token = tokenize(filename, fd, -1, NULL, includepath);
close(fd);
return sparse_tokenstream(token);
diff --git a/pre-process.c b/pre-process.c
index 403e3507..6f4bf897 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -894,7 +894,7 @@ static void set_stream_include_path(struct stream *stream)
#define PATH_MAX 4096 // for Hurd where it's not defined
#endif
-static int try_include(const char *path, const char *filename, int flen, struct token **where, const char **next_path)
+static int try_include(struct position pos, const char *path, const char *filename, int flen, struct token **where, const char **next_path)
{
int fd;
int plen = strlen(path);
@@ -911,7 +911,7 @@ static int try_include(const char *path, const char *filename, int flen, struct
fd = open(fullname, O_RDONLY);
if (fd >= 0) {
char *streamname = xmemdup(fullname, plen + flen);
- *where = tokenize(streamname, fd, *where, next_path);
+ *where = tokenize(streamname, fd, pos.stream, *where, next_path);
close(fd);
return 1;
}
@@ -923,7 +923,7 @@ static int do_include_path(const char **pptr, struct token **list, struct token
const char *path;
while ((path = *pptr++) != NULL) {
- if (!try_include(path, filename, flen, list, pptr))
+ if (!try_include(token->pos, path, filename, flen, list, pptr))
continue;
return 1;
}
@@ -966,7 +966,7 @@ static int handle_include_path(struct stream *stream, struct token **list, struc
/* Absolute path? */
if (filename[0] == '/') {
- if (try_include("", filename, flen, list, includepath))
+ if (try_include(token->pos, "", filename, flen, list, includepath))
return 0;
goto out;
}
@@ -2091,7 +2091,7 @@ static void create_arglist(struct symbol *sym, int count)
static void init_preprocessor(void)
{
int i;
- int stream = init_stream("preprocessor", -1, includepath);
+ int stream = init_stream("preprocessor", -1, includepath, -1);
static struct {
const char *name;
int (*handler)(struct stream *, struct token **, struct token *);
diff --git a/symbol.c b/symbol.c
index c0ca79e4..2cc9f82d 100644
--- a/symbol.c
+++ b/symbol.c
@@ -776,7 +776,7 @@ struct symbol zero_int;
void init_symbols(void)
{
- int stream = init_stream("builtin", -1, includepath);
+ int stream = init_stream("builtin", -1, includepath, -1);
#define __IDENT(n,str,res) \
hash_ident(&n)
diff --git a/token.h b/token.h
index c5fdf3d0..6d2b0b65 100644
--- a/token.h
+++ b/token.h
@@ -49,7 +49,7 @@ enum constantfile {
extern const char *includepath[];
struct stream {
- int fd;
+ int fd, prev;
const char *name;
const char *path; // input-file path - see set_stream_include_path()
const char **next_path;
@@ -214,7 +214,8 @@ static inline struct token *containing_token(struct token **p)
extern struct token eof_token_entry;
#define eof_token(x) ((x) == &eof_token_entry)
-extern int init_stream(const char *, int fd, const char **next_path);
+extern int init_stream(const char *, int fd, const char **next_path, int prev_stream);
+extern int stream_prev(int stream);
extern const char *stream_name(int stream);
extern struct ident *hash_ident(struct ident *);
extern struct ident *built_in_ident(const char *);
@@ -224,7 +225,7 @@ extern const char *show_ident(const struct ident *);
extern const char *show_string(const struct string *string);
extern const char *show_token(const struct token *);
extern const char *quote_token(const struct token *);
-extern struct token * tokenize(const char *, int, struct token *, const char **next_path);
+extern struct token * tokenize(const char *, int, int, struct token *, const char **next_path);
extern struct token * tokenize_buffer(void *, unsigned long, struct token **);
extern void show_identifier_stats(void);
diff --git a/tokenize.c b/tokenize.c
index d3371e1e..c5ba6e6b 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -62,6 +62,13 @@ const char *stream_name(int stream)
return input_streams[stream].name;
}
+int stream_prev(int stream)
+{
+ if (stream < 0 || stream > input_stream_nr)
+ return -1;
+ return input_streams[stream].prev;
+}
+
static struct position stream_pos(stream_t *stream)
{
struct position pos;
@@ -300,7 +307,7 @@ int *hash_stream(const char *name)
return input_stream_hashes + hash;
}
-int init_stream(const char *name, int fd, const char **next_path)
+int init_stream(const char *name, int fd, const char **next_path, int prev_stream)
{
int stream = input_stream_nr, *hash;
struct stream *current;
@@ -319,6 +326,7 @@ int init_stream(const char *name, int fd, const char **next_path)
current->next_path = next_path;
current->path = NULL;
current->constant = CONSTANT_FILE_MAYBE;
+ current->prev = prev_stream;
input_stream_nr = stream+1;
hash = hash_stream(name);
current->next_stream = *hash;
@@ -1006,14 +1014,14 @@ struct token * tokenize_buffer(void *buffer, unsigned long size, struct token **
return begin;
}
-struct token * tokenize(const char *name, int fd, struct token *endtoken, const char **next_path)
+struct token * tokenize(const char *name, int fd, int prev_stream, struct token *endtoken, const char **next_path)
{
struct token *begin, *end;
stream_t stream;
unsigned char buffer[BUFSIZE];
int idx;
- idx = init_stream(name, fd, next_path);
+ idx = init_stream(name, fd, next_path, prev_stream);
if (idx < 0) {
// info(endtoken->pos, "File %s is const", name);
return endtoken;
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index 0c0cd673..32a106d4 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -6,6 +6,7 @@
* check-assert: sizeof(long) == 8
*
* check-error-start
+cast-kinds-check.c: note: in included file:
optim/cast-kinds.c:5:45: warning: cast drops bits
optim/cast-kinds.c:6:47: warning: cast drops bits
optim/cast-kinds.c:7:46: warning: cast drops bits