diff options
Diffstat (limited to 'scripts/dtc/srcpos.c')
| -rw-r--r-- | scripts/dtc/srcpos.c | 153 | 
1 files changed, 138 insertions, 15 deletions
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index cb6ed0e3e5e4..41f83700ee91 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -33,6 +33,9 @@ struct search_path {  /* This is the list of directories that we search for source files */  static struct search_path *search_path_head, **search_path_tail; +/* Detect infinite include recursion. */ +#define MAX_SRCFILE_DEPTH     (100) +static int srcfile_depth; /* = 0 */  static char *get_dirname(const char *path)  { @@ -51,11 +54,51 @@ static char *get_dirname(const char *path)  FILE *depfile; /* = NULL */  struct srcfile_state *current_srcfile; /* = NULL */ +static char *initial_path; /* = NULL */ +static int initial_pathlen; /* = 0 */ +static bool initial_cpp = true; -/* Detect infinite include recursion. */ -#define MAX_SRCFILE_DEPTH     (100) -static int srcfile_depth; /* = 0 */ +static void set_initial_path(char *fname) +{ +	int i, len = strlen(fname); +	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; +}  /**   * Try to open a file in a given directory. @@ -157,6 +200,9 @@ void srcfile_push(const char *fname)  	srcfile->colno = 1;  	current_srcfile = srcfile; + +	if (srcfile_depth == 1) +		set_initial_path(srcfile->name);  }  bool srcfile_pop(void) @@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)  	search_path_tail = &node->next;  } -/* - * The empty source position. - */ - -struct srcpos srcpos_empty = { -	.first_line = 0, -	.first_column = 0, -	.last_line = 0, -	.last_column = 0, -	.file = NULL, -}; -  void srcpos_update(struct srcpos *pos, const char *text, int len)  {  	int i; @@ -234,13 +268,35 @@ struct srcpos *  srcpos_copy(struct srcpos *pos)  {  	struct srcpos *pos_new; +	struct srcfile_state *srcfile_state; + +	if (!pos) +		return NULL;  	pos_new = xmalloc(sizeof(struct srcpos)); +	assert(pos->next == NULL);  	memcpy(pos_new, pos, sizeof(struct srcpos)); +	/* allocate without free */ +	srcfile_state = xmalloc(sizeof(struct srcfile_state)); +	memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state)); +	pos_new->file = srcfile_state; +  	return pos_new;  } +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; +} +  char *  srcpos_string(struct srcpos *pos)  { @@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)  	return pos_str;  } +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); +} +  void srcpos_verror(struct srcpos *pos, const char *prefix,  		   const char *fmt, va_list va)  { @@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)  {  	current_srcfile->name = f;  	current_srcfile->lineno = l; + +	if (initial_cpp) { +		initial_cpp = false; +		set_initial_path(f); +	}  }  | 
