delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/09/13/09:27:45

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <3D812C51.C17EC79F@pajhome.org.uk>
Date: Fri, 13 Sep 2002 01:07:45 +0100
From: Paul Johnston <paj AT pajhome DOT org DOT uk>
X-Accept-Language: en
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Finding exact case of paths
References: <Pine DOT GSO DOT 4 DOT 44 DOT 0209121548220 DOT 19696-100000 AT slinky DOT cs DOT nyu DOT edu>

--------------2BCB8D9710F9ABDECC9B590D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

> Oh, I see, add a modifier similar to '-s', so that it verifies the case of
> each element in the path...  Yeah, that could work, something like:
>   -e, --exact-case      print exact case of NAME

Yep, exactly. Now, cygpath seems to generally not hit the filesystem - cygpath
c:/complete/crap gives me /c/complete/crap so using that switch will
necessarily involve a performance hit. Given that, I think I'm happy with my
solution based on dirent/strcasecmp. I've attached a stand-alone utility that
seems to work (just on cygwin paths), although it has the side effect of
squishing down multiple slashes ///like////this//path down to /like/this/path.

I think it would be ok to restrict --exact-case to cygwin paths.

Paul

--------------2BCB8D9710F9ABDECC9B590D
Content-Type: text/plain; charset=us-ascii;
 name="exactcase.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="exactcase.c"

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <string.h>

#include <stdio.h> /* Only needed for test code */

/***
 * Main subroutine is just for testing
 **/
int main(int argc, char *argv[])
{
  char path[PATH_MAX];
  if(argc == 2)
  {
    strcpy(path, argv[1]);
    if(exact_case(path)) printf("OUTPUT: %s\n", path);
    else printf("ERROR: %s\n", strerror(errno));
  }
  return 0;
}

/***
 * Vague attempt to make code independent of path type
 **/
#define DLM_STR "/"
#define DLM_CHR '/'
#define CWD_STR "."
#define IS_ABSOLUTE(X) (X[0] == DLM_CHR)

/***
 * Determine the correct case for a cygwin path, fill-in in place
 * Returns TRUE/FALSE - success/failure
 **/
int exact_case(char *path)
{
  char work[PATH_MAX], *part, path_strtok[PATH_MAX];

  if(strlen(path) > (PATH_MAX - 1)) /* PATH_MAX allows for the NUL */
  {
    errno = ENAMETOOLONG;
    return 0;
  }

  strcpy(path_strtok, path);
  part = strtok(path_strtok, DLM_STR);

  if(IS_ABSOLUTE(path))
  {
    if(!exact_case_part(DLM_STR, part)) return 0;
    strcpy(work, DLM_STR);
    strcat(work, part);
  }
  else
  {
    if(!exact_case_part(CWD_STR, part)) return 0;
    strcpy(work, part);
  }

  while(part = strtok(NULL, DLM_STR))
  {
    if(!exact_case_part(work, part)) return 0;
    strcat(work, DLM_STR);
    strcat(work, part);
  }

  strcpy(path, work);
  return 1;
}

/***
 * Search a directory for an entry; fill-in it's correct case
 * Returns TRUE/FALSE - success/failure
 **/
int exact_case_part(const char *base, char *part)
{
  struct dirent *de;
  DIR *dh = opendir(base);
  if(!dh) return 0;
  while(de = readdir(dh))
  {
    if(strcasecmp(part, de->d_name) == 0) break;
  }
  closedir(dh);
  if(de) strcpy(part, de->d_name);
  else errno = ENOENT;
  return (int) de;
}


--------------2BCB8D9710F9ABDECC9B590D
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--------------2BCB8D9710F9ABDECC9B590D--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019