diff options
Diffstat (limited to 'usr.bin/make')
-rw-r--r-- | usr.bin/make/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/make/arch.c | 3 | ||||
-rw-r--r-- | usr.bin/make/dir.c | 281 | ||||
-rw-r--r-- | usr.bin/make/dir.h | 22 | ||||
-rw-r--r-- | usr.bin/make/direxpand.c | 343 | ||||
-rw-r--r-- | usr.bin/make/direxpand.h | 53 | ||||
-rw-r--r-- | usr.bin/make/main.c | 3 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 3 | ||||
-rw-r--r-- | usr.bin/make/suff.c | 3 |
9 files changed, 420 insertions, 296 deletions
diff --git a/usr.bin/make/Makefile b/usr.bin/make/Makefile index 8d83964ef88..9a19d075a2f 100644 --- a/usr.bin/make/Makefile +++ b/usr.bin/make/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.43 2007/07/21 14:40:33 espie Exp $ +# $OpenBSD: Makefile,v 1.44 2007/09/16 10:14:26 espie Exp $ PROG= make CFLAGS+= -I${.OBJDIR} -I${.CURDIR} @@ -15,7 +15,8 @@ CDEFS+=-DHAS_EXTENDED_GETCWD CFLAGS+=${CDEFS} HOSTCFLAGS+=${CDEFS} -SRCS= arch.c buf.c cmd_exec.c compat.c cond.c dir.c error.c for.c \ +SRCS= arch.c buf.c cmd_exec.c compat.c cond.c dir.c direxpand.c \ + error.c for.c \ init.c job.c lowparse.c main.c make.c memory.c parse.c \ parsevar.c str.c stats.c suff.c targ.c timestamp.c \ var.c varmodifiers.c varname.c diff --git a/usr.bin/make/arch.c b/usr.bin/make/arch.c index 7617dc10803..b60cf3346a2 100644 --- a/usr.bin/make/arch.c +++ b/usr.bin/make/arch.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: arch.c,v 1.62 2007/09/16 09:49:24 espie Exp $ */ +/* $OpenBSD: arch.c,v 1.63 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: arch.c,v 1.17 1996/11/06 17:58:59 christos Exp $ */ /* @@ -87,6 +87,7 @@ #include "config.h" #include "defines.h" #include "dir.h" +#include "direxpand.h" #include "arch.h" #include "var.h" #include "targ.h" diff --git a/usr.bin/make/dir.c b/usr.bin/make/dir.c index 2f403d4fcff..45171f2e395 100644 --- a/usr.bin/make/dir.c +++ b/usr.bin/make/dir.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: dir.c,v 1.46 2007/07/24 21:09:07 espie Exp $ */ +/* $OpenBSD: dir.c,v 1.47 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: dir.c,v 1.14 1997/03/29 16:51:26 christos Exp $ */ /* @@ -175,7 +175,7 @@ static int hits, /* Found in directory cache */ bigmisses; /* Sought by itself */ #endif -static Path *dot; /* contents of current directory */ +Path *dot; /* contents of current directory */ struct file_stamp { TIMESTAMP mtime; /* time stamp... */ @@ -225,18 +225,6 @@ static void free_hash(struct ohash *); /* p = DirReaddiri(name, end): read an actual directory, caching results * as we go. */ static Path *DirReaddiri(const char *, const char *); -/* Handles wildcard expansion on a given directory. */ -static void DirMatchFilesi(const char *, const char *, Path *, Lst); -/* Handles simple wildcard expansion on a path. */ -static void PathMatchFilesi(const char *, const char *, Lst, Lst); -/* Handles wildcards expansion except for curly braces. */ -static void DirExpandWildi(const char *, const char *, Lst, Lst); -#define DirExpandWild(s, l1, l2) DirExpandWildi(s, strchr(s, '\0'), l1, l2) -/* Handles wildcard expansion including curly braces. */ -static void DirExpandCurlyi(const char *, const char *, Lst, Lst); - -/* Debugging: show each word in an expansion list. */ -static void DirPrintWord(void *); /* Debugging: show a dir name in a path. */ static void DirPrintDir(void *); @@ -339,49 +327,9 @@ Dir_End(void) } #endif - -/* XXX: This code is not 100% correct ([^]] fails) */ -bool -Dir_HasWildcardsi(const char *name, const char *ename) -{ - const char *cp; - bool wild = false; - unsigned long brace = 0, bracket = 0; - - for (cp = name; cp != ename; cp++) { - switch (*cp) { - case '{': - brace++; - wild = true; - break; - case '}': - if (brace == 0) - return false; - brace--; - break; - case '[': - bracket++; - wild = true; - break; - case ']': - if (bracket == 0) - return false; - bracket--; - break; - case '?': - case '*': - wild = true; - break; - default: - break; - } - } - return wild && bracket == 0 && brace == 0; -} - /*- *----------------------------------------------------------------------- - * DirMatchFilesi -- + * Dir_MatchFilesi -- * Given a pattern and a Path structure, see if any files * match the pattern and add their names to the 'expansions' list if * any do. This is incomplete -- it doesn't take care of patterns like @@ -389,8 +337,8 @@ Dir_HasWildcardsi(const char *name, const char *ename) * will do for now. *----------------------------------------------------------------------- */ -static void -DirMatchFilesi(const char *word, const char *eword, Path *p, Lst expansions) +void +Dir_MatchFilesi(const char *word, const char *eword, Path *p, Lst expansions) { unsigned int search; /* Index into the directory's table */ const char *entry; /* Current entry in the table */ @@ -414,225 +362,6 @@ DirMatchFilesi(const char *word, const char *eword, Path *p, Lst expansions) } /*- - *----------------------------------------------------------------------- - * PathMatchFilesi -- - * Traverse directories in the path, calling DirMatchFiles for each. - * NOTE: This doesn't handle patterns in directories. - *----------------------------------------------------------------------- - */ -static void -PathMatchFilesi(const char *word, const char *eword, Lst path, Lst expansions) -{ - LstNode ln; /* Current node */ - - for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) - DirMatchFilesi(word, eword, (Path *)Lst_Datum(ln), expansions); -} - -static void -DirPrintWord(void *word) -{ - printf("%s ", (char *)word); -} - -/*- - *----------------------------------------------------------------------- - * DirExpandWildi: - * Expand all wild cards in a fully qualified name, except for - * curly braces. - * Side-effect: - * Will hash any directory in which a file is found, and add it to - * the path, on the assumption that future lookups will find files - * there as well. - *----------------------------------------------------------------------- - */ -static void -DirExpandWildi(const char *word, const char *eword, Lst path, Lst expansions) -{ - const char *cp; - const char *slash; /* keep track of first slash before wildcard */ - - slash = memchr(word, '/', eword - word); - if (slash == NULL) { - /* First the files in dot. */ - DirMatchFilesi(word, eword, dot, expansions); - - /* Then the files in every other directory on the path. */ - PathMatchFilesi(word, eword, path, expansions); - return; - } - /* The thing has a directory component -- find the first wildcard - * in the string. */ - slash = word; - for (cp = word; cp != eword; cp++) { - if (*cp == '/') - slash = cp; - if (*cp == '?' || *cp == '[' || *cp == '*') { - - if (slash != word) { - char *dirpath; - - /* If the glob isn't in the first component, - * try and find all the components up to - * the one with a wildcard. */ - dirpath = Dir_FindFilei(word, slash+1, path); - /* dirpath is null if we can't find the - * leading component - * XXX: Dir_FindFile won't find internal - * components. i.e. if the path contains - * ../Etc/Object and we're looking for Etc, - * it won't be found. */ - if (dirpath != NULL) { - char *dp; - LIST temp; - - dp = strchr(dirpath, '\0'); - while (dp > dirpath && dp[-1] == '/') - dp--; - - Lst_Init(&temp); - Dir_AddDiri(&temp, dirpath, dp); - PathMatchFilesi(slash+1, eword, &temp, - expansions); - Lst_Destroy(&temp, NOFREE); - } - } else - /* Start the search from the local directory. */ - PathMatchFilesi(word, eword, path, expansions); - return; - } - } - /* Return the file -- this should never happen. */ - PathMatchFilesi(word, eword, path, expansions); -} - -/*- - *----------------------------------------------------------------------- - * DirExpandCurly -- - * Expand curly braces like the C shell, and other wildcards as per - * Str_Match. - * XXX: if curly expansion yields a result with - * no wildcards, the result is placed on the list WITHOUT CHECKING - * FOR ITS EXISTENCE. - *----------------------------------------------------------------------- - */ -static void -DirExpandCurlyi(const char *word, const char *eword, Lst path, Lst expansions) -{ - const char *cp2;/* Pointer for checking for wildcards in - * expansion before calling Dir_Expand */ - LIST curled; /* Queue of words to expand */ - char *toexpand; /* Current word to expand */ - bool dowild; /* Wildcard left after curlies ? */ - - /* Determine once and for all if there is something else going on */ - dowild = false; - for (cp2 = word; cp2 != eword; cp2++) - if (*cp2 == '*' || *cp2 == '?' || *cp2 == '[') { - dowild = true; - break; - } - - /* Prime queue with copy of initial word */ - Lst_Init(&curled); - Lst_EnQueue(&curled, Str_dupi(word, eword)); - while ((toexpand = (char *)Lst_DeQueue(&curled)) != NULL) { - const char *brace; - const char *start; - /* Start of current chunk of brace clause */ - const char *end;/* Character after the closing brace */ - int bracelevel; /* Keep track of nested braces. If we hit - * the right brace with bracelevel == 0, - * this is the end of the clause. */ - size_t endLen; /* The length of the ending non-curlied - * part of the current expansion */ - - /* End case: no curly left to expand */ - brace = strchr(toexpand, '{'); - if (brace == NULL) { - if (dowild) { - DirExpandWild(toexpand, path, expansions); - free(toexpand); - } else - Lst_AtEnd(expansions, toexpand); - continue; - } - - start = brace+1; - - /* Find the end of the brace clause first, being wary of - * nested brace clauses. */ - for (end = start, bracelevel = 0;; end++) { - if (*end == '{') - bracelevel++; - else if (*end == '\0') { - Error("Unterminated {} clause \"%s\"", start); - return; - } else if (*end == '}' && bracelevel-- == 0) - break; - } - end++; - endLen = strlen(end); - - for (;;) { - char *file; /* To hold current expansion */ - const char *cp; /* Current position in brace clause */ - - /* Find the end of the current expansion */ - for (bracelevel = 0, cp = start; - bracelevel != 0 || (*cp != '}' && *cp != ','); - cp++) { - if (*cp == '{') - bracelevel++; - else if (*cp == '}') - bracelevel--; - } - - /* Build the current combination and enqueue it. */ - file = emalloc((brace - toexpand) + (cp - start) + - endLen + 1); - if (brace != toexpand) - memcpy(file, toexpand, brace-toexpand); - if (cp != start) - memcpy(file+(brace-toexpand), start, cp-start); - memcpy(file+(brace-toexpand)+(cp-start), end, - endLen + 1); - Lst_EnQueue(&curled, file); - if (*cp == '}') - break; - start = cp+1; - } - free(toexpand); - } -} - -/* Side effects: - * Dir_Expandi will hash directories that were not yet visited */ -void -Dir_Expandi(const char *word, const char *eword, Lst path, Lst expansions) -{ - const char *cp; - - if (DEBUG(DIR)) { - char *s = Str_dupi(word, eword); - printf("expanding \"%s\"...", s); - free(s); - } - - cp = memchr(word, '{', eword - word); - if (cp) - DirExpandCurlyi(word, eword, path, expansions); - else - DirExpandWildi(word, eword, path, expansions); - - if (DEBUG(DIR)) { - Lst_Every(expansions, DirPrintWord); - fputc('\n', stdout); - } -} - - -/*- * Side Effects: * If the file is found in a directory which is not on the path * already (either 'name' is absolute or it is a relative path diff --git a/usr.bin/make/dir.h b/usr.bin/make/dir.h index 58bfdf73ced..d87c983211e 100644 --- a/usr.bin/make/dir.h +++ b/usr.bin/make/dir.h @@ -2,7 +2,7 @@ #define DIR_H /* $OpenPackages$ */ -/* $OpenBSD: dir.h,v 1.17 2007/01/18 17:49:51 espie Exp $ */ +/* $OpenBSD: dir.h,v 1.18 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: dir.h,v 1.4 1996/11/06 17:59:05 christos Exp $ */ /* @@ -102,19 +102,6 @@ extern void Dir_PrintPath(Lst); * Handling file names, and looking them up in paths */ -/* boolean = Dir_HasWildcardsi(name, end) - * Returns true if (name, end) needs to be wildcard-expanded. - */ -extern bool Dir_HasWildcardsi(const char *, const char *); -#define Dir_HasWildcards(n) Dir_HasWildcardsi(n, strchr(n, '\0')) - -/* Dir_Expandi(pattern, endp, path, expansions); - * Expand (pattern, endp) to Lst of names matching on the search path. - * Put result in expansions. - */ -extern void Dir_Expandi(const char *, const char *, Lst, Lst); -#define Dir_Expand(n, l1, l2) Dir_Expandi(n, strchr(n, '\0'), l1, l2) - /* fullname = Dir_FindFileComplexi(name, end, path, checkCurdirFirst) * Searches for a file (name, end) on a given search path. If it exists, * return the fullname of the file, otherwise NULL. @@ -165,4 +152,11 @@ extern void Dir_PrintDirectories(void); /* List of directories to search when looking for targets. */ extern Lst dirSearchPath; + +/* communication between dir.c and direxpand.c */ +struct Path_; +extern struct Path_ *dot; +/* Handles wildcard expansion on a given directory. */ +extern void Dir_MatchFilesi(const char *, const char *, struct Path_ *, + Lst); #endif /* DIR_H */ diff --git a/usr.bin/make/direxpand.c b/usr.bin/make/direxpand.c new file mode 100644 index 00000000000..a81cc84f716 --- /dev/null +++ b/usr.bin/make/direxpand.c @@ -0,0 +1,343 @@ +/* $OpenBSD: direxpand.c,v 1.1 2007/09/16 10:14:26 espie Exp $ */ +/* + * Copyright (c) 1999,2007 Marc Espie. + * + * Extensive code changes for the OpenBSD project. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD + * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. + * Copyright (c) 1988, 1989 by Adam de Boor + * Copyright (c) 1989 by Berkeley Softworks + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "config.h" +#include "defines.h" +#include "lst.h" +#include "dir.h" +#include "direxpand.h" +#include "error.h" +#include "memory.h" +#include "str.h" + +/* Handles simple wildcard expansion on a path. */ +static void PathMatchFilesi(const char *, const char *, Lst, Lst); +/* Handles wildcards expansion except for curly braces. */ +static void DirExpandWildi(const char *, const char *, Lst, Lst); +#define DirExpandWild(s, l1, l2) DirExpandWildi(s, strchr(s, '\0'), l1, l2) +/* Handles wildcard expansion including curly braces. */ +static void DirExpandCurlyi(const char *, const char *, Lst, Lst); + +/* Debugging: show each word in an expansion list. */ +static void DirPrintWord(void *); + +/*- + *----------------------------------------------------------------------- + * PathMatchFilesi -- + * Traverse directories in the path, calling Dir_MatchFiles for each. + * NOTE: This doesn't handle patterns in directories. + *----------------------------------------------------------------------- + */ +static void +PathMatchFilesi(const char *word, const char *eword, Lst path, Lst expansions) +{ + LstNode ln; /* Current node */ + + for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) + Dir_MatchFilesi(word, eword, (struct Path_ *)Lst_Datum(ln), expansions); +} + +/*- + *----------------------------------------------------------------------- + * DirExpandWildi: + * Expand all wild cards in a fully qualified name, except for + * curly braces. + * Side-effect: + * Will hash any directory in which a file is found, and add it to + * the path, on the assumption that future lookups will find files + * there as well. + *----------------------------------------------------------------------- + */ +static void +DirExpandWildi(const char *word, const char *eword, Lst path, Lst expansions) +{ + const char *cp; + const char *slash; /* keep track of first slash before wildcard */ + + slash = memchr(word, '/', eword - word); + if (slash == NULL) { + /* First the files in dot. */ + Dir_MatchFilesi(word, eword, dot, expansions); + + /* Then the files in every other directory on the path. */ + PathMatchFilesi(word, eword, path, expansions); + return; + } + /* The thing has a directory component -- find the first wildcard + * in the string. */ + slash = word; + for (cp = word; cp != eword; cp++) { + if (*cp == '/') + slash = cp; + if (*cp == '?' || *cp == '[' || *cp == '*') { + + if (slash != word) { + char *dirpath; + + /* If the glob isn't in the first component, + * try and find all the components up to + * the one with a wildcard. */ + dirpath = Dir_FindFilei(word, slash+1, path); + /* dirpath is null if we can't find the + * leading component + * XXX: Dir_FindFile won't find internal + * components. i.e. if the path contains + * ../Etc/Object and we're looking for Etc, + * it won't be found. */ + if (dirpath != NULL) { + char *dp; + LIST temp; + + dp = strchr(dirpath, '\0'); + while (dp > dirpath && dp[-1] == '/') + dp--; + + Lst_Init(&temp); + Dir_AddDiri(&temp, dirpath, dp); + PathMatchFilesi(slash+1, eword, &temp, + expansions); + Lst_Destroy(&temp, NOFREE); + } + } else + /* Start the search from the local directory. */ + PathMatchFilesi(word, eword, path, expansions); + return; + } + } + /* Return the file -- this should never happen. */ + PathMatchFilesi(word, eword, path, expansions); +} + +/*- + *----------------------------------------------------------------------- + * DirExpandCurly -- + * Expand curly braces like the C shell, and other wildcards as per + * Str_Match. + * XXX: if curly expansion yields a result with + * no wildcards, the result is placed on the list WITHOUT CHECKING + * FOR ITS EXISTENCE. + *----------------------------------------------------------------------- + */ +static void +DirExpandCurlyi(const char *word, const char *eword, Lst path, Lst expansions) +{ + const char *cp2;/* Pointer for checking for wildcards in + * expansion before calling Dir_Expand */ + LIST curled; /* Queue of words to expand */ + char *toexpand; /* Current word to expand */ + bool dowild; /* Wildcard left after curlies ? */ + + /* Determine once and for all if there is something else going on */ + dowild = false; + for (cp2 = word; cp2 != eword; cp2++) + if (*cp2 == '*' || *cp2 == '?' || *cp2 == '[') { + dowild = true; + break; + } + + /* Prime queue with copy of initial word */ + Lst_Init(&curled); + Lst_EnQueue(&curled, Str_dupi(word, eword)); + while ((toexpand = (char *)Lst_DeQueue(&curled)) != NULL) { + const char *brace; + const char *start; + /* Start of current chunk of brace clause */ + const char *end;/* Character after the closing brace */ + int bracelevel; /* Keep track of nested braces. If we hit + * the right brace with bracelevel == 0, + * this is the end of the clause. */ + size_t endLen; /* The length of the ending non-curlied + * part of the current expansion */ + + /* End case: no curly left to expand */ + brace = strchr(toexpand, '{'); + if (brace == NULL) { + if (dowild) { + DirExpandWild(toexpand, path, expansions); + free(toexpand); + } else + Lst_AtEnd(expansions, toexpand); + continue; + } + + start = brace+1; + + /* Find the end of the brace clause first, being wary of + * nested brace clauses. */ + for (end = start, bracelevel = 0;; end++) { + if (*end == '{') + bracelevel++; + else if (*end == '\0') { + Error("Unterminated {} clause \"%s\"", start); + return; + } else if (*end == '}' && bracelevel-- == 0) + break; + } + end++; + endLen = strlen(end); + + for (;;) { + char *file; /* To hold current expansion */ + const char *cp; /* Current position in brace clause */ + + /* Find the end of the current expansion */ + for (bracelevel = 0, cp = start; + bracelevel != 0 || (*cp != '}' && *cp != ','); + cp++) { + if (*cp == '{') + bracelevel++; + else if (*cp == '}') + bracelevel--; + } + + /* Build the current combination and enqueue it. */ + file = emalloc((brace - toexpand) + (cp - start) + + endLen + 1); + if (brace != toexpand) + memcpy(file, toexpand, brace-toexpand); + if (cp != start) + memcpy(file+(brace-toexpand), start, cp-start); + memcpy(file+(brace-toexpand)+(cp-start), end, + endLen + 1); + Lst_EnQueue(&curled, file); + if (*cp == '}') + break; + start = cp+1; + } + free(toexpand); + } +} + +/* Side effects: + * Dir_Expandi will hash directories that were not yet visited */ +void +Dir_Expandi(const char *word, const char *eword, Lst path, Lst expansions) +{ + const char *cp; + + if (DEBUG(DIR)) { + char *s = Str_dupi(word, eword); + printf("expanding \"%s\"...", s); + free(s); + } + + cp = memchr(word, '{', eword - word); + if (cp) + DirExpandCurlyi(word, eword, path, expansions); + else + DirExpandWildi(word, eword, path, expansions); + + if (DEBUG(DIR)) { + Lst_Every(expansions, DirPrintWord); + fputc('\n', stdout); + } +} + +static void +DirPrintWord(void *word) +{ + printf("%s ", (char *)word); +} + + +/* XXX: This code is not 100% correct ([^]] fails) */ +bool +Dir_HasWildcardsi(const char *name, const char *ename) +{ + const char *cp; + bool wild = false; + unsigned long brace = 0, bracket = 0; + + for (cp = name; cp != ename; cp++) { + switch (*cp) { + case '{': + brace++; + wild = true; + break; + case '}': + if (brace == 0) + return false; + brace--; + break; + case '[': + bracket++; + wild = true; + break; + case ']': + if (bracket == 0) + return false; + bracket--; + break; + case '?': + case '*': + wild = true; + break; + default: + break; + } + } + return wild && bracket == 0 && brace == 0; +} + + diff --git a/usr.bin/make/direxpand.h b/usr.bin/make/direxpand.h new file mode 100644 index 00000000000..7cbd13914f4 --- /dev/null +++ b/usr.bin/make/direxpand.h @@ -0,0 +1,53 @@ +#ifndef DIREXPAND_H +#define DIREXPAND_H +/* $OpenBSD: direxpand.h,v 1.1 2007/09/16 10:14:26 espie Exp $ */ +/* + * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. + * Copyright (c) 1988, 1989 by Adam de Boor + * Copyright (c) 1989 by Berkeley Softworks + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)dir.h 8.1 (Berkeley) 6/6/93 + */ + +/* boolean = Dir_HasWildcardsi(name, end) + * Returns true if (name, end) needs to be wildcard-expanded. + */ +extern bool Dir_HasWildcardsi(const char *, const char *); +#define Dir_HasWildcards(n) Dir_HasWildcardsi(n, strchr(n, '\0')) + +/* Dir_Expandi(pattern, endp, path, expansions); + * Expand (pattern, endp) to Lst of names matching on the search path. + * Put result in expansions. + */ +extern void Dir_Expandi(const char *, const char *, Lst, Lst); +#define Dir_Expand(n, l1, l2) Dir_Expandi(n, strchr(n, '\0'), l1, l2) + +#endif diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 8d6c4e0b94b..2ef60a3c732 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: main.c,v 1.77 2007/09/16 09:46:14 espie Exp $ */ +/* $OpenBSD: main.c,v 1.78 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */ /* @@ -53,6 +53,7 @@ #include "parse.h" #include "parsevar.h" #include "dir.h" +#include "direxpand.h" #include "error.h" #include "pathnames.h" #include "init.h" diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index cf114ecfd55..272712508c5 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: parse.c,v 1.80 2007/08/05 11:00:58 espie Exp $ */ +/* $OpenBSD: parse.c,v 1.81 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* @@ -70,6 +70,7 @@ #include "config.h" #include "defines.h" #include "dir.h" +#include "direxpand.h" #include "job.h" #include "buf.h" #include "for.h" diff --git a/usr.bin/make/suff.c b/usr.bin/make/suff.c index 2b43ed72aa2..729f3e2e16b 100644 --- a/usr.bin/make/suff.c +++ b/usr.bin/make/suff.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: suff.c,v 1.62 2007/09/16 09:49:24 espie Exp $ */ +/* $OpenBSD: suff.c,v 1.63 2007/09/16 10:14:26 espie Exp $ */ /* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */ /* @@ -94,6 +94,7 @@ #include "config.h" #include "defines.h" #include "dir.h" +#include "direxpand.h" #include "arch.h" #include "suff.h" #include "var.h" |