]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprof/source.c
sim: bfin: initial bf60x support
[thirdparty/binutils-gdb.git] / gprof / source.c
CommitLineData
ef368dac
NC
1/* source.c - Keep track of source files.
2
d87bef3a 3 Copyright (C) 2000-2023 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
651dbc76 9 the Free Software Foundation; either version 3 of the License, or
ef368dac
NC
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
44eb1801
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
ef368dac 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. */
faa7a260 31bool create_annotation_files = false;
252b5132 32
ef368dac 33Search_List src_search_list = {0, 0};
252b5132
RH
34Source_File *first_src_file = 0;
35
36
37Source_File *
3e8f6abf 38source_file_lookup_path (const char *path)
252b5132
RH
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
64Source_File *
3e8f6abf 65source_file_lookup_name (const char *filename)
252b5132
RH
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
91FILE *
3e8f6abf
BE
92annotate_source (Source_File *sf, unsigned int max_width,
93 void (*annote) (char *, unsigned int, int, void *),
94 void *arg)
252b5132 95{
faa7a260 96 static bool first_file = true;
252b5132 97 int i, line_num, nread;
faa7a260 98 bool new_line;
252b5132 99 char buf[8192];
13acb58d 100 char *fname;
252b5132
RH
101 char *annotation, *name_only;
102 FILE *ifp, *ofp;
103 Search_List_Elem *sle = src_search_list.head;
104
ef368dac
NC
105 /* Open input file. If open fails, walk along search-list until
106 open succeeds or reaching end of list. */
13acb58d 107 fname = (char *) sf->name;
0eee5820 108
5af11cab 109 if (IS_ABSOLUTE_PATH (sf->name))
ef368dac
NC
110 sle = 0; /* Don't use search list for absolute paths. */
111
252b5132 112 name_only = 0;
faa7a260 113 while (true)
252b5132
RH
114 {
115 DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n",
116 sf->name, fname));
0eee5820 117
252b5132 118 ifp = fopen (fname, FOPEN_RB);
13acb58d
AM
119 if (fname != sf->name)
120 free (fname);
252b5132 121 if (ifp)
ef368dac
NC
122 break;
123
252b5132
RH
124 if (!sle && !name_only)
125 {
126 name_only = strrchr (sf->name, '/');
5af11cab
AM
127#ifdef HAVE_DOS_BASED_FILE_SYSTEM
128 {
129 char *bslash = strrchr (sf->name, '\\');
2ab47eed 130 if (name_only == NULL || (bslash != NULL && bslash > name_only))
5af11cab
AM
131 name_only = bslash;
132 if (name_only == NULL && sf->name[0] != '\0' && sf->name[1] == ':')
133 name_only = (char *)sf->name + 1;
134 }
135#endif
252b5132
RH
136 if (name_only)
137 {
ef368dac 138 /* Try search-list again, but this time with name only. */
252b5132
RH
139 ++name_only;
140 sle = src_search_list.head;
141 }
142 }
0eee5820 143
252b5132
RH
144 if (sle)
145 {
13acb58d
AM
146 fname = xmalloc (strlen (sle->path) + 3
147 + strlen (name_only ? name_only : sf->name));
252b5132 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 197
13acb58d 198 fname = xmalloc (strlen (filename) + strlen (EXT_ANNO) + 1);
252b5132
RH
199 strcpy (fname, filename);
200 strcat (fname, EXT_ANNO);
5af11cab
AM
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
13acb58d
AM
213 if (!dot)
214 dot = fname + strlen (filename);
215 strcpy (dot, ".ann");
5af11cab
AM
216 }
217 }
218#endif
252b5132 219 ofp = fopen (fname, "w");
0eee5820 220
252b5132
RH
221 if (!ofp)
222 {
223 perror (fname);
13acb58d 224 free (fname);
252b5132
RH
225 return 0;
226 }
13acb58d 227 free (fname);
252b5132
RH
228 }
229
ef368dac
NC
230 /* Print file names if output goes to stdout
231 and there are more than one source file. */
252b5132
RH
232 if (ofp == stdout)
233 {
234 if (first_file)
faa7a260 235 first_file = false;
252b5132 236 else
ef368dac
NC
237 fputc ('\n', ofp);
238
252b5132 239 if (first_output)
faa7a260 240 first_output = false;
252b5132 241 else
ef368dac
NC
242 fprintf (ofp, "\f\n");
243
252b5132
RH
244 fprintf (ofp, _("*** File %s:\n"), sf->name);
245 }
246
1e9cc1c2 247 annotation = (char *) xmalloc (max_width + 1);
252b5132 248 line_num = 1;
faa7a260 249 new_line = true;
0eee5820 250
252b5132
RH
251 while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0)
252 {
253 for (i = 0; i < nread; ++i)
254 {
255 if (new_line)
256 {
257 (*annote) (annotation, max_width, line_num, arg);
258 fputs (annotation, ofp);
259 ++line_num;
252b5132 260 }
0eee5820 261
252b5132
RH
262 new_line = (buf[i] == '\n');
263 fputc (buf[i], ofp);
264 }
265 }
0eee5820 266
252b5132 267 free (annotation);
5af84f93 268 fclose (ifp);
252b5132
RH
269 return ofp;
270}