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