示例#1
0
        /// <summary>
        /// Returns a list of all items in the provided item group whose itemspecs match the specification, after it is split and any wildcards are expanded.
        /// If not items match, returns null.
        /// </summary>
        internal static List <BuildItem> FindItemsMatchingSpecification(BuildItemGroup items, string specification, XmlAttribute attribute, Expander expander, string baseDirectory)
        {
            if (items.Count == 0 || specification.Length == 0)
            {
                return(null);
            }

            // This is a hashtable whose key is the filename for the individual items
            // in the Exclude list, after wildcard expansion.  The value in the hash table
            // is just an empty string.
            Hashtable specificationsToFind = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // Split by semicolons
            List <string> specificationPieces = expander.ExpandAllIntoStringListLeaveEscaped(specification, attribute);

            foreach (string piece in specificationPieces)
            {
                // Take each individual path or file expression, and expand any
                // wildcards.  Then loop through each file returned, and add it
                // to our hashtable.

                // Don't unescape wildcards just yet - if there were any escaped, the caller wants to treat them
                // as literals. Everything else is safe to unescape at this point, since we're only matching
                // against the file system.
                string[] fileList = EngineFileUtilities.GetFileListEscaped(baseDirectory, piece);

                foreach (string file in fileList)
                {
                    // Now unescape everything, because this is the end of the road for this filename.
                    // We're just going to compare it to the unescaped include path to filter out the
                    // file excludes.
                    specificationsToFind[EscapingUtilities.UnescapeAll(file)] = String.Empty;
                }
            }

            if (specificationsToFind.Count == 0)
            {
                return(null);
            }

            // Now loop through our list and filter out any that match a
            // filename in the remove list.
            List <BuildItem> itemsRemoved = new List <BuildItem>();

            foreach (BuildItem item in items)
            {
                // Even if the case for the excluded files is different, they
                // will still get excluded, as expected.  However, if the excluded path
                // references the same file in a different way, such as by relative
                // path instead of absolute path, we will not realize that they refer
                // to the same file, and thus we will not exclude it.
                if (specificationsToFind.ContainsKey(item.FinalItemSpec))
                {
                    itemsRemoved.Add(item);
                }
            }

            return(itemsRemoved);
        }