Make it easier to find modules. New gnulib-tool option '--find'.
authorBruno Haible <bruno@clisp.org>
Fri, 19 Feb 2010 10:54:07 +0000 (11:54 +0100)
committerBruno Haible <bruno@clisp.org>
Fri, 19 Feb 2010 10:54:07 +0000 (11:54 +0100)
ChangeLog
doc/gnulib-tool.texi
gnulib-tool

index 1137dba..9d3367e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-19  Bruno Haible  <bruno@clisp.org>
+
+       Make it easier to find modules. New gnulib-tool option '--find'.
+       * gnulib-tool: New option --find.
+       (func_usage): Document it.
+       (func_sanitize_modulelist): New function, extracted from
+       func_all_modules.
+       (func_all_modules): Invoke it.
+       * doc/gnulib-tool.texi (Which modules?): New node.
+
 2010-02-18  Markus Duft <mduft@gentoo.org>  (tiny change)
 
        * lib/sys_select.in.h: Provide select replacement even if
index b80d3c5..9a597e1 100644 (file)
@@ -39,6 +39,7 @@ some commands with the option @samp{--dry-run}; then
 a real run without changing anything.
 
 @menu
+* Which modules?::              Determining the needed set of Gnulib modules
 * Initial import::              First import of Gnulib modules.
 * Modified imports::            Changing the import specification.
 * Simple update::               Tracking Gnulib development.
@@ -50,6 +51,32 @@ a real run without changing anything.
 @end menu
 
 
+@node Which modules?
+@section Finding modules
+@cindex Finding modules
+
+There are three ways of finding the names of Gnulib modules that you can use
+in your package:
+
+@itemize
+@item
+You have the complete module list, sorted according to categories, in
+@url{http://www.gnu.org/software/gnulib/MODULES.html}.
+
+@item
+If you are looking for a particular POSIX header or function replacement,
+look in the chapters @ref{Header File Substitutes} and
+@ref{Function Substitutes}.  For headers and functions that are provided by
+Glibc but not standardized by POSIX, look in the chapters
+@ref{Glibc Header File Substitutes} and @ref{Glibc Function Substitutes}.
+
+@item
+If you have already found the source file in Gnulib and are looking for the
+module that contains this source file, you can use the command
+@samp{gnulib-tool --find @var{filename}}.
+@end itemize
+
+
 @node Initial import
 @section Initial import
 @cindex initial import
index 7c2efc6..ef2bd46 100755 (executable)
@@ -117,6 +117,7 @@ func_usage ()
 {
   echo "\
 Usage: gnulib-tool --list
+       gnulib-tool --find filename
        gnulib-tool --import [module1 ... moduleN]
        gnulib-tool --update
        gnulib-tool --create-testdir --dir=directory [module1 ... moduleN]
@@ -140,6 +141,7 @@ Usage: gnulib-tool --list
 
 Operation modes:
       --list                print the available module names
+      --find                find the modules which contain the specified file
       --import              import the given modules into the current package;
                             if no modules are specified, update the current
                             package from the current gnulib
@@ -901,6 +903,9 @@ fi
       --list | --lis )
         mode=list
         shift ;;
+      --find | --fin | --fi | --f )
+        mode=find
+        shift ;;
       --import | --impor | --impo | --imp | --im | --i )
         mode=import
         shift ;;
@@ -1291,6 +1296,23 @@ func_lookup_file ()
   fi
 }
 
+# func_sanitize_modulelist
+# receives a list of possible module names on standard input, one per line.
+# It removes those which are just file names unrelated to modules, and outputs
+# the resulting list to standard output, one per line.
+func_sanitize_modulelist ()
+{
+  sed -e '/^CVS\//d' -e '/\/CVS\//d' \
+      -e '/^ChangeLog$/d' -e '/\/ChangeLog$/d' \
+      -e '/^COPYING$/d' -e '/\/COPYING$/d' \
+      -e '/^README$/d' -e '/\/README$/d' \
+      -e '/^TEMPLATE$/d' \
+      -e '/^TEMPLATE-EXTENDED$/d' \
+      -e '/^TEMPLATE-TESTS$/d' \
+      -e '/^\..*/d' \
+      -e '/~$/d'
+}
+
 # func_all_modules
 # Input:
 # - local_gnulib_dir  from --local-dir
@@ -1305,15 +1327,7 @@ func_all_modules ()
       (cd "$local_gnulib_dir" && find modules -type f -print | sed -e 's,^modules/,,' -e 's,\.diff$,,')
     fi
   } \
-      | sed -e '/^CVS\//d' -e '/\/CVS\//d' \
-            -e '/^ChangeLog$/d' -e '/\/ChangeLog$/d' \
-            -e '/^COPYING$/d' -e '/\/COPYING$/d' \
-            -e '/^README$/d' -e '/\/README$/d' \
-            -e '/^TEMPLATE$/d' \
-            -e '/^TEMPLATE-EXTENDED$/d' \
-            -e '/^TEMPLATE-TESTS$/d' \
-            -e '/^\..*/d' \
-            -e '/~$/d' \
+      | func_sanitize_modulelist \
       | sed -e '/-tests$/d' \
       | LC_ALL=C sort -u
 }
@@ -4997,6 +5011,39 @@ case $mode in
     func_all_modules
     ;;
 
+  find )
+    # sed expression that converts a literal to a basic regular expression.
+    # Needs to handle . [ \ * ^ $.
+    sed_literal_to_basic_regex='s/\\/\\\\/g
+s/\[/\\[/g
+s/\^/\\^/g
+s/\([.*$]\)/[\1]/g'
+    for filename
+    do
+      if test -f "$gnulib_dir/$filename" \
+         || { test -n "$local_gnulib_dir" && test -f "$local_gnulib_dir/$filename"; }; then
+        filenameregex='^'`echo "$filename" | sed -e "$sed_literal_to_basic_regex"`'$'
+        module_candidates=`
+          {
+            (cd "$gnulib_dir" && find modules -type f -print | xargs -n 100 grep -l "$filenameregex" /dev/null | sed -e 's,^modules/,,')
+            if test -n "$local_gnulib_dir" && test -d "$local_gnulib_dir/modules"; then
+              (cd "$local_gnulib_dir" && find modules -type f -print | sed -e 's,^modules/,,' -e 's,\.diff$,,')
+            fi
+          } \
+            | func_sanitize_modulelist \
+            | LC_ALL=C sort -u
+          `
+        for module in $module_candidates; do
+          if func_get_filelist $module | grep "$filenameregex" > /dev/null; then
+            echo $module
+          fi
+        done
+      else
+        func_warning "file $filename does not exist"
+      fi
+    done
+    ;;
+
   import | update )
 
     # Where to import.