Skip to content

ICU-23156 Implement icupkg --keep option #3547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion icu4c/source/tools/icupkg/icupkg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -237,6 +239,7 @@ enum {
OPT_ADD_LIST,
OPT_REMOVE_LIST,
OPT_EXTRACT_LIST,
OPT_KEEP_LIST,

OPT_LIST_ITEMS,
OPT_LIST_FILE,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
33 changes: 33 additions & 0 deletions icu4c/source/tools/toolutil/package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,18 @@ Package::~Package() {
uprv_free((void*)items);
}

void
Package::clear() {
for(int32_t idx=0; idx<itemCount; ++idx) {
if(items[idx].isDataOwned) {
uprv_free(items[idx].data);
}
}
memset(items, 0, itemCount*sizeof(Item));
itemCount=0;
findNextIndex=-1;
}

void
Package::setPrefix(const char *p) {
if(strlen(p)>=sizeof(pkgPrefix)) {
Expand Down Expand Up @@ -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; i<listPkg.itemCount; ++pItem, ++i) {
int32_t idx;
findItems(pItem->name);
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;
Expand Down
4 changes: 4 additions & 0 deletions icu4c/source/tools/toolutil/package.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down