summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--convert-dtsv0-lexer.l6
-rw-r--r--dtc-lexer.l91
-rw-r--r--dtc-parser.y18
-rw-r--r--dtc.c24
-rw-r--r--dtc.h4
-rw-r--r--flattree.c24
-rw-r--r--srcpos.c151
-rw-r--r--srcpos.h27
-rw-r--r--treesource.c4
-rw-r--r--util.c24
-rw-r--r--util.h1
11 files changed, 141 insertions, 233 deletions
diff --git a/convert-dtsv0-lexer.l b/convert-dtsv0-lexer.l
index 59137f1..edb9110 100644
--- a/convert-dtsv0-lexer.l
+++ b/convert-dtsv0-lexer.l
@@ -210,8 +210,10 @@ static void convert_file(const char *fname)
memcpy(newname, fname, len);
memcpy(newname + len, suffix, sizeof(suffix));
- srcpos_file = dtc_open_file(fname, NULL);
- yyin = srcpos_file->file;
+ yyin = fopen(fname, "r");
+ if (!yyin)
+ die("Couldn't open input file %s: %s\n",
+ fname, strerror(errno));
yyout = fopen(newname, "w");
if (!yyout)
diff --git a/dtc-lexer.l b/dtc-lexer.l
index d142de5..12467c0 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -40,7 +40,7 @@ LINECOMMENT "//".*\n
#define YY_USER_ACTION \
{ \
- yylloc.file = srcpos_file; \
+ yylloc.file = current_srcfile; \
yylloc.first_line = yylineno; \
}
@@ -165,100 +165,29 @@ static int pop_input_file(void);
%%
-
-/*
- * Stack of nested include file contexts.
- */
-
-struct incl_file {
- struct dtc_file *file;
- YY_BUFFER_STATE yy_prev_buf;
- int yy_prev_lineno;
- struct incl_file *prev;
-};
-
-static struct incl_file *incl_file_stack;
-
-
-/*
- * Detect infinite include recursion.
- */
-#define MAX_INCLUDE_DEPTH (100)
-
-static int incl_depth = 0;
-
-
static void push_input_file(const char *filename)
{
- struct incl_file *incl_file;
- struct dtc_file *newfile;
- struct search_path search, *searchptr = NULL;
-
assert(filename);
- if (incl_depth++ >= MAX_INCLUDE_DEPTH)
- die("Includes nested too deeply");
-
- if (srcpos_file) {
- search.dir = srcpos_file->dir;
- search.next = NULL;
- search.prev = NULL;
- searchptr = &search;
- }
-
- newfile = dtc_open_file(filename, searchptr);
-
- incl_file = xmalloc(sizeof(struct incl_file));
-
- /*
- * Save current context.
- */
- incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
- incl_file->yy_prev_lineno = yylineno;
- incl_file->file = srcpos_file;
- incl_file->prev = incl_file_stack;
+ current_srcfile->lineno = yylineno;
- incl_file_stack = incl_file;
+ srcfile_push(filename);
- /*
- * Establish new context.
- */
- srcpos_file = newfile;
+ yyin = current_srcfile->f;
yylineno = 1;
- yyin = newfile->file;
- yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+
+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
}
static int pop_input_file(void)
{
- struct incl_file *incl_file;
-
- if (incl_file_stack == 0)
+ if (srcfile_pop() == 0)
return 0;
- dtc_close_file(srcpos_file);
-
- /*
- * Pop.
- */
- --incl_depth;
- incl_file = incl_file_stack;
- incl_file_stack = incl_file->prev;
-
- /*
- * Recover old context.
- */
- yy_delete_buffer(YY_CURRENT_BUFFER);
- yy_switch_to_buffer(incl_file->yy_prev_buf);
- yylineno = incl_file->yy_prev_lineno;
- srcpos_file = incl_file->file;
- yyin = incl_file->file ? incl_file->file->file : NULL;
-
- /*
- * Free old state.
- */
- free(incl_file);
+ yypop_buffer_state();
+ yylineno = current_srcfile->lineno;
+ yyin = current_srcfile->f;
return 1;
}
diff --git a/dtc-parser.y b/dtc-parser.y
index 31c14d7..b7c7dbd 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -169,33 +169,31 @@ propdata:
}
| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
{
- struct search_path path = { srcpos_file->dir, NULL, NULL };
- struct dtc_file *file = dtc_open_file($4.val, &path);
- struct data d = empty_data;
+ FILE *f = srcfile_relative_open($4.val, NULL);
+ struct data d;
if ($6 != 0)
- if (fseek(file->file, $6, SEEK_SET) != 0)
+ if (fseek(f, $6, SEEK_SET) != 0)
srcpos_error(&yylloc,
"Couldn't seek to offset %llu in \"%s\": %s",
(unsigned long long)$6,
$4.val,
strerror(errno));
- d = data_copy_file(file->file, $8);
+ d = data_copy_file(f, $8);
$$ = data_merge($1, d);
- dtc_close_file(file);
+ fclose(f);
}
| propdataprefix DT_INCBIN '(' DT_STRING ')'
{
- struct search_path path = { srcpos_file->dir, NULL, NULL };
- struct dtc_file *file = dtc_open_file($4.val, &path);
+ FILE *f = srcfile_relative_open($4.val, NULL);
struct data d = empty_data;
- d = data_copy_file(file->file, -1);
+ d = data_copy_file(f, -1);
$$ = data_merge($1, d);
- dtc_close_file(file);
+ fclose(f);
}
| propdata DT_LABEL
{
diff --git a/dtc.c b/dtc.c
index 800664c..8b31d20 100644
--- a/dtc.c
+++ b/dtc.c
@@ -32,30 +32,6 @@ int minsize; /* Minimum blob size */
int padsize; /* Additional padding to blob */
int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
-char *join_path(const char *path, const char *name)
-{
- int lenp = strlen(path);
- int lenn = strlen(name);
- int len;
- int needslash = 1;
- char *str;
-
- len = lenp + lenn + 2;
- if ((lenp > 0) && (path[lenp-1] == '/')) {
- needslash = 0;
- len--;
- }
-
- str = xmalloc(len);
- memcpy(str, path, lenp);
- if (needslash) {
- str[lenp] = '/';
- lenp++;
- }
- memcpy(str+lenp, name, lenn+1);
- return str;
-}
-
static void fill_fullpaths(struct node *tree, const char *prefix)
{
struct node *child;
diff --git a/dtc.h b/dtc.h
index 0d7f0ed..a85e5b7 100644
--- a/dtc.h
+++ b/dtc.h
@@ -224,8 +224,4 @@ struct boot_info *dt_from_source(const char *f);
struct boot_info *dt_from_fs(const char *dirname);
-/* misc */
-
-char *join_path(const char *path, const char *name);
-
#endif /* _DTC_H */
diff --git a/flattree.c b/flattree.c
index 3eb0201..8637407 100644
--- a/flattree.c
+++ b/flattree.c
@@ -797,7 +797,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
struct boot_info *dt_from_blob(const char *fname)
{
- struct dtc_file *dtcf;
+ FILE *f;
uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
uint32_t off_dt, off_str, off_mem_rsvmap;
int rc;
@@ -812,14 +812,14 @@ struct boot_info *dt_from_blob(const char *fname)
uint32_t val;
int flags = 0;
- dtcf = dtc_open_file(fname, NULL);
+ f = srcfile_relative_open(fname, NULL);
- rc = fread(&magic, sizeof(magic), 1, dtcf->file);
- if (ferror(dtcf->file))
+ rc = fread(&magic, sizeof(magic), 1, f);
+ if (ferror(f))
die("Error reading DT blob magic number: %s\n",
strerror(errno));
if (rc < 1) {
- if (feof(dtcf->file))
+ if (feof(f))
die("EOF reading DT blob magic number\n");
else
die("Mysterious short read reading magic number\n");
@@ -829,11 +829,11 @@ struct boot_info *dt_from_blob(const char *fname)
if (magic != FDT_MAGIC)
die("Blob has incorrect magic number\n");
- rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
- if (ferror(dtcf->file))
+ rc = fread(&totalsize, sizeof(totalsize), 1, f);
+ if (ferror(f))
die("Error reading DT blob size: %s\n", strerror(errno));
if (rc < 1) {
- if (feof(dtcf->file))
+ if (feof(f))
die("EOF reading DT blob size\n");
else
die("Mysterious short read reading blob size\n");
@@ -853,12 +853,12 @@ struct boot_info *dt_from_blob(const char *fname)
p = blob + sizeof(magic) + sizeof(totalsize);
while (sizeleft) {
- if (feof(dtcf->file))
+ if (feof(f))
die("EOF before reading %d bytes of DT blob\n",
totalsize);
- rc = fread(p, 1, sizeleft, dtcf->file);
- if (ferror(dtcf->file))
+ rc = fread(p, 1, sizeleft, f);
+ if (ferror(f))
die("Error reading DT blob: %s\n",
strerror(errno));
@@ -921,7 +921,7 @@ struct boot_info *dt_from_blob(const char *fname)
free(blob);
- dtc_close_file(dtcf);
+ fclose(f);
return build_boot_info(reservelist, tree, boot_cpuid_phys);
}
diff --git a/srcpos.c b/srcpos.c
index 8bb0c02..f08c1c3 100644
--- a/srcpos.c
+++ b/srcpos.c
@@ -25,117 +25,102 @@
#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, '/');
-/*
- * The empty source position.
- */
+ if (slash) {
+ int len = slash - path;
+ char *dir = xmalloc(len + 1);
-struct dtc_file dtc_empty_file = {
- .dir = NULL,
- .name = "<no file>",
- .file = NULL
-};
+ memcpy(dir, path, len);
+ dir[len] = '\0';
+ return dir;
+ }
+ return NULL;
+}
-srcpos srcpos_empty = {
- .first_line = 0,
- .first_column = 0,
- .last_line = 0,
- .last_column = 0,
- .file = &dtc_empty_file
-};
+struct srcfile_state *current_srcfile; /* = NULL */
+/* Detect infinite include recursion. */
+#define MAX_SRCFILE_DEPTH (100)
+static int srcfile_depth; /* = 0 */
-static int
-dtc_open_one(struct dtc_file *file, const char *search, const char *fname)
+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 = xstrdup(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;
}
-
-struct dtc_file *
-dtc_open_file(const char *fname, const struct search_path *search)
+void srcfile_push(const char *fname)
{
- static const struct search_path default_search = { NULL, NULL, NULL };
+ struct srcfile_state *srcfile;
- struct dtc_file *file;
- const char *slash;
+ if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
+ die("Includes nested too deeply");
- file = xmalloc(sizeof(struct dtc_file));
+ srcfile = xmalloc(sizeof(*srcfile));
- slash = strrchr(fname, '/');
- if (slash) {
- char *dir = xmalloc(slash - fname + 1);
-
- memcpy(dir, fname, slash - fname);
- dir[slash - fname] = 0;
- file->dir = dir;
- } else {
- file->dir = NULL;
- }
-
- if (streq(fname, "-")) {
- file->name = "stdin";
- file->file = stdin;
- return file;
- }
-
- if (fname[0] == '/') {
- file->file = fopen(fname, "r");
- if (!file->file)
- goto fail;
+ srcfile->f = srcfile_relative_open(fname, &srcfile->name);
+ srcfile->dir = dirname(srcfile->name);
+ srcfile->prev = current_srcfile;
+ current_srcfile = srcfile;
+}
- file->name = xstrdup(fname);
- return file;
- }
+int srcfile_pop(void)
+{
+ struct srcfile_state *srcfile = current_srcfile;
- if (!search)
- search = &default_search;
+ assert(srcfile);
- while (search) {
- if (dtc_open_one(file, search->dir, fname))
- return file;
+ current_srcfile = srcfile->prev;
- if (errno != ENOENT)
- goto fail;
+ if (fclose(srcfile->f))
+ die("Error closing \"%s\": %s\n", srcfile->name, strerror(errno));
- search = search->next;
- }
+ /* 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. */
-fail:
- die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
+ return current_srcfile ? 1 : 0;
}
+/*
+ * The empty source position.
+ */
-void
-dtc_close_file(struct dtc_file *file)
-{
- if (fclose(file->file))
- die("Error closing \"%s\": %s\n", file->name, strerror(errno));
-}
-
+srcpos srcpos_empty = {
+ .first_line = 0,
+ .first_column = 0,
+ .last_line = 0,
+ .last_column = 0,
+ .file = NULL,
+};
srcpos *
srcpos_copy(srcpos *pos)
diff --git a/srcpos.h b/srcpos.h
index a6d0077..38cc988 100644
--- a/srcpos.h
+++ b/srcpos.h
@@ -27,19 +27,27 @@
#include <stdio.h>
-struct dtc_file {
+struct srcfile_state {
+ FILE *f;
+ char *name;
char *dir;
- const char *name;
- FILE *file;
+ int lineno;
+ struct srcfile_state *prev;
};
+extern struct srcfile_state *current_srcfile; /* = NULL */
+
+FILE *srcfile_relative_open(const char *fname, char **fullnamep);
+void srcfile_push(const char *fname);
+int srcfile_pop(void);
+
#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
typedef struct YYLTYPE {
int first_line;
int first_column;
int last_line;
int last_column;
- struct dtc_file *file;
+ struct srcfile_state *file;
} YYLTYPE;
#define YYLTYPE_IS_DECLARED 1
@@ -81,17 +89,6 @@ typedef YYLTYPE srcpos;
*/
extern srcpos srcpos_empty;
-extern struct dtc_file *srcpos_file;
-
-struct search_path {
- const char *dir; /* NULL for current directory */
- struct search_path *prev, *next;
-};
-
-extern struct dtc_file *dtc_open_file(const char *fname,
- const struct search_path *search);
-extern void dtc_close_file(struct dtc_file *file);
-
extern srcpos *srcpos_copy(srcpos *pos);
extern char *srcpos_string(srcpos *pos);
extern void srcpos_dump(srcpos *pos);
diff --git a/treesource.c b/treesource.c
index cc1751d..331c22c 100644
--- a/treesource.c
+++ b/treesource.c
@@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname)
the_boot_info = NULL;
treesource_error = 0;
- srcpos_file = dtc_open_file(fname, NULL);
- yyin = srcpos_file->file;
+ srcfile_push(fname);
+ yyin = current_srcfile->f;
if (yyparse() != 0)
die("Unable to parse input tree\n");
diff --git a/util.c b/util.c
index 33631ce..c1d3ca4 100644
--- a/util.c
+++ b/util.c
@@ -28,3 +28,27 @@ char *xstrdup(const char *s)
return dup;
}
+
+char *join_path(const char *path, const char *name)
+{
+ int lenp = strlen(path);
+ int lenn = strlen(name);
+ int len;
+ int needslash = 1;
+ char *str;
+
+ len = lenp + lenn + 2;
+ if ((lenp > 0) && (path[lenp-1] == '/')) {
+ needslash = 0;
+ len--;
+ }
+
+ str = xmalloc(len);
+ memcpy(str, path, lenp);
+ if (needslash) {
+ str[lenp] = '/';
+ lenp++;
+ }
+ memcpy(str+lenp, name, lenn+1);
+ return str;
+}
diff --git a/util.h b/util.h
index 0fb60fe..9cead84 100644
--- a/util.h
+++ b/util.h
@@ -51,5 +51,6 @@ static inline void *xrealloc(void *p, size_t len)
}
extern char *xstrdup(const char *s);
+extern char *join_path(const char *path, const char *name);
#endif /* _UTIL_H */