source: branches/libc-0.6/src/binutils/gprof/source.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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