cd /usr/local/src/debian/MSS-modified/PATCHES/make/ diff -u /usr/local/src/debian/MSS-modified/PATCHES/make/function.orig.c /usr/local/src/debian/MSS-modified/PATCHES/make/function.mss.c --- /usr/local/src/debian/MSS-modified/PATCHES/make/function.orig.c 2002-12-12 17:30:17.000000000 -0500 +++ /usr/local/src/debian/MSS-modified/PATCHES/make/function.mss.c 2002-12-15 09:28:26.000000000 -0500 @@ -836,6 +836,89 @@ return o; } +/* +`$(index FIND,IN)' + Searches IN for an occurrence of FIND. If it occurs, the value of the function is + the index of IN in FIND, starting with 1; otherwise, the value is 0. + + Compare the function `findstring'. + + You can use this function in a conditional to test for the presence of a + specific substring in a given string. Thus, the two examples, + + $(index a,a b c) + $(index a,b c) + + produce the values `1' and `0', respectively. + + When $(index $(a), $(x)) is not `0', + $(word $(index $(a), $(x)), $(x)) is always equal to $(a). + + +FIX Make func_word return empty string when passed N=0? Would possibly break + existing code, but would fit better with func_index. + +FIX what about: + $(findstring a,ax a b c) + $(findstring a,xax a b c) + $(index a,ax a b c) + $(index a,xax a b c) + +FIX Expand to regexp and/or glob matching etc. one day. + + */ +static char* +func_index (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + unsigned int i = 0; /* loop counter */ + char *match_string = argv[0]; /* string to match */ + unsigned int matchlen = strlen (argv[0]); /* length of string to match */ + char *word_iterator = argv[1]; /* candidate tokens */ + char *word; /* start of current token */ + unsigned int wordlen; /* length of current token */ + char buf[20]; /* we can deal with a 19-digit result(!) */ + /* FIX shouldn't this be macro constant here and in func_words? */ + + /* FIX + Why is the !=0 always explicit in this file? Programming style, or a necessity? + I include it here for consistency. */ + + /* Loop through the tokens, compare each with the string to match. On a + match, return the value of the loop counter as a string, else return + "0". */ + + /* The first WORD will be the first candidate for matching. */ + while ((word = find_next_token (&word_iterator, &wordlen)) != 0) + { + ++i; + /* FIX Shouldn't we use strcoll (strncoll if it existed?) instead? */ + /* Break if there's a match. */ + if (! strncmp (match_string, word, MAX(matchlen,wordlen))) break; + } + /* If no match, reset counter variable to 0, the value we want to return. */ + if (!word) i = 0; + /* Return the value of the counter as a string. */ + sprintf (buf, "0", i); + o = variable_buffer_output (o, buf, strlen (buf)); + return o; + + /* FIX modify real dox + Augmented dox for find_next_token: + Find the next token in PTR; return the address of it, store the end of it in + PTR, and store the length of the token into *LENGTHPTR if LENGTHPTR is not nil. + + Augmented dox for sindex: + Search string BIG (length BLEN) for an occurrence of + string SMALL (length SLEN). Return a pointer to the + beginning of the first occurrence, or return nil if none found. + BLEN and/or SLEN 0 means compute the values with strlen. + */ + +} + static char * func_foreach (o, argv, funcname) char *o; @@ -889,6 +972,60 @@ return o; } +/* Like foreach, but separate components with newline instead of space, for use with $(eval ..) */ +static char * +func_foreach_star (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* expand only the first two. */ + char *varname = expand_argument (argv[0], NULL); + char *list = expand_argument (argv[1], NULL); + char *body = argv[2]; + + int doneany = 0; + char *list_iterator = list; + char *p; + unsigned int len; + register struct variable *var; + + push_new_variable_scope (); + var = define_variable (varname, strlen (varname), "", o_automatic, 0); + + /* loop through LIST, put the value in VAR and expand BODY */ + while ((p = find_next_token (&list_iterator, &len)) != 0) + { + char *result = 0; + + { + char save = p[len]; + + p[len] = '\0'; + free (var->value); + var->value = (char *) xstrdup ((char*) p); + p[len] = save; + } + + result = allocated_variable_expand (body); + + o = variable_buffer_output (o, result, strlen (result)); + o = variable_buffer_output (o, "\n", 1); + doneany = 1; + free (result); + } + + if (doneany) + /* Kill the last space. */ + --o; + + pop_variable_scope (); + free (varname); + free (list); + + return o; +} + struct a_word { struct a_word *next; @@ -1809,6 +1946,7 @@ { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout}, { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout}, { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring}, + { STRING_SIZE_TUPLE("index"), 2, 2, 1, func_index}, { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword}, { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, @@ -1821,6 +1959,7 @@ { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words}, { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin}, { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach}, + { STRING_SIZE_TUPLE("foreachstar"), 3, 3, 0, func_foreach_star}, { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call}, { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error}, { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error}, Diff finished at Sun Dec 15 09:51:40