From 39e54b9167feb6bbc9994ed88ac9dda64be6246f Mon Sep 17 00:00:00 2001 From: Diego Frias Date: Sat, 5 Jul 2025 12:40:04 -0700 Subject: [PATCH] ICU-23156 Implement `icupkg --keep` option --- icu4c/source/tools/icupkg/icupkg.cpp | 23 ++++++++++++++++- icu4c/source/tools/toolutil/package.cpp | 33 +++++++++++++++++++++++++ icu4c/source/tools/toolutil/package.h | 4 +++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/icu4c/source/tools/icupkg/icupkg.cpp b/icu4c/source/tools/icupkg/icupkg.cpp index 3da4af745786..cc65b4f8a24f 100644 --- a/icu4c/source/tools/icupkg/icupkg.cpp +++ b/icu4c/source/tools/icupkg/icupkg.cpp @@ -57,7 +57,7 @@ printUsage(const char *pname, UBool isHelp) { fprintf(where, "%csage: %s [-h|-?|--help ] [-tl|-tb|-te] [-c] [-C comment]\n" - "\t[-a list] [-r list] [-x list] [-l [-o outputListFileName]]\n" + "\t[-a list] [-r list] [-x list] [-k list] [-l [-o outputListFileName]]\n" "\t[-s path] [-d path] [-w] [-m mode]\n" "\t[--ignore-deps]\n" "\t[--auto_toc_prefix] [--auto_toc_prefix_with_type] [--toc_prefix]\n" @@ -108,6 +108,7 @@ printUsage(const char *pname, UBool isHelp) { "\t-a list or --add list add items to the package\n" "\t-r list or --remove list remove items from the package\n" "\t-x list or --extract list extract items from the package\n" + "\t-k list or --keep list keep only certain items from the package\n" "\tThe list can be a single item's filename,\n" "\tor a .txt filename with a list of item filenames,\n" "\tor an ICU .dat package filename.\n"); @@ -208,6 +209,7 @@ static UOption options[]={ UOPTION_DEF("add", 'a', UOPT_REQUIRES_ARG), UOPTION_DEF("remove", 'r', UOPT_REQUIRES_ARG), UOPTION_DEF("extract", 'x', UOPT_REQUIRES_ARG), + UOPTION_DEF("keep", 'k', UOPT_REQUIRES_ARG), UOPTION_DEF("list", 'l', UOPT_NO_ARG), UOPTION_DEF("outlist", 'o', UOPT_REQUIRES_ARG), @@ -237,6 +239,7 @@ enum { OPT_ADD_LIST, OPT_REMOVE_LIST, OPT_EXTRACT_LIST, + OPT_KEEP_LIST, OPT_LIST_ITEMS, OPT_LIST_FILE, @@ -400,6 +403,7 @@ main(int argc, char *argv[]) { options[OPT_REMOVE_LIST].doesOccur || options[OPT_ADD_LIST].doesOccur || options[OPT_EXTRACT_LIST].doesOccur || + options[OPT_KEEP_LIST].doesOccur || options[OPT_LIST_ITEMS].doesOccur ) { printUsage(pname, false); @@ -487,6 +491,23 @@ main(int argc, char *argv[]) { } } + /* keep items */ + if(options[OPT_KEEP_LIST].doesOccur) { + listPkg=new Package(); + if(listPkg==nullptr) { + fprintf(stderr, "icupkg: not enough memory\n"); + exit(U_MEMORY_ALLOCATION_ERROR); + } + if(readList(nullptr, options[OPT_KEEP_LIST].value, false, listPkg)) { + pkg->keepItems(*listPkg); + delete listPkg; + isModified=true; + } else { + printUsage(pname, false); + return U_ILLEGAL_ARGUMENT_ERROR; + } + } + /* list items */ if(options[OPT_LIST_ITEMS].doesOccur) { int32_t i; diff --git a/icu4c/source/tools/toolutil/package.cpp b/icu4c/source/tools/toolutil/package.cpp index e58c6648b647..7b827036d204 100644 --- a/icu4c/source/tools/toolutil/package.cpp +++ b/icu4c/source/tools/toolutil/package.cpp @@ -431,6 +431,18 @@ Package::~Package() { uprv_free((void*)items); } +void +Package::clear() { + for(int32_t idx=0; idx=sizeof(pkgPrefix)) { @@ -1206,6 +1218,27 @@ Package::extractItems(const char *filesPath, const Package &listPkg, char outTyp } } +void +Package::keepItems(const Package &listPkg) { + Package *keepPkg=new Package(); + + const Item *pItem; + int32_t i; + for(pItem=listPkg.items, i=0; iname); + while((idx=findNextItem())>=0) { + const Item *item=getItem(idx); + keepPkg->addItem(item->name, item->data, item->length, false, item->type); + } + } + + clear(); + addItems(*keepPkg); + + delete keepPkg; +} + int32_t Package::getItemCount() const { return itemCount; diff --git a/icu4c/source/tools/toolutil/package.h b/icu4c/source/tools/toolutil/package.h index ea60c13a74a5..023ffde69665 100644 --- a/icu4c/source/tools/toolutil/package.h +++ b/icu4c/source/tools/toolutil/package.h @@ -53,6 +53,8 @@ class U_TOOLUTIL_API Package { /* Destructor. */ ~Package(); + void clear(); + /** * Uses the prefix of the first entry of the package in readPackage(), * rather than the package basename. @@ -124,6 +126,8 @@ class U_TOOLUTIL_API Package { /* This variant extracts an item to a specific filename. */ void extractItem(const char *filesPath, const char *outName, int32_t itemIndex, char outType); + void keepItems(const Package &listPkg); + int32_t getItemCount() const; const Item *getItem(int32_t idx) const;