@@ -92,24 +92,70 @@ namespace shellanything
9292 return EMPTY_VALUE;
9393 }
9494
95- std::string PropertyManager::Expand ( const std::string & value) const
95+ bool IsPropertyReference ( const std::string & token_open, const std::string & token_close, const std::string & value, size_t offset, std::string & name)
9696 {
97- std::string output = value;
97+ size_t value_length = value.size ();
98+ name.clear ();
99+ if (offset >= value_length)
100+ return false ;
98101
99- // for each properties
100- for (PropertyMap::const_iterator propertyIt = properties. begin (); propertyIt != properties. end (); propertyIt ++)
102+ // Validate a token_open prefix at value[offset]
103+ for ( size_t i= 0 ; i<token_open. size (); i ++)
101104 {
102- const std::string & name = propertyIt->first ;
103- const std::string & value = propertyIt->second ;
105+ if (value[offset+i] != token_open[i])
106+ return false ;
107+ }
104108
105- // generate the search token
106- std::string token;
107- token.append (" ${" );
108- token.append (name);
109- token.append (" }" );
109+ // Found a token_open position at value[offset]
110+ // Search for the token_close position.
111+ size_t name_start_pos = offset + token_open.size ();
112+ size_t token_close_pos = value.find (token_close, name_start_pos);
113+ if (token_close_pos == std::string::npos)
114+ return false ; // token_close not found
115+
116+ // Found a token_close position.
117+ // Extract the name of the property.
118+ size_t length = (token_close_pos) - name_start_pos;
119+ if (length == 0 )
120+ return false ;
121+ std::string temp_name (&value[name_start_pos], length);
122+
123+ // Validate if name
124+ PropertyManager & pmgr = PropertyManager::GetInstance ();
125+ bool exists = pmgr.HasProperty (temp_name);
126+ if (exists)
127+ name = temp_name;
128+ return exists;
129+ }
110130
111- // process with search and replace
112- ra::strings::Replace (output, token, value);
131+ std::string PropertyManager::Expand (const std::string & value) const
132+ {
133+ std::string output;
134+ output.reserve (value.size ()*2 );
135+
136+ static const std::string token_open = " ${" ;
137+ static const std::string token_close = " }" ;
138+
139+ for (size_t i=0 ; i<value.size (); i++)
140+ {
141+ std::string name;
142+ if (strncmp (&value[i], token_open.c_str (), token_open.size ()) == 0 && IsPropertyReference (token_open, token_close, value, i, name))
143+ {
144+ // Found a property reference at value[i]
145+ const std::string & property_value = this ->GetProperty (name);
146+
147+ // Also expands property_value
148+ std::string expanded = this ->Expand (property_value);
149+
150+ // Proceed with the string replacement
151+ output.append (expanded);
152+
153+ // Update i to skip this property reference
154+ size_t length = token_open.size () + name.size () + token_close.size ();
155+ i += length-1 ; // -1 since the next for loop will increase i by 1.
156+ }
157+ else
158+ output.append (1 , value[i]);
113159 }
114160
115161 return output;
0 commit comments