Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* File name comparison routine.
  2.  
  3.    Copyright (C) 2007 Free Software Foundation, Inc.
  4.  
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software Foundation,
  17.    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
  18.  
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22.  
  23. #ifdef HAVE_STRING_H
  24. #include <string.h>
  25. #endif
  26.  
  27. #include "filenames.h"
  28. #include "safe-ctype.h"
  29.  
  30. /*
  31.  
  32. @deftypefn Extension int filename_cmp (const char *@var{s1}, const char *@var{s2})
  33.  
  34. Return zero if the two file names @var{s1} and @var{s2} are equivalent.
  35. If not equivalent, the returned value is similar to what @code{strcmp}
  36. would return.  In other words, it returns a negative value if @var{s1}
  37. is less than @var{s2}, or a positive value if @var{s2} is greater than
  38. @var{s2}.
  39.  
  40. This function does not normalize file names.  As a result, this function
  41. will treat filenames that are spelled differently as different even in
  42. the case when the two filenames point to the same underlying file.
  43. However, it does handle the fact that on DOS-like file systems, forward
  44. and backward slashes are equal.
  45.  
  46. @end deftypefn
  47.  
  48. */
  49.  
  50. int
  51. filename_cmp (const char *s1, const char *s2)
  52. {
  53. #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \
  54.     && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
  55.   return strcmp(s1, s2);
  56. #else
  57.   for (;;)
  58.     {
  59.       int c1 = *s1;
  60.       int c2 = *s2;
  61.  
  62. #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
  63.       c1 = TOLOWER (c1);
  64.       c2 = TOLOWER (c2);
  65. #endif
  66.  
  67. #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
  68.       /* On DOS-based file systems, the '/' and the '\' are equivalent.  */
  69.       if (c1 == '/')
  70.         c1 = '\\';
  71.       if (c2 == '/')
  72.         c2 = '\\';
  73. #endif
  74.  
  75.       if (c1 != c2)
  76.         return (c1 - c2);
  77.  
  78.       if (c1 == '\0')
  79.         return 0;
  80.  
  81.       s1++;
  82.       s2++;
  83.     }
  84. #endif
  85. }
  86.  
  87. /*
  88.  
  89. @deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
  90.  
  91. Return zero if the two file names @var{s1} and @var{s2} are equivalent
  92. in range @var{n}.
  93. If not equivalent, the returned value is similar to what @code{strncmp}
  94. would return.  In other words, it returns a negative value if @var{s1}
  95. is less than @var{s2}, or a positive value if @var{s2} is greater than
  96. @var{s2}.
  97.  
  98. This function does not normalize file names.  As a result, this function
  99. will treat filenames that are spelled differently as different even in
  100. the case when the two filenames point to the same underlying file.
  101. However, it does handle the fact that on DOS-like file systems, forward
  102. and backward slashes are equal.
  103.  
  104. @end deftypefn
  105.  
  106. */
  107.  
  108. int
  109. filename_ncmp (const char *s1, const char *s2, size_t n)
  110. {
  111. #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \
  112.     && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
  113.   return strncmp(s1, s2, n);
  114. #else
  115.   if (!n)
  116.     return 0;
  117.   for (; n > 0; --n)
  118.   {
  119.       int c1 = *s1;
  120.       int c2 = *s2;
  121.  
  122. #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
  123.       c1 = TOLOWER (c1);
  124.       c2 = TOLOWER (c2);
  125. #endif
  126.  
  127. #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
  128.       /* On DOS-based file systems, the '/' and the '\' are equivalent.  */
  129.       if (c1 == '/')
  130.         c1 = '\\';
  131.       if (c2 == '/')
  132.         c2 = '\\';
  133. #endif
  134.  
  135.       if (c1 == '\0' || c1 != c2)
  136.         return (c1 - c2);
  137.  
  138.       s1++;
  139.       s2++;
  140.   }
  141.   return 0;
  142. #endif
  143. }
  144.  
  145. /*
  146.  
  147. @deftypefn Extension hashval_t filename_hash (const void *@var{s})
  148.  
  149. Return the hash value for file name @var{s} that will be compared
  150. using filename_cmp.
  151. This function is for use with hashtab.c hash tables.
  152.  
  153. @end deftypefn
  154.  
  155. */
  156.  
  157. hashval_t
  158. filename_hash (const void *s)
  159. {
  160.   /* The cast is for -Wc++-compat.  */
  161.   const unsigned char *str = (const unsigned char *) s;
  162.   hashval_t r = 0;
  163.   unsigned char c;
  164.  
  165.   while ((c = *str++) != 0)
  166.     {
  167.       if (c == '\\')
  168.         c = '/';
  169.       c = TOLOWER (c);
  170.       r = r * 67 + c - 113;
  171.     }
  172.  
  173.   return r;
  174. }
  175.  
  176. /*
  177.  
  178. @deftypefn Extension int filename_eq (const void *@var{s1}, const void *@var{s2})
  179.  
  180. Return non-zero if file names @var{s1} and @var{s2} are equivalent.
  181. This function is for use with hashtab.c hash tables.
  182.  
  183. @end deftypefn
  184.  
  185. */
  186.  
  187. int
  188. filename_eq (const void *s1, const void *s2)
  189. {
  190.   /* The casts are for -Wc++-compat.  */
  191.   return filename_cmp ((const char *) s1, (const char *) s2) == 0;
  192. }
  193.