VirtualBox

Changeset 3140 in kBuild for trunk/src/kmk/dir.c


Ignore:
Timestamp:
Mar 14, 2018 9:28:10 PM (7 years ago)
Author:
bird
Message:

kmk: Merged in changes from GNU make 4.2.1 (2e55f5e4abdc0e38c1d64be703b446695e70b3b6 / https://git.savannah.gnu.org/git/make.git).

Location:
trunk/src/kmk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk

  • trunk/src/kmk/dir.c

    r3065 r3140  
    11/* Directory hashing for GNU Make.
    2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
    3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
    4 2010 Free Software Foundation, Inc.
     2Copyright (C) 1988-2016 Free Software Foundation, Inc.
    53This file is part of GNU Make.
    64
     
    1715this program.  If not, see <http://www.gnu.org/licenses/>.  */
    1816
    19 #include "make.h"
     17#include "makeint.h"
    2018#include "hash.h"
    21 
    22 #ifdef  HAVE_DIRENT_H
     19#include "filedef.h"
     20#include "dep.h"
     21
     22#ifdef  HAVE_DIRENT_H
    2323# include <dirent.h>
    2424# define NAMLEN(dirent) strlen((dirent)->d_name)
     
    9797
    9898  /* First, transform the name part.  */
    99   for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
     99  for (i = 0; i < 8 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
    100100    *df++ = tolower ((unsigned char)*filename++);
    101101
    102102  /* Now skip to the next dot.  */
    103   while (*filename != '\0' && *filename != '.')
     103  while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
    104104    ++filename;
    105105  if (*filename != '\0')
    106106    {
    107107      *df++ = *filename++;
    108       for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
    109         *df++ = tolower ((unsigned char)*filename++);
     108      for (i = 0; i < 3 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
     109        *df++ = tolower ((unsigned char)*filename++);
    110110    }
    111111
    112112  /* Look for more dots.  */
    113   while (*filename != '\0' && *filename != '.')
     113  while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
    114114    ++filename;
    115115  if (*filename == '.')
     
    154154#ifdef VMS
    155155
     156static char *
     157downcase_inplace(char *filename)
     158{
     159  char *name;
     160  name = filename;
     161  while (*name != '\0')
     162    {
     163      *name = tolower ((unsigned char)*name);
     164      ++name;
     165    }
     166  return filename;
     167}
     168
     169#ifndef _USE_STD_STAT
     170/* VMS 8.2 fixed the VMS stat output to have unique st_dev and st_ino
     171   when _USE_STD_STAT is used on the compile line.
     172
     173   Prior to _USE_STD_STAT support, the st_dev is a pointer to thread
     174   static memory containing the device of the last filename looked up.
     175
     176   Todo: find out if the ino_t still needs to be faked on a directory.
     177 */
     178
     179/* Define this if the older VMS_INO_T is needed */
     180#define VMS_INO_T 1
     181
    156182static int
    157183vms_hash (const char *name)
    158184{
    159185  int h = 0;
    160   int g;
    161186
    162187  while (*name)
    163188    {
    164189      unsigned char uc = *name;
     190      int g;
    165191#ifdef HAVE_CASE_INSENSITIVE_FS
    166192      h = (h << 4) + (isupper (uc) ? tolower (uc) : uc);
     
    171197      g = h & 0xf0000000;
    172198      if (g)
    173         {
    174           h = h ^ (g >> 24);
    175           h = h ^ g;
    176         }
     199        {
     200          h = h ^ (g >> 24);
     201          h = h ^ g;
     202        }
    177203    }
    178204  return h;
     
    191217    return -1;
    192218  closedir (dir);
    193   s = strchr (name, ':');       /* find device */
     219  s = strchr (name, ':');       /* find device */
    194220  if (s)
    195221    {
     
    212238  return 0;
    213239}
     240
     241# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
     242
     243#endif /* _USE_STD_STAT */
    214244#endif /* VMS */
    215245
     
    217247/* Hash table of directories.  */
    218248
    219 #ifndef DIRECTORY_BUCKETS
     249#ifndef DIRECTORY_BUCKETS
    220250#ifdef KMK
    221251#  define DIRECTORY_BUCKETS 4096
     
    227257struct directory_contents
    228258  {
    229     dev_t dev;                  /* Device and inode numbers of this dir.  */
     259    dev_t dev;                  /* Device and inode numbers of this dir.  */
    230260#ifdef WINDOWS32
    231261    /* Inode means nothing on WINDOWS32. Even file key information is
     
    239269    char const *path_key; /* strcache'ed */
    240270# endif
    241     int  ctime;
    242     int  mtime;        /* controls check for stale directory cache */
    243     int   fs_flags;     /* FS_FAT, FS_NTFS, ... */
     271    time_t ctime;
     272    time_t mtime;        /* controls check for stale directory cache */
     273    int fs_flags;     /* FS_FAT, FS_NTFS, ... */
    244274# define FS_FAT      0x1
    245275# define FS_NTFS     0x2
     
    249279# endif
    250280#else
    251 # ifdef VMS
     281# ifdef VMS_INO_T
    252282    ino_t ino[3];
    253283# else
     
    255285# endif
    256286#endif /* WINDOWS32 */
    257     struct hash_table dirfiles; /* Files in this directory.  */
    258     DIR *dirstream;             /* Stream reading this directory.  */
     287    struct hash_table dirfiles; /* Files in this directory.  */
     288    DIR *dirstream;             /* Stream reading this directory.  */
    259289  };
    260290
     
    274304  hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
    275305#else
    276 # ifdef VMS
     306# ifdef VMS_INO_T
    277307  hash = (((unsigned int) key->dev << 4)
    278           ^ ((unsigned int) key->ino[0]
    279              + (unsigned int) key->ino[1]
    280              + (unsigned int) key->ino[2]));
     308          ^ ((unsigned int) key->ino[0]
     309             + (unsigned int) key->ino[1]
     310             + (unsigned int) key->ino[2]));
    281311# else
    282312  hash = ((unsigned int) key->dev << 4) ^ (unsigned int) key->ino;
     
    301331  hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
    302332#else
    303 # ifdef VMS
     333# ifdef VMS_INO_T
    304334  hash = (((unsigned int) key->dev << 4)
    305           ^ ~((unsigned int) key->ino[0]
    306               + (unsigned int) key->ino[1]
    307               + (unsigned int) key->ino[2]));
     335          ^ ~((unsigned int) key->ino[0]
     336              + (unsigned int) key->ino[1]
     337              + (unsigned int) key->ino[2]));
    308338# else
    309339  hash = ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ino;
     
    345375    return result;
    346376#else
    347 # ifdef VMS
     377# ifdef VMS_INO_T
    348378  result = MAKECMP(x->ino[0], y->ino[0]);
    349379  if (result)
     
    375405struct directory
    376406  {
    377     const char *name;                   /* Name of the directory.  */
     407    const char *name;                   /* Name of the directory.  */
    378408
    379409    /* The directory's contents.  This data may be shared by several
    380410       entries in the hash table, which refer to the same directory
    381        (identified uniquely by `dev' and `ino') under different names.  */
     411       (identified uniquely by 'dev' and 'ino') under different names.  */
    382412    struct directory_contents *contents;
    383413  };
     
    400430{
    401431  return_ISTRING_COMPARE (((const struct directory *) x)->name,
    402                           ((const struct directory *) y)->name);
     432                          ((const struct directory *) y)->name);
    403433}
    404434#endif /* !CONFIG_WITH_STRCACHE2 */
     
    423453struct dirfile
    424454  {
    425     const char *name;           /* Name of the file.  */
    426     short length;
    427     short impossible;           /* This file is impossible.  */
     455    const char *name;           /* Name of the file.  */
     456    size_t length;
     457    short impossible;           /* This file is impossible.  */
    428458  };
    429459
     
    453483#endif /* !CONFIG_WITH_STRCACHE2 */
    454484
    455 #ifndef DIRFILE_BUCKETS
     485#ifndef DIRFILE_BUCKETS
    456486#define DIRFILE_BUCKETS 107
    457487#endif
     
    468498static struct directory *find_directory (const char *name);
    469499
    470 /* Find the directory named NAME and return its `struct directory'.  */
     500/* Find the directory named NAME and return its 'struct directory'.  */
    471501
    472502static struct directory *
    473503find_directory (const char *name)
    474504{
    475   const char *p;
    476505  struct directory *dir;
    477506  struct directory **dir_slot;
    478507  struct directory dir_key;
    479   int r;
    480 #ifdef WINDOWS32
    481   char* w32_path;
    482   char  fs_label[BUFSIZ];
    483   char  fs_type[BUFSIZ];
    484   unsigned long  fs_serno;
    485   unsigned long  fs_flags;
    486   unsigned long  fs_len;
    487 #endif
    488 #ifdef VMS
    489   if ((*name == '.') && (*(name+1) == 0))
    490     name = "[]";
    491   else
    492     name = vmsify (name,1);
    493 #endif
    494508
    495509#ifndef CONFIG_WITH_STRCACHE2
     
    497511  dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
    498512#else
    499   p = name + strlen (name);
     513  const char *p = name + strlen (name);
    500514# if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
    501515  dir_key.name = strcache_add_len (downcase(name), p - name);
     
    509523  if (HASH_VACANT (dir))
    510524    {
     525      /* The directory was not found.  Create a new entry for it.  */
     526#ifndef CONFIG_WITH_STRCACHE2
     527      const char *p = name + strlen (name);
     528#endif
    511529      struct stat st;
    512 
    513       /* The directory was not found.  Create a new entry for it.  */
    514 
    515 #ifndef CONFIG_WITH_STRCACHE2
    516       p = name + strlen (name);
    517 #endif
     530      int r;
     531
    518532#ifndef CONFIG_WITH_ALLOC_CACHES
    519533      dir = xmalloc (sizeof (struct directory));
     
    523537#ifndef CONFIG_WITH_STRCACHE2
    524538#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
    525       dir->name = strcache_add_len (downcase(name), p - name);
     539      /* Todo: Why is this only needed on VMS? */
     540      {
     541        char *lname = downcase_inplace (xstrdup (name));
     542        dir->name = strcache_add_len (lname, p - name);
     543        free (lname);
     544      }
    526545#else
    527546      dir->name = strcache_add_len (name, p - name);
     
    532551      hash_insert_at (&directories, dir, dir_slot);
    533552      /* The directory is not in the name hash table.
    534          Find its device and inode numbers, and look it up by them.  */
    535 
    536 #ifdef VMS
    537       r = vmsstat_dir (name, &st);
    538 #elif defined(WINDOWS32)
     553         Find its device and inode numbers, and look it up by them.  */
     554
     555#if defined(WINDOWS32)
    539556      {
    540557        char tem[MAXPATHLEN], *tstart, *tend;
     
    559576      if (r < 0)
    560577        {
    561         /* Couldn't stat the directory.  Mark this by
    562            setting the `contents' member to a nil pointer.  */
    563           dir->contents = 0;
    564         }
     578        /* Couldn't stat the directory.  Mark this by
     579           setting the 'contents' member to a nil pointer.  */
     580          dir->contents = 0;
     581        }
    565582      else
    566         {
    567           /* Search the contents hash table; device and inode are the key.  */
    568 
    569           struct directory_contents *dc;
    570           struct directory_contents **dc_slot;
    571           struct directory_contents dc_key;
    572 
    573           dc_key.dev = st.st_dev;
     583        {
     584          /* Search the contents hash table; device and inode are the key.  */
     585
     586#ifdef WINDOWS32
     587          char *w32_path;
     588#endif
     589          struct directory_contents *dc;
     590          struct directory_contents **dc_slot;
     591          struct directory_contents dc_key;
     592
     593          dc_key.dev = st.st_dev;
    574594#ifdef WINDOWS32
    575595# ifndef CONFIG_WITH_STRCACHE2
     
    581601          dc_key.ctime = st.st_ctime;
    582602#else
    583 # ifdef VMS
    584           dc_key.ino[0] = st.st_ino[0];
    585           dc_key.ino[1] = st.st_ino[1];
    586           dc_key.ino[2] = st.st_ino[2];
     603# ifdef VMS_INO_T
     604          dc_key.ino[0] = st.st_ino[0];
     605          dc_key.ino[1] = st.st_ino[1];
     606          dc_key.ino[2] = st.st_ino[2];
    587607# else
    588           dc_key.ino = st.st_ino;
    589 # endif
    590 #endif
    591           dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
    592           dc = *dc_slot;
    593 
    594           if (HASH_VACANT (dc))
    595             {
     608          dc_key.ino = st.st_ino;
     609# endif
     610#endif
     611          dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
     612          dc = *dc_slot;
     613
     614          if (HASH_VACANT (dc))
     615            {
     616              /* Nope; this really is a directory we haven't seen before.  */
     617#ifdef WINDOWS32
     618              char  fs_label[BUFSIZ];
     619              char  fs_type[BUFSIZ];
     620              unsigned long  fs_serno;
     621              unsigned long  fs_flags;
     622              unsigned long  fs_len;
     623#endif
    596624#if defined(WINDOWS32) && defined(KMK)
    597625              static char s_last_volume[4];
    598626              static int  s_last_flags;
    599627#endif
    600               /* Nope; this really is a directory we haven't seen before.  */
    601628
    602629#ifndef CONFIG_WITH_ALLOC_CACHES
     
    608635#endif
    609636
    610               /* Enter it in the contents hash table.  */
    611               dc->dev = st.st_dev;
     637              /* Enter it in the contents hash table.  */
     638              dc->dev = st.st_dev;
    612639#ifdef WINDOWS32
    613640# ifndef CONFIG_WITH_STRCACHE2
     
    617644# endif /* CONFIG_WITH_STRCACHE2 */
    618645
    619               dc->ctime = st.st_ctime;
     646              dc->ctime = st.st_ctime;
    620647              dc->mtime = st.st_mtime;
    621648# ifdef KMK
     
    623650# endif
    624651
    625               /*
    626                * NTFS is the only WINDOWS32 filesystem that bumps mtime
    627                * on a directory when files are added/deleted from
    628                * a directory.
    629                */
     652              /* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
     653                 directory when files are added/deleted from a directory.  */
    630654              w32_path[3] = '\0';
     655
    631656# ifdef KMK /* Need for speed: Cache the GetVolumeInformation result. */
    632657              if (   s_last_volume[0] == w32_path[0]
     
    638663                {
    639664# endif
    640               if (GetVolumeInformation(w32_path,
    641                      fs_label, sizeof (fs_label),
    642                      &fs_serno, &fs_len,
    643                      &fs_flags, fs_type, sizeof (fs_type)) == FALSE)
     665              if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
     666                                        &fs_serno, &fs_len, &fs_flags, fs_type,
     667                                        sizeof (fs_type)) == FALSE)
    644668                dc->fs_flags = FS_UNKNOWN;
    645               else if (!strcmp(fs_type, "FAT"))
     669              else if (!strcmp (fs_type, "FAT"))
    646670                dc->fs_flags = FS_FAT;
    647               else if (!strcmp(fs_type, "NTFS"))
     671              else if (!strcmp (fs_type, "NTFS"))
    648672                dc->fs_flags = FS_NTFS;
    649673              else
    650674                dc->fs_flags = FS_UNKNOWN;
    651675# ifdef KMK
    652                   s_last_volume[0] = w32_path[0];
    653                   s_last_volume[1] = w32_path[1];
    654                   s_last_volume[2] = w32_path[2];
    655                   s_last_volume[3] = w32_path[3];
    656                   s_last_flags     = dc->fs_flags;
    657                 }
    658 # endif
    659 #else
    660 # ifdef VMS
    661               dc->ino[0] = st.st_ino[0];
    662               dc->ino[1] = st.st_ino[1];
    663               dc->ino[2] = st.st_ino[2];
     676              s_last_volume[0] = w32_path[0];
     677              s_last_volume[1] = w32_path[1];
     678              s_last_volume[2] = w32_path[2];
     679              s_last_volume[3] = w32_path[3];
     680              s_last_flags     = dc->fs_flags;
     681# endif
     682#else
     683# ifdef VMS_INO_T
     684              dc->ino[0] = st.st_ino[0];
     685              dc->ino[1] = st.st_ino[1];
     686              dc->ino[2] = st.st_ino[2];
    664687# else
    665               dc->ino = st.st_ino;
     688              dc->ino = st.st_ino;
    666689# endif
    667690#endif /* WINDOWS32 */
    668               hash_insert_at (&directory_contents, dc, dc_slot);
    669               ENULLLOOP (dc->dirstream, opendir (name));
    670               if (dc->dirstream == 0)
     691              hash_insert_at (&directory_contents, dc, dc_slot);
     692              ENULLLOOP (dc->dirstream, opendir (name));
     693              if (dc->dirstream == 0)
    671694                /* Couldn't open the directory.  Mark this by setting the
    672                    `files' member to a nil pointer.  */
     695                   'files' member to a nil pointer.  */
    673696                dc->dirfiles.ht_vec = 0;
    674697              else
     
    682705#else
    683706# ifndef CONFIG_WITH_STRCACHE2
    684                   hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
    685                              dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
     707                  hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
     708                             dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
    686709# else  /* CONFIG_WITH_STRCACHE2 */
    687710                  hash_init_strcached (&dc->dirfiles, DIRFILE_BUCKETS,
     
    690713# endif /* CONFIG_WITH_STRCACHE2 */
    691714#endif
    692                   /* Keep track of how many directories are open.  */
    693                   ++open_directories;
    694                   if (open_directories == MAX_OPEN_DIRECTORIES)
    695                     /* We have too many directories open already.
    696                        Read the entire directory and then close it.  */
    697                     dir_contents_file_exists_p (dc, 0);
    698                 }
    699             }
    700 
    701           /* Point the name-hashed entry for DIR at its contents data.  */
    702           dir->contents = dc;
    703         }
     715                  ++open_directories;
     716                  if (open_directories == MAX_OPEN_DIRECTORIES)
     717                    /* We have too many directories open already.
     718                       Read the entire directory and then close it.  */
     719                    dir_contents_file_exists_p (dc, 0);
     720                }
     721            }
     722
     723          /* Point the name-hashed entry for DIR at its contents data.  */
     724          dir->contents = dc;
     725        }
    704726    }
    705727
     
    715737                            const char *filename)
    716738{
    717   /*unsigned int hash;*/
    718739  struct dirfile *df;
    719740  struct dirent *d;
     
    744765    _fnlwr (filename); /* lower case for FAT drives */
    745766#endif
    746 
    747 #ifdef VMS
    748   filename = vmsify (filename,0);
    749 #endif
    750 
    751   /*hash = 0;*/
    752767  if (filename != 0)
    753768    {
     
    755770
    756771      if (*filename == '\0')
    757         {
    758           /* Checking if the directory exists.  */
    759           return 1;
    760         }
     772        {
     773          /* Checking if the directory exists.  */
     774          return 1;
     775        }
    761776#ifndef CONFIG_WITH_STRCACHE2
    762777      dirfile_key.name = filename;
     
    789804      if (dir->path_key)
    790805# endif
    791         {
     806        {
    792807          if ((dir->fs_flags & FS_FAT) != 0)
    793808            {
     
    801816          else if (stat (dir->path_key, &st) == 0 && st.st_mtime > dir->mtime)
    802817# endif
    803             {
    804               /* reset date stamp to show most recent re-process.  */
    805               dir->mtime = st.st_mtime;
    806               rehash = 1;
    807             }
     818            {
     819              /* reset date stamp to show most recent re-process.  */
     820              dir->mtime = st.st_mtime;
     821              rehash = 1;
     822            }
    808823
    809824
    810825          /* If it has been already read in, all done.  */
    811           if (!rehash)
    812             return 0;
     826          if (!rehash)
     827            return 0;
    813828
    814829          /* make sure directory can still be opened; if not return.  */
     
    819834          dc->last_updated = time(NULL);
    820835# endif
    821         }
     836        }
    822837      else
    823838#endif
    824         /* The directory has been all read in.  */
    825         return 0;
     839        /* The directory has been all read in.  */
     840        return 0;
    826841    }
    827842
     
    857872/* bird: end */
    858873          if (errno)
    859             fatal (NILF, "INTERNAL: readdir(%p): %s (filename=%s)\n", (void *)dir, strerror (errno), filename);
     874            pfatal_with_name ("INTERNAL: readdir");
    860875          break;
    861876        }
    862877
    863878#if defined(VMS) && defined(HAVE_DIRENT_H)
    864       /* In VMS we get file versions too, which have to be stripped off */
     879      /* In VMS we get file versions too, which have to be stripped off.
     880         Some versions of VMS return versions on Unix files even when
     881         the feature option to strip them is set.  */
    865882      {
    866883        char *p = strrchr (d->d_name, ';');
     
    870887#endif
    871888      if (!REAL_DIR_ENTRY (d))
    872         continue;
     889        continue;
    873890
    874891      len = NAMLEN (d);
     
    895912        {
    896913#ifndef CONFIG_WITH_ALLOC_CACHES
    897           df = xmalloc (sizeof (struct dirfile));
     914          df = xmalloc (sizeof (struct dirfile));
    898915#else
    899916          df = alloccache_alloc (&dirfile_cache);
     
    901918#ifndef CONFIG_WITH_STRCACHE2
    902919#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
    903           df->name = strcache_add_len (downcase(d->d_name), len);
    904 #else
    905           df->name = strcache_add_len (d->d_name, len);
     920          /* TODO: Why is this only needed on VMS? */
     921          df->name = strcache_add_len (downcase_inplace (d->d_name), len);
     922#else
     923          df->name = strcache_add_len (d->d_name, len);
    906924#endif
    907925#else  /* CONFIG_WITH_STRCACHE2 */
    908926          df->name = dirfile_key.name;
    909927#endif /* CONFIG_WITH_STRCACHE2 */
    910           df->length = len;
    911           df->impossible = 0;
    912           hash_insert_at (&dir->dirfiles, df, dirfile_slot);
    913         }
     928          df->length = len;
     929          df->impossible = 0;
     930          hash_insert_at (&dir->dirfiles, df, dirfile_slot);
     931        }
    914932      /* Check if the name matches the one we're searching for.  */
    915933#ifndef CONFIG_WITH_STRCACHE2
     
    947965dir_file_exists_p (const char *dirname, const char *filename)
    948966{
     967#ifdef VMS
     968  if ((filename != NULL) && (dirname != NULL))
     969    {
     970      int want_vmsify;
     971      want_vmsify = (strpbrk (dirname, ":<[") != NULL);
     972      if (want_vmsify)
     973        filename = vmsify (filename, 0);
     974    }
     975#endif
    949976  return dir_contents_file_exists_p (find_directory (dirname)->contents,
    950                                      filename);
     977                                     filename);
    951978}
    952979
     
    961988  const char *slash;
    962989
    963 #ifndef NO_ARCHIVES
     990#ifndef NO_ARCHIVES
    964991  if (ar_name (name))
    965992    return ar_member_date (name) != (time_t) -1;
    966993#endif
    967994
     995  dirend = strrchr (name, '/');
    968996#ifdef VMS
    969   dirend = strrchr (name, ']');
    970997  if (dirend == 0)
    971     dirend = strrchr (name, ':');
     998    {
     999      dirend = strrchr (name, ']');
     1000      dirend == NULL ? dirend : dirend++;
     1001    }
    9721002  if (dirend == 0)
    973     return dir_file_exists_p ("[]", name);
    974 #else /* !VMS */
    975   dirend = strrchr (name, '/');
     1003    {
     1004      dirend = strrchr (name, '>');
     1005      dirend == NULL ? dirend : dirend++;
     1006    }
     1007  if (dirend == 0)
     1008    {
     1009      dirend = strrchr (name, ':');
     1010      dirend == NULL ? dirend : dirend++;
     1011    }
     1012#endif /* VMS */
    9761013#ifdef HAVE_DOS_PATHS
    9771014  /* Forward and backslashes might be mixed.  We need the rightmost one.  */
    9781015  {
    979     const char *bslash = strrchr(name, '\\');
     1016    const char *bslash = strrchr (name, '\\');
    9801017    if (!dirend || bslash > dirend)
    9811018      dirend = bslash;
     
    9881025#ifndef _AMIGA
    9891026    return dir_file_exists_p (".", name);
    990 #else /* !VMS && !AMIGA */
     1027#else /* !AMIGA */
    9911028    return dir_file_exists_p ("", name);
    9921029#endif /* AMIGA */
    993 #endif /* VMS */
    9941030
    9951031  slash = dirend;
     
    10021038  /* d:/ and d: are *very* different...  */
    10031039      if (dirend < name + 3 && name[1] == ':' &&
    1004           (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
    1005         dirend++;
     1040          (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
     1041        dirend++;
    10061042#endif
    10071043      p = alloca (dirend - name + 1);
     
    10101046      dirname = p;
    10111047    }
    1012   return dir_file_exists_p (dirname, slash + 1);
    1013 }
    1014 
    1015 
    1016 /* Mark FILENAME as `impossible' for `file_impossible_p'.
     1048#ifdef VMS
     1049  if (*slash == '/')
     1050    slash++;
     1051#else
     1052  slash++;
     1053#endif
     1054  return dir_file_exists_p (dirname, slash);
     1055}
     1056
     1057
     1058/* Mark FILENAME as 'impossible' for 'file_impossible_p'.
    10171059   This means an attempt has been made to search for FILENAME
    10181060   as an intermediate file, and it has failed.  */
     
    10261068  struct dirfile *new;
    10271069
     1070  dirend = strrchr (p, '/');
    10281071#ifdef VMS
    1029   dirend = strrchr (p, ']');
    1030   if (dirend == 0)
    1031     dirend = strrchr (p, ':');
    1032   dirend++;
    1033   if (dirend == (char *)1)
    1034     dir = find_directory ("[]");
    1035 #else
    1036   dirend = strrchr (p, '/');
    1037 # ifdef HAVE_DOS_PATHS
     1072  if (dirend == NULL)
     1073    {
     1074      dirend = strrchr (p, ']');
     1075      dirend == NULL ? dirend : dirend++;
     1076    }
     1077  if (dirend == NULL)
     1078    {
     1079      dirend = strrchr (p, '>');
     1080      dirend == NULL ? dirend : dirend++;
     1081    }
     1082  if (dirend == NULL)
     1083    {
     1084      dirend = strrchr (p, ':');
     1085      dirend == NULL ? dirend : dirend++;
     1086    }
     1087#endif
     1088#ifdef HAVE_DOS_PATHS
    10381089  /* Forward and backslashes might be mixed.  We need the rightmost one.  */
    10391090  {
    1040     const char *bslash = strrchr(p, '\\');
     1091    const char *bslash = strrchr (p, '\\');
    10411092    if (!dirend || bslash > dirend)
    10421093      dirend = bslash;
     
    10451096      dirend = p + 1;
    10461097  }
    1047 # endif /* HAVE_DOS_PATHS */
     1098#endif /* HAVE_DOS_PATHS */
    10481099  if (dirend == 0)
    1049 # ifdef _AMIGA
     1100#ifdef _AMIGA
    10501101    dir = find_directory ("");
    1051 # else /* !VMS && !AMIGA */
     1102#else /* !AMIGA */
    10521103    dir = find_directory (".");
    1053 # endif /* AMIGA */
    1054 #endif /* VMS */
     1104#endif /* AMIGA */
    10551105  else
    10561106    {
     
    10581108      const char *slash = dirend;
    10591109      if (dirend == p)
    1060         dirname = "/";
     1110        dirname = "/";
    10611111      else
    1062         {
     1112        {
    10631113          char *cp;
    10641114#ifdef HAVE_DOS_PATHS
    1065           /* d:/ and d: are *very* different...  */
    1066           if (dirend < p + 3 && p[1] == ':' &&
    1067               (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
    1068             dirend++;
    1069 #endif
    1070           cp = alloca (dirend - p + 1);
    1071           memcpy (cp, p, dirend - p);
    1072           cp[dirend - p] = '\0';
     1115          /* d:/ and d: are *very* different...  */
     1116          if (dirend < p + 3 && p[1] == ':' &&
     1117              (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
     1118            dirend++;
     1119#endif
     1120          cp = alloca (dirend - p + 1);
     1121          memcpy (cp, p, dirend - p);
     1122          cp[dirend - p] = '\0';
    10731123          dirname = cp;
    1074         }
     1124        }
    10751125      dir = find_directory (dirname);
     1126#ifdef VMS
     1127      if (*slash == '/')
     1128        filename = p = slash + 1;
     1129      else
     1130        filename = p = slash;
     1131#else
    10761132      filename = p = slash + 1;
     1133#endif
    10771134    }
    10781135
     
    10901147#ifndef CONFIG_WITH_STRCACHE2
    10911148      hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS,
    1092                 dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
     1149                dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
    10931150#else  /* CONFIG_WITH_STRCACHE2 */
    10941151      hash_init_strcached (&dir->contents->dirfiles, DIRFILE_BUCKETS,
     
    11061163  new->length = strlen (filename);
    11071164#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
    1108   new->name = strcache_add_len (downcase(filename), new->length);
     1165  /* todo: Why is this only needed on VMS? */
     1166  new->name = strcache_add_len (downcase (filename), new->length);
    11091167#else
    11101168  new->name = strcache_add_len (filename, new->length);
     
    11251183{
    11261184  const char *dirend;
    1127   const char *p = filename;
    11281185  struct directory_contents *dir;
    11291186  struct dirfile *dirfile;
    11301187  struct dirfile dirfile_key;
    1131 
    11321188#ifdef VMS
    1133   dirend = strrchr (filename, ']');
    1134   if (dirend == 0)
    1135     dir = find_directory ("[]")->contents;
    1136 #else
     1189  int want_vmsify = 0;
     1190#endif
     1191
    11371192  dirend = strrchr (filename, '/');
     1193#ifdef VMS
     1194  if (dirend == NULL)
     1195    {
     1196      want_vmsify = (strpbrk (filename, "]>:^") != NULL);
     1197      dirend = strrchr (filename, ']');
     1198    }
     1199  if (dirend == NULL && want_vmsify)
     1200    dirend = strrchr (filename, '>');
     1201  if (dirend == NULL && want_vmsify)
     1202    dirend = strrchr (filename, ':');
     1203#endif
    11381204#ifdef HAVE_DOS_PATHS
    11391205  /* Forward and backslashes might be mixed.  We need the rightmost one.  */
    11401206  {
    1141     const char *bslash = strrchr(filename, '\\');
     1207    const char *bslash = strrchr (filename, '\\');
    11421208    if (!dirend || bslash > dirend)
    11431209      dirend = bslash;
     
    11501216#ifdef _AMIGA
    11511217    dir = find_directory ("")->contents;
    1152 #else /* !VMS && !AMIGA */
     1218#else /* !AMIGA */
    11531219    dir = find_directory (".")->contents;
    11541220#endif /* AMIGA */
    1155 #endif /* VMS */
    11561221  else
    11571222    {
     
    11591224      const char *slash = dirend;
    11601225      if (dirend == filename)
    1161         dirname = "/";
     1226        dirname = "/";
    11621227      else
    1163         {
     1228        {
    11641229          char *cp;
    11651230#ifdef HAVE_DOS_PATHS
    1166           /* d:/ and d: are *very* different...  */
    1167           if (dirend < filename + 3 && filename[1] == ':' &&
    1168               (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
    1169             dirend++;
    1170 #endif
    1171           cp = alloca (dirend - filename + 1);
    1172           memcpy (cp, p, dirend - p);
    1173           cp[dirend - p] = '\0';
     1231          /* d:/ and d: are *very* different...  */
     1232          if (dirend < filename + 3 && filename[1] == ':' &&
     1233              (*dirend == '/' || *dirend == '\\' || *dirend == ':'))
     1234            dirend++;
     1235#endif
     1236          cp = alloca (dirend - filename + 1);
     1237          memcpy (cp, filename, dirend - filename);
     1238          cp[dirend - filename] = '\0';
    11741239          dirname = cp;
    1175         }
     1240        }
    11761241      dir = find_directory (dirname)->contents;
    1177       p = filename = slash + 1;
     1242#ifdef VMS
     1243      if (*slash == '/')
     1244        filename = slash + 1;
     1245      else
     1246        filename = slash;
     1247#else
     1248      filename = slash + 1;
     1249#endif
    11781250    }
    11791251
     
    11831255
    11841256#ifdef __MSDOS__
    1185   filename = dosify (p);
     1257  filename = dosify (filename);
    11861258#endif
    11871259#ifdef HAVE_CASE_INSENSITIVE_FS
    1188   filename = downcase (p);
     1260  filename = downcase (filename);
    11891261#endif
    11901262#ifdef VMS
    1191   filename = vmsify (p, 1);
     1263  if (want_vmsify)
     1264    filename = vmsify (filename, 1);
    11921265#endif
    11931266
     
    12381311      struct directory *dir = *dir_slot;
    12391312      if (! HASH_VACANT (dir))
    1240         {
    1241           if (dir->contents == 0)
    1242             printf (_("# %s: could not be stat'd.\n"), dir->name);
    1243           else if (dir->contents->dirfiles.ht_vec == 0)
    1244             {
     1313        {
     1314          if (dir->contents == 0)
     1315            printf (_("# %s: could not be stat'd.\n"), dir->name);
     1316          else if (dir->contents->dirfiles.ht_vec == 0)
     1317            {
    12451318#ifdef WINDOWS32
    1246               printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
    1247                       dir->name, dir->contents->path_key,dir->contents->mtime);
     1319              printf (_("# %s (key %s, mtime %I64u): could not be opened.\n"),
     1320                      dir->name, dir->contents->path_key,
     1321                      (unsigned long long)dir->contents->mtime);
    12481322#else  /* WINDOWS32 */
    1249 #ifdef VMS
    1250               printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
    1251                       dir->name, dir->contents->dev,
    1252                       dir->contents->ino[0], dir->contents->ino[1],
    1253                       dir->contents->ino[2]);
    1254 #else
    1255               printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
    1256                       dir->name, (long int) dir->contents->dev,
    1257                       (long int) dir->contents->ino);
     1323#ifdef VMS_INO_T
     1324              printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
     1325                      dir->name, dir->contents->dev,
     1326                      dir->contents->ino[0], dir->contents->ino[1],
     1327                      dir->contents->ino[2]);
     1328#else
     1329              printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
     1330                      dir->name, (long int) dir->contents->dev,
     1331                      (long int) dir->contents->ino);
    12581332#endif
    12591333#endif /* WINDOWS32 */
    1260             }
    1261           else
    1262             {
    1263               unsigned int f = 0;
    1264               unsigned int im = 0;
    1265               struct dirfile **files_slot;
    1266               struct dirfile **files_end;
    1267 
    1268               files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec;
    1269               files_end = files_slot + dir->contents->dirfiles.ht_size;
    1270               for ( ; files_slot < files_end; files_slot++)
    1271                 {
    1272                   struct dirfile *df = *files_slot;
    1273                   if (! HASH_VACANT (df))
    1274                     {
    1275                       if (df->impossible)
    1276                         ++im;
    1277                       else
    1278                         ++f;
    1279                     }
    1280                 }
     1334            }
     1335          else
     1336            {
     1337              unsigned int f = 0;
     1338              unsigned int im = 0;
     1339              struct dirfile **files_slot;
     1340              struct dirfile **files_end;
     1341
     1342              files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec;
     1343              files_end = files_slot + dir->contents->dirfiles.ht_size;
     1344              for ( ; files_slot < files_end; files_slot++)
     1345                {
     1346                  struct dirfile *df = *files_slot;
     1347                  if (! HASH_VACANT (df))
     1348                    {
     1349                      if (df->impossible)
     1350                        ++im;
     1351                      else
     1352                        ++f;
     1353                    }
     1354                }
    12811355#ifdef WINDOWS32
    1282               printf (_("# %s (key %s, mtime %d): "),
    1283                       dir->name, dir->contents->path_key, dir->contents->mtime);
     1356              printf (_("# %s (key %s, mtime %I64u): "),
     1357                      dir->name, dir->contents->path_key,
     1358                      (unsigned long long)dir->contents->mtime);
    12841359#else  /* WINDOWS32 */
    1285 #ifdef VMS
    1286               printf (_("# %s (device %d, inode [%d,%d,%d]): "),
    1287                       dir->name, dir->contents->dev,
    1288                       dir->contents->ino[0], dir->contents->ino[1],
    1289                       dir->contents->ino[2]);
    1290 #else
    1291               printf (_("# %s (device %ld, inode %ld): "),
    1292                       dir->name,
    1293                       (long)dir->contents->dev, (long)dir->contents->ino);
     1360#ifdef VMS_INO_T
     1361              printf (_("# %s (device %d, inode [%d,%d,%d]): "),
     1362                      dir->name, dir->contents->dev,
     1363                      dir->contents->ino[0], dir->contents->ino[1],
     1364                      dir->contents->ino[2]);
     1365#else
     1366              printf (_("# %s (device %ld, inode %ld): "),
     1367                      dir->name,
     1368                      (long)dir->contents->dev, (long)dir->contents->ino);
    12941369#endif
    12951370#endif /* WINDOWS32 */
    1296               if (f == 0)
    1297                 fputs (_("No"), stdout);
    1298               else
    1299                 printf ("%u", f);
    1300               fputs (_(" files, "), stdout);
    1301               if (im == 0)
    1302                 fputs (_("no"), stdout);
    1303               else
    1304                 printf ("%u", im);
    1305               fputs (_(" impossibilities"), stdout);
    1306               if (dir->contents->dirstream == 0)
    1307                 puts (".");
    1308               else
    1309                 puts (_(" so far."));
    1310               files += f;
    1311               impossible += im;
     1371              if (f == 0)
     1372                fputs (_("No"), stdout);
     1373              else
     1374                printf ("%u", f);
     1375              fputs (_(" files, "), stdout);
     1376              if (im == 0)
     1377                fputs (_("no"), stdout);
     1378              else
     1379                printf ("%u", im);
     1380              fputs (_(" impossibilities"), stdout);
     1381              if (dir->contents->dirstream == 0)
     1382                puts (".");
     1383              else
     1384                puts (_(" so far."));
     1385              files += f;
     1386              impossible += im;
    13121387#ifdef KMK
    13131388              fputs ("# ", stdout);
     
    13151390              fputs ("\n", stdout);
    13161391#endif
    1317             }
    1318         }
     1392            }
     1393        }
    13191394    }
    13201395
     
    13521427/* Hooks for globbing.  */
    13531428
    1354 #include <glob.h>
    1355 
    13561429/* Structure describing state of iterating through a directory hash table.  */
    13571430
     
    14031476      struct dirfile *df = *ds->dirfile_slot++;
    14041477      if (! HASH_VACANT (df) && !df->impossible)
    1405         {
    1406           /* The glob interface wants a `struct dirent', so mock one up.  */
    1407           struct dirent *d;
    1408           unsigned int len = df->length + 1;
     1478        {
     1479          /* The glob interface wants a 'struct dirent', so mock one up.  */
     1480          struct dirent *d;
     1481          unsigned int len = df->length + 1;
    14091482          unsigned int sz = sizeof (*d) - sizeof (d->d_name) + len;
    1410           if (sz > bufsz)
    1411             {
    1412               bufsz *= 2;
    1413               if (sz > bufsz)
    1414                 bufsz = sz;
    1415               buf = xrealloc (buf, bufsz);
    1416             }
    1417           d = (struct dirent *) buf;
     1483          if (sz > bufsz)
     1484            {
     1485              bufsz *= 2;
     1486              if (sz > bufsz)
     1487                bufsz = sz;
     1488              buf = xrealloc (buf, bufsz);
     1489            }
     1490          d = (struct dirent *) buf;
    14181491#ifdef __MINGW32__
    14191492# if __MINGW32_MAJOR_VERSION < 3 || (__MINGW32_MAJOR_VERSION == 3 && \
    1420                                      __MINGW32_MINOR_VERSION == 0)
    1421           d->d_name = xmalloc(len);
    1422 # endif
    1423 #endif
    1424           FAKE_DIR_ENTRY (d);
     1493                                     __MINGW32_MINOR_VERSION == 0)
     1494          d->d_name = xmalloc (len);
     1495# endif
     1496#endif
     1497          FAKE_DIR_ENTRY (d);
    14251498#ifdef _DIRENT_HAVE_D_NAMLEN
    1426           d->d_namlen = len - 1;
     1499          d->d_namlen = len - 1;
    14271500#endif
    14281501#ifdef _DIRENT_HAVE_D_TYPE
    1429           d->d_type = DT_UNKNOWN;
    1430 #endif
    1431           memcpy (d->d_name, df->name, len);
    1432           return d;
    1433         }
     1502          d->d_type = DT_UNKNOWN;
     1503#endif
     1504          memcpy (d->d_name, df->name, len);
     1505          return d;
     1506        }
    14341507    }
    14351508
    14361509  return 0;
    1437 }
    1438 
    1439 static void
    1440 ansi_free (void *p)
    1441 {
    1442   if (p)
    1443     free(p);
    14441510}
    14451511
     
    14471513 * macro for stat64().  If stat is a macro, make a local wrapper function to
    14481514 * invoke it.
     1515 *
     1516 * On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
     1517 * regular file; fix that here.
    14491518 */
    1450 #ifndef stat
     1519#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
    14511520# ifndef VMS
     1521#  ifndef HAVE_SYS_STAT_H
    14521522int stat (const char *path, struct stat *sbuf);
     1523#  endif
     1524# else
     1525    /* We are done with the fake stat.  Go back to the real stat */
     1526#   ifdef stat
     1527#     undef stat
     1528#   endif
    14531529# endif
    14541530# define local_stat stat
     
    14581534{
    14591535  int e;
     1536#ifdef WINDOWS32
     1537  size_t plen = strlen (path);
     1538
     1539  /* Make sure the parent of "." exists and is a directory, not a
     1540     file.  This is because 'stat' on Windows normalizes the argument
     1541     foo/. => foo without checking first that foo is a directory.  */
     1542  if (plen > 1 && path[plen - 1] == '.'
     1543      && (path[plen - 2] == '/' || path[plen - 2] == '\\'))
     1544    {
     1545      char parent[MAXPATHLEN];
     1546
     1547      strncpy (parent, path, plen - 2);
     1548      parent[plen - 2] = '\0';
     1549      if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
     1550        return -1;
     1551    }
     1552#endif
    14601553
    14611554  EINTRLOOP (e, stat (path, buf));
     
    14821575  gl->gl_opendir = open_dirstream;
    14831576  gl->gl_readdir = read_dirstream;
    1484   gl->gl_closedir = ansi_free;
     1577  gl->gl_closedir = free;
    14851578  gl->gl_stat = local_stat;
    14861579#ifdef __EMX__ /* The FreeBSD implementation actually uses gl_lstat!! */
     
    15001593#ifndef CONFIG_WITH_STRCACHE2
    15011594  hash_init (&directories, DIRECTORY_BUCKETS,
    1502              directory_hash_1, directory_hash_2, directory_hash_cmp);
     1595             directory_hash_1, directory_hash_2, directory_hash_cmp);
    15031596#else  /* CONFIG_WITH_STRCACHE2 */
    15041597  hash_init_strcached (&directories, DIRECTORY_BUCKETS, &file_strcache,
     
    15061599#endif /* CONFIG_WITH_STRCACHE2 */
    15071600  hash_init (&directory_contents, DIRECTORY_BUCKETS,
    1508              directory_contents_hash_1, directory_contents_hash_2,
     1601             directory_contents_hash_1, directory_contents_hash_2,
    15091602             directory_contents_hash_cmp);
    15101603#ifdef CONFIG_WITH_ALLOC_CACHES
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette