<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def format_name(format, name, target_type, prop_set):
 """ Given a target, as given to a custom tag rule, returns a string formatted according to the passed format. Format is a list of properties that is represented in the result. For each element of format the corresponding target information is obtained and added to the result string. For all, but the literal, the format value is taken as the as string to prepend to the output to join the item to the rest of the result. If not given "-" is used as a joiner. The format options can be: <base>[joiner] :: The basename of the target name. <toolset>[joiner] :: The abbreviated toolset tag being used to build the target. <threading>[joiner] :: Indication of a multi-threaded build. <runtime>[joiner] :: Collective tag of the build runtime. <version:/version-feature | X.Y[.Z]/>[joiner] :: Short version tag taken from the given "version-feature" in the build properties. Or if not present, the literal value as the version number. <property:/property-name/>[joiner] :: Direct lookup of the given property-name value in the build properties. /property-name/ is a regular expression. e.g. <property:toolset-.*:flavor> will match every toolset. /otherwise/ :: The literal value of the format argument. For example this format: boost_ <base> <toolset> <threading> <runtime> <version:boost-version> Might return: boost_thread-vc80-mt-gd-1_33.dll, or boost_regex-vc80-gd-1_33.dll The returned name also has the target type specific prefix and suffix which puts it in a ready form to use as the value from a custom tag rule. """

    if __debug__:
        from ..build.property_set import PropertySet
        assert is_iterable_typed(format, basestring)
        assert isinstance(name, basestring)
        assert isinstance(target_type, basestring)
        assert isinstance(prop_set, PropertySet)
    # assert(isinstance(prop_set, property_set.PropertySet))
    if type.is_derived(target_type, 'LIB'):
        result = "" ;
        for f in format:
            grist = get_grist(f)
            if grist == '<base>':
                result += os.path.basename(name)
            elif grist == '<toolset>':
                result += join_tag(get_value(f),
                    toolset_tag(name, target_type, prop_set))
            elif grist == '<threading>':
                result += join_tag(get_value(f),
                    threading_tag(name, target_type, prop_set))
            elif grist == '<runtime>':
                result += join_tag(get_value(f),
                    runtime_tag(name, target_type, prop_set))
            elif grist.startswith('<version:'):
                key = grist[len('<version:'):-1]
                version = prop_set.get('<' + key + '>')
                if not version:
                    version = key
                version = __re_version.match(version)
                result += join_tag(get_value(f), version[1] + '_' + version[2])
            elif grist.startswith('<property:'):
                key = grist[len('<property:'):-1]
                property_re = re.compile('<(' + key + ')>')
                p0 = None
                for prop in prop_set.raw():
                    match = property_re.match(prop)
                    if match:
                        p0 = match[1]
                        break
                if p0:
                    p = prop_set.get('<' + p0 + '>')
                    if p:
                        assert(len(p) == 1)
                        result += join_tag(ungrist(f), p)
            else:
                result += f

        result = b2.build.virtual_target.add_prefix_and_suffix(
            ''.join(result), target_type, prop_set)
        return result