summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Include
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2021-01-13 09:54:49 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-01-19 18:23:28 +0000
commit101c55ac0db79b9ccff8b612f11755a3d473a82c (patch)
tree5c1cf46a33afe2e13339e1d61a311edd5fcc83da /ShellPkg/Include
parentef03e72651b8160b31c2b34ce4dfdf25bc328f20 (diff)
downloadedk2-101c55ac0db79b9ccff8b612f11755a3d473a82c.tar.gz
edk2-101c55ac0db79b9ccff8b612f11755a3d473a82c.tar.bz2
edk2-101c55ac0db79b9ccff8b612f11755a3d473a82c.zip
ShellPkg/ShellCommandLib: add ShellSortFileList()
Introduce the ShellSortFileList() function, for sorting an EFI_SHELL_FILE_INFO list, by FileName or by FullName. Duplicates can be kept in the same list, or separated out to a new list. In either case, the relative order between duplicates does not change (the sorting is stable). For the sorting, use OrderedCollectionLib rather than SortLib: - The PerformQuickSort() function from the latter has quadratic worst-case time complexity, plus it is implemented recursively (see "MdeModulePkg/Library/UefiSortLib/UefiSortLib.c"). It can also not return an error on memory allocation failure. - In comparison, the Red-Black Tree instance of OrderedCollectionLib sorts in O(n*log(n)) worst-case time, contains no recursion with the default PcdValidateOrderedCollection=FALSE setting, and the OrderedCollectionLib class APIs return errors appropriately. The OrderedCollectionLib APIs do not permit duplicates natively, but by using lists as collection entries, stable sorting of duplicates can be achieved. Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Zhichao Gao <zhichao.gao@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3151 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Zhichao Gao <zhichao.gao@intel.com> Message-Id: <20210113085453.10168-7-lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Diffstat (limited to 'ShellPkg/Include')
-rw-r--r--ShellPkg/Include/Library/ShellCommandLib.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/ShellPkg/Include/Library/ShellCommandLib.h b/ShellPkg/Include/Library/ShellCommandLib.h
index 63fcac82a2..bc1afed5e7 100644
--- a/ShellPkg/Include/Library/ShellCommandLib.h
+++ b/ShellPkg/Include/Library/ShellCommandLib.h
@@ -714,4 +714,85 @@ CatSDumpHex (
IN UINTN DataSize,
IN VOID *UserData
);
+
+//
+// Determines the ordering operation for ShellSortFileList().
+//
+typedef enum {
+ //
+ // Sort the EFI_SHELL_FILE_INFO objects by the FileName field, in increasing
+ // order, using gUnicodeCollation->StriColl().
+ //
+ ShellSortFileListByFileName,
+ //
+ // Sort the EFI_SHELL_FILE_INFO objects by the FullName field, in increasing
+ // order, using gUnicodeCollation->StriColl().
+ //
+ ShellSortFileListByFullName,
+ ShellSortFileListMax
+} SHELL_SORT_FILE_LIST;
+
+/**
+ Sort an EFI_SHELL_FILE_INFO list, optionally moving duplicates to a separate
+ list.
+
+ @param[in,out] FileList The list of EFI_SHELL_FILE_INFO objects to sort.
+
+ If FileList is NULL on input, then FileList is
+ considered an empty, hence already sorted, list.
+
+ Otherwise, if (*FileList) is NULL on input, then
+ EFI_INVALID_PARAMETER is returned.
+
+ Otherwise, the caller is responsible for having
+ initialized (*FileList)->Link with
+ InitializeListHead(). No other fields in the
+ (**FileList) head element are accessed by this
+ function.
+
+ On output, (*FileList) is sorted according to Order.
+ If Duplicates is NULL on input, then duplicate
+ elements are preserved, sorted stably, on
+ (*FileList). If Duplicates is not NULL on input,
+ then duplicates are moved (stably sorted) to the
+ new, dynamically allocated (*Duplicates) list.
+
+ @param[out] Duplicates If Duplicates is NULL on input, (*FileList) will be
+ a monotonically ordered list on output, with
+ duplicates stably sorted.
+
+ If Duplicates is not NULL on input, (*FileList) will
+ be a strictly monotonically oredered list on output,
+ with duplicates separated (stably sorted) to
+ (*Duplicates). All fields except Link will be
+ zero-initialized in the (**Duplicates) head element.
+ If no duplicates exist, then (*Duplicates) is set to
+ NULL on output.
+
+ @param[in] Order Determines the comparison operation between
+ EFI_SHELL_FILE_INFO objects.
+
+ @retval EFI_INVALID_PARAMETER (UINTN)Order is greater than or equal to
+ (UINTN)ShellSortFileListMax. Neither the
+ (*FileList) nor the (*Duplicates) list has
+ been modified.
+
+ @retval EFI_INVALID_PARAMETER (*FileList) was NULL on input. Neither the
+ (*FileList) nor the (*Duplicates) list has
+ been modified.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed. Neither the
+ (*FileList) nor the (*Duplicates) list has
+ been modified.
+
+ @retval EFI_SUCCESS Sorting successful, including the case when
+ FileList is NULL on input.
+**/
+EFI_STATUS
+EFIAPI
+ShellSortFileList (
+ IN OUT EFI_SHELL_FILE_INFO **FileList,
+ OUT EFI_SHELL_FILE_INFO **Duplicates OPTIONAL,
+ IN SHELL_SORT_FILE_LIST Order
+ );
#endif //_SHELL_COMMAND_LIB_