1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 *
6 * Copyright (C) 1999-2012, International Business Machines
7 * Corporation and others. All Rights Reserved.
8 *
9 *******************************************************************************
10 * file name: genprops.cpp
11 * encoding: US-ASCII
12 * tab size: 8 (not used)
13 * indentation:4
14 *
15 * created on: 1999dec08
16 * created by: Markus W. Scherer
17 *
18 * This program parses the ppucd.txt preparsed Unicode Character Database file
19 * and writes several source and binary files into the ICU source tree.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "unicode/utypes.h"
25 #include "unicode/localpointer.h"
26 #include "unicode/uniset.h"
27 #include "unicode/unistr.h"
28 #include "charstr.h"
29 #include "genprops.h"
30 #include "ppucd.h"
31 #include "toolutil.h"
32 #include "uoptions.h"
33
34 U_NAMESPACE_USE
35
36 UBool beVerbose=FALSE;
37 UBool beQuiet=FALSE;
38
PropsBuilder()39 PropsBuilder::PropsBuilder() {}
~PropsBuilder()40 PropsBuilder::~PropsBuilder() {}
setUnicodeVersion(const UVersionInfo)41 void PropsBuilder::setUnicodeVersion(const UVersionInfo) {}
setAlgNamesRange(UChar32,UChar32,const char *,const char *,UErrorCode &)42 void PropsBuilder::setAlgNamesRange(UChar32, UChar32,
43 const char *, const char *, UErrorCode &) {}
setProps(const UniProps &,const UnicodeSet &,UErrorCode &)44 void PropsBuilder::setProps(const UniProps &, const UnicodeSet &, UErrorCode &) {}
build(UErrorCode &)45 void PropsBuilder::build(UErrorCode &) {}
writeCSourceFile(const char *,UErrorCode &)46 void PropsBuilder::writeCSourceFile(const char *, UErrorCode &) {}
writeJavaSourceFile(const char *,UErrorCode &)47 void PropsBuilder::writeJavaSourceFile(const char *, UErrorCode &) {}
writeBinaryData(const char *,UBool,UErrorCode &)48 void PropsBuilder::writeBinaryData(const char *, UBool, UErrorCode &) {}
49
50 enum {
51 HELP_H,
52 HELP_QUESTION_MARK,
53 VERBOSE,
54 QUIET,
55 COPYRIGHT
56 };
57
58 /* Keep these values in sync with the above enums */
59 static UOption options[]={
60 UOPTION_HELP_H,
61 UOPTION_HELP_QUESTION_MARK,
62 UOPTION_VERBOSE,
63 UOPTION_QUIET,
64 UOPTION_COPYRIGHT
65 };
66
67 extern int
main(int argc,char * argv[])68 main(int argc, char* argv[]) {
69 U_MAIN_INIT_ARGS(argc, argv);
70 argc=u_parseArgs(argc, argv, LENGTHOF(options), options);
71
72 /* error handling, printing usage message */
73 if(argc<0) {
74 fprintf(stderr,
75 "error in command line argument \"%s\"\n",
76 argv[-argc]);
77 }
78 if(argc<2 || options[HELP_H].doesOccur || options[HELP_QUESTION_MARK].doesOccur) {
79 /*
80 * Broken into chunks because the C89 standard says the minimum
81 * required supported string length is 509 bytes.
82 */
83 fprintf(stderr,
84 "Usage: %s [-options] path/to/ICU/src/root\n"
85 "\n"
86 "Reads the preparsed UCD file path/to/ICU/src/root/source/data/unidata/ppucd.txt and\n"
87 "writes source and binary data files with the character properties.\n"
88 "(UCD=Unicode Character Database)\n"
89 "\n",
90 argv[0]);
91 fprintf(stderr,
92 "Options:\n"
93 "\t-h or -? or --help this usage text\n"
94 "\t-v or --verbose verbose output\n"
95 "\t-q or --quiet no output\n"
96 "\t-c or --copyright include a copyright notice\n");
97 return argc<2 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
98 }
99
100 /* get the options values */
101 beVerbose=options[VERBOSE].doesOccur;
102 beQuiet=options[QUIET].doesOccur;
103
104 /* initialize */
105 IcuToolErrorCode errorCode("genprops");
106 LocalPointer<PNamesBuilder> pnamesBuilder(createPNamesBuilder(errorCode));
107 LocalPointer<PropsBuilder> corePropsBuilder(createCorePropsBuilder(errorCode));
108 LocalPointer<PropsBuilder> bidiPropsBuilder(createBiDiPropsBuilder(errorCode));
109 LocalPointer<PropsBuilder> casePropsBuilder(createCasePropsBuilder(errorCode));
110 LocalPointer<PropsBuilder> layoutPropsBuilder(createLayoutPropsBuilder(errorCode));
111 LocalPointer<PropsBuilder> namesPropsBuilder(createNamesPropsBuilder(errorCode));
112 if(errorCode.isFailure()) {
113 fprintf(stderr, "genprops: unable to create PropsBuilders - %s\n", errorCode.errorName());
114 return errorCode.reset();
115 }
116
117 CharString icuSrcRoot(argv[1], errorCode);
118
119 CharString icuSource(icuSrcRoot, errorCode);
120 icuSource.appendPathPart("source", errorCode);
121
122 CharString icuSourceData(icuSource, errorCode);
123 icuSourceData.appendPathPart("data", errorCode);
124
125 CharString ppucdPath(icuSourceData, errorCode);
126 ppucdPath.appendPathPart("unidata", errorCode);
127 ppucdPath.appendPathPart("ppucd.txt", errorCode);
128
129 PreparsedUCD ppucd(ppucdPath.data(), errorCode);
130 if(errorCode.isFailure()) {
131 fprintf(stderr, "genprops: unable to open %s - %s\n",
132 ppucdPath.data(), errorCode.errorName());
133 return errorCode.reset();
134 }
135
136 // The PNamesBuilder uses preparsed pnames_data.h.
137 pnamesBuilder->build(errorCode);
138 if(U_FAILURE(errorCode)) {
139 fprintf(stderr, "genprops: PNamesBuilder::build() failed - %s\n",
140 errorCode.errorName());
141 return errorCode.reset();
142 }
143 ppucd.setPropertyNames(pnamesBuilder->getPropertyNames());
144
145 PreparsedUCD::LineType lineType;
146 UnicodeSet newValues;
147 while((lineType=ppucd.readLine(errorCode))!=PreparsedUCD::NO_LINE) {
148 if(ppucd.lineHasPropertyValues()) {
149 const UniProps *props=ppucd.getProps(newValues, errorCode);
150 corePropsBuilder->setProps(*props, newValues, errorCode);
151 bidiPropsBuilder->setProps(*props, newValues, errorCode);
152 casePropsBuilder->setProps(*props, newValues, errorCode);
153 layoutPropsBuilder->setProps(*props, newValues, errorCode);
154 namesPropsBuilder->setProps(*props, newValues, errorCode);
155 } else if(lineType==PreparsedUCD::UNICODE_VERSION_LINE) {
156 const UVersionInfo &version=ppucd.getUnicodeVersion();
157 corePropsBuilder->setUnicodeVersion(version);
158 bidiPropsBuilder->setUnicodeVersion(version);
159 casePropsBuilder->setUnicodeVersion(version);
160 layoutPropsBuilder->setUnicodeVersion(version);
161 namesPropsBuilder->setUnicodeVersion(version);
162 } else if(lineType==PreparsedUCD::ALG_NAMES_RANGE_LINE) {
163 UChar32 start, end;
164 if(ppucd.getRangeForAlgNames(start, end, errorCode)) {
165 const char *type=ppucd.nextField();
166 const char *prefix=ppucd.nextField(); // NULL if type==hangul
167 namesPropsBuilder->setAlgNamesRange(start, end, type, prefix, errorCode);
168 }
169 }
170 if(errorCode.isFailure()) {
171 fprintf(stderr,
172 "genprops: error parsing or setting values from ppucd.txt line %ld - %s\n",
173 (long)ppucd.getLineNumber(), errorCode.errorName());
174 return errorCode.reset();
175 }
176 }
177
178 corePropsBuilder->build(errorCode);
179 bidiPropsBuilder->build(errorCode);
180 casePropsBuilder->build(errorCode);
181 layoutPropsBuilder->build(errorCode);
182 namesPropsBuilder->build(errorCode);
183 if(errorCode.isFailure()) {
184 fprintf(stderr, "genprops error: failure finalizing the data - %s\n",
185 errorCode.errorName());
186 return errorCode.reset();
187 }
188
189 // Write the files with the generated data.
190 CharString sourceCommon(icuSource, errorCode);
191 sourceCommon.appendPathPart("common", errorCode);
192
193 CharString sourceDataIn(icuSourceData, errorCode);
194 sourceDataIn.appendPathPart("in", errorCode);
195
196 UBool withCopyright=options[COPYRIGHT].doesOccur;
197
198 pnamesBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
199 pnamesBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
200 corePropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
201 corePropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
202 bidiPropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
203 bidiPropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
204 casePropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
205 casePropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
206 namesPropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
207 layoutPropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
208
209 return errorCode;
210 }
211
212 /*
213 * Hey, Emacs, please set the following:
214 *
215 * Local Variables:
216 * indent-tabs-mode: nil
217 * End:
218 *
219 */
220