diff options
Diffstat (limited to 'arch/powerpc/boot/dtc-src/srcpos.c')
-rw-r--r-- | arch/powerpc/boot/dtc-src/srcpos.c | 121 |
1 files changed, 66 insertions, 55 deletions
diff --git a/arch/powerpc/boot/dtc-src/srcpos.c b/arch/powerpc/boot/dtc-src/srcpos.c index 352b0fe06fde..9641b7628b4d 100644 --- a/arch/powerpc/boot/dtc-src/srcpos.c +++ b/arch/powerpc/boot/dtc-src/srcpos.c | |||
@@ -20,86 +20,97 @@ | |||
20 | #include "dtc.h" | 20 | #include "dtc.h" |
21 | #include "srcpos.h" | 21 | #include "srcpos.h" |
22 | 22 | ||
23 | |||
24 | /* | ||
25 | * Record the complete unique set of opened file names. | ||
26 | * Primarily used to cache source position file names. | ||
27 | */ | ||
28 | #define MAX_N_FILE_NAMES (100) | ||
29 | |||
30 | const char *file_names[MAX_N_FILE_NAMES]; | ||
31 | static int n_file_names = 0; | ||
32 | |||
33 | /* | 23 | /* |
34 | * Like yylineno, this is the current open file pos. | 24 | * Like yylineno, this is the current open file pos. |
35 | */ | 25 | */ |
36 | 26 | ||
37 | int srcpos_filenum = -1; | 27 | struct dtc_file *srcpos_file; |
38 | |||
39 | 28 | ||
40 | 29 | static int dtc_open_one(struct dtc_file *file, | |
41 | FILE *dtc_open_file(const char *fname) | 30 | const char *search, |
31 | const char *fname) | ||
42 | { | 32 | { |
43 | FILE *f; | 33 | char *fullname; |
44 | 34 | ||
45 | if (lookup_file_name(fname, 1) < 0) | 35 | if (search) { |
46 | die("Too many files opened\n"); | 36 | fullname = xmalloc(strlen(search) + strlen(fname) + 2); |
47 | 37 | ||
48 | if (streq(fname, "-")) | 38 | strcpy(fullname, search); |
49 | f = stdin; | 39 | strcat(fullname, "/"); |
50 | else | 40 | strcat(fullname, fname); |
51 | f = fopen(fname, "r"); | 41 | } else { |
42 | fullname = strdup(fname); | ||
43 | } | ||
52 | 44 | ||
53 | if (! f) | 45 | file->file = fopen(fullname, "r"); |
54 | die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); | 46 | if (!file->file) { |
47 | free(fullname); | ||
48 | return 0; | ||
49 | } | ||
55 | 50 | ||
56 | return f; | 51 | file->name = fullname; |
52 | return 1; | ||
57 | } | 53 | } |
58 | 54 | ||
59 | 55 | ||
56 | struct dtc_file *dtc_open_file(const char *fname, | ||
57 | const struct search_path *search) | ||
58 | { | ||
59 | static const struct search_path default_search = { NULL, NULL, NULL }; | ||
60 | 60 | ||
61 | /* | 61 | struct dtc_file *file; |
62 | * Locate and optionally add filename fname in the file_names[] array. | 62 | const char *slash; |
63 | * | ||
64 | * If the filename is currently not in the array and the boolean | ||
65 | * add_it is non-zero, an attempt to add the filename will be made. | ||
66 | * | ||
67 | * Returns; | ||
68 | * Index [0..MAX_N_FILE_NAMES) where the filename is kept | ||
69 | * -1 if the name can not be recorded | ||
70 | */ | ||
71 | 63 | ||
72 | int lookup_file_name(const char *fname, int add_it) | 64 | file = xmalloc(sizeof(struct dtc_file)); |
73 | { | ||
74 | int i; | ||
75 | 65 | ||
76 | for (i = 0; i < n_file_names; i++) { | 66 | slash = strrchr(fname, '/'); |
77 | if (strcmp(file_names[i], fname) == 0) | 67 | if (slash) { |
78 | return i; | 68 | char *dir = xmalloc(slash - fname + 1); |
69 | |||
70 | memcpy(dir, fname, slash - fname); | ||
71 | dir[slash - fname] = 0; | ||
72 | file->dir = dir; | ||
73 | } else { | ||
74 | file->dir = NULL; | ||
79 | } | 75 | } |
80 | 76 | ||
81 | if (add_it) { | 77 | if (streq(fname, "-")) { |
82 | if (n_file_names < MAX_N_FILE_NAMES) { | 78 | file->name = "stdin"; |
83 | file_names[n_file_names] = strdup(fname); | 79 | file->file = stdin; |
84 | return n_file_names++; | 80 | return file; |
85 | } | ||
86 | } | 81 | } |
87 | 82 | ||
88 | return -1; | 83 | if (fname[0] == '/') { |
89 | } | 84 | file->file = fopen(fname, "r"); |
85 | if (!file->file) | ||
86 | goto fail; | ||
87 | |||
88 | file->name = strdup(fname); | ||
89 | return file; | ||
90 | } | ||
90 | 91 | ||
92 | if (!search) | ||
93 | search = &default_search; | ||
91 | 94 | ||
92 | const char *srcpos_filename_for_num(int filenum) | 95 | while (search) { |
93 | { | 96 | if (dtc_open_one(file, search->dir, fname)) |
94 | if (0 <= filenum && filenum < n_file_names) { | 97 | return file; |
95 | return file_names[filenum]; | 98 | |
99 | if (errno != ENOENT) | ||
100 | goto fail; | ||
101 | |||
102 | search = search->next; | ||
96 | } | 103 | } |
97 | 104 | ||
98 | return 0; | 105 | fail: |
106 | die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); | ||
99 | } | 107 | } |
100 | 108 | ||
101 | 109 | void dtc_close_file(struct dtc_file *file) | |
102 | const char *srcpos_get_filename(void) | ||
103 | { | 110 | { |
104 | return srcpos_filename_for_num(srcpos_filenum); | 111 | if (fclose(file->file)) |
112 | die("Error closing \"%s\": %s\n", file->name, strerror(errno)); | ||
113 | |||
114 | free(file->dir); | ||
115 | free(file); | ||
105 | } | 116 | } |