From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13464 invoked by alias); 16 Sep 2002 19:07:06 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 13457 invoked from network); 16 Sep 2002 19:07:05 -0000 Received: from unknown (HELO msgbas2.cos.agilent.com) (192.25.240.37) by sources.redhat.com with SMTP; 16 Sep 2002 19:07:05 -0000 Received: from relcos2.cos.agilent.com (relcos2.cos.agilent.com [130.29.152.237]) by msgbas2.cos.agilent.com (Postfix) with ESMTP id 5D9A32060; Mon, 16 Sep 2002 13:07:04 -0600 (MDT) Received: from websvr.canada.agilent.com (websvr.canada.agilent.com [141.184.122.102]) by relcos2.cos.agilent.com (Postfix) with ESMTP id 31AC6507; Mon, 16 Sep 2002 13:06:14 -0600 (MDT) Received: from agilent.com (dhcp6burnaby.canada.agilent.com [141.184.123.147]) by websvr.canada.agilent.com (8.9.3 (PHNE_25183)/8.9.3 SMKit7.1.1_Agilent) with ESMTP id MAA27390; Mon, 16 Sep 2002 12:06:58 -0700 (PDT) Message-ID: <3D862BD0.A5298600@agilent.com> Date: Mon, 16 Sep 2002 12:07:00 -0000 From: Earl Chew Organization: Agilent Technologies X-Accept-Language: en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com, cgf@redhat.com Subject: Re: Finding source files under Cygwin References: <3D82897C.81376AD6@agilent.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-09/txt/msg00314.txt.bz2 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;