2019-06-20 23:19:38 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2007-03-23 21:18:41 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
|
|
|
|
*/
|
|
|
|
|
2008-09-12 20:39:49 +02:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2007-03-23 21:18:41 +01:00
|
|
|
#include "dtc.h"
|
|
|
|
#include "srcpos.h"
|
|
|
|
|
2012-03-15 04:04:13 +01:00
|
|
|
/* A node in our list of directories to search for source/include files */
|
|
|
|
struct search_path {
|
|
|
|
struct search_path *next; /* next node in list, NULL for end */
|
|
|
|
const char *dirname; /* name of directory to search */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* This is the list of directories that we search for source files */
|
|
|
|
static struct search_path *search_path_head, **search_path_tail;
|
|
|
|
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
/* Detect infinite include recursion. */
|
2021-01-13 00:13:23 +01:00
|
|
|
#define MAX_SRCFILE_DEPTH (200)
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
static int srcfile_depth; /* = 0 */
|
2008-09-12 20:39:49 +02:00
|
|
|
|
2014-01-25 02:19:10 +01:00
|
|
|
static char *get_dirname(const char *path)
|
2009-12-08 04:24:42 +01:00
|
|
|
{
|
|
|
|
const char *slash = strrchr(path, '/');
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (slash) {
|
|
|
|
int len = slash - path;
|
|
|
|
char *dir = xmalloc(len + 1);
|
2008-09-12 20:39:49 +02:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
memcpy(dir, path, len);
|
|
|
|
dir[len] = '\0';
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-09-12 20:39:49 +02:00
|
|
|
|
2012-01-12 19:31:00 +01:00
|
|
|
FILE *depfile; /* = NULL */
|
2009-12-08 04:24:42 +01:00
|
|
|
struct srcfile_state *current_srcfile; /* = NULL */
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
static char *initial_path; /* = NULL */
|
|
|
|
static int initial_pathlen; /* = 0 */
|
|
|
|
static bool initial_cpp = true;
|
2008-09-12 20:39:49 +02:00
|
|
|
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
static void set_initial_path(char *fname)
|
|
|
|
{
|
|
|
|
int i, len = strlen(fname);
|
2008-09-12 20:39:49 +02:00
|
|
|
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
xasprintf(&initial_path, "%s", fname);
|
|
|
|
initial_pathlen = 0;
|
|
|
|
for (i = 0; i != len; i++)
|
|
|
|
if (initial_path[i] == '/')
|
|
|
|
initial_pathlen++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *shorten_to_initial_path(char *fname)
|
|
|
|
{
|
|
|
|
char *p1, *p2, *prevslash1 = NULL;
|
|
|
|
int slashes = 0;
|
|
|
|
|
|
|
|
for (p1 = fname, p2 = initial_path; *p1 && *p2; p1++, p2++) {
|
|
|
|
if (*p1 != *p2)
|
|
|
|
break;
|
|
|
|
if (*p1 == '/') {
|
|
|
|
prevslash1 = p1;
|
|
|
|
slashes++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p1 = prevslash1 + 1;
|
|
|
|
if (prevslash1) {
|
|
|
|
int diff = initial_pathlen - slashes, i, j;
|
|
|
|
int restlen = strlen(fname) - (p1 - fname);
|
|
|
|
char *res;
|
|
|
|
|
|
|
|
res = xmalloc((3 * diff) + restlen + 1);
|
|
|
|
for (i = 0, j = 0; i != diff; i++) {
|
|
|
|
res[j++] = '.';
|
|
|
|
res[j++] = '.';
|
|
|
|
res[j++] = '/';
|
|
|
|
}
|
|
|
|
strcpy(res + j, p1);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-03-15 04:04:13 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Try to open a file in a given directory.
|
|
|
|
*
|
|
|
|
* If the filename is an absolute path, then dirname is ignored. If it is a
|
|
|
|
* relative path, then we look in that directory for the file.
|
|
|
|
*
|
|
|
|
* @param dirname Directory to look in, or NULL for none
|
|
|
|
* @param fname Filename to look for
|
|
|
|
* @param fp Set to NULL if file did not open
|
|
|
|
* @return allocated filename on success (caller must free), NULL on failure
|
|
|
|
*/
|
|
|
|
static char *try_open(const char *dirname, const char *fname, FILE **fp)
|
|
|
|
{
|
|
|
|
char *fullname;
|
|
|
|
|
|
|
|
if (!dirname || fname[0] == '/')
|
|
|
|
fullname = xstrdup(fname);
|
|
|
|
else
|
|
|
|
fullname = join_path(dirname, fname);
|
|
|
|
|
2014-06-19 13:12:27 +02:00
|
|
|
*fp = fopen(fullname, "rb");
|
2012-03-15 04:04:13 +01:00
|
|
|
if (!*fp) {
|
|
|
|
free(fullname);
|
|
|
|
fullname = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fullname;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Open a file for read access
|
|
|
|
*
|
|
|
|
* If it is a relative filename, we search the full search path for it.
|
|
|
|
*
|
|
|
|
* @param fname Filename to open
|
|
|
|
* @param fp Returns pointer to opened FILE, or NULL on failure
|
|
|
|
* @return pointer to allocated filename, which caller must free
|
|
|
|
*/
|
|
|
|
static char *fopen_any_on_path(const char *fname, FILE **fp)
|
|
|
|
{
|
|
|
|
const char *cur_dir = NULL;
|
|
|
|
struct search_path *node;
|
|
|
|
char *fullname;
|
|
|
|
|
|
|
|
/* Try current directory first */
|
|
|
|
assert(fp);
|
|
|
|
if (current_srcfile)
|
|
|
|
cur_dir = current_srcfile->dir;
|
|
|
|
fullname = try_open(cur_dir, fname, fp);
|
|
|
|
|
|
|
|
/* Failing that, try each search path in turn */
|
|
|
|
for (node = search_path_head; !*fp && node; node = node->next)
|
|
|
|
fullname = try_open(node->dirname, fname, fp);
|
|
|
|
|
|
|
|
return fullname;
|
|
|
|
}
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
FILE *srcfile_relative_open(const char *fname, char **fullnamep)
|
2007-03-23 21:18:41 +01:00
|
|
|
{
|
2009-12-08 04:24:42 +01:00
|
|
|
FILE *f;
|
2008-01-04 00:43:31 +01:00
|
|
|
char *fullname;
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (streq(fname, "-")) {
|
|
|
|
f = stdin;
|
|
|
|
fullname = xstrdup("<stdin>");
|
2008-01-04 00:43:31 +01:00
|
|
|
} else {
|
2012-03-15 04:04:13 +01:00
|
|
|
fullname = fopen_any_on_path(fname, &f);
|
2009-12-08 04:24:42 +01:00
|
|
|
if (!f)
|
|
|
|
die("Couldn't open \"%s\": %s\n", fname,
|
|
|
|
strerror(errno));
|
2008-01-04 00:43:31 +01:00
|
|
|
}
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2012-01-12 19:31:00 +01:00
|
|
|
if (depfile)
|
|
|
|
fprintf(depfile, " %s", fullname);
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (fullnamep)
|
|
|
|
*fullnamep = fullname;
|
|
|
|
else
|
2008-01-04 00:43:31 +01:00
|
|
|
free(fullname);
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
return f;
|
2007-03-23 21:18:41 +01:00
|
|
|
}
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
void srcfile_push(const char *fname)
|
2007-03-23 21:18:41 +01:00
|
|
|
{
|
2009-12-08 04:24:42 +01:00
|
|
|
struct srcfile_state *srcfile;
|
2008-01-04 00:43:31 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
|
|
|
|
die("Includes nested too deeply");
|
2008-01-04 00:43:31 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
srcfile = xmalloc(sizeof(*srcfile));
|
2008-01-04 00:43:31 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
srcfile->f = srcfile_relative_open(fname, &srcfile->name);
|
2014-01-25 02:19:10 +01:00
|
|
|
srcfile->dir = get_dirname(srcfile->name);
|
2009-12-08 04:24:42 +01:00
|
|
|
srcfile->prev = current_srcfile;
|
2009-12-08 04:24:42 +01:00
|
|
|
|
|
|
|
srcfile->lineno = 1;
|
|
|
|
srcfile->colno = 1;
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
current_srcfile = srcfile;
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
|
|
|
|
if (srcfile_depth == 1)
|
|
|
|
set_initial_path(srcfile->name);
|
2009-12-08 04:24:42 +01:00
|
|
|
}
|
2008-01-04 22:10:45 +01:00
|
|
|
|
2013-10-28 11:06:53 +01:00
|
|
|
bool srcfile_pop(void)
|
2009-12-08 04:24:42 +01:00
|
|
|
{
|
|
|
|
struct srcfile_state *srcfile = current_srcfile;
|
2008-01-04 22:10:45 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
assert(srcfile);
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
current_srcfile = srcfile->prev;
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (fclose(srcfile->f))
|
2009-12-08 04:24:42 +01:00
|
|
|
die("Error closing \"%s\": %s\n", srcfile->name,
|
|
|
|
strerror(errno));
|
2008-01-04 00:43:31 +01:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
/* FIXME: We allow the srcfile_state structure to leak,
|
|
|
|
* because it could still be referenced from a location
|
|
|
|
* variable being carried through the parser somewhere. To
|
|
|
|
* fix this we could either allocate all the files from a
|
|
|
|
* table, or use a pool allocator. */
|
2007-03-23 21:18:41 +01:00
|
|
|
|
2013-10-28 11:06:53 +01:00
|
|
|
return current_srcfile ? true : false;
|
2007-03-23 21:18:41 +01:00
|
|
|
}
|
|
|
|
|
2012-03-15 04:04:13 +01:00
|
|
|
void srcfile_add_search_path(const char *dirname)
|
|
|
|
{
|
|
|
|
struct search_path *node;
|
|
|
|
|
|
|
|
/* Create the node */
|
|
|
|
node = xmalloc(sizeof(*node));
|
|
|
|
node->next = NULL;
|
|
|
|
node->dirname = xstrdup(dirname);
|
|
|
|
|
|
|
|
/* Add to the end of our list */
|
|
|
|
if (search_path_tail)
|
|
|
|
*search_path_tail = node;
|
|
|
|
else
|
|
|
|
search_path_head = node;
|
|
|
|
search_path_tail = &node->next;
|
|
|
|
}
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
void srcpos_update(struct srcpos *pos, const char *text, int len)
|
2009-12-08 04:24:42 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pos->file = current_srcfile;
|
|
|
|
|
|
|
|
pos->first_line = current_srcfile->lineno;
|
|
|
|
pos->first_column = current_srcfile->colno;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
if (text[i] == '\n') {
|
|
|
|
current_srcfile->lineno++;
|
|
|
|
current_srcfile->colno = 1;
|
|
|
|
} else {
|
|
|
|
current_srcfile->colno++;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos->last_line = current_srcfile->lineno;
|
|
|
|
pos->last_column = current_srcfile->colno;
|
|
|
|
}
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
struct srcpos *
|
|
|
|
srcpos_copy(struct srcpos *pos)
|
2008-09-12 20:39:49 +02:00
|
|
|
{
|
2009-12-08 04:24:42 +01:00
|
|
|
struct srcpos *pos_new;
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:29:59 +01:00
|
|
|
struct srcfile_state *srcfile_state;
|
|
|
|
|
|
|
|
if (!pos)
|
|
|
|
return NULL;
|
2008-09-12 20:39:49 +02:00
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
pos_new = xmalloc(sizeof(struct srcpos));
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:29:59 +01:00
|
|
|
assert(pos->next == NULL);
|
2009-12-08 04:24:42 +01:00
|
|
|
memcpy(pos_new, pos, sizeof(struct srcpos));
|
2008-09-12 20:39:49 +02:00
|
|
|
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:29:59 +01:00
|
|
|
/* allocate without free */
|
|
|
|
srcfile_state = xmalloc(sizeof(struct srcfile_state));
|
|
|
|
memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state));
|
|
|
|
pos_new->file = srcfile_state;
|
|
|
|
|
2008-09-12 20:39:49 +02:00
|
|
|
return pos_new;
|
|
|
|
}
|
|
|
|
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:29:59 +01:00
|
|
|
struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
|
|
|
|
{
|
|
|
|
struct srcpos *p;
|
|
|
|
|
|
|
|
if (!pos)
|
|
|
|
return newtail;
|
|
|
|
|
|
|
|
for (p = pos; p->next != NULL; p = p->next);
|
|
|
|
p->next = newtail;
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2008-09-12 20:39:49 +02:00
|
|
|
char *
|
2009-12-08 04:24:42 +01:00
|
|
|
srcpos_string(struct srcpos *pos)
|
2008-09-12 20:39:49 +02:00
|
|
|
{
|
2009-12-08 04:24:42 +01:00
|
|
|
const char *fname = "<no-file>";
|
2008-09-12 20:39:49 +02:00
|
|
|
char *pos_str;
|
|
|
|
|
2017-02-08 07:39:36 +01:00
|
|
|
if (pos->file && pos->file->name)
|
2008-09-12 20:39:49 +02:00
|
|
|
fname = pos->file->name;
|
|
|
|
|
|
|
|
|
2009-12-08 04:24:42 +01:00
|
|
|
if (pos->first_line != pos->last_line)
|
2016-05-25 07:15:36 +02:00
|
|
|
xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
|
|
|
|
pos->first_line, pos->first_column,
|
|
|
|
pos->last_line, pos->last_column);
|
2009-12-08 04:24:42 +01:00
|
|
|
else if (pos->first_column != pos->last_column)
|
2016-05-25 07:15:36 +02:00
|
|
|
xasprintf(&pos_str, "%s:%d.%d-%d", fname,
|
|
|
|
pos->first_line, pos->first_column,
|
|
|
|
pos->last_column);
|
2009-12-08 04:24:42 +01:00
|
|
|
else
|
2016-05-25 07:15:36 +02:00
|
|
|
xasprintf(&pos_str, "%s:%d.%d", fname,
|
|
|
|
pos->first_line, pos->first_column);
|
2008-09-12 20:39:49 +02:00
|
|
|
|
|
|
|
return pos_str;
|
|
|
|
}
|
|
|
|
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
static char *
|
|
|
|
srcpos_string_comment(struct srcpos *pos, bool first_line, int level)
|
|
|
|
{
|
|
|
|
char *pos_str, *fname, *first, *rest;
|
|
|
|
bool fresh_fname = false;
|
|
|
|
|
|
|
|
if (!pos) {
|
|
|
|
if (level > 1) {
|
|
|
|
xasprintf(&pos_str, "<no-file>:<no-line>");
|
|
|
|
return pos_str;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pos->file)
|
|
|
|
fname = "<no-file>";
|
|
|
|
else if (!pos->file->name)
|
|
|
|
fname = "<no-filename>";
|
|
|
|
else if (level > 1)
|
|
|
|
fname = pos->file->name;
|
|
|
|
else {
|
|
|
|
fname = shorten_to_initial_path(pos->file->name);
|
|
|
|
if (fname)
|
|
|
|
fresh_fname = true;
|
|
|
|
else
|
|
|
|
fname = pos->file->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (level > 1)
|
|
|
|
xasprintf(&first, "%s:%d:%d-%d:%d", fname,
|
|
|
|
pos->first_line, pos->first_column,
|
|
|
|
pos->last_line, pos->last_column);
|
|
|
|
else
|
|
|
|
xasprintf(&first, "%s:%d", fname,
|
|
|
|
first_line ? pos->first_line : pos->last_line);
|
|
|
|
|
|
|
|
if (fresh_fname)
|
|
|
|
free(fname);
|
|
|
|
|
|
|
|
if (pos->next != NULL) {
|
|
|
|
rest = srcpos_string_comment(pos->next, first_line, level);
|
|
|
|
xasprintf(&pos_str, "%s, %s", first, rest);
|
|
|
|
free(first);
|
|
|
|
free(rest);
|
|
|
|
} else {
|
|
|
|
pos_str = first;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *srcpos_string_first(struct srcpos *pos, int level)
|
|
|
|
{
|
|
|
|
return srcpos_string_comment(pos, true, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *srcpos_string_last(struct srcpos *pos, int level)
|
|
|
|
{
|
|
|
|
return srcpos_string_comment(pos, false, level);
|
|
|
|
}
|
|
|
|
|
2014-01-01 13:27:31 +01:00
|
|
|
void srcpos_verror(struct srcpos *pos, const char *prefix,
|
|
|
|
const char *fmt, va_list va)
|
2010-10-20 23:44:58 +02:00
|
|
|
{
|
2014-01-01 13:23:54 +01:00
|
|
|
char *srcstr;
|
2010-10-20 23:44:58 +02:00
|
|
|
|
2014-01-01 13:17:39 +01:00
|
|
|
srcstr = srcpos_string(pos);
|
2010-10-20 23:44:58 +02:00
|
|
|
|
2014-01-01 13:27:31 +01:00
|
|
|
fprintf(stderr, "%s: %s ", prefix, srcstr);
|
2014-01-01 13:17:39 +01:00
|
|
|
vfprintf(stderr, fmt, va);
|
|
|
|
fprintf(stderr, "\n");
|
2014-01-01 13:23:54 +01:00
|
|
|
|
|
|
|
free(srcstr);
|
2010-10-20 23:44:58 +02:00
|
|
|
}
|
2008-09-12 20:39:49 +02:00
|
|
|
|
2014-01-01 13:27:31 +01:00
|
|
|
void srcpos_error(struct srcpos *pos, const char *prefix,
|
|
|
|
const char *fmt, ...)
|
2008-09-12 20:39:49 +02:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
|
2010-10-20 23:44:58 +02:00
|
|
|
va_start(va, fmt);
|
2014-01-01 13:27:31 +01:00
|
|
|
srcpos_verror(pos, prefix, fmt, va);
|
2008-09-12 20:39:49 +02:00
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
|
2012-09-28 01:11:05 +02:00
|
|
|
void srcpos_set_line(char *f, int l)
|
|
|
|
{
|
|
|
|
current_srcfile->name = f;
|
|
|
|
current_srcfile->lineno = l;
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-11-16 17:30:00 +01:00
|
|
|
|
|
|
|
if (initial_cpp) {
|
|
|
|
initial_cpp = false;
|
|
|
|
set_initial_path(f);
|
|
|
|
}
|
2012-09-28 01:11:05 +02:00
|
|
|
}
|