symbian-qemu-0.9.1-12/dtc-trunk/srcpos.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/dtc-trunk/srcpos.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *                                                                   USA
+ */
+
+#include "dtc.h"
+#include "srcpos.h"
+
+/*
+ * Like yylineno, this is the current open file pos.
+ */
+
+struct dtc_file *srcpos_file;
+
+static int dtc_open_one(struct dtc_file *file,
+                        const char *search,
+                        const char *fname)
+{
+	char *fullname;
+
+	if (search) {
+		fullname = xmalloc(strlen(search) + strlen(fname) + 2);
+
+		strcpy(fullname, search);
+		strcat(fullname, "/");
+		strcat(fullname, fname);
+	} else {
+		fullname = strdup(fname);
+	}
+
+	file->file = fopen(fullname, "r");
+	if (!file->file) {
+		free(fullname);
+		return 0;
+	}
+
+	file->name = fullname;
+	return 1;
+}
+
+
+struct dtc_file *dtc_open_file(const char *fname,
+                               const struct search_path *search)
+{
+	static const struct search_path default_search = { NULL, NULL, NULL };
+
+	struct dtc_file *file;
+	const char *slash;
+
+	file = xmalloc(sizeof(struct dtc_file));
+
+	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;
+
+		file->name = strdup(fname);
+		return file;
+	}
+
+	if (!search)
+		search = &default_search;
+
+	while (search) {
+		if (dtc_open_one(file, search->dir, fname))
+			return file;
+
+		if (errno != ENOENT)
+			goto fail;
+
+		search = search->next;
+	}
+
+fail:
+	die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
+}
+
+void dtc_close_file(struct dtc_file *file)
+{
+	if (fclose(file->file))
+		die("Error closing \"%s\": %s\n", file->name, strerror(errno));
+
+	free(file->dir);
+	free(file);
+}