]>
Commit | Line | Data |
---|---|---|
ef368dac NC |
1 | /* source.c - Keep track of source files. |
2 | ||
0eee5820 | 3 | Copyright 2000, 2001 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. */ |
bde52789 | 31 | 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 * | |
38 | DEFUN (source_file_lookup_path, (path), const char *path) | |
39 | { | |
40 | Source_File *sf; | |
41 | ||
42 | for (sf = first_src_file; sf; sf = sf->next) | |
43 | { | |
5af11cab | 44 | if (FILENAME_CMP (path, sf->name) == 0) |
ef368dac | 45 | break; |
252b5132 | 46 | } |
0eee5820 | 47 | |
252b5132 RH |
48 | if (!sf) |
49 | { | |
ef368dac | 50 | /* Create a new source file descriptor. */ |
252b5132 | 51 | sf = (Source_File *) xmalloc (sizeof (*sf)); |
0eee5820 | 52 | |
252b5132 | 53 | memset (sf, 0, sizeof (*sf)); |
0eee5820 | 54 | |
252b5132 RH |
55 | sf->name = xstrdup (path); |
56 | sf->next = first_src_file; | |
57 | first_src_file = sf; | |
58 | } | |
0eee5820 | 59 | |
252b5132 RH |
60 | return sf; |
61 | } | |
62 | ||
63 | ||
64 | Source_File * | |
65 | DEFUN (source_file_lookup_name, (filename), const char *filename) | |
66 | { | |
67 | const char *fname; | |
68 | Source_File *sf; | |
0eee5820 | 69 | |
ef368dac NC |
70 | /* The user cannot know exactly how a filename will be stored in |
71 | the debugging info (e.g., ../include/foo.h | |
72 | vs. /usr/include/foo.h). So we simply compare the filename | |
73 | component of a path only. */ | |
252b5132 RH |
74 | for (sf = first_src_file; sf; sf = sf->next) |
75 | { | |
76 | fname = strrchr (sf->name, '/'); | |
0eee5820 | 77 | |
252b5132 | 78 | if (fname) |
ef368dac | 79 | ++fname; |
252b5132 | 80 | else |
ef368dac NC |
81 | fname = sf->name; |
82 | ||
5af11cab | 83 | if (FILENAME_CMP (filename, fname) == 0) |
ef368dac | 84 | break; |
252b5132 | 85 | } |
0eee5820 | 86 | |
252b5132 RH |
87 | return sf; |
88 | } | |
89 | ||
90 | ||
91 | FILE * | |
92 | DEFUN (annotate_source, (sf, max_width, annote, arg), | |
93 | Source_File * sf AND int max_width | |
94 | AND void (*annote) PARAMS ((char *buf, int w, int l, void *arg)) | |
95 | AND void *arg) | |
96 | { | |
bde52789 | 97 | static boolean first_file = true; |
252b5132 | 98 | int i, line_num, nread; |
bde52789 | 99 | boolean new_line; |
252b5132 RH |
100 | char buf[8192]; |
101 | char fname[PATH_MAX]; | |
102 | char *annotation, *name_only; | |
103 | FILE *ifp, *ofp; | |
104 | Search_List_Elem *sle = src_search_list.head; | |
105 | ||
ef368dac NC |
106 | /* Open input file. If open fails, walk along search-list until |
107 | open succeeds or reaching end of list. */ | |
252b5132 | 108 | strcpy (fname, sf->name); |
0eee5820 | 109 | |
5af11cab | 110 | if (IS_ABSOLUTE_PATH (sf->name)) |
ef368dac NC |
111 | sle = 0; /* Don't use search list for absolute paths. */ |
112 | ||
252b5132 | 113 | name_only = 0; |
bde52789 | 114 | while (true) |
252b5132 RH |
115 | { |
116 | DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n", | |
117 | sf->name, fname)); | |
0eee5820 | 118 | |
252b5132 RH |
119 | ifp = fopen (fname, FOPEN_RB); |
120 | if (ifp) | |
ef368dac NC |
121 | break; |
122 | ||
252b5132 RH |
123 | if (!sle && !name_only) |
124 | { | |
125 | name_only = strrchr (sf->name, '/'); | |
5af11cab AM |
126 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
127 | { | |
128 | char *bslash = strrchr (sf->name, '\\'); | |
2ab47eed | 129 | if (name_only == NULL || (bslash != NULL && bslash > name_only)) |
5af11cab AM |
130 | name_only = bslash; |
131 | if (name_only == NULL && sf->name[0] != '\0' && sf->name[1] == ':') | |
132 | name_only = (char *)sf->name + 1; | |
133 | } | |
134 | #endif | |
252b5132 RH |
135 | if (name_only) |
136 | { | |
ef368dac | 137 | /* Try search-list again, but this time with name only. */ |
252b5132 RH |
138 | ++name_only; |
139 | sle = src_search_list.head; | |
140 | } | |
141 | } | |
0eee5820 | 142 | |
252b5132 RH |
143 | if (sle) |
144 | { | |
145 | strcpy (fname, sle->path); | |
5af11cab AM |
146 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
147 | /* d:foo is not the same thing as d:/foo! */ | |
148 | if (fname[strlen (fname) - 1] == ':') | |
149 | strcat (fname, "."); | |
150 | #endif | |
252b5132 | 151 | strcat (fname, "/"); |
0eee5820 | 152 | |
252b5132 | 153 | if (name_only) |
ef368dac | 154 | strcat (fname, name_only); |
252b5132 | 155 | else |
ef368dac NC |
156 | strcat (fname, sf->name); |
157 | ||
252b5132 RH |
158 | sle = sle->next; |
159 | } | |
160 | else | |
161 | { | |
162 | if (errno == ENOENT) | |
ef368dac NC |
163 | fprintf (stderr, _("%s: could not locate `%s'\n"), |
164 | whoami, sf->name); | |
252b5132 | 165 | else |
ef368dac NC |
166 | perror (sf->name); |
167 | ||
252b5132 RH |
168 | return 0; |
169 | } | |
170 | } | |
171 | ||
172 | ofp = stdout; | |
0eee5820 | 173 | |
252b5132 RH |
174 | if (create_annotation_files) |
175 | { | |
ef368dac | 176 | /* Try to create annotated source file. */ |
252b5132 RH |
177 | const char *filename; |
178 | ||
ef368dac | 179 | /* Create annotation files in the current working directory. */ |
252b5132 | 180 | filename = strrchr (sf->name, '/'); |
5af11cab AM |
181 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM |
182 | { | |
183 | char *bslash = strrchr (sf->name, '\\'); | |
2ab47eed | 184 | if (filename == NULL || (bslash != NULL && bslash > filename)) |
5af11cab AM |
185 | filename = bslash; |
186 | if (filename == NULL && sf->name[0] != '\0' && sf->name[1] == ':') | |
187 | filename = sf->name + 1; | |
188 | } | |
189 | #endif | |
252b5132 | 190 | if (filename) |
ef368dac | 191 | ++filename; |
252b5132 | 192 | else |
ef368dac | 193 | filename = sf->name; |
252b5132 RH |
194 | |
195 | strcpy (fname, filename); | |
196 | strcat (fname, EXT_ANNO); | |
5af11cab AM |
197 | #ifdef __MSDOS__ |
198 | { | |
199 | /* foo.cpp-ann can overwrite foo.cpp due to silent truncation of | |
200 | file names on 8+3 filesystems. Their `stat' better be good... */ | |
201 | struct stat buf1, buf2; | |
202 | ||
203 | if (stat (filename, &buf1) == 0 | |
204 | && stat (fname, &buf2) == 0 | |
205 | && buf1.st_ino == buf2.st_ino) | |
206 | { | |
207 | char *dot = strrchr (fname, '.'); | |
208 | ||
209 | if (dot) | |
210 | *dot = '\0'; | |
211 | strcat (fname, ".ann"); | |
212 | } | |
213 | } | |
214 | #endif | |
252b5132 | 215 | ofp = fopen (fname, "w"); |
0eee5820 | 216 | |
252b5132 RH |
217 | if (!ofp) |
218 | { | |
219 | perror (fname); | |
220 | return 0; | |
221 | } | |
222 | } | |
223 | ||
ef368dac NC |
224 | /* Print file names if output goes to stdout |
225 | and there are more than one source file. */ | |
252b5132 RH |
226 | if (ofp == stdout) |
227 | { | |
228 | if (first_file) | |
bde52789 | 229 | first_file = false; |
252b5132 | 230 | else |
ef368dac NC |
231 | fputc ('\n', ofp); |
232 | ||
252b5132 | 233 | if (first_output) |
bde52789 | 234 | first_output = false; |
252b5132 | 235 | else |
ef368dac NC |
236 | fprintf (ofp, "\f\n"); |
237 | ||
252b5132 RH |
238 | fprintf (ofp, _("*** File %s:\n"), sf->name); |
239 | } | |
240 | ||
241 | annotation = xmalloc (max_width + 1); | |
242 | line_num = 1; | |
bde52789 | 243 | new_line = true; |
0eee5820 | 244 | |
252b5132 RH |
245 | while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0) |
246 | { | |
247 | for (i = 0; i < nread; ++i) | |
248 | { | |
249 | if (new_line) | |
250 | { | |
251 | (*annote) (annotation, max_width, line_num, arg); | |
252 | fputs (annotation, ofp); | |
253 | ++line_num; | |
bde52789 | 254 | new_line = false; |
252b5132 | 255 | } |
0eee5820 | 256 | |
252b5132 RH |
257 | new_line = (buf[i] == '\n'); |
258 | fputc (buf[i], ofp); | |
259 | } | |
260 | } | |
0eee5820 | 261 | |
252b5132 RH |
262 | free (annotation); |
263 | return ofp; | |
264 | } |