Skip to content

Commit

Permalink
dtc: Simpler interface to source file management
Browse files Browse the repository at this point in the history
This patch cleans up our handling of input files, particularly dts
source files, but also (to an extent) other input files such as those
used by /incbin/ and those used in -I dtb and -I fs modes.

We eliminate the current clunky mechanism which combines search paths
(which we don't actually use at present) with the open relative to
current source file behaviour, which we do.

Instead there's a single srcfile_relative_open() entry point for
callers which opens a new input file relative to the current source
file (which the srcpos code tracks internally).  It doesn't currently
do search paths, but we can add that later without messing with the
callers, by drawing the search path from a global (which makes sense
anyway, rather than shuffling it around the rest of the processing
code).

That suffices for non-dts input files.  For the actual dts files,
srcfile_push() and srcfile_pop() wrappers open the file while also
keeping track of it as the current source file for future opens.

Signed-off-by: David Gibson <[email protected]>
  • Loading branch information
dgibson authored and Jon Loeliger committed Jan 14, 2010
1 parent d75b33a commit d68cb36
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 233 deletions.
6 changes: 4 additions & 2 deletions convert-dtsv0-lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
91 changes: 10 additions & 81 deletions dtc-lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ LINECOMMENT "//".*\n

#define YY_USER_ACTION \
{ \
yylloc.file = srcpos_file; \
yylloc.file = current_srcfile; \
yylloc.first_line = yylineno; \
}

Expand Down Expand Up @@ -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;
}
18 changes: 8 additions & 10 deletions dtc-parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
24 changes: 0 additions & 24 deletions dtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions dtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
24 changes: 12 additions & 12 deletions flattree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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));

Expand Down Expand Up @@ -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);
}
Loading

0 comments on commit d68cb36

Please sign in to comment.