]>
Commit | Line | Data |
---|---|---|
ef368dac NC |
1 | /* source.c - Keep track of source files. |
2 | ||
1355568a | 3 | Copyright 2000, 2001, 2002 Free Software Foundation, Inc. |
ef368dac NC |
4 | |
5 | This file is part of GNU Binutils. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
21 | \f | |
252b5132 RH |
22 | #include "gprof.h" |
23 | #include "libiberty.h" | |
5af11cab | 24 | #include "filenames.h" |
252b5132 RH |
25 | #include "search_list.h" |
26 | #include "source.h" | |
27 | ||
ef368dac | 28 | #define EXT_ANNO "-ann" /* Postfix of annotated files. */ |
252b5132 | 29 | |
ef368dac | 30 | /* Default option values. */ |
b34976b6 | 31 | bfd_boolean create_annotation_files = FALSE; |
252b5132 | 32 | |
ef368dac | 33 | Search_List src_search_list = {0, 0}; |
252b5132 RH |
34 | Source_File *first_src_file = 0; |
35 | ||
36 | ||
37 | Source_File * | |
1355568a AM |
38 | source_file_lookup_path (path) |
39 | const char *path; | |
252b5132 RH |
40 | { |
41 | Source_File *sf; | |
42 | ||
43 | for (sf = first_src_file; sf; sf = sf->next) | |
44 | { | |
5af11cab | 45 | if (FILENAME_CMP (path, sf->name) == 0) |
ef368dac | 46 | break; |
252b5132 | 47 | } |
0eee5820 | 48 | |
252b5132 RH |
49 | if (!sf) |
50 | { | |
ef368dac | 51 | /* Create a new source file descriptor. */ |
252b5132 | 52 | sf = (Source_File *) xmalloc (sizeof (*sf)); |
0eee5820 | 53 | |
252b5132 | 54 | memset (sf, 0, sizeof (*sf)); |
0eee5820 | 55 | |
252b5132 RH |
56 | sf->name = xstrdup (path); |
57 | sf->next = first_src_file; | |
58 | first_src_file = sf; | |
59 | } | |
0eee5820 | 60 | |
252b5132 RH |
61 | return sf; |
62 | } | |
63 | ||
64 | ||
65 | Source_File * | |
1355568a AM |
66 | source_file_lookup_name (filename) |
67 | const char *filename; | |
252b5132 RH |
68 | { |
69 | const char *fname; | |
70 | Source_File *sf; | |
0eee5820 | 71 | |
ef368dac NC |
72 | /* The user cannot know exactly how a filename will be stored in |
73 | the debugging info (e.g., ../include/foo.h | |
74 | vs. /usr/include/foo.h). So we simply compare the filename | |
75 | component of a path only. */ | |
252b5132 RH |
76 | for (sf = first_src_file; sf; sf = sf->next) |
77 | { | |
78 | fname = strrchr (sf->name, '/'); | |
0eee5820 | 79 | |
252b5132 | 80 | if (fname) |
ef368dac | 81 | ++fname; |
252b5132 | 82 | else |
ef368dac NC |
83 | fname = sf->name; |
84 | ||
5af11cab | 85 | if (FILENAME_CMP (filename, fname) == 0) |
ef368dac | 86 | break; |
252b5132 | 87 | } |
0eee5820 | 88 | |
252b5132 RH |
89 | return sf; |
90 | } | |
91 | ||
92 | ||
93 | FILE * | |
1355568a AM |
94 | annotate_source (sf, max_width, annote, arg) |
95 | Source_File *sf; | |
96 | unsigned int max_width; | |
97 | void (*annote) PARAMS ((char *, unsigned int, int, void *)); | |
98 | void *arg; | |
252b5132 | 99 | { |
b34976b6 | 100 | static bfd_boolean first_file = TRUE; |
252b5132 | 101 | int i, line_num, nread; |
b34976b6 | 102 | bfd_boolean new_line; |
252b5132 RH |
103 | char buf[8192]; |
104 | char fname[PATH_MAX]; | |
105 | char *annotation, *name_only; | |
106 | FILE *ifp, *ofp; | |
107 | Search_List_Elem *sle = src_search_list.head; | |
108 | ||
ef368dac NC |
109 | /* Open input file. If open fails, walk along search-list until |
110 | open succeeds or reaching end of list. */ | |
252b5132 | 111 | strcpy (fname, sf->name); |
0eee5820 | 112 | |
5af11cab | 113 | if (IS_ABSOLUTE_PATH (sf->name)) |
ef368dac NC |
114 | sle = 0; /* Don't use search list for absolute paths. */ |
115 | ||
252b5132 | 116 | name_only = 0; |
b34976b6 | 117 | while (TRUE) |
252b5132 RH |
118 | { |
119 | DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n", | |
120 | sf->name, fname)); | |
0eee5820 | 121 | |
252b5132 RH |
122 | ifp = fopen (fname, FOPEN_RB); |
123 | if (ifp) | |
ef368dac NC |
124 | break; |
125 | ||
252b5132 RH |
126 | if (!sle && !name_only) |
127 | { | |
128 | name_only = strrchr (sf->name, '/'); | |
5af11cab AM |
129 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
130 | { | |
131 | char *bslash = strrchr (sf->name, '\\'); | |
2ab47eed | 132 | if (name_only == NULL || (bslash != NULL && bslash > name_only)) |
5af11cab AM |
133 | name_only = bslash; |
134 | if (name_only == NULL && sf->name[0] != '\0' && sf->name[1] == ':') | |
135 | name_only = (char *)sf->name + 1; | |
136 | } | |
137 | #endif | |
252b5132 RH |
138 | if (name_only) |
139 | { | |
ef368dac | 140 | /* Try search-list again, but this time with name only. */ |
252b5132 RH |
141 | ++name_only; |
142 | sle = src_search_list.head; | |
143 | } | |
144 | } | |
0eee5820 | 145 | |
252b5132 RH |
146 | if (sle) |
147 | { | |
148 | strcpy (fname, sle->path); | |
5af11cab AM |
149 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
150 | /* d:foo is not the same thing as d:/foo! */ | |
151 | if (fname[strlen (fname) - 1] == ':') | |
152 | strcat (fname, "."); | |
153 | #endif | |
252b5132 | 154 | strcat (fname, "/"); |
0eee5820 | 155 | |
252b5132 | 156 | if (name_only) |
ef368dac | 157 | strcat (fname, name_only); |
252b5132 | 158 | else |
ef368dac NC |
159 | strcat (fname, sf->name); |
160 | ||
252b5132 RH |
161 | sle = sle->next; |
162 | } | |
163 | else | |
164 | { | |
165 | if (errno == ENOENT) | |
ef368dac NC |
166 | fprintf (stderr, _("%s: could not locate `%s'\n"), |
167 | whoami, sf->name); | |
252b5132 | 168 | else |
ef368dac NC |
169 | perror (sf->name); |
170 | ||
252b5132 RH |
171 | return 0; |
172 | } | |
173 | } | |
174 | ||
175 | ofp = stdout; | |
0eee5820 | 176 | |
252b5132 RH |
177 | if (create_annotation_files) |
178 | { | |
ef368dac | 179 | /* Try to create annotated source file. */ |
252b5132 RH |
180 | const char *filename; |
181 | ||
ef368dac | 182 | /* Create annotation files in the current working directory. */ |
252b5132 | 183 | filename = strrchr (sf->name, '/'); |
5af11cab AM |
184 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
185 | { | |
186 | char *bslash = strrchr (sf->name, '\\'); | |
2ab47eed | 187 | if (filename == NULL || (bslash != NULL && bslash > filename)) |
5af11cab AM |
188 | filename = bslash; |
189 | if (filename == NULL && sf->name[0] != '\0' && sf->name[1] == ':') | |
190 | filename = sf->name + 1; | |
191 | } | |
192 | #endif | |
252b5132 | 193 | if (filename) |
ef368dac | 194 | ++filename; |
252b5132 | 195 | else |
ef368dac | 196 | filename = sf->name; |
252b5132 RH |
197 | |
198 | strcpy (fname, filename); | |
199 | strcat (fname, EXT_ANNO); | |
5af11cab AM |
200 | #ifdef __MSDOS__ |
201 | { | |
202 | /* foo.cpp-ann can overwrite foo.cpp due to silent truncation of | |
203 | file names on 8+3 filesystems. Their `stat' better be good... */ | |
204 | struct stat buf1, buf2; | |
205 | ||
206 | if (stat (filename, &buf1) == 0 | |
207 | && stat (fname, &buf2) == 0 | |
208 | && buf1.st_ino == buf2.st_ino) | |
209 | { | |
210 | char *dot = strrchr (fname, '.'); | |
211 | ||
212 | if (dot) | |
213 | *dot = '\0'; | |
214 | strcat (fname, ".ann"); | |
215 | } | |
216 | } | |
217 | #endif | |
252b5132 | 218 | ofp = fopen (fname, "w"); |
0eee5820 | 219 | |
252b5132 RH |
220 | if (!ofp) |
221 | { | |
222 | perror (fname); | |
223 | return 0; | |
224 | } | |
225 | } | |
226 | ||
ef368dac NC |
227 | /* Print file names if output goes to stdout |
228 | and there are more than one source file. */ | |
252b5132 RH |
229 | if (ofp == stdout) |
230 | { | |
231 | if (first_file) | |
b34976b6 | 232 | first_file = FALSE; |
252b5132 | 233 | else |
ef368dac NC |
234 | fputc ('\n', ofp); |
235 | ||
252b5132 | 236 | if (first_output) |
b34976b6 | 237 | first_output = FALSE; |
252b5132 | 238 | else |
ef368dac NC |
239 | fprintf (ofp, "\f\n"); |
240 | ||
252b5132 RH |
241 | fprintf (ofp, _("*** File %s:\n"), sf->name); |
242 | } | |
243 | ||
244 | annotation = xmalloc (max_width + 1); | |
245 | line_num = 1; | |
b34976b6 | 246 | new_line = TRUE; |
0eee5820 | 247 | |
252b5132 RH |
248 | while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0) |
249 | { | |
250 | for (i = 0; i < nread; ++i) | |
251 | { | |
252 | if (new_line) | |
253 | { | |
254 | (*annote) (annotation, max_width, line_num, arg); | |
255 | fputs (annotation, ofp); | |
256 | ++line_num; | |
b34976b6 | 257 | new_line = FALSE; |
252b5132 | 258 | } |
0eee5820 | 259 | |
252b5132 RH |
260 | new_line = (buf[i] == '\n'); |
261 | fputc (buf[i], ofp); | |
262 | } | |
263 | } | |
0eee5820 | 264 | |
252b5132 RH |
265 | free (annotation); |
266 | return ofp; | |
267 | } |