diff options
Diffstat (limited to 'src/PropSet.cxx')
| -rw-r--r-- | src/PropSet.cxx | 104 | 
1 files changed, 74 insertions, 30 deletions
| diff --git a/src/PropSet.cxx b/src/PropSet.cxx index 6fc02cb0a..0f2b1bd85 100644 --- a/src/PropSet.cxx +++ b/src/PropSet.cxx @@ -24,6 +24,16 @@ bool EqualCaseInsensitive(const char *a, const char *b) {  #endif  } +unsigned int HashString(const char *s) { +    unsigned int ret = 0; +    while (*s) { +        ret <<= 4; +        ret ^= *s; +        s++; +    } +    return ret; +} +  // Get a line of input. If end of line escaped with '\\' then continue reading.  static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {  	bool continuation = true; @@ -56,44 +66,46 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {  PropSet::PropSet() {  	superPS = 0; -	size = 10; +	size = 20;  	used = 0; -	vals = new char * [size]; +	properties = new Property[size];  }  PropSet::~PropSet() {  	superPS = 0;  	Clear(); -	delete []vals; +	delete []properties;  }  void PropSet::EnsureCanAddEntry() { -	if (used >= size - 2) { -		int newsize = size + 10; -		char **newvals = new char * [newsize]; +	if (used >= size - 1) { +		int newsize = size + 20; +		Property *newprops = new Property[newsize];  		for (int i = 0; i < used; i++) { -			newvals[i] = vals[i]; +			newprops[i] = properties[i];  		} -		delete []vals; -		vals = newvals; +		delete []properties; +		properties = newprops;  		size = newsize;  	}  }  void PropSet::Set(const char *key, const char *val) {  	EnsureCanAddEntry(); -	for (int i = 0; i < used; i += 2) { -		if (0 == strcmp(vals[i], key)) { +	for (int i = 0; i < used; i++) { +		if (0 == strcmp(properties[i].key, key)) {  			// Replace current value -			delete [](vals[i + 1]); -			vals[i + 1] = StringDup(val); +			delete [](properties[i].val); +			properties[i].val = StringDup(val);  			return;  		}  	}  	// Not found -	vals[used++] = StringDup(key); -	vals[used++] = StringDup(val); +    properties[used].hash = HashString(key); +	properties[used].key = StringDup(key); +	properties[used].val = StringDup(val); +    used++;  }  void PropSet::Set(char *keyval) { @@ -108,9 +120,10 @@ void PropSet::Set(char *keyval) {  }  SString PropSet::Get(const char *key) { -	for (int i = 0; i < used; i += 2) { -		if (0 == strcmp(vals[i], key)) { -			return vals[i + 1]; +    unsigned int hash = HashString(key); +	for (int i = 0; i < used; i++) { +		if ((hash == properties[i].hash) && (0 == strcmp(properties[i].key, key))) { +			return properties[i].val;  		}  	}  	if (superPS) { @@ -121,6 +134,36 @@ SString PropSet::Get(const char *key) {  	}  } +SString PropSet::GetExpanded(const char *key) { +    SString val = Get(key); +    return Expand(val.c_str()); +} + +SString PropSet::Expand(const char *withvars) { +	char *base = StringDup(withvars); +	char *cpvar = strstr(base, "$("); +	while (cpvar) { +		char *cpendvar = strchr(cpvar, ')'); +		if (cpendvar) { +			int lenvar = cpendvar - cpvar - 2;  	// Subtract the $() +			char *var = StringDup(cpvar+2, lenvar); +			SString val = GetExpanded(var); +			int 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, "$("); +	} +	SString sret = base; +	delete []base; +	return sret; +} +  int PropSet::GetInt(const char *key, int defaultValue) {  	SString val = Get(key);  	if (val.length()) @@ -155,9 +198,9 @@ bool issuffix(const char *target, const char *suffix) {  }  SString PropSet::GetWild(const char *keybase, const char *filename) { -	for (int i = 0; i < used; i += 2) { -		if (isprefix(vals[i], keybase)) { -			char *orgkeyfile = vals[i] + strlen(keybase); +	for (int i = 0; i < used; i++) { +		if (isprefix(properties[i].key, keybase)) { +			char *orgkeyfile = properties[i].key + strlen(keybase);  			char *keyfile = NULL;  			if (strstr(orgkeyfile, "$(") == orgkeyfile) { @@ -184,12 +227,12 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {  					if (issuffix(filename, keyfile + 1)) {  						*del = delchr;  						free(keyptr); -						return vals[i + 1]; +						return properties[i].val;  					}  				} else if (0 == strcmp(keyfile, filename)) {  					*del = delchr;  					free(keyptr); -					return vals[i + 1]; +					return properties[i].val;  				}  				if (delchr == '\0')  					break; @@ -198,8 +241,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {  			}  			free(keyptr); -			if (0 == strcmp(vals[i], keybase)) { -				return vals[i + 1]; +			if (0 == strcmp(properties[i].key, keybase)) { +				return properties[i].val;  			}  		}  	} @@ -218,9 +261,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {  		char *cpendvar = strchr(cpvar, ')');  		if (cpendvar) {  			int lenvar = cpendvar - cpvar - 2;  	// Subtract the $() -			char *var = new char[lenvar + 1]; -			strncpy(var, cpvar + 2, lenvar); -			var[lenvar] = '\0'; +			char *var = StringDup(cpvar+2, lenvar);  			SString val = GetWild(var, filename);  			int newlenbase = strlen(base) + val.length() - lenvar;  			char *newbase = new char[newlenbase]; @@ -240,8 +281,11 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {  void PropSet::Clear() {  	for (int i = 0; i < used; i++) { -		delete [](vals[i]); -		vals[i] = 0; +		properties[i].hash = 0; +		delete []properties[i].key; +		properties[i].key = 0; +		delete []properties[i].val; +		properties[i].val = 0;  	}  	used = 0;  } | 
