srcpos.c 2.6 KB
Newer Older
D
David Gibson 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * 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.
 */

27
struct dtc_file *srcpos_file;
D
David Gibson 已提交
28

29 30 31
static int dtc_open_one(struct dtc_file *file,
                        const char *search,
                        const char *fname)
D
David Gibson 已提交
32
{
33
	char *fullname;
D
David Gibson 已提交
34

35 36
	if (search) {
		fullname = xmalloc(strlen(search) + strlen(fname) + 2);
D
David Gibson 已提交
37

38 39 40 41 42 43
		strcpy(fullname, search);
		strcat(fullname, "/");
		strcat(fullname, fname);
	} else {
		fullname = strdup(fname);
	}
D
David Gibson 已提交
44

45 46 47 48 49
	file->file = fopen(fullname, "r");
	if (!file->file) {
		free(fullname);
		return 0;
	}
D
David Gibson 已提交
50

51 52
	file->name = fullname;
	return 1;
D
David Gibson 已提交
53 54 55
}


56 57 58 59
struct dtc_file *dtc_open_file(const char *fname,
                               const struct search_path *search)
{
	static const struct search_path default_search = { NULL, NULL, NULL };
D
David Gibson 已提交
60

61 62
	struct dtc_file *file;
	const char *slash;
D
David Gibson 已提交
63

64
	file = xmalloc(sizeof(struct dtc_file));
D
David Gibson 已提交
65

66 67 68 69 70 71 72 73 74
	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;
D
David Gibson 已提交
75 76
	}

77 78 79 80
	if (streq(fname, "-")) {
		file->name = "stdin";
		file->file = stdin;
		return file;
D
David Gibson 已提交
81 82
	}

83 84 85 86 87 88 89 90
	if (fname[0] == '/') {
		file->file = fopen(fname, "r");
		if (!file->file)
			goto fail;

		file->name = strdup(fname);
		return file;
	}
D
David Gibson 已提交
91

92 93
	if (!search)
		search = &default_search;
D
David Gibson 已提交
94

95 96 97 98 99 100 101 102
	while (search) {
		if (dtc_open_one(file, search->dir, fname))
			return file;

		if (errno != ENOENT)
			goto fail;

		search = search->next;
D
David Gibson 已提交
103 104
	}

105 106
fail:
	die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
D
David Gibson 已提交
107 108
}

109
void dtc_close_file(struct dtc_file *file)
D
David Gibson 已提交
110
{
111 112 113 114 115
	if (fclose(file->file))
		die("Error closing \"%s\": %s\n", file->name, strerror(errno));

	free(file->dir);
	free(file);
D
David Gibson 已提交
116
}