summaryrefslogtreecommitdiffstats
path: root/contrib/dtc/srcpos.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2012-07-24 16:29:33 +0000
committerimp <imp@FreeBSD.org>2012-07-24 16:29:33 +0000
commit271289d4bf786cb542f44a7cc435e7eea1463eec (patch)
tree60be8a4bac3452ea449c82c5dfefde0485cdb631 /contrib/dtc/srcpos.c
parentb7a0f04c526af6628c15d9d29f4ea078ad0f4caf (diff)
parent411f4c1084154670913f56f4218e1d7f103cd348 (diff)
downloadFreeBSD-src-271289d4bf786cb542f44a7cc435e7eea1463eec.zip
FreeBSD-src-271289d4bf786cb542f44a7cc435e7eea1463eec.tar.gz
Update to latest git version of dtc to get new dtsv2 support,
including the include directive. Fix minor build issue corrected by converting yypush_buffer_state and yypop_buffer_state to yy_set_buffer_state and a hard-coded 100-deep stack. It was easier to fix it here than to import that support into our flex. The new tools and test hardness remain unsupported at the moment.
Diffstat (limited to 'contrib/dtc/srcpos.c')
-rw-r--r--contrib/dtc/srcpos.c332
1 files changed, 211 insertions, 121 deletions
diff --git a/contrib/dtc/srcpos.c b/contrib/dtc/srcpos.c
index 8bb0c02..3ee523d 100644
--- a/contrib/dtc/srcpos.c
+++ b/contrib/dtc/srcpos.c
@@ -24,126 +24,224 @@
#include "dtc.h"
#include "srcpos.h"
+/* 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 */
+};
-/*
- * Like yylineno, this is the current open file pos.
- */
-struct dtc_file *srcpos_file;
+/* This is the list of directories that we search for source files */
+static struct search_path *search_path_head, **search_path_tail;
-/*
- * The empty source position.
- */
-struct dtc_file dtc_empty_file = {
- .dir = NULL,
- .name = "<no file>",
- .file = NULL
-};
+static char *dirname(const char *path)
+{
+ const char *slash = strrchr(path, '/');
-srcpos srcpos_empty = {
- .first_line = 0,
- .first_column = 0,
- .last_line = 0,
- .last_column = 0,
- .file = &dtc_empty_file
-};
+ if (slash) {
+ int len = slash - path;
+ char *dir = xmalloc(len + 1);
+
+ memcpy(dir, path, len);
+ dir[len] = '\0';
+ return dir;
+ }
+ return NULL;
+}
+
+FILE *depfile; /* = NULL */
+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)
+
+/**
+ * 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 (search) {
- fullname = xmalloc(strlen(search) + strlen(fname) + 2);
-
- strcpy(fullname, search);
- strcat(fullname, "/");
- strcat(fullname, fname);
- } else {
+ if (!dirname || fname[0] == '/')
fullname = xstrdup(fname);
- }
+ else
+ fullname = join_path(dirname, fname);
- file->file = fopen(fullname, "r");
- if (!file->file) {
+ *fp = fopen(fullname, "r");
+ if (!*fp) {
free(fullname);
- return 0;
+ fullname = NULL;
}
- file->name = fullname;
- return 1;
+ return fullname;
}
-
-struct dtc_file *
-dtc_open_file(const char *fname, const struct search_path *search)
+/**
+ * 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)
{
- static const struct search_path default_search = { NULL, NULL, NULL };
+ const char *cur_dir = NULL;
+ struct search_path *node;
+ char *fullname;
- struct dtc_file *file;
- const char *slash;
+ /* Try current directory first */
+ assert(fp);
+ if (current_srcfile)
+ cur_dir = current_srcfile->dir;
+ fullname = try_open(cur_dir, fname, fp);
- file = xmalloc(sizeof(struct dtc_file));
+ /* 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);
- slash = strrchr(fname, '/');
- if (slash) {
- char *dir = xmalloc(slash - fname + 1);
+ return fullname;
+}
- memcpy(dir, fname, slash - fname);
- dir[slash - fname] = 0;
- file->dir = dir;
- } else {
- file->dir = NULL;
- }
+FILE *srcfile_relative_open(const char *fname, char **fullnamep)
+{
+ FILE *f;
+ char *fullname;
if (streq(fname, "-")) {
- file->name = "stdin";
- file->file = stdin;
- return file;
+ f = stdin;
+ fullname = xstrdup("<stdin>");
+ } else {
+ fullname = fopen_any_on_path(fname, &f);
+ if (!f)
+ die("Couldn't open \"%s\": %s\n", fname,
+ strerror(errno));
}
- if (fname[0] == '/') {
- file->file = fopen(fname, "r");
- if (!file->file)
- goto fail;
+ if (depfile)
+ fprintf(depfile, " %s", fullname);
- file->name = xstrdup(fname);
- return file;
- }
+ if (fullnamep)
+ *fullnamep = fullname;
+ else
+ free(fullname);
- if (!search)
- search = &default_search;
+ return f;
+}
- while (search) {
- if (dtc_open_one(file, search->dir, fname))
- return file;
+void srcfile_push(const char *fname)
+{
+ struct srcfile_state *srcfile;
- if (errno != ENOENT)
- goto fail;
+ if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
+ die("Includes nested too deeply");
- search = search->next;
- }
+ srcfile = xmalloc(sizeof(*srcfile));
+
+ srcfile->f = srcfile_relative_open(fname, &srcfile->name);
+ srcfile->dir = dirname(srcfile->name);
+ srcfile->prev = current_srcfile;
-fail:
- die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
+ srcfile->lineno = 1;
+ srcfile->colno = 1;
+
+ current_srcfile = srcfile;
}
+int srcfile_pop(void)
+{
+ struct srcfile_state *srcfile = current_srcfile;
+
+ assert(srcfile);
-void
-dtc_close_file(struct dtc_file *file)
+ current_srcfile = srcfile->prev;
+
+ if (fclose(srcfile->f))
+ die("Error closing \"%s\": %s\n", srcfile->name,
+ strerror(errno));
+
+ /* 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. */
+
+ return current_srcfile ? 1 : 0;
+}
+
+void srcfile_add_search_path(const char *dirname)
{
- if (fclose(file->file))
- die("Error closing \"%s\": %s\n", file->name, strerror(errno));
+ 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;
}
+/*
+ * The empty source position.
+ */
-srcpos *
-srcpos_copy(srcpos *pos)
+struct srcpos srcpos_empty = {
+ .first_line = 0,
+ .first_column = 0,
+ .last_line = 0,
+ .last_column = 0,
+ .file = NULL,
+};
+
+#define TAB_SIZE 8
+
+void srcpos_update(struct srcpos *pos, const char *text, int len)
{
- srcpos *pos_new;
+ int i;
+
+ pos->file = current_srcfile;
- pos_new = xmalloc(sizeof(srcpos));
- memcpy(pos_new, pos, sizeof(srcpos));
+ 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;
+}
+
+struct srcpos *
+srcpos_copy(struct srcpos *pos)
+{
+ struct srcpos *pos_new;
+
+ pos_new = xmalloc(sizeof(struct srcpos));
+ memcpy(pos_new, pos, sizeof(struct srcpos));
return pos_new;
}
@@ -151,7 +249,7 @@ srcpos_copy(srcpos *pos)
void
-srcpos_dump(srcpos *pos)
+srcpos_dump(struct srcpos *pos)
{
printf("file : \"%s\"\n",
pos->file ? (char *) pos->file : "<no file>");
@@ -164,67 +262,59 @@ srcpos_dump(srcpos *pos)
char *
-srcpos_string(srcpos *pos)
+srcpos_string(struct srcpos *pos)
{
- const char *fname;
- char col_buf[100];
+ const char *fname = "<no-file>";
char *pos_str;
+ int rc;
- if (!pos) {
- fname = "<no-file>";
- } else if (pos->file->name) {
+ if (pos)
fname = pos->file->name;
- if (strcmp(fname, "-") == 0)
- fname = "stdin";
- } else {
- fname = "<no-file>";
- }
- if (pos->first_line == pos->last_line) {
- if (pos->first_column == pos->last_column) {
- snprintf(col_buf, sizeof(col_buf),
- "%d:%d",
- pos->first_line, pos->first_column);
- } else {
- snprintf(col_buf, sizeof(col_buf),
- "%d:%d-%d",
- pos->first_line,
- pos->first_column, pos->last_column);
- }
- } else {
- snprintf(col_buf, sizeof(col_buf),
- "%d:%d - %d:%d",
- pos->first_line, pos->first_column,
- pos->last_line, pos->last_column);
- }
+ 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 (asprintf(&pos_str, "%s %s", fname, col_buf) == -1)
- return "<unknown source position?";
+ if (rc == -1)
+ die("Couldn't allocate in srcpos string");
return pos_str;
}
-
void
-srcpos_error(srcpos *pos, char const *fmt, ...)
+srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
{
- const char *srcstr;
- va_list va;
- va_start(va, fmt);
+ const char *srcstr;
- srcstr = srcpos_string(pos);
+ srcstr = srcpos_string(pos);
- fprintf(stderr, "Error: %s ", srcstr);
- vfprintf(stderr, fmt, va);
- fprintf(stderr, "\n");
+ fprintf(stdout, "Error: %s ", srcstr);
+ vfprintf(stdout, fmt, va);
+ fprintf(stdout, "\n");
+}
+void
+srcpos_error(struct srcpos *pos, char const *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ srcpos_verror(pos, fmt, va);
va_end(va);
}
void
-srcpos_warn(srcpos *pos, char const *fmt, ...)
+srcpos_warn(struct srcpos *pos, char const *fmt, ...)
{
const char *srcstr;
va_list va;
OpenPOWER on IntegriCloud