ICU-4739 icupkg command-line tool, adds/removes/extracts items to/from ICU .dat data package files
X-SVN-Rev: 18467
This commit is contained in:
parent
180d06a431
commit
6a745cd16e
11
.gitignore
vendored
11
.gitignore
vendored
@ -394,6 +394,17 @@ icu4c/source/tools/genuca/Makefile
|
||||
icu4c/source/tools/genuca/Release
|
||||
icu4c/source/tools/genuca/genuca
|
||||
icu4c/source/tools/genuca/genuca.8
|
||||
icu4c/source/tools/icupkg/*.d
|
||||
icu4c/source/tools/icupkg/*.ncb
|
||||
icu4c/source/tools/icupkg/*.o
|
||||
icu4c/source/tools/icupkg/*.opt
|
||||
icu4c/source/tools/icupkg/*.pdb
|
||||
icu4c/source/tools/icupkg/*.plg
|
||||
icu4c/source/tools/icupkg/Debug
|
||||
icu4c/source/tools/icupkg/Makefile
|
||||
icu4c/source/tools/icupkg/Release
|
||||
icu4c/source/tools/icupkg/icupkg
|
||||
icu4c/source/tools/icupkg/icupkg.[0-9]
|
||||
icu4c/source/tools/icuswap/*.d
|
||||
icu4c/source/tools/icuswap/*.ncb
|
||||
icu4c/source/tools/icuswap/*.o
|
||||
|
@ -219,6 +219,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencase", "..\tools\gencase
|
||||
{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icupkg", "..\tools\icupkg\icupkg.vcproj", "{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
|
||||
{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@ -353,6 +359,10 @@ Global
|
||||
{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Debug.Build.0 = Debug|Win32
|
||||
{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release.ActiveCfg = Release|Win32
|
||||
{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release.Build.0 = Release|Win32
|
||||
{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug.ActiveCfg = Debug|Win32
|
||||
{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug.Build.0 = Debug|Win32
|
||||
{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release.ActiveCfg = Release|Win32
|
||||
{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
11
icu4c/source/tools/icupkg/.cvsignore
Normal file
11
icu4c/source/tools/icupkg/.cvsignore
Normal file
@ -0,0 +1,11 @@
|
||||
Debug
|
||||
Release
|
||||
Makefile
|
||||
*.d
|
||||
*.o
|
||||
*.pdb
|
||||
icupkg
|
||||
icupkg.[0-9]
|
||||
*.plg
|
||||
*.ncb
|
||||
*.opt
|
96
icu4c/source/tools/icupkg/Makefile.in
Normal file
96
icu4c/source/tools/icupkg/Makefile.in
Normal file
@ -0,0 +1,96 @@
|
||||
## Makefile.in for ICU - tools/icupkg
|
||||
## Copyright (c) 1999-2005, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
## Steven R. Loomis
|
||||
|
||||
## Source directory information
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
top_builddir = ../..
|
||||
|
||||
include $(top_builddir)/icudefs.mk
|
||||
|
||||
## Build directory information
|
||||
subdir = tools/icupkg
|
||||
|
||||
##
|
||||
|
||||
TARGET_STUB_NAME = icupkg
|
||||
|
||||
SECTION = 1
|
||||
|
||||
#MANX_FILES = $(TARGET_STUB_NAME).$(SECTION)
|
||||
|
||||
#ALL_MAN_FILES = $(MANX_FILES)
|
||||
|
||||
## Extra files to remove for 'make clean'
|
||||
CLEANFILES = *~ $(DEPS) $(ALL_MAN_FILES)
|
||||
|
||||
## Target information
|
||||
TARGET = $(BINDIR)/$(TARGET_STUB_NAME)$(EXEEXT)
|
||||
|
||||
CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(srcdir)/../toolutil $(BIR_CPPFLAGS)
|
||||
LIBS = $(LIBICUTOOLUTIL) $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS) $(LIB_M)
|
||||
|
||||
OBJECTS = icupkg.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
## List of phony targets
|
||||
.PHONY : all all-local install install-local clean clean-local \
|
||||
distclean distclean-local dist dist-local check \
|
||||
check-local install-man install-manx
|
||||
|
||||
## Clear suffix list
|
||||
.SUFFIXES :
|
||||
|
||||
## List of standard targets
|
||||
all: all-local
|
||||
install: install-local
|
||||
clean: clean-local
|
||||
distclean : distclean-local
|
||||
dist: dist-local
|
||||
check: all check-local
|
||||
|
||||
all-local: $(TARGET) $(ALL_MAN_FILES)
|
||||
|
||||
install-local: all-local install-man
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(sbindir)
|
||||
$(INSTALL) $(TARGET) $(DESTDIR)$(sbindir)
|
||||
|
||||
dist-local:
|
||||
|
||||
clean-local:
|
||||
test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
|
||||
$(RMV) $(TARGET) $(OBJECTS)
|
||||
|
||||
distclean-local: clean-local
|
||||
$(RMV) Makefile
|
||||
|
||||
check-local: all-local
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(TARGET) : $(OBJECTS)
|
||||
$(LINK.cc) $(OUTOPT)$@ $^ $(LIBS)
|
||||
|
||||
# man page
|
||||
install-man: install-manx
|
||||
install-manx: $(MANX_FILES)
|
||||
# $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$(SECTION)
|
||||
# $(INSTALL_DATA) $? $(DESTDIR)$(mandir)/man$(SECTION)
|
||||
|
||||
%.$(SECTION): $(srcdir)/%.$(SECTION).in
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
ifeq (,$(MAKECMDGOALS))
|
||||
-include $(DEPS)
|
||||
else
|
||||
ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
endif
|
472
icu4c/source/tools/icupkg/icupkg.cpp
Normal file
472
icu4c/source/tools/icupkg/icupkg.cpp
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: icupkg.cpp
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* created on: 2005jul29
|
||||
* created by: Markus W. Scherer
|
||||
*
|
||||
* This tool operates on ICU data (.dat package) files.
|
||||
* It takes one as input, or creates an empty one, and can remove, add, and
|
||||
* extract data pieces according to command-line options.
|
||||
* At the same time, it swaps each piece to a consistent set of platform
|
||||
* properties as desired.
|
||||
* Useful as an install-time tool for shipping only one flavor of ICU data
|
||||
* and preparing data files for the target platform.
|
||||
* Also for customizing ICU data (pruning, augmenting, replacing) and for
|
||||
* taking it apart.
|
||||
* Subsumes functionality and implementation code from
|
||||
* gencmn, decmn, and icuswap tools.
|
||||
* Will not work with data DLLs (shared libraries).
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "cstring.h"
|
||||
#include "toolutil.h"
|
||||
#include "uoptions.h"
|
||||
#include "uparse.h"
|
||||
#include "package.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO: add --matchmode=regex for using the ICU regex engine for item name pattern matching?
|
||||
|
||||
// general definitions ----------------------------------------------------- ***
|
||||
|
||||
#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
|
||||
|
||||
// read a file list -------------------------------------------------------- ***
|
||||
|
||||
static const char *reservedChars="\"%&'()*+,-./:;<=>?_";
|
||||
|
||||
/*
|
||||
* Read a file list.
|
||||
* If the listname ends with ".txt", then read the list file
|
||||
* (in the system/ invariant charset).
|
||||
* If the listname ends with ".dat", then read the ICU .dat package file.
|
||||
* Otherwise, read the file itself as a single-item list.
|
||||
*/
|
||||
static Package *
|
||||
readList(const char *filesPath, const char *listname, UBool readContents) {
|
||||
Package *listPkg;
|
||||
FILE *file;
|
||||
char *end;
|
||||
|
||||
if(listname==NULL || listname[0]==0) {
|
||||
fprintf(stderr, "missing list file\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listPkg=new Package();
|
||||
if(listPkg==NULL) {
|
||||
fprintf(stderr, "icupkg: not enough memory\n");
|
||||
exit(U_MEMORY_ALLOCATION_ERROR);
|
||||
}
|
||||
|
||||
end=strchr(listname, 0);
|
||||
if((end-listname)>4 && 0==memcmp(end-4, ".txt", 4)) {
|
||||
// read the list file
|
||||
char line[1024];
|
||||
const char *start;
|
||||
|
||||
file=fopen(listname, "r");
|
||||
if(file==NULL) {
|
||||
fprintf(stderr, "icupkg: unable to open list file \"%s\"\n", listname);
|
||||
delete listPkg;
|
||||
exit(U_FILE_ACCESS_ERROR);
|
||||
}
|
||||
|
||||
while(fgets(line, sizeof(line), file)) {
|
||||
// remove comments
|
||||
end=strchr(line, '#');
|
||||
if(end!=NULL) {
|
||||
*end=0;
|
||||
} else {
|
||||
// remove trailing CR LF
|
||||
end=strchr(line, 0);
|
||||
while(line<end && (*(end-1)=='\r' || *(end-1)=='\n')) {
|
||||
*--end=0;
|
||||
}
|
||||
}
|
||||
|
||||
// check first non-whitespace character and
|
||||
// skip empty lines and
|
||||
// skip lines starting with reserved characters
|
||||
start=u_skipWhitespace(line);
|
||||
if(*start==0 || NULL!=strchr(reservedChars, *start)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// take whitespace-separated items from the line
|
||||
for(;;) {
|
||||
// find whitespace after the item or the end of the line
|
||||
for(end=(char *)start; *end!=0 && *end!=' ' && *end!='\t'; ++end) {}
|
||||
if(*end==0) {
|
||||
// this item is the last one on the line
|
||||
end=NULL;
|
||||
} else {
|
||||
// the item is terminated by whitespace, terminate it with NUL
|
||||
*end=0;
|
||||
}
|
||||
if(readContents) {
|
||||
listPkg->addFile(filesPath, start);
|
||||
} else {
|
||||
listPkg->addItem(start);
|
||||
}
|
||||
|
||||
// find the start of the next item or exit the loop
|
||||
if(end==NULL || *(start=u_skipWhitespace(end+1))==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
} else if((end-listname)>4 && 0==memcmp(end-4, ".dat", 4)) {
|
||||
// read the ICU .dat package
|
||||
listPkg->readPackage(listname);
|
||||
} else {
|
||||
// list the single file itself
|
||||
if(readContents) {
|
||||
listPkg->addFile(filesPath, listname);
|
||||
} else {
|
||||
listPkg->addItem(listname);
|
||||
}
|
||||
}
|
||||
|
||||
return listPkg;
|
||||
}
|
||||
|
||||
// main() ------------------------------------------------------------------ ***
|
||||
|
||||
static void
|
||||
printUsage(const char *pname, UBool isHelp) {
|
||||
FILE *where=isHelp ? stdout : stderr;
|
||||
|
||||
fprintf(where,
|
||||
"%csage: %s [-h|-?|--help ] [-tl|-tb|-te] [-c] [-C comment]\n"
|
||||
"\t[-a list] [-r list] [-x list] [-l]\n"
|
||||
"\tinfilename [outfilename]\n",
|
||||
isHelp ? 'U' : 'u', pname);
|
||||
if(isHelp) {
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"Read the input ICU .dat package file, modify it according to the options,\n"
|
||||
"swap it to the desired platform properties (charset & endianness),\n"
|
||||
"and optionally write the resulting ICU .dat package to the output file.\n"
|
||||
"Items are removed, then added, then extracted and listed.\n"
|
||||
"An ICU .dat package is written if items are removed or added,\n"
|
||||
"or if the input and output filenames differ,\n"
|
||||
"or if the --writepkg (-w) option is set.\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"If the input filename is \"new\" then an empty package is created.\n"
|
||||
"If the output filename is missing, then it is automatically generated\n"
|
||||
"from the input filename: If the input filename ends with an l, b, or e\n"
|
||||
"matching its platform properties, then the output filename will\n"
|
||||
"contain the letter from the -t (--type) option.\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"\t(Only the last occurrence of an option is used.)\n"
|
||||
"\n"
|
||||
"\t-h or -? or --help print this message and exit\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\t-tl or --type l output for little-endian/ASCII charset family\n"
|
||||
"\t-tb or --type b output for big-endian/ASCII charset family\n"
|
||||
"\t-te or --type e output for big-endian/EBCDIC charset family\n"
|
||||
"\t The output type defaults to the input type.\n"
|
||||
"\n"
|
||||
"\t-c or --copyright include the ICU copyright notice\n"
|
||||
"\t-C comment or --comment comment include a comment string\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\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"
|
||||
"\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");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\t-w or --writepkg write the output package even if no items are removed\n"
|
||||
"\t or added (e.g., for only swapping the data)\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\t-m mode or --matchmode mode set the matching mode for item names with\n"
|
||||
"\t wildcards\n"
|
||||
"\t noslash: the '*' wildcard does not match the '/' tree separator\n");
|
||||
/*
|
||||
* Usage text columns, starting after the initial TAB.
|
||||
* 1 2 3 4 5 6 7 8
|
||||
* 901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
*/
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\tList file syntax: Items are listed on one or more lines and separated\n"
|
||||
"\tby whitespace (space+tab).\n"
|
||||
"\tComments begin with # and are ignored. Empty lines are ignored.\n"
|
||||
"\tLines where the first non-whitespace character is one of %s\n"
|
||||
"\tare also ignored, to reserve for future syntax.\n",
|
||||
reservedChars);
|
||||
fprintf(where,
|
||||
"\tItems for removal or extraction may contain a single '*' wildcard\n"
|
||||
"\tcharacter. The '*' matches zero or more characters.\n"
|
||||
"\tIf --matchmode noslash (-m noslash) is set, then the '*'\n"
|
||||
"\tdoes not match '/'.\n");
|
||||
fprintf(where,
|
||||
"\n"
|
||||
"\tItems must be listed relative to the package, and the --dir path\n"
|
||||
"\twill be prepended.\n"
|
||||
"\tThe --dir path is only prepended to item filenames, not to\n"
|
||||
"\tICU .dat package or list filenames.\n"
|
||||
"\n"
|
||||
"\t-d path or --dir path directory for the add/remove/extract items\n"
|
||||
"\t-l or --list list the package items to stdout\n"
|
||||
"\t (after modifying it)\n");
|
||||
}
|
||||
}
|
||||
|
||||
static UOption options[]={
|
||||
UOPTION_HELP_H,
|
||||
UOPTION_HELP_QUESTION_MARK,
|
||||
UOPTION_DEF("type", 't', UOPT_REQUIRES_ARG),
|
||||
|
||||
UOPTION_COPYRIGHT,
|
||||
UOPTION_DEF("comment", 'C', UOPT_REQUIRES_ARG),
|
||||
|
||||
UOPTION_DEF("dir", 'd', UOPT_REQUIRES_ARG),
|
||||
|
||||
UOPTION_DEF("writepkg", 'w', UOPT_NO_ARG),
|
||||
|
||||
UOPTION_DEF("matchmode", 'm', UOPT_REQUIRES_ARG),
|
||||
|
||||
UOPTION_DEF("add", 'a', UOPT_REQUIRES_ARG),
|
||||
UOPTION_DEF("remove", 'r', UOPT_REQUIRES_ARG),
|
||||
UOPTION_DEF("extract", 'x', UOPT_REQUIRES_ARG),
|
||||
|
||||
UOPTION_DEF("list", 'l', UOPT_NO_ARG)
|
||||
};
|
||||
|
||||
enum {
|
||||
OPT_HELP_H,
|
||||
OPT_HELP_QUESTION_MARK,
|
||||
OPT_OUT_TYPE,
|
||||
|
||||
OPT_COPYRIGHT,
|
||||
OPT_COMMENT,
|
||||
|
||||
OPT_DIR,
|
||||
|
||||
OPT_WRITEPKG,
|
||||
|
||||
OPT_MATCHMODE,
|
||||
|
||||
OPT_ADD_LIST,
|
||||
OPT_REMOVE_LIST,
|
||||
OPT_EXTRACT_LIST,
|
||||
|
||||
OPT_LIST_ITEMS,
|
||||
|
||||
OPT_COUNT
|
||||
};
|
||||
|
||||
extern int
|
||||
main(int argc, char *argv[]) {
|
||||
const char *pname, *filesPath, *inFilename, *outFilename, *outComment;
|
||||
char outType;
|
||||
UBool isHelp, isModified;
|
||||
|
||||
Package *pkg, *listPkg, *addListPkg;
|
||||
|
||||
U_MAIN_INIT_ARGS(argc, argv);
|
||||
|
||||
/* get the program basename */
|
||||
pname=findBasename(argv[0]);
|
||||
|
||||
argc=u_parseArgs(argc, argv, LENGTHOF(options), options);
|
||||
isHelp=options[OPT_HELP_H].doesOccur || options[OPT_HELP_QUESTION_MARK].doesOccur;
|
||||
if(isHelp) {
|
||||
printUsage(pname, TRUE);
|
||||
return U_ZERO_ERROR;
|
||||
}
|
||||
if(argc<2 || 3<argc) {
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
pkg=new Package;
|
||||
if(pkg==NULL) {
|
||||
fprintf(stderr, "icupkg: not enough memory\n");
|
||||
return U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
isModified=FALSE;
|
||||
|
||||
if(options[OPT_DIR].doesOccur) {
|
||||
filesPath=options[OPT_DIR].value;
|
||||
} else {
|
||||
// work relative to the current working directory
|
||||
filesPath=NULL;
|
||||
}
|
||||
|
||||
if(0==strcmp(argv[1], "new")) {
|
||||
inFilename=NULL;
|
||||
} else {
|
||||
inFilename=argv[1];
|
||||
pkg->readPackage(inFilename);
|
||||
}
|
||||
|
||||
if(argc>=3) {
|
||||
outFilename=argv[2];
|
||||
if(0!=strcmp(argv[1], argv[2])) {
|
||||
isModified=TRUE;
|
||||
}
|
||||
} else {
|
||||
outFilename=NULL;
|
||||
}
|
||||
|
||||
/* parse the output type option */
|
||||
if(options[OPT_OUT_TYPE].doesOccur) {
|
||||
const char *type=options[OPT_OUT_TYPE].value;
|
||||
if(type[0]==0 || type[1]!=0) {
|
||||
/* the type must be exactly one letter */
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
outType=type[0];
|
||||
switch(outType) {
|
||||
case 'l':
|
||||
case 'b':
|
||||
case 'e':
|
||||
break;
|
||||
default:
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
} else {
|
||||
outType=pkg->getInType(); // default to input type
|
||||
}
|
||||
|
||||
if(options[OPT_WRITEPKG].doesOccur) {
|
||||
isModified=TRUE;
|
||||
}
|
||||
|
||||
if(options[OPT_COMMENT].doesOccur) {
|
||||
outComment=options[OPT_COMMENT].value;
|
||||
} else if(options[OPT_COPYRIGHT].doesOccur) {
|
||||
outComment=U_COPYRIGHT_STRING;
|
||||
} else {
|
||||
outComment=NULL;
|
||||
}
|
||||
|
||||
if(options[OPT_MATCHMODE].doesOccur) {
|
||||
if(0==strcmp(options[OPT_MATCHMODE].value, "noslash")) {
|
||||
pkg->setMatchMode(Package::MATCH_NOSLASH);
|
||||
} else {
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove items */
|
||||
if(options[OPT_REMOVE_LIST].doesOccur) {
|
||||
listPkg=readList(NULL, options[OPT_REMOVE_LIST].value, FALSE);
|
||||
if(listPkg!=NULL) {
|
||||
pkg->removeItems(*listPkg);
|
||||
delete listPkg;
|
||||
isModified=TRUE;
|
||||
} else {
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add items
|
||||
* use a separate Package so that its memory and items stay around
|
||||
* as long as the main Package
|
||||
*/
|
||||
if(options[OPT_ADD_LIST].doesOccur) {
|
||||
addListPkg=readList(filesPath, options[OPT_ADD_LIST].value, TRUE);
|
||||
if(addListPkg!=NULL) {
|
||||
pkg->addItems(*addListPkg);
|
||||
// do not delete addListPkg;
|
||||
isModified=TRUE;
|
||||
} else {
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
} else {
|
||||
addListPkg=NULL;
|
||||
}
|
||||
|
||||
/* extract items */
|
||||
if(options[OPT_EXTRACT_LIST].doesOccur) {
|
||||
listPkg=readList(NULL, options[OPT_EXTRACT_LIST].value, FALSE);
|
||||
if(listPkg!=NULL) {
|
||||
pkg->extractItems(filesPath, *listPkg, outType);
|
||||
delete listPkg;
|
||||
} else {
|
||||
printUsage(pname, FALSE);
|
||||
return U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* list items */
|
||||
if(options[OPT_LIST_ITEMS].doesOccur) {
|
||||
pkg->listItems(stdout);
|
||||
}
|
||||
|
||||
/* write the output .dat package if there are any modifications */
|
||||
if(isModified) {
|
||||
char outFilenameBuffer[1024]; // for auto-generated output filename, if necessary
|
||||
|
||||
if(outFilename==NULL || outFilename[0]==0) {
|
||||
if(inFilename==NULL || inFilename[0]==0) {
|
||||
fprintf(stderr, "icupkg: unable to auto-generate an output filename if there is no input filename\n");
|
||||
exit(U_ILLEGAL_ARGUMENT_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* auto-generate a filename:
|
||||
* copy the inFilename,
|
||||
* and if the last basename character matches the input file's type,
|
||||
* then replace it with the output file's type
|
||||
*/
|
||||
char suffix[6]="?.dat";
|
||||
char *s;
|
||||
|
||||
suffix[0]=pkg->getInType();
|
||||
strcpy(outFilenameBuffer, inFilename);
|
||||
s=strchr(outFilenameBuffer, 0);
|
||||
if((s-outFilenameBuffer)>5 && 0==memcmp(s-5, suffix, 5)) {
|
||||
*(s-5)=outType;
|
||||
}
|
||||
outFilename=outFilenameBuffer;
|
||||
}
|
||||
pkg->writePackage(outFilename, outType, outComment);
|
||||
}
|
||||
|
||||
delete pkg;
|
||||
delete addListPkg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hey, Emacs, please set the following:
|
||||
*
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
*/
|
143
icu4c/source/tools/icupkg/icupkg.vcproj
Normal file
143
icu4c/source/tools/icupkg/icupkg.vcproj
Normal file
@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="icupkg"
|
||||
ProjectGUID="{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
AdditionalIncludeDirectories="..\..\common;..\toolutil"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
DisableLanguageExtensions="TRUE"
|
||||
PrecompiledHeaderFile="Release/icupkg.pch"
|
||||
AssemblerListingLocation="Release/"
|
||||
ObjectFile="Release/"
|
||||
ProgramDataBaseFileName="Release/"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(TargetPath)" ..\..\..\bin
|
||||
"
|
||||
Outputs="..\..\..\bin\$(TargetFileName)"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/icupkg.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ProgramDatabaseFile="Release/icupkg.pdb"
|
||||
SubSystem="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
AdditionalIncludeDirectories="..\..\common;..\toolutil"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="TRUE"
|
||||
DisableLanguageExtensions="TRUE"
|
||||
PrecompiledHeaderFile="Debug/icupkg.pch"
|
||||
AssemblerListingLocation="Debug/"
|
||||
ObjectFile="Debug/"
|
||||
ProgramDataBaseFileName="Debug/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(TargetPath)" ..\..\..\bin
|
||||
"
|
||||
Outputs="..\..\..\bin\$(TargetFileName)"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/icupkg.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/icupkg.pdb"
|
||||
SubSystem="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="icupkg.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -42,7 +42,9 @@ CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n
|
||||
DEFS += -DU_TOOLUTIL_IMPLEMENTATION
|
||||
LIBS = $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS)
|
||||
|
||||
OBJECTS = filestrm.o propsvec.o toolutil.o unewdata.o ucm.o ucmstate.o uoptions.o uparse.o ucbuf.o xmlparser.o writesrc.o
|
||||
OBJECTS = filestrm.o package.o propsvec.o swapimpl.o toolutil.o unewdata.o \
|
||||
ucm.o ucmstate.o uoptions.o uparse.o \
|
||||
ucbuf.o xmlparser.o writesrc.o
|
||||
|
||||
STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O))
|
||||
|
||||
|
1157
icu4c/source/tools/toolutil/package.cpp
Normal file
1157
icu4c/source/tools/toolutil/package.cpp
Normal file
File diff suppressed because it is too large
Load Diff
143
icu4c/source/tools/toolutil/package.h
Normal file
143
icu4c/source/tools/toolutil/package.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: package.h
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* created on: 2005aug25
|
||||
* created by: Markus W. Scherer
|
||||
*
|
||||
* Read, modify, and write ICU .dat data package files.
|
||||
*/
|
||||
|
||||
#ifndef __PACKAGE_H__
|
||||
#define __PACKAGE_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// .dat package file representation ---------------------------------------- ***
|
||||
|
||||
#define STRING_STORE_SIZE 100000
|
||||
#define MAX_FILE_COUNT 2000
|
||||
#define MAX_PKG_NAME_LENGTH 32
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct Item {
|
||||
char *name;
|
||||
uint8_t *data;
|
||||
int32_t length;
|
||||
UBool isDataOwned;
|
||||
char type;
|
||||
};
|
||||
|
||||
class U_TOOLUTIL_API Package {
|
||||
public:
|
||||
/*
|
||||
* Constructor.
|
||||
* Prepare this object for a new, empty package.
|
||||
*/
|
||||
Package();
|
||||
|
||||
/* Destructor. */
|
||||
~Package();
|
||||
|
||||
/*
|
||||
* Read an existing .dat package file.
|
||||
* The header and item name strings are swapped into this object,
|
||||
* but the items are left unswapped.
|
||||
*/
|
||||
void readPackage(const char *filename);
|
||||
/*
|
||||
* Write a .dat package file with the items in this object.
|
||||
* Swap all pieces to the desired output platform properties.
|
||||
* The package becomes unusable:
|
||||
* The item names are swapped and sorted in the outCharset rather than the local one.
|
||||
* Also, the items themselves are swapped in-place
|
||||
*/
|
||||
void writePackage(const char *filename, char outType, const char *comment);
|
||||
|
||||
/*
|
||||
* Return the input data type letter (l, b, or e).
|
||||
*/
|
||||
char getInType();
|
||||
|
||||
// find the item in items[], return the non-negative index if found, else the binary-not of the insertion point
|
||||
int32_t findItem(const char *name, int32_t length=-1);
|
||||
|
||||
/*
|
||||
* Set internal state for following calls to findNextItem() which will return
|
||||
* indexes for items whose names match the pattern.
|
||||
*/
|
||||
void findItems(const char *pattern);
|
||||
int32_t findNextItem();
|
||||
/*
|
||||
* Set the match mode for findItems() & findNextItem().
|
||||
* @param mode 0=default
|
||||
* MATCH_NOSLASH * does not match a '/'
|
||||
*/
|
||||
void setMatchMode(uint32_t mode);
|
||||
|
||||
enum {
|
||||
MATCH_NOSLASH=1
|
||||
};
|
||||
|
||||
void addItem(const char *name);
|
||||
void addItem(const char *name, uint8_t *data, int32_t length, UBool isDataOwned, char type);
|
||||
void addFile(const char *filesPath, const char *name);
|
||||
void addItems(const Package &listPkg);
|
||||
|
||||
void removeItem(int32_t index);
|
||||
void removeItems(const char *pattern);
|
||||
void removeItems(const Package &listPkg);
|
||||
|
||||
void extractItem(const char *filesPath, int32_t index, char outType);
|
||||
void extractItems(const char *filesPath, const char *pattern, char outType);
|
||||
void extractItems(const char *filesPath, const Package &listPkg, char outType);
|
||||
|
||||
void listItems(FILE *file);
|
||||
|
||||
private:
|
||||
/*
|
||||
* Allocate a string in inStrings or outStrings.
|
||||
* The length does not include the terminating NUL.
|
||||
*/
|
||||
char *allocString(UBool in, int32_t length);
|
||||
|
||||
void sortItems();
|
||||
|
||||
// data fields
|
||||
char inPkgName[MAX_PKG_NAME_LENGTH];
|
||||
|
||||
uint8_t *inData;
|
||||
uint8_t header[1024];
|
||||
int32_t inLength, headerLength;
|
||||
uint8_t inCharset;
|
||||
UBool inIsBigEndian;
|
||||
|
||||
int32_t itemCount;
|
||||
Item items[MAX_FILE_COUNT];
|
||||
|
||||
int32_t inStringTop, outStringTop;
|
||||
char inStrings[STRING_STORE_SIZE], outStrings[STRING_STORE_SIZE];
|
||||
|
||||
// match mode for findItems(pattern) and findNextItem()
|
||||
uint32_t matchMode;
|
||||
|
||||
// state for findItems(pattern) and findNextItem()
|
||||
const char *findPrefix, *findSuffix;
|
||||
int32_t findPrefixLength, findSuffixLength;
|
||||
int32_t findNextIndex;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
@ -148,9 +148,15 @@
|
||||
<File
|
||||
RelativePath=".\filestrm.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\package.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\propsvec.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\swapimpl.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\toolutil.c">
|
||||
</File>
|
||||
@ -185,9 +191,15 @@
|
||||
<File
|
||||
RelativePath=".\filestrm.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\package.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\propsvec.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\swapimpl.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\toolutil.h">
|
||||
</File>
|
||||
|
Loading…
Reference in New Issue
Block a user