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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [source.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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