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:
> I'm sorry but it is rarely a good idea to mix functionality like this.
> You're mixing an (arguable) bug fix with an (arguable) gdb enhancement.
> 
> Please submit each as a separate patch.

Ok. Here's the patch to robustly handle the presence
of DIRNAME_SEPARATOR in the file names embedded in the object file.

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.

--- ../../gdb-5.2.1-orig/gdb/source.c   2002-01-17 13:15:18.000000000
-0800
+++ source.c    2002-09-16 13:08:17.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,23 +721,36 @@
          && (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)


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