diff options
| author | nyamatongwe <devnull@localhost> | 2004-07-19 10:16:49 +0000 | 
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2004-07-19 10:16:49 +0000 | 
| commit | 181be9ff0128bb0133e26e581257cb60a6764e57 (patch) | |
| tree | 1bc43a269619c127fc105697666a8efc9264a2b6 /src | |
| parent | d087a0fa725a2ddbe871041c8473fdf701009922 (diff) | |
| download | scintilla-mirror-181be9ff0128bb0133e26e581257cb60a6764e57.tar.gz | |
Patch from Bruce Dodson to substitute any recursive definitions with "".
Diffstat (limited to 'src')
| -rw-r--r-- | src/PropSet.cxx | 92 | 
1 files changed, 63 insertions, 29 deletions
| diff --git a/src/PropSet.cxx b/src/PropSet.cxx index b2265c597..3711c03c8 100644 --- a/src/PropSet.cxx +++ b/src/PropSet.cxx @@ -449,39 +449,71 @@ bool PropSet::IncludesVar(const char *value, const char *key) {  	return false;  } -SString PropSet::GetExpanded(const char *key) { -	SString val = Get(key); -	return Expand(val.c_str(), 100, key); -} -SString PropSet::Expand(const char *withVars, int maxExpands, const char *blankVar) { -	char *base = StringDup(withVars); -	char *cpvar = strstr(base, "$("); -	while (cpvar && (maxExpands > 0)) { -		char *cpendvar = strchr(cpvar, ')'); -		if (!cpendvar) +// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)"). +// A solution is to keep a stack of variables that have been expanded, so that +// recursive expansions can be skipped.  For now I'll just use the C++ stack +// for that, through a recursive function and a simple chain of pointers. + +struct VarChain { +	VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {} + +	bool contains(const char *testVar) const { +		return (var && (0 == strcmp(var, testVar)))  +			|| (link && link->contains(testVar)); +	} + +	const char *var; +	const VarChain *link; +}; + +static int ExpandAllInPlace(PropSet &props, SString &withVars, int maxExpands, const VarChain &blankVars = VarChain()) { +	int varStart = withVars.search("$("); +	while ((varStart >= 0) && (maxExpands > 0)) { +		int varEnd = withVars.search(")", varStart+2); +		if (varEnd < 0) {  			break; -		int lenvar = cpendvar - cpvar - 2;  	// Subtract the $() -		char *var = StringDup(cpvar + 2, lenvar); -		SString val = Get(var); -		if (blankVar && (0 == strcmp(var, blankVar))) +		} + +		// For consistency, when we see '$(ab$(cde))', expand the inner variable first, +		// regardless whether there is actually a degenerate variable named 'ab$(cde'. +		int innerVarStart = withVars.search("$(", varStart+2); +		while ((innerVarStart > varStart) && (innerVarStart < varEnd)) { +			varStart = innerVarStart; +			innerVarStart = withVars.search("$(", varStart+2); +		} + +		SString var(withVars.c_str(), varStart + 2, varEnd); +		SString val = props.Get(var.c_str()); + +		if (blankVars.contains(var.c_str())) {  			val.clear(); // treat blankVar as an empty string (e.g. to block self-reference) -		if (IncludesVar(val.c_str(), var)) -			break; -		size_t newlenbase = strlen(base) + val.length() - lenvar; -		char *newbase = new char[newlenbase]; -		strncpy(newbase, base, cpvar - base); -		strcpy(newbase + (cpvar - base), val.c_str()); -		strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1); -		delete []var; -		delete []base; -		base = newbase; -		cpvar = strstr(base, "$("); -		maxExpands--; +		} + +		if (--maxExpands >= 0) { +			maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars)); +		} + +		withVars.remove(varStart, varEnd-varStart+1); +		withVars.insert(varStart, val.c_str(), val.length()); + +		varStart = withVars.search("$(");  	} -	SString sret = base; -	delete []base; -	return sret; + +	return maxExpands; +} + + +SString PropSet::GetExpanded(const char *key) { +	SString val = Get(key); +	ExpandAllInPlace(*this, val, 100, VarChain(key)); +	return val; +} + +SString PropSet::Expand(const char *withVars, int maxExpands) { +	SString val = withVars; +	ExpandAllInPlace(*this, val, maxExpands); +	return val;  }  int PropSet::GetInt(const char *key, int defaultValue) { @@ -576,6 +608,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {  	}  } + +  // GetNewExpand does not use Expand as it has to use GetWild with the filename for each  // variable reference found.  SString PropSet::GetNewExpand(const char *keybase, const char *filename) { | 
