diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 3221bdd8ea84..dd39ce6bc9f9 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -606,6 +606,48 @@ VarModify (char *str, Boolean (*modProc)(const char *, Boolean, Buffer, void *), return (str); } +/*- + *----------------------------------------------------------------------- + * VarSortWords -- + * Sort the words in the string. + * + * Input: + * str String whose words should be sorted + * cmp A comparison function to control the ordering + * + * Results: + * A string containing the words sorted + * + * Side Effects: + * None. + * + *----------------------------------------------------------------------- + */ +static char * +VarSortWords(char *str, int (*cmp)(const void *, const void *)) +{ + Buffer buf; + char **av; + int ac, i; + + buf = Buf_Init(0); + av = brk_string(str, &ac, FALSE); + qsort((void*)(av + 1), ac - 1, sizeof(char*), cmp); + for (i = 1; i < ac; i++) { + Buf_AddBytes(buf, strlen(av[i]), (Byte *)av[i]); + Buf_AddByte(buf, (Byte)((i < ac - 1) ? ' ' : '\0')); + } + str = (char *)Buf_GetAll(buf, (int *)NULL); + Buf_Destroy(buf, FALSE); + return (str); +} + +static int +SortIncreasing(const void *l, const void *r) +{ + return (strcmp(*(const char* const*)l, *(const char* const*)r)); +} + /*- *----------------------------------------------------------------------- * VarGetPattern -- @@ -1114,7 +1156,7 @@ Var_Parse(char *str, GNode *ctxt, Boolean err, int *lengthPtr, Boolean *freePtr) DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, str)); switch (*tstr) { - case 'U': + case 'U': if (tstr[1] == endc || tstr[1] == ':') { Buffer buf; buf = Buf_Init(MAKE_BSIZE); @@ -1448,6 +1490,14 @@ Var_Parse(char *str, GNode *ctxt, Boolean err, int *lengthPtr, Boolean *freePtr) free(pattern.matches); break; } + case 'O': + if (tstr[1] == endc || tstr[1] == ':') { + newStr = VarSortWords(str, SortIncreasing); + cp = tstr + 1; + termc = *cp; + break; + } + /* FALLTHROUGH */ case 'Q': if (tstr[1] == endc || tstr[1] == ':') { newStr = VarQuote (str);