From 547abfa13e2037c0461e3965911f5322737f2bda Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 21 Oct 2004 17:42:24 +0000 Subject: [PATCH] New $(lastword ) built-in function: implementation, documentation and tests. --- ChangeLog | 7 +++++ doc/make.texi | 62 ++++++++++++++++++++++++++++++-------------- function.c | 17 ++++++++++++ tests/ChangeLog | 4 +++ tests/scripts/functions/word | 39 +++++++++++++++++++++++++++- 5 files changed, 109 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd5aaa3..37df6bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-10-21 Boris Kolpackov + + * 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 Apply patch from Alessandro Vesely, provided with bug # 9748. diff --git a/doc/make.texi b/doc/make.texi index e694068..a31c3ad 100644 --- a/doc/make.texi +++ b/doc/make.texi @@ -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).@* diff --git a/function.c b/function.c index 54f5445..ed5cc44 100644 --- a/function.c +++ b/function.c @@ -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}, diff --git a/tests/ChangeLog b/tests/ChangeLog index f1c59d6..8cc25db 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2004-10-21 Boris Kolpackov + + * scripts/functions/word: Test $(firstword ) and $(lastword ). + 2004-10-05 Boris Kolpackov * scripts/features/patspecific_vars: Test simple/recursive diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word index 5083cec..398cd65 100644 --- a/tests/scripts/functions/word +++ b/tests/scripts/functions/word @@ -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; -- 2.7.4