--- parser3/src/classes/hash.C 2024/09/28 19:42:41 1.164 +++ parser3/src/classes/hash.C 2024/10/27 17:50:59 1.166 @@ -11,13 +11,14 @@ #include "pa_request.h" #include "pa_charsets.h" #include "pa_vhash.h" +#include "pa_varray.h" #include "pa_vvoid.h" #include "pa_sql_connection.h" #include "pa_vtable.h" #include "pa_vbool.h" #include "pa_vmethod_frame.h" -volatile const char * IDENT_HASH_C="$Id: hash.C,v 1.164 2024/09/28 19:42:41 moko Exp $"; +volatile const char * IDENT_HASH_C="$Id: hash.C,v 1.166 2024/10/27 17:50:59 moko Exp $"; // class @@ -197,7 +198,13 @@ static void _create_or_add(Request& r, M HashStringValue* self_hash=&(self.hash()); HashStringValue* src_hash; - if(VHashBase* src=dynamic_cast(&vsrc)) { + if(VArray* src=dynamic_cast(&vsrc)) { + for(ArrayValue::Iterator i(src->array()); i; i.next()){ + if(i.value()) + self_hash->put(i.key(), i.value()); + } + return; + } else if(VHashBase* src=dynamic_cast(&vsrc)) { src_hash=&(src->hash()); if(src_hash==self_hash) // same: doing nothing @@ -206,6 +213,7 @@ static void _create_or_add(Request& r, M if(Value* vdefault=src->get_default()) self.set_default(vdefault); } else { + // allows $h[^hash::create[non-blank string]], thus as_hash("param") is more correct, but is not backward compatible src_hash=vsrc.get_hash(); } @@ -472,7 +480,7 @@ enum AtResultType { AtResultTypeHash = 2 }; -inline Value& SingleElementHash(String::Body akey, Value* avalue) { +static Value& SingleElementHash(String::Body akey, Value* avalue) { Value& result=*new VHash; result.put_element(*new String(akey, String::L_TAINTED), avalue); return result; @@ -564,8 +572,6 @@ static void _at(Request& r, MethodParams HashStringValue& hash=GET_SELF(r, VHashBase).hash(); size_t count=hash.count(); - int pos=0; - // misha@ // I do not like that type is checked before whence. // But I do not like the idea to move it after whence (where process can be called) even more. @@ -580,20 +586,7 @@ static void _at(Request& r, MethodParams throw Exception(PARSER_RUNTIME, &stype, "type must be 'key', 'value' or 'hash'"); } - Value& vwhence=params[0]; - if(vwhence.is_string()) { - const String& swhence=*vwhence.get_string(); - if(swhence == "last") - pos=count-1; - else if(swhence != "first") - throw Exception(PARSER_RUNTIME, - &swhence, - "whence must be 'first', 'last' or expression"); - } else { - pos=r.process(vwhence).as_int(); - if(pos < 0) - pos+=count; - } + int pos=params.as_index(0, count, r); if(count && pos >= 0 && (size_t)pos < count){ switch(result_type) {