Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <stdio.h>
21 : : #include <stdlib.h>
22 : : #include <string.h>
23 : : #include <iostream>
24 : : #include <set>
25 : : #include <vector>
26 : :
27 : : #include <rtl/ustrbuf.hxx>
28 : : #include <sal/macros.h>
29 : :
30 : : #include "LocaleNode.hxx"
31 : : #include <com/sun/star/i18n/NumberFormatIndex.hpp>
32 : :
33 : : // NOTE: MUST match the Locale versionDTD attribute defined in data/locale.dtd
34 : : #define LOCALE_VERSION_DTD "2.0.3"
35 : :
36 : : typedef ::std::set< ::rtl::OUString > NameSet;
37 : : typedef ::std::set< sal_Int16 > ValueSet;
38 : :
39 : : namespace cssi = ::com::sun::star::i18n;
40 : :
41 : 43100 : LocaleNode::LocaleNode (const OUString& name, const Reference< XAttributeList > & attr)
42 : : : aName(name)
43 : : , aAttribs(attr)
44 : : , parent(0)
45 : : , children(0)
46 : : , nChildren(0)
47 : : , childArrSize(0)
48 [ + - ]: 43100 : , nError(0)
49 : : {
50 : 43100 : }
51 : :
52 : 43100 : int LocaleNode::getError() const
53 : : {
54 : 43100 : int err = nError;
55 [ + + ]: 86003 : for (sal_Int32 i=0;i<nChildren;i++)
56 : 42903 : err += children[i]->getError();
57 : 43100 : return err;
58 : : }
59 : :
60 : 0 : void LocaleNode::print () const {
61 [ # # ]: 0 : printf ("<");
62 : 0 : ::rtl::OUString str (aName);
63 [ # # ]: 0 : for(sal_Int32 i = 0; i < str.getLength(); i++)
64 [ # # ]: 0 : printf( "%c", str[i]);
65 [ # # ]: 0 : printf (">\n");
66 : 0 : }
67 : :
68 : 0 : void LocaleNode::printR () const {
69 : 0 : print();
70 [ # # ]: 0 : for (sal_Int32 i=0;i<nChildren;i++)
71 : 0 : children[i]->printR();
72 : 0 : printf ("\t");
73 : 0 : print();
74 : 0 : }
75 : :
76 : 42903 : void LocaleNode::addChild ( LocaleNode * node) {
77 [ + + ]: 42903 : if (childArrSize <= nChildren) {
78 : 15585 : LocaleNode ** arrN = new LocaleNode*[childArrSize+10];
79 [ + + ]: 36875 : for (sal_Int32 i = 0; i<childArrSize; ++i)
80 : 21290 : arrN[i] = children[i];
81 [ + + ]: 15585 : delete [] children;
82 : 15585 : childArrSize += 10;
83 : 15585 : children = arrN;
84 : : }
85 : 42903 : children[nChildren++] = node;
86 : 42903 : node->setParent (this);
87 : 42903 : }
88 : :
89 : 42903 : void LocaleNode::setParent ( LocaleNode * node) {
90 : 42903 : parent = node;
91 : 42903 : }
92 : :
93 : 438 : const LocaleNode* LocaleNode::getRoot() const
94 : : {
95 : 438 : const LocaleNode* pRoot = 0;
96 : 438 : const LocaleNode* pParent = this;
97 [ + + ]: 876 : while ( (pParent = pParent->getParent()) != 0 )
98 : 438 : pRoot = pParent;
99 : 438 : return pRoot;
100 : : }
101 : :
102 : 91328 : const LocaleNode * LocaleNode::findNode ( const sal_Char *name) const {
103 [ + + ]: 91328 : if (aName.equalsAscii(name))
104 : 14529 : return this;
105 [ + + ]: 128777 : for (sal_Int32 i = 0; i< nChildren; i++) {
106 : 69557 : const LocaleNode *n=children[i]->findNode(name);
107 [ + + ]: 69557 : if (n)
108 : 17579 : return n;
109 : : }
110 : 91328 : return 0;
111 : : }
112 : :
113 [ + - ]: 43100 : LocaleNode::~LocaleNode()
114 : : {
115 [ + + ]: 86003 : for (sal_Int32 i=0; i < nChildren; ++i)
116 [ + - ][ + - ]: 42903 : delete children[i];
117 [ + + ]: 43100 : delete [] children;
118 [ - + ]: 83835 : }
119 : :
120 : 43100 : LocaleNode* LocaleNode::createNode (const OUString& name, const Reference< XAttributeList > & attr)
121 : : {
122 [ + + ]: 43100 : if ( name == "LC_INFO" )
123 [ + - ]: 197 : return new LCInfoNode (name,attr);
124 [ + + ]: 42903 : if ( name == "LC_CTYPE" )
125 [ + - ]: 197 : return new LCCTYPENode (name,attr);
126 [ + + ]: 42706 : if ( name == "LC_FORMAT" )
127 [ + - ]: 197 : return new LCFormatNode (name,attr);
128 [ + + ]: 42509 : if ( name == "LC_FORMAT_1" )
129 [ + - ]: 1 : return new LCFormatNode (name,attr);
130 [ + + ]: 42508 : if ( name == "LC_CALENDAR" )
131 [ + - ]: 197 : return new LCCalendarNode (name,attr);
132 [ + + ]: 42311 : if ( name == "LC_CURRENCY" )
133 [ + - ]: 197 : return new LCCurrencyNode (name,attr);
134 [ + + ]: 42114 : if ( name == "LC_TRANSLITERATION" )
135 [ + - ]: 197 : return new LCTransliterationNode (name,attr);
136 [ + + ]: 41917 : if ( name == "LC_COLLATION" )
137 [ + - ]: 197 : return new LCCollationNode (name,attr);
138 [ + + ]: 41720 : if ( name == "LC_INDEX" )
139 [ + - ]: 197 : return new LCIndexNode (name,attr);
140 [ + + ]: 41523 : if ( name == "LC_SEARCH" )
141 [ + - ]: 197 : return new LCSearchNode (name,attr);
142 [ + + ]: 41326 : if ( name == "LC_MISC" )
143 [ + - ]: 197 : return new LCMiscNode (name,attr);
144 [ + + ]: 41129 : if ( name == "LC_NumberingLevel" )
145 [ + - ]: 197 : return new LCNumberingLevelNode (name, attr);
146 [ + + ]: 40932 : if ( name == "LC_OutLineNumberingLevel" )
147 [ + - ]: 197 : return new LCOutlineNumberingLevelNode (name, attr);
148 : :
149 [ + - ]: 43100 : return new LocaleNode(name,attr);
150 : : }
151 : :
152 : :
153 : : // printf(" name: '%s'\n", p->getName().pData->buffer );
154 : : // printf("value: '%s'\n", p->getValue().pData->buffer );
155 : :
156 : : #define OSTR(s) (OUStringToOString( (s), RTL_TEXTENCODING_UTF8).getStr())
157 : :
158 : 0 : void print_OUString( const OUString& s )
159 : : {
160 [ # # ]: 0 : printf( "%s", OSTR(s));
161 : 0 : }
162 : :
163 : 0 : bool is_empty_string( const OUString& s )
164 : : {
165 [ # # ][ # # ]: 0 : return s.isEmpty() || (s.getLength()==1 && s[0]=='\n');
[ # # ]
166 : : }
167 : :
168 : 0 : void print_indent( int depth )
169 : : {
170 [ # # ]: 0 : for( int i=0; i<depth; i++ ) printf(" ");
171 : 0 : }
172 : :
173 : 0 : void print_color( int color )
174 : : {
175 : 0 : printf("\033[%dm", color);
176 : 0 : }
177 : :
178 : 0 : void print_node( const LocaleNode* p, int depth=0 )
179 : : {
180 [ # # ]: 0 : if( !p ) return;
181 : :
182 : 0 : print_indent( depth );
183 : 0 : printf("<");
184 : 0 : print_color(36);
185 : 0 : print_OUString( p->getName() );
186 : 0 : print_color(0);
187 : 0 : const Attr& q = p->getAttr();
188 [ # # ]: 0 : for( sal_Int32 j = 0; j < q.getLength(); ++j )
189 : : {
190 : 0 : printf(" ");
191 : 0 : print_color(33);
192 : 0 : print_OUString( q.getTypeByIndex(j) );
193 : 0 : print_color(0);
194 : 0 : printf("=");
195 : 0 : print_color(31);
196 : 0 : printf("'");
197 : 0 : print_OUString( q.getValueByIndex(j) );
198 : 0 : printf("'");
199 : 0 : print_color(0);
200 : : }
201 : 0 : printf(">");
202 : 0 : printf("\n");
203 [ # # ]: 0 : if( !is_empty_string( p->getValue() ) )
204 : : {
205 : 0 : print_indent( depth+1 );
206 : 0 : printf("value: ");
207 : 0 : print_color(31);
208 : 0 : printf("'");
209 : 0 : print_OUString( p->getValue() );
210 : 0 : printf("'");
211 : 0 : print_color(0);
212 : 0 : printf("\n");
213 : : }
214 [ # # ]: 0 : for( sal_Int32 i=0; i<p->getNumberOfChildren(); i++ )
215 : : {
216 : 0 : print_node( p->getChildAt(i), depth+1 );
217 : : }
218 : 0 : print_indent( depth );
219 : 0 : printf("</");
220 : 0 : print_OUString( p->getName() );
221 : 0 : printf(">");
222 : 0 : printf("\n");
223 : : }
224 : :
225 : 197 : void LocaleNode :: generateCode (const OFileWriter &of) const
226 : : {
227 [ + - ]: 197 : ::rtl::OUString aDTD = getAttr().getValueByName("versionDTD");
228 [ - + ]: 197 : if ( aDTD != LOCALE_VERSION_DTD )
229 : : {
230 : 0 : ++nError;
231 [ # # ]: 0 : fprintf( stderr, "Error: Locale versionDTD is not %s, see comment in locale.dtd\n", LOCALE_VERSION_DTD);
232 : : }
233 [ + + ]: 2562 : for (sal_Int32 i=0; i<nChildren;i++)
234 [ + - ]: 2562 : children[i]->generateCode (of);
235 : : // print_node( this );
236 : 197 : }
237 : :
238 : :
239 : 2081 : ::rtl::OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of,
240 : : const char* pParameterName, const LocaleNode* pNode,
241 : : sal_Int32 nMinLen, sal_Int32 nMaxLen ) const
242 : : {
243 : 2081 : OUString aVal;
244 [ + - ]: 2081 : if (pNode)
245 : 2081 : aVal = pNode->getValue();
246 : : else
247 : : {
248 : 0 : ++nError;
249 : : fprintf( stderr, "Error: node NULL pointer for parameter %s.\n",
250 [ # # ]: 0 : pParameterName);
251 : : }
252 : : // write empty data if error
253 [ + - ]: 2081 : of.writeParameter( pParameterName, aVal);
254 : 2081 : sal_Int32 nLen = aVal.getLength();
255 [ - + ]: 2081 : if (nLen < nMinLen)
256 : : {
257 : 0 : ++nError;
258 : : fprintf( stderr, "Error: less than %ld character%s (%ld) in %s '%s'.\n",
259 : : sal::static_int_cast< long >(nMinLen), (nMinLen > 1 ? "s" : ""),
260 : : sal::static_int_cast< long >(nLen),
261 [ # # ][ # # ]: 0 : (pNode ? OSTR( pNode->getName()) : ""),
[ # # ]
262 [ # # ][ # # ]: 0 : OSTR( aVal));
[ # # ][ # # ]
263 : : }
264 [ + + ][ - + ]: 2081 : else if (nLen > nMaxLen && nMaxLen >= 0)
265 : : fprintf( stderr,
266 : : "Warning: more than %ld character%s (%ld) in %s %s not supported by application.\n",
267 : : sal::static_int_cast< long >(nMaxLen), (nMaxLen > 1 ? "s" : ""),
268 : : sal::static_int_cast< long >(nLen),
269 [ # # ][ # # ]: 0 : (pNode ? OSTR( pNode->getName()) : ""),
[ # # ]
270 [ # # ][ # # ]: 0 : OSTR( aVal));
[ # # ][ # # ]
271 : 2081 : return aVal;
272 : : }
273 : :
274 : :
275 : 1884 : ::rtl::OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of,
276 : : const char* pNodeName, const char* pParameterName,
277 : : sal_Int32 nMinLen, sal_Int32 nMaxLen ) const
278 : : {
279 : 1884 : OUString aVal;
280 [ + - ]: 1884 : const LocaleNode * pNode = findNode( pNodeName);
281 [ + - ]: 1884 : if (pNode)
282 [ + - ]: 1884 : aVal = writeParameterCheckLen( of, pParameterName, pNode, nMinLen, nMaxLen);
283 : : else
284 : : {
285 : 0 : ++nError;
286 [ # # ]: 0 : fprintf( stderr, "Error: node %s not found.\n", pNodeName);
287 : : // write empty data if error
288 [ # # ]: 0 : of.writeParameter( pParameterName, aVal);
289 : : }
290 : 1884 : return aVal;
291 : : }
292 : :
293 : 0 : void LocaleNode::incError( const char* pStr ) const
294 : : {
295 : 0 : ++nError;
296 : 0 : fprintf( stderr, "Error: %s\n", pStr);
297 : 0 : }
298 : :
299 : 0 : void LocaleNode::incError( const ::rtl::OUString& rStr ) const
300 : : {
301 [ # # ]: 0 : incError( OSTR( rStr));
302 : 0 : }
303 : :
304 : 0 : char* LocaleNode::prepareErrorFormat( const char* pFormat, const char* pDefaultConversion ) const
305 : : {
306 : : static char buf[2048];
307 : 0 : strcpy( buf, "Error: ");
308 : 0 : strncat( buf, pFormat, 2000);
309 : 0 : char* p = buf;
310 [ # # ][ # # ]: 0 : while (((p = strchr( p, '%')) != 0) && p[1] == '%')
[ # # ]
311 : 0 : p += 2;
312 [ # # ]: 0 : if (!p)
313 : 0 : strcat( buf, pDefaultConversion);
314 : 0 : strcat( buf, "\n");
315 : 0 : return buf;
316 : : }
317 : :
318 : 0 : void LocaleNode::incErrorInt( const char* pStr, int nVal ) const
319 : : {
320 : 0 : ++nError;
321 : 0 : fprintf( stderr, prepareErrorFormat( pStr, ": %d"), nVal);
322 : 0 : }
323 : :
324 : 0 : void LocaleNode::incErrorStr( const char* pStr, const ::rtl::OUString& rVal ) const
325 : : {
326 : 0 : ++nError;
327 [ # # ]: 0 : fprintf( stderr, prepareErrorFormat( pStr, ": %s"), OSTR( rVal));
328 : 0 : }
329 : :
330 : 0 : void LocaleNode::incErrorStrStr( const char* pStr, const ::rtl::OUString& rVal1, const ::rtl::OUString& rVal2 ) const
331 : : {
332 : 0 : ++nError;
333 [ # # ][ # # ]: 0 : fprintf( stderr, prepareErrorFormat( pStr, ": %s %s"), OSTR( rVal1), OSTR( rVal2));
334 : 0 : }
335 : :
336 : 197 : void LCInfoNode::generateCode (const OFileWriter &of) const
337 : : {
338 : :
339 : 197 : const LocaleNode * languageNode = findNode("Language");
340 : 197 : const LocaleNode * countryNode = findNode("Country");
341 : 197 : const LocaleNode * variantNode = findNode("Variant");
342 : :
343 [ + - ]: 197 : if (languageNode)
344 : : {
345 : 197 : writeParameterCheckLen( of, "langID", languageNode->getChildAt(0), 2, -1);
346 : 197 : of.writeParameter("langDefaultName", languageNode->getChildAt(1)->getValue());
347 : : }
348 : : else
349 : 0 : incError( "No Language node.");
350 [ + - ]: 197 : if (countryNode)
351 : : {
352 : 197 : of.writeParameter("countryID", countryNode->getChildAt(0)->getValue());
353 : 197 : of.writeParameter("countryDefaultName", countryNode->getChildAt(1)->getValue());
354 : : }
355 : : else
356 : 0 : incError( "No Country node.");
357 [ - + ]: 197 : if (variantNode)
358 : : {
359 : 0 : of.writeParameter("Variant", variantNode->getValue());
360 : : fprintf( stderr, "Warning: %s\n",
361 : 0 : "Variants are not supported by application.");
362 : : }
363 : : else
364 [ + - ]: 197 : of.writeParameter("Variant", ::rtl::OUString());
365 : 197 : of.writeAsciiString("\nstatic const sal_Unicode* LCInfoArray[] = {\n");
366 : 197 : of.writeAsciiString("\tlangID,\n");
367 : 197 : of.writeAsciiString("\tlangDefaultName,\n");
368 : 197 : of.writeAsciiString("\tcountryID,\n");
369 : 197 : of.writeAsciiString("\tcountryDefaultName,\n");
370 : 197 : of.writeAsciiString("\tVariant\n");
371 : 197 : of.writeAsciiString("};\n\n");
372 : 197 : of.writeFunction("getLCInfo_", "0", "LCInfoArray");
373 : 197 : }
374 : :
375 : :
376 : 197 : static OUString aDateSep;
377 : 197 : static OUString aDecSep;
378 : :
379 : 197 : void LCCTYPENode::generateCode (const OFileWriter &of) const
380 : : {
381 : 197 : const LocaleNode * sepNode = 0;
382 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
383 [ + + ]: 197 : if (!useLocale.isEmpty()) {
384 [ + - ]: 40 : of.writeRefFunction("getLocaleItem_", useLocale);
385 : 197 : return;
386 : : }
387 [ + - ]: 157 : ::rtl::OUString str = getAttr().getValueByName("unoid");
388 [ + - ]: 157 : of.writeAsciiString("\n\n");
389 [ + - ]: 157 : of.writeParameter("LC_CTYPE_Unoid", str);;
390 : :
391 : : aDateSep =
392 [ + - ]: 157 : writeParameterCheckLen( of, "DateSeparator", "dateSeparator", 1, 1);
393 : : OUString aThoSep =
394 [ + - ]: 157 : writeParameterCheckLen( of, "ThousandSeparator", "thousandSeparator", 1, 1);
395 : : aDecSep =
396 [ + - ]: 157 : writeParameterCheckLen( of, "DecimalSeparator", "decimalSeparator", 1, 1);
397 : : OUString aTimeSep =
398 [ + - ]: 157 : writeParameterCheckLen( of, "TimeSeparator", "timeSeparator", 1, 1);
399 : : OUString aTime100Sep =
400 [ + - ]: 157 : writeParameterCheckLen( of, "Time100SecSeparator", "time100SecSeparator", 1, 1);
401 : : OUString aListSep =
402 [ + - ]: 157 : writeParameterCheckLen( of, "ListSeparator", "listSeparator", 1, 1);
403 : :
404 : 157 : OUString aLDS;
405 : :
406 [ + - ]: 157 : sepNode = findNode("LongDateDayOfWeekSeparator");
407 : 157 : aLDS = sepNode->getValue();
408 [ + - ]: 157 : of.writeParameter("LongDateDayOfWeekSeparator", aLDS);
409 [ + + ][ - + ]: 157 : if (aLDS.getLength() == 1 && aLDS.getStr()[0] == ',')
[ - + ]
410 : : fprintf( stderr, "Warning: %s\n",
411 [ # # ]: 0 : "LongDateDayOfWeekSeparator is only a comma not followed by a space. Usually this is not the case and may lead to concatenated display names like \"Wednesday,May 9, 2007\".");
412 : :
413 [ + - ]: 157 : sepNode = findNode("LongDateDaySeparator");
414 : 157 : aLDS = sepNode->getValue();
415 [ + - ]: 157 : of.writeParameter("LongDateDaySeparator", aLDS);
416 [ + + ][ + - ]: 157 : if (aLDS.getLength() == 1 && (aLDS.getStr()[0] == ',' || aLDS.getStr()[0] == '.'))
[ + + ][ + + ]
417 : : fprintf( stderr, "Warning: %s\n",
418 [ + - ]: 9 : "LongDateDaySeparator is only a comma or dot not followed by a space. Usually this is not the case and may lead to concatenated display names like \"Wednesday, May 9,2007\".");
419 : :
420 [ + - ]: 157 : sepNode = findNode("LongDateMonthSeparator");
421 : 157 : aLDS = sepNode->getValue();
422 [ + - ]: 157 : of.writeParameter("LongDateMonthSeparator", aLDS);
423 [ - + ]: 157 : if (aLDS.isEmpty())
424 : : fprintf( stderr, "Warning: %s\n",
425 [ # # ]: 0 : "LongDateMonthSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, May9, 2007\".");
426 : :
427 [ + - ]: 157 : sepNode = findNode("LongDateYearSeparator");
428 : 157 : aLDS = sepNode->getValue();
429 [ + - ]: 157 : of.writeParameter("LongDateYearSeparator", aLDS);
430 [ + + ]: 157 : if (aLDS.isEmpty())
431 : : fprintf( stderr, "Warning: %s\n",
432 [ + - ]: 2 : "LongDateYearSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, 2007May 9\".");
433 : :
434 : :
435 : 157 : int nSavErr = nError;
436 : 157 : int nWarn = 0;
437 [ - + ]: 157 : if (aDateSep == aTimeSep)
438 [ # # ]: 0 : incError( "DateSeparator equals TimeSeparator.");
439 [ - + ]: 157 : if (aDecSep == aThoSep)
440 [ # # ]: 0 : incError( "DecimalSeparator equals ThousandSeparator.");
441 [ - + ]: 157 : if ( aThoSep == " " )
442 [ # # ]: 0 : incError( "ThousandSeparator is an ' ' ordinary space, this should be a non-breaking space U+00A0 instead.");
443 [ - + ]: 157 : if (aListSep == aDecSep)
444 : : fprintf( stderr, "Warning: %s\n",
445 [ # # ]: 0 : "ListSeparator equals DecimalSeparator.");
446 [ - + ]: 157 : if (aListSep == aThoSep)
447 : : fprintf( stderr, "Warning: %s\n",
448 [ # # ]: 0 : "ListSeparator equals ThousandSeparator.");
449 [ + - ][ - + ]: 157 : if (aListSep.getLength() != 1 || aListSep.getStr()[0] != ';')
[ - + ]
450 : : {
451 [ # # ]: 0 : incError( "ListSeparator not ';' semicolon. Strongly recommended. Currently required.");
452 : 0 : ++nSavErr; // format codes not affected
453 : : }
454 [ - + ]: 157 : if (aTimeSep == aTime100Sep)
455 : : ++nWarn, fprintf( stderr, "Warning: %s\n",
456 [ # # ]: 0 : "Time100SecSeparator equals TimeSeparator, this is probably an error.");
457 [ + + ]: 157 : if (aDecSep != aTime100Sep)
458 : : ++nWarn, fprintf( stderr, "Warning: %s\n",
459 [ + - ]: 7 : "Time100SecSeparator is different from DecimalSeparator, this may be correct or not. Intended?");
460 [ + - ][ + + ]: 157 : if (nSavErr != nError || nWarn)
461 : : fprintf( stderr, "Warning: %s\n",
462 [ + - ]: 7 : "Don't forget to adapt corresponding FormatCode elements when changing separators.");
463 : :
464 : : OUString aQuoteStart =
465 [ + - ]: 157 : writeParameterCheckLen( of, "QuotationStart", "quotationStart", 1, 1);
466 : : OUString aQuoteEnd =
467 [ + - ]: 157 : writeParameterCheckLen( of, "QuotationEnd", "quotationEnd", 1, 1);
468 : : OUString aDoubleQuoteStart =
469 [ + - ]: 157 : writeParameterCheckLen( of, "DoubleQuotationStart", "doubleQuotationStart", 1, 1);
470 : : OUString aDoubleQuoteEnd =
471 [ + - ]: 157 : writeParameterCheckLen( of, "DoubleQuotationEnd", "doubleQuotationEnd", 1, 1);
472 : :
473 [ + + ][ - + ]: 157 : if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() > 127)
[ - + ]
474 : : fprintf( stderr, "Warning: %s\n",
475 [ # # ]: 0 : "QuotationStart is an ASCII character but QuotationEnd is not.");
476 [ + + ][ - + ]: 157 : if (aQuoteEnd.toChar() <= 127 && aQuoteStart.toChar() > 127)
[ - + ]
477 : : fprintf( stderr, "Warning: %s\n",
478 [ # # ]: 0 : "QuotationEnd is an ASCII character but QuotationStart is not.");
479 [ + + ][ + + ]: 157 : if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() > 127)
[ + + ]
480 : : fprintf( stderr, "Warning: %s\n",
481 [ + - ]: 2 : "DoubleQuotationStart is an ASCII character but DoubleQuotationEnd is not.");
482 [ + + ][ - + ]: 157 : if (aDoubleQuoteEnd.toChar() <= 127 && aDoubleQuoteStart.toChar() > 127)
[ - + ]
483 : : fprintf( stderr, "Warning: %s\n",
484 [ # # ]: 0 : "DoubleQuotationEnd is an ASCII character but DoubleQuotationStart is not.");
485 [ + + ][ + - ]: 157 : if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() <= 127)
[ + + ]
486 : : fprintf( stderr, "Warning: %s\n",
487 [ + - ]: 11 : "QuotationStart and QuotationEnd are both ASCII characters. Not necessarily an issue, but unusual.");
488 [ + + ][ + + ]: 157 : if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() <= 127)
[ + + ]
489 : : fprintf( stderr, "Warning: %s\n",
490 [ + - ]: 17 : "DoubleQuotationStart and DoubleQuotationEnd are both ASCII characters. Not necessarily an issue, but unusual.");
491 [ + + ]: 157 : if (aQuoteStart == aQuoteEnd)
492 : : fprintf( stderr, "Warning: %s\n",
493 [ + - ]: 19 : "QuotationStart equals QuotationEnd. Not necessarily an issue, but unusual.");
494 [ + + ]: 157 : if (aDoubleQuoteStart == aDoubleQuoteEnd)
495 : : fprintf( stderr, "Warning: %s\n",
496 [ + - ]: 23 : "DoubleQuotationStart equals DoubleQuotationEnd. Not necessarily an issue, but unusual.");
497 : : /* TODO: should equalness of single and double quotes be an error? Would
498 : : * need to adapt quite some locales' data. */
499 [ + + ]: 157 : if (aQuoteStart == aDoubleQuoteStart)
500 : : fprintf( stderr, "Warning: %s\n",
501 [ + - ]: 2 : "QuotationStart equals DoubleQuotationStart. Not necessarily an isue, but unusual.");
502 [ + + ]: 157 : if (aQuoteEnd == aDoubleQuoteEnd)
503 : : fprintf( stderr, "Warning: %s\n",
504 [ + - ]: 2 : "QuotationEnd equals DoubleQuotationEnd. Not necessarily an issue, but unusual.");
505 : : // Known good values, exclude ASCII single (U+0027, ') and double (U+0022, ") quotes.
506 : : int ic;
507 [ + + ]: 157 : switch (ic = aQuoteStart.toChar())
508 : : {
509 : : case 0x2018: // LEFT SINGLE QUOTATION MARK
510 : : case 0x201a: // SINGLE LOW-9 QUOTATION MARK
511 : : case 0x201b: // SINGLE HIGH-REVERSED-9 QUOTATION MARK
512 : : case 0x2039: // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
513 : : case 0x203a: // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
514 : : case 0x300c: // LEFT CORNER BRACKET (Chinese)
515 : : ;
516 : 110 : break;
517 : : default:
518 : : fprintf( stderr, "Warning: %s U+%04X %s\n",
519 [ + - ][ + - ]: 47 : "QuotationStart may be wrong:", ic, OSTR( aQuoteStart));
520 : : }
521 [ + + ]: 157 : switch (ic = aQuoteEnd.toChar())
522 : : {
523 : : case 0x2019: // RIGHT SINGLE QUOTATION MARK
524 : : case 0x201a: // SINGLE LOW-9 QUOTATION MARK
525 : : case 0x201b: // SINGLE HIGH-REVERSED-9 QUOTATION MARK
526 : : case 0x2039: // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
527 : : case 0x203a: // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
528 : : case 0x300d: // RIGHT CORNER BRACKET (Chinese)
529 : : ;
530 : 105 : break;
531 : : default:
532 : : fprintf( stderr, "Warning: %s U+%04X %s\n",
533 [ + - ][ + - ]: 52 : "QuotationEnd may be wrong:", ic, OSTR( aQuoteEnd));
534 : : }
535 [ + + ]: 157 : switch (ic = aDoubleQuoteStart.toChar())
536 : : {
537 : : case 0x00ab: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
538 : : case 0x00bb: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
539 : : case 0x201c: // LEFT DOUBLE QUOTATION MARK
540 : : case 0x201e: // DOUBLE LOW-9 QUOTATION MARK
541 : : case 0x201f: // DOUBLE HIGH-REVERSED-9 QUOTATION MARK
542 : : case 0x300e: // LEFT WHITE CORNER BRACKET (Chinese)
543 : : ;
544 : 122 : break;
545 : : default:
546 : : fprintf( stderr, "Warning: %s U+%04X %s\n",
547 [ + - ][ + - ]: 35 : "DoubleQuotationStart may be wrong:", ic, OSTR( aDoubleQuoteStart));
548 : : }
549 [ + + ]: 157 : switch (ic = aDoubleQuoteEnd.toChar())
550 : : {
551 : : case 0x00ab: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
552 : : case 0x00bb: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
553 : : case 0x201d: // RIGHT DOUBLE QUOTATION MARK
554 : : case 0x201e: // DOUBLE LOW-9 QUOTATION MARK
555 : : case 0x201f: // DOUBLE HIGH-REVERSED-9 QUOTATION MARK
556 : : case 0x300f: // RIGHT WHITE CORNER BRACKET (Chinese)
557 : : ;
558 : 112 : break;
559 : : default:
560 : : fprintf( stderr, "Warning: %s U+%04X %s\n",
561 [ + - ][ + - ]: 45 : "DoubleQuotationEnd may be wrong:", ic, OSTR( aDoubleQuoteEnd));
562 : : }
563 : :
564 [ + - ]: 157 : writeParameterCheckLen( of, "TimeAM", "timeAM", 1, -1);
565 [ + - ]: 157 : writeParameterCheckLen( of, "TimePM", "timePM", 1, -1);
566 [ + - ]: 157 : sepNode = findNode("MeasurementSystem");
567 [ + - ]: 157 : of.writeParameter("measurementSystem", sepNode->getValue());
568 : :
569 [ + - ]: 157 : of.writeAsciiString("\nstatic const sal_Unicode* LCType[] = {\n");
570 [ + - ]: 157 : of.writeAsciiString("\tLC_CTYPE_Unoid,\n");
571 [ + - ]: 157 : of.writeAsciiString("\tdateSeparator,\n");
572 [ + - ]: 157 : of.writeAsciiString("\tthousandSeparator,\n");
573 [ + - ]: 157 : of.writeAsciiString("\tdecimalSeparator,\n");
574 [ + - ]: 157 : of.writeAsciiString("\ttimeSeparator,\n");
575 [ + - ]: 157 : of.writeAsciiString("\ttime100SecSeparator,\n");
576 [ + - ]: 157 : of.writeAsciiString("\tlistSeparator,\n");
577 [ + - ]: 157 : of.writeAsciiString("\tquotationStart,\n");
578 [ + - ]: 157 : of.writeAsciiString("\tquotationEnd,\n");
579 [ + - ]: 157 : of.writeAsciiString("\tdoubleQuotationStart,\n");
580 [ + - ]: 157 : of.writeAsciiString("\tdoubleQuotationEnd,\n");
581 [ + - ]: 157 : of.writeAsciiString("\ttimeAM,\n");
582 [ + - ]: 157 : of.writeAsciiString("\ttimePM,\n");
583 [ + - ]: 157 : of.writeAsciiString("\tmeasurementSystem,\n");
584 [ + - ]: 157 : of.writeAsciiString("\tLongDateDayOfWeekSeparator,\n");
585 [ + - ]: 157 : of.writeAsciiString("\tLongDateDaySeparator,\n");
586 [ + - ]: 157 : of.writeAsciiString("\tLongDateMonthSeparator,\n");
587 [ + - ]: 157 : of.writeAsciiString("\tLongDateYearSeparator\n");
588 [ + - ]: 157 : of.writeAsciiString("};\n\n");
589 [ + - ][ + + ]: 197 : of.writeFunction("getLocaleItem_", "0", "LCType");
590 : : }
591 : :
592 : :
593 : 197 : static OUString sTheCurrencyReplaceTo;
594 : 197 : static OUString sTheCompatibleCurrency;
595 : 197 : static OUString sTheDateEditFormat;
596 : :
597 : : sal_Int16 LCFormatNode::mnSection = 0;
598 : : sal_Int16 LCFormatNode::mnFormats = 0;
599 : :
600 : 198 : void LCFormatNode::generateCode (const OFileWriter &of) const
601 : : {
602 [ - + ]: 198 : if (mnSection >= 2)
603 [ # # ]: 0 : incError("more than 2 LC_FORMAT sections");
604 : :
605 [ + - ]: 198 : ::std::vector< OUString > theDateAcceptancePatterns;
606 : :
607 : 198 : OUString str;
608 [ + - ]: 198 : OUString strFrom( getAttr().getValueByName("replaceFrom"));
609 [ + - ]: 198 : of.writeParameter("replaceFrom", strFrom, mnSection);
610 [ + - ]: 198 : str = getAttr().getValueByName("replaceTo");
611 [ - + ][ - + ]: 198 : if (!strFrom.isEmpty() && str.isEmpty())
[ + + ]
612 [ # # ]: 0 : incErrorStr("replaceFrom=\"%s\" replaceTo=\"\" is empty replacement.", strFrom);
613 : : // Locale data generator inserts FFFF for LangID, we need to adapt that.
614 [ - + ]: 198 : if (str.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "-FFFF]")))
615 [ # # ]: 0 : incErrorStr("replaceTo=\"%s\" needs FFFF to be adapted to the real LangID value.", str);
616 [ + - ]: 198 : of.writeParameter("replaceTo", str, mnSection);
617 : : // Remember the replaceTo value for "[CURRENCY]" to check format codes.
618 [ + + ]: 198 : if ( strFrom == "[CURRENCY]" )
619 : 97 : sTheCurrencyReplaceTo = str;
620 : : // Remember the currency symbol if present.
621 [ + + ]: 198 : if (str.indexOfAsciiL( "[$", 2) == 0)
622 : : {
623 : 140 : sal_Int32 nHyphen = str.indexOf( '-');
624 [ + - ]: 140 : if (nHyphen >= 3)
625 : : {
626 : 140 : sTheCompatibleCurrency = str.copy( 2, nHyphen - 2);
627 : : }
628 : : }
629 : :
630 [ + - ]: 198 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
631 [ + + ]: 198 : if (!useLocale.isEmpty())
632 : : {
633 [ + - - ]: 51 : switch (mnSection)
634 : : {
635 : : case 0:
636 [ + - ]: 51 : of.writeRefFunction("getAllFormats0_", useLocale, "replaceTo0");
637 : 51 : break;
638 : : case 1:
639 [ # # ]: 0 : of.writeRefFunction("getAllFormats1_", useLocale, "replaceTo1");
640 : 0 : break;
641 : : }
642 [ + - ]: 51 : of.writeRefFunction("getDateAcceptancePatterns_", useLocale);
643 : 198 : return;
644 : : }
645 : :
646 : 147 : sal_Int16 formatCount = mnFormats;
647 [ + - ]: 147 : NameSet aMsgIdSet;
648 [ + - ]: 147 : ValueSet aFormatIndexSet;
649 [ + - ]: 147 : NameSet aDefaultsSet;
650 : 147 : bool bCtypeIsRef = false;
651 : :
652 [ + + ]: 7260 : for (sal_Int16 i = 0; i< getNumberOfChildren() ; i++, formatCount++)
653 : : {
654 : 7113 : LocaleNode * currNode = getChildAt (i);
655 [ + + ]: 7113 : if ( currNode->getName() == "DateAcceptancePattern" )
656 : : {
657 [ - + ]: 155 : if (mnSection > 0)
658 [ # # ]: 0 : incError( "DateAcceptancePattern only handled in LC_FORMAT, not LC_FORMAT_1");
659 : : else
660 [ + - ]: 155 : theDateAcceptancePatterns.push_back( currNode->getValue());
661 : 155 : --formatCount;
662 : 155 : continue; // for
663 : : }
664 [ - + ]: 6958 : if ( currNode->getName() != "FormatElement" )
665 : : {
666 [ # # ]: 0 : incErrorStr( "Undefined element in LC_FORMAT", currNode->getName());
667 : 0 : --formatCount;
668 : 0 : continue; // for
669 : : }
670 : :
671 : 6958 : OUString aUsage;
672 : 6958 : OUString aType;
673 : 6958 : OUString aFormatIndex;
674 : : // currNode -> print();
675 : 6958 : const Attr &currNodeAttr = currNode->getAttr();
676 : : //printf ("getLen() = %d\n", currNode->getAttr().getLength());
677 : :
678 [ + - ]: 6958 : str = currNodeAttr.getValueByName("msgid");
679 [ - + ][ + - ]: 6958 : if (!aMsgIdSet.insert( str).second)
680 [ # # ]: 0 : incErrorStr( "Duplicated msgid=\"%s\" in FormatElement.", str);
681 [ + - ]: 6958 : of.writeParameter("FormatKey", str, formatCount);
682 : :
683 [ + - ]: 6958 : str = currNodeAttr.getValueByName("default");
684 : 6958 : bool bDefault = str == "true";
685 [ + - ]: 6958 : of.writeDefaultParameter("FormatElement", str, formatCount);
686 : :
687 [ + - ]: 6958 : aType = currNodeAttr.getValueByName("type");
688 [ + - ]: 6958 : of.writeParameter("FormatType", aType, formatCount);
689 : :
690 [ + - ]: 6958 : aUsage = currNodeAttr.getValueByName("usage");
691 [ + - ]: 6958 : of.writeParameter("FormatUsage", aUsage, formatCount);
692 : :
693 [ + - ]: 6958 : aFormatIndex = currNodeAttr.getValueByName("formatindex");
694 : 6958 : sal_Int16 formatindex = (sal_Int16)aFormatIndex.toInt32();
695 [ - + ][ + - ]: 6958 : if (!aFormatIndexSet.insert( formatindex).second)
696 [ # # ]: 0 : incErrorInt( "Duplicated formatindex=\"%d\" in FormatElement.", formatindex);
697 [ + - ]: 6958 : of.writeIntParameter("Formatindex", formatCount, formatindex);
698 : :
699 : : // Ensure only one default per usage and type.
700 [ + + ]: 6958 : if (bDefault)
701 : : {
702 : 1900 : OUString aKey( aUsage + OUString( sal_Unicode(',')) + aType);
703 [ - + ][ + - ]: 1900 : if (!aDefaultsSet.insert( aKey).second)
704 : : {
705 : 0 : OUString aStr( "Duplicated default for usage=\"");
706 : 0 : aStr += aUsage;
707 : 0 : aStr += OUString( "\" type=\"");
708 : 0 : aStr += aType;
709 : 0 : aStr += OUString( "\": formatindex=\"");
710 : 0 : aStr += aFormatIndex;
711 : 0 : aStr += OUString( "\".");
712 [ # # ]: 0 : incError( aStr);
713 : 1900 : }
714 : : }
715 : :
716 [ + - ]: 6958 : const LocaleNode * n = currNode -> findNode("FormatCode");
717 [ + - ]: 6958 : if (n)
718 : : {
719 [ + - ]: 6958 : of.writeParameter("FormatCode", n->getValue(), formatCount);
720 : : // Check separator usage for some FormatCode elements.
721 : 6958 : const LocaleNode* pCtype = 0;
722 [ + + + + : 6958 : switch (formatindex)
+ ]
723 : : {
724 : : case cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY :
725 : 146 : sTheDateEditFormat = n->getValue();
726 : 146 : break;
727 : : case cssi::NumberFormatIndex::NUMBER_1000DEC2 : // #,##0.00
728 : : case cssi::NumberFormatIndex::TIME_MMSS00 : // MM:SS.00
729 : : case cssi::NumberFormatIndex::TIME_HH_MMSS00 : // [HH]:MM:SS.00
730 : : {
731 : 438 : const LocaleNode* pRoot = getRoot();
732 [ - + ]: 438 : if (!pRoot)
733 [ # # ]: 0 : incError( "No root for FormatCode.");
734 : : else
735 : : {
736 [ + - ]: 438 : pCtype = pRoot->findNode( "LC_CTYPE");
737 [ - + ]: 438 : if (!pCtype)
738 [ # # ]: 0 : incError( "No LC_CTYPE found for FormatCode.");
739 : : else
740 : : {
741 [ + - ]: 438 : OUString aRef( pCtype->getAttr().getValueByName("ref"));
742 [ + + ]: 438 : if (!aRef.isEmpty())
743 : : {
744 [ + + ]: 12 : if (!bCtypeIsRef)
745 : : fprintf( stderr,
746 : : "Warning: Can't check separators used in FormatCode due to LC_CTYPE ref=\"%s\".\n"
747 : : "If these two locales use identical format codes, you should consider to use the ref= mechanism also for the LC_FORMAT element, together with replaceFrom= and replaceTo= for the currency.\n",
748 [ + - ][ + - ]: 4 : OSTR( aRef));
749 : 12 : bCtypeIsRef = true;
750 : 12 : pCtype = 0;
751 : 438 : }
752 : : }
753 : : }
754 : : }
755 : 438 : break;
756 : : case cssi::NumberFormatIndex::CURRENCY_1000DEC2 :
757 : : // Remember the currency symbol if present.
758 : : {
759 : : sal_Int32 nStart;
760 [ + + + - ]: 203 : if (sTheCompatibleCurrency.isEmpty() &&
[ + + ]
761 : 57 : ((nStart = n->getValue().indexOfAsciiL( "[$", 2)) >= 0))
762 : : {
763 : 57 : OUString aCode( n->getValue());
764 : 57 : sal_Int32 nHyphen = aCode.indexOf( '-', nStart);
765 [ + - ]: 57 : if (nHyphen >= nStart + 3)
766 : 57 : sTheCompatibleCurrency = aCode.copy( nStart + 2, nHyphen - nStart - 2);
767 : : }
768 : : }
769 : : // fallthru
770 : : case cssi::NumberFormatIndex::CURRENCY_1000INT :
771 : : case cssi::NumberFormatIndex::CURRENCY_1000INT_RED :
772 : : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_RED :
773 : : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_CCC :
774 : : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_DASHED :
775 : : // Currency formats should be something like [C]###0;-[C]###0
776 : : // and not parenthesized [C]###0;([C]###0) if not en_US.
777 [ + + ]: 876 : if (strcmp( of.getLocale(), "en_US") != 0)
778 : : {
779 : 870 : OUString aCode( n->getValue());
780 : 870 : OUString aPar1( "0)");
781 : 870 : OUString aPar2( "-)" );
782 : 870 : OUString aPar3( " )" );
783 : 870 : OUString aPar4( "])" );
784 [ + + + - : 2530 : if (aCode.indexOf( aPar1 ) > 0 || aCode.indexOf( aPar2 ) > 0 ||
- + ][ + + ]
[ + + ]
785 : 1660 : aCode.indexOf( aPar3 ) > 0 || aCode.indexOf( aPar4 ) > 0)
786 [ + - ]: 870 : fprintf( stderr, "Warning: FormatCode formatindex=\"%d\" for currency uses parentheses for negative amounts, which probably is not correct for locales not based on en_US.\n", formatindex);
787 : : }
788 : : // Check if we have replaceTo for "[CURRENCY]" placeholder.
789 [ + + ]: 876 : if (sTheCurrencyReplaceTo.isEmpty())
790 : : {
791 : 342 : OUString aCode( n->getValue());
792 [ - + ]: 342 : if (aCode.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "[CURRENCY]")) >= 0)
793 [ # # ]: 342 : incErrorInt( "[CURRENCY] replaceTo not found for formatindex=\"%d\".", formatindex);
794 : : }
795 : 876 : break;
796 : : }
797 [ + + ]: 6958 : if (pCtype)
798 : : {
799 : 426 : int nSavErr = nError;
800 : 426 : OUString aCode( n->getValue());
801 [ + + ]: 426 : if (formatindex == cssi::NumberFormatIndex::NUMBER_1000DEC2)
802 : : {
803 : 142 : sal_Int32 nDec = -1;
804 : 142 : sal_Int32 nGrp = -1;
805 [ + - ]: 142 : const LocaleNode* pSep = pCtype->findNode( "DecimalSeparator");
806 [ - + ]: 142 : if (!pSep)
807 [ # # ]: 0 : incError( "No DecimalSeparator found for FormatCode.");
808 : : else
809 : : {
810 : 142 : nDec = aCode.indexOf( pSep->getValue());
811 [ - + ]: 142 : if (nDec < 0)
812 : : incErrorInt( "DecimalSeparator not present in FormatCode formatindex=\"%d\".",
813 [ # # ]: 0 : formatindex);
814 : : }
815 [ + - ]: 142 : pSep = pCtype->findNode( "ThousandSeparator");
816 [ - + ]: 142 : if (!pSep)
817 [ # # ]: 0 : incError( "No ThousandSeparator found for FormatCode.");
818 : : else
819 : : {
820 : 142 : nGrp = aCode.indexOf( pSep->getValue());
821 [ - + ]: 142 : if (nGrp < 0)
822 : : incErrorInt( "ThousandSeparator not present in FormatCode formatindex=\"%d\".",
823 [ # # ]: 0 : formatindex);
824 : : }
825 [ + - ][ + - ]: 142 : if (nDec >= 0 && nGrp >= 0 && nDec <= nGrp)
[ - + ]
826 : : incErrorInt( "Ordering of ThousandSeparator and DecimalSeparator not correct in formatindex=\"%d\".",
827 [ # # ]: 0 : formatindex);
828 : : }
829 [ + + ][ + + ]: 426 : if (formatindex == cssi::NumberFormatIndex::TIME_MMSS00 ||
830 : : formatindex == cssi::NumberFormatIndex::TIME_HH_MMSS00)
831 : : {
832 : 284 : sal_Int32 nTime = -1;
833 : 284 : sal_Int32 n100s = -1;
834 [ + - ]: 284 : const LocaleNode* pSep = pCtype->findNode( "TimeSeparator");
835 [ - + ]: 284 : if (!pSep)
836 [ # # ]: 0 : incError( "No TimeSeparator found for FormatCode.");
837 : : else
838 : : {
839 : 284 : nTime = aCode.indexOf( pSep->getValue());
840 [ - + ]: 284 : if (nTime < 0)
841 : : incErrorInt( "TimeSeparator not present in FormatCode formatindex=\"%d\".",
842 [ # # ]: 0 : formatindex);
843 : : }
844 [ + - ]: 284 : pSep = pCtype->findNode( "Time100SecSeparator");
845 [ - + ]: 284 : if (!pSep)
846 [ # # ]: 0 : incError( "No Time100SecSeparator found for FormatCode.");
847 : : else
848 : : {
849 : 284 : n100s = aCode.indexOf( pSep->getValue());
850 [ - + ]: 284 : if (n100s < 0)
851 : : incErrorInt( "Time100SecSeparator not present in FormatCode formatindex=\"%d\".",
852 [ # # ]: 0 : formatindex);
853 [ + - ]: 284 : OUStringBuffer a100s( pSep->getValue());
854 [ + - ]: 284 : a100s.appendAscii( "00");
855 [ + - ]: 284 : n100s = aCode.indexOf( a100s.makeStringAndClear());
856 [ - + ]: 284 : if (n100s < 0)
857 : : incErrorInt( "Time100SecSeparator+00 not present in FormatCode formatindex=\"%d\".",
858 [ # # ]: 284 : formatindex);
859 : : }
860 [ + - ][ + - ]: 284 : if (n100s >= 0 && nTime >= 0 && n100s <= nTime)
[ - + ]
861 : : incErrorInt( "Ordering of Time100SecSeparator and TimeSeparator not correct in formatindex=\"%d\".",
862 [ # # ]: 0 : formatindex);
863 : : }
864 [ - + ]: 426 : if (nSavErr != nError)
865 : : fprintf( stderr,
866 : : "Warning: formatindex=\"%d\",\"%d\",\"%d\" are the only FormatCode elements checked for separator usage, there may be others that have errors.\n",
867 : : int(cssi::NumberFormatIndex::NUMBER_1000DEC2),
868 : : int(cssi::NumberFormatIndex::TIME_MMSS00),
869 [ # # ]: 426 : int(cssi::NumberFormatIndex::TIME_HH_MMSS00));
870 : :
871 : : }
872 : : }
873 : : else
874 [ # # ]: 0 : incError( "No FormatCode in FormatElement.");
875 [ + - ]: 6958 : n = currNode -> findNode("DefaultName");
876 [ + + ]: 6958 : if (n)
877 [ + - ]: 158 : of.writeParameter("FormatDefaultName", n->getValue(), formatCount);
878 : : else
879 [ + - ]: 6800 : of.writeParameter("FormatDefaultName", ::rtl::OUString(), formatCount);
880 : :
881 : 7113 : }
882 : :
883 : : // Check presence of all required format codes only in first section
884 : : // LC_FORMAT, not in optional LC_FORMAT_1
885 [ + + ]: 147 : if (mnSection == 0)
886 : : {
887 : : // 0..47 MUST be present, 48,49 MUST NOT be present
888 : 146 : ValueSet::const_iterator aIter( aFormatIndexSet.begin());
889 [ + + ]: 7008 : for (sal_Int16 nNext = cssi::NumberFormatIndex::NUMBER_START;
890 : : nNext < cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES; ++nNext)
891 : : {
892 [ + - ]: 6862 : sal_Int16 nHere = ::std::min( ((aIter != aFormatIndexSet.end() ? *aIter :
893 : : cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES)),
894 [ + + ][ + - ]: 6862 : cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES);
[ + - ]
895 [ + - ][ + + ]: 6862 : if (aIter != aFormatIndexSet.end()) ++aIter;
[ + - ]
896 [ + + ]: 7446 : for ( ; nNext < nHere; ++nNext)
897 : : {
898 [ + - ]: 584 : switch (nNext)
899 : : {
900 : : case cssi::NumberFormatIndex::FRACTION_1 :
901 : : case cssi::NumberFormatIndex::FRACTION_2 :
902 : : case cssi::NumberFormatIndex::BOOLEAN :
903 : : case cssi::NumberFormatIndex::TEXT :
904 : : // generated internally
905 : 584 : break;
906 : : default:
907 [ # # ]: 0 : incErrorInt( "FormatElement formatindex=\"%d\" not present.", nNext);
908 : : }
909 : : }
910 [ - - + ]: 6862 : switch (nHere)
911 : : {
912 : : case cssi::NumberFormatIndex::BOOLEAN :
913 [ # # ]: 0 : incErrorInt( "FormatElement formatindex=\"%d\" reserved for internal ``BOOLEAN''.", nNext);
914 : 0 : break;
915 : : case cssi::NumberFormatIndex::TEXT :
916 [ # # ]: 0 : incErrorInt( "FormatElement formatindex=\"%d\" reserved for internal ``@'' (TEXT).", nNext);
917 : 0 : break;
918 : : default:
919 : : ; // nothing
920 : : }
921 : : }
922 : : }
923 : :
924 [ + - ]: 147 : of.writeAsciiString("\nstatic const sal_Int16 ");
925 [ + - ]: 147 : of.writeAsciiString("FormatElementsCount");
926 [ + - ]: 147 : of.writeInt(mnSection);
927 [ + - ]: 147 : of.writeAsciiString(" = ");
928 [ + - ]: 147 : of.writeInt( formatCount - mnFormats);
929 [ + - ]: 147 : of.writeAsciiString(";\n");
930 [ + - ]: 147 : of.writeAsciiString("static const sal_Unicode* ");
931 [ + - ]: 147 : of.writeAsciiString("FormatElementsArray");
932 [ + - ]: 147 : of.writeInt(mnSection);
933 [ + - ]: 147 : of.writeAsciiString("[] = {\n");
934 [ + + ]: 7105 : for(sal_Int16 i = mnFormats; i < formatCount; i++) {
935 : :
936 [ + - ]: 6958 : of.writeAsciiString("\t");
937 [ + - ]: 6958 : of.writeAsciiString("FormatCode");
938 [ + - ]: 6958 : of.writeInt(i);
939 [ + - ]: 6958 : of.writeAsciiString(",\n");
940 : :
941 [ + - ]: 6958 : of.writeAsciiString("\t");
942 [ + - ]: 6958 : of.writeAsciiString("FormatDefaultName");
943 [ + - ]: 6958 : of.writeInt(i);
944 [ + - ]: 6958 : of.writeAsciiString(",\n");
945 : :
946 [ + - ]: 6958 : of.writeAsciiString("\t");
947 [ + - ]: 6958 : of.writeAsciiString("FormatKey");
948 [ + - ]: 6958 : of.writeInt(i);
949 [ + - ]: 6958 : of.writeAsciiString(",\n");
950 : :
951 [ + - ]: 6958 : of.writeAsciiString("\t");
952 [ + - ]: 6958 : of.writeAsciiString("FormatType");
953 [ + - ]: 6958 : of.writeInt(i);
954 [ + - ]: 6958 : of.writeAsciiString(",\n");
955 : :
956 [ + - ]: 6958 : of.writeAsciiString("\t");
957 [ + - ]: 6958 : of.writeAsciiString("FormatUsage");
958 [ + - ]: 6958 : of.writeInt(i);
959 [ + - ]: 6958 : of.writeAsciiString(",\n");
960 : :
961 [ + - ]: 6958 : of.writeAsciiString("\t");
962 [ + - ]: 6958 : of.writeAsciiString("Formatindex");
963 [ + - ]: 6958 : of.writeInt(i);
964 [ + - ]: 6958 : of.writeAsciiString(",\n");
965 : :
966 : :
967 [ + - ]: 6958 : of.writeAsciiString("\tdefaultFormatElement");
968 [ + - ]: 6958 : of.writeInt(i);
969 [ + - ]: 6958 : of.writeAsciiString(",\n");
970 : : }
971 [ + - ]: 147 : of.writeAsciiString("};\n\n");
972 : :
973 [ + + - ]: 147 : switch (mnSection)
974 : : {
975 : : case 0:
976 [ + - ]: 146 : of.writeFunction("getAllFormats0_", "FormatElementsCount0", "FormatElementsArray0", "replaceFrom0", "replaceTo0");
977 : 146 : break;
978 : : case 1:
979 [ + - ]: 1 : of.writeFunction("getAllFormats1_", "FormatElementsCount1", "FormatElementsArray1", "replaceFrom1", "replaceTo1");
980 : 1 : break;
981 : : }
982 : :
983 : 147 : mnFormats = mnFormats + formatCount;
984 : :
985 [ + + ]: 147 : if (mnSection == 0)
986 : : {
987 : : // Extract and add date acceptance pattern for full date, so we provide
988 : : // at least one valid pattern, even if the number parser doesn't need
989 : : // that one.
990 : : /* XXX NOTE: only simple [...] modifier and "..." quotes detected and
991 : : * ignored, not nested, no fancy stuff. */
992 : 146 : sal_Int32 nIndex = 0;
993 : : // aDateSep can be empty if LC_CTYPE was a ref=..., determine from
994 : : // FormatCode then.
995 [ + + ][ + - ]: 146 : sal_uInt32 cDateSep = (aDateSep.isEmpty() ? 0 : aDateSep.iterateCodePoints( &nIndex));
996 : 146 : sal_uInt32 cDateSep2 = cDateSep;
997 : 146 : nIndex = 0;
998 : 146 : OUStringBuffer aPatternBuf(5);
999 : 146 : OUStringBuffer aPatternBuf2(5);
1000 : 146 : sal_uInt8 nDetected = 0; // bits Y,M,D
1001 : 146 : bool bInModifier = false;
1002 : 146 : bool bQuoted = false;
1003 [ + + ][ + + ]: 1249 : while (nIndex < sTheDateEditFormat.getLength() && nDetected < 7)
[ + + ]
1004 : : {
1005 [ + - ]: 1103 : sal_uInt32 cChar = sTheDateEditFormat.iterateCodePoints( &nIndex);
1006 [ + + ]: 1103 : if (bInModifier)
1007 : : {
1008 [ + + ]: 33 : if (cChar == ']')
1009 : 4 : bInModifier = false;
1010 : 33 : continue; // while
1011 : : }
1012 [ - + ]: 1070 : if (bQuoted)
1013 : : {
1014 [ # # ]: 0 : if (cChar == '"')
1015 : 0 : bQuoted = false;
1016 : 0 : continue; // while
1017 : : }
1018 [ + + + + : 1070 : switch (cChar)
- - + + +
+ + + + +
+ ]
1019 : : {
1020 : : case 'Y':
1021 : : case 'y':
1022 [ + + ]: 193 : if (!(nDetected & 4))
1023 : : {
1024 [ + - ]: 118 : aPatternBuf.append( 'Y');
1025 [ - + ]: 118 : if (aPatternBuf2.getLength() > 0)
1026 [ # # ]: 0 : aPatternBuf2.append( 'Y');
1027 : 118 : nDetected |= 4;
1028 : : }
1029 : 193 : break;
1030 : : case 'M':
1031 : : case 'm':
1032 [ + + ]: 284 : if (!(nDetected & 2))
1033 : : {
1034 [ + - ]: 145 : aPatternBuf.append( 'M');
1035 [ + + ]: 145 : if (aPatternBuf2.getLength() > 0)
1036 [ + - ]: 1 : aPatternBuf2.append( 'M');
1037 : 145 : nDetected |= 2;
1038 : : }
1039 : 284 : break;
1040 : : case 'D':
1041 : : case 'd':
1042 [ + + ]: 237 : if (!(nDetected & 1))
1043 : : {
1044 [ + - ]: 133 : aPatternBuf.append( 'D');
1045 [ + + ]: 133 : if (aPatternBuf2.getLength() > 0)
1046 [ + - ]: 1 : aPatternBuf2.append( 'D');
1047 : 133 : nDetected |= 1;
1048 : : }
1049 : 237 : break;
1050 : : case '[':
1051 : 4 : bInModifier = true;
1052 : 4 : break;
1053 : : case '"':
1054 : 0 : bQuoted = true;
1055 : 0 : break;
1056 : : case '\\':
1057 [ # # ]: 0 : cChar = sTheDateEditFormat.iterateCodePoints( &nIndex);
1058 : 0 : break;
1059 : : case '-':
1060 : : case '.':
1061 : : case '/':
1062 : : // There are locales that use an ISO 8601 edit format
1063 : : // regardless of what the date separator or other formats
1064 : : // say, for example hu-HU. Generalize this for all cases
1065 : : // where the used separator differs and is one of the known
1066 : : // separators and generate a second pattern with the
1067 : : // format's separator at the current position.
1068 : 290 : cDateSep2 = cChar;
1069 : : // fallthru
1070 : : default:
1071 [ + + ]: 294 : if (!cDateSep)
1072 : 4 : cDateSep = cChar;
1073 [ - + ]: 294 : if (!cDateSep2)
1074 : 0 : cDateSep2 = cChar;
1075 [ + + ][ + + ]: 294 : if (cDateSep != cDateSep2 && aPatternBuf2.getLength() == 0)
[ + + ]
1076 [ + - ]: 1 : aPatternBuf2 = aPatternBuf;
1077 [ + + ][ + + ]: 294 : if (cChar == cDateSep || cChar == cDateSep2)
1078 [ + - ][ + - ]: 292 : aPatternBuf.append( OUString( &cDateSep, 1)); // always the defined separator
1079 [ + + ][ + + ]: 294 : if (cChar == cDateSep2 && aPatternBuf2.getLength() > 0)
[ + + ]
1080 [ + - ][ + - ]: 2 : aPatternBuf2.append( OUString( &cDateSep2, 1)); // always the format's separator
1081 : 294 : break;
1082 : : // The localized legacy:
1083 : : case 'A':
1084 [ + + ][ + + ]: 23 : if (((nDetected & 7) == 3) || ((nDetected & 7) == 0))
1085 : : {
1086 : : // es DD/MM/AAAA
1087 : : // fr JJ.MM.AAAA
1088 : : // it GG/MM/AAAA
1089 : : // fr_CA AAAA-MM-JJ
1090 [ + - ]: 20 : aPatternBuf.append( 'Y');
1091 [ - + ]: 20 : if (aPatternBuf2.getLength() > 0)
1092 [ # # ]: 0 : aPatternBuf2.append( 'Y');
1093 : 20 : nDetected |= 4;
1094 : : }
1095 : 23 : break;
1096 : : case 'J':
1097 [ + + ][ + + ]: 16 : if (((nDetected & 7) == 0) || ((nDetected & 7) == 6))
1098 : : {
1099 : : // fr JJ.MM.AAAA
1100 : : // fr_CA AAAA-MM-JJ
1101 [ + - ]: 5 : aPatternBuf.append( 'D');
1102 [ - + ]: 5 : if (aPatternBuf2.getLength() > 0)
1103 [ # # ]: 0 : aPatternBuf2.append( 'D');
1104 : 5 : nDetected |= 1;
1105 : : }
1106 [ + + ]: 11 : else if ((nDetected & 7) == 3)
1107 : : {
1108 : : // nl DD-MM-JJJJ
1109 : : // de TT.MM.JJJJ
1110 [ + - ]: 7 : aPatternBuf.append( 'Y');
1111 [ - + ]: 7 : if (aPatternBuf2.getLength() > 0)
1112 [ # # ]: 0 : aPatternBuf2.append( 'Y');
1113 : 7 : nDetected |= 4;
1114 : : }
1115 : 16 : break;
1116 : : case 'T':
1117 [ + + ]: 10 : if ((nDetected & 7) == 0)
1118 : : {
1119 : : // de TT.MM.JJJJ
1120 [ + - ]: 5 : aPatternBuf.append( 'D');
1121 [ - + ]: 5 : if (aPatternBuf2.getLength() > 0)
1122 [ # # ]: 0 : aPatternBuf2.append( 'D');
1123 : 5 : nDetected |= 1;
1124 : : }
1125 : 10 : break;
1126 : : case 'G':
1127 [ + + ]: 4 : if ((nDetected & 7) == 0)
1128 : : {
1129 : : // it GG/MM/AAAA
1130 [ + - ]: 2 : aPatternBuf.append( 'D');
1131 [ - + ]: 2 : if (aPatternBuf2.getLength() > 0)
1132 [ # # ]: 0 : aPatternBuf2.append( 'D');
1133 : 2 : nDetected |= 1;
1134 : : }
1135 : 4 : break;
1136 : : case 'P':
1137 [ + + ]: 2 : if ((nDetected & 7) == 0)
1138 : : {
1139 : : // fi PP.KK.VVVV
1140 [ + - ]: 1 : aPatternBuf.append( 'D');
1141 [ - + ]: 1 : if (aPatternBuf2.getLength() > 0)
1142 [ # # ]: 0 : aPatternBuf2.append( 'D');
1143 : 1 : nDetected |= 1;
1144 : : }
1145 : 2 : break;
1146 : : case 'K':
1147 [ + + ]: 2 : if ((nDetected & 7) == 1)
1148 : : {
1149 : : // fi PP.KK.VVVV
1150 [ + - ]: 1 : aPatternBuf.append( 'M');
1151 [ - + ]: 1 : if (aPatternBuf2.getLength() > 0)
1152 [ # # ]: 0 : aPatternBuf2.append( 'M');
1153 : 1 : nDetected |= 2;
1154 : : }
1155 : 2 : break;
1156 : : case 'V':
1157 [ + - ]: 1 : if ((nDetected & 7) == 3)
1158 : : {
1159 : : // fi PP.KK.VVVV
1160 [ + - ]: 1 : aPatternBuf.append( 'Y');
1161 [ - + ]: 1 : if (aPatternBuf2.getLength() > 0)
1162 [ # # ]: 0 : aPatternBuf2.append( 'Y');
1163 : 1 : nDetected |= 4;
1164 : : }
1165 : 1 : break;
1166 : : }
1167 : : }
1168 [ + - ]: 146 : OUString aPattern( aPatternBuf.makeStringAndClear());
1169 [ + - ][ - + ]: 146 : if (((nDetected & 7) != 7) || aPattern.getLength() < 5)
[ - + ]
1170 : : {
1171 [ # # ]: 0 : incErrorStr( "failed to extract full date acceptance pattern", aPattern);
1172 : : fprintf( stderr, " with DateSeparator '%s' from FormatCode '%s' (formatindex=\"%d\")\n",
1173 : : OSTR( OUString( cDateSep)), OSTR( sTheDateEditFormat),
1174 [ # # ][ # # ]: 0 : (int)cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY);
[ # # ]
1175 : : }
1176 : : else
1177 : : {
1178 : : fprintf( stderr, "Generated date acceptance pattern: '%s' from '%s' (formatindex=\"%d\" and defined DateSeparator '%s')\n",
1179 : : OSTR( aPattern), OSTR( sTheDateEditFormat),
1180 : : (int)cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY,
1181 [ + - ][ + - ]: 146 : OSTR( OUString( cDateSep)));
[ + - ][ + - ]
1182 : : // Insert at front so full date pattern is first in checks.
1183 [ + - ]: 146 : theDateAcceptancePatterns.insert( theDateAcceptancePatterns.begin(), aPattern);
1184 : : }
1185 [ + + ]: 146 : if (aPatternBuf2.getLength() > 0)
1186 : : {
1187 [ + - ]: 1 : OUString aPattern2( aPatternBuf2.makeStringAndClear());
1188 [ - + ]: 1 : if (aPattern2.getLength() < 5)
1189 : : {
1190 [ # # ]: 0 : incErrorStr( "failed to extract 2nd date acceptance pattern", aPattern2);
1191 : : fprintf( stderr, " with DateSeparator '%s' from FormatCode '%s' (formatindex=\"%d\")\n",
1192 : : OSTR( OUString( cDateSep2)), OSTR( sTheDateEditFormat),
1193 [ # # ][ # # ]: 0 : (int)cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY);
[ # # ]
1194 : : }
1195 : : else
1196 : : {
1197 : : fprintf( stderr, "Generated 2nd acceptance pattern: '%s' from '%s' (formatindex=\"%d\")\n",
1198 : : OSTR( aPattern2), OSTR( sTheDateEditFormat),
1199 [ + - ][ + - ]: 1 : (int)cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY);
[ + - ]
1200 [ + - ]: 1 : theDateAcceptancePatterns.insert( theDateAcceptancePatterns.begin(), aPattern2);
1201 : 1 : }
1202 : : }
1203 : :
1204 : : // Rudimentary check if a pattern interferes with decimal number.
1205 : 146 : nIndex = 0;
1206 [ + - ]: 146 : sal_uInt32 cDecSep = aDecSep.iterateCodePoints( &nIndex);
1207 [ + - ][ + - ]: 896 : for (vector<OUString>::const_iterator aIt = theDateAcceptancePatterns.begin();
[ + + ]
1208 : 448 : aIt != theDateAcceptancePatterns.end(); ++aIt)
1209 : : {
1210 [ + - ][ + + ]: 302 : if ((*aIt).getLength() == (cDecSep <= 0xffff ? 3 : 4))
1211 : : {
1212 : 100 : nIndex = 1;
1213 [ + - ][ - + ]: 100 : if ((*aIt).iterateCodePoints( &nIndex) == cDecSep)
1214 : : {
1215 : 0 : ++nError;
1216 : : fprintf( stderr, "Error: Date acceptance pattern '%s' matches decimal number '#%s#'\n",
1217 [ # # ][ # # ]: 0 : OSTR( *aIt), OSTR( aDecSep));
[ # # ]
1218 : : }
1219 : : }
1220 : : }
1221 : :
1222 : : // Check for duplicates.
1223 [ + - ][ + - ]: 896 : for (vector<OUString>::const_iterator aIt = theDateAcceptancePatterns.begin();
[ + + ]
1224 : 448 : aIt != theDateAcceptancePatterns.end(); ++aIt)
1225 : : {
1226 [ + - ][ + + ]: 1446 : for (vector<OUString>::iterator aComp = theDateAcceptancePatterns.begin();
1227 : 1144 : aComp != theDateAcceptancePatterns.end(); /*nop*/)
1228 : : {
1229 [ + - ][ + + ]: 842 : if (aIt != aComp && *aIt == *aComp)
[ - + ][ - + ]
1230 : : {
1231 [ # # ]: 0 : incErrorStr( "Duplicated DateAcceptancePattern", *aComp);
1232 [ # # ]: 0 : aComp = theDateAcceptancePatterns.erase( aComp);
1233 : : }
1234 : : else
1235 : 842 : ++aComp;
1236 : : }
1237 : : }
1238 : :
1239 : 146 : sal_Int16 nbOfDateAcceptancePatterns = static_cast<sal_Int16>(theDateAcceptancePatterns.size());
1240 : :
1241 [ + + ]: 448 : for (sal_Int16 i = 0; i < nbOfDateAcceptancePatterns; ++i)
1242 : : {
1243 [ + - ]: 302 : of.writeParameter("DateAcceptancePattern", theDateAcceptancePatterns[i], i);
1244 : : }
1245 : :
1246 [ + - ]: 146 : of.writeAsciiString("static const sal_Int16 DateAcceptancePatternsCount = ");
1247 [ + - ]: 146 : of.writeInt( nbOfDateAcceptancePatterns);
1248 [ + - ]: 146 : of.writeAsciiString(";\n");
1249 : :
1250 [ + - ]: 146 : of.writeAsciiString("static const sal_Unicode* DateAcceptancePatternsArray[] = {\n");
1251 [ + + ]: 448 : for (sal_Int16 i = 0; i < nbOfDateAcceptancePatterns; ++i)
1252 : : {
1253 [ + - ]: 302 : of.writeAsciiString("\t");
1254 [ + - ]: 302 : of.writeAsciiString("DateAcceptancePattern");
1255 [ + - ]: 302 : of.writeInt(i);
1256 [ + - ]: 302 : of.writeAsciiString(",\n");
1257 : : }
1258 [ + - ]: 146 : of.writeAsciiString("};\n\n");
1259 : :
1260 [ + - ]: 146 : of.writeFunction("getDateAcceptancePatterns_", "DateAcceptancePatternsCount", "DateAcceptancePatternsArray");
1261 : : }
1262 : :
1263 [ + + ][ + + ]: 198 : ++mnSection;
[ + + ][ + + ]
1264 : : }
1265 : :
1266 : 197 : void LCCollationNode::generateCode (const OFileWriter &of) const
1267 : : {
1268 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1269 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1270 [ + - ]: 121 : of.writeRefFunction("getCollatorImplementation_", useLocale);
1271 [ + - ]: 121 : of.writeRefFunction("getCollationOptions_", useLocale);
1272 : 197 : return;
1273 : : }
1274 : 76 : sal_Int16 nbOfCollations = 0;
1275 : 76 : sal_Int16 nbOfCollationOptions = 0;
1276 : : sal_Int16 j;
1277 : :
1278 [ + + ]: 240 : for ( j = 0; j < getNumberOfChildren(); j++ ) {
1279 : 164 : LocaleNode * currNode = getChildAt (j);
1280 [ + + ]: 164 : if( currNode->getName().compareToAscii("Collator") == 0 )
1281 : : {
1282 : 88 : ::rtl::OUString str;
1283 [ + - ]: 88 : str = currNode->getAttr().getValueByName("unoid");
1284 [ + - ]: 88 : of.writeParameter("CollatorID", str, j);
1285 : 88 : str = currNode->getValue();
1286 [ + - ]: 88 : of.writeParameter("CollatorRule", str, j);
1287 [ + - ]: 88 : str = currNode -> getAttr().getValueByName("default");
1288 [ + - ]: 88 : of.writeDefaultParameter("Collator", str, j);
1289 [ + - ]: 88 : of.writeAsciiString("\n");
1290 : :
1291 : 88 : nbOfCollations++;
1292 : : }
1293 [ + + ]: 164 : if( currNode->getName().compareToAscii("CollationOptions") == 0 )
1294 : : {
1295 : 76 : LocaleNode* pCollationOptions = currNode;
1296 : 76 : nbOfCollationOptions = sal::static_int_cast<sal_Int16>( pCollationOptions->getNumberOfChildren() );
1297 [ + + ]: 152 : for( sal_Int16 i=0; i<nbOfCollationOptions; i++ )
1298 : : {
1299 [ + - ]: 76 : of.writeParameter("collationOption", pCollationOptions->getChildAt( i )->getValue(), i );
1300 : : }
1301 : :
1302 [ + - ]: 76 : of.writeAsciiString("static const sal_Int16 nbOfCollationOptions = ");
1303 [ + - ]: 76 : of.writeInt( nbOfCollationOptions );
1304 [ + - ]: 76 : of.writeAsciiString(";\n\n");
1305 : : }
1306 : : }
1307 [ + - ]: 76 : of.writeAsciiString("static const sal_Int16 nbOfCollations = ");
1308 [ + - ]: 76 : of.writeInt(nbOfCollations);
1309 [ + - ]: 76 : of.writeAsciiString(";\n\n");
1310 : :
1311 [ + - ]: 76 : of.writeAsciiString("\nstatic const sal_Unicode* LCCollatorArray[] = {\n");
1312 [ + + ]: 164 : for(j = 0; j < nbOfCollations; j++) {
1313 [ + - ]: 88 : of.writeAsciiString("\tCollatorID");
1314 [ + - ]: 88 : of.writeInt(j);
1315 [ + - ]: 88 : of.writeAsciiString(",\n");
1316 : :
1317 [ + - ]: 88 : of.writeAsciiString("\tdefaultCollator");
1318 [ + - ]: 88 : of.writeInt(j);
1319 [ + - ]: 88 : of.writeAsciiString(",\n");
1320 : :
1321 [ + - ]: 88 : of.writeAsciiString("\tCollatorRule");
1322 [ + - ]: 88 : of.writeInt(j);
1323 [ + - ]: 88 : of.writeAsciiString(",\n");
1324 : : }
1325 [ + - ]: 76 : of.writeAsciiString("};\n\n");
1326 : :
1327 [ + - ]: 76 : of.writeAsciiString("static const sal_Unicode* collationOptions[] = {");
1328 [ + + ]: 152 : for( j=0; j<nbOfCollationOptions; j++ )
1329 : : {
1330 [ + - ]: 76 : of.writeAsciiString( "collationOption" );
1331 [ + - ]: 76 : of.writeInt( j );
1332 [ + - ]: 76 : of.writeAsciiString( ", " );
1333 : : }
1334 [ + - ]: 76 : of.writeAsciiString("NULL };\n");
1335 [ + - ]: 76 : of.writeFunction("getCollatorImplementation_", "nbOfCollations", "LCCollatorArray");
1336 [ + - ][ + + ]: 197 : of.writeFunction("getCollationOptions_", "nbOfCollationOptions", "collationOptions");
1337 : : }
1338 : :
1339 : 197 : void LCSearchNode::generateCode (const OFileWriter &of) const
1340 : : {
1341 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1342 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1343 [ + - ]: 132 : of.writeRefFunction("getSearchOptions_", useLocale);
1344 : 197 : return;
1345 : : }
1346 : :
1347 [ - + ]: 65 : if( getNumberOfChildren() != 1 )
1348 : : {
1349 : 0 : ++nError;
1350 : : fprintf(
1351 : : stderr, "Error: LC_SEARCH: more than 1 child: %ld\n",
1352 [ # # ]: 0 : sal::static_int_cast< long >(getNumberOfChildren()));
1353 : : }
1354 : : sal_Int32 i;
1355 : 65 : LocaleNode* pSearchOptions = getChildAt( 0 );
1356 : 65 : sal_Int32 nSearchOptions = pSearchOptions->getNumberOfChildren();
1357 [ + + ]: 132 : for( i=0; i<nSearchOptions; i++ )
1358 : : {
1359 [ + - ]: 67 : of.writeParameter("searchOption", pSearchOptions->getChildAt( i )->getValue(), sal::static_int_cast<sal_Int16>(i) );
1360 : : }
1361 : :
1362 [ + - ]: 65 : of.writeAsciiString("static const sal_Int16 nbOfSearchOptions = ");
1363 [ + - ]: 65 : of.writeInt( sal::static_int_cast<sal_Int16>( nSearchOptions ) );
1364 [ + - ]: 65 : of.writeAsciiString(";\n\n");
1365 : :
1366 [ + - ]: 65 : of.writeAsciiString("static const sal_Unicode* searchOptions[] = {");
1367 [ + + ]: 132 : for( i=0; i<nSearchOptions; i++ )
1368 : : {
1369 [ + - ]: 67 : of.writeAsciiString( "searchOption" );
1370 [ + - ]: 67 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1371 [ + - ]: 67 : of.writeAsciiString( ", " );
1372 : : }
1373 [ + - ]: 65 : of.writeAsciiString("NULL };\n");
1374 [ + - ][ + + ]: 197 : of.writeFunction("getSearchOptions_", "nbOfSearchOptions", "searchOptions");
1375 : : }
1376 : :
1377 : 197 : void LCIndexNode::generateCode (const OFileWriter &of) const
1378 : : {
1379 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1380 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1381 [ + - ]: 80 : of.writeRefFunction("getIndexAlgorithm_", useLocale);
1382 [ + - ]: 80 : of.writeRefFunction("getUnicodeScripts_", useLocale);
1383 [ + - ]: 80 : of.writeRefFunction("getFollowPageWords_", useLocale);
1384 : 197 : return;
1385 : : }
1386 : 117 : sal_Int16 nbOfIndexs = 0;
1387 : 117 : sal_Int16 nbOfUnicodeScripts = 0;
1388 : 117 : sal_Int16 nbOfPageWords = 0;
1389 : : sal_Int16 i;
1390 [ + + ]: 703 : for (i = 0; i< getNumberOfChildren();i++) {
1391 : 586 : LocaleNode * currNode = getChildAt (i);
1392 [ + + ]: 586 : if( currNode->getName().compareToAscii("IndexKey") == 0 )
1393 : : {
1394 : 125 : ::rtl::OUString str;
1395 [ + - ]: 125 : str = currNode->getAttr().getValueByName("unoid");
1396 [ + - ]: 125 : of.writeParameter("IndexID", str, nbOfIndexs);
1397 [ + - ]: 125 : str = currNode->getAttr().getValueByName("module");
1398 [ + - ]: 125 : of.writeParameter("IndexModule", str, nbOfIndexs);
1399 : 125 : str = currNode->getValue();
1400 [ + - ]: 125 : of.writeParameter("IndexKey", str, nbOfIndexs);
1401 [ + - ]: 125 : str = currNode -> getAttr().getValueByName("default");
1402 [ + - ]: 125 : of.writeDefaultParameter("Index", str, nbOfIndexs);
1403 [ + - ]: 125 : str = currNode -> getAttr().getValueByName("phonetic");
1404 [ + - ]: 125 : of.writeDefaultParameter("Phonetic", str, nbOfIndexs);
1405 [ + - ]: 125 : of.writeAsciiString("\n");
1406 : :
1407 : 125 : nbOfIndexs++;
1408 : : }
1409 [ + + ]: 586 : if( currNode->getName().compareToAscii("UnicodeScript") == 0 )
1410 : : {
1411 [ + - ]: 231 : of.writeParameter("unicodeScript", currNode->getValue(), nbOfUnicodeScripts );
1412 : 231 : nbOfUnicodeScripts++;
1413 : :
1414 : : }
1415 [ + + ]: 586 : if( currNode->getName().compareToAscii("FollowPageWord") == 0 )
1416 : : {
1417 [ + - ]: 230 : of.writeParameter("followPageWord", currNode->getValue(), nbOfPageWords);
1418 : 230 : nbOfPageWords++;
1419 : : }
1420 : : }
1421 [ + - ]: 117 : of.writeAsciiString("static const sal_Int16 nbOfIndexs = ");
1422 [ + - ]: 117 : of.writeInt(nbOfIndexs);
1423 [ + - ]: 117 : of.writeAsciiString(";\n\n");
1424 : :
1425 [ + - ]: 117 : of.writeAsciiString("\nstatic const sal_Unicode* IndexArray[] = {\n");
1426 [ + + ]: 242 : for(i = 0; i < nbOfIndexs; i++) {
1427 [ + - ]: 125 : of.writeAsciiString("\tIndexID");
1428 [ + - ]: 125 : of.writeInt(i);
1429 [ + - ]: 125 : of.writeAsciiString(",\n");
1430 : :
1431 [ + - ]: 125 : of.writeAsciiString("\tIndexModule");
1432 [ + - ]: 125 : of.writeInt(i);
1433 [ + - ]: 125 : of.writeAsciiString(",\n");
1434 : :
1435 [ + - ]: 125 : of.writeAsciiString("\tIndexKey");
1436 [ + - ]: 125 : of.writeInt(i);
1437 [ + - ]: 125 : of.writeAsciiString(",\n");
1438 : :
1439 [ + - ]: 125 : of.writeAsciiString("\tdefaultIndex");
1440 [ + - ]: 125 : of.writeInt(i);
1441 [ + - ]: 125 : of.writeAsciiString(",\n");
1442 : :
1443 [ + - ]: 125 : of.writeAsciiString("\tdefaultPhonetic");
1444 [ + - ]: 125 : of.writeInt(i);
1445 [ + - ]: 125 : of.writeAsciiString(",\n");
1446 : : }
1447 [ + - ]: 117 : of.writeAsciiString("};\n\n");
1448 : :
1449 [ + - ]: 117 : of.writeAsciiString("static const sal_Int16 nbOfUnicodeScripts = ");
1450 [ + - ]: 117 : of.writeInt( nbOfUnicodeScripts );
1451 [ + - ]: 117 : of.writeAsciiString(";\n\n");
1452 : :
1453 [ + - ]: 117 : of.writeAsciiString("static const sal_Unicode* UnicodeScriptArray[] = {");
1454 [ + + ]: 348 : for( i=0; i<nbOfUnicodeScripts; i++ )
1455 : : {
1456 [ + - ]: 231 : of.writeAsciiString( "unicodeScript" );
1457 [ + - ]: 231 : of.writeInt( i );
1458 [ + - ]: 231 : of.writeAsciiString( ", " );
1459 : : }
1460 [ + - ]: 117 : of.writeAsciiString("NULL };\n\n");
1461 : :
1462 [ + - ]: 117 : of.writeAsciiString("static const sal_Int16 nbOfPageWords = ");
1463 [ + - ]: 117 : of.writeInt(nbOfPageWords);
1464 [ + - ]: 117 : of.writeAsciiString(";\n\n");
1465 : :
1466 [ + - ]: 117 : of.writeAsciiString("static const sal_Unicode* FollowPageWordArray[] = {\n");
1467 [ + + ]: 347 : for(i = 0; i < nbOfPageWords; i++) {
1468 [ + - ]: 230 : of.writeAsciiString("\tfollowPageWord");
1469 [ + - ]: 230 : of.writeInt(i);
1470 [ + - ]: 230 : of.writeAsciiString(",\n");
1471 : : }
1472 [ + - ]: 117 : of.writeAsciiString("\tNULL\n};\n\n");
1473 : :
1474 [ + - ]: 117 : of.writeFunction("getIndexAlgorithm_", "nbOfIndexs", "IndexArray");
1475 [ + - ]: 117 : of.writeFunction("getUnicodeScripts_", "nbOfUnicodeScripts", "UnicodeScriptArray");
1476 [ + - ][ + + ]: 197 : of.writeFunction("getFollowPageWords_", "nbOfPageWords", "FollowPageWordArray");
1477 : : }
1478 : :
1479 : :
1480 : 7051 : static void lcl_writeAbbrFullNarrNames( const OFileWriter & of, const LocaleNode* currNode,
1481 : : const sal_Char* elementTag, sal_Int16 i, sal_Int16 j )
1482 : : {
1483 : 7051 : OUString aAbbrName = currNode->getChildAt(1)->getValue();
1484 : 7051 : OUString aFullName = currNode->getChildAt(2)->getValue();
1485 : 7051 : OUString aNarrName;
1486 [ - + ]: 7051 : LocaleNode* p = (currNode->getNumberOfChildren() > 3 ? currNode->getChildAt(3) : 0);
1487 [ - + ][ # # ]: 7051 : if ( p && p->getName() == "DefaultNarrowName" )
[ - + ]
1488 : 0 : aNarrName = p->getValue();
1489 : : else
1490 : : {
1491 : 7051 : sal_Int32 nIndex = 0;
1492 [ + - ]: 7051 : sal_uInt32 nChar = aFullName.iterateCodePoints( &nIndex);
1493 [ + - ]: 7051 : aNarrName = OUString( &nChar, 1);
1494 : : }
1495 [ + - ]: 7051 : of.writeParameter( elementTag, "DefaultAbbrvName", aAbbrName, i, j);
1496 [ + - ]: 7051 : of.writeParameter( elementTag, "DefaultFullName", aFullName, i, j);
1497 [ + - ]: 7051 : of.writeParameter( elementTag, "DefaultNarrowName", aNarrName, i, j);
1498 : 7051 : }
1499 : :
1500 : 29279 : static void lcl_writeTabTagString( const OFileWriter & of, const sal_Char* pTag, const sal_Char* pStr )
1501 : : {
1502 : 29279 : of.writeAsciiString("\t");
1503 : 29279 : of.writeAsciiString( pTag);
1504 : 29279 : of.writeAsciiString( pStr);
1505 : 29279 : }
1506 : :
1507 : 29197 : static void lcl_writeTabTagStringNums( const OFileWriter & of,
1508 : : const sal_Char* pTag, const sal_Char* pStr, sal_Int16 i, sal_Int16 j )
1509 : : {
1510 : 29197 : lcl_writeTabTagString( of, pTag, pStr);
1511 : 29197 : of.writeInt(i); of.writeInt(j); of.writeAsciiString(",\n");
1512 : 29197 : }
1513 : :
1514 : 860 : static void lcl_writeAbbrFullNarrArrays( const OFileWriter & of, sal_Int16 nCount,
1515 : : const sal_Char* elementTag, sal_Int16 i, bool bNarrow )
1516 : : {
1517 [ + + ]: 860 : if (nCount == 0)
1518 : : {
1519 : 41 : lcl_writeTabTagString( of, elementTag, "Ref");
1520 : 41 : of.writeInt(i); of.writeAsciiString(",\n");
1521 : 41 : lcl_writeTabTagString( of, elementTag, "RefName");
1522 : 41 : of.writeInt(i); of.writeAsciiString(",\n");
1523 : : }
1524 : : else
1525 : : {
1526 [ + + ]: 8201 : for (sal_Int16 j = 0; j < nCount; j++)
1527 : : {
1528 : 7382 : lcl_writeTabTagStringNums( of, elementTag, "ID", i, j);
1529 : 7382 : lcl_writeTabTagStringNums( of, elementTag, "DefaultAbbrvName", i, j);
1530 : 7382 : lcl_writeTabTagStringNums( of, elementTag, "DefaultFullName", i, j);
1531 [ + + ]: 7382 : if (bNarrow)
1532 : 7051 : lcl_writeTabTagStringNums( of, elementTag, "DefaultNarrowName", i, j);
1533 : : }
1534 : : }
1535 : 860 : }
1536 : :
1537 : 197 : void LCCalendarNode::generateCode (const OFileWriter &of) const
1538 : : {
1539 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1540 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1541 [ + - ]: 39 : of.writeRefFunction("getAllCalendars_", useLocale);
1542 : 197 : return;
1543 : : }
1544 : 158 : sal_Int16 nbOfCalendars = sal::static_int_cast<sal_Int16>( getNumberOfChildren() );
1545 : 158 : ::rtl::OUString str;
1546 [ + - ]: 158 : sal_Int16 * nbOfDays = new sal_Int16[nbOfCalendars];
1547 [ + - ]: 158 : sal_Int16 * nbOfMonths = new sal_Int16[nbOfCalendars];
1548 [ + - ]: 158 : sal_Int16 * nbOfGenitiveMonths = new sal_Int16[nbOfCalendars];
1549 [ + - ]: 158 : sal_Int16 * nbOfPartitiveMonths = new sal_Int16[nbOfCalendars];
1550 [ + - ]: 158 : sal_Int16 * nbOfEras = new sal_Int16[nbOfCalendars];
1551 : : sal_Int16 j;
1552 : : sal_Int16 i;
1553 : 158 : bool bHasGregorian = false;
1554 : :
1555 : :
1556 [ + + ]: 330 : for ( i = 0; i < nbOfCalendars; i++) {
1557 : 172 : LocaleNode * calNode = getChildAt (i);
1558 [ + - ]: 172 : OUString calendarID = calNode -> getAttr().getValueByName("unoid");
1559 [ + - ]: 172 : of.writeParameter( "calendarID", calendarID, i);
1560 : 172 : bool bGregorian = calendarID == "gregorian";
1561 [ + + ]: 172 : if (!bHasGregorian)
1562 : 160 : bHasGregorian = bGregorian;
1563 [ + - ]: 172 : str = calNode -> getAttr().getValueByName("default");
1564 [ + - ]: 172 : of.writeDefaultParameter("Calendar", str, i);
1565 : :
1566 : 172 : sal_Int16 nChild = 0;
1567 : :
1568 : : // Generate Days of Week
1569 : : const sal_Char *elementTag;
1570 : 172 : LocaleNode * daysNode = NULL;
1571 [ + - ]: 172 : ::rtl::OUString ref_name = calNode->getChildAt(nChild)->getAttr().getValueByName("ref");
1572 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && i > 0) {
[ + + ]
1573 [ + + ]: 6 : for (j = 0; j < i; j++) {
1574 [ + - ]: 3 : str = getChildAt(j)->getAttr().getValueByName("unoid");
1575 [ + + ]: 3 : if (str.equals(ref_name))
1576 : 2 : daysNode = getChildAt(j)->getChildAt(0);
1577 : : }
1578 : : }
1579 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && daysNode == NULL) {
[ + + ]
1580 [ + - ]: 9 : of.writeParameter("dayRef", OUString("ref"), i);
1581 [ + - ]: 9 : of.writeParameter("dayRefName", ref_name, i);
1582 : 9 : nbOfDays[i] = 0;
1583 : : } else {
1584 [ + + ]: 163 : if (daysNode == NULL)
1585 : 161 : daysNode = calNode -> getChildAt(nChild);
1586 : 163 : nbOfDays[i] = sal::static_int_cast<sal_Int16>( daysNode->getNumberOfChildren() );
1587 [ - + ][ + + ]: 163 : if (bGregorian && nbOfDays[i] != 7)
1588 [ # # ]: 0 : incErrorInt( "A Gregorian calendar must have 7 days per week, this one has %d", nbOfDays[i]);
1589 : 163 : elementTag = "day";
1590 [ + + ]: 1304 : for (j = 0; j < nbOfDays[i]; j++) {
1591 : 1141 : LocaleNode *currNode = daysNode -> getChildAt(j);
1592 : 1141 : OUString dayID( currNode->getChildAt(0)->getValue());
1593 [ + - ]: 1141 : of.writeParameter("dayID", dayID, i, j);
1594 [ + + ][ + + ]: 1141 : if ( j == 0 && bGregorian && dayID != "sun" )
[ - + ][ - + ]
1595 [ # # ]: 0 : incError( "First day of a week of a Gregorian calendar must be <DayID>sun</DayID>");
1596 [ + - ]: 1141 : lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j);
1597 : 1141 : }
1598 : : }
1599 : 172 : ++nChild;
1600 : :
1601 : : // Generate Months of Year
1602 : 172 : LocaleNode * monthsNode = NULL;
1603 [ + - ]: 172 : ref_name = calNode->getChildAt(nChild)->getAttr().getValueByName("ref");
1604 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && i > 0) {
[ + + ]
1605 [ + + ]: 2 : for (j = 0; j < i; j++) {
1606 [ + - ]: 1 : str = getChildAt(j)->getAttr().getValueByName("unoid");
1607 [ + - ]: 1 : if (str.equals(ref_name))
1608 : 1 : monthsNode = getChildAt(j)->getChildAt(1);
1609 : : }
1610 : : }
1611 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && monthsNode == NULL) {
[ + + ]
1612 [ + - ]: 8 : of.writeParameter("monthRef", OUString("ref"), i);
1613 [ + - ]: 8 : of.writeParameter("monthRefName", ref_name, i);
1614 : 8 : nbOfMonths[i] = 0;
1615 : : } else {
1616 [ + + ]: 164 : if (monthsNode == NULL)
1617 : 163 : monthsNode = calNode -> getChildAt(nChild);
1618 : 164 : nbOfMonths[i] = sal::static_int_cast<sal_Int16>( monthsNode->getNumberOfChildren() );
1619 [ - + ][ + + ]: 164 : if (bGregorian && nbOfMonths[i] != 12)
1620 [ # # ]: 0 : incErrorInt( "A Gregorian calendar must have 12 months, this one has %d", nbOfMonths[i]);
1621 : 164 : elementTag = "month";
1622 [ + + ]: 2134 : for (j = 0; j < nbOfMonths[i]; j++) {
1623 : 1970 : LocaleNode *currNode = monthsNode -> getChildAt(j);
1624 : 1970 : OUString monthID( currNode->getChildAt(0)->getValue());
1625 [ + - ]: 1970 : of.writeParameter("monthID", monthID, i, j);
1626 [ + + ][ + + ]: 1970 : if ( j == 0 && bGregorian && monthID != "jan" )
[ - + ][ - + ]
1627 [ # # ]: 0 : incError( "First month of a year of a Gregorian calendar must be <MonthID>jan</MonthID>");
1628 [ + - ]: 1970 : lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j);
1629 : 1970 : }
1630 : : }
1631 : 172 : ++nChild;
1632 : :
1633 : : // Generate genitive Months of Year
1634 : : // Optional, if not present fall back to month nouns.
1635 [ + + ]: 172 : if ( calNode->getChildAt(nChild)->getName() != "GenitiveMonths" )
1636 : 164 : --nChild;
1637 : 172 : LocaleNode * genitiveMonthsNode = NULL;
1638 [ + - ]: 172 : ref_name = calNode->getChildAt(nChild)->getAttr().getValueByName("ref");
1639 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && i > 0) {
[ + + ]
1640 [ + + ]: 2 : for (j = 0; j < i; j++) {
1641 [ + - ]: 1 : str = getChildAt(j)->getAttr().getValueByName("unoid");
1642 [ + - ]: 1 : if (str.equals(ref_name))
1643 : 1 : genitiveMonthsNode = getChildAt(j)->getChildAt(1);
1644 : : }
1645 : : }
1646 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && genitiveMonthsNode == NULL) {
[ + + ]
1647 [ + - ]: 8 : of.writeParameter("genitiveMonthRef", OUString("ref"), i);
1648 [ + - ]: 8 : of.writeParameter("genitiveMonthRefName", ref_name, i);
1649 : 8 : nbOfGenitiveMonths[i] = 0;
1650 : : } else {
1651 [ + + ]: 164 : if (genitiveMonthsNode == NULL)
1652 : 163 : genitiveMonthsNode = calNode -> getChildAt(nChild);
1653 : 164 : nbOfGenitiveMonths[i] = sal::static_int_cast<sal_Int16>( genitiveMonthsNode->getNumberOfChildren() );
1654 [ - + ][ + + ]: 164 : if (bGregorian && nbOfGenitiveMonths[i] != 12)
1655 [ # # ]: 0 : incErrorInt( "A Gregorian calendar must have 12 genitive months, this one has %d", nbOfGenitiveMonths[i]);
1656 : 164 : elementTag = "genitiveMonth";
1657 [ + + ]: 2134 : for (j = 0; j < nbOfGenitiveMonths[i]; j++) {
1658 : 1970 : LocaleNode *currNode = genitiveMonthsNode -> getChildAt(j);
1659 : 1970 : OUString genitiveMonthID( currNode->getChildAt(0)->getValue());
1660 [ + - ]: 1970 : of.writeParameter("genitiveMonthID", genitiveMonthID, i, j);
1661 [ + + ][ + + ]: 1970 : if ( j == 0 && bGregorian && genitiveMonthID != "jan" )
[ - + ][ - + ]
1662 [ # # ]: 0 : incError( "First genitive month of a year of a Gregorian calendar must be <MonthID>jan</MonthID>");
1663 [ + - ]: 1970 : lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j);
1664 : 1970 : }
1665 : : }
1666 : 172 : ++nChild;
1667 : :
1668 : : // Generate partitive Months of Year
1669 : : // Optional, if not present fall back to genitive months, or nominative
1670 : : // months (nouns) if that isn't present either.
1671 [ + + ]: 172 : if ( calNode->getChildAt(nChild)->getName() != "PartitiveMonths" )
1672 : 168 : --nChild;
1673 : 172 : LocaleNode * partitiveMonthsNode = NULL;
1674 [ + - ]: 172 : ref_name = calNode->getChildAt(nChild)->getAttr().getValueByName("ref");
1675 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && i > 0) {
[ + + ]
1676 [ + + ]: 2 : for (j = 0; j < i; j++) {
1677 [ + - ]: 1 : str = getChildAt(j)->getAttr().getValueByName("unoid");
1678 [ + - ]: 1 : if (str.equals(ref_name))
1679 : 1 : partitiveMonthsNode = getChildAt(j)->getChildAt(1);
1680 : : }
1681 : : }
1682 [ + + ][ + + ]: 172 : if (!ref_name.isEmpty() && partitiveMonthsNode == NULL) {
[ + + ]
1683 [ + - ]: 8 : of.writeParameter("partitiveMonthRef", OUString("ref"), i);
1684 [ + - ]: 8 : of.writeParameter("partitiveMonthRefName", ref_name, i);
1685 : 8 : nbOfPartitiveMonths[i] = 0;
1686 : : } else {
1687 [ + + ]: 164 : if (partitiveMonthsNode == NULL)
1688 : 163 : partitiveMonthsNode = calNode -> getChildAt(nChild);
1689 : 164 : nbOfPartitiveMonths[i] = sal::static_int_cast<sal_Int16>( partitiveMonthsNode->getNumberOfChildren() );
1690 [ - + ][ + + ]: 164 : if (bGregorian && nbOfPartitiveMonths[i] != 12)
1691 [ # # ]: 0 : incErrorInt( "A Gregorian calendar must have 12 partitive months, this one has %d", nbOfPartitiveMonths[i]);
1692 : 164 : elementTag = "partitiveMonth";
1693 [ + + ]: 2134 : for (j = 0; j < nbOfPartitiveMonths[i]; j++) {
1694 : 1970 : LocaleNode *currNode = partitiveMonthsNode -> getChildAt(j);
1695 : 1970 : OUString partitiveMonthID( currNode->getChildAt(0)->getValue());
1696 [ + - ]: 1970 : of.writeParameter("partitiveMonthID", partitiveMonthID, i, j);
1697 [ + + ][ + + ]: 1970 : if ( j == 0 && bGregorian && partitiveMonthID != "jan" )
[ - + ][ - + ]
1698 [ # # ]: 0 : incError( "First partitive month of a year of a Gregorian calendar must be <MonthID>jan</MonthID>");
1699 [ + - ]: 1970 : lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j);
1700 : 1970 : }
1701 : : }
1702 : 172 : ++nChild;
1703 : :
1704 : : // Generate Era name
1705 : 172 : LocaleNode * erasNode = NULL;
1706 [ + - ]: 172 : ref_name = calNode -> getChildAt(nChild) ->getAttr().getValueByName("ref");
1707 [ - + ][ - + ]: 172 : if (!ref_name.isEmpty() && i > 0) {
[ + + ]
1708 [ # # ]: 0 : for (j = 0; j < i; j++) {
1709 [ # # ]: 0 : str = getChildAt(j)->getAttr().getValueByName("unoid");
1710 [ # # ]: 0 : if (str.equals(ref_name))
1711 : 0 : erasNode = getChildAt(j)->getChildAt(2);
1712 : : }
1713 : : }
1714 [ + + ][ + - ]: 172 : if (!ref_name.isEmpty() && erasNode == NULL) {
[ + + ]
1715 [ + - ]: 8 : of.writeParameter("eraRef", OUString("ref"), i);
1716 [ + - ]: 8 : of.writeParameter("eraRefName", ref_name, i);
1717 : 8 : nbOfEras[i] = 0;
1718 : : } else {
1719 [ + - ]: 164 : if (erasNode == NULL)
1720 : 164 : erasNode = calNode -> getChildAt(nChild);
1721 : 164 : nbOfEras[i] = sal::static_int_cast<sal_Int16>( erasNode->getNumberOfChildren() );
1722 [ - + ][ + + ]: 164 : if (bGregorian && nbOfEras[i] != 2)
1723 [ # # ]: 0 : incErrorInt( "A Gregorian calendar must have 2 eras, this one has %d", nbOfEras[i]);
1724 : 164 : elementTag = "era";
1725 [ + + ]: 495 : for (j = 0; j < nbOfEras[i]; j++) {
1726 : 331 : LocaleNode *currNode = erasNode -> getChildAt(j);
1727 : 331 : OUString eraID( currNode->getChildAt(0)->getValue());
1728 [ + - ]: 331 : of.writeParameter("eraID", eraID, i, j);
1729 [ + + ][ + + ]: 331 : if ( j == 0 && bGregorian && eraID != "bc" )
[ - + ][ - + ]
1730 [ # # ]: 0 : incError( "First era of a Gregorian calendar must be <EraID>bc</EraID>");
1731 [ + + ][ + + ]: 331 : if ( j == 1 && bGregorian && eraID != "ad" )
[ - + ][ - + ]
1732 [ # # ]: 0 : incError( "Second era of a Gregorian calendar must be <EraID>ad</EraID>");
1733 [ + - ]: 331 : of.writeAsciiString("\n");
1734 [ + - ]: 331 : of.writeParameter(elementTag, "DefaultAbbrvName",currNode->getChildAt(1)->getValue() ,i, j);
1735 [ + - ]: 331 : of.writeParameter(elementTag, "DefaultFullName",currNode->getChildAt(2)->getValue() , i, j);
1736 : 331 : }
1737 : : }
1738 : 172 : ++nChild;
1739 : :
1740 : 172 : str = calNode->getChildAt(nChild)->getChildAt(0)->getValue();
1741 [ + + ]: 172 : if (nbOfDays[i])
1742 : : {
1743 [ + - ]: 518 : for (j = 0; j < nbOfDays[i]; j++)
1744 : : {
1745 : 355 : LocaleNode *currNode = daysNode->getChildAt(j);
1746 : 355 : OUString dayID( currNode->getChildAt(0)->getValue());
1747 [ + + ]: 355 : if (str == dayID)
1748 : : break; // for
1749 [ + + ]: 355 : }
1750 [ - + ]: 163 : if (j >= nbOfDays[i])
1751 [ # # ]: 0 : incErrorStr( "<StartDayOfWeek> <DayID> must be one of the <DaysOfWeek>, but is", str);
1752 : : }
1753 [ + - ]: 172 : of.writeParameter("startDayOfWeek", str, i);
1754 : 172 : ++nChild;
1755 : :
1756 : 172 : str = calNode ->getChildAt(nChild)-> getValue();
1757 : 172 : sal_Int16 nDays = sal::static_int_cast<sal_Int16>( str.toInt32() );
1758 [ + + ][ - + ]: 172 : if (nDays < 1 || (0 < nbOfDays[i] && nbOfDays[i] < nDays))
[ + - ]
1759 [ # # ]: 0 : incErrorInt( "Bad value of MinimalDaysInFirstWeek: %d, must be 1 <= value <= days_in_week", nDays);
1760 [ + - ]: 172 : of.writeIntParameter("minimalDaysInFirstWeek", i, nDays);
1761 : 172 : }
1762 [ - + ]: 158 : if (!bHasGregorian)
1763 [ # # ]: 0 : fprintf( stderr, "Warning: %s\n", "No Gregorian calendar defined, are you sure?");
1764 : :
1765 [ + - ]: 158 : of.writeAsciiString("static const sal_Int16 calendarsCount = ");
1766 [ + - ]: 158 : of.writeInt(nbOfCalendars);
1767 [ + - ]: 158 : of.writeAsciiString(";\n\n");
1768 : :
1769 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode nbOfDays[] = {");
1770 [ + + ]: 172 : for(i = 0; i < nbOfCalendars - 1; i++) {
1771 [ + - ]: 14 : of.writeInt(nbOfDays[i]);
1772 [ + - ]: 14 : of.writeAsciiString(", ");
1773 : : };
1774 [ + - ]: 158 : of.writeInt(nbOfDays[i]);
1775 [ + - ]: 158 : of.writeAsciiString("};\n");
1776 : :
1777 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode nbOfMonths[] = {");
1778 [ + + ]: 172 : for(i = 0; i < nbOfCalendars - 1; i++) {
1779 [ + - ]: 14 : of.writeInt(nbOfMonths[i]);
1780 [ + - ]: 14 : of.writeAsciiString(", ");
1781 : : };
1782 [ + - ]: 158 : of.writeInt(nbOfMonths[i]);
1783 [ + - ]: 158 : of.writeAsciiString("};\n");
1784 : :
1785 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode nbOfGenitiveMonths[] = {");
1786 [ + + ]: 172 : for(i = 0; i < nbOfCalendars - 1; i++) {
1787 [ + - ]: 14 : of.writeInt(nbOfGenitiveMonths[i]);
1788 [ + - ]: 14 : of.writeAsciiString(", ");
1789 : : };
1790 [ + - ]: 158 : of.writeInt(nbOfGenitiveMonths[i]);
1791 [ + - ]: 158 : of.writeAsciiString("};\n");
1792 : :
1793 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode nbOfPartitiveMonths[] = {");
1794 [ + + ]: 172 : for(i = 0; i < nbOfCalendars - 1; i++) {
1795 [ + - ]: 14 : of.writeInt(nbOfPartitiveMonths[i]);
1796 [ + - ]: 14 : of.writeAsciiString(", ");
1797 : : };
1798 [ + - ]: 158 : of.writeInt(nbOfPartitiveMonths[i]);
1799 [ + - ]: 158 : of.writeAsciiString("};\n");
1800 : :
1801 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode nbOfEras[] = {");
1802 [ + + ]: 172 : for(i = 0; i < nbOfCalendars - 1; i++) {
1803 [ + - ]: 14 : of.writeInt(nbOfEras[i]);
1804 [ + - ]: 14 : of.writeAsciiString(", ");
1805 : : };
1806 [ + - ]: 158 : of.writeInt(nbOfEras[i]);
1807 [ + - ]: 158 : of.writeAsciiString("};\n");
1808 : :
1809 : :
1810 [ + - ]: 158 : of.writeAsciiString("static const sal_Unicode* calendars[] = {\n");
1811 [ + - ]: 158 : of.writeAsciiString("\tnbOfDays,\n");
1812 [ + - ]: 158 : of.writeAsciiString("\tnbOfMonths,\n");
1813 [ + - ]: 158 : of.writeAsciiString("\tnbOfGenitiveMonths,\n");
1814 [ + - ]: 158 : of.writeAsciiString("\tnbOfPartitiveMonths,\n");
1815 [ + - ]: 158 : of.writeAsciiString("\tnbOfEras,\n");
1816 [ + + ]: 330 : for(i = 0; i < nbOfCalendars; i++) {
1817 [ + - ]: 172 : of.writeAsciiString("\tcalendarID");
1818 [ + - ]: 172 : of.writeInt(i);
1819 [ + - ]: 172 : of.writeAsciiString(",\n");
1820 [ + - ]: 172 : of.writeAsciiString("\tdefaultCalendar");
1821 [ + - ]: 172 : of.writeInt(i);
1822 [ + - ]: 172 : of.writeAsciiString(",\n");
1823 [ + - ]: 172 : lcl_writeAbbrFullNarrArrays( of, nbOfDays[i], "day", i, true);
1824 [ + - ]: 172 : lcl_writeAbbrFullNarrArrays( of, nbOfMonths[i], "month", i, true);
1825 [ + - ]: 172 : lcl_writeAbbrFullNarrArrays( of, nbOfGenitiveMonths[i], "genitiveMonth", i, true);
1826 [ + - ]: 172 : lcl_writeAbbrFullNarrArrays( of, nbOfPartitiveMonths[i], "partitiveMonth", i, true);
1827 [ + - ]: 172 : lcl_writeAbbrFullNarrArrays( of, nbOfEras[i], "era", i, false /*noNarrow*/);
1828 [ + - ][ + - ]: 172 : of.writeAsciiString("\tstartDayOfWeek");of.writeInt(i); of.writeAsciiString(",\n");
[ + - ]
1829 [ + - ][ + - ]: 172 : of.writeAsciiString("\tminimalDaysInFirstWeek");of.writeInt(i); of.writeAsciiString(",\n");
[ + - ]
1830 : : }
1831 : :
1832 [ + - ]: 158 : of.writeAsciiString("};\n\n");
1833 [ + - ]: 158 : of.writeFunction("getAllCalendars_", "calendarsCount", "calendars");
1834 : :
1835 [ + - ]: 158 : delete []nbOfDays;
1836 [ + - ]: 158 : delete []nbOfMonths;
1837 [ + - ]: 158 : delete []nbOfGenitiveMonths;
1838 [ + - ]: 158 : delete []nbOfPartitiveMonths;
1839 [ + - ][ + + ]: 197 : delete []nbOfEras;
1840 : : }
1841 : :
1842 : 464 : bool isIso4217( const OUString& rStr )
1843 : : {
1844 : 464 : const sal_Unicode* p = rStr.getStr();
1845 : 464 : return rStr.getLength() == 3
1846 : 464 : && 'A' <= p[0] && p[0] <= 'Z'
1847 : 928 : && 'A' <= p[1] && p[1] <= 'Z'
1848 [ + - ][ + - ]: 464 : && 'A' <= p[2] && p[2] <= 'Z'
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1849 : : ;
1850 : : }
1851 : :
1852 : 197 : void LCCurrencyNode :: generateCode (const OFileWriter &of) const
1853 : : {
1854 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1855 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1856 [ + - ]: 17 : of.writeRefFunction("getAllCurrencies_", useLocale);
1857 : 197 : return;
1858 : : }
1859 : 180 : sal_Int16 nbOfCurrencies = 0;
1860 : 180 : ::rtl::OUString str;
1861 : : sal_Int16 i;
1862 : :
1863 : 180 : bool bTheDefault= false;
1864 : 180 : bool bTheCompatible = false;
1865 [ + + ]: 448 : for ( i = 0; i < getNumberOfChildren(); i++,nbOfCurrencies++) {
1866 : 268 : LocaleNode * currencyNode = getChildAt (i);
1867 [ + - ]: 268 : str = currencyNode->getAttr().getValueByName("default");
1868 [ + - ]: 268 : bool bDefault = of.writeDefaultParameter("Currency", str, nbOfCurrencies);
1869 [ + - ]: 268 : str = currencyNode->getAttr().getValueByName("usedInCompatibleFormatCodes");
1870 [ + - ]: 268 : bool bCompatible = of.writeDefaultParameter("CurrencyUsedInCompatibleFormatCodes", str, nbOfCurrencies);
1871 [ + - ]: 268 : str = currencyNode->getAttr().getValueByName("legacyOnly");
1872 [ + - ]: 268 : bool bLegacy = of.writeDefaultParameter("CurrencyLegacyOnly", str, nbOfCurrencies);
1873 [ + + ][ + - ]: 268 : if (bLegacy && (bDefault || bCompatible))
[ - + ]
1874 [ # # ]: 0 : incError( "Currency: if legacyOnly==true, both 'default' and 'usedInCompatibleFormatCodes' must be false.");
1875 [ + + ]: 268 : if (bDefault)
1876 : : {
1877 [ - + ]: 180 : if (bTheDefault)
1878 [ # # ]: 0 : incError( "Currency: more than one default currency.");
1879 : 180 : bTheDefault = true;
1880 : : }
1881 [ + + ]: 268 : if (bCompatible)
1882 : : {
1883 [ - + ]: 180 : if (bTheCompatible)
1884 [ # # ]: 0 : incError( "Currency: more than one currency flagged as usedInCompatibleFormatCodes.");
1885 : 180 : bTheCompatible = true;
1886 : : }
1887 [ + - ]: 268 : str = currencyNode -> findNode ("CurrencyID") -> getValue();
1888 [ + - ]: 268 : of.writeParameter("currencyID", str, nbOfCurrencies);
1889 : : // CurrencyID MUST be ISO 4217.
1890 [ + + ][ - + ]: 268 : if (!bLegacy && !isIso4217(str))
[ - + ]
1891 [ # # ]: 0 : incError( "CurrencyID is not ISO 4217");
1892 [ + - ]: 268 : str = currencyNode -> findNode ("CurrencySymbol") -> getValue();
1893 [ + - ]: 268 : of.writeParameter("currencySymbol", str, nbOfCurrencies);
1894 : : // Check if this currency really is the one used in number format
1895 : : // codes. In case of ref=... mechanisms it may be that TheCurrency
1896 : : // couldn't had been determined from the current locale (i.e. is
1897 : : // empty), silently assume the referred locale has things right.
1898 [ + + ][ + - ]: 268 : if (bCompatible && !sTheCompatibleCurrency.isEmpty() && sTheCompatibleCurrency != str)
[ - + ][ - + ]
1899 [ # # ]: 0 : incErrorStrStr( "CurrencySymbol \"%s\" flagged as usedInCompatibleFormatCodes doesn't match \"%s\" determined from format codes.", str, sTheCompatibleCurrency);
1900 [ + - ]: 268 : str = currencyNode -> findNode ("BankSymbol") -> getValue();
1901 [ + - ]: 268 : of.writeParameter("bankSymbol", str, nbOfCurrencies);
1902 : : // BankSymbol currently must be ISO 4217. May change later if
1903 : : // application always uses CurrencyID instead of BankSymbol.
1904 [ + + ][ - + ]: 268 : if (!bLegacy && !isIso4217(str))
[ - + ]
1905 [ # # ]: 0 : incError( "BankSymbol is not ISO 4217");
1906 [ + - ]: 268 : str = currencyNode -> findNode ("CurrencyName") -> getValue();
1907 [ + - ]: 268 : of.writeParameter("currencyName", str, nbOfCurrencies);
1908 [ + - ]: 268 : str = currencyNode -> findNode ("DecimalPlaces") -> getValue();
1909 : 268 : sal_Int16 nDecimalPlaces = (sal_Int16)str.toInt32();
1910 [ + - ]: 268 : of.writeIntParameter("currencyDecimalPlaces", nbOfCurrencies, nDecimalPlaces);
1911 [ + - ]: 268 : of.writeAsciiString("\n");
1912 : : };
1913 : :
1914 [ - + ]: 180 : if (!bTheDefault)
1915 [ # # ]: 0 : incError( "Currency: no default currency.");
1916 [ - + ]: 180 : if (!bTheCompatible)
1917 [ # # ]: 0 : incError( "Currency: no currency flagged as usedInCompatibleFormatCodes.");
1918 : :
1919 [ + - ]: 180 : of.writeAsciiString("static const sal_Int16 currencyCount = ");
1920 [ + - ]: 180 : of.writeInt(nbOfCurrencies);
1921 [ + - ]: 180 : of.writeAsciiString(";\n\n");
1922 [ + - ]: 180 : of.writeAsciiString("static const sal_Unicode* currencies[] = {\n");
1923 [ + + ]: 448 : for(i = 0; i < nbOfCurrencies; i++) {
1924 [ + - ]: 268 : of.writeAsciiString("\tcurrencyID");
1925 [ + - ]: 268 : of.writeInt(i);
1926 [ + - ]: 268 : of.writeAsciiString(",\n");
1927 [ + - ]: 268 : of.writeAsciiString("\tcurrencySymbol");
1928 [ + - ]: 268 : of.writeInt(i);
1929 [ + - ]: 268 : of.writeAsciiString(",\n");
1930 [ + - ]: 268 : of.writeAsciiString("\tbankSymbol");
1931 [ + - ]: 268 : of.writeInt(i);
1932 [ + - ]: 268 : of.writeAsciiString(",\n");
1933 [ + - ]: 268 : of.writeAsciiString("\tcurrencyName");
1934 [ + - ]: 268 : of.writeInt(i);
1935 [ + - ]: 268 : of.writeAsciiString(",\n");
1936 [ + - ]: 268 : of.writeAsciiString("\tdefaultCurrency");
1937 [ + - ]: 268 : of.writeInt(i);
1938 [ + - ]: 268 : of.writeAsciiString(",\n");
1939 [ + - ]: 268 : of.writeAsciiString("\tdefaultCurrencyUsedInCompatibleFormatCodes");
1940 [ + - ]: 268 : of.writeInt(i);
1941 [ + - ]: 268 : of.writeAsciiString(",\n");
1942 [ + - ]: 268 : of.writeAsciiString("\tcurrencyDecimalPlaces");
1943 [ + - ]: 268 : of.writeInt(i);
1944 [ + - ]: 268 : of.writeAsciiString(",\n");
1945 [ + - ]: 268 : of.writeAsciiString("\tdefaultCurrencyLegacyOnly");
1946 [ + - ]: 268 : of.writeInt(i);
1947 [ + - ]: 268 : of.writeAsciiString(",\n");
1948 : : }
1949 [ + - ]: 180 : of.writeAsciiString("};\n\n");
1950 [ + - ][ + + ]: 197 : of.writeFunction("getAllCurrencies_", "currencyCount", "currencies");
1951 : : }
1952 : :
1953 : 197 : void LCTransliterationNode::generateCode (const OFileWriter &of) const
1954 : : {
1955 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
1956 [ + + ]: 197 : if (!useLocale.isEmpty()) {
1957 [ + - ]: 129 : of.writeRefFunction("getTransliterations_", useLocale);
1958 : 197 : return;
1959 : : }
1960 : 68 : sal_Int16 nbOfModules = 0;
1961 : 68 : ::rtl::OUString str;
1962 : : sal_Int16 i;
1963 : :
1964 [ + + ]: 453 : for ( i = 0; i < getNumberOfChildren(); i++,nbOfModules++) {
1965 : 385 : LocaleNode * transNode = getChildAt (i);
1966 [ + - ]: 385 : str = transNode->getAttr().getValueByIndex(0);
1967 [ + - ]: 385 : of.writeParameter("Transliteration", str, nbOfModules);
1968 : : }
1969 [ + - ]: 68 : of.writeAsciiString("static const sal_Int16 nbOfTransliterations = ");
1970 [ + - ]: 68 : of.writeInt(nbOfModules);
1971 [ + - ]: 68 : of.writeAsciiString(";\n\n");
1972 : :
1973 [ + - ]: 68 : of.writeAsciiString("\nstatic const sal_Unicode* LCTransliterationsArray[] = {\n");
1974 [ + + ]: 453 : for( i = 0; i < nbOfModules; i++) {
1975 [ + - ]: 385 : of.writeAsciiString("\tTransliteration");
1976 [ + - ]: 385 : of.writeInt(i);
1977 [ + - ]: 385 : of.writeAsciiString(",\n");
1978 : : }
1979 [ + - ]: 68 : of.writeAsciiString("};\n\n");
1980 [ + - ][ + + ]: 197 : of.writeFunction("getTransliterations_", "nbOfTransliterations", "LCTransliterationsArray");
1981 : : }
1982 : :
1983 : : struct NameValuePair {
1984 : : const sal_Char *name;
1985 : : const sal_Char *value;
1986 : : };
1987 : : static NameValuePair ReserveWord[] = {
1988 : : { "trueWord", "true" },
1989 : : { "falseWord", "false" },
1990 : : { "quarter1Word", "1st quarter" },
1991 : : { "quarter2Word", "2nd quarter" },
1992 : : { "quarter3Word", "3rd quarter" },
1993 : : { "quarter4Word", "4th quarter" },
1994 : : { "aboveWord", "above" },
1995 : : { "belowWord", "below" },
1996 : : { "quarter1Abbreviation", "Q1" },
1997 : : { "quarter2Abbreviation", "Q2" },
1998 : : { "quarter3Abbreviation", "Q3" },
1999 : : { "quarter4Abbreviation", "Q4" }
2000 : : };
2001 : :
2002 : 197 : void LCMiscNode::generateCode (const OFileWriter &of) const
2003 : : {
2004 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
2005 [ + + ]: 197 : if (!useLocale.isEmpty()) {
2006 [ + - ]: 66 : of.writeRefFunction("getForbiddenCharacters_", useLocale);
2007 [ + - ]: 66 : of.writeRefFunction("getBreakIteratorRules_", useLocale);
2008 [ + - ]: 66 : of.writeRefFunction("getReservedWords_", useLocale);
2009 : 197 : return;
2010 : : }
2011 [ + - ]: 131 : const LocaleNode * reserveNode = findNode("ReservedWords");
2012 [ - + ]: 131 : if (!reserveNode)
2013 [ # # ]: 0 : incError( "No ReservedWords element."); // should not happen if validated..
2014 [ + - ]: 131 : const LocaleNode * forbidNode = findNode("ForbiddenCharacters");
2015 [ + - ]: 131 : const LocaleNode * breakNode = findNode("BreakIteratorRules");
2016 : :
2017 : 131 : bool bEnglishLocale = (strncmp( of.getLocale(), "en_", 3) == 0);
2018 : :
2019 : 131 : sal_Int16 nbOfWords = 0;
2020 : 131 : ::rtl::OUString str;
2021 : : sal_Int16 i;
2022 : :
2023 [ + + ]: 1703 : for ( i = 0; i < sal_Int16(SAL_N_ELEMENTS(ReserveWord)); i++,nbOfWords++) {
2024 : : const LocaleNode * curNode = (reserveNode ? reserveNode->findNode(
2025 [ + - ][ + - ]: 1572 : ReserveWord[i].name) : 0);
2026 [ - + ]: 1572 : if (!curNode)
2027 : : fprintf( stderr,
2028 : : "Warning: No %s in ReservedWords, using en_US default: \"%s\".\n",
2029 [ # # ]: 0 : ReserveWord[i].name, ReserveWord[i].value);
2030 [ + - ]: 1572 : str = curNode ? curNode -> getValue() : OUString::createFromAscii(ReserveWord[i].value);
2031 [ - + ]: 1572 : if (str.isEmpty())
2032 : : {
2033 : 0 : ++nError;
2034 [ # # ]: 0 : fprintf( stderr, "Error: No content for ReservedWords %s.\n", ReserveWord[i].name);
2035 : : }
2036 [ + - ]: 1572 : of.writeParameter("ReservedWord", str, nbOfWords);
2037 : : // "true", ..., "below" trigger untranslated warning.
2038 [ + + ][ + - ]: 2604 : if (!bEnglishLocale && curNode && (0 <= i && i <= 7) &&
[ + - ]
[ + + + + ]
[ + + ]
2039 : 1032 : str.equalsIgnoreAsciiCaseAscii( ReserveWord[i].value))
2040 : : {
2041 : : fprintf( stderr,
2042 : : "Warning: ReservedWord %s seems to be untranslated \"%s\".\n",
2043 [ + - ]: 35 : ReserveWord[i].name, ReserveWord[i].value);
2044 : : }
2045 : : }
2046 [ + - ]: 131 : of.writeAsciiString("static const sal_Int16 nbOfReservedWords = ");
2047 [ + - ]: 131 : of.writeInt(nbOfWords);
2048 [ + - ]: 131 : of.writeAsciiString(";\n\n");
2049 [ + - ]: 131 : of.writeAsciiString("\nstatic const sal_Unicode* LCReservedWordsArray[] = {\n");
2050 [ + + ]: 1703 : for( i = 0; i < nbOfWords; i++) {
2051 [ + - ]: 1572 : of.writeAsciiString("\tReservedWord");
2052 [ + - ]: 1572 : of.writeInt(i);
2053 [ + - ]: 1572 : of.writeAsciiString(",\n");
2054 : : }
2055 [ + - ]: 131 : of.writeAsciiString("};\n\n");
2056 [ + - ]: 131 : of.writeFunction("getReservedWords_", "nbOfReservedWords", "LCReservedWordsArray");
2057 : :
2058 [ + + ]: 131 : if (forbidNode) {
2059 [ + - ]: 4 : of.writeParameter( "forbiddenBegin", forbidNode -> getChildAt(0)->getValue());
2060 [ + - ]: 4 : of.writeParameter( "forbiddenEnd", forbidNode -> getChildAt(1)->getValue());
2061 [ + - ]: 4 : of.writeParameter( "hangingChars", forbidNode -> getChildAt(2)->getValue());
2062 : : } else {
2063 [ + - ]: 127 : of.writeParameter( "forbiddenBegin", ::rtl::OUString());
2064 [ + - ]: 127 : of.writeParameter( "forbiddenEnd", ::rtl::OUString());
2065 [ + - ]: 127 : of.writeParameter( "hangingChars", ::rtl::OUString());
2066 : : }
2067 [ + - ]: 131 : of.writeAsciiString("\nstatic const sal_Unicode* LCForbiddenCharactersArray[] = {\n");
2068 [ + - ]: 131 : of.writeAsciiString("\tforbiddenBegin,\n");
2069 [ + - ]: 131 : of.writeAsciiString("\tforbiddenEnd,\n");
2070 [ + - ]: 131 : of.writeAsciiString("\thangingChars\n");
2071 [ + - ]: 131 : of.writeAsciiString("};\n\n");
2072 [ + - ]: 131 : of.writeFunction("getForbiddenCharacters_", "3", "LCForbiddenCharactersArray");
2073 : :
2074 [ + + ]: 131 : if (breakNode) {
2075 [ + - ]: 13 : of.writeParameter( "EditMode", breakNode -> getChildAt(0)->getValue());
2076 [ + - ]: 13 : of.writeParameter( "DictionaryMode", breakNode -> getChildAt(1)->getValue());
2077 [ + - ]: 13 : of.writeParameter( "WordCountMode", breakNode -> getChildAt(2)->getValue());
2078 [ + - ]: 13 : of.writeParameter( "CharacterMode", breakNode -> getChildAt(3)->getValue());
2079 [ + - ]: 13 : of.writeParameter( "LineMode", breakNode -> getChildAt(4)->getValue());
2080 : : } else {
2081 [ + - ]: 118 : of.writeParameter( "EditMode", ::rtl::OUString());
2082 [ + - ]: 118 : of.writeParameter( "DictionaryMode", ::rtl::OUString());
2083 [ + - ]: 118 : of.writeParameter( "WordCountMode", ::rtl::OUString());
2084 [ + - ]: 118 : of.writeParameter( "CharacterMode", ::rtl::OUString());
2085 [ + - ]: 118 : of.writeParameter( "LineMode", ::rtl::OUString());
2086 : : }
2087 [ + - ]: 131 : of.writeAsciiString("\nstatic const sal_Unicode* LCBreakIteratorRulesArray[] = {\n");
2088 [ + - ]: 131 : of.writeAsciiString("\tEditMode,\n");
2089 [ + - ]: 131 : of.writeAsciiString("\tDictionaryMode,\n");
2090 [ + - ]: 131 : of.writeAsciiString("\tWordCountMode,\n");
2091 [ + - ]: 131 : of.writeAsciiString("\tCharacterMode,\n");
2092 [ + - ]: 131 : of.writeAsciiString("\tLineMode\n");
2093 [ + - ]: 131 : of.writeAsciiString("};\n\n");
2094 [ + - ][ + + ]: 197 : of.writeFunction("getBreakIteratorRules_", "5", "LCBreakIteratorRulesArray");
2095 : :
2096 : : }
2097 : :
2098 : 197 : void LCNumberingLevelNode::generateCode (const OFileWriter &of) const
2099 : : {
2100 [ + - ]: 197 : of.writeAsciiString("// ---> ContinuousNumbering\n");
2101 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
2102 [ + + ]: 197 : if (!useLocale.isEmpty()) {
2103 [ + - ]: 130 : of.writeRefFunction2("getContinuousNumberingLevels_", useLocale);
2104 : 197 : return;
2105 : : }
2106 : :
2107 : : // hard code number of attributes per style.
2108 : 67 : const int nAttributes = 5;
2109 : 67 : const char* attr[ nAttributes ] = { "Prefix", "NumType", "Suffix", "Transliteration", "NatNum" };
2110 : :
2111 : : // record each attribute of each style in a static C++ variable.
2112 : : // determine number of styles on the fly.
2113 : 67 : sal_Int32 nStyles = getNumberOfChildren();
2114 : : sal_Int32 i;
2115 : :
2116 [ + + ]: 613 : for( i = 0; i < nStyles; ++i )
2117 : : {
2118 : 546 : const Attr &q = getChildAt( i )->getAttr();
2119 [ + + ]: 3276 : for( sal_Int32 j=0; j<nAttributes; ++j )
2120 : : {
2121 : 2730 : const char* name = attr[j];
2122 [ + - ]: 2730 : OUString value = q.getValueByName( name );
2123 [ + - ]: 2730 : of.writeParameter("continuous", name, value, sal::static_int_cast<sal_Int16>(i) );
2124 : 2730 : }
2125 : : }
2126 : :
2127 : : // record number of styles and attributes.
2128 [ + - ]: 67 : of.writeAsciiString("static const sal_Int16 continuousNbOfStyles = ");
2129 [ + - ]: 67 : of.writeInt( sal::static_int_cast<sal_Int16>( nStyles ) );
2130 [ + - ]: 67 : of.writeAsciiString(";\n\n");
2131 [ + - ]: 67 : of.writeAsciiString("static const sal_Int16 continuousNbOfAttributesPerStyle = ");
2132 [ + - ]: 67 : of.writeInt( nAttributes );
2133 [ + - ]: 67 : of.writeAsciiString(";\n\n");
2134 : :
2135 : : // generate code. (intermediate arrays)
2136 [ + + ]: 613 : for( i=0; i<nStyles; i++ )
2137 : : {
2138 [ + - ]: 546 : of.writeAsciiString("\nstatic const sal_Unicode* continuousStyle" );
2139 [ + - ]: 546 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2140 [ + - ]: 546 : of.writeAsciiString("[] = {\n");
2141 [ + + ]: 3276 : for( sal_Int32 j=0; j<nAttributes; j++)
2142 : : {
2143 [ + - ]: 2730 : of.writeAsciiString("\t");
2144 [ + - ]: 2730 : of.writeAsciiString( "continuous" );
2145 [ + - ]: 2730 : of.writeAsciiString( attr[j] );
2146 [ + - ]: 2730 : of.writeInt(sal::static_int_cast<sal_Int16>(i));
2147 [ + - ]: 2730 : of.writeAsciiString(",\n");
2148 : : }
2149 [ + - ]: 546 : of.writeAsciiString("\t0\n};\n\n");
2150 : : }
2151 : :
2152 : : // generate code. (top-level array)
2153 [ + - ]: 67 : of.writeAsciiString("\n");
2154 [ + - ]: 67 : of.writeAsciiString("static const sal_Unicode** LCContinuousNumberingLevelsArray[] = {\n" );
2155 [ + + ]: 613 : for( i=0; i<nStyles; i++ )
2156 : : {
2157 [ + - ]: 546 : of.writeAsciiString( "\t" );
2158 [ + - ]: 546 : of.writeAsciiString( "continuousStyle" );
2159 [ + - ]: 546 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2160 [ + - ]: 546 : of.writeAsciiString( ",\n");
2161 : : }
2162 [ + - ]: 67 : of.writeAsciiString("\t0\n};\n\n");
2163 : : of.writeFunction2("getContinuousNumberingLevels_", "continuousNbOfStyles",
2164 [ + - ][ + + ]: 197 : "continuousNbOfAttributesPerStyle", "LCContinuousNumberingLevelsArray");
2165 : : }
2166 : :
2167 : :
2168 : 197 : void LCOutlineNumberingLevelNode::generateCode (const OFileWriter &of) const
2169 : : {
2170 [ + - ]: 197 : of.writeAsciiString("// ---> OutlineNumbering\n");
2171 [ + - ]: 197 : ::rtl::OUString useLocale = getAttr().getValueByName("ref");
2172 [ + + ]: 197 : if (!useLocale.isEmpty()) {
2173 [ + - ]: 170 : of.writeRefFunction3("getOutlineNumberingLevels_", useLocale);
2174 : 197 : return;
2175 : : }
2176 : :
2177 : : // hardcode number of attributes per level
2178 : 27 : const int nAttributes = 11;
2179 : : const char* attr[ nAttributes ] =
2180 : : {
2181 : : "Prefix",
2182 : : "NumType",
2183 : : "Suffix",
2184 : : "BulletChar",
2185 : : "BulletFontName",
2186 : : "ParentNumbering",
2187 : : "LeftMargin",
2188 : : "SymbolTextDistance",
2189 : : "FirstLineOffset",
2190 : : "Transliteration",
2191 : : "NatNum",
2192 : 27 : };
2193 : :
2194 : : // record each attribute of each level of each style in a static C++ variable.
2195 : : // determine number of styles and number of levels per style on the fly.
2196 : 27 : sal_Int32 nStyles = getNumberOfChildren();
2197 [ + - ]: 27 : vector<sal_Int32> nLevels; // may be different for each style?
2198 [ + + ]: 251 : for( sal_Int32 i = 0; i < nStyles; i++ )
2199 : : {
2200 : 224 : LocaleNode* p = getChildAt( i );
2201 [ + - ]: 224 : nLevels.push_back( p->getNumberOfChildren() );
2202 [ + - ][ + + ]: 1344 : for( sal_Int32 j=0; j<nLevels.back(); j++ )
2203 : : {
2204 : 1120 : const Attr& q = p->getChildAt( j )->getAttr();
2205 [ + + ]: 13440 : for( sal_Int32 k=0; k<nAttributes; ++k )
2206 : : {
2207 : 12320 : const char* name = attr[k];
2208 [ + - ]: 12320 : OUString value = q.getValueByName( name );
2209 : : of.writeParameter("outline", name, value,
2210 : 12320 : sal::static_int_cast<sal_Int16>(i),
2211 [ + - ]: 24640 : sal::static_int_cast<sal_Int16>(j) );
2212 : 12320 : }
2213 : : }
2214 : : }
2215 : :
2216 : : // verify that each style has the same number of levels.
2217 [ + + ]: 251 : for( size_t i=0; i<nLevels.size(); i++ )
2218 : : {
2219 [ + - ][ + - ]: 224 : if( nLevels[0] != nLevels[i] )
[ - + ]
2220 : : {
2221 [ # # ]: 0 : incError( "Numbering levels don't match.");
2222 : : }
2223 : : }
2224 : :
2225 : : // record number of attributes, levels, and styles.
2226 [ + - ]: 27 : of.writeAsciiString("static const sal_Int16 outlineNbOfStyles = ");
2227 [ + - ]: 27 : of.writeInt( sal::static_int_cast<sal_Int16>( nStyles ) );
2228 [ + - ]: 27 : of.writeAsciiString(";\n\n");
2229 [ + - ]: 27 : of.writeAsciiString("static const sal_Int16 outlineNbOfLevelsPerStyle = ");
2230 [ + - ][ + - ]: 27 : of.writeInt( sal::static_int_cast<sal_Int16>( nLevels.back() ) );
2231 [ + - ]: 27 : of.writeAsciiString(";\n\n");
2232 [ + - ]: 27 : of.writeAsciiString("static const sal_Int16 outlineNbOfAttributesPerLevel = ");
2233 [ + - ]: 27 : of.writeInt( nAttributes );
2234 [ + - ]: 27 : of.writeAsciiString(";\n\n");
2235 : :
2236 : : // too complicated for now...
2237 : : // of.writeAsciiString("static const sal_Int16 nbOfOutlineNumberingLevels[] = { ");
2238 : : // for( sal_Int32 j=0; j<nStyles; j++ )
2239 : : // {
2240 : : // of.writeInt( nLevels[j] );
2241 : : // of.writeAsciiString(", ");
2242 : : // }
2243 : : // of.writeAsciiString("};\n\n");
2244 : :
2245 : :
2246 [ + + ]: 251 : for( sal_Int32 i=0; i<nStyles; i++ )
2247 : : {
2248 [ + - ][ + + ]: 1344 : for( sal_Int32 j=0; j<nLevels.back(); j++ )
2249 : : {
2250 [ + - ]: 1120 : of.writeAsciiString("static const sal_Unicode* outline");
2251 [ + - ]: 1120 : of.writeAsciiString("Style");
2252 [ + - ]: 1120 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2253 [ + - ]: 1120 : of.writeAsciiString("Level");
2254 [ + - ]: 1120 : of.writeInt( sal::static_int_cast<sal_Int16>(j) );
2255 [ + - ]: 1120 : of.writeAsciiString("[] = { ");
2256 : :
2257 [ + + ]: 13440 : for( sal_Int32 k=0; k<nAttributes; k++ )
2258 : : {
2259 [ + - ]: 12320 : of.writeAsciiString( "outline" );
2260 [ + - ]: 12320 : of.writeAsciiString( attr[k] );
2261 [ + - ]: 12320 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2262 [ + - ]: 12320 : of.writeInt( sal::static_int_cast<sal_Int16>(j) );
2263 [ + - ]: 12320 : of.writeAsciiString(", ");
2264 : : }
2265 [ + - ]: 1120 : of.writeAsciiString("NULL };\n");
2266 : : }
2267 : : }
2268 : :
2269 [ + - ]: 27 : of.writeAsciiString("\n");
2270 : :
2271 : :
2272 [ + + ]: 251 : for( sal_Int32 i=0; i<nStyles; i++ )
2273 : : {
2274 [ + - ]: 224 : of.writeAsciiString("static const sal_Unicode** outline");
2275 [ + - ]: 224 : of.writeAsciiString( "Style" );
2276 [ + - ]: 224 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2277 [ + - ]: 224 : of.writeAsciiString("[] = { ");
2278 : :
2279 [ + - ][ + + ]: 1344 : for( sal_Int32 j=0; j<nLevels.back(); j++ )
2280 : : {
2281 [ + - ]: 1120 : of.writeAsciiString("outlineStyle");
2282 [ + - ]: 1120 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2283 [ + - ]: 1120 : of.writeAsciiString("Level");
2284 [ + - ]: 1120 : of.writeInt( sal::static_int_cast<sal_Int16>(j) );
2285 [ + - ]: 1120 : of.writeAsciiString(", ");
2286 : : }
2287 [ + - ]: 224 : of.writeAsciiString("NULL };\n");
2288 : : }
2289 [ + - ]: 27 : of.writeAsciiString("\n");
2290 : :
2291 [ + - ]: 27 : of.writeAsciiString("static const sal_Unicode*** LCOutlineNumberingLevelsArray[] = {\n" );
2292 [ + + ]: 251 : for( sal_Int32 i=0; i<nStyles; i++ )
2293 : : {
2294 [ + - ]: 224 : of.writeAsciiString( "\t" );
2295 [ + - ]: 224 : of.writeAsciiString( "outlineStyle" );
2296 [ + - ]: 224 : of.writeInt( sal::static_int_cast<sal_Int16>(i) );
2297 [ + - ]: 224 : of.writeAsciiString(",\n");
2298 : : }
2299 [ + - ]: 27 : of.writeAsciiString("\tNULL\n};\n\n");
2300 : : of.writeFunction3("getOutlineNumberingLevels_", "outlineNbOfStyles", "outlineNbOfLevelsPerStyle",
2301 [ + - ][ + + ]: 197 : "outlineNbOfAttributesPerLevel", "LCOutlineNumberingLevelsArray");
2302 : : }
2303 : :
2304 [ + - ]: 43100 : Attr::Attr (const Reference< XAttributeList > & attr) {
2305 [ + - ][ + - ]: 43100 : sal_Int16 len = attr->getLength();
2306 [ + - ]: 43100 : name.realloc (len);
2307 [ + - ]: 43100 : value.realloc (len);
2308 [ + + ]: 93368 : for (sal_Int16 i =0; i< len;i++) {
2309 [ + - ][ + - ]: 50268 : name[i] = attr->getNameByIndex(i);
[ + - ]
2310 [ + - ][ + - ]: 50268 : value[i] = attr -> getValueByIndex(i);
[ + - ]
2311 : : }
2312 : 43100 : }
2313 : :
2314 : 55886 : const OUString& Attr::getValueByName (const sal_Char *str) const {
2315 [ + + ][ + - ]: 55886 : static OUString empty;
2316 : 55886 : sal_Int32 len = name.getLength();
2317 [ + + ]: 193358 : for (sal_Int32 i = 0;i<len;i++)
2318 [ + + ]: 186997 : if (name[i].equalsAscii(str))
2319 : 49525 : return value[i];
2320 : 55886 : return empty;
2321 : : }
2322 : :
2323 : 0 : sal_Int32 Attr::getLength() const{
2324 : 0 : return name.getLength();
2325 : : }
2326 : :
2327 : 0 : const OUString& Attr::getTypeByIndex (sal_Int32 idx) const {
2328 : 0 : return name[idx];
2329 : : }
2330 : :
2331 : 385 : const OUString& Attr::getValueByIndex (sal_Int32 idx) const
2332 : : {
2333 : 385 : return value[idx];
2334 [ + - ][ + - ]: 591 : }
2335 : :
2336 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|