• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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