New $(lastword ) built-in function: implementation, documentation and tests.
authorBoris Kolpackov <boris@kolpackov.net>
Thu, 21 Oct 2004 17:42:24 +0000 (17:42 +0000)
committerBoris Kolpackov <boris@kolpackov.net>
Thu, 21 Oct 2004 17:42:24 +0000 (17:42 +0000)
ChangeLog
doc/make.texi
function.c
tests/ChangeLog
tests/scripts/functions/word

index fd5aaa3..37df6bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-10-21  Boris Kolpackov  <boris@kolpackov.net>
+
+       * function.c (func_lastword): New function: return last word
+       from the list of words.
+       * doc/make.texi: Document $(lastword ). Fix broken links in
+       Quick Reference section.
+
 2004-10-06  Paul D. Smith  <psmith@gnu.org>
 
        Apply patch from Alessandro Vesely, provided with bug # 9748.
index e694068..a31c3ad 100644 (file)
@@ -1239,11 +1239,11 @@ If a makefile named @code{Makefile} has this content:
 
 @example
 @group
-name1 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+name1 := $(lastword $(MAKEFILE_LIST))
 
 include inc.mk
 
-name2 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+name2 := $(lastword $(MAKEFILE_LIST))
 
 all:
         @@echo name1 = $(name1)
@@ -5963,8 +5963,28 @@ $(firstword foo bar)
 produces the result @samp{foo}.  Although @code{$(firstword
 @var{text})} is the same as @code{$(word 1,@var{text})}, the
 @code{firstword} function is retained for its simplicity.@refill
+
+
+@item $(lastword @var{names}@dots{})
+@findex lastword
+@cindex words, extracting last
+The argument @var{names} is regarded as a series of names, separated
+by whitespace.  The value is the last name in the series.
+
+For example,
+
+@example
+$(lastword foo bar)
+@end example
+
+@noindent
+produces the result @samp{bar}.  Although @code{$(lastword
+@var{text})} is the same as @code{$(word $(words @var{text}),@var{text})},
+the @code{lastword} function was added for its simplicity and better
+performance.@refill
 @end table
 
+
 Here is a realistic example of the use of @code{subst} and
 @code{patsubst}.  Suppose that a makefile uses the @code{VPATH} variable
 to specify a list of directories that @code{make} should search for
@@ -9636,7 +9656,7 @@ Remove all search paths previously specified in any @code{vpath}
 directive.
 @end table
 
-Here is a summary of the text manipulation functions (@pxref{Functions}):
+Here is a summary of the built-in functions (@pxref{Functions}):
 
 @table @code
 @item $(subst @var{from},@var{to},@var{text})
@@ -9667,6 +9687,26 @@ Select words in @var{text} that @emph{do not} match any of the @var{pattern} wor
 Sort the words in @var{list} lexicographically, removing duplicates.@*
 @xref{Text Functions, , Functions for String Substitution and Analysis}.
 
+@item $(word @var{n},@var{text})
+Extract the @var{n}th word (one-origin) of @var{text}.@*
+@xref{Text Functions, , Functions for String Substitution and Analysis}.
+
+@item $(words @var{text})
+Count the number of words in @var{text}.@*
+@xref{Text Functions, , Functions for String Substitution and Analysis}.
+
+@item $(wordlist @var{s},@var{e},@var{text})
+Returns the list of words in @var{text} from @var{s} to @var{e}.@*
+@xref{Text Functions, , Functions for String Substitution and Analysis}.
+
+@item $(firstword @var{names}@dots{})
+Extract the first word of @var{names}.@*
+@xref{Text Functions, , Functions for String Substitution and Analysis}.
+
+@item $(lastword @var{names}@dots{})
+Extract the last word of @var{names}.@*
+@xref{Text Functions, , Functions for String Substitution and Analysis}.
+
 @item $(dir @var{names}@dots{})
 Extract the directory part of each file name.@*
 @xref{File Name Functions, ,Functions for File Names}.
@@ -9695,22 +9735,6 @@ Prepend @var{prefix} to each word in @var{names}.@*
 Join two parallel lists of words.@*
 @xref{File Name Functions, ,Functions for File Names}.
 
-@item $(word @var{n},@var{text})
-Extract the @var{n}th word (one-origin) of @var{text}.@*
-@xref{File Name Functions, ,Functions for File Names}.
-
-@item $(words @var{text})
-Count the number of words in @var{text}.@*
-@xref{File Name Functions, ,Functions for File Names}.
-
-@item $(wordlist @var{s},@var{e},@var{text})
-Returns the list of words in @var{text} from @var{s} to @var{e}.@*
-@xref{File Name Functions, ,Functions for File Names}.
-
-@item $(firstword @var{names}@dots{})
-Extract the first word of @var{names}.@*
-@xref{File Name Functions, ,Functions for File Names}.
-
 @item $(wildcard @var{pattern}@dots{})
 Find file names matching a shell file name pattern (@emph{not} a
 @samp{%} pattern).@*
index 54f5445..ed5cc44 100644 (file)
@@ -667,6 +667,22 @@ func_firstword (char *o, char **argv, const char *funcname UNUSED)
   return o;
 }
 
+static char *
+func_lastword (char *o, char **argv, const char *funcname UNUSED)
+{
+  unsigned int i;
+  char *words = argv[0];    /* Use a temp variable for find_next_token */
+  char *p = 0;
+  char *t;
+
+  while ((t = find_next_token (&words, &i)))
+    p = t;
+
+  if (p != 0)
+    o = variable_buffer_output (o, p, i);
+
+  return o;
+}
 
 static char *
 func_words (char *o, char **argv, const char *funcname UNUSED)
@@ -1754,6 +1770,7 @@ static struct function_table_entry function_table_init[] =
   { STRING_SIZE_TUPLE("findstring"),    2,  2,  1,  func_findstring},
   { STRING_SIZE_TUPLE("firstword"),     0,  1,  1,  func_firstword},
   { STRING_SIZE_TUPLE("join"),          2,  2,  1,  func_join},
+  { STRING_SIZE_TUPLE("lastword"),      0,  1,  1,  func_lastword},
   { STRING_SIZE_TUPLE("patsubst"),      3,  3,  1,  func_patsubst},
   { STRING_SIZE_TUPLE("shell"),         0,  1,  1,  func_shell},
   { STRING_SIZE_TUPLE("sort"),          0,  1,  1,  func_sort},
index f1c59d6..8cc25db 100644 (file)
@@ -1,3 +1,7 @@
+2004-10-21  Boris Kolpackov  <boris@kolpackov.net>
+
+       * scripts/functions/word: Test $(firstword ) and $(lastword ).
+
 2004-10-05  Boris Kolpackov  <boris@kolpackov.net>
 
        * scripts/features/patspecific_vars: Test simple/recursive
index 5083cec..398cd65 100644 (file)
@@ -1,5 +1,6 @@
 #                                                                    -*-perl-*-
-$description = "Test the word, words, and wordlist functions.\n";
+$description = "\
+Test the word, words, wordlist, firstword, and lastword functions.\n";
 
 $details = "\
 Produce a variable with a large number of words in it,
@@ -87,5 +88,41 @@ $answer = "$makefile2:8: *** non-numeric first argument to `wordlist' function:
 $answer = "$makefile2:9: *** non-numeric second argument to `wordlist' function: ' 12a '.  Stop.\n";
 &compare_output($answer, &get_logfile(1));
 
+
+# TEST #8 -- test $(firstword )
+#
+run_make_test('
+void :=
+list := $(void) foo bar baz #
+
+a := $(word 1,$(list))
+b := $(firstword $(list))
+
+.PHONY: all
+
+all:
+       @test "$a" = "$b" && echo $a
+',
+'',
+'foo');
+
+
+# TEST #9 -- test $(lastword )
+#
+run_make_test('
+void :=
+list := $(void) foo bar baz #
+
+a := $(word $(words $(list)),$(list))
+b := $(lastword $(list))
+
+.PHONY: all
+
+all:
+       @test "$a" = "$b" && echo $a
+',
+'',
+'baz');
+
 # This tells the test driver that the perl test script executed properly.
 1;