OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [source.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* List lines of source files for GDB, the GNU debugger.
2
   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
3
   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "symtab.h"
25
#include "expression.h"
26
#include "language.h"
27
#include "command.h"
28
#include "source.h"
29
#include "gdbcmd.h"
30
#include "frame.h"
31
#include "value.h"
32
 
33
#include <sys/types.h>
34
#include "gdb_string.h"
35
#include "gdb_stat.h"
36
#include <fcntl.h>
37
#include "gdbcore.h"
38
#include "gdb_regex.h"
39
#include "symfile.h"
40
#include "objfiles.h"
41
#include "annotate.h"
42
#include "gdbtypes.h"
43
#include "linespec.h"
44
#include "filenames.h"          /* for DOSish file names */
45
#include "completer.h"
46
#include "ui-out.h"
47
 
48
#ifdef CRLF_SOURCE_FILES
49
 
50
/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
51
   host use \r\n rather than just \n.  Defining CRLF_SOURCE_FILES is
52
   much faster than defining LSEEK_NOT_LINEAR.  */
53
 
54
#ifndef O_BINARY
55
#define O_BINARY 0
56
#endif
57
 
58
#define OPEN_MODE (O_RDONLY | O_BINARY)
59
#define FDOPEN_MODE FOPEN_RB
60
 
61
#else /* ! defined (CRLF_SOURCE_FILES) */
62
 
63
#define OPEN_MODE O_RDONLY
64
#define FDOPEN_MODE FOPEN_RT
65
 
66
#endif /* ! defined (CRLF_SOURCE_FILES) */
67
 
68
/* Prototypes for exported functions. */
69
 
70
void _initialize_source (void);
71
 
72
/* Prototypes for local functions. */
73
 
74
static int get_filename_and_charpos (struct symtab *, char **);
75
 
76
static void reverse_search_command (char *, int);
77
 
78
static void forward_search_command (char *, int);
79
 
80
static void line_info (char *, int);
81
 
82
static void list_command (char *, int);
83
 
84
static void ambiguous_line_spec (struct symtabs_and_lines *);
85
 
86
static void source_info (char *, int);
87
 
88
static void show_directories (char *, int);
89
 
90
/* Path of directories to search for source files.
91
   Same format as the PATH environment variable's value.  */
92
 
93
char *source_path;
94
 
95
/* Symtab of default file for listing lines of.  */
96
 
97
struct symtab *current_source_symtab;
98
 
99
/* Default next line to list.  */
100
 
101
int current_source_line;
102
 
103
/* Default number of lines to print with commands like "list".
104
   This is based on guessing how many long (i.e. more than chars_per_line
105
   characters) lines there will be.  To be completely correct, "list"
106
   and friends should be rewritten to count characters and see where
107
   things are wrapping, but that would be a fair amount of work.  */
108
 
109
int lines_to_list = 10;
110
 
111
/* Line number of last line printed.  Default for various commands.
112
   current_source_line is usually, but not always, the same as this.  */
113
 
114
static int last_line_listed;
115
 
116
/* First line number listed by last listing command.  */
117
 
118
static int first_line_listed;
119
 
120
/* Saves the name of the last source file visited and a possible error code.
121
   Used to prevent repeating annoying "No such file or directories" msgs */
122
 
123
static struct symtab *last_source_visited = NULL;
124
static int last_source_error = 0;
125
 
126
 
127
/* Set the source file default for the "list" command to be S.
128
 
129
   If S is NULL, and we don't have a default, find one.  This
130
   should only be called when the user actually tries to use the
131
   default, since we produce an error if we can't find a reasonable
132
   default.  Also, since this can cause symbols to be read, doing it
133
   before we need to would make things slower than necessary.  */
134
 
135
void
136
select_source_symtab (register struct symtab *s)
137
{
138
  struct symtabs_and_lines sals;
139
  struct symtab_and_line sal;
140
  struct partial_symtab *ps;
141
  struct partial_symtab *cs_pst = 0;
142
  struct objfile *ofp;
143
 
144
  if (s)
145
    {
146
      current_source_symtab = s;
147
      current_source_line = 1;
148
      return;
149
    }
150
 
151
  if (current_source_symtab)
152
    return;
153
 
154
  /* Make the default place to list be the function `main'
155
     if one exists.  */
156
  if (lookup_symbol (main_name (), 0, VAR_NAMESPACE, 0, NULL))
157
    {
158
      sals = decode_line_spec (main_name (), 1);
159
      sal = sals.sals[0];
160
      xfree (sals.sals);
161
      current_source_symtab = sal.symtab;
162
      current_source_line = max (sal.line - (lines_to_list - 1), 1);
163
      if (current_source_symtab)
164
        return;
165
    }
166
 
167
  /* All right; find the last file in the symtab list (ignoring .h's).  */
168
 
169
  current_source_line = 1;
170
 
171
  for (ofp = object_files; ofp != NULL; ofp = ofp->next)
172
    {
173
      for (s = ofp->symtabs; s; s = s->next)
174
        {
175
          char *name = s->filename;
176
          int len = strlen (name);
177
          if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
178
            {
179
              current_source_symtab = s;
180
            }
181
        }
182
    }
183
  if (current_source_symtab)
184
    return;
185
 
186
  /* Howabout the partial symbol tables? */
187
 
188
  for (ofp = object_files; ofp != NULL; ofp = ofp->next)
189
    {
190
      for (ps = ofp->psymtabs; ps != NULL; ps = ps->next)
191
        {
192
          char *name = ps->filename;
193
          int len = strlen (name);
194
          if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
195
            {
196
              cs_pst = ps;
197
            }
198
        }
199
    }
200
  if (cs_pst)
201
    {
202
      if (cs_pst->readin)
203
        {
204
          internal_error (__FILE__, __LINE__,
205
                          "select_source_symtab: "
206
                          "readin pst found and no symtabs.");
207
        }
208
      else
209
        {
210
          current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
211
        }
212
    }
213
  if (current_source_symtab)
214
    return;
215
 
216
  error ("Can't find a default source file");
217
}
218
 
219
static void
220
show_directories (char *ignore, int from_tty)
221
{
222
  puts_filtered ("Source directories searched: ");
223
  puts_filtered (source_path);
224
  puts_filtered ("\n");
225
}
226
 
227
/* Forget what we learned about line positions in source files, and
228
   which directories contain them; must check again now since files
229
   may be found in a different directory now.  */
230
 
231
void
232
forget_cached_source_info (void)
233
{
234
  register struct symtab *s;
235
  register struct objfile *objfile;
236
  struct partial_symtab *pst;
237
 
238
  for (objfile = object_files; objfile != NULL; objfile = objfile->next)
239
    {
240
      for (s = objfile->symtabs; s != NULL; s = s->next)
241
        {
242
          if (s->line_charpos != NULL)
243
            {
244
              xmfree (objfile->md, s->line_charpos);
245
              s->line_charpos = NULL;
246
            }
247
          if (s->fullname != NULL)
248
            {
249
              xmfree (objfile->md, s->fullname);
250
              s->fullname = NULL;
251
            }
252
        }
253
 
254
      ALL_OBJFILE_PSYMTABS (objfile, pst)
255
      {
256
        if (pst->fullname != NULL)
257
          {
258
            xfree (pst->fullname);
259
            pst->fullname = NULL;
260
          }
261
      }
262
    }
263
}
264
 
265
void
266
init_source_path (void)
267
{
268
  char buf[20];
269
 
270
  sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
271
  source_path = xstrdup (buf);
272
  forget_cached_source_info ();
273
}
274
 
275
/* Add zero or more directories to the front of the source path.  */
276
 
277
void
278
directory_command (char *dirname, int from_tty)
279
{
280
  dont_repeat ();
281
  /* FIXME, this goes to "delete dir"... */
282
  if (dirname == 0)
283
    {
284
      if (from_tty && query ("Reinitialize source path to empty? "))
285
        {
286
          xfree (source_path);
287
          init_source_path ();
288
        }
289
    }
290
  else
291
    {
292
      mod_path (dirname, &source_path);
293
      last_source_visited = NULL;
294
    }
295
  if (from_tty)
296
    show_directories ((char *) 0, from_tty);
297
  forget_cached_source_info ();
298
}
299
 
300
/* Add zero or more directories to the front of an arbitrary path.  */
301
 
302
void
303
mod_path (char *dirname, char **which_path)
304
{
305
  char *old = *which_path;
306
  int prefix = 0;
307
 
308
  if (dirname == 0)
309
    return;
310
 
311
  dirname = xstrdup (dirname);
312
  make_cleanup (xfree, dirname);
313
 
314
  do
315
    {
316
      char *name = dirname;
317
      register char *p;
318
      struct stat st;
319
 
320
      {
321
        char *separator = strchr (name, DIRNAME_SEPARATOR);
322
        char *space = strchr (name, ' ');
323
        char *tab = strchr (name, '\t');
324
 
325
        if (separator == 0 && space == 0 && tab == 0)
326
          p = dirname = name + strlen (name);
327
        else
328
          {
329
            p = 0;
330
            if (separator != 0 && (p == 0 || separator < p))
331
              p = separator;
332
            if (space != 0 && (p == 0 || space < p))
333
              p = space;
334
            if (tab != 0 && (p == 0 || tab < p))
335
              p = tab;
336
            dirname = p + 1;
337
            while (*dirname == DIRNAME_SEPARATOR
338
                   || *dirname == ' '
339
                   || *dirname == '\t')
340
              ++dirname;
341
          }
342
      }
343
 
344
      if (!(IS_DIR_SEPARATOR (*name) && p <= name + 1)   /* "/" */
345
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
346
      /* On MS-DOS and MS-Windows, h:\ is different from h: */
347
          && !(p == name + 3 && name[1] == ':')          /* "d:/" */
348
#endif
349
          && IS_DIR_SEPARATOR (p[-1]))
350
        /* Sigh. "foo/" => "foo" */
351
        --p;
352
      *p = '\0';
353
 
354
      while (p > name && p[-1] == '.')
355
        {
356
          if (p - name == 1)
357
            {
358
              /* "." => getwd ().  */
359
              name = current_directory;
360
              goto append;
361
            }
362
          else if (p > name + 1 && IS_DIR_SEPARATOR (p[-2]))
363
            {
364
              if (p - name == 2)
365
                {
366
                  /* "/." => "/".  */
367
                  *--p = '\0';
368
                  goto append;
369
                }
370
              else
371
                {
372
                  /* "...foo/." => "...foo".  */
373
                  p -= 2;
374
                  *p = '\0';
375
                  continue;
376
                }
377
            }
378
          else
379
            break;
380
        }
381
 
382
      if (name[0] == '~')
383
        name = tilde_expand (name);
384
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
385
      else if (IS_ABSOLUTE_PATH (name) && p == name + 2) /* "d:" => "d:." */
386
        name = concat (name, ".", NULL);
387
#endif
388
      else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
389
        name = concat (current_directory, SLASH_STRING, name, NULL);
390
      else
391
        name = savestring (name, p - name);
392
      make_cleanup (xfree, name);
393
 
394
      /* Unless it's a variable, check existence.  */
395
      if (name[0] != '$')
396
        {
397
          /* These are warnings, not errors, since we don't want a
398
             non-existent directory in a .gdbinit file to stop processing
399
             of the .gdbinit file.
400
 
401
             Whether they get added to the path is more debatable.  Current
402
             answer is yes, in case the user wants to go make the directory
403
             or whatever.  If the directory continues to not exist/not be
404
             a directory/etc, then having them in the path should be
405
             harmless.  */
406
          if (stat (name, &st) < 0)
407
            {
408
              int save_errno = errno;
409
              fprintf_unfiltered (gdb_stderr, "Warning: ");
410
              print_sys_errmsg (name, save_errno);
411
            }
412
          else if ((st.st_mode & S_IFMT) != S_IFDIR)
413
            warning ("%s is not a directory.", name);
414
        }
415
 
416
    append:
417
      {
418
        register unsigned int len = strlen (name);
419
 
420
        p = *which_path;
421
        while (1)
422
          {
423
            /* FIXME: strncmp loses in interesting ways on MS-DOS and
424
               MS-Windows because of case-insensitivity and two different
425
               but functionally identical slash characters.  We need a
426
               special filesystem-dependent file-name comparison function.
427
 
428
               Actually, even on Unix I would use realpath() or its work-
429
               alike before comparing.  Then all the code above which
430
               removes excess slashes and dots could simply go away.  */
431
            if (!strncmp (p, name, len)
432
                && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
433
              {
434
                /* Found it in the search path, remove old copy */
435
                if (p > *which_path)
436
                  p--;          /* Back over leading separator */
437
                if (prefix > p - *which_path)
438
                  goto skip_dup;        /* Same dir twice in one cmd */
439
                strcpy (p, &p[len + 1]);        /* Copy from next \0 or  : */
440
              }
441
            p = strchr (p, DIRNAME_SEPARATOR);
442
            if (p != 0)
443
              ++p;
444
            else
445
              break;
446
          }
447
        if (p == 0)
448
          {
449
            char tinybuf[2];
450
 
451
            tinybuf[0] = DIRNAME_SEPARATOR;
452
            tinybuf[1] = '\0';
453
 
454
            /* 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.  */
455
            if (prefix)
456
              {
457
                char *temp, c;
458
 
459
                c = old[prefix];
460
                old[prefix] = '\0';
461
                temp = concat (old, tinybuf, name, NULL);
462
                old[prefix] = c;
463
                *which_path = concat (temp, "", &old[prefix], NULL);
464
                prefix = strlen (temp);
465
                xfree (temp);
466
              }
467
            else
468
              {
469
                *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
470
                prefix = strlen (name);
471
              }
472
            xfree (old);
473
            old = *which_path;
474
          }
475
      }
476
    skip_dup:;
477
    }
478
  while (*dirname != '\0');
479
}
480
 
481
 
482
static void
483
source_info (char *ignore, int from_tty)
484
{
485
  register struct symtab *s = current_source_symtab;
486
 
487
  if (!s)
488
    {
489
      printf_filtered ("No current source file.\n");
490
      return;
491
    }
492
  printf_filtered ("Current source file is %s\n", s->filename);
493
  if (s->dirname)
494
    printf_filtered ("Compilation directory is %s\n", s->dirname);
495
  if (s->fullname)
496
    printf_filtered ("Located in %s\n", s->fullname);
497
  if (s->nlines)
498
    printf_filtered ("Contains %d line%s.\n", s->nlines,
499
                     s->nlines == 1 ? "" : "s");
500
 
501
  printf_filtered ("Source language is %s.\n", language_str (s->language));
502
  printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
503
  printf_filtered ("%s preprocessor macro info.\n",
504
                   s->macro_table ? "Includes" : "Does not include");
505
}
506
 
507
 
508
/* Return True if the file NAME exists and is a regular file */
509
static int
510
is_regular_file (const char *name)
511
{
512
  struct stat st;
513
  const int status = stat (name, &st);
514
 
515
  /* Stat should never fail except when the file does not exist.
516
     If stat fails, analyze the source of error and return True
517
     unless the file does not exist, to avoid returning false results
518
     on obscure systems where stat does not work as expected.
519
   */
520
  if (status != 0)
521
    return (errno != ENOENT);
522
 
523
  return S_ISREG (st.st_mode);
524
}
525
 
526
/* Open a file named STRING, searching path PATH (dir names sep by some char)
527
   using mode MODE and protection bits PROT in the calls to open.
528
 
529
   If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
530
   (ie pretend the first element of PATH is ".").  This also indicates
531
   that a slash in STRING disables searching of the path (this is
532
   so that "exec-file ./foo" or "symbol-file ./foo" insures that you
533
   get that particular version of foo or an error message).
534
 
535
   If FILENAME_OPENED is non-null, set it to a newly allocated string naming
536
   the actual file opened (this string will always start with a "/").  We
537
   have to take special pains to avoid doubling the "/" between the directory
538
   and the file, sigh!  Emacs gets confuzzed by this when we print the
539
   source file name!!!
540
 
541
   If a file is found, return the descriptor.
542
   Otherwise, return -1, with errno set for the last name we tried to open.  */
543
 
544
/*  >>>> This should only allow files of certain types,
545
    >>>>  eg executable, non-directory */
546
int
547
openp (const char *path, int try_cwd_first, const char *string,
548
       int mode, int prot,
549
       char **filename_opened)
550
{
551
  register int fd;
552
  register char *filename;
553
  const char *p;
554
  const char *p1;
555
  register int len;
556
  int alloclen;
557
 
558
  if (!path)
559
    path = ".";
560
 
561
#if defined(_WIN32) || defined(__CYGWIN__)
562
  mode |= O_BINARY;
563
#endif
564
 
565
  if ((try_cwd_first || IS_ABSOLUTE_PATH (string)) && is_regular_file (string))
566
    {
567
      int i;
568
      filename = alloca (strlen (string) + 1);
569
      strcpy (filename, string);
570
      fd = open (filename, mode, prot);
571
      if (fd >= 0)
572
        goto done;
573
      for (i = 0; string[i]; i++)
574
        if (IS_DIR_SEPARATOR (string[i]))
575
          goto done;
576
    }
577
 
578
  /* ./foo => foo */
579
  while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
580
    string += 2;
581
 
582
  alloclen = strlen (path) + strlen (string) + 2;
583
  filename = alloca (alloclen);
584
  fd = -1;
585
  for (p = path; p; p = p1 ? p1 + 1 : 0)
586
    {
587
      p1 = strchr (p, DIRNAME_SEPARATOR);
588
      if (p1)
589
        len = p1 - p;
590
      else
591
        len = strlen (p);
592
 
593
      if (len == 4 && p[0] == '$' && p[1] == 'c'
594
          && p[2] == 'w' && p[3] == 'd')
595
        {
596
          /* Name is $cwd -- insert current directory name instead.  */
597
          int newlen;
598
 
599
          /* First, realloc the filename buffer if too short. */
600
          len = strlen (current_directory);
601
          newlen = len + strlen (string) + 2;
602
          if (newlen > alloclen)
603
            {
604
              alloclen = newlen;
605
              filename = alloca (alloclen);
606
            }
607
          strcpy (filename, current_directory);
608
        }
609
      else
610
        {
611
          /* Normal file name in path -- just use it.  */
612
          strncpy (filename, p, len);
613
          filename[len] = 0;
614
        }
615
 
616
      /* Remove trailing slashes */
617
      while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1]))
618
        filename[--len] = 0;
619
 
620
      strcat (filename + len, SLASH_STRING);
621
      strcat (filename, string);
622
 
623
      if (is_regular_file (filename))
624
      {
625
        fd = open (filename, mode);
626
        if (fd >= 0)
627
          break;
628
      }
629
    }
630
 
631
done:
632
  if (filename_opened)
633
    {
634
      /* If a file was opened, canonicalize its filename. Use xfullpath
635
         rather than gdb_realpath to avoid resolving the basename part
636
         of filenames when the associated file is a symbolic link. This
637
         fixes a potential inconsistency between the filenames known to
638
         GDB and the filenames it prints in the annotations.  */
639
      if (fd < 0)
640
        *filename_opened = NULL;
641
      else if (IS_ABSOLUTE_PATH (filename))
642
        *filename_opened = xfullpath (filename);
643
      else
644
        {
645
          /* Beware the // my son, the Emacs barfs, the botch that catch... */
646
 
647
          char *f = concat (current_directory,
648
           IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
649
                                     ? "" : SLASH_STRING,
650
                                     filename, NULL);
651
          *filename_opened = xfullpath (f);
652
          xfree (f);
653
        }
654
    }
655
 
656
  return fd;
657
}
658
 
659
 
660
/* This is essentially a convenience, for clients that want the behaviour
661
   of openp, using source_path, but that really don't want the file to be
662
   opened but want instead just to know what the full pathname is (as
663
   qualified against source_path).
664
 
665
   The current working directory is searched first.
666
 
667
   If the file was found, this function returns 1, and FULL_PATHNAME is
668
   set to the fully-qualified pathname.
669
 
670
   Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
671
 */
672
int
673
source_full_path_of (char *filename, char **full_pathname)
674
{
675
  int fd;
676
 
677
  fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
678
  if (fd < 0)
679
    {
680
      *full_pathname = NULL;
681
      return 0;
682
    }
683
 
684
  close (fd);
685
  return 1;
686
}
687
 
688
 
689
/* Open a source file given a symtab S.  Returns a file descriptor or
690
   negative number for error.  */
691
 
692
int
693
open_source_file (struct symtab *s)
694
{
695
  char *path = source_path;
696
  const char *p;
697
  int result;
698
  char *fullname;
699
 
700
  /* Quick way out if we already know its full name */
701
  if (s->fullname)
702
    {
703
      result = open (s->fullname, OPEN_MODE);
704
      if (result >= 0)
705
        return result;
706
      /* Didn't work -- free old one, try again. */
707
      xmfree (s->objfile->md, s->fullname);
708
      s->fullname = NULL;
709
    }
710
 
711
  if (s->dirname != NULL)
712
    {
713
      /* Replace a path entry of  $cdir  with the compilation directory name */
714
#define cdir_len        5
715
      /* We cast strstr's result in case an ANSIhole has made it const,
716
         which produces a "required warning" when assigned to a nonconst. */
717
      p = (char *) strstr (source_path, "$cdir");
718
      if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
719
          && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
720
        {
721
          int len;
722
 
723
          path = (char *)
724
            alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
725
          len = p - source_path;
726
          strncpy (path, source_path, len);     /* Before $cdir */
727
          strcpy (path + len, s->dirname);      /* new stuff */
728
          strcat (path + len, source_path + len + cdir_len);    /* After $cdir */
729
        }
730
    }
731
 
732
  result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
733
  if (result < 0)
734
    {
735
      /* Didn't work.  Try using just the basename. */
736
      p = lbasename (s->filename);
737
      if (p != s->filename)
738
        result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
739
    }
740
 
741
  if (result >= 0)
742
    {
743
      fullname = s->fullname;
744
      s->fullname = mstrsave (s->objfile->md, s->fullname);
745
      xfree (fullname);
746
    }
747
  return result;
748
}
749
 
750
/* Return the path to the source file associated with symtab.  Returns NULL
751
   if no symtab.  */
752
 
753
char *
754
symtab_to_filename (struct symtab *s)
755
{
756
  int fd;
757
 
758
  if (!s)
759
    return NULL;
760
 
761
  /* If we've seen the file before, just return fullname. */
762
 
763
  if (s->fullname)
764
    return s->fullname;
765
 
766
  /* Try opening the file to setup fullname */
767
 
768
  fd = open_source_file (s);
769
  if (fd < 0)
770
    return s->filename;         /* File not found.  Just use short name */
771
 
772
  /* Found the file.  Cleanup and return the full name */
773
 
774
  close (fd);
775
  return s->fullname;
776
}
777
 
778
 
779
/* Create and initialize the table S->line_charpos that records
780
   the positions of the lines in the source file, which is assumed
781
   to be open on descriptor DESC.
782
   All set S->nlines to the number of such lines.  */
783
 
784
void
785
find_source_lines (struct symtab *s, int desc)
786
{
787
  struct stat st;
788
  register char *data, *p, *end;
789
  int nlines = 0;
790
  int lines_allocated = 1000;
791
  int *line_charpos;
792
  long mtime = 0;
793
  int size;
794
 
795
  line_charpos = (int *) xmmalloc (s->objfile->md,
796
                                   lines_allocated * sizeof (int));
797
  if (fstat (desc, &st) < 0)
798
    perror_with_name (s->filename);
799
 
800
  if (s && s->objfile && s->objfile->obfd)
801
    mtime = bfd_get_mtime (s->objfile->obfd);
802
  else if (exec_bfd)
803
    mtime = bfd_get_mtime (exec_bfd);
804
 
805
  if (mtime && mtime < st.st_mtime)
806
    {
807
      warning ("Source file is more recent than executable.\n");
808
    }
809
 
810
#ifdef LSEEK_NOT_LINEAR
811
  {
812
    char c;
813
 
814
    /* Have to read it byte by byte to find out where the chars live */
815
 
816
    line_charpos[0] = lseek (desc, 0, SEEK_CUR);
817
    nlines = 1;
818
    while (myread (desc, &c, 1) > 0)
819
      {
820
        if (c == '\n')
821
          {
822
            if (nlines == lines_allocated)
823
              {
824
                lines_allocated *= 2;
825
                line_charpos =
826
                  (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
827
                                     sizeof (int) * lines_allocated);
828
              }
829
            line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
830
          }
831
      }
832
  }
833
#else /* lseek linear.  */
834
  {
835
    struct cleanup *old_cleanups;
836
 
837
    /* st_size might be a large type, but we only support source files whose
838
       size fits in an int.  */
839
    size = (int) st.st_size;
840
 
841
    /* Use malloc, not alloca, because this may be pretty large, and we may
842
       run into various kinds of limits on stack size.  */
843
    data = (char *) xmalloc (size);
844
    old_cleanups = make_cleanup (xfree, data);
845
 
846
    /* Reassign `size' to result of read for systems where \r\n -> \n.  */
847
    size = myread (desc, data, size);
848
    if (size < 0)
849
      perror_with_name (s->filename);
850
    end = data + size;
851
    p = data;
852
    line_charpos[0] = 0;
853
    nlines = 1;
854
    while (p != end)
855
      {
856
        if (*p++ == '\n'
857
        /* A newline at the end does not start a new line.  */
858
            && p != end)
859
          {
860
            if (nlines == lines_allocated)
861
              {
862
                lines_allocated *= 2;
863
                line_charpos =
864
                  (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
865
                                     sizeof (int) * lines_allocated);
866
              }
867
            line_charpos[nlines++] = p - data;
868
          }
869
      }
870
    do_cleanups (old_cleanups);
871
  }
872
#endif /* lseek linear.  */
873
  s->nlines = nlines;
874
  s->line_charpos =
875
    (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
876
                       nlines * sizeof (int));
877
 
878
}
879
 
880
/* Return the character position of a line LINE in symtab S.
881
   Return 0 if anything is invalid.  */
882
 
883
#if 0                           /* Currently unused */
884
 
885
int
886
source_line_charpos (struct symtab *s, int line)
887
{
888
  if (!s)
889
    return 0;
890
  if (!s->line_charpos || line <= 0)
891
    return 0;
892
  if (line > s->nlines)
893
    line = s->nlines;
894
  return s->line_charpos[line - 1];
895
}
896
 
897
/* Return the line number of character position POS in symtab S.  */
898
 
899
int
900
source_charpos_line (register struct symtab *s, register int chr)
901
{
902
  register int line = 0;
903
  register int *lnp;
904
 
905
  if (s == 0 || s->line_charpos == 0)
906
    return 0;
907
  lnp = s->line_charpos;
908
  /* Files are usually short, so sequential search is Ok */
909
  while (line < s->nlines && *lnp <= chr)
910
    {
911
      line++;
912
      lnp++;
913
    }
914
  if (line >= s->nlines)
915
    line = s->nlines;
916
  return line;
917
}
918
 
919
#endif /* 0 */
920
 
921
 
922
/* Get full pathname and line number positions for a symtab.
923
   Return nonzero if line numbers may have changed.
924
   Set *FULLNAME to actual name of the file as found by `openp',
925
   or to 0 if the file is not found.  */
926
 
927
static int
928
get_filename_and_charpos (struct symtab *s, char **fullname)
929
{
930
  register int desc, linenums_changed = 0;
931
 
932
  desc = open_source_file (s);
933
  if (desc < 0)
934
    {
935
      if (fullname)
936
        *fullname = NULL;
937
      return 0;
938
    }
939
  if (fullname)
940
    *fullname = s->fullname;
941
  if (s->line_charpos == 0)
942
    linenums_changed = 1;
943
  if (linenums_changed)
944
    find_source_lines (s, desc);
945
  close (desc);
946
  return linenums_changed;
947
}
948
 
949
/* Print text describing the full name of the source file S
950
   and the line number LINE and its corresponding character position.
951
   The text starts with two Ctrl-z so that the Emacs-GDB interface
952
   can easily find it.
953
 
954
   MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
955
 
956
   Return 1 if successful, 0 if could not find the file.  */
957
 
958
int
959
identify_source_line (struct symtab *s, int line, int mid_statement,
960
                      CORE_ADDR pc)
961
{
962
  if (s->line_charpos == 0)
963
    get_filename_and_charpos (s, (char **) NULL);
964
  if (s->fullname == 0)
965
    return 0;
966
  if (line > s->nlines)
967
    /* Don't index off the end of the line_charpos array.  */
968
    return 0;
969
  annotate_source (s->fullname, line, s->line_charpos[line - 1],
970
                   mid_statement, pc);
971
 
972
  current_source_line = line;
973
  first_line_listed = line;
974
  last_line_listed = line;
975
  current_source_symtab = s;
976
  return 1;
977
}
978
 
979
 
980
/* Print source lines from the file of symtab S,
981
   starting with line number LINE and stopping before line number STOPLINE. */
982
 
983
static void print_source_lines_base (struct symtab *s, int line, int stopline,
984
                                     int noerror);
985
static void
986
print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
987
{
988
  register int c;
989
  register int desc;
990
  register FILE *stream;
991
  int nlines = stopline - line;
992
 
993
  /* Regardless of whether we can open the file, set current_source_symtab. */
994
  current_source_symtab = s;
995
  current_source_line = line;
996
  first_line_listed = line;
997
 
998
  /* If printing of source lines is disabled, just print file and line number */
999
  if (ui_out_test_flags (uiout, ui_source_list))
1000
    {
1001
      /* Only prints "No such file or directory" once */
1002
      if ((s != last_source_visited) || (!last_source_error))
1003
        {
1004
          last_source_visited = s;
1005
          desc = open_source_file (s);
1006
        }
1007
      else
1008
        {
1009
          desc = last_source_error;
1010
          noerror = 1;
1011
        }
1012
    }
1013
  else
1014
    {
1015
      desc = -1;
1016
      noerror = 1;
1017
    }
1018
 
1019
  if (desc < 0)
1020
    {
1021
      last_source_error = desc;
1022
 
1023
      if (!noerror)
1024
        {
1025
          char *name = alloca (strlen (s->filename) + 100);
1026
          sprintf (name, "%d\t%s", line, s->filename);
1027
          print_sys_errmsg (name, errno);
1028
        }
1029
      else
1030
        ui_out_field_int (uiout, "line", line);
1031
      ui_out_text (uiout, "\tin ");
1032
      ui_out_field_string (uiout, "file", s->filename);
1033
      ui_out_text (uiout, "\n");
1034
 
1035
      return;
1036
    }
1037
 
1038
  last_source_error = 0;
1039
 
1040
  if (s->line_charpos == 0)
1041
    find_source_lines (s, desc);
1042
 
1043
  if (line < 1 || line > s->nlines)
1044
    {
1045
      close (desc);
1046
      error ("Line number %d out of range; %s has %d lines.",
1047
             line, s->filename, s->nlines);
1048
    }
1049
 
1050
  if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
1051
    {
1052
      close (desc);
1053
      perror_with_name (s->filename);
1054
    }
1055
 
1056
  stream = fdopen (desc, FDOPEN_MODE);
1057
  clearerr (stream);
1058
 
1059
  while (nlines-- > 0)
1060
    {
1061
      char buf[20];
1062
 
1063
      c = fgetc (stream);
1064
      if (c == EOF)
1065
        break;
1066
      last_line_listed = current_source_line;
1067
      sprintf (buf, "%d\t", current_source_line++);
1068
      ui_out_text (uiout, buf);
1069
      do
1070
        {
1071
          if (c < 040 && c != '\t' && c != '\n' && c != '\r')
1072
            {
1073
              sprintf (buf, "^%c", c + 0100);
1074
              ui_out_text (uiout, buf);
1075
            }
1076
          else if (c == 0177)
1077
            ui_out_text (uiout, "^?");
1078
#ifdef CRLF_SOURCE_FILES
1079
          else if (c == '\r')
1080
            {
1081
              /* Skip a \r character, but only before a \n.  */
1082
              int c1 = fgetc (stream);
1083
 
1084
              if (c1 != '\n')
1085
                printf_filtered ("^%c", c + 0100);
1086
              if (c1 != EOF)
1087
                ungetc (c1, stream);
1088
            }
1089
#endif
1090
          else
1091
            {
1092
              sprintf (buf, "%c", c);
1093
              ui_out_text (uiout, buf);
1094
            }
1095
        }
1096
      while (c != '\n' && (c = fgetc (stream)) >= 0);
1097
    }
1098
 
1099
  fclose (stream);
1100
}
1101
 
1102
/* Show source lines from the file of symtab S, starting with line
1103
   number LINE and stopping before line number STOPLINE.  If this is the
1104
   not the command line version, then the source is shown in the source
1105
   window otherwise it is simply printed */
1106
 
1107
void
1108
print_source_lines (struct symtab *s, int line, int stopline, int noerror)
1109
{
1110
  print_source_lines_base (s, line, stopline, noerror);
1111
}
1112
 
1113
 
1114
 
1115
/* Print a list of files and line numbers which a user may choose from
1116
   in order to list a function which was specified ambiguously (as with
1117
   `list classname::overloadedfuncname', for example).  The vector in
1118
   SALS provides the filenames and line numbers.  */
1119
 
1120
static void
1121
ambiguous_line_spec (struct symtabs_and_lines *sals)
1122
{
1123
  int i;
1124
 
1125
  for (i = 0; i < sals->nelts; ++i)
1126
    printf_filtered ("file: \"%s\", line number: %d\n",
1127
                     sals->sals[i].symtab->filename, sals->sals[i].line);
1128
}
1129
 
1130
static void
1131
list_command (char *arg, int from_tty)
1132
{
1133
  struct symtabs_and_lines sals, sals_end;
1134
  struct symtab_and_line sal, sal_end;
1135
  struct symbol *sym;
1136
  char *arg1;
1137
  int no_end = 1;
1138
  int dummy_end = 0;
1139
  int dummy_beg = 0;
1140
  int linenum_beg = 0;
1141
  char *p;
1142
 
1143
  if (!have_full_symbols () && !have_partial_symbols ())
1144
    error ("No symbol table is loaded.  Use the \"file\" command.");
1145
 
1146
  /* Pull in a current source symtab if necessary */
1147
  if (current_source_symtab == 0 &&
1148
      (arg == 0 || arg[0] == '+' || arg[0] == '-'))
1149
    select_source_symtab (0);
1150
 
1151
  /* "l" or "l +" lists next ten lines.  */
1152
 
1153
  if (arg == 0 || STREQ (arg, "+"))
1154
    {
1155
      if (current_source_symtab == 0)
1156
        error ("No default source file yet.  Do \"help list\".");
1157
      print_source_lines (current_source_symtab, current_source_line,
1158
                          current_source_line + lines_to_list, 0);
1159
      return;
1160
    }
1161
 
1162
  /* "l -" lists previous ten lines, the ones before the ten just listed.  */
1163
  if (STREQ (arg, "-"))
1164
    {
1165
      if (current_source_symtab == 0)
1166
        error ("No default source file yet.  Do \"help list\".");
1167
      print_source_lines (current_source_symtab,
1168
                          max (first_line_listed - lines_to_list, 1),
1169
                          first_line_listed, 0);
1170
      return;
1171
    }
1172
 
1173
  /* Now if there is only one argument, decode it in SAL
1174
     and set NO_END.
1175
     If there are two arguments, decode them in SAL and SAL_END
1176
     and clear NO_END; however, if one of the arguments is blank,
1177
     set DUMMY_BEG or DUMMY_END to record that fact.  */
1178
 
1179
  arg1 = arg;
1180
  if (*arg1 == ',')
1181
    dummy_beg = 1;
1182
  else
1183
    {
1184
      sals = decode_line_1 (&arg1, 0, 0, 0, 0);
1185
 
1186
      if (!sals.nelts)
1187
        return;                 /*  C++  */
1188
      if (sals.nelts > 1)
1189
        {
1190
          ambiguous_line_spec (&sals);
1191
          xfree (sals.sals);
1192
          return;
1193
        }
1194
 
1195
      sal = sals.sals[0];
1196
      xfree (sals.sals);
1197
    }
1198
 
1199
  /* Record whether the BEG arg is all digits.  */
1200
 
1201
  for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
1202
  linenum_beg = (p == arg1);
1203
 
1204
  while (*arg1 == ' ' || *arg1 == '\t')
1205
    arg1++;
1206
  if (*arg1 == ',')
1207
    {
1208
      no_end = 0;
1209
      arg1++;
1210
      while (*arg1 == ' ' || *arg1 == '\t')
1211
        arg1++;
1212
      if (*arg1 == 0)
1213
        dummy_end = 1;
1214
      else
1215
        {
1216
          if (dummy_beg)
1217
            sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
1218
          else
1219
            sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
1220
          if (sals_end.nelts == 0)
1221
            return;
1222
          if (sals_end.nelts > 1)
1223
            {
1224
              ambiguous_line_spec (&sals_end);
1225
              xfree (sals_end.sals);
1226
              return;
1227
            }
1228
          sal_end = sals_end.sals[0];
1229
          xfree (sals_end.sals);
1230
        }
1231
    }
1232
 
1233
  if (*arg1)
1234
    error ("Junk at end of line specification.");
1235
 
1236
  if (!no_end && !dummy_beg && !dummy_end
1237
      && sal.symtab != sal_end.symtab)
1238
    error ("Specified start and end are in different files.");
1239
  if (dummy_beg && dummy_end)
1240
    error ("Two empty args do not say what lines to list.");
1241
 
1242
  /* if line was specified by address,
1243
     first print exactly which line, and which file.
1244
     In this case, sal.symtab == 0 means address is outside
1245
     of all known source files, not that user failed to give a filename.  */
1246
  if (*arg == '*')
1247
    {
1248
      if (sal.symtab == 0)
1249
        /* FIXME-32x64--assumes sal.pc fits in long.  */
1250
        error ("No source file for address %s.",
1251
               local_hex_string ((unsigned long) sal.pc));
1252
      sym = find_pc_function (sal.pc);
1253
      if (sym)
1254
        {
1255
          print_address_numeric (sal.pc, 1, gdb_stdout);
1256
          printf_filtered (" is in ");
1257
          fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
1258
          printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
1259
        }
1260
      else
1261
        {
1262
          print_address_numeric (sal.pc, 1, gdb_stdout);
1263
          printf_filtered (" is at %s:%d.\n",
1264
                           sal.symtab->filename, sal.line);
1265
        }
1266
    }
1267
 
1268
  /* If line was not specified by just a line number,
1269
     and it does not imply a symtab, it must be an undebuggable symbol
1270
     which means no source code.  */
1271
 
1272
  if (!linenum_beg && sal.symtab == 0)
1273
    error ("No line number known for %s.", arg);
1274
 
1275
  /* If this command is repeated with RET,
1276
     turn it into the no-arg variant.  */
1277
 
1278
  if (from_tty)
1279
    *arg = 0;
1280
 
1281
  if (dummy_beg && sal_end.symtab == 0)
1282
    error ("No default source file yet.  Do \"help list\".");
1283
  if (dummy_beg)
1284
    print_source_lines (sal_end.symtab,
1285
                        max (sal_end.line - (lines_to_list - 1), 1),
1286
                        sal_end.line + 1, 0);
1287
  else if (sal.symtab == 0)
1288
    error ("No default source file yet.  Do \"help list\".");
1289
  else if (no_end)
1290
    {
1291
      int first_line = sal.line - lines_to_list / 2;
1292
 
1293
      if (first_line < 1) first_line = 1;
1294
 
1295
      print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
1296
                          0);
1297
    }
1298
  else
1299
    print_source_lines (sal.symtab, sal.line,
1300
                        (dummy_end
1301
                         ? sal.line + lines_to_list
1302
                         : sal_end.line + 1),
1303
                        0);
1304
}
1305
 
1306
/* Print info on range of pc's in a specified line.  */
1307
 
1308
static void
1309
line_info (char *arg, int from_tty)
1310
{
1311
  struct symtabs_and_lines sals;
1312
  struct symtab_and_line sal;
1313
  CORE_ADDR start_pc, end_pc;
1314
  int i;
1315
 
1316
  INIT_SAL (&sal);              /* initialize to zeroes */
1317
 
1318
  if (arg == 0)
1319
    {
1320
      sal.symtab = current_source_symtab;
1321
      sal.line = last_line_listed;
1322
      sals.nelts = 1;
1323
      sals.sals = (struct symtab_and_line *)
1324
        xmalloc (sizeof (struct symtab_and_line));
1325
      sals.sals[0] = sal;
1326
    }
1327
  else
1328
    {
1329
      sals = decode_line_spec_1 (arg, 0);
1330
 
1331
      dont_repeat ();
1332
    }
1333
 
1334
  /* C++  More than one line may have been specified, as when the user
1335
     specifies an overloaded function name. Print info on them all. */
1336
  for (i = 0; i < sals.nelts; i++)
1337
    {
1338
      sal = sals.sals[i];
1339
 
1340
      if (sal.symtab == 0)
1341
        {
1342
          printf_filtered ("No line number information available");
1343
          if (sal.pc != 0)
1344
            {
1345
              /* This is useful for "info line *0x7f34".  If we can't tell the
1346
                 user about a source line, at least let them have the symbolic
1347
                 address.  */
1348
              printf_filtered (" for address ");
1349
              wrap_here ("  ");
1350
              print_address (sal.pc, gdb_stdout);
1351
            }
1352
          else
1353
            printf_filtered (".");
1354
          printf_filtered ("\n");
1355
        }
1356
      else if (sal.line > 0
1357
               && find_line_pc_range (sal, &start_pc, &end_pc))
1358
        {
1359
          if (start_pc == end_pc)
1360
            {
1361
              printf_filtered ("Line %d of \"%s\"",
1362
                               sal.line, sal.symtab->filename);
1363
              wrap_here ("  ");
1364
              printf_filtered (" is at address ");
1365
              print_address (start_pc, gdb_stdout);
1366
              wrap_here ("  ");
1367
              printf_filtered (" but contains no code.\n");
1368
            }
1369
          else
1370
            {
1371
              printf_filtered ("Line %d of \"%s\"",
1372
                               sal.line, sal.symtab->filename);
1373
              wrap_here ("  ");
1374
              printf_filtered (" starts at address ");
1375
              print_address (start_pc, gdb_stdout);
1376
              wrap_here ("  ");
1377
              printf_filtered (" and ends at ");
1378
              print_address (end_pc, gdb_stdout);
1379
              printf_filtered (".\n");
1380
            }
1381
 
1382
          /* x/i should display this line's code.  */
1383
          set_next_address (start_pc);
1384
 
1385
          /* Repeating "info line" should do the following line.  */
1386
          last_line_listed = sal.line + 1;
1387
 
1388
          /* If this is the only line, show the source code.  If it could
1389
             not find the file, don't do anything special.  */
1390
          if (annotation_level && sals.nelts == 1)
1391
            identify_source_line (sal.symtab, sal.line, 0, start_pc);
1392
        }
1393
      else
1394
        /* Is there any case in which we get here, and have an address
1395
           which the user would want to see?  If we have debugging symbols
1396
           and no line numbers?  */
1397
        printf_filtered ("Line number %d is out of range for \"%s\".\n",
1398
                         sal.line, sal.symtab->filename);
1399
    }
1400
  xfree (sals.sals);
1401
}
1402
 
1403
/* Commands to search the source file for a regexp.  */
1404
 
1405
/* ARGSUSED */
1406
static void
1407
forward_search_command (char *regex, int from_tty)
1408
{
1409
  register int c;
1410
  register int desc;
1411
  register FILE *stream;
1412
  int line;
1413
  char *msg;
1414
 
1415
  line = last_line_listed + 1;
1416
 
1417
  msg = (char *) re_comp (regex);
1418
  if (msg)
1419
    error (msg);
1420
 
1421
  if (current_source_symtab == 0)
1422
    select_source_symtab (0);
1423
 
1424
  desc = open_source_file (current_source_symtab);
1425
  if (desc < 0)
1426
    perror_with_name (current_source_symtab->filename);
1427
 
1428
  if (current_source_symtab->line_charpos == 0)
1429
    find_source_lines (current_source_symtab, desc);
1430
 
1431
  if (line < 1 || line > current_source_symtab->nlines)
1432
    {
1433
      close (desc);
1434
      error ("Expression not found");
1435
    }
1436
 
1437
  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1438
    {
1439
      close (desc);
1440
      perror_with_name (current_source_symtab->filename);
1441
    }
1442
 
1443
  stream = fdopen (desc, FDOPEN_MODE);
1444
  clearerr (stream);
1445
  while (1)
1446
    {
1447
      static char *buf = NULL;
1448
      register char *p;
1449
      int cursize, newsize;
1450
 
1451
      cursize = 256;
1452
      buf = xmalloc (cursize);
1453
      p = buf;
1454
 
1455
      c = getc (stream);
1456
      if (c == EOF)
1457
        break;
1458
      do
1459
        {
1460
          *p++ = c;
1461
          if (p - buf == cursize)
1462
            {
1463
              newsize = cursize + cursize / 2;
1464
              buf = xrealloc (buf, newsize);
1465
              p = buf + cursize;
1466
              cursize = newsize;
1467
            }
1468
        }
1469
      while (c != '\n' && (c = getc (stream)) >= 0);
1470
 
1471
#ifdef CRLF_SOURCE_FILES
1472
      /* Remove the \r, if any, at the end of the line, otherwise
1473
         regular expressions that end with $ or \n won't work.  */
1474
      if (p - buf > 1 && p[-2] == '\r')
1475
        {
1476
          p--;
1477
          p[-1] = '\n';
1478
        }
1479
#endif
1480
 
1481
      /* we now have a source line in buf, null terminate and match */
1482
      *p = 0;
1483
      if (re_exec (buf) > 0)
1484
        {
1485
          /* Match! */
1486
          fclose (stream);
1487
          print_source_lines (current_source_symtab, line, line + 1, 0);
1488
          set_internalvar (lookup_internalvar ("_"),
1489
                           value_from_longest (builtin_type_int,
1490
                                               (LONGEST) line));
1491
          current_source_line = max (line - lines_to_list / 2, 1);
1492
          return;
1493
        }
1494
      line++;
1495
    }
1496
 
1497
  printf_filtered ("Expression not found\n");
1498
  fclose (stream);
1499
}
1500
 
1501
/* ARGSUSED */
1502
static void
1503
reverse_search_command (char *regex, int from_tty)
1504
{
1505
  register int c;
1506
  register int desc;
1507
  register FILE *stream;
1508
  int line;
1509
  char *msg;
1510
 
1511
  line = last_line_listed - 1;
1512
 
1513
  msg = (char *) re_comp (regex);
1514
  if (msg)
1515
    error (msg);
1516
 
1517
  if (current_source_symtab == 0)
1518
    select_source_symtab (0);
1519
 
1520
  desc = open_source_file (current_source_symtab);
1521
  if (desc < 0)
1522
    perror_with_name (current_source_symtab->filename);
1523
 
1524
  if (current_source_symtab->line_charpos == 0)
1525
    find_source_lines (current_source_symtab, desc);
1526
 
1527
  if (line < 1 || line > current_source_symtab->nlines)
1528
    {
1529
      close (desc);
1530
      error ("Expression not found");
1531
    }
1532
 
1533
  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1534
    {
1535
      close (desc);
1536
      perror_with_name (current_source_symtab->filename);
1537
    }
1538
 
1539
  stream = fdopen (desc, FDOPEN_MODE);
1540
  clearerr (stream);
1541
  while (line > 1)
1542
    {
1543
/* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
1544
      char buf[4096];           /* Should be reasonable??? */
1545
      register char *p = buf;
1546
 
1547
      c = getc (stream);
1548
      if (c == EOF)
1549
        break;
1550
      do
1551
        {
1552
          *p++ = c;
1553
        }
1554
      while (c != '\n' && (c = getc (stream)) >= 0);
1555
 
1556
#ifdef CRLF_SOURCE_FILES
1557
      /* Remove the \r, if any, at the end of the line, otherwise
1558
         regular expressions that end with $ or \n won't work.  */
1559
      if (p - buf > 1 && p[-2] == '\r')
1560
        {
1561
          p--;
1562
          p[-1] = '\n';
1563
        }
1564
#endif
1565
 
1566
      /* We now have a source line in buf; null terminate and match.  */
1567
      *p = 0;
1568
      if (re_exec (buf) > 0)
1569
        {
1570
          /* Match! */
1571
          fclose (stream);
1572
          print_source_lines (current_source_symtab, line, line + 1, 0);
1573
          set_internalvar (lookup_internalvar ("_"),
1574
                           value_from_longest (builtin_type_int,
1575
                                               (LONGEST) line));
1576
          current_source_line = max (line - lines_to_list / 2, 1);
1577
          return;
1578
        }
1579
      line--;
1580
      if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
1581
        {
1582
          fclose (stream);
1583
          perror_with_name (current_source_symtab->filename);
1584
        }
1585
    }
1586
 
1587
  printf_filtered ("Expression not found\n");
1588
  fclose (stream);
1589
  return;
1590
}
1591
 
1592
void
1593
_initialize_source (void)
1594
{
1595
  struct cmd_list_element *c;
1596
  current_source_symtab = 0;
1597
  init_source_path ();
1598
 
1599
  /* The intention is to use POSIX Basic Regular Expressions.
1600
     Always use the GNU regex routine for consistency across all hosts.
1601
     Our current GNU regex.c does not have all the POSIX features, so this is
1602
     just an approximation.  */
1603
  re_set_syntax (RE_SYNTAX_GREP);
1604
 
1605
  c = add_cmd ("directory", class_files, directory_command,
1606
               "Add directory DIR to beginning of search path for source files.\n\
1607
Forget cached info on source file locations and line positions.\n\
1608
DIR can also be $cwd for the current working directory, or $cdir for the\n\
1609
directory in which the source file was compiled into object code.\n\
1610
With no argument, reset the search path to $cdir:$cwd, the default.",
1611
               &cmdlist);
1612
 
1613
  if (dbx_commands)
1614
    add_com_alias ("use", "directory", class_files, 0);
1615
 
1616
  set_cmd_completer (c, filename_completer);
1617
 
1618
  add_cmd ("directories", no_class, show_directories,
1619
           "Current search path for finding source files.\n\
1620
$cwd in the path means the current working directory.\n\
1621
$cdir in the path means the compilation directory of the source file.",
1622
           &showlist);
1623
 
1624
  if (xdb_commands)
1625
    {
1626
      add_com_alias ("D", "directory", class_files, 0);
1627
      add_cmd ("ld", no_class, show_directories,
1628
               "Current search path for finding source files.\n\
1629
$cwd in the path means the current working directory.\n\
1630
$cdir in the path means the compilation directory of the source file.",
1631
               &cmdlist);
1632
    }
1633
 
1634
  add_info ("source", source_info,
1635
            "Information about the current source file.");
1636
 
1637
  add_info ("line", line_info,
1638
            concat ("Core addresses of the code for a source line.\n\
1639
Line can be specified as\n\
1640
  LINENUM, to list around that line in current file,\n\
1641
  FILE:LINENUM, to list around that line in that file,\n\
1642
  FUNCTION, to list around beginning of that function,\n\
1643
  FILE:FUNCTION, to distinguish among like-named static functions.\n\
1644
", "\
1645
Default is to describe the last source line that was listed.\n\n\
1646
This sets the default address for \"x\" to the line's first instruction\n\
1647
so that \"x/i\" suffices to start examining the machine code.\n\
1648
The address is also stored as the value of \"$_\".", NULL));
1649
 
1650
  add_com ("forward-search", class_files, forward_search_command,
1651
           "Search for regular expression (see regex(3)) from last line listed.\n\
1652
The matching line number is also stored as the value of \"$_\".");
1653
  add_com_alias ("search", "forward-search", class_files, 0);
1654
 
1655
  add_com ("reverse-search", class_files, reverse_search_command,
1656
           "Search backward for regular expression (see regex(3)) from last line listed.\n\
1657
The matching line number is also stored as the value of \"$_\".");
1658
 
1659
  if (xdb_commands)
1660
    {
1661
      add_com_alias ("/", "forward-search", class_files, 0);
1662
      add_com_alias ("?", "reverse-search", class_files, 0);
1663
    }
1664
 
1665
  add_com ("list", class_files, list_command,
1666
           concat ("List specified function or line.\n\
1667
With no argument, lists ten more lines after or around previous listing.\n\
1668
\"list -\" lists the ten lines before a previous ten-line listing.\n\
1669
One argument specifies a line, and ten lines are listed around that line.\n\
1670
Two arguments with comma between specify starting and ending lines to list.\n\
1671
", "\
1672
Lines can be specified in these ways:\n\
1673
  LINENUM, to list around that line in current file,\n\
1674
  FILE:LINENUM, to list around that line in that file,\n\
1675
  FUNCTION, to list around beginning of that function,\n\
1676
  FILE:FUNCTION, to distinguish among like-named static functions.\n\
1677
  *ADDRESS, to list around the line containing that address.\n\
1678
With two args if one is empty it stands for ten lines away from the other arg.", NULL));
1679
 
1680
  if (!xdb_commands)
1681
    add_com_alias ("l", "list", class_files, 1);
1682
  else
1683
    add_com_alias ("v", "list", class_files, 1);
1684
 
1685
  if (dbx_commands)
1686
    add_com_alias ("file", "list", class_files, 1);
1687
 
1688
  add_show_from_set
1689
    (add_set_cmd ("listsize", class_support, var_uinteger,
1690
                  (char *) &lines_to_list,
1691
                  "Set number of source lines gdb will list by default.",
1692
                  &setlist),
1693
     &showlist);
1694
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.