diff options
author | John Bonesio <bones@secretlab.ca> | 2010-11-18 00:28:20 +0100 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-01-04 00:02:49 +0100 |
commit | 658f29a51e9830e620bb9a1ce3534b318a38bfeb (patch) | |
tree | e6cc7cd9b9e17d97308619fd8516b77bcc038114 /scripts/dtc/srcpos.c | |
parent | of/device: Don't register disabled devices (diff) | |
download | linux-658f29a51e9830e620bb9a1ce3534b318a38bfeb.tar.xz linux-658f29a51e9830e620bb9a1ce3534b318a38bfeb.zip |
of/flattree: Update dtc to current mainline.
Pull in recent changes from the main dtc repository. These changes
primarily allow multiple device trees to be declared which are merged
by dtc. This feature allows us to include a basic dts file and then
provide more information for the specific system through the merging
functionality.
Changes pulled from git://git.jdl.com/software/dtc.git
commit id: 37c0b6a0, "dtc: Add code to make diffing trees easier"
Signed-off-by: John Bonesio <bones@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'scripts/dtc/srcpos.c')
-rw-r--r-- | scripts/dtc/srcpos.c | 258 |
1 files changed, 195 insertions, 63 deletions
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 9641b7628b4d..2dbc874288ca 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -17,100 +17,232 @@ * USA */ +#define _GNU_SOURCE + +#include <stdio.h> + #include "dtc.h" #include "srcpos.h" -/* - * Like yylineno, this is the current open file pos. - */ -struct dtc_file *srcpos_file; +static char *dirname(const char *path) +{ + const char *slash = strrchr(path, '/'); + + if (slash) { + int len = slash - path; + char *dir = xmalloc(len + 1); + + memcpy(dir, path, len); + dir[len] = '\0'; + return dir; + } + return NULL; +} + +struct srcfile_state *current_srcfile; /* = NULL */ -static int dtc_open_one(struct dtc_file *file, - const char *search, - const char *fname) +/* Detect infinite include recursion. */ +#define MAX_SRCFILE_DEPTH (100) +static int srcfile_depth; /* = 0 */ + +FILE *srcfile_relative_open(const char *fname, char **fullnamep) { + FILE *f; char *fullname; - if (search) { - fullname = xmalloc(strlen(search) + strlen(fname) + 2); - - strcpy(fullname, search); - strcat(fullname, "/"); - strcat(fullname, fname); + if (streq(fname, "-")) { + f = stdin; + fullname = xstrdup("<stdin>"); } else { - fullname = strdup(fname); + if (!current_srcfile || !current_srcfile->dir + || (fname[0] == '/')) + fullname = xstrdup(fname); + else + fullname = join_path(current_srcfile->dir, fname); + + f = fopen(fullname, "r"); + if (!f) + die("Couldn't open \"%s\": %s\n", fname, + strerror(errno)); } - file->file = fopen(fullname, "r"); - if (!file->file) { + if (fullnamep) + *fullnamep = fullname; + else free(fullname); - return 0; - } - file->name = fullname; - return 1; + return f; } +void srcfile_push(const char *fname) +{ + struct srcfile_state *srcfile; + + if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) + die("Includes nested too deeply"); + + srcfile = xmalloc(sizeof(*srcfile)); + + srcfile->f = srcfile_relative_open(fname, &srcfile->name); + srcfile->dir = dirname(srcfile->name); + srcfile->prev = current_srcfile; + + srcfile->lineno = 1; + srcfile->colno = 1; + + current_srcfile = srcfile; +} -struct dtc_file *dtc_open_file(const char *fname, - const struct search_path *search) +int srcfile_pop(void) { - static const struct search_path default_search = { NULL, NULL, NULL }; + struct srcfile_state *srcfile = current_srcfile; - struct dtc_file *file; - const char *slash; + assert(srcfile); - file = xmalloc(sizeof(struct dtc_file)); + current_srcfile = srcfile->prev; - slash = strrchr(fname, '/'); - if (slash) { - char *dir = xmalloc(slash - fname + 1); + if (fclose(srcfile->f)) + die("Error closing \"%s\": %s\n", srcfile->name, + strerror(errno)); - memcpy(dir, fname, slash - fname); - dir[slash - fname] = 0; - file->dir = dir; - } else { - file->dir = NULL; - } + /* 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. */ - if (streq(fname, "-")) { - file->name = "stdin"; - file->file = stdin; - return file; - } + return current_srcfile ? 1 : 0; +} - if (fname[0] == '/') { - file->file = fopen(fname, "r"); - if (!file->file) - goto fail; +/* + * The empty source position. + */ - file->name = strdup(fname); - return file; - } +struct srcpos srcpos_empty = { + .first_line = 0, + .first_column = 0, + .last_line = 0, + .last_column = 0, + .file = NULL, +}; - if (!search) - search = &default_search; +#define TAB_SIZE 8 - while (search) { - if (dtc_open_one(file, search->dir, fname)) - return file; +void srcpos_update(struct srcpos *pos, const char *text, int len) +{ + 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 if (text[i] == '\t') { + current_srcfile->colno = + ALIGN(current_srcfile->colno, TAB_SIZE); + } else { + current_srcfile->colno++; + } + + pos->last_line = current_srcfile->lineno; + pos->last_column = current_srcfile->colno; +} - if (errno != ENOENT) - goto fail; +struct srcpos * +srcpos_copy(struct srcpos *pos) +{ + struct srcpos *pos_new; - search = search->next; - } + pos_new = xmalloc(sizeof(struct srcpos)); + memcpy(pos_new, pos, sizeof(struct srcpos)); + + return pos_new; +} + + + +void +srcpos_dump(struct srcpos *pos) +{ + printf("file : \"%s\"\n", + pos->file ? (char *) pos->file : "<no file>"); + printf("first_line : %d\n", pos->first_line); + printf("first_column: %d\n", pos->first_column); + printf("last_line : %d\n", pos->last_line); + printf("last_column : %d\n", pos->last_column); + printf("file : %s\n", pos->file->name); +} -fail: - die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); + +char * +srcpos_string(struct srcpos *pos) +{ + const char *fname = "<no-file>"; + char *pos_str; + int rc; + + if (pos) + fname = pos->file->name; + + + if (pos->first_line != pos->last_line) + rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, + pos->first_line, pos->first_column, + pos->last_line, pos->last_column); + else if (pos->first_column != pos->last_column) + rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, + pos->first_line, pos->first_column, + pos->last_column); + else + rc = asprintf(&pos_str, "%s:%d.%d", fname, + pos->first_line, pos->first_column); + + if (rc == -1) + die("Couldn't allocate in srcpos string"); + + return pos_str; +} + +void +srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) +{ + const char *srcstr; + + srcstr = srcpos_string(pos); + + fprintf(stdout, "Error: %s ", srcstr); + vfprintf(stdout, fmt, va); + fprintf(stdout, "\n"); } -void dtc_close_file(struct dtc_file *file) +void +srcpos_error(struct srcpos *pos, char const *fmt, ...) { - if (fclose(file->file)) - die("Error closing \"%s\": %s\n", file->name, strerror(errno)); + va_list va; + + va_start(va, fmt); + srcpos_verror(pos, fmt, va); + va_end(va); +} + + +void +srcpos_warn(struct srcpos *pos, char const *fmt, ...) +{ + const char *srcstr; + va_list va; + va_start(va, fmt); + + srcstr = srcpos_string(pos); + + fprintf(stderr, "Warning: %s ", srcstr); + vfprintf(stderr, fmt, va); + fprintf(stderr, "\n"); - free(file->dir); - free(file); + va_end(va); } |