]> Git Repo - binutils.git/blob - gdb/source.c
* source.c: #if defined => #ifdef.
[binutils.git] / gdb / source.c
1 /* List lines of source files for GDB, the GNU debugger.
2    Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <stdio.h>
21 #include "defs.h"
22 #include "symtab.h"
23 #include "param.h"
24 #include "command.h"
25 #include "gdbcmd.h"
26 #include "frame.h"
27
28 #ifdef USG
29 #include <sys/types.h>
30 #endif
31
32 #include <string.h>
33 #include <sys/param.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include "gdbcore.h"
37 #include "regex.h"
38
39 extern char *strstr();
40
41 extern void set_next_address ();
42
43 /* Path of directories to search for source files.
44    Same format as the PATH environment variable's value.  */
45
46 char *source_path;
47
48 /* Symtab of default file for listing lines of.  */
49
50 struct symtab *current_source_symtab;
51
52 /* Default next line to list.  */
53
54 int current_source_line;
55
56 /* Line number of last line printed.  Default for various commands.
57    current_source_line is usually, but not always, the same as this.  */
58
59 static int last_line_listed;
60
61 /* First line number listed by last listing command.  */
62
63 static int first_line_listed;
64
65 \f
66 /* Set the source file default for the "list" command, specifying a
67    symtab.  Sigh.  Behavior specification: If it is called with a
68    non-zero argument, that is the symtab to select.  If it is not,
69    first lookup "main"; if it exists, use the symtab and line it
70    defines.  If not, take the last symtab in the symtab_list (if it
71    exists) or the last symtab in the psymtab_list (if *it* exists).  If
72    none of this works, report an error.   */
73
74 void
75 select_source_symtab (s)
76      register struct symtab *s;
77 {
78   struct symtabs_and_lines sals;
79   struct symtab_and_line sal;
80   struct partial_symtab *ps;
81   struct partial_symtab *cs_pst = 0;
82   
83   if (s)
84     {
85       current_source_symtab = s;
86       current_source_line = 1;
87       return;
88     }
89
90   /* Make the default place to list be the function `main'
91      if one exists.  */
92   if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
93     {
94       sals = decode_line_spec ("main", 1);
95       sal = sals.sals[0];
96       free (sals.sals);
97       current_source_symtab = sal.symtab;
98       current_source_line = max (sal.line - (lines_to_list () - 1), 1);
99       if (current_source_symtab)
100         return;
101     }
102   
103   /* All right; find the last file in the symtab list (ignoring .h's).  */
104
105   current_source_line = 1;
106
107   for (s = symtab_list; s; s = s->next)
108     {
109       char *name = s->filename;
110       int len = strlen (name);
111       if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
112         current_source_symtab = s;
113     }
114   if (current_source_symtab)
115     return;
116
117   /* Howabout the partial symtab list?  */
118
119   if (partial_symtab_list)
120     {
121       ps = partial_symtab_list;
122       while (ps)
123         {
124           char *name = ps->filename;
125           int len = strlen (name);
126           if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
127             cs_pst = ps;
128           ps = ps->next;
129         }
130       if (cs_pst)
131         if (cs_pst->readin)
132           fatal ("Internal: select_source_symtab: readin pst found and no symtabs.");
133         else
134           current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
135     }
136   if (current_source_symtab)
137     return;
138
139   error ("Can't find a default source file");
140 }
141 \f
142 static void
143 show_directories ()
144 {
145   printf ("Source directories searched: %s\n", source_path);
146 }
147
148 /* Forget what we learned about line positions in source files,
149    and which directories contain them;
150    must check again now since files may be found in
151    a different directory now.  */
152
153 void
154 forget_cached_source_info ()
155 {
156   register struct symtab *s;
157
158   for (s = symtab_list; s; s = s->next)
159     {
160       if (s->line_charpos != 0)
161         {
162           free (s->line_charpos);
163           s->line_charpos = 0;
164         }
165       if (s->fullname != 0)
166         {
167           free (s->fullname);
168           s->fullname = 0;
169         }
170     }
171 }
172
173 void
174 init_source_path ()
175 {
176   source_path = savestring ("$cdir:$cwd", /* strlen of it */ 10);
177   forget_cached_source_info ();
178 }
179
180 /* Add zero or more directories to the front of the source path.  */
181  
182 void
183 directory_command (dirname, from_tty)
184      char *dirname;
185      int from_tty;
186 {
187   dont_repeat ();
188   /* FIXME, this goes to "delete dir"... */
189   if (dirname == 0)
190     {
191       if (query ("Reinitialize source path to empty? ", ""))
192         {
193           free (source_path);
194           init_source_path ();
195         }
196     }
197   else
198     mod_path (dirname, &source_path);
199   if (from_tty)
200     show_directories ();
201   forget_cached_source_info ();
202 }
203
204 /* Add zero or more directories to the front of an arbitrary path.  */
205
206 void
207 mod_path (dirname, which_path)
208      char *dirname;
209      char **which_path;
210 {
211   char *old = *which_path;
212   int prefix = 0;
213
214   if (dirname == 0)
215     return;
216
217   dirname = strsave (dirname);
218   make_cleanup (free, dirname);
219
220   do
221     {
222       extern char *index ();
223       char *name = dirname;
224       register char *p;
225       struct stat st;
226
227       {
228         char *colon = index (name, ':');
229         char *space = index (name, ' ');
230         char *tab = index (name, '\t');
231         if (colon == 0 && space == 0 && tab ==  0)
232           p = dirname = name + strlen (name);
233         else
234           {
235             p = 0;
236             if (colon != 0 && (p == 0 || colon < p))
237               p = colon;
238             if (space != 0 && (p == 0 || space < p))
239               p = space;
240             if (tab != 0 && (p == 0 || tab < p))
241               p = tab;
242             dirname = p + 1;
243             while (*dirname == ':' || *dirname == ' ' || *dirname == '\t')
244               ++dirname;
245           }
246       }
247
248       if (p[-1] == '/')
249         /* Sigh. "foo/" => "foo" */
250         --p;
251       *p = '\0';
252
253       while (p[-1] == '.')
254         {
255           if (p - name == 1)
256             {
257               /* "." => getwd ().  */
258               name = current_directory;
259               goto append;
260             }
261           else if (p[-2] == '/')
262             {
263               if (p - name == 2)
264                 {
265                   /* "/." => "/".  */
266                   *--p = '\0';
267                   goto append;
268                 }
269               else
270                 {
271                   /* "...foo/." => "...foo".  */
272                   p -= 2;
273                   *p = '\0';
274                   continue;
275                 }
276             }
277           else
278             break;
279         }
280
281       if (name[0] == '~')
282         name = tilde_expand (name);
283       else if (name[0] != '/' && name[0] != '$')
284         name = concat (current_directory, "/", name);
285       else
286         name = savestring (name, p - name);
287       make_cleanup (free, name);
288
289       /* Unless it's a variable, check existence.  */
290       if (name[0] != '$') {
291         if (stat (name, &st) < 0)
292           perror_with_name (name);
293         if ((st.st_mode & S_IFMT) != S_IFDIR)
294           error ("%s is not a directory.", name);
295       }
296
297     append:
298       {
299         register unsigned int len = strlen (name);
300
301         p = *which_path;
302         while (1)
303           {
304             if (!strncmp (p, name, len)
305                 && (p[len] == '\0' || p[len] == ':'))
306               {
307                 /* Found it in the search path, remove old copy */
308                 if (p > *which_path)
309                   p--;                  /* Back over leading colon */
310                 if (prefix > p - *which_path)
311                   goto skip_dup;        /* Same dir twice in one cmd */
312                 strcpy (p, &p[len+1]);  /* Copy from next \0 or  : */
313               }
314             p = index (p, ':');
315             if (p != 0)
316               ++p;
317             else
318               break;
319           }
320         if (p == 0)
321           {
322             /* If we have already tacked on a name(s) in this command,                     be sure they stay on the front as we tack on some more.  */
323             if (prefix)
324               {
325                 char *temp, c;
326
327                 c = old[prefix];
328                 old[prefix] = '\0';
329                 temp = concat (old, ":", name);
330                 old[prefix] = c;
331                 *which_path = concat (temp, "", &old[prefix]);
332                 prefix = strlen (temp);
333                 free (temp);
334               }
335             else
336               {
337                 *which_path = concat (name, (old[0]? ":" : old), old);
338                 prefix = strlen (name);
339               }
340             free (old);
341             old = *which_path;
342           }
343       }
344   skip_dup: ;
345     } while (*dirname != '\0');
346 }
347
348
349 static void
350 source_info ()
351 {
352   register struct symtab *s = current_source_symtab;
353
354   if (!s)
355     {
356       printf("No current source file.\n");
357       return;
358     }
359   printf ("Current source file is %s\n", s->filename);
360   if (s->dirname)
361     printf ("Compilation directory is %s\n", s->dirname);
362   if (s->fullname)
363     printf ("Located in %s\n", s->fullname);
364   if (s->nlines)
365     printf ("Contains %d lines\n", s->nlines);
366
367   switch (s->language) {
368   case language_c:
369     printf("Written in the C language.\n");
370   /* Add more cases here when -Wswitch complains... */
371   case language_unknown:
372     break;
373   }
374 }
375
376
377 \f
378 /* Open a file named STRING, searching path PATH (dir names sep by colons)
379    using mode MODE and protection bits PROT in the calls to open.
380    If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
381    (ie pretend the first element of PATH is ".")
382    If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
383    the actual file opened (this string will always start with a "/".  We
384    have to take special pains to avoid doubling the "/" between the directory
385    and the file, sigh!  Emacs gets confuzzed by this when we print the
386    source file name!!! 
387
388    If a file is found, return the descriptor.
389    Otherwise, return -1, with errno set for the last name we tried to open.  */
390
391 /*  >>>> This should only allow files of certain types,
392     >>>>  eg executable, non-directory */
393 int
394 openp (path, try_cwd_first, string, mode, prot, filename_opened)
395      char *path;
396      int try_cwd_first;
397      char *string;
398      int mode;
399      int prot;
400      char **filename_opened;
401 {
402   register int fd;
403   register char *filename;
404   register char *p, *p1;
405   register int len;
406   int alloclen;
407
408   if (!path)
409     path = ".";
410
411   /* ./foo => foo */
412   while (string[0] == '.' && string[1] == '/')
413     string += 2;
414
415   if (try_cwd_first || string[0] == '/')
416     {
417       filename = string;
418       fd = open (filename, mode, prot);
419       if (fd >= 0 || string[0] == '/')
420         goto done;
421     }
422
423   alloclen = strlen (path) + strlen (string) + 2;
424   filename = (char *) alloca (alloclen);
425   fd = -1;
426   for (p = path; p; p = p1 ? p1 + 1 : 0)
427     {
428       p1 = (char *) index (p, ':');
429       if (p1)
430         len = p1 - p;
431       else
432         len = strlen (p);
433
434       if (len == 4 && p[0] == '$' && p[1] == 'c'
435                    && p[2] == 'w' && p[3] == 'd') {
436         /* Name is $cwd -- insert current directory name instead.  */
437         int newlen;
438
439         /* First, realloc the filename buffer if too short. */
440         len = strlen (current_directory);
441         newlen = len + strlen (string) + 2;
442         if (newlen > alloclen) {
443           alloclen = newlen;
444           filename = (char *) alloca (alloclen);
445         }
446         strcpy (filename, current_directory);
447       } else {
448         /* Normal file name in path -- just use it.  */
449         strncpy (filename, p, len);
450         filename[len] = 0;
451       }
452
453       /* Beware the // my son, the Emacs barfs, the botch that catch... */
454       while (len > 1 && filename[len-1] == '/')
455         filename[--len] = 0;
456       strcat (filename+len, "/");
457       strcat (filename, string);
458
459       fd = open (filename, mode, prot);
460       if (fd >= 0) break;
461     }
462
463  done:
464   if (filename_opened)
465     if (fd < 0)
466       *filename_opened = (char *) 0;
467     else if (filename[0] == '/')
468       *filename_opened = savestring (filename, strlen (filename));
469     else
470       {
471         /* Beware the // my son, the Emacs barfs, the botch that catch... */
472            
473         *filename_opened = concat (current_directory, 
474            '/' == current_directory[strlen(current_directory)-1]? "": "/",
475                                    filename);
476       }
477
478   return fd;
479 }
480
481 /* Open a source file given a symtab S.  Returns a file descriptor
482    or negative number for error.  */
483 int
484 open_source_file (s)
485      struct symtab *s;
486 {
487   char *path = source_path;
488   char *p;
489   int result;
490
491   /* Quick way out if we already know its full name */
492   if (s->fullname) 
493     {
494       result = open (s->fullname, O_RDONLY);
495       if (result >= 0)
496         return result;
497       /* Didn't work -- free old one, try again. */
498       free (s->fullname);
499       s->fullname = NULL;
500     }
501
502   if (s->dirname != NULL)
503     {
504       /* Replace a path entry of  $cdir  with the compilation directory name */
505 #define cdir_len        5
506       p = strstr (source_path, "$cdir");
507       if (p && (p == path || p[-1] == ':')
508             && (p[cdir_len] == ':' || p[cdir_len] == '\0')) {
509         int len;
510
511         path = (char *)
512                alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
513         len = p - source_path;
514         strncpy (path, source_path, len);               /* Before $cdir */
515         strcpy (path + len, s->dirname);                /* new stuff */
516         strcat (path + len, source_path + len + cdir_len); /* After $cdir */
517       }
518     }
519
520   return openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
521 }
522
523 \f
524 /* Create and initialize the table S->line_charpos that records
525    the positions of the lines in the source file, which is assumed
526    to be open on descriptor DESC.
527    All set S->nlines to the number of such lines.  */
528
529 static void
530 find_source_lines (s, desc)
531      struct symtab *s;
532      int desc;
533 {
534   struct stat st;
535   register char *data, *p, *end;
536   int nlines = 0;
537   int lines_allocated = 1000;
538   int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
539
540   if (fstat (desc, &st) < 0)
541     perror_with_name (s->filename);
542   if (exec_bfd && bfd_get_mtime(exec_bfd) < st.st_mtime)
543     printf ("Source file is more recent than executable.\n");
544
545 #ifdef BROKEN_LARGE_ALLOCA
546   data = (char *) xmalloc (st.st_size);
547   make_cleanup (free, data);
548 #else
549   data = (char *) alloca (st.st_size);
550 #endif
551   if (myread (desc, data, st.st_size) < 0)
552     perror_with_name (s->filename);
553   end = data + st.st_size;
554   p = data;
555   line_charpos[0] = 0;
556   nlines = 1;
557   while (p != end)
558     {
559       if (*p++ == '\n'
560           /* A newline at the end does not start a new line.  */
561           && p != end)
562         {
563           if (nlines == lines_allocated)
564             {
565               lines_allocated *= 2;
566               line_charpos = (int *) xrealloc (line_charpos,
567                                                sizeof (int) * lines_allocated);
568             }
569           line_charpos[nlines++] = p - data;
570         }
571     }
572   s->nlines = nlines;
573   s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int));
574 }
575
576 /* Return the character position of a line LINE in symtab S.
577    Return 0 if anything is invalid.  */
578
579 int
580 source_line_charpos (s, line)
581      struct symtab *s;
582      int line;
583 {
584   if (!s) return 0;
585   if (!s->line_charpos || line <= 0) return 0;
586   if (line > s->nlines)
587     line = s->nlines;
588   return s->line_charpos[line - 1];
589 }
590
591 /* Return the line number of character position POS in symtab S.  */
592
593 int
594 source_charpos_line (s, chr)
595     register struct symtab *s;
596     register int chr;
597 {
598   register int line = 0;
599   register int *lnp;
600     
601   if (s == 0 || s->line_charpos == 0) return 0;
602   lnp = s->line_charpos;
603   /* Files are usually short, so sequential search is Ok */
604   while (line < s->nlines  && *lnp <= chr)
605     {
606       line++;
607       lnp++;
608     }
609   if (line >= s->nlines)
610     line = s->nlines;
611   return line;
612 }
613 \f
614 /* Get full pathname and line number positions for a symtab.
615    Return nonzero if line numbers may have changed.
616    Set *FULLNAME to actual name of the file as found by `openp',
617    or to 0 if the file is not found.  */
618
619 int
620 get_filename_and_charpos (s, fullname)
621      struct symtab *s;
622      char **fullname;
623 {
624   register int desc, linenums_changed = 0;
625   
626   desc = open_source_file (s);
627   if (desc < 0)
628     {
629       if (fullname)
630         *fullname = NULL;
631       return 0;
632     }  
633   if (fullname)
634     *fullname = s->fullname;
635   if (s->line_charpos == 0) linenums_changed = 1;
636   if (linenums_changed) find_source_lines (s, desc);
637   close (desc);
638   return linenums_changed;
639 }
640
641 /* Print text describing the full name of the source file S
642    and the line number LINE and its corresponding character position.
643    The text starts with two Ctrl-z so that the Emacs-GDB interface
644    can easily find it.
645
646    MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
647
648    Return 1 if successful, 0 if could not find the file.  */
649
650 int
651 identify_source_line (s, line, mid_statement)
652      struct symtab *s;
653      int line;
654      int mid_statement;
655 {
656   if (s->line_charpos == 0)
657     get_filename_and_charpos (s, (char **)NULL);
658   if (s->fullname == 0)
659     return 0;
660   printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
661           line, s->line_charpos[line - 1],
662           mid_statement ? "middle" : "beg",
663           get_frame_pc (get_current_frame()));
664   current_source_line = line;
665   first_line_listed = line;
666   last_line_listed = line;
667   current_source_symtab = s;
668   return 1;
669 }
670 \f
671 /* Print source lines from the file of symtab S,
672    starting with line number LINE and stopping before line number STOPLINE.  */
673
674 void
675 print_source_lines (s, line, stopline, noerror)
676      struct symtab *s;
677      int line, stopline;
678      int noerror;
679 {
680   register int c;
681   register int desc;
682   register FILE *stream;
683   int nlines = stopline - line;
684
685   /* Regardless of whether we can open the file, set current_source_symtab. */
686   current_source_symtab = s;
687   current_source_line = line;
688   first_line_listed = line;
689
690   desc = open_source_file (s);
691   if (desc < 0)
692     {
693       if (! noerror) {
694         char *name = alloca (strlen (s->filename) + 100);
695         sprintf (name, "%s:%d", s->filename, line);
696         print_sys_errmsg (name, errno);
697       }
698       return;
699     }
700
701   if (s->line_charpos == 0)
702     find_source_lines (s, desc);
703
704   if (line < 1 || line > s->nlines)
705     {
706       close (desc);
707       error ("Line number %d out of range; %s has %d lines.",
708              line, s->filename, s->nlines);
709     }
710
711   if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
712     {
713       close (desc);
714       perror_with_name (s->filename);
715     }
716
717   stream = fdopen (desc, "r");
718   clearerr (stream);
719
720   while (nlines-- > 0)
721     {
722       c = fgetc (stream);
723       if (c == EOF) break;
724       last_line_listed = current_source_line;
725       printf_filtered ("%d\t", current_source_line++);
726       do
727         {
728           if (c < 040 && c != '\t' && c != '\n')
729               printf_filtered ("^%c", c + 0100);
730           else if (c == 0177)
731             printf_filtered ("^?");
732           else
733             printf_filtered ("%c", c);
734         } while (c != '\n' && (c = fgetc (stream)) >= 0);
735     }
736
737   fclose (stream);
738 }
739 \f
740
741
742 /* 
743   C++
744   Print a list of files and line numbers which a user may choose from
745   in order to list a function which was specified ambiguously
746   (as with `list classname::overloadedfuncname', for example).
747   The vector in SALS provides the filenames and line numbers.
748   */
749 static void
750 ambiguous_line_spec (sals)
751      struct symtabs_and_lines *sals;
752 {
753   int i;
754
755   for (i = 0; i < sals->nelts; ++i)
756     printf("file: \"%s\", line number: %d\n",
757            sals->sals[i].symtab->filename, sals->sals[i].line);
758 }
759
760
761 static void
762 list_command (arg, from_tty)
763      char *arg;
764      int from_tty;
765 {
766   struct symtabs_and_lines sals, sals_end;
767   struct symtab_and_line sal, sal_end;
768   struct symbol *sym;
769   char *arg1;
770   int no_end = 1;
771   int dummy_end = 0;
772   int dummy_beg = 0;
773   int linenum_beg = 0;
774   char *p;
775
776   if (symtab_list == 0 && partial_symtab_list == 0)
777     error ("No symbol table is loaded.  Use the \"file\" command.");
778
779   /* Pull in a current source symtab if necessary */
780   if (current_source_symtab == 0 &&
781       (arg == 0 || arg[0] == '+' || arg[0] == '-'))
782     select_source_symtab (0);
783
784   /* "l" or "l +" lists next ten lines.  */
785
786   if (arg == 0 || !strcmp (arg, "+"))
787     {
788       if (current_source_symtab == 0)
789         error ("No default source file yet.  Do \"help list\".");
790       print_source_lines (current_source_symtab, current_source_line,
791                           current_source_line + lines_to_list (), 0);
792       return;
793     }
794
795   /* "l -" lists previous ten lines, the ones before the ten just listed.  */
796   if (!strcmp (arg, "-"))
797     {
798       if (current_source_symtab == 0)
799         error ("No default source file yet.  Do \"help list\".");
800       print_source_lines (current_source_symtab,
801                           max (first_line_listed - lines_to_list (), 1),
802                           first_line_listed, 0);
803       return;
804     }
805
806   /* Now if there is only one argument, decode it in SAL
807      and set NO_END.
808      If there are two arguments, decode them in SAL and SAL_END
809      and clear NO_END; however, if one of the arguments is blank,
810      set DUMMY_BEG or DUMMY_END to record that fact.  */
811
812   arg1 = arg;
813   if (*arg1 == ',')
814     dummy_beg = 1;
815   else
816     {
817       sals = decode_line_1 (&arg1, 0, 0, 0);
818
819       if (! sals.nelts) return;  /*  C++  */
820       if (sals.nelts > 1)
821         {
822           ambiguous_line_spec (&sals);
823           free (sals.sals);
824           return;
825         }
826
827       sal = sals.sals[0];
828       free (sals.sals);
829     }
830
831   /* Record whether the BEG arg is all digits.  */
832
833   for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
834   linenum_beg = (p == arg1);
835
836   while (*arg1 == ' ' || *arg1 == '\t')
837     arg1++;
838   if (*arg1 == ',')
839     {
840       no_end = 0;
841       arg1++;
842       while (*arg1 == ' ' || *arg1 == '\t')
843         arg1++;
844       if (*arg1 == 0)
845         dummy_end = 1;
846       else
847         {
848           if (dummy_beg)
849             sals_end = decode_line_1 (&arg1, 0, 0, 0);
850           else
851             sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
852           if (sals_end.nelts == 0) 
853             return;
854           if (sals_end.nelts > 1)
855             {
856               ambiguous_line_spec (&sals_end);
857               free (sals_end.sals);
858               return;
859             }
860           sal_end = sals_end.sals[0];
861           free (sals_end.sals);
862         }
863     }
864
865   if (*arg1)
866     error ("Junk at end of line specification.");
867
868   if (!no_end && !dummy_beg && !dummy_end
869       && sal.symtab != sal_end.symtab)
870     error ("Specified start and end are in different files.");
871   if (dummy_beg && dummy_end)
872     error ("Two empty args do not say what lines to list.");
873  
874   /* if line was specified by address,
875      first print exactly which line, and which file.
876      In this case, sal.symtab == 0 means address is outside
877      of all known source files, not that user failed to give a filename.  */
878   if (*arg == '*')
879     {
880       if (sal.symtab == 0)
881         error ("No source file for address 0x%x.", sal.pc);
882       sym = find_pc_function (sal.pc);
883       if (sym)
884         printf ("0x%x is in %s (%s, line %d).\n",
885                 sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line);
886       else
887         printf ("0x%x is in %s, line %d.\n",
888                 sal.pc, sal.symtab->filename, sal.line);
889     }
890
891   /* If line was not specified by just a line number,
892      and it does not imply a symtab, it must be an undebuggable symbol
893      which means no source code.  */
894
895   if (! linenum_beg && sal.symtab == 0)
896     error ("No line number known for %s.", arg);
897
898   /* If this command is repeated with RET,
899      turn it into the no-arg variant.  */
900
901   if (from_tty)
902     *arg = 0;
903
904   if (dummy_beg && sal_end.symtab == 0)
905     error ("No default source file yet.  Do \"help list\".");
906   if (dummy_beg)
907     print_source_lines (sal_end.symtab,
908                         max (sal_end.line - (lines_to_list () - 1), 1),
909                         sal_end.line + 1, 0);
910   else if (sal.symtab == 0)
911     error ("No default source file yet.  Do \"help list\".");
912   else if (no_end)
913     print_source_lines (sal.symtab,
914                         max (sal.line - (lines_to_list () / 2), 1),
915                         sal.line + (lines_to_list() / 2), 0);
916   else
917     print_source_lines (sal.symtab, sal.line,
918                         (dummy_end
919                          ? sal.line + lines_to_list ()
920                          : sal_end.line + 1),
921                         0);
922 }
923 \f
924 /* Print info on range of pc's in a specified line.  */
925
926 static void
927 line_info (arg, from_tty)
928      char *arg;
929      int from_tty;
930 {
931   struct symtabs_and_lines sals;
932   struct symtab_and_line sal;
933   CORE_ADDR start_pc, end_pc;
934   int i;
935
936   if (arg == 0)
937     {
938       sal.symtab = current_source_symtab;
939       sal.line = last_line_listed;
940       sals.nelts = 1;
941       sals.sals = (struct symtab_and_line *)
942         xmalloc (sizeof (struct symtab_and_line));
943       sals.sals[0] = sal;
944     }
945   else
946     {
947       sals = decode_line_spec_1 (arg, 0);
948       
949       /* If this command is repeated with RET,
950          turn it into the no-arg variant.  */
951       if (from_tty)
952         *arg = 0;
953     }
954
955   /* C++  More than one line may have been specified, as when the user
956      specifies an overloaded function name. Print info on them all. */
957   for (i = 0; i < sals.nelts; i++)
958     {
959       sal = sals.sals[i];
960       
961       if (sal.symtab == 0)
962         error ("No source file specified.");
963
964       if (sal.line > 0
965           && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
966         {
967           if (start_pc == end_pc)
968             printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
969                     sal.line, sal.symtab->filename, start_pc);
970           else
971             printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
972                     sal.line, sal.symtab->filename, start_pc, end_pc);
973           /* x/i should display this line's code.  */
974           set_next_address (start_pc);
975           /* Repeating "info line" should do the following line.  */
976           last_line_listed = sal.line + 1;
977         }
978       else
979         printf ("Line number %d is out of range for \"%s\".\n",
980                 sal.line, sal.symtab->filename);
981     }
982 }
983 \f
984 /* Commands to search the source file for a regexp.  */
985
986 /* ARGSUSED */
987 static void
988 forward_search_command (regex, from_tty)
989      char *regex;
990      int from_tty;
991 {
992   register int c;
993   register int desc;
994   register FILE *stream;
995   int line = last_line_listed + 1;
996   char *msg;
997
998   msg = (char *) re_comp (regex);
999   if (msg)
1000     error (msg);
1001
1002   if (current_source_symtab == 0)
1003     select_source_symtab (0);
1004
1005   /* Search from last_line_listed+1 in current_source_symtab */
1006
1007   desc = open_source_file (current_source_symtab);
1008   if (desc < 0)
1009     perror_with_name (current_source_symtab->filename);
1010
1011   if (current_source_symtab->line_charpos == 0)
1012     find_source_lines (current_source_symtab, desc);
1013
1014   if (line < 1 || line > current_source_symtab->nlines)
1015     {
1016       close (desc);
1017       error ("Expression not found");
1018     }
1019
1020   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1021     {
1022       close (desc);
1023       perror_with_name (current_source_symtab->filename);
1024     }
1025
1026   stream = fdopen (desc, "r");
1027   clearerr (stream);
1028   while (1) {
1029 /* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
1030     char buf[4096];             /* Should be reasonable??? */
1031     register char *p = buf;
1032
1033     c = getc (stream);
1034     if (c == EOF)
1035       break;
1036     do {
1037       *p++ = c;
1038     } while (c != '\n' && (c = getc (stream)) >= 0);
1039
1040     /* we now have a source line in buf, null terminate and match */
1041     *p = 0;
1042     if (re_exec (buf) > 0)
1043       {
1044         /* Match! */
1045         fclose (stream);
1046         print_source_lines (current_source_symtab,
1047                            line, line+1, 0);
1048         current_source_line = max (line - lines_to_list () / 2, 1);
1049         return;
1050       }
1051     line++;
1052   }
1053
1054   printf ("Expression not found\n");
1055   fclose (stream);
1056 }
1057
1058 /* ARGSUSED */
1059 static void
1060 reverse_search_command (regex, from_tty)
1061      char *regex;
1062      int from_tty;
1063 {
1064   register int c;
1065   register int desc;
1066   register FILE *stream;
1067   int line = last_line_listed - 1;
1068   char *msg;
1069
1070   msg = (char *) re_comp (regex);
1071   if (msg)
1072     error (msg);
1073
1074   if (current_source_symtab == 0)
1075     select_source_symtab (0);
1076
1077   /* Search from last_line_listed-1 in current_source_symtab */
1078
1079   desc = open_source_file (current_source_symtab);
1080   if (desc < 0)
1081     perror_with_name (current_source_symtab->filename);
1082
1083   if (current_source_symtab->line_charpos == 0)
1084     find_source_lines (current_source_symtab, desc);
1085
1086   if (line < 1 || line > current_source_symtab->nlines)
1087     {
1088       close (desc);
1089       error ("Expression not found");
1090     }
1091
1092   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1093     {
1094       close (desc);
1095       perror_with_name (current_source_symtab->filename);
1096     }
1097
1098   stream = fdopen (desc, "r");
1099   clearerr (stream);
1100   while (line > 1)
1101     {
1102 /* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
1103       char buf[4096];           /* Should be reasonable??? */
1104       register char *p = buf;
1105
1106       c = getc (stream);
1107       if (c == EOF)
1108         break;
1109       do {
1110         *p++ = c;
1111       } while (c != '\n' && (c = getc (stream)) >= 0);
1112
1113       /* We now have a source line in buf; null terminate and match.  */
1114       *p = 0;
1115       if (re_exec (buf) > 0)
1116         {
1117           /* Match! */
1118           fclose (stream);
1119           print_source_lines (current_source_symtab,
1120                               line, line+1, 0);
1121           current_source_line = max (line - lines_to_list () / 2, 1);
1122           return;
1123         }
1124       line--;
1125       if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
1126         {
1127           fclose (stream);
1128           perror_with_name (current_source_symtab->filename);
1129         }
1130     }
1131
1132   printf ("Expression not found\n");
1133   fclose (stream);
1134   return;
1135 }
1136 \f
1137 void
1138 _initialize_source ()
1139 {
1140   current_source_symtab = 0;
1141   init_source_path ();
1142
1143   add_com ("directory", class_files, directory_command,
1144            "Add directory DIR to beginning of search path for source files.\n\
1145 Forget cached info on source file locations and line positions.\n\
1146 DIR can also be $cwd for the current working directory, or $cdir for the\n\
1147 directory in which the source file was compiled into object code.\n\
1148 With no argument, reset the search path to $cdir:$cwd, the default.");
1149
1150   add_cmd ("directories", no_class, show_directories,
1151            "Current search path for finding source files.\n\
1152 $cwd in the path means the current working directory.\n\
1153 $cdir in the path means the compilation directory of the source file.",
1154            &showlist);
1155
1156   add_info ("source", source_info,
1157             "Information about the current source file.");
1158
1159   add_info ("line", line_info,
1160             "Core addresses of the code for a source line.\n\
1161 Line can be specified as\n\
1162   LINENUM, to list around that line in current file,\n\
1163   FILE:LINENUM, to list around that line in that file,\n\
1164   FUNCTION, to list around beginning of that function,\n\
1165   FILE:FUNCTION, to distinguish among like-named static functions.\n\
1166 Default is to describe the last source line that was listed.\n\n\
1167 This sets the default address for \"x\" to the line's first instruction\n\
1168 so that \"x/i\" suffices to start examining the machine code.\n\
1169 The address is also stored as the value of \"$_\".");
1170
1171   add_com ("forward-search", class_files, forward_search_command,
1172            "Search for regular expression (see regex(3)) from last line listed.");
1173   add_com_alias ("search", "forward-search", class_files, 0);
1174
1175   add_com ("reverse-search", class_files, reverse_search_command,
1176            "Search backward for regular expression (see regex(3)) from last line listed.");
1177
1178   add_com ("list", class_files, list_command,
1179            "List specified function or line.\n\
1180 With no argument, lists ten more lines after or around previous listing.\n\
1181 \"list -\" lists the ten lines before a previous ten-line listing.\n\
1182 One argument specifies a line, and ten lines are listed around that line.\n\
1183 Two arguments with comma between specify starting and ending lines to list.\n\
1184 Lines can be specified in these ways:\n\
1185   LINENUM, to list around that line in current file,\n\
1186   FILE:LINENUM, to list around that line in that file,\n\
1187   FUNCTION, to list around beginning of that function,\n\
1188   FILE:FUNCTION, to distinguish among like-named static functions.\n\
1189   *ADDRESS, to list around the line containing that address.\n\
1190 With two args if one is empty it stands for ten lines away from the other arg.");
1191   add_com_alias ("l", "list", class_files, 0);
1192 }
1193
This page took 0.091512 seconds and 4 git commands to generate.