This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Finding source files under Cygwin


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]