home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / gnu / utils / bug / 1409 next >
Encoding:
Text File  |  1992-08-25  |  9.7 KB  |  368 lines

  1. Newsgroups: gnu.utils.bug
  2. Path: sparky!uunet!convex!darwin.sura.net!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!skipsun.UUCP!skip
  3. From: skip@skipsun.UUCP (Skip Gilbrech)
  4. Subject: Patches for find-3.7 to enable case-insensitive filename matching
  5. Message-ID: <9208250528.AA00424@skipsun.UUCP>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. Distribution: gnu
  9. Date: Tue, 25 Aug 1992 05:28:11 GMT
  10. Approved: bug-gnu-utils@prep.ai.mit.edu
  11. Lines: 355
  12.  
  13. Following is a set of patches for find-3.7 which implement a -nocase
  14. option that allows case-insensitive shell pattern matching in
  15. conjunction with the -name, -lname, and -path predicates.
  16.  
  17. Case-insensitive matching could be done before, but only by explicitly
  18. specifying the upper/lower case letters to match ([Aa][Bb][Cc] ...).
  19.  
  20. Some systems apparently provide a `fnmatch()' call already, and
  21. lib/fnmatch.c had to be modified, and must be used, for this to work,
  22. so I changed configure to unconditionally include it in LIBOBJS.  The
  23. change probably should be made to `configure.in', but since I don't
  24. have `autoconf' (mentioned in INSTALL), I couldn't do that.
  25.  
  26. My hope was that these changes, or equivalent functionality, might be
  27. integrated into the base find distribution.  I've submitted similar
  28. patches for earlier versions (2.2 and 3.5) without that happening,
  29. though, and have received several requests for an update, so I'm
  30. providing these patches to enable those who like the -nocase option to
  31. implement it independently.
  32.  
  33. -Skip Gilbrech
  34.  
  35. ######################################################################
  36. Diffs follow:
  37.  
  38. *** configure-dist    Mon Jul 20 02:05:20 1992
  39. --- configure    Mon Aug 24 21:56:09 1992
  40. ***************
  41. *** 449,455 ****
  42.   fi
  43.   rm -f conftest*
  44.   
  45. ! for func in fnmatch memset stpcpy strdup strftime strspn strstr strtol
  46.   do
  47.   echo checking for ${func}
  48.   echo "
  49. --- 449,457 ----
  50.   fi
  51.   rm -f conftest*
  52.   
  53. ! LIBOBJS="fnmatch.o"
  54. ! for func in memset stpcpy strdup strftime strspn strstr strtol
  55.   do
  56.   echo checking for ${func}
  57.   echo "
  58. *** lib/fnmatch.h-dist    Thu May 28 17:36:19 1992
  59. --- lib/fnmatch.h    Mon Aug 24 22:31:57 1992
  60. ***************
  61. *** 38,44 ****
  62.   #define    FNM_PATHNAME    (1 << 0)/* No wildcard can ever match `/'.  */
  63.   #define    FNM_NOESCAPE    (1 << 1)/* Backslashes don't quote special chars.  */
  64.   #define    FNM_PERIOD    (1 << 2)/* Leading `.' is matched only explicitly.  */
  65. ! #define    __FNM_FLAGS    (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD)
  66.   
  67.   #if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE)
  68.   #define    FNM_FILE_NAME    FNM_PATHNAME
  69. --- 38,45 ----
  70.   #define    FNM_PATHNAME    (1 << 0)/* No wildcard can ever match `/'.  */
  71.   #define    FNM_NOESCAPE    (1 << 1)/* Backslashes don't quote special chars.  */
  72.   #define    FNM_PERIOD    (1 << 2)/* Leading `.' is matched only explicitly.  */
  73. ! #define    FNM_ANYCASE    (1 << 3)/* Matches ignore case. */
  74. ! #define    __FNM_FLAGS    (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD|FNM_ANYCASE)
  75.   
  76.   #if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE)
  77.   #define    FNM_FILE_NAME    FNM_PATHNAME
  78. *** lib/fnmatch.c-dist    Wed Jun  3 19:51:40 1992
  79. --- lib/fnmatch.c    Mon Aug 24 22:26:28 1992
  80. ***************
  81. *** 26,31 ****
  82. --- 26,40 ----
  83.   #define const
  84.   #endif
  85.   
  86. + #include <ctype.h>
  87. + #define CHAR_SET_SIZE  256
  88. + static char ci_tbl[CHAR_SET_SIZE];
  89. + static int ci_tbl_initialized = 0;
  90. + #define CI_LOWER(c)    (ci_tbl[ (c) & (CHAR_SET_SIZE - 1) ])
  91. + #define CI_MATCH(c1,c2)    (CI_LOWER(c1) == CI_LOWER(c2))
  92.   /* Match STRING against the filename pattern PATTERN, returning zero if
  93.      it matches, nonzero if not.  */
  94.   int
  95. ***************
  96. *** 43,48 ****
  97. --- 52,68 ----
  98.         return -1;
  99.       }
  100.   
  101. +   if ((flags & FNM_ANYCASE) && ! ci_tbl_initialized)
  102. +   {
  103. +       unsigned count;
  104. +       
  105. +       /* Map uppercase characters to corresponding lowercase ones.  */
  106. +       for (count = 0; count < CHAR_SET_SIZE; ++count)
  107. +       ci_tbl[count] = isupper (count) ? tolower (count) : count;
  108. +       ci_tbl_initialized = 1;
  109. +   }
  110.     while ((c = *p++) != '\0')
  111.       {
  112.         switch (c)
  113. ***************
  114. *** 60,66 ****
  115.       case '\\':
  116.         if (!(flags & FNM_NOESCAPE))
  117.           c = *p++;
  118. !       if (*n != c)
  119.           return FNM_NOMATCH;
  120.         break;
  121.   
  122. --- 80,86 ----
  123.       case '\\':
  124.         if (!(flags & FNM_NOESCAPE))
  125.           c = *p++;
  126. !       if ((flags & FNM_ANYCASE) ? !CI_MATCH(*n, c) : *n != c)
  127.           return FNM_NOMATCH;
  128.         break;
  129.   
  130. ***************
  131. *** 80,86 ****
  132.         {
  133.           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  134.           for (--p; *n != '\0'; ++n)
  135. !           if ((c == '[' || *n == c1) &&
  136.             fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  137.           return 0;
  138.           return FNM_NOMATCH;
  139. --- 100,107 ----
  140.         {
  141.           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  142.           for (--p; *n != '\0'; ++n)
  143. !           if ((c == '[' ||
  144. !            ((flags & FNM_ANYCASE) ? CI_MATCH(*n, c1) : *n == c1)) &&
  145.             fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  146.           return 0;
  147.           return FNM_NOMATCH;
  148. ***************
  149. *** 130,136 ****
  150.               c = *p++;
  151.             }
  152.   
  153. !         if (*n >= cstart && *n <= cend)
  154.             goto matched;
  155.   
  156.           if (c == ']')
  157. --- 151,164 ----
  158.               c = *p++;
  159.             }
  160.   
  161. !         if (flags & FNM_ANYCASE)
  162. !           {
  163. !             if (CI_LOWER(*n) >= CI_LOWER(cstart) &&
  164. !             CI_LOWER(*n) <= CI_LOWER(cend))
  165. !               goto matched;
  166. !           }
  167. !         else if (*n >= cstart && *n <= cend)
  168.             goto matched;
  169.   
  170.           if (c == ']')
  171. ***************
  172. *** 159,165 ****
  173.         break;
  174.   
  175.       default:
  176. !       if (c != *n)
  177.           return FNM_NOMATCH;
  178.       }
  179.   
  180. --- 187,193 ----
  181.         break;
  182.   
  183.       default:
  184. !       if ((flags & FNM_ANYCASE) ? !CI_MATCH(c, *n) : c != *n)
  185.           return FNM_NOMATCH;
  186.       }
  187.   
  188. *** find/pred.c-dist    Mon Jul 13 22:09:20 1992
  189. --- find/pred.c    Mon Aug 24 23:37:30 1992
  190. ***************
  191. *** 123,128 ****
  192. --- 123,129 ----
  193.   boolean pred_name ();
  194.   boolean pred_negate ();
  195.   boolean pred_newer ();
  196. + /* no pred_nocase */
  197.   /* no pred_noleaf */
  198.   boolean pred_nogroup ();
  199.   boolean pred_nouser ();
  200. ***************
  201. *** 872,878 ****
  202.         else
  203.       {
  204.         linkname[linklen] = '\0';
  205. !       if (fnmatch (pred_ptr->args.str, linkname, 0) == 0)
  206.           ret = true;
  207.       }
  208.         free (linkname);
  209. --- 873,880 ----
  210.         else
  211.       {
  212.         linkname[linklen] = '\0';
  213. !       if (fnmatch (pred_ptr->args.str, linkname,
  214. !                case_insensitive ? FNM_ANYCASE : 0) == 0)
  215.           ret = true;
  216.       }
  217.         free (linkname);
  218. ***************
  219. *** 951,957 ****
  220.     char *base;
  221.   
  222.     base = basename (pathname);
  223. !   if (fnmatch (pred_ptr->args.str, base, FNM_PERIOD) == 0)
  224.       return (true);
  225.     return (false);
  226.   }
  227. --- 953,960 ----
  228.     char *base;
  229.   
  230.     base = basename (pathname);
  231. !   if (fnmatch (pred_ptr->args.str, base,
  232. !            case_insensitive ? (FNM_ANYCASE|FNM_PERIOD) : FNM_PERIOD) == 0)
  233.       return (true);
  234.     return (false);
  235.   }
  236. ***************
  237. *** 1084,1090 ****
  238.        struct stat *stat_buf;
  239.        struct predicate *pred_ptr;
  240.   {
  241. !   if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
  242.       return (true);
  243.     return (false);
  244.   }
  245. --- 1087,1094 ----
  246.        struct stat *stat_buf;
  247.        struct predicate *pred_ptr;
  248.   {
  249. !   if (fnmatch (pred_ptr->args.str, pathname,
  250. !            case_insensitive ? FNM_ANYCASE : 0) == 0)
  251.       return (true);
  252.     return (false);
  253.   }
  254. *** find/find.c-dist    Fri Apr 24 02:55:34 1992
  255. --- find/find.c    Mon Aug 24 22:41:44 1992
  256. ***************
  257. *** 103,108 ****
  258. --- 103,112 ----
  259.   /* Pointer to the function used to stat files. */
  260.   int (*xstat) ();
  261.   
  262. + /* If true, enables case-insensitive filename searching.
  263. +    Set by -nocase. */
  264. + boolean case_insensitive;
  265.   #ifdef DEBUG_STAT
  266.   int
  267.   debug_stat (file, bufp)
  268. ***************
  269. *** 135,140 ****
  270. --- 139,145 ----
  271.     no_leaf_check = false;
  272.     stay_on_filesystem = false;
  273.     exit_status = 0;
  274. +   case_insensitive = false;
  275.   #ifdef DEBUG_STAT
  276.     xstat = debug_stat;
  277.   #else /* !DEBUG_STAT */
  278. *** find/defs.h-dist    Tue Jul 14 00:21:55 1992
  279. --- find/defs.h    Mon Aug 24 21:56:07 1992
  280. ***************
  281. *** 201,203 ****
  282. --- 201,204 ----
  283.   extern int exit_status;
  284.   extern int path_length;
  285.   extern int (*xstat) ();
  286. + extern boolean case_insensitive;
  287. *** find/parser.c-dist    Mon Jul 13 13:04:31 1992
  288. --- find/parser.c    Mon Aug 24 23:27:54 1992
  289. ***************
  290. *** 98,103 ****
  291. --- 98,104 ----
  292.   boolean parse_name ();
  293.   boolean parse_negate ();
  294.   boolean parse_newer ();
  295. + boolean parse_nocase ();
  296.   boolean parse_noleaf ();
  297.   boolean parse_nogroup ();
  298.   boolean parse_nouser ();
  299. ***************
  300. *** 153,158 ****
  301. --- 154,160 ----
  302.   boolean pred_name ();
  303.   boolean pred_negate ();
  304.   boolean pred_newer ();
  305. + /* no pred_nocase */
  306.   /* no pred_noleaf */
  307.   boolean pred_nogroup ();
  308.   boolean pred_nouser ();
  309. ***************
  310. *** 245,250 ****
  311. --- 247,253 ----
  312.     {"ncpio", parse_ncpio},    /* Unix */
  313.   #endif
  314.     {"newer", parse_newer},
  315. +   {"nocase", parse_nocase},    /* GNU (nocase patch - sg) */
  316.     {"noleaf", parse_noleaf},    /* GNU */
  317.     {"nogroup", parse_nogroup},
  318.     {"nouser", parse_nouser},
  319. ***************
  320. *** 768,773 ****
  321. --- 771,785 ----
  322.     our_pred->args.time = stat_newer.st_mtime;
  323.     (*arg_ptr)++;
  324.     return (true);
  325. + }
  326. + boolean
  327. + parse_nocase (argv, arg_ptr)
  328. +      char *argv[];
  329. +      int *arg_ptr;
  330. + {
  331. +   case_insensitive = true;
  332. +   return true;
  333.   }
  334.   
  335.   boolean
  336. *** man/find.1-dist    Tue May 12 04:43:31 1992
  337. --- man/find.1    Mon Aug 24 23:41:15 1992
  338. ***************
  339. *** 53,58 ****
  340. --- 53,61 ----
  341.   Do not apply any tests or actions at levels less than \fIlevels\fR (a
  342.   non-negative integer).  `\-mindepth 1' means process all files except
  343.   the command line arguments.
  344. + .IP \-nocase
  345. + Shell patterns used with \-name, \-lname, and \-path are matched without
  346. + regard to case.
  347.   .IP "\-noleaf"
  348.   Do not optimize by assuming that directories contain 2 fewer
  349.   subdirectories than their hard link count.  Each directory on a normal
  350.  
  351.  
  352. -- 
  353. Skip Gilbrech            email:    skip@fsg.com
  354. Fusion Systems Group            uupsi!fsg!skip
  355. 225 Broadway, 24th Floor        uupsi!skipnyc!skip
  356. New York, NY 10007        phones:    212-285-8001 (work)
  357.                     201-825-8732 (home)
  358.  
  359.