Finding source files under Cygwin
Earl Chew
earl_chew@agilent.com
Mon Sep 16 12:07:00 GMT 2002
Christopher Faylor wrote:
> >Another fix is to make source.c use ; (semicolon) as a path
> >separator instead of : (colon) should HAVE_DOS_BASED_FILE_SYSTEM
> >be true. The downside here is that it might be surprising
> >to current cygwin users.
>
> This one is out. This would break backwards compatibility and would be
> incompatible with the convention used in the rest of cygwin.
>
> The simplest solution is to just compile your object files using
> the /cygdrive/d/xxx/yyy/zzz syntax. The ability to use this syntax
> is one of the motivations for cygwin.
>
> However, if you want to provide a patch for either open_source_file
> or buildsym.c, I'll gladly review it.
I've included a patch below for you to consider. In addition to
robustly handling the presence of DIRNAME_SEPARATOR in the file
names embedded in the object file, I've included a patch to allow
files to be found in source trees.
The motivation for this addition is to accommodate large projects
where source files are scattered in large source trees. I want to
be able to point gdb at the root of the source tree, rather than have
to specify each leaf directory. Thus I can write:
gdb> dir /myproject/source
instead of:
gdb> dir /myproject/source/a/b/c:/myproject/source/z/b/d: etc
Earl
--
> ---------------------------------------------------------------------+
> Earl Chew http://www.agilent.com |
> Agilent Technologies mailto:earl_chew@agilent.com |
> Advanced Networks Division Tel: +1 604 454 3411 |
> 2500-4710 Kingsway Fax: +1 604 454 3401 |
> Burnaby BC V5H 4M2 Canada |
> ---------------------------------------------------------------------+
ChangeLog:
* source.c: Source file lookup changes.
(openp): Delegate to openp_1.
(openp_1): Allow arbitrary path component separators.
(open_source_file): Use \0 to separate path components
when splitting path to insert $cdir. If the source file
/w/x/y/z.c cannot be found, try using w/x/y/z.c,
x/y/z.c, y/z.c in addition to z.c (the basename).
--- ../../gdb-5.2.1-orig/gdb/source.c 2002-01-17 13:15:18.000000000
-0800
+++ source.c 2002-09-14 10:51:19.000000000 -0700
@@ -71,6 +71,11 @@
/* Prototypes for local functions. */
+static int openp_1 (const char *path, int pathlen, char sep,
+ int try_cwd_first, const char *string,
+ int mode, int prot,
+ char **filename_opened);
+
static int get_filename_and_charpos (struct symtab *, char **);
static void reverse_search_command (char *, int);
@@ -507,6 +512,11 @@
/* Open a file named STRING, searching path PATH (dir names sep by some
char)
using mode MODE and protection bits PROT in the calls to open.
+ The internal function openp_1 accepts an additional arguemnt SEP
+ which is normally set to DIRNAME_SEPARATOR by openp, but for
internal use
+ (see open_source_file) it may be set to \0 to avoid any ambiguity
+ when separating path components.
+
If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
(ie pretend the first element of PATH is "."). This also indicates
that a slash in STRING disables searching of the path (this is
@@ -524,20 +534,37 @@
/* >>>> This should only allow files of certain types,
>>>> eg executable, non-directory */
+
int
openp (const char *path, int try_cwd_first, const char *string,
int mode, int prot,
char **filename_opened)
{
+ int pathlen = path ? strlen (path) : 0;
+
+ return openp_1 (path, pathlen, DIRNAME_SEPARATOR, try_cwd_first,
string,
+ mode, prot, filename_opened);
+}
+
+static int
+openp_1 (const char *path, int pathlen, char sep,
+ int try_cwd_first, const char *string,
+ int mode, int prot,
+ char **filename_opened)
+{
register int fd;
register char *filename;
const char *p;
+ const char *ep;
const char *p1;
register int len;
int alloclen;
if (!path)
- path = ".";
+ {
+ path = ".";
+ pathlen = 1;
+ }
#if defined(_WIN32) || defined(__CYGWIN__)
mode |= O_BINARY;
@@ -560,12 +587,12 @@
while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
string += 2;
- alloclen = strlen (path) + strlen (string) + 2;
+ alloclen = pathlen + strlen (string) + 2;
filename = alloca (alloclen);
fd = -1;
- for (p = path; p; p = p1 ? p1 + 1 : 0)
+ for (p = path, ep = p + pathlen; p && (p < ep); p = p1 ? p1 + 1 : 0)
{
- p1 = strchr (p, DIRNAME_SEPARATOR);
+ p1 = strchr (p, sep);
if (p1)
len = p1 - p;
else
@@ -666,6 +693,8 @@
open_source_file (struct symtab *s)
{
char *path = source_path;
+ int pathlen = strlen (path);
+ char sep = DIRNAME_SEPARATOR;
const char *p;
int result;
char *fullname;
@@ -692,25 +721,57 @@
&& (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
{
int len;
+ char *q;
path = (char *)
- alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
+ alloca (pathlen + 1 + strlen (s->dirname) + 1);
len = p - source_path;
strncpy (path, source_path, len); /* Before $cdir */
strcpy (path + len, s->dirname); /* new stuff */
strcat (path + len, source_path + len + cdir_len); /* After
$cdir */
+
+ /* The segment inserted for $cdir may contain instances of
+ DIRNAME_SEPARATOR which causes ambiguity when parsing
+ the revised path. Use \0 to separate the path components
+ instead. */
+ pathlen = strlen (path);
+ sep = '\0';
+ for (q = path; len; len--, q++)
+ if (*q == DIRNAME_SEPARATOR) *q = sep;
+ for (q += strlen (s->dirname); *q; q++)
+ if (*q == DIRNAME_SEPARATOR) *q = sep;
}
}
- result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
+ result = openp_1 (path, pathlen, sep, 0,
+ s->filename, OPEN_MODE, 0, &s->fullname);
if (result < 0)
{
/* Didn't work. Try using just the basename. */
p = lbasename (s->filename);
if (p != s->filename)
- result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
+ result = openp_1 (path, pathlen, sep, 0, p, OPEN_MODE, 0,
&s->fullname);
}
+ if (result < 0)
+ {
+ /* Didn't work. Try lopping off prefixes from the full name. */
+ p = s->filename;
+
+ do
+ {
+ while (*p && ! IS_DIR_SEPARATOR (*p))
+ p++;
+ if (*p && *++p)
+ {
+ result = openp_1 (path, pathlen, sep, 0,
+ p, OPEN_MODE, 0, &s->fullname);
+ if (result >= 0)
+ break;
+ }
+ } while (*p);
+ }
+
if (result >= 0)
{
fullname = s->fullname;
More information about the Gdb-patches
mailing list