merge the formfield patch from ooo-build
[ooovba.git] / i18npool / source / localedata / LocaleNode.cxx
blobad8728dc37879f59d88f2d0ebdc97bfbb73d6156
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: LocaleNode.cxx,v $
10 * $Revision: 1.29.24.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_i18npool.hxx"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <iostream>
37 #include <set>
39 #include <rtl/ustrbuf.hxx>
41 #include "LocaleNode.hxx"
42 #include <com/sun/star/i18n/NumberFormatIndex.hpp>
44 // NOTE: MUST match the Locale versionDTD attribute defined in data/locale.dtd
45 #define LOCALE_VERSION_DTD "2.0.3"
47 typedef ::std::set< ::rtl::OUString > NameSet;
48 typedef ::std::set< sal_Int16 > ValueSet;
50 namespace cssi = ::com::sun::star::i18n;
52 LocaleNode::LocaleNode (const OUString& name, const Reference< XAttributeList > & attr)
53 : aName(name)
54 , xAttribs(new Attr(attr))
55 , parent(0)
56 , children(0)
57 , nChildren(0)
58 , childArrSize(0)
59 , nError(0)
63 int LocaleNode::getError() const
65 int err = nError;
66 for (sal_Int32 i=0;i<nChildren;i++)
67 err += children[i]->getError();
68 return err;
71 void LocaleNode::print () const {
72 printf ("<");
73 ::rtl::OUString str (aName);
74 for(sal_Int32 i = 0; i < str.getLength(); i++)
75 printf( "%c", str[i]);
76 printf (">\n");
79 void LocaleNode::printR () const {
80 print();
81 for (sal_Int32 i=0;i<nChildren;i++)
82 children[i]->printR();
83 printf ("\t");
84 print();
87 void LocaleNode::addChild ( LocaleNode * node) {
88 if (childArrSize <= nChildren) {
89 LocaleNode ** arrN = (LocaleNode **)malloc( sizeof (LocaleNode *)*(childArrSize+10) ) ;
90 for (sal_Int32 i = 0; i<childArrSize ; i++)
91 arrN[i] = children[i];
92 if ( childArrSize > 0 )
93 free(children);
94 childArrSize += 10;
95 children = arrN;
97 children[nChildren++] = node;
98 node->setParent (this);
101 void LocaleNode::setParent ( LocaleNode * node) {
102 parent = node;
105 const LocaleNode* LocaleNode::getRoot() const
107 const LocaleNode* pRoot = 0;
108 const LocaleNode* pParent = this;
109 while ( (pParent = pParent->getParent()) != 0 )
110 pRoot = pParent;
111 return pRoot;
114 const LocaleNode * LocaleNode::findNode ( const sal_Char *name) const {
115 if (aName.equalsAscii(name))
116 return this;
117 for (sal_Int32 i = 0; i< nChildren; i++) {
118 const LocaleNode *n=children[i]->findNode(name);
119 if (n)
120 return n;
122 return 0;
125 LocaleNode::~LocaleNode() {
126 for (sal_Int32 i=0; i<nChildren;i++)
127 delete (children[i]);
130 LocaleNode* LocaleNode::createNode (const OUString& name, const Reference< XAttributeList > & attr)
132 if (name.equalsAscii("LC_INFO"))
133 return new LCInfoNode (name,attr);
134 if (name.equalsAscii("LC_CTYPE"))
135 return new LCCTYPENode (name,attr);
136 if (name.equalsAscii("LC_FORMAT"))
137 return new LCFormatNode (name,attr);
138 if (name.equalsAscii("LC_FORMAT_1"))
139 return new LCFormatNode (name,attr);
140 if (name.equalsAscii("LC_CALENDAR"))
141 return new LCCalendarNode (name,attr);
142 if (name.equalsAscii("LC_CURRENCY"))
143 return new LCCurrencyNode (name,attr);
144 if (name.equalsAscii("LC_TRANSLITERATION"))
145 return new LCTransliterationNode (name,attr);
146 if (name.equalsAscii("LC_COLLATION"))
147 return new LCCollationNode (name,attr);
148 if (name.equalsAscii("LC_INDEX"))
149 return new LCIndexNode (name,attr);
150 if (name.equalsAscii("LC_SEARCH"))
151 return new LCSearchNode (name,attr);
152 if (name.equalsAscii("LC_MISC"))
153 return new LCMiscNode (name,attr);
154 if (name.equalsAscii("LC_NumberingLevel"))
155 return new LCNumberingLevelNode (name, attr);
156 if (name.equalsAscii("LC_OutLineNumberingLevel"))
157 return new LCOutlineNumberingLevelNode (name, attr);
159 return new LocaleNode(name,attr);
163 // printf(" name: '%s'\n", p->getName().pData->buffer );
164 // printf("value: '%s'\n", p->getValue().pData->buffer );
166 void print_OUString( const OUString& s )
168 printf( "%s", OUStringToOString( s, RTL_TEXTENCODING_UTF8).getStr());
171 bool is_empty( const OUString& s )
173 return (s.getLength()==0) || (s.getLength()==1 && s[0]=='\n');
176 void print_indent( int depth )
178 for( int i=0; i<depth; i++ ) printf(" ");
181 void print_color( int color )
183 printf("\033[%dm", color);
186 void print_node( const LocaleNode* p, int depth=0 )
188 if( !p ) return;
190 print_indent( depth );
191 printf("<");
192 print_color(36);
193 print_OUString( p->getName() );
194 print_color(0);
195 const Attr* q = p->getAttr();
196 if( q )
198 for( sal_Int32 j=0; j<q->getLength(); j++ )
200 printf(" ");
201 print_color(33);
202 print_OUString( q->getTypeByIndex(j) );
203 print_color(0);
204 printf("=");
205 print_color(31);
206 printf("'");
207 print_OUString( q->getValueByIndex(j) );
208 printf("'");
209 print_color(0);
212 printf(">");
213 printf("\n");
214 if( !is_empty( p->getValue() ) )
216 print_indent( depth+1 );
217 printf("value: ");
218 print_color(31);
219 printf("'");
220 print_OUString( p->getValue() );
221 printf("'");
222 print_color(0);
223 printf("\n");
225 for( sal_Int32 i=0; i<p->getNumberOfChildren(); i++ )
227 print_node( p->getChildAt(i), depth+1 );
229 print_indent( depth );
230 printf("</");
231 print_OUString( p->getName() );
232 printf(">");
233 printf("\n");
236 void LocaleNode :: generateCode (const OFileWriter &of) const
238 ::rtl::OUString aDTD = getAttr()->getValueByName("versionDTD");
239 if (!aDTD.equalsAscii( LOCALE_VERSION_DTD))
241 ++nError;
242 fprintf( stderr, "Error: Locale versionDTD is not %s, see comment in locale.dtd\n", LOCALE_VERSION_DTD);
244 for (sal_Int32 i=0; i<nChildren;i++)
245 children[i]->generateCode (of);
246 // print_node( this );
250 ::rtl::OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of,
251 const char* pParameterName, const LocaleNode* pNode,
252 sal_Int32 nMinLen, sal_Int32 nMaxLen ) const
254 OUString aVal;
255 if (pNode)
256 aVal = pNode->getValue();
257 else
259 ++nError;
260 fprintf( stderr, "Error: node NULL pointer for parameter %s.\n",
261 pParameterName);
263 // write empty data if error
264 of.writeParameter( pParameterName, aVal);
265 sal_Int32 nLen = aVal.getLength();
266 if (nLen < nMinLen)
268 ++nError;
269 fprintf( stderr, "Error: less than %ld character%s (%ld) in %s '%s'.\n",
270 sal::static_int_cast< long >(nMinLen), (nMinLen > 1 ? "s" : ""),
271 sal::static_int_cast< long >(nLen),
272 (pNode ? OUStringToOString( pNode->getName(), RTL_TEXTENCODING_UTF8).getStr() : ""),
273 OUStringToOString( aVal, RTL_TEXTENCODING_UTF8).getStr());
275 else if (nLen > nMaxLen && nMaxLen >= 0)
276 fprintf( stderr,
277 "Warning: more than %ld character%s (%ld) in %s %s not supported by application.\n",
278 sal::static_int_cast< long >(nMaxLen), (nMaxLen > 1 ? "s" : ""),
279 sal::static_int_cast< long >(nLen),
280 (pNode ? OUStringToOString( pNode->getName(), RTL_TEXTENCODING_UTF8).getStr() : ""),
281 OUStringToOString( aVal, RTL_TEXTENCODING_UTF8).getStr());
282 return aVal;
286 ::rtl::OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of,
287 const char* pNodeName, const char* pParameterName,
288 sal_Int32 nMinLen, sal_Int32 nMaxLen ) const
290 OUString aVal;
291 const LocaleNode * pNode = findNode( pNodeName);
292 if (pNode)
293 aVal = writeParameterCheckLen( of, pParameterName, pNode, nMinLen, nMaxLen);
294 else
296 ++nError;
297 fprintf( stderr, "Error: node %s not found.\n", pNodeName);
298 // write empty data if error
299 of.writeParameter( pParameterName, aVal);
301 return aVal;
304 void LocaleNode::incError( const char* pStr ) const
306 ++nError;
307 fprintf( stderr, "Error: %s\n", pStr);
310 void LocaleNode::incError( const ::rtl::OUString& rStr ) const
312 incError( OUStringToOString( rStr, RTL_TEXTENCODING_UTF8).getStr());
315 char* LocaleNode::prepareErrorFormat( const char* pFormat, const char* pDefaultConversion ) const
317 static char buf[2048];
318 strcpy( buf, "Error: ");
319 strncat( buf, pFormat, 2000);
320 char* p = buf;
321 while (((p = strchr( p, '%')) != 0) && p[1] == '%')
322 p += 2;
323 if (!p)
324 strcat( buf, pDefaultConversion);
325 strcat( buf, "\n");
326 return buf;
329 void LocaleNode::incErrorInt( const char* pStr, int nVal ) const
331 ++nError;
332 fprintf( stderr, prepareErrorFormat( pStr, ": %d"), nVal);
335 void LocaleNode::incErrorStr( const char* pStr, const ::rtl::OUString& rVal ) const
337 ++nError;
338 fprintf( stderr, prepareErrorFormat( pStr, ": %s"), OUStringToOString(
339 rVal, RTL_TEXTENCODING_UTF8).getStr());
342 void LCInfoNode::generateCode (const OFileWriter &of) const
345 const LocaleNode * languageNode = findNode("Language");
346 const LocaleNode * countryNode = findNode("Country");
347 const LocaleNode * variantNode = findNode("Variant");
349 if (languageNode)
351 writeParameterCheckLen( of, "langID", languageNode->getChildAt(0), 2, -1);
352 of.writeParameter("langDefaultName", languageNode->getChildAt(1)->getValue());
354 else
355 incError( "No Language node.");
356 if (countryNode)
358 of.writeParameter("countryID", countryNode->getChildAt(0)->getValue());
359 of.writeParameter("countryDefaultName", countryNode->getChildAt(1)->getValue());
361 else
362 incError( "No Country node.");
363 if (variantNode)
365 of.writeParameter("Variant", variantNode->getValue());
366 fprintf( stderr, "Warning: %s\n",
367 "Variants are not supported by application.");
369 else
370 of.writeParameter("Variant", ::rtl::OUString());
371 of.writeAsciiString("\nstatic const sal_Unicode* LCInfoArray[] = {\n");
372 of.writeAsciiString("\tlangID,\n");
373 of.writeAsciiString("\tlangDefaultName,\n");
374 of.writeAsciiString("\tcountryID,\n");
375 of.writeAsciiString("\tcountryDefaultName,\n");
376 of.writeAsciiString("\tVariant\n");
377 of.writeAsciiString("};\n\n");
378 of.writeFunction("getLCInfo_", "0", "LCInfoArray");
381 void LCCTYPENode::generateCode (const OFileWriter &of) const
383 const LocaleNode * sepNode = 0;
384 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
385 if (useLocale.getLength() > 0) {
386 of.writeRefFunction("getLocaleItem_", useLocale);
387 return;
389 ::rtl::OUString str = getAttr() -> getValueByName("unoid");
390 of.writeAsciiString("\n\n");
391 of.writeParameter("LC_CTYPE_Unoid", str);;
393 OUString aDateSep =
394 writeParameterCheckLen( of, "DateSeparator", "dateSeparator", 1, 1);
395 OUString aThoSep =
396 writeParameterCheckLen( of, "ThousandSeparator", "thousandSeparator", 1, 1);
397 OUString aDecSep =
398 writeParameterCheckLen( of, "DecimalSeparator", "decimalSeparator", 1, 1);
399 OUString aTimeSep =
400 writeParameterCheckLen( of, "TimeSeparator", "timeSeparator", 1, 1);
401 OUString aTime100Sep =
402 writeParameterCheckLen( of, "Time100SecSeparator", "time100SecSeparator", 1, 1);
403 OUString aListSep =
404 writeParameterCheckLen( of, "ListSeparator", "listSeparator", 1, 1);
406 OUString aLDS;
408 sepNode = findNode("LongDateDayOfWeekSeparator");
409 aLDS = sepNode->getValue();
410 of.writeParameter("LongDateDayOfWeekSeparator", aLDS);
411 if (aLDS.getLength() == 1 && aLDS.getStr()[0] == ',')
412 fprintf( stderr, "Warning: %s\n",
413 "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\".");
415 sepNode = findNode("LongDateDaySeparator");
416 aLDS = sepNode->getValue();
417 of.writeParameter("LongDateDaySeparator", aLDS);
418 if (aLDS.getLength() == 1 && (aLDS.getStr()[0] == ',' || aLDS.getStr()[0] == '.'))
419 fprintf( stderr, "Warning: %s\n",
420 "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\".");
422 sepNode = findNode("LongDateMonthSeparator");
423 aLDS = sepNode->getValue();
424 of.writeParameter("LongDateMonthSeparator", aLDS);
425 if (aLDS.getLength() == 0)
426 fprintf( stderr, "Warning: %s\n",
427 "LongDateMonthSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, May9, 2007\".");
429 sepNode = findNode("LongDateYearSeparator");
430 aLDS = sepNode->getValue();
431 of.writeParameter("LongDateYearSeparator", aLDS);
432 if (aLDS.getLength() == 0)
433 fprintf( stderr, "Warning: %s\n",
434 "LongDateYearSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, 2007May 9\".");
437 int nSavErr = nError;
438 int nWarn = 0;
439 if (aDateSep == aTimeSep)
440 incError( "DateSeparator equals TimeSeparator.");
441 if (aDecSep == aThoSep)
442 incError( "DecimalSeparator equals ThousandSeparator.");
443 if (aThoSep.equalsAscii( " "))
444 incError( "ThousandSeparator is an ' ' ordinary space, this should be a non-breaking space U+00A0 instead.");
445 if (aListSep == aDecSep)
446 fprintf( stderr, "Warning: %s\n",
447 "ListSeparator equals DecimalSeparator.");
448 if (aListSep == aThoSep)
449 fprintf( stderr, "Warning: %s\n",
450 "ListSeparator equals ThousandSeparator.");
451 if (aListSep.getLength() != 1 || aListSep.getStr()[0] != ';')
453 incError( "ListSeparator not ';' semicolon. Strongly recommended. Currently required.");
454 ++nSavErr; // format codes not affected
456 if (aTimeSep == aTime100Sep)
457 ++nWarn, fprintf( stderr, "Warning: %s\n",
458 "Time100SecSeparator equals TimeSeparator, this is probably an error.");
459 if (aDecSep != aTime100Sep)
460 ++nWarn, fprintf( stderr, "Warning: %s\n",
461 "Time100SecSeparator is different from DecimalSeparator, this may be correct or not. Intended?");
462 if (nSavErr != nError || nWarn)
463 fprintf( stderr, "Warning: %s\n",
464 "Don't forget to adapt corresponding FormatCode elements when changing separators.");
466 OUString aQuoteStart =
467 writeParameterCheckLen( of, "QuotationStart", "quotationStart", 1, 1);
468 OUString aQuoteEnd =
469 writeParameterCheckLen( of, "QuotationEnd", "quotationEnd", 1, 1);
470 OUString aDoubleQuoteStart =
471 writeParameterCheckLen( of, "DoubleQuotationStart", "doubleQuotationStart", 1, 1);
472 OUString aDoubleQuoteEnd =
473 writeParameterCheckLen( of, "DoubleQuotationEnd", "doubleQuotationEnd", 1, 1);
475 if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() > 127)
476 fprintf( stderr, "Warning: %s\n",
477 "QuotationStart is an ASCII character but QuotationEnd is not.");
478 if (aQuoteEnd.toChar() <= 127 && aQuoteStart.toChar() > 127)
479 fprintf( stderr, "Warning: %s\n",
480 "QuotationEnd is an ASCII character but QuotationStart is not.");
481 if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() > 127)
482 fprintf( stderr, "Warning: %s\n",
483 "DoubleQuotationStart is an ASCII character but DoubleQuotationEnd is not.");
484 if (aDoubleQuoteEnd.toChar() <= 127 && aDoubleQuoteStart.toChar() > 127)
485 fprintf( stderr, "Warning: %s\n",
486 "DoubleQuotationEnd is an ASCII character but DoubleQuotationStart is not.");
487 if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() <= 127)
488 fprintf( stderr, "Warning: %s\n",
489 "QuotationStart and QuotationEnd are both ASCII characters. Not necessarily an error, but unusual.");
490 if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() <= 127)
491 fprintf( stderr, "Warning: %s\n",
492 "DoubleQuotationStart and DoubleQuotationEnd are both ASCII characters. Not necessarily an error, but unusual.");
493 if (aQuoteStart == aQuoteEnd)
494 fprintf( stderr, "Warning: %s\n",
495 "QuotationStart equals QuotationEnd. Not necessarily an error, but unusual.");
496 if (aDoubleQuoteStart == aDoubleQuoteEnd)
497 fprintf( stderr, "Warning: %s\n",
498 "DoubleQuotationStart equals DoubleQuotationEnd. Not necessarily an error, but unusual.");
500 writeParameterCheckLen( of, "TimeAM", "timeAM", 1, -1);
501 writeParameterCheckLen( of, "TimePM", "timePM", 1, -1);
502 sepNode = findNode("MeasurementSystem");
503 of.writeParameter("measurementSystem", sepNode->getValue());
505 of.writeAsciiString("\nstatic const sal_Unicode* LCType[] = {\n");
506 of.writeAsciiString("\tLC_CTYPE_Unoid,\n");
507 of.writeAsciiString("\tdateSeparator,\n");
508 of.writeAsciiString("\tthousandSeparator,\n");
509 of.writeAsciiString("\tdecimalSeparator,\n");
510 of.writeAsciiString("\ttimeSeparator,\n");
511 of.writeAsciiString("\ttime100SecSeparator,\n");
512 of.writeAsciiString("\tlistSeparator,\n");
513 of.writeAsciiString("\tquotationStart,\n");
514 of.writeAsciiString("\tquotationEnd,\n");
515 of.writeAsciiString("\tdoubleQuotationStart,\n");
516 of.writeAsciiString("\tdoubleQuotationEnd,\n");
517 of.writeAsciiString("\ttimeAM,\n");
518 of.writeAsciiString("\ttimePM,\n");
519 of.writeAsciiString("\tmeasurementSystem,\n");
520 of.writeAsciiString("\tLongDateDayOfWeekSeparator,\n");
521 of.writeAsciiString("\tLongDateDaySeparator,\n");
522 of.writeAsciiString("\tLongDateMonthSeparator,\n");
523 of.writeAsciiString("\tLongDateYearSeparator\n");
524 of.writeAsciiString("};\n\n");
525 of.writeFunction("getLocaleItem_", "0", "LCType");
529 sal_Int16 LCFormatNode::mnSection = 0;
530 sal_Int16 LCFormatNode::mnFormats = 0;
532 void LCFormatNode::generateCode (const OFileWriter &of) const
534 OUString str;
535 if (mnSection >= 2)
536 incError("more than 2 LC_FORMAT sections");
537 of.writeParameter("replaceFrom", getAttr() -> getValueByName("replaceFrom"), mnSection);
538 str = getAttr() -> getValueByName("replaceTo");
539 // Locale data generator inserts FFFF for LangID, we need to adapt that.
540 if (str.endsWithIgnoreAsciiCaseAsciiL( "-FFFF]", 6))
541 incErrorStr("replaceTo=\"%s\" needs FFFF to be adapted to the real LangID value.", str);
542 of.writeParameter("replaceTo", str, mnSection);
543 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
544 if (useLocale.getLength() > 0) {
545 switch (mnSection)
547 case 0:
548 of.writeRefFunction("getAllFormats0_", useLocale, "replaceTo0");
549 break;
550 case 1:
551 of.writeRefFunction("getAllFormats1_", useLocale, "replaceTo1");
552 break;
554 return;
556 sal_Int16 formatCount = mnFormats;
557 NameSet aMsgIdSet;
558 ValueSet aFormatIndexSet;
559 NameSet aDefaultsSet;
560 bool bCtypeIsRef = false;
562 for (sal_Int16 i = 0; i< getNumberOfChildren() ; i++,formatCount++) {
563 LocaleNode * currNode = getChildAt (i);
564 OUString aUsage;
565 OUString aType;
566 OUString aFormatIndex;
567 // currNode -> print();
568 const Attr * currNodeAttr = currNode->getAttr();
569 //printf ("getLen() = %d\n", currNode->getAttr()->getLength());
571 str = currNodeAttr -> getValueByName("msgid");
572 if (!aMsgIdSet.insert( str).second)
573 incErrorStr( "Duplicated msgid=\"%s\" in FormatElement.", str);
574 of.writeParameter("FormatKey", str, formatCount);
576 str = currNodeAttr -> getValueByName("default");
577 bool bDefault = str.equalsAscii( "true");
578 of.writeDefaultParameter("FormatElement", str, formatCount);
580 aType = currNodeAttr -> getValueByName("type");
581 of.writeParameter("FormatType", aType, formatCount);
583 aUsage = currNodeAttr -> getValueByName("usage");
584 of.writeParameter("FormatUsage", aUsage, formatCount);
586 aFormatIndex = currNodeAttr -> getValueByName("formatindex");
587 sal_Int16 formatindex = (sal_Int16)aFormatIndex.toInt32();
588 if (!aFormatIndexSet.insert( formatindex).second)
589 incErrorInt( "Duplicated formatindex=\"%d\" in FormatElement.", formatindex);
590 of.writeIntParameter("Formatindex", formatCount, formatindex);
592 // Ensure only one default per usage and type.
593 if (bDefault)
595 OUString aKey( aUsage + OUString( sal_Unicode(',')) + aType);
596 if (!aDefaultsSet.insert( aKey).second)
598 OUString aStr( RTL_CONSTASCII_USTRINGPARAM( "Duplicated default for usage=\""));
599 aStr += aUsage;
600 aStr += OUString( RTL_CONSTASCII_USTRINGPARAM( "\" type=\""));
601 aStr += aType;
602 aStr += OUString( RTL_CONSTASCII_USTRINGPARAM( "\": formatindex=\""));
603 aStr += aFormatIndex;
604 aStr += OUString( RTL_CONSTASCII_USTRINGPARAM( "\"."));
605 incError( aStr);
609 const LocaleNode * n = currNode -> findNode("FormatCode");
610 if (n)
612 of.writeParameter("FormatCode", n->getValue(), formatCount);
613 // Check separator usage for some FormatCode elements.
614 const LocaleNode* pCtype = 0;
615 switch (formatindex)
617 case cssi::NumberFormatIndex::NUMBER_1000DEC2 : // #,##0.00
618 case cssi::NumberFormatIndex::TIME_MMSS00 : // MM:SS.00
619 case cssi::NumberFormatIndex::TIME_HH_MMSS00 : // [HH]:MM:SS.00
621 const LocaleNode* pRoot = getRoot();
622 if (!pRoot)
623 incError( "No root for FormatCode.");
624 else
626 pCtype = pRoot->findNode( "LC_CTYPE");
627 if (!pCtype)
628 incError( "No LC_CTYPE found for FormatCode.");
629 else
631 OUString aRef( pCtype->getAttr()->getValueByName("ref"));
632 if (aRef.getLength() > 0)
634 if (!bCtypeIsRef)
635 fprintf( stderr,
636 "Warning: Can't check separators used in FormatCode due to LC_CTYPE ref=\"%s\".\n"
637 "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",
638 OUStringToOString( aRef, RTL_TEXTENCODING_UTF8).getStr());
639 bCtypeIsRef = true;
640 pCtype = 0;
645 break;
646 // Currency formats should be something like [C]###0;-[C]###0
647 // and not parenthesized [C]###0;([C]###0) if not en_US.
648 case cssi::NumberFormatIndex::CURRENCY_1000INT :
649 case cssi::NumberFormatIndex::CURRENCY_1000INT_RED :
650 case cssi::NumberFormatIndex::CURRENCY_1000DEC2 :
651 case cssi::NumberFormatIndex::CURRENCY_1000DEC2_RED :
652 case cssi::NumberFormatIndex::CURRENCY_1000DEC2_CCC :
653 case cssi::NumberFormatIndex::CURRENCY_1000DEC2_DASHED :
654 if (strcmp( of.getLocale(), "en_US") != 0)
656 OUString aCode( n->getValue());
657 OUString aPar1( RTL_CONSTASCII_USTRINGPARAM( "0)" ));
658 OUString aPar2( RTL_CONSTASCII_USTRINGPARAM( "-)" ));
659 OUString aPar3( RTL_CONSTASCII_USTRINGPARAM( " )" ));
660 if (aCode.indexOf( aPar1 ) > 0 || aCode.indexOf( aPar2 ) > 0 || aCode.indexOf( aPar3 ) > 0)
661 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);
663 break;
665 if (pCtype)
667 int nSavErr = nError;
668 OUString aCode( n->getValue());
669 if (formatindex == cssi::NumberFormatIndex::NUMBER_1000DEC2)
671 sal_Int32 nDec = -1;
672 sal_Int32 nGrp = -1;
673 const LocaleNode* pSep = pCtype->findNode( "DecimalSeparator");
674 if (!pSep)
675 incError( "No DecimalSeparator found for FormatCode.");
676 else
678 nDec = aCode.indexOf( pSep->getValue());
679 if (nDec < 0)
680 incErrorInt( "DecimalSeparator not present in FormatCode formatindex=\"%d\".",
681 formatindex);
683 pSep = pCtype->findNode( "ThousandSeparator");
684 if (!pSep)
685 incError( "No ThousandSeparator found for FormatCode.");
686 else
688 nGrp = aCode.indexOf( pSep->getValue());
689 if (nGrp < 0)
690 incErrorInt( "ThousandSeparator not present in FormatCode formatindex=\"%d\".",
691 formatindex);
693 if (nDec <= nGrp)
694 incErrorInt( "Ordering of ThousandSeparator and DecimalSeparator not correct in formatindex=\"%d\".",
695 formatindex);
697 if (formatindex == cssi::NumberFormatIndex::TIME_MMSS00 ||
698 formatindex == cssi::NumberFormatIndex::TIME_HH_MMSS00)
700 sal_Int32 nTime = -1;
701 sal_Int32 n100s = -1;
702 const LocaleNode* pSep = pCtype->findNode( "TimeSeparator");
703 if (!pSep)
704 incError( "No TimeSeparator found for FormatCode.");
705 else
707 nTime = aCode.indexOf( pSep->getValue());
708 if (nTime < 0)
709 incErrorInt( "TimeSeparator not present in FormatCode formatindex=\"%d\".",
710 formatindex);
712 pSep = pCtype->findNode( "Time100SecSeparator");
713 if (!pSep)
714 incError( "No Time100SecSeparator found for FormatCode.");
715 else
717 n100s = aCode.indexOf( pSep->getValue());
718 if (n100s < 0)
719 incErrorInt( "Time100SecSeparator not present in FormatCode formatindex=\"%d\".",
720 formatindex);
721 OUStringBuffer a100s( pSep->getValue());
722 a100s.appendAscii( "00");
723 n100s = aCode.indexOf( a100s.makeStringAndClear());
724 if (n100s < 0)
725 incErrorInt( "Time100SecSeparator+00 not present in FormatCode formatindex=\"%d\".",
726 formatindex);
728 if (n100s <= nTime)
729 incErrorInt( "Ordering of Time100SecSeparator and TimeSeparator not correct in formatindex=\"%d\".",
730 formatindex);
732 if (nSavErr != nError)
733 fprintf( stderr,
734 "Warning: formatindex=\"%d\",\"%d\",\"%d\" are the only FormatCode elements checked for separator usage, there may be others that have errors.\n",
735 int(cssi::NumberFormatIndex::NUMBER_1000DEC2),
736 int(cssi::NumberFormatIndex::TIME_MMSS00),
737 int(cssi::NumberFormatIndex::TIME_HH_MMSS00));
741 else
742 incError( "No FormatCode in FormatElement.");
743 n = currNode -> findNode("DefaultName");
744 if (n)
745 of.writeParameter("FormatDefaultName", n->getValue(), formatCount);
746 else
747 of.writeParameter("FormatDefaultName", ::rtl::OUString(), formatCount);
751 // Check presence of all required format codes only in first section
752 // LC_FORMAT, not in optional LC_FORMAT_1
753 if (mnSection == 0)
755 // 0..47 MUST be present, 48,49 MUST NOT be present
756 ValueSet::const_iterator aIter( aFormatIndexSet.begin());
757 for (sal_Int16 nNext = cssi::NumberFormatIndex::NUMBER_START;
758 nNext < cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES; ++nNext)
760 sal_Int16 nHere = ::std::min( ((aIter != aFormatIndexSet.end() ? *aIter :
761 cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES)),
762 cssi::NumberFormatIndex::INDEX_TABLE_ENTRIES);
763 if (aIter != aFormatIndexSet.end()) ++aIter;
764 for ( ; nNext < nHere; ++nNext)
766 switch (nNext)
768 case cssi::NumberFormatIndex::FRACTION_1 :
769 case cssi::NumberFormatIndex::FRACTION_2 :
770 case cssi::NumberFormatIndex::BOOLEAN :
771 case cssi::NumberFormatIndex::TEXT :
772 // generated internally
773 break;
774 default:
775 incErrorInt( "FormatElement formatindex=\"%d\" not present.", nNext);
778 switch (nHere)
780 case cssi::NumberFormatIndex::BOOLEAN :
781 incErrorInt( "FormatElement formatindex=\"%d\" reserved for internal ``BOOLEAN''.", nNext);
782 break;
783 case cssi::NumberFormatIndex::TEXT :
784 incErrorInt( "FormatElement formatindex=\"%d\" reserved for internal ``@'' (TEXT).", nNext);
785 break;
786 default:
787 ; // nothing
792 of.writeAsciiString("\nstatic const sal_Int16 ");
793 of.writeAsciiString("FormatElementsCount");
794 of.writeInt(mnSection);
795 of.writeAsciiString(" = ");
796 of.writeInt( formatCount - mnFormats);
797 of.writeAsciiString(";\n");
798 of.writeAsciiString("static const sal_Unicode* ");
799 of.writeAsciiString("FormatElementsArray");
800 of.writeInt(mnSection);
801 of.writeAsciiString("[] = {\n");
802 for(sal_Int16 i = mnFormats; i < formatCount; i++) {
804 of.writeAsciiString("\t");
805 of.writeAsciiString("FormatCode");
806 of.writeInt(i);
807 of.writeAsciiString(",\n");
809 of.writeAsciiString("\t");
810 of.writeAsciiString("FormatDefaultName");
811 of.writeInt(i);
812 of.writeAsciiString(",\n");
814 of.writeAsciiString("\t");
815 of.writeAsciiString("FormatKey");
816 of.writeInt(i);
817 of.writeAsciiString(",\n");
819 of.writeAsciiString("\t");
820 of.writeAsciiString("FormatType");
821 of.writeInt(i);
822 of.writeAsciiString(",\n");
824 of.writeAsciiString("\t");
825 of.writeAsciiString("FormatUsage");
826 of.writeInt(i);
827 of.writeAsciiString(",\n");
829 of.writeAsciiString("\t");
830 of.writeAsciiString("Formatindex");
831 of.writeInt(i);
832 of.writeAsciiString(",\n");
835 of.writeAsciiString("\tdefaultFormatElement");
836 of.writeInt(i);
837 of.writeAsciiString(",\n");
839 of.writeAsciiString("};\n\n");
841 switch (mnSection)
843 case 0:
844 of.writeFunction("getAllFormats0_", "FormatElementsCount0", "FormatElementsArray0", "replaceFrom0", "replaceTo0");
845 break;
846 case 1:
847 of.writeFunction("getAllFormats1_", "FormatElementsCount1", "FormatElementsArray1", "replaceFrom1", "replaceTo1");
848 break;
851 mnFormats = mnFormats + formatCount;
852 ++mnSection;
855 void LCCollationNode::generateCode (const OFileWriter &of) const
857 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
858 if (useLocale.getLength() > 0) {
859 of.writeRefFunction("getCollatorImplementation_", useLocale);
860 of.writeRefFunction("getCollationOptions_", useLocale);
861 return;
863 sal_Int16 nbOfCollations = 0;
864 sal_Int16 nbOfCollationOptions = 0;
865 sal_Int16 j;
867 for ( j = 0; j < getNumberOfChildren(); j++ ) {
868 LocaleNode * currNode = getChildAt (j);
869 if( currNode->getName().compareToAscii("Collator") == 0 )
871 ::rtl::OUString str;
872 str = currNode->getAttr() -> getValueByName("unoid");
873 of.writeParameter("CollatorID", str, j);
874 str = currNode->getValue();
875 of.writeParameter("CollatorRule", str, j);
876 str = currNode -> getAttr() -> getValueByName("default");
877 of.writeDefaultParameter("Collator", str, j);
878 of.writeAsciiString("\n");
880 nbOfCollations++;
882 if( currNode->getName().compareToAscii("CollationOptions") == 0 )
884 LocaleNode* pCollationOptions = currNode;
885 nbOfCollationOptions = sal::static_int_cast<sal_Int16>( pCollationOptions->getNumberOfChildren() );
886 for( sal_Int16 i=0; i<nbOfCollationOptions; i++ )
888 of.writeParameter("collationOption", pCollationOptions->getChildAt( i )->getValue(), i );
891 of.writeAsciiString("static const sal_Int16 nbOfCollationOptions = ");
892 of.writeInt( nbOfCollationOptions );
893 of.writeAsciiString(";\n\n");
896 of.writeAsciiString("static const sal_Int16 nbOfCollations = ");
897 of.writeInt(nbOfCollations);
898 of.writeAsciiString(";\n\n");
900 of.writeAsciiString("\nstatic const sal_Unicode* LCCollatorArray[] = {\n");
901 for(j = 0; j < nbOfCollations; j++) {
902 of.writeAsciiString("\tCollatorID");
903 of.writeInt(j);
904 of.writeAsciiString(",\n");
906 of.writeAsciiString("\tdefaultCollator");
907 of.writeInt(j);
908 of.writeAsciiString(",\n");
910 of.writeAsciiString("\tCollatorRule");
911 of.writeInt(j);
912 of.writeAsciiString(",\n");
914 of.writeAsciiString("};\n\n");
916 of.writeAsciiString("static const sal_Unicode* collationOptions[] = {");
917 for( j=0; j<nbOfCollationOptions; j++ )
919 of.writeAsciiString( "collationOption" );
920 of.writeInt( j );
921 of.writeAsciiString( ", " );
923 of.writeAsciiString("NULL };\n");
924 of.writeFunction("getCollatorImplementation_", "nbOfCollations", "LCCollatorArray");
925 of.writeFunction("getCollationOptions_", "nbOfCollationOptions", "collationOptions");
928 void LCSearchNode::generateCode (const OFileWriter &of) const
930 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
931 if (useLocale.getLength() > 0) {
932 of.writeRefFunction("getSearchOptions_", useLocale);
933 return;
936 if( getNumberOfChildren() != 1 )
938 ++nError;
939 fprintf(
940 stderr, "Error: LC_SEARCH: more than 1 child: %ld\n",
941 sal::static_int_cast< long >(getNumberOfChildren()));
943 sal_Int32 i;
944 LocaleNode* pSearchOptions = getChildAt( 0 );
945 sal_Int32 nSearchOptions = pSearchOptions->getNumberOfChildren();
946 for( i=0; i<nSearchOptions; i++ )
948 of.writeParameter("searchOption", pSearchOptions->getChildAt( i )->getValue(), sal::static_int_cast<sal_Int16>(i) );
951 of.writeAsciiString("static const sal_Int16 nbOfSearchOptions = ");
952 of.writeInt( sal::static_int_cast<sal_Int16>( nSearchOptions ) );
953 of.writeAsciiString(";\n\n");
955 of.writeAsciiString("static const sal_Unicode* searchOptions[] = {");
956 for( i=0; i<nSearchOptions; i++ )
958 of.writeAsciiString( "searchOption" );
959 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
960 of.writeAsciiString( ", " );
962 of.writeAsciiString("NULL };\n");
963 of.writeFunction("getSearchOptions_", "nbOfSearchOptions", "searchOptions");
966 void LCIndexNode::generateCode (const OFileWriter &of) const
968 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
969 if (useLocale.getLength() > 0) {
970 of.writeRefFunction("getIndexAlgorithm_", useLocale);
971 of.writeRefFunction("getUnicodeScripts_", useLocale);
972 of.writeRefFunction("getFollowPageWords_", useLocale);
973 return;
975 sal_Int16 nbOfIndexs = 0;
976 sal_Int16 nbOfUnicodeScripts = 0;
977 sal_Int16 nbOfPageWords = 0;
978 sal_Int16 i;
979 for (i = 0; i< getNumberOfChildren();i++) {
980 LocaleNode * currNode = getChildAt (i);
981 if( currNode->getName().compareToAscii("IndexKey") == 0 )
983 ::rtl::OUString str;
984 str = currNode->getAttr() -> getValueByName("unoid");
985 of.writeParameter("IndexID", str, nbOfIndexs);
986 str = currNode->getAttr() -> getValueByName("module");
987 of.writeParameter("IndexModule", str, nbOfIndexs);
988 str = currNode->getValue();
989 of.writeParameter("IndexKey", str, nbOfIndexs);
990 str = currNode -> getAttr() -> getValueByName("default");
991 of.writeDefaultParameter("Index", str, nbOfIndexs);
992 str = currNode -> getAttr() -> getValueByName("phonetic");
993 of.writeDefaultParameter("Phonetic", str, nbOfIndexs);
994 of.writeAsciiString("\n");
996 nbOfIndexs++;
998 if( currNode->getName().compareToAscii("UnicodeScript") == 0 )
1000 of.writeParameter("unicodeScript", currNode->getValue(), nbOfUnicodeScripts );
1001 nbOfUnicodeScripts++;
1004 if( currNode->getName().compareToAscii("FollowPageWord") == 0 )
1006 of.writeParameter("followPageWord", currNode->getValue(), nbOfPageWords);
1007 nbOfPageWords++;
1010 of.writeAsciiString("static const sal_Int16 nbOfIndexs = ");
1011 of.writeInt(nbOfIndexs);
1012 of.writeAsciiString(";\n\n");
1014 of.writeAsciiString("\nstatic const sal_Unicode* IndexArray[] = {\n");
1015 for(i = 0; i < nbOfIndexs; i++) {
1016 of.writeAsciiString("\tIndexID");
1017 of.writeInt(i);
1018 of.writeAsciiString(",\n");
1020 of.writeAsciiString("\tIndexModule");
1021 of.writeInt(i);
1022 of.writeAsciiString(",\n");
1024 of.writeAsciiString("\tIndexKey");
1025 of.writeInt(i);
1026 of.writeAsciiString(",\n");
1028 of.writeAsciiString("\tdefaultIndex");
1029 of.writeInt(i);
1030 of.writeAsciiString(",\n");
1032 of.writeAsciiString("\tdefaultPhonetic");
1033 of.writeInt(i);
1034 of.writeAsciiString(",\n");
1036 of.writeAsciiString("};\n\n");
1038 of.writeAsciiString("static const sal_Int16 nbOfUnicodeScripts = ");
1039 of.writeInt( nbOfUnicodeScripts );
1040 of.writeAsciiString(";\n\n");
1042 of.writeAsciiString("static const sal_Unicode* UnicodeScriptArray[] = {");
1043 for( i=0; i<nbOfUnicodeScripts; i++ )
1045 of.writeAsciiString( "unicodeScript" );
1046 of.writeInt( i );
1047 of.writeAsciiString( ", " );
1049 of.writeAsciiString("NULL };\n\n");
1051 of.writeAsciiString("static const sal_Int16 nbOfPageWords = ");
1052 of.writeInt(nbOfPageWords);
1053 of.writeAsciiString(";\n\n");
1055 of.writeAsciiString("static const sal_Unicode* FollowPageWordArray[] = {\n");
1056 for(i = 0; i < nbOfPageWords; i++) {
1057 of.writeAsciiString("\tfollowPageWord");
1058 of.writeInt(i);
1059 of.writeAsciiString(",\n");
1061 of.writeAsciiString("\tNULL\n};\n\n");
1063 of.writeFunction("getIndexAlgorithm_", "nbOfIndexs", "IndexArray");
1064 of.writeFunction("getUnicodeScripts_", "nbOfUnicodeScripts", "UnicodeScriptArray");
1065 of.writeFunction("getFollowPageWords_", "nbOfPageWords", "FollowPageWordArray");
1068 void LCCalendarNode::generateCode (const OFileWriter &of) const
1070 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1071 if (useLocale.getLength() > 0) {
1072 of.writeRefFunction("getAllCalendars_", useLocale);
1073 return;
1075 sal_Int16 nbOfCalendars = sal::static_int_cast<sal_Int16>( getNumberOfChildren() );
1076 ::rtl::OUString str;
1077 sal_Int16 * nbOfDays = new sal_Int16[nbOfCalendars];
1078 sal_Int16 * nbOfMonths = new sal_Int16[nbOfCalendars];
1079 sal_Int16 * nbOfEras = new sal_Int16[nbOfCalendars];
1080 sal_Int16 j;
1081 sal_Int16 i;
1082 bool bHasGregorian = false;
1085 for ( i = 0; i < nbOfCalendars; i++) {
1086 LocaleNode * calNode = getChildAt (i);
1087 OUString calendarID = calNode -> getAttr() -> getValueByName("unoid");
1088 of.writeParameter( "calendarID", calendarID, i);
1089 bool bGregorian = calendarID.equalsAscii( "gregorian");
1090 if (!bHasGregorian)
1091 bHasGregorian = bGregorian;
1092 str = calNode -> getAttr() -> getValueByName("default");
1093 of.writeDefaultParameter("Calendar", str, i);
1095 // Generate Days of Week
1096 const sal_Char *elementTag;
1097 LocaleNode * daysNode = NULL;
1098 ::rtl::OUString ref_name = calNode->getChildAt(0)->getAttr()->getValueByName("ref");
1099 if (ref_name.getLength() > 0 && i > 0) {
1100 for (j = 0; j < i; j++) {
1101 str = getChildAt(j)->getAttr()->getValueByName("unoid");
1102 if (str.equals(ref_name))
1103 daysNode = getChildAt(j)->getChildAt(0);
1106 if (ref_name.getLength() > 0 && daysNode == NULL) {
1107 of.writeParameter("dayRef", OUString::createFromAscii("ref"), i);
1108 of.writeParameter("dayRefName", ref_name, i);
1109 nbOfDays[i] = 0;
1110 } else {
1111 if (daysNode == NULL)
1112 daysNode = calNode -> getChildAt(0);
1113 nbOfDays[i] = sal::static_int_cast<sal_Int16>( daysNode->getNumberOfChildren() );
1114 if (bGregorian && nbOfDays[i] != 7)
1115 incErrorInt( "A Gregorian calendar must have 7 days per week, this one has %d", nbOfDays[i]);
1116 elementTag = "day";
1117 for (j = 0; j < nbOfDays[i]; j++) {
1118 LocaleNode *currNode = daysNode -> getChildAt(j);
1119 OUString dayID( currNode->getChildAt(0)->getValue());
1120 of.writeParameter("dayID", dayID, i, j);
1121 if (j == 0 && bGregorian && !dayID.equalsAscii( "sun"))
1122 incError( "First day of a week of a Gregorian calendar must be <DayID>sun</DayID>");
1123 of.writeParameter(elementTag, "DefaultAbbrvName",currNode->getChildAt(1)->getValue() ,i, j);
1124 of.writeParameter(elementTag, "DefaultFullName",currNode->getChildAt(2)->getValue() , i, j);
1128 // Generate Months of Year
1129 LocaleNode * monthsNode = NULL;
1130 ref_name = calNode->getChildAt(1)->getAttr()->getValueByName("ref");
1131 if (ref_name.getLength() > 0 && i > 0) {
1132 for (j = 0; j < i; j++) {
1133 str = getChildAt(j)->getAttr()->getValueByName("unoid");
1134 if (str.equals(ref_name))
1135 monthsNode = getChildAt(j)->getChildAt(1);
1138 if (ref_name.getLength() > 0 && monthsNode == NULL) {
1139 of.writeParameter("monthRef", OUString::createFromAscii("ref"), i);
1140 of.writeParameter("monthRefName", ref_name, i);
1141 nbOfMonths[i] = 0;
1142 } else {
1143 if (monthsNode == NULL)
1144 monthsNode = calNode -> getChildAt(1);
1145 nbOfMonths[i] = sal::static_int_cast<sal_Int16>( monthsNode->getNumberOfChildren() );
1146 if (bGregorian && nbOfMonths[i] != 12)
1147 incErrorInt( "A Gregorian calendar must have 12 months, this one has %d", nbOfMonths[i]);
1148 elementTag = "month";
1149 for (j = 0; j < nbOfMonths[i]; j++) {
1150 LocaleNode *currNode = monthsNode -> getChildAt(j);
1151 OUString monthID( currNode->getChildAt(0)->getValue());
1152 of.writeParameter("monthID", monthID, i, j);
1153 if (j == 0 && bGregorian && !monthID.equalsAscii( "jan"))
1154 incError( "First month of a year of a Gregorian calendar must be <MonthID>jan</MonthID>");
1155 of.writeParameter(elementTag, "DefaultAbbrvName",currNode->getChildAt(1)->getValue() ,i, j);
1156 of.writeParameter(elementTag, "DefaultFullName",currNode->getChildAt(2)->getValue() , i, j);
1160 // Generate Era name
1161 LocaleNode * erasNode = NULL;
1162 ref_name = calNode -> getChildAt(2) ->getAttr()->getValueByName("ref");
1163 if (ref_name.getLength() > 0 && i > 0) {
1164 for (j = 0; j < i; j++) {
1165 str = getChildAt(j)->getAttr()->getValueByName("unoid");
1166 if (str.equals(ref_name))
1167 erasNode = getChildAt(j)->getChildAt(2);
1170 if (ref_name.getLength() > 0 && erasNode == NULL) {
1171 of.writeParameter("eraRef", OUString::createFromAscii("ref"), i);
1172 of.writeParameter("eraRefName", ref_name, i);
1173 nbOfEras[i] = 0;
1174 } else {
1175 if (erasNode == NULL)
1176 erasNode = calNode -> getChildAt(2);
1177 nbOfEras[i] = sal::static_int_cast<sal_Int16>( erasNode->getNumberOfChildren() );
1178 if (bGregorian && nbOfEras[i] != 2)
1179 incErrorInt( "A Gregorian calendar must have 2 eras, this one has %d", nbOfEras[i]);
1180 elementTag = "era";
1181 for (j = 0; j < nbOfEras[i]; j++) {
1182 LocaleNode *currNode = erasNode -> getChildAt(j);
1183 OUString eraID( currNode->getChildAt(0)->getValue());
1184 of.writeParameter("eraID", eraID, i, j);
1185 if (j == 0 && bGregorian && !eraID.equalsAscii( "bc"))
1186 incError( "First era of a Gregorian calendar must be <EraID>bc</EraID>");
1187 if (j == 1 && bGregorian && !eraID.equalsAscii( "ad"))
1188 incError( "Second era of a Gregorian calendar must be <EraID>ad</EraID>");
1189 of.writeAsciiString("\n");
1190 of.writeParameter(elementTag, "DefaultAbbrvName",currNode->getChildAt(1)->getValue() ,i, j);
1191 of.writeParameter(elementTag, "DefaultFullName",currNode->getChildAt(2)->getValue() , i, j);
1194 str = calNode->getChildAt(3)->getChildAt(0)->getValue();
1195 if (nbOfDays[i])
1197 for (j = 0; j < nbOfDays[i]; j++)
1199 LocaleNode *currNode = daysNode->getChildAt(j);
1200 OUString dayID( currNode->getChildAt(0)->getValue());
1201 if (str == dayID)
1202 break; // for
1204 if (j >= nbOfDays[i])
1205 incErrorStr( "<StartDayOfWeek> <DayID> must be one of the <DaysOfWeek>, but is", str);
1207 of.writeParameter("startDayOfWeek", str, i);
1208 str = calNode ->getChildAt(4)-> getValue();
1209 sal_Int16 nDays = sal::static_int_cast<sal_Int16>( str.toInt32() );
1210 if (nDays < 1 || (0 < nbOfDays[i] && nbOfDays[i] < nDays))
1211 incErrorInt( "Bad value of MinimalDaysInFirstWeek: %d, must be 1 <= value <= days_in_week", nDays);
1212 of.writeIntParameter("minimalDaysInFirstWeek", i, nDays);
1214 if (!bHasGregorian)
1215 fprintf( stderr, "Warning: %s\n", "No Gregorian calendar defined, are you sure?");
1217 of.writeAsciiString("static const sal_Int16 calendarsCount = ");
1218 of.writeInt(nbOfCalendars);
1219 of.writeAsciiString(";\n\n");
1221 of.writeAsciiString("static const sal_Unicode nbOfDays[] = {");
1222 for(i = 0; i < nbOfCalendars - 1; i++) {
1223 of.writeInt(nbOfDays[i]);
1224 of.writeAsciiString(", ");
1226 of.writeInt(nbOfDays[i]);
1227 of.writeAsciiString("};\n");
1229 of.writeAsciiString("static const sal_Unicode nbOfMonths[] = {");
1230 for(i = 0; i < nbOfCalendars - 1; i++) {
1231 of.writeInt(nbOfMonths[i]);
1232 of.writeAsciiString(", ");
1234 of.writeInt(nbOfMonths[i]);
1235 of.writeAsciiString("};\n");
1237 of.writeAsciiString("static const sal_Unicode nbOfEras[] = {");
1238 for(i = 0; i < nbOfCalendars - 1; i++) {
1239 of.writeInt(nbOfEras[i]);
1240 of.writeAsciiString(", ");
1242 of.writeInt(nbOfEras[i]);
1243 of.writeAsciiString("};\n");
1246 of.writeAsciiString("static const sal_Unicode* calendars[] = {\n");
1247 of.writeAsciiString("\tnbOfDays,\n");
1248 of.writeAsciiString("\tnbOfMonths,\n");
1249 of.writeAsciiString("\tnbOfEras,\n");
1250 for(i = 0; i < nbOfCalendars; i++) {
1251 of.writeAsciiString("\tcalendarID");
1252 of.writeInt(i);
1253 of.writeAsciiString(",\n");
1254 of.writeAsciiString("\tdefaultCalendar");
1255 of.writeInt(i);
1256 of.writeAsciiString(",\n");
1257 if (nbOfDays[i] == 0) {
1258 of.writeAsciiString("\tdayRef");
1259 of.writeInt(i); of.writeAsciiString(",\n");
1260 of.writeAsciiString("\tdayRefName");
1261 of.writeInt(i); of.writeAsciiString(",\n");
1262 } else {
1263 for(j = 0; j < nbOfDays[i]; j++) {
1264 of.writeAsciiString("\tdayID");
1265 of.writeInt(i); of.writeInt(j); of.writeAsciiString(",\n");
1266 of.writeAsciiString("\tdayDefaultAbbrvName");
1267 of.writeInt(i); of.writeInt(j); of.writeAsciiString(",\n");
1268 of.writeAsciiString("\tdayDefaultFullName");of.writeInt(i); of.writeInt(j); of.writeAsciiString(",\n");
1271 if (nbOfMonths[i] == 0) {
1272 of.writeAsciiString("\tmonthRef");
1273 of.writeInt(i); of.writeAsciiString(",\n");
1274 of.writeAsciiString("\tmonthRefName");
1275 of.writeInt(i); of.writeAsciiString(",\n");
1276 } else {
1277 for(j = 0; j < nbOfMonths[i]; j++) {
1278 of.writeAsciiString("\tmonthID");of.writeInt(i);of.writeInt(j);of.writeAsciiString(",\n");
1279 of.writeAsciiString("\tmonthDefaultAbbrvName");of.writeInt(i);of.writeInt(j);of.writeAsciiString(",\n");
1280 of.writeAsciiString("\tmonthDefaultFullName");of.writeInt(i);of.writeInt(j);of.writeAsciiString(",\n");
1283 if (nbOfEras[i] == 0) {
1284 of.writeAsciiString("\teraRef");
1285 of.writeInt(i); of.writeAsciiString(",\n");
1286 of.writeAsciiString("\teraRefName");
1287 of.writeInt(i); of.writeAsciiString(",\n");
1288 } else {
1289 for(j = 0; j < nbOfEras[i]; j++) {
1290 of.writeAsciiString("\teraID"); of.writeInt(i); of.writeInt(j); of.writeAsciiString(",\n");
1291 of.writeAsciiString("\teraDefaultAbbrvName");of.writeInt(i);of.writeInt(j);of.writeAsciiString(",\n");
1292 of.writeAsciiString("\teraDefaultFullName");of.writeInt(i);of.writeInt(j);of.writeAsciiString(",\n");
1295 of.writeAsciiString("\tstartDayOfWeek");of.writeInt(i); of.writeAsciiString(",\n");
1296 of.writeAsciiString("\tminimalDaysInFirstWeek");of.writeInt(i); of.writeAsciiString(",\n");
1299 of.writeAsciiString("};\n\n");
1300 of.writeFunction("getAllCalendars_", "calendarsCount", "calendars");
1302 delete []nbOfDays;
1303 delete []nbOfMonths;
1304 delete []nbOfEras;
1307 bool isIso4217( const OUString& rStr )
1309 const sal_Unicode* p = rStr.getStr();
1310 return rStr.getLength() == 3
1311 && 'A' <= p[0] && p[0] <= 'Z'
1312 && 'A' <= p[1] && p[1] <= 'Z'
1313 && 'A' <= p[2] && p[2] <= 'Z'
1317 void LCCurrencyNode :: generateCode (const OFileWriter &of) const
1319 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1320 if (useLocale.getLength() > 0) {
1321 of.writeRefFunction("getAllCurrencies_", useLocale);
1322 return;
1324 sal_Int16 nbOfCurrencies = 0;
1325 ::rtl::OUString str;
1326 sal_Int16 i;
1328 bool bTheDefault= false;
1329 bool bTheCompatible = false;
1330 for ( i = 0; i < getNumberOfChildren(); i++,nbOfCurrencies++) {
1331 LocaleNode * calNode = getChildAt (i);
1332 str = calNode->getAttr() -> getValueByName("default");
1333 bool bDefault = of.writeDefaultParameter("Currency", str, nbOfCurrencies);
1334 str = calNode->getAttr() -> getValueByName("usedInCompatibleFormatCodes");
1335 bool bCompatible = of.writeDefaultParameter("CurrencyUsedInCompatibleFormatCodes", str, nbOfCurrencies);
1336 str = calNode->getAttr() -> getValueByName("legacyOnly");
1337 bool bLegacy = of.writeDefaultParameter("CurrencyLegacyOnly", str, nbOfCurrencies);
1338 if (bLegacy && (bDefault || bCompatible))
1339 incError( "Currency: if legacyOnly==true, both 'default' and 'usedInCompatibleFormatCodes' must be false.");
1340 if (bDefault)
1342 if (bTheDefault)
1343 incError( "Currency: more than one default currency.");
1344 bTheDefault = true;
1346 if (bCompatible)
1348 if (bTheCompatible)
1349 incError( "Currency: more than one currency flagged as usedInCompatibleFormatCodes.");
1350 bTheCompatible = true;
1352 str = calNode -> findNode ("CurrencyID") -> getValue();
1353 of.writeParameter("currencyID", str, nbOfCurrencies);
1354 // CurrencyID MUST be ISO 4217.
1355 if (!bLegacy && !isIso4217(str))
1356 incError( "CurrencyID is not ISO 4217");
1357 str = calNode -> findNode ("CurrencySymbol") -> getValue();
1358 of.writeParameter("currencySymbol", str, nbOfCurrencies);
1359 str = calNode -> findNode ("BankSymbol") -> getValue();
1360 of.writeParameter("bankSymbol", str, nbOfCurrencies);
1361 // BankSymbol currently must be ISO 4217. May change later if
1362 // application always uses CurrencyID instead of BankSymbol.
1363 if (!bLegacy && !isIso4217(str))
1364 incError( "BankSymbol is not ISO 4217");
1365 str = calNode -> findNode ("CurrencyName") -> getValue();
1366 of.writeParameter("currencyName", str, nbOfCurrencies);
1367 str = calNode -> findNode ("DecimalPlaces") -> getValue();
1368 sal_Int16 nDecimalPlaces = (sal_Int16)str.toInt32();
1369 of.writeIntParameter("currencyDecimalPlaces", nbOfCurrencies, nDecimalPlaces);
1370 of.writeAsciiString("\n");
1373 if (!bTheDefault)
1374 incError( "Currency: no default currency.");
1375 if (!bTheCompatible)
1376 incError( "Currency: no currency flagged as usedInCompatibleFormatCodes.");
1378 of.writeAsciiString("static const sal_Int16 currencyCount = ");
1379 of.writeInt(nbOfCurrencies);
1380 of.writeAsciiString(";\n\n");
1381 of.writeAsciiString("static const sal_Unicode* currencies[] = {\n");
1382 for(i = 0; i < nbOfCurrencies; i++) {
1383 of.writeAsciiString("\tcurrencyID");
1384 of.writeInt(i);
1385 of.writeAsciiString(",\n");
1386 of.writeAsciiString("\tcurrencySymbol");
1387 of.writeInt(i);
1388 of.writeAsciiString(",\n");
1389 of.writeAsciiString("\tbankSymbol");
1390 of.writeInt(i);
1391 of.writeAsciiString(",\n");
1392 of.writeAsciiString("\tcurrencyName");
1393 of.writeInt(i);
1394 of.writeAsciiString(",\n");
1395 of.writeAsciiString("\tdefaultCurrency");
1396 of.writeInt(i);
1397 of.writeAsciiString(",\n");
1398 of.writeAsciiString("\tdefaultCurrencyUsedInCompatibleFormatCodes");
1399 of.writeInt(i);
1400 of.writeAsciiString(",\n");
1401 of.writeAsciiString("\tcurrencyDecimalPlaces");
1402 of.writeInt(i);
1403 of.writeAsciiString(",\n");
1404 of.writeAsciiString("\tdefaultCurrencyLegacyOnly");
1405 of.writeInt(i);
1406 of.writeAsciiString(",\n");
1408 of.writeAsciiString("};\n\n");
1409 of.writeFunction("getAllCurrencies_", "currencyCount", "currencies");
1412 void LCTransliterationNode::generateCode (const OFileWriter &of) const
1414 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1415 if (useLocale.getLength() > 0) {
1416 of.writeRefFunction("getTransliterations_", useLocale);
1417 return;
1419 sal_Int16 nbOfModules = 0;
1420 ::rtl::OUString str;
1421 sal_Int16 i;
1423 for ( i = 0; i < getNumberOfChildren(); i++,nbOfModules++) {
1424 LocaleNode * calNode = getChildAt (i);
1425 str = calNode->getAttr() -> getValueByIndex(0);
1426 of.writeParameter("Transliteration", str, nbOfModules);
1428 of.writeAsciiString("static const sal_Int16 nbOfTransliterations = ");
1429 of.writeInt(nbOfModules);
1430 of.writeAsciiString(";\n\n");
1432 of.writeAsciiString("\nstatic const sal_Unicode* LCTransliterationsArray[] = {\n");
1433 for( i = 0; i < nbOfModules; i++) {
1434 of.writeAsciiString("\tTransliteration");
1435 of.writeInt(i);
1436 of.writeAsciiString(",\n");
1438 of.writeAsciiString("};\n\n");
1439 of.writeFunction("getTransliterations_", "nbOfTransliterations", "LCTransliterationsArray");
1442 struct NameValuePair {
1443 const sal_Char *name;
1444 const sal_Char *value;
1446 static NameValuePair ReserveWord[] = {
1447 { "trueWord", "true" },
1448 { "falseWord", "false" },
1449 { "quarter1Word", "1st quarter" },
1450 { "quarter2Word", "2nd quarter" },
1451 { "quarter3Word", "3rd quarter" },
1452 { "quarter4Word", "4th quarter" },
1453 { "aboveWord", "above" },
1454 { "belowWord", "below" },
1455 { "quarter1Abbreviation", "Q1" },
1456 { "quarter2Abbreviation", "Q2" },
1457 { "quarter3Abbreviation", "Q3" },
1458 { "quarter4Abbreviation", "Q4" }
1461 void LCMiscNode::generateCode (const OFileWriter &of) const
1463 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1464 if (useLocale.getLength() > 0) {
1465 of.writeRefFunction("getForbiddenCharacters_", useLocale);
1466 of.writeRefFunction("getBreakIteratorRules_", useLocale);
1467 of.writeRefFunction("getReservedWords_", useLocale);
1468 return;
1470 const LocaleNode * reserveNode = findNode("ReservedWords");
1471 if (!reserveNode)
1472 incError( "No ReservedWords element."); // should not happen if validated..
1473 const LocaleNode * forbidNode = findNode("ForbiddenCharacters");
1474 const LocaleNode * breakNode = findNode("BreakIteratorRules");
1476 bool bEnglishLocale = (strncmp( of.getLocale(), "en_", 3) == 0);
1478 sal_Int16 nbOfWords = 0;
1479 ::rtl::OUString str;
1480 sal_Int16 i;
1482 for ( i = 0; i < sal_Int16(sizeof(ReserveWord)/sizeof(ReserveWord[0])); i++,nbOfWords++) {
1483 const LocaleNode * curNode = (reserveNode ? reserveNode->findNode(
1484 ReserveWord[i].name) : 0);
1485 if (!curNode)
1486 fprintf( stderr,
1487 "Warning: No %s in ReservedWords, using en_US default: \"%s\".\n",
1488 ReserveWord[i].name, ReserveWord[i].value);
1489 str = curNode ? curNode -> getValue() : OUString::createFromAscii(ReserveWord[i].value);
1490 if (!str.getLength())
1492 ++nError;
1493 fprintf( stderr, "Error: No content for ReservedWords %s.\n", ReserveWord[i].name);
1495 of.writeParameter("ReservedWord", str, nbOfWords);
1496 // "true", ..., "below" trigger untranslated warning.
1497 if (!bEnglishLocale && curNode && (0 <= i && i <= 7) &&
1498 str.equalsIgnoreAsciiCaseAscii( ReserveWord[i].value))
1500 fprintf( stderr,
1501 "Warning: ReservedWord %s seems to be untranslated \"%s\".\n",
1502 ReserveWord[i].name, ReserveWord[i].value);
1505 of.writeAsciiString("static const sal_Int16 nbOfReservedWords = ");
1506 of.writeInt(nbOfWords);
1507 of.writeAsciiString(";\n\n");
1508 of.writeAsciiString("\nstatic const sal_Unicode* LCReservedWordsArray[] = {\n");
1509 for( i = 0; i < nbOfWords; i++) {
1510 of.writeAsciiString("\tReservedWord");
1511 of.writeInt(i);
1512 of.writeAsciiString(",\n");
1514 of.writeAsciiString("};\n\n");
1515 of.writeFunction("getReservedWords_", "nbOfReservedWords", "LCReservedWordsArray");
1517 if (forbidNode) {
1518 of.writeParameter( "forbiddenBegin", forbidNode -> getChildAt(0)->getValue());
1519 of.writeParameter( "forbiddenEnd", forbidNode -> getChildAt(1)->getValue());
1520 of.writeParameter( "hangingChars", forbidNode -> getChildAt(2)->getValue());
1521 } else {
1522 of.writeParameter( "forbiddenBegin", ::rtl::OUString());
1523 of.writeParameter( "forbiddenEnd", ::rtl::OUString());
1524 of.writeParameter( "hangingChars", ::rtl::OUString());
1526 of.writeAsciiString("\nstatic const sal_Unicode* LCForbiddenCharactersArray[] = {\n");
1527 of.writeAsciiString("\tforbiddenBegin,\n");
1528 of.writeAsciiString("\tforbiddenEnd,\n");
1529 of.writeAsciiString("\thangingChars\n");
1530 of.writeAsciiString("};\n\n");
1531 of.writeFunction("getForbiddenCharacters_", "3", "LCForbiddenCharactersArray");
1533 if (breakNode) {
1534 of.writeParameter( "EditMode", breakNode -> getChildAt(0)->getValue());
1535 of.writeParameter( "DictionaryMode", breakNode -> getChildAt(1)->getValue());
1536 of.writeParameter( "WordCountMode", breakNode -> getChildAt(2)->getValue());
1537 of.writeParameter( "CharacterMode", breakNode -> getChildAt(3)->getValue());
1538 of.writeParameter( "LineMode", breakNode -> getChildAt(4)->getValue());
1539 } else {
1540 of.writeParameter( "EditMode", ::rtl::OUString());
1541 of.writeParameter( "DictionaryMode", ::rtl::OUString());
1542 of.writeParameter( "WordCountMode", ::rtl::OUString());
1543 of.writeParameter( "CharacterMode", ::rtl::OUString());
1544 of.writeParameter( "LineMode", ::rtl::OUString());
1546 of.writeAsciiString("\nstatic const sal_Unicode* LCBreakIteratorRulesArray[] = {\n");
1547 of.writeAsciiString("\tEditMode,\n");
1548 of.writeAsciiString("\tDictionaryMode,\n");
1549 of.writeAsciiString("\tWordCountMode,\n");
1550 of.writeAsciiString("\tCharacterMode,\n");
1551 of.writeAsciiString("\tLineMode\n");
1552 of.writeAsciiString("};\n\n");
1553 of.writeFunction("getBreakIteratorRules_", "5", "LCBreakIteratorRulesArray");
1557 void LCNumberingLevelNode::generateCode (const OFileWriter &of) const
1559 of.writeAsciiString("// ---> ContinuousNumbering\n");
1560 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1561 if (useLocale.getLength() > 0) {
1562 of.writeRefFunction2("getContinuousNumberingLevels_", useLocale);
1563 return;
1566 // hard code number of attributes per style.
1567 const int nAttributes = 5;
1568 const char* attr[ nAttributes ] = { "Prefix", "NumType", "Suffix", "Transliteration", "NatNum" };
1570 // record each attribute of each style in a static C++ variable.
1571 // determine number of styles on the fly.
1572 sal_Int32 nStyles = getNumberOfChildren();
1573 sal_Int32 i;
1575 for( i = 0; i < nStyles; i++ )
1577 const Attr* q = getChildAt( i )->getAttr();
1578 for( sal_Int32 j=0; j<nAttributes; j++ )
1580 const char* name = attr[j];
1581 OUString value = q->getValueByName( name );
1582 of.writeParameter("continuous", name, value, sal::static_int_cast<sal_Int16>(i) );
1586 // record number of styles and attributes.
1587 of.writeAsciiString("static const sal_Int16 continuousNbOfStyles = ");
1588 of.writeInt( sal::static_int_cast<sal_Int16>( nStyles ) );
1589 of.writeAsciiString(";\n\n");
1590 of.writeAsciiString("static const sal_Int16 continuousNbOfAttributesPerStyle = ");
1591 of.writeInt( nAttributes );
1592 of.writeAsciiString(";\n\n");
1594 // generate code. (intermediate arrays)
1595 for( i=0; i<nStyles; i++ )
1597 of.writeAsciiString("\nstatic const sal_Unicode* continuousStyle" );
1598 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1599 of.writeAsciiString("[] = {\n");
1600 for( sal_Int32 j=0; j<nAttributes; j++)
1602 of.writeAsciiString("\t");
1603 of.writeAsciiString( "continuous" );
1604 of.writeAsciiString( attr[j] );
1605 of.writeInt(sal::static_int_cast<sal_Int16>(i));
1606 of.writeAsciiString(",\n");
1608 of.writeAsciiString("\t0\n};\n\n");
1611 // generate code. (top-level array)
1612 of.writeAsciiString("\n");
1613 of.writeAsciiString("static const sal_Unicode** LCContinuousNumberingLevelsArray[] = {\n" );
1614 for( i=0; i<nStyles; i++ )
1616 of.writeAsciiString( "\t" );
1617 of.writeAsciiString( "continuousStyle" );
1618 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1619 of.writeAsciiString( ",\n");
1621 of.writeAsciiString("\t0\n};\n\n");
1622 of.writeFunction2("getContinuousNumberingLevels_", "continuousNbOfStyles",
1623 "continuousNbOfAttributesPerStyle", "LCContinuousNumberingLevelsArray");
1627 void LCOutlineNumberingLevelNode::generateCode (const OFileWriter &of) const
1629 of.writeAsciiString("// ---> OutlineNumbering\n");
1630 ::rtl::OUString useLocale = getAttr() -> getValueByName("ref");
1631 if (useLocale.getLength() > 0) {
1632 of.writeRefFunction3("getOutlineNumberingLevels_", useLocale);
1633 return;
1636 // hardcode number of attributes per level
1637 const int nAttributes = 11;
1638 const char* attr[ nAttributes ] =
1640 "Prefix",
1641 "NumType",
1642 "Suffix",
1643 "BulletChar",
1644 "BulletFontName",
1645 "ParentNumbering",
1646 "LeftMargin",
1647 "SymbolTextDistance",
1648 "FirstLineOffset",
1649 "Transliteration",
1650 "NatNum",
1653 // record each attribute of each level of each style in a static C++ variable.
1654 // determine number of styles and number of levels per style on the fly.
1655 sal_Int32 nStyles = getNumberOfChildren();
1656 vector<sal_Int32> nLevels; // may be different for each style?
1657 for( sal_Int32 i = 0; i < nStyles; i++ )
1659 LocaleNode* p = getChildAt( i );
1660 nLevels.push_back( p->getNumberOfChildren() );
1661 for( sal_Int32 j=0; j<nLevels.back(); j++ )
1663 const Attr* q = p->getChildAt( j )->getAttr();
1664 for( sal_Int32 k=0; k<nAttributes; k++ )
1666 const char* name = attr[k];
1667 OUString value = q->getValueByName( name );
1668 of.writeParameter("outline", name, value,
1669 sal::static_int_cast<sal_Int16>(i),
1670 sal::static_int_cast<sal_Int16>(j) );
1675 // verify that each style has the same number of levels.
1676 for( size_t i=0; i<nLevels.size(); i++ )
1678 if( nLevels[0] != nLevels[i] )
1680 incError( "Numbering levels don't match.");
1684 // record number of attributes, levels, and styles.
1685 of.writeAsciiString("static const sal_Int16 outlineNbOfStyles = ");
1686 of.writeInt( sal::static_int_cast<sal_Int16>( nStyles ) );
1687 of.writeAsciiString(";\n\n");
1688 of.writeAsciiString("static const sal_Int16 outlineNbOfLevelsPerStyle = ");
1689 of.writeInt( sal::static_int_cast<sal_Int16>( nLevels.back() ) );
1690 of.writeAsciiString(";\n\n");
1691 of.writeAsciiString("static const sal_Int16 outlineNbOfAttributesPerLevel = ");
1692 of.writeInt( nAttributes );
1693 of.writeAsciiString(";\n\n");
1695 // too complicated for now...
1696 // of.writeAsciiString("static const sal_Int16 nbOfOutlineNumberingLevels[] = { ");
1697 // for( sal_Int32 j=0; j<nStyles; j++ )
1698 // {
1699 // of.writeInt( nLevels[j] );
1700 // of.writeAsciiString(", ");
1701 // }
1702 // of.writeAsciiString("};\n\n");
1705 for( sal_Int32 i=0; i<nStyles; i++ )
1707 for( sal_Int32 j=0; j<nLevels.back(); j++ )
1709 of.writeAsciiString("static const sal_Unicode* outline");
1710 of.writeAsciiString("Style");
1711 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1712 of.writeAsciiString("Level");
1713 of.writeInt( sal::static_int_cast<sal_Int16>(j) );
1714 of.writeAsciiString("[] = { ");
1716 for( sal_Int32 k=0; k<nAttributes; k++ )
1718 of.writeAsciiString( "outline" );
1719 of.writeAsciiString( attr[k] );
1720 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1721 of.writeInt( sal::static_int_cast<sal_Int16>(j) );
1722 of.writeAsciiString(", ");
1724 of.writeAsciiString("NULL };\n");
1728 of.writeAsciiString("\n");
1731 for( sal_Int32 i=0; i<nStyles; i++ )
1733 of.writeAsciiString("static const sal_Unicode** outline");
1734 of.writeAsciiString( "Style" );
1735 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1736 of.writeAsciiString("[] = { ");
1738 for( sal_Int32 j=0; j<nLevels.back(); j++ )
1740 of.writeAsciiString("outlineStyle");
1741 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1742 of.writeAsciiString("Level");
1743 of.writeInt( sal::static_int_cast<sal_Int16>(j) );
1744 of.writeAsciiString(", ");
1746 of.writeAsciiString("NULL };\n");
1748 of.writeAsciiString("\n");
1750 of.writeAsciiString("static const sal_Unicode*** LCOutlineNumberingLevelsArray[] = {\n" );
1751 for( sal_Int32 i=0; i<nStyles; i++ )
1753 of.writeAsciiString( "\t" );
1754 of.writeAsciiString( "outlineStyle" );
1755 of.writeInt( sal::static_int_cast<sal_Int16>(i) );
1756 of.writeAsciiString(",\n");
1758 of.writeAsciiString("\tNULL\n};\n\n");
1759 of.writeFunction3("getOutlineNumberingLevels_", "outlineNbOfStyles", "outlineNbOfLevelsPerStyle",
1760 "outlineNbOfAttributesPerLevel", "LCOutlineNumberingLevelsArray");
1763 Attr::Attr (const Reference< XAttributeList > & attr) {
1764 sal_Int16 len = attr->getLength();
1765 name.realloc (len);
1766 value.realloc (len);
1767 for (sal_Int16 i =0; i< len;i++) {
1768 name[i] = attr->getNameByIndex(i);
1769 value[i] = attr -> getValueByIndex(i);
1773 const OUString& Attr::getValueByName (const sal_Char *str) const {
1774 static OUString empty;
1775 sal_Int32 len = name.getLength();
1776 for (sal_Int32 i = 0;i<len;i++)
1777 if (name[i].equalsAscii(str))
1778 return value[i];
1779 return empty;
1782 sal_Int32 Attr::getLength() const{
1783 return name.getLength();
1786 const OUString& Attr::getTypeByIndex (sal_Int32 idx) const {
1787 return name[idx];
1790 const OUString& Attr::getValueByIndex (sal_Int32 idx) const
1792 return value[idx];