bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/5] gnulib-tool: cache module metainformation.


From: Bruno Haible
Subject: Re: [PATCH 1/5] gnulib-tool: cache module metainformation.
Date: Mon, 8 Feb 2010 01:51:47 +0100
User-agent: KMail/1.9.9

Hi Ralf,

I applied your patches 1, 6, 7, with the modifications below.

Regarding the objections mentioned in
  <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00008.html>:

Ad 1): About 'sed' as a bash built-in: Your func_cache_var function makes
good use of the ${param//pattern/replacement} syntax. We should use more of
this. Anyone going to write a library of reasonably named shell functions
that offer all the various substitutions that you can do with bash built-ins?

Ad 2): About the echo command which appends a newline: I documented the
convention that a field value consisting of n lines has, when stored in a
shell variable, the last newline omitted. When the field value is empty,
the variable is unset. This way, you can distinguish between an empty
value and a single newline.

Ad 3) A sed program with multiple labels and no comments is unmaintainable.
I added comments to the sed program.

Ad 4) Too much 'eval'. I change the code so that 'eval' is *only* ever called
on variable assignments. When I see non-intuitive results like this:

   $ eval test -n ''
   $ echo $?
   0

or when I find myself wondering for long minutes whether I should write

   eval test -n "\"\${${cachevar}_description}\""
or
   eval test -n "\"\${\${cachevar}_description}\""

then I know a red line is crossed. Bottom line: Only use 'eval' on simple
variable assignments.

I rewrote the 'sed' program which processes a module description, because the
original one did not ignore lines that occur before the first field header.
(The non-optimized code ignores such lines, therefore the optimized variant
must do the same. This follows from the principle that optimizations must not
change the behaviour.)

The support of bash associative arrays caused a further reduction in run time.
Time for "./gnulib-tool --create-testdir --with-tests" on my machine:
  With --no-cache-modules:
                                real    1078.825s
                                user     551.782s
                                sys      524.177s
  With --cache-modules and bash 3:
                                real    1515.906s
                                user     899.768s
                                sys      659.965s
  With --cache-modules and bash 4 (has associative arrays):
                                real    1363.068s
                                user     769.792s
                                sys      607.742s

The reason that --cache-modules causes no win at this point is that
func_lookup_cache_module is mostly called from short-lived sub-shells. The
sub-shell cannot propagate the cached results to the parent shell.

So, the next step is to eliminate the subshells.

Btw, while doing these benches, I can confirm your observation that reducing
the number of 'fork()'s done per module in gnulib-tool can greatly increase
the speed.


2010-02-07  Bruno Haible  <address@hidden>

        gnulib-tool: Fix up caching patches.
        * gnulib-tool: New options --cache-modules, --no-cache-modules. Remove
        option --no-cache. Use associative arrays when supported by the shell.
        (sed_comments): New variable.
        (modcache): Renamed from do_cache.
        (sed_extract_field_header): Renamed from sed_extract_cache_prog. Don't
        abbreviate unnecessarily.
        (have_associative): New variable.
        (func_cache_var): Define correctly for bash 1.x. Define in an optimized
        way also for ksh and zsh.
        (func_init_sed_convert_to_cache_statements): New function, extracted
        from func_cache_lookup_module. Add support for associative arrays.
        Don't set the c_MODULE_cached variable here. Ignore all lines before
        the first field header. Remove only the final newline, not all trailing
        newlines. Support empty fields correctly. Limit the use of 'eval' to
        assignments.
        (func_get_description, func_get_status, func_get_notice,
        func_get_applicability, func_get_filelist, func_get_dependencies,
        func_get_autoconf_early_snippet, func_get_autoconf_snippet,
        func_get_automake_snippet, func_get_include_directive,
        func_get_link_directive, func_get_license, func_get_maintainer):
        Update documentation. List the unoptimized code first. Add support for
        associative arrays. Limit the use of 'eval' to assignments.
        (func_get_applicability): Undo stylistic pessimisations.
        (func_get_automake_snippet, func_get_include_directive): Reduce code
        duplication.
        (func_modules_transitive_closure, func_modules_add_dummy,
        func_modules_notice, func_modules_to_filelist, func_add_file,
        func_update_file, func_emit_lib_Makefile_am, func_emit_po_Makevars,
        func_emit_po_POTFILES_in, func_emit_tests_Makefile_am, func_import,
        func_create_testdir, func_create_megatestdir): Update documentation.

*** gnulib-tool.orig    Mon Feb  8 01:06:47 2010
--- gnulib-tool Mon Feb  8 00:45:41 2010
***************
*** 100,105 ****
--- 100,116 ----
  # An empty expression does not work with the native 'sed' on AIX 6.1.
  sed_noop='s,x,x,'
  
+ # sed_comments is true or false, depending whether 'sed' supports comments.
+ # (The GNU autoconf doc says that sed comments are not portable, but does
+ # not say which 'sed' versions are affected.)
+ if echo fo | sed -e 's/f/g/
+ # s/o/u/
+ s/o/e/' 2>/dev/null | grep ge > /dev/null; then
+   sed_comments=true
+ else
+   sed_comments=false
+ fi
+ 
  # func_usage
  # outputs to stdout the --help usage message.
  func_usage ()
***************
*** 163,171 ****
                              directory.
        --local-dir=DIRECTORY  Specify a local override directory where to look
                              up files before looking in gnulib's directory.
        --verbose             Increase verbosity. May be repeated.
        --quiet               Decrease verbosity. May be repeated.
-       --no-cache            Disable module caching optimization.
  
  Options for --import:
        --lib=LIBRARY         Specify the library name.  Defaults to 'libgnu'.
--- 174,183 ----
                              directory.
        --local-dir=DIRECTORY  Specify a local override directory where to look
                              up files before looking in gnulib's directory.
+       --cache-modules       Enable module caching optimization.
+       --no-cache-modules    Disable module caching optimization.
        --verbose             Increase verbosity. May be repeated.
        --quiet               Decrease verbosity. May be repeated.
  
  Options for --import:
        --lib=LIBRARY         Specify the library name.  Defaults to 'libgnu'.
***************
*** 826,831 ****
--- 838,844 ----
  # - mode            list or import or create-testdir or create-megatestdir
  # - destdir         from --dir
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - verbose         integer, default 0, inc/decremented by --verbose/--quiet
  # - libname, supplied_libname  from --lib
  # - sourcebase      from --source-base
***************
*** 856,863 ****
    mode=
    destdir=
    local_gnulib_dir=
    verbose=0
-   do_cache=:
    libname=libgnu
    supplied_libname=
    sourcebase=
--- 869,876 ----
    mode=
    destdir=
    local_gnulib_dir=
+   modcache=true
    verbose=0
    libname=libgnu
    supplied_libname=
    sourcebase=
***************
*** 932,946 ****
        --local-dir=* )
          local_gnulib_dir=`echo "X$1" | sed -e 's/^X--local-dir=//'`
          shift ;;
        --verbose | --verbos | --verbo | --verb )
          verbose=`expr $verbose + 1`
          shift ;;
        --quiet | --quie | --qui | --qu | --q )
          verbose=`expr $verbose - 1`
          shift ;;
-       --no-cache | --no-cach | --no-cac | --no-ca )
-         do_cache=false
-         shift ;;
        --lib )
          shift
          if test $# = 0; then
--- 945,962 ----
        --local-dir=* )
          local_gnulib_dir=`echo "X$1" | sed -e 's/^X--local-dir=//'`
          shift ;;
+       --cache-modules | --cache-module | --cache-modul | --cache-modu | 
--cache-mod | --cache-mo | --cache-m | --cache- | --cache | --cach | --cac | 
--ca )
+         modcache=true
+         shift ;;
+       --no-cache-modules | --no-cache-module | --no-cache-modul | 
--no-cache-modu | --no-cache-mod | --no-cache-mo | --no-cache-m | --no-cache- | 
--no-cache | --no-cach | --no-cac | --no-ca )
+         modcache=false
+         shift ;;
        --verbose | --verbos | --verbo | --verb )
          verbose=`expr $verbose + 1`
          shift ;;
        --quiet | --quie | --qui | --qu | --q )
          verbose=`expr $verbose - 1`
          shift ;;
        --lib )
          shift
          if test $# = 0; then
***************
*** 1354,1417 ****
    esac
  }
  
! # func_cache_var file
! #
! # return the cache variable name corresponding to $file.
! # Output:
! # - cachevar
! if test -n "$BASH_VERSION"; then
!   func_cache_var ()
!   {
!     cachevar=c_${1//[!a-zA-Z0-9_]/_}
!   }
! else
!   func_cache_var ()
!   {
!     case $1 in
!       *[!a-zA-Z0-9_]*)
!         cachevar=c_`echo "$1" | LC_ALL=C sed 's/[^a-zA-Z0-9_]/_/g'` ;;
!       *)
!         cachevar=c_$1 ;;
!     esac
!   }
! fi
  
! # Extract headers from module descriptions.
! # NOTE: Keep this in sync with sed_extract_prog below!
! sed_extract_cache_prog="
!   s/^Description:[     ]*$/desc/
    s/^Status:[  ]*$/status/
    s/^Notice:[  ]*$/notice/
    s/^Applicability:[   ]*$/applicability/
    s/^Files:[   ]*$/files/
!   s/^Depends-on:[      ]*$/deps/
!   s/^configure\.ac-early:[     ]*$/config_early/
!   s/^configure\.ac:[   ]*$/config/
    s/^Makefile\.am:[    ]*$/makefile/
    s/^Include:[         ]*$/include/
    s/^Link:[    ]*$/link/
    s/^License:[         ]*$/license/
!   s/^Maintainer:[      ]*$/maint/"
  
! # func_cache_lookup_module file
! #
! # look up a module, like 'func_lookup_file modules/$file', and store all of 
its
! # relevant data in a cache.  If already cached, do not look it up again.
! # Input:
! # - file
! # Output:
! # - cachevar
! # - ${cachevar}_cached
! # - ${cachevar}_desc
! # - ${cachevar}_status
! # - ...
! func_cache_lookup_module ()
! {
!   func_cache_var "$1"
!   if eval test -z \"\$${cachevar}_cached\"; then
!     func_lookup_file "modules/$1"
!     # Turn module descriptions into shell script assignments,
!     # suitable to be eval'ed.  All active characters are escaped.
      # This script turns
      #   Description:
      #   Some module's description
--- 1370,1484 ----
    esac
  }
  
! # Suffix of a sed expression that extracts a particular field from a
! # module description.
! # A field starts with a line that contains a keyword, such as 'Description',
! # followed by a colon and optional whitespace. All following lines, up to
! # the next field (or end of file if there is none) form the contents of the
! # field.
! # An absent field is equivalent to a field with empty contents.
! # NOTE: Keep this in sync with sed_extract_cache_prog below!
! sed_extract_prog=':[   ]*$/ {
!   :a
!     n
!     s/^Description:[   ]*$//
!     s/^Status:[        ]*$//
!     s/^Notice:[        ]*$//
!     s/^Applicability:[         ]*$//
!     s/^Files:[         ]*$//
!     s/^Depends-on:[    ]*$//
!     s/^configure\.ac-early:[   ]*$//
!     s/^configure\.ac:[         ]*$//
!     s/^Makefile\.am:[  ]*$//
!     s/^Include:[       ]*$//
!     s/^Link:[  ]*$//
!     s/^License:[       ]*$//
!     s/^Maintainer:[    ]*$//
!     tb
!     p
!     ba
!   :b
! }'
  
! # Piece of a sed expression that converts a field header line to a shell
! # variable name,
! # NOTE: Keep this in sync with sed_extract_prog above!
! sed_extract_field_header='
!   s/^Description:[     ]*$/description/
    s/^Status:[  ]*$/status/
    s/^Notice:[  ]*$/notice/
    s/^Applicability:[   ]*$/applicability/
    s/^Files:[   ]*$/files/
!   s/^Depends-on:[      ]*$/dependson/
!   s/^configure\.ac-early:[     ]*$/configureac_early/
!   s/^configure\.ac:[   ]*$/configureac/
    s/^Makefile\.am:[    ]*$/makefile/
    s/^Include:[         ]*$/include/
    s/^Link:[    ]*$/link/
    s/^License:[         ]*$/license/
!   s/^Maintainer:[      ]*$/maintainer/'
  
! if $modcache; then
! 
!   # Note: The 'eval' silences stderr output in dash.
!   if declare -A x 2>/dev/null && { x[f/2]='foo'; x[f/3]='bar'; eval test 
'${x[f/2]}' = foo; }; then
!     # Zsh 4 and Bash 4 have associative arrays.
!     have_associative=true
!   else
!     # For other shells, use 'eval' with computed shell variable names.
!     have_associative=false
!   fi
! 
!   if $have_associative; then
! 
!     # Declare the associative arrays.
!     declare -A modcache_cached
!     sed_to_declare_statement='s|^.*/\([a-zA-Z0-9_]*\)/$|declare -A 
modcache_\1|p'
!     declare_script=`echo "$sed_extract_field_header" | sed -n -e 
"$sed_to_declare_statement"`
!     eval "$declare_script"
! 
!   else
! 
!     # func_cache_var module
!     # computes the cache variable name corresponding to $module.
!     # Note: This computation can map different module names to the same
!     # cachevar (such as 'foo-bar', 'foo_bar', or 'foo/bar'); the caller has
!     # to protect against this case.
!     # Output:
!     # - cachevar               a shell variable name
!     if (f=foo; eval echo '${f//o/e}') < /dev/null 2>/dev/null | grep fee 
>/dev/null; then
!       # Bash 2.0 and newer, ksh, and zsh support the syntax
!       #   ${param//pattern/replacement}
!       # as a shorthand for
!       #   `echo "$param" | sed -e "s/pattern/replacement/g"`.
!       # Note: The 'eval' above silences stderr output in dash.
!       func_cache_var ()
!       {
!         cachevar=c_${1//[!a-zA-Z0-9_]/_}
!       }
!     else
!       func_cache_var ()
!       {
!         case $1 in
!           *[!a-zA-Z0-9_]*)
!             cachevar=c_`echo "$1" | LC_ALL=C sed -e 's/[^a-zA-Z0-9_]/_/g'` ;;
!           *)
!             cachevar=c_$1 ;;
!         esac
!       }
!     fi
! 
!   fi
! 
!   # func_init_sed_convert_to_cache_statements
!   # Input:
!   # - modcachevar_assignment
!   # Output:
!   # - sed_convert_to_cache_statements
!   func_init_sed_convert_to_cache_statements ()
!   {
!     # 'sed' script that turns a module description into shell script
!     # assignments, suitable to be eval'ed.  All active characters are escaped.
      # This script turns
      #   Description:
      #   Some module's description
***************
*** 1419,1579 ****
      #   Files:
      #   lib/file.h
      # into:
!     #   c_MODULE_cached='yes
      #   '
!     #   c_MODULE_desc=\
!     #   'Some module'\''s description
!     #
      #   '
!     #   c_MODULE_files=\
      #   'lib/file.h'
!     # The script consists of four parts:
!     # 1) Insert the "c_MODULE_cached='yes" line,
!     # 2) The 'match' loop, treating non-header lines by escaping single
!     #    quotes and adding a closing quote in the last line,
!     # 3) The 'header' treatment, closing the last quote and inserting
!     #    the "c_MODULE_HEADER=" assignment line as well starting the
!     #    following line with an opening quote, if any.
!     # 4) Special treatment if two headers are only separated by one newline.
!     sed_cache_module='
!       1i\'$nl$cachevar'_name='\'$1\'\\$nl$cachevar'_cached='\''yes\'$nl'
! 
!       :match
!       t match
!       '"$sed_extract_cache_prog"'
!       t hdr
!       s/'\''/&"'\''"&/g
!       :more
!       $s/$/'\''/
!       n
!       b match
  
!       :hdr
!       s/\([a-zA-Z0-9_]\{1,\}\)[        ]*$/'\'\\$nl${cachevar}_'\1=/
!       $!s/$/\\/
!       n
!       t clear
!       :clear
!       '"$sed_extract_cache_prog"'
!       t hdr2
!       s/'\''/&"'\''"&/g
!       s/^/'\''/
!       b more
! 
!       :hdr2
!       s/^/'\'\\$nl'/
!       b hdr
!       '
!     # Strip trailing newlines from quoted variable assignment strings.
!     sed_strip_trailing_nl='
!       :more
!       $b cut
!       /\\$/{
          p
!         d
!       }
!       N
!       /\n$/b more
!       :cut
!       s/\n\n*\('\''\)$/\1/
!       '
!     cache_script=`sed "$sed_cache_module" < "$lookedup_file" \
!                     | sed "$sed_strip_trailing_nl"`
!     eval "$cache_script"
!   else
!     if eval test "$1" != \"\$${cachevar}_name\"; then
!       eval 'func_fatal_error "cache variable collision: $1 and 
$'${cachevar}'_name"'
      fi
!   fi
! }
  
! # Extract headers from module descriptions, without caching.
! # NOTE: Keep this in sync with sed_extract_cache_prog above!
! sed_extract_prog=':[   ]*$/ {
!   :a
!     n
!     s/^Description:[   ]*$//
!     s/^Status:[        ]*$//
!     s/^Notice:[        ]*$//
!     s/^Applicability:[         ]*$//
!     s/^Files:[         ]*$//
!     s/^Depends-on:[    ]*$//
!     s/^configure\.ac-early:[   ]*$//
!     s/^configure\.ac:[         ]*$//
!     s/^Makefile\.am:[  ]*$//
!     s/^Include:[       ]*$//
!     s/^Link:[  ]*$//
!     s/^License:[       ]*$//
!     s/^Maintainer:[    ]*$//
!     tb
!     p
!     ba
!   :b
! }'
  
  
  # func_get_description module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_description ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_desc\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Description$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_status module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_status ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_status\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Status$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_notice module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_notice ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_notice\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Notice$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_applicability module
  # Input:
  # - local_gnulib_dir  from --local-dir
  # The expected result (on stdout) is either 'main', or 'tests', or 'all'.
  func_get_applicability ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval my_applicability=\$${cachevar}_applicability
!   else
      func_lookup_file "modules/$1"
      my_applicability=`sed -n -e "/^Applicability$sed_extract_prog" < 
"$lookedup_file"`
    fi
    if test -n "$my_applicability"; then
      echo $my_applicability
    else
      # The default is 'main' or 'tests', depending on the module's name.
      case $1 in
!       *-tests) echo tests;;
!       *)       echo main;;
      esac
    fi
  }
--- 1486,1780 ----
      #   Files:
      #   lib/file.h
      # into:
!     #   modcache_description[$1]=\
!     #   'Some module'"'"'s description
      #   '
!     #   modcache_files[$1]=\
!     #   'lib/file.h'
!     # or:
!     #   c_MODULE_description_set=set; c_MODULE_description=\
!     #   'Some module'"'"'s description
      #   '
!     #   c_MODULE_files_set=set; c_MODULE_files=\
      #   'lib/file.h'
!     # The script consists of two parts:
!     # 1) Ignore the lines before the first field header.
!     # 2) A loop, treating non-field-header lines by escaping single quotes
!     #    and adding a closing quote in the last line,
!     sed_convert_to_cache_statements="
!       :llla
!         # Here we have not yet seen a field header.
! 
!         # See if the current line contains a field header.
!         t llla1
!         :llla1
!         ${sed_extract_field_header}
!         t lllb
! 
!         # No field header. Ignore the line.
! 
!         # Read the next line. Upon EOF, just exit.
!         n
!       b llla
! 
!       :lllb
!         # The current line contains a field header.
! 
!         # Turn it into the beginning of an assignment.
!         s/^\\(.*\\)\$/${modcachevar_assignment}\\\\/
! 
!         # Move it to the hold space. Don't print it yet,
!         # because we want no assignment if the field is empty.
!         h
! 
!         # Read the next line.
!         # Upon EOF, the field was empty. Print no assignment. Just exit.
!         n
! 
!         # See if the current line contains a field header.
!         t lllb1
!         :lllb1
!         ${sed_extract_field_header}
!         # If it is, the previous field was empty. Print no assignment.
!         t lllb
  
!         # Not a field header.
! 
!         # Print the previous line, held in the hold space.
!         x
          p
!         x
! 
!         # Transform single quotes.
!         s/'/'\"'\"'/g
! 
!         # Prepend a single quote.
!         s/^/'/
! 
!         :lllc
! 
!           # Move it to the hold space.
!           h
! 
!           # Read the next line.
!           # Upon EOF, branch.
!           \${
!             b llle
!           }
!           n
! 
!           # See if the current line contains a field header.
!           t lllc1
!           :lllc1
!           ${sed_extract_field_header}
!           t llld
! 
!           # Print the previous line, held in the hold space.
!           x
!           p
!           x
! 
!           # Transform single quotes.
!           s/'/'\"'\"'/g
! 
!         b lllc
! 
!         :llld
!         # A field header.
!         # Print the previous line, held in the hold space, with a single quote
!         # to end the assignment.
!         x
!         s/\$/'/
!         p
!         x
! 
!       b lllb
! 
!       :llle
!       # EOF seen.
!       # Print the previous line, held in the hold space, with a single quote
!       # to end the assignment.
!       x
!       s/\$/'/
!       p
!       # Exit.
!       n
!       "
!     if ! $sed_comments; then
!       # Remove comments.
!       sed_convert_to_cache_statements=`echo 
"$sed_convert_to_cache_statements" \
!                                        | sed -e 's/^ *//' -e 's/^#.*//'`
      fi
!   }
  
!   if $have_associative; then
!     # sed_convert_to_cache_statements does not depend on the module.
!     modcachevar_assignment='modcache_\1[$1]='
!     func_init_sed_convert_to_cache_statements
!   fi
! 
!   # func_cache_lookup_module module
!   #
!   # looks up a module, like 'func_lookup_file modules/$module', and stores all
!   # of its relevant data in a cache in the memory of the processing shell.  If
!   # already cached, it does not look it up again, thus saving file access 
time.
!   # Parameters:
!   # - module                             non-empty string
!   # Output if $have_associative:
!   # - modcache_cached[$module]           set to yes
!   # - modcache_description[$module] ==
!   # - modcache_status[$module]        \  set to the field's value, minus the
!   # - ...                             /  final newline,
!   # - modcache_maintainer[$module]  ==   or unset if the field's value is 
empty
!   # Output if ! $have_associative:
!   # - cachevar                           a shell variable name
!   # - ${cachevar}_cached                 set to $module
!   # - ${cachevar}_description       ==
!   # - ${cachevar}_status              \  set to the field's value, minus the
!   # - ...                             /  final newline,
!   # - ${cachevar}_maintainer        ==   or unset if the field's value is 
empty
!   # - ${cachevar}_description_set   ==
!   # - ${cachevar}_status_set          \  set to non-empty if the field's value
!   # - ...                             /  is non-empty,
!   # - ${cachevar}_maintainer_set    ==   or unset if the field's value is 
empty
!   func_cache_lookup_module ()
!   {
!     if $have_associative; then
!       cached=${modcache_cached[$1]}
!     else
!       func_cache_var "$1"
!       eval "cached=\"\$${cachevar}_cached\""
!     fi
!     if test -z "$cached"; then
!       # Not found in cache. Look it up on the file system.
!       func_lookup_file "modules/$1"
!       if $have_associative; then
!         modcache_cached[$1]=yes
!       else
!         eval "${cachevar}_cached=\"\$1\""
!       fi
!       if ! $have_associative; then
!         # sed_convert_to_cache_statements depends on the module.
!         modcachevar_assignment="${cachevar}"'_\1_set=set; '"${cachevar}"'_\1='
!         func_init_sed_convert_to_cache_statements
!       fi
!       cache_statements=`LC_ALL=C sed -n -e "$sed_convert_to_cache_statements" 
< "$lookedup_file"`
!       eval "$cache_statements"
!     else
!       if ! $have_associative; then
!         if test "$1" != "$cached"; then
!           func_fatal_error "cache variable collision between $1 and $cached"
!         fi
!       fi
!     fi
!   }
  
+ fi
  
  # func_get_description module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_description ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Description$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_description[$1]+set}"; then
+         echo "${modcache_description[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_description_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_description\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_status module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_status ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Status$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_status[$1]+set}"; then
+         echo "${modcache_status[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_status_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_status\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_notice module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_notice ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Notice$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_notice[$1]+set}"; then
+         echo "${modcache_notice[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_notice_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_notice\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_applicability module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  # The expected result (on stdout) is either 'main', or 'tests', or 'all'.
  func_get_applicability ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      my_applicability=`sed -n -e "/^Applicability$sed_extract_prog" < 
"$lookedup_file"`
+   else
+     func_cache_lookup_module "$1"
+     # Get the field's value, without the final newline.
+     if $have_associative; then
+       my_applicability="${modcache_applicability[$1]}"
+     else
+       eval "my_applicability=\"\$${cachevar}_applicability\""
+     fi
    fi
    if test -n "$my_applicability"; then
      echo $my_applicability
    else
      # The default is 'main' or 'tests', depending on the module's name.
      case $1 in
!       *-tests) echo "tests";;
!       *)       echo "main";;
      esac
    fi
  }
***************
*** 1581,1594 ****
  # func_get_filelist module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_filelist ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_files\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Files$sed_extract_prog" < "$lookedup_file"
    fi
    echo m4/00gnulib.m4
    echo m4/gnulib-common.m4
--- 1782,1807 ----
  # func_get_filelist module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_filelist ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Files$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_files[$1]+set}"; then
+         echo "${modcache_files[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_files_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_files\""
+         echo "${field_value}"
+       fi
+     fi
    fi
    echo m4/00gnulib.m4
    echo m4/gnulib-common.m4
***************
*** 1649,1654 ****
--- 1862,1868 ----
  # func_get_dependencies module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_dependencies ()
  {
    # ${module}-tests always implicitly depends on ${module}.
***************
*** 1656,1713 ****
      *-tests)
        fgd1="$1"
        func_remove_suffix fgd1 '-tests'
!       module_deps=$fgd1
        ;;
    esac
    # Then the explicit dependencies listed in the module description.
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_deps\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Depends-on$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_autoconf_early_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_autoconf_early_snippet ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_config_early\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^configure\.ac-early$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_autoconf_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_autoconf_snippet ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_config\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^configure\.ac$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_automake_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_automake_snippet ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_makefile\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Makefile\.am$sed_extract_prog" < "$lookedup_file"
    fi
    case "$1" in
      *-tests)
--- 1870,1974 ----
      *-tests)
        fgd1="$1"
        func_remove_suffix fgd1 '-tests'
!       echo "$fgdl"
        ;;
    esac
    # Then the explicit dependencies listed in the module description.
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Depends-on$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_dependson[$1]+set}"; then
+         echo "${modcache_dependson[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_dependson_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_dependson\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_autoconf_early_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_autoconf_early_snippet ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^configure\.ac-early$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_configureac_early[$1]+set}"; then
+         echo "${modcache_configureac_early[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_configureac_early_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_configureac_early\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_autoconf_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_autoconf_snippet ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^configure\.ac$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_configureac[$1]+set}"; then
+         echo "${modcache_configureac[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_configureac_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_configureac\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_automake_snippet module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_automake_snippet ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Makefile\.am$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_makefile[$1]+set}"; then
+         echo "${modcache_makefile[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_makefile_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_makefile\""
+         echo "${field_value}"
+       fi
+     fi
    fi
    case "$1" in
      *-tests)
***************
*** 1731,1747 ****
          ta
        }'
        sed_extract_mentioned_files='s/^lib_SOURCES[     ]*+=[   ]*//p'
!       if $do_cache; then
!         already_mentioned_files=` \
!           { eval 'echo "$'${cachevar}'_makefile"'; echo; } \
!           | sed -e "$sed_combine_lines" \
!           | sed -n -e "$sed_extract_mentioned_files" | sed -e 's/#.*//'`
!       else
!         already_mentioned_files=` \
!           sed -n -e "/^Makefile\.am$sed_extract_prog" < "$lookedup_file" \
!           | sed -e "$sed_combine_lines" \
!           | sed -n -e "$sed_extract_mentioned_files" | sed -e 's/#.*//'`
!       fi
        all_files=`func_get_filelist $1`
        func_filter_filelist lib_files "$nl" "$all_files" 'lib/' '' 'lib/' ''
        # Remove $already_mentioned_files from $lib_files.
--- 1992,2016 ----
          ta
        }'
        sed_extract_mentioned_files='s/^lib_SOURCES[     ]*+=[   ]*//p'
!       already_mentioned_files=` \
!         { if ! $modcache; then
!             sed -n -e "/^Makefile\.am$sed_extract_prog" < "$lookedup_file"
!           else
!             if $have_associative; then
!               if test -n "${modcache_makefile[$1]+set}"; then
!                 echo "${modcache_makefile[$1]}"
!               fi
!             else
!               eval 'field_set="$'"${cachevar}"'_makefile_set"'
!               if test -n "$field_set"; then
!                 eval 'field_value="$'"${cachevar}"'_makefile"'
!                 echo "${field_value}"
!               fi
!             fi
!           fi
!         } \
!         | sed -e "$sed_combine_lines" \
!         | sed -n -e "$sed_extract_mentioned_files" | sed -e 's/#.*//'`
        all_files=`func_get_filelist $1`
        func_filter_filelist lib_files "$nl" "$all_files" 'lib/' '' 'lib/' ''
        # Remove $already_mentioned_files from $lib_files.
***************
*** 1795,1839 ****
  # func_get_include_directive module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_include_directive ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_include\"" | \
!     sed -e 's/^\(["<]\)/#include \1/'
!   else
!     func_lookup_file "modules/$1"
!     sed -n -e "/^Include$sed_extract_prog" < "$lookedup_file" | \
!     sed -e 's/^\(["<]\)/#include \1/'
!   fi
  }
  
  # func_get_link_directive module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_link_directive ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_link\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Link$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
  # func_get_license module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_license ()
  {
    {
!     if $do_cache; then
!       func_cache_lookup_module "$1"
!       eval "echo \"\$${cachevar}_license\""
!     else
        func_lookup_file "modules/$1"
        sed -n -e "/^License$sed_extract_prog" < "$lookedup_file"
      fi
      # The default is GPL.
      echo "GPL"
--- 2064,2144 ----
  # func_get_include_directive module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_include_directive ()
  {
!   {
!     if ! $modcache; then
!       func_lookup_file "modules/$1"
!       sed -n -e "/^Include$sed_extract_prog" < "$lookedup_file"
!     else
!       func_cache_lookup_module "$1"
!       # Output the field's value, including the final newline (if any).
!       if $have_associative; then
!         if test -n "${modcache_include[$1]+set}"; then
!           echo "${modcache_include[$1]}"
!         fi
!       else
!         eval "field_set=\"\$${cachevar}_include_set\""
!         if test -n "$field_set"; then
!           eval "field_value=\"\$${cachevar}_include\""
!           echo "${field_value}"
!         fi
!       fi
!     fi
!   } | sed -e 's/^\(["<]\)/#include \1/'
  }
  
  # func_get_link_directive module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_link_directive ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Link$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_link[$1]+set}"; then
+         echo "${modcache_link[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_link_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_link\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
  # func_get_license module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_license ()
  {
    {
!     if ! $modcache; then
        func_lookup_file "modules/$1"
        sed -n -e "/^License$sed_extract_prog" < "$lookedup_file"
+     else
+       func_cache_lookup_module "$1"
+       # Output the field's value, including the final newline (if any).
+       if $have_associative; then
+         if test -n "${modcache_license[$1]+set}"; then
+           echo "${modcache_license[$1]}"
+         fi
+       else
+         eval "field_set=\"\$${cachevar}_license_set\""
+         if test -n "$field_set"; then
+           eval "field_value=\"\$${cachevar}_license\""
+           echo "${field_value}"
+         fi
+       fi
      fi
      # The default is GPL.
      echo "GPL"
***************
*** 1843,1856 ****
  # func_get_maintainer module
  # Input:
  # - local_gnulib_dir  from --local-dir
  func_get_maintainer ()
  {
!   if $do_cache; then
!     func_cache_lookup_module "$1"
!     eval "echo \"\$${cachevar}_maint\""
!   else
      func_lookup_file "modules/$1"
      sed -n -e "/^Maintainer$sed_extract_prog" < "$lookedup_file"
    fi
  }
  
--- 2148,2173 ----
  # func_get_maintainer module
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache          true or false, from --cache-modules/--no-cache-modules
  func_get_maintainer ()
  {
!   if ! $modcache; then
      func_lookup_file "modules/$1"
      sed -n -e "/^Maintainer$sed_extract_prog" < "$lookedup_file"
+   else
+     func_cache_lookup_module "$1"
+     # Output the field's value, including the final newline (if any).
+     if $have_associative; then
+       if test -n "${modcache_maintainer[$1]+set}"; then
+         echo "${modcache_maintainer[$1]}"
+       fi
+     else
+       eval "field_set=\"\$${cachevar}_maintainer_set\""
+       if test -n "$field_set"; then
+         eval "field_value=\"\$${cachevar}_maintainer\""
+         echo "${field_value}"
+       fi
+     fi
    fi
  }
  
***************
*** 1884,1889 ****
--- 2201,2207 ----
  # func_modules_transitive_closure
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - modules         list of specified modules
  # - inctests        true if tests should be included, blank otherwise
  # - incobsolete     true if obsolete modules among dependencies should be
***************
*** 1943,1948 ****
--- 2261,2267 ----
  # func_modules_add_dummy
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - modules         list of modules, including dependencies
  # Output:
  # - modules         list of modules, including 'dummy' if needed
***************
*** 1984,1989 ****
--- 2303,2309 ----
  # func_modules_notice
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - verbose         integer, default 0, inc/decremented by --verbose/--quiet
  # - modules         list of modules, including dependencies
  func_modules_notice ()
***************
*** 2005,2010 ****
--- 2325,2331 ----
  # func_modules_to_filelist
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - modules         list of modules, including dependencies
  # Output:
  # - files           list of files
***************
*** 2073,2078 ****
--- 2394,2400 ----
  # Input:
  # - destdir         target directory
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - f               the original file name
  # - lookedup_file   name of the merged (combined) file
  # - lookedup_tmp    true if it is located in the tmp directory, blank 
otherwise
***************
*** 2106,2111 ****
--- 2428,2434 ----
  # Input:
  # - destdir         target directory
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - f               the original file name
  # - lookedup_file   name of the merged (combined) file
  # - lookedup_tmp    true if it is located in the tmp directory, blank 
otherwise
***************
*** 2152,2157 ****
--- 2475,2481 ----
  # emits the contents of library makefile to standard output.
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - modules         list of modules, including dependencies
  # - libname         library name
  # - pobase          directory relative to destdir where to place *.po files
***************
*** 2345,2350 ****
--- 2669,2675 ----
  # emits the contents of po/ makefile parameterization to standard output.
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - sourcebase      directory relative to destdir where to place source code
  # - pobase          directory relative to destdir where to place *.po files
  # - po_domain       prefix of i18n domain to use (without -gnulib suffix)
***************
*** 2406,2411 ****
--- 2731,2737 ----
  # emits the file list to be passed to xgettext to standard output.
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - sourcebase      directory relative to destdir where to place source code
  # - files           list of new files
  func_emit_po_POTFILES_in ()
***************
*** 2421,2426 ****
--- 2747,2753 ----
  # emits the contents of tests makefile to standard output.
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - modules         list of modules, including dependencies
  # - libname         library name
  # - auxdir          directory relative to destdir where to place build aux 
files
***************
*** 2735,2740 ****
--- 3062,3068 ----
  # Uses also the variables
  # - destdir         target directory
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - verbose         integer, default 0, inc/decremented by --verbose/--quiet
  # - libname         library name
  # - sourcebase      directory relative to destdir where to place source code
***************
*** 4069,4074 ****
--- 4397,4403 ----
  # func_create_testdir testdir modules
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - auxdir          directory relative to destdir where to place build aux 
files
  func_create_testdir ()
  {
***************
*** 4559,4564 ****
--- 4888,4894 ----
  # func_create_megatestdir megatestdir allmodules
  # Input:
  # - local_gnulib_dir  from --local-dir
+ # - modcache        true or false, from --cache-modules/--no-cache-modules
  # - auxdir          directory relative to destdir where to place build aux 
files
  func_create_megatestdir ()
  {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]