~evan-nelson/armagetronad/armagetronad+pcm

« back to all changes in this revision

Viewing changes to src/tools/tLocale.cpp

Attempting to create a timeout for PLAYER_CENTER_MESSAGE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
*************************************************************************
4
 
 
5
 
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
 
Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
7
 
 
8
 
**************************************************************************
9
 
 
10
 
This program is free software; you can redistribute it and/or
11
 
modify it under the terms of the GNU General Public License
12
 
as published by the Free Software Foundation; either version 2
13
 
of the License, or (at your option) any later version.
14
 
 
15
 
This program is distributed in the hope that it will be useful,
16
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
GNU General Public License for more details.
19
 
 
20
 
You should have received a copy of the GNU General Public License
21
 
along with this program; if not, write to the Free Software
22
 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
 
  
24
 
***************************************************************************
25
 
 
26
 
*/
27
 
 
28
 
#include "tMemManager.h"
29
 
#include "tLocale.h"
30
 
#include "tConsole.h"
31
 
#include "tDirectories.h"
32
 
#include "tSafePTR.h"
33
 
 
34
 
#include <fstream>
35
 
#include <string>
36
 
#include <map>
37
 
 
38
 
class tLocaleSubItem; // identifies a single string in a single language
39
 
 
40
 
static tArray<tString> st_TemplateParameters;
41
 
 
42
 
static tString s_gameName("Armagetron"); // the official name of this game
43
 
 
44
 
class tLocaleItem: public tReferencable< tLocaleItem >    // idendifies a string in all languages
45
 
{
46
 
    friend class tLocaleSubItem;
47
 
 
48
 
    tString identifier;     // the cross-language identifier of this string
49
 
    tLocaleSubItem *items;  // the versions of various languages
50
 
    bool istemplate;        // does it contain \i-directives?
51
 
 
52
 
public:
53
 
    // static void Check();    // display warnings for all strings not defined in
54
 
    // the favorite language
55
 
 
56
 
    //  operator tString() const; // return the version of this string in the favorite language
57
 
    operator const char *() const;
58
 
 
59
 
    tLocaleItem(const char *identifier); // constructor taking the string identifier
60
 
    ~tLocaleItem();
61
 
 
62
 
    static void Load(const char *file, bool complete = true );  // load the language definitions from a file
63
 
 
64
 
    static void Clear();           // clear all locale data on program exit
65
 
 
66
 
    static tLocaleItem& Find(const char *identifier); // find identifier
67
 
};
68
 
 
69
 
 
70
 
static const tLanguage* st_firstLanguage  = NULL;
71
 
static const tLanguage* st_secondLanguage = NULL;
72
 
 
73
 
static tLanguage*      st_languageAnchor = NULL;
74
 
 
75
 
typedef std::map< std::string, tJUST_CONTROLLED_PTR< tLocaleItem > > tLocaleItemMap;
76
 
 
77
 
// static tLocaleItem*    st_localeAnchor   = NULL;
78
 
 
79
 
static tLanguage *currentLanguage = NULL;
80
 
 
81
 
 
82
 
class tLocaleSubItem: public tListItem<tLocaleSubItem>
83
 
{
84
 
public:
85
 
    const tLanguage *language;  // the language this string is in
86
 
    tString translation;        // the string itself
87
 
 
88
 
    tLocaleSubItem(tLocaleItem *item) // adds this SubItem to item
89
 
            : tListItem<tLocaleSubItem>(item->items){}
90
 
};
91
 
 
92
 
 
93
 
 
94
 
tLanguage::tLanguage(const tString& n)
95
 
        :tListItem<tLanguage>(st_languageAnchor),
96
 
        name(n)
97
 
{
98
 
}
99
 
 
100
 
 
101
 
tLanguage* tLanguage::FirstLanguage()
102
 
{
103
 
    return st_languageAnchor;
104
 
}
105
 
 
106
 
void tLanguage::SetFirstLanguage()  const
107
 
{
108
 
    st_firstLanguage = this;
109
 
    Load();
110
 
}
111
 
 
112
 
void tLanguage::SetSecondLanguage() const
113
 
{
114
 
    st_secondLanguage = this;
115
 
    Load();
116
 
}
117
 
 
118
 
void tLanguage::Load() const
119
 
{
120
 
    if (file.Len() > 1)
121
 
    {
122
 
        tLocaleItem::Load( file );
123
 
        file.Clear();
124
 
    }
125
 
}
126
 
 
127
 
void tLanguage::LoadLater( char const * file ) const
128
 
{
129
 
    // store name for later loading
130
 
    this->file = file;
131
 
}
132
 
 
133
 
tLanguage* tLanguage::Find(tString const & name )
134
 
{
135
 
    tLanguage *ret = FindSloppy( name );
136
 
 
137
 
    if (ret)
138
 
        return ret;
139
 
 
140
 
    return tNEW(tLanguage(name));
141
 
}
142
 
 
143
 
tLanguage* tLanguage::FindStrict(tString const & name )
144
 
{
145
 
    tLanguage *ret = FindSloppy( name );
146
 
 
147
 
    if (ret)
148
 
        return ret;
149
 
 
150
 
    tERR_ERROR_INT("Language " << name << " not found.");
151
 
    return NULL;
152
 
}
153
 
 
154
 
tLanguage* tLanguage::FindSloppy(tString const & name )
155
 
{
156
 
    tLanguage *ret = st_languageAnchor;
157
 
    while (ret)
158
 
    {
159
 
        if (ret->name == name)
160
 
            return ret;
161
 
        ret = ret->Next();
162
 
    }
163
 
 
164
 
    return NULL;
165
 
}
166
 
 
167
 
 
168
 
/*
169
 
void tLocaleItem::Check()
170
 
{
171
 
    tLocaleItem *run = st_localeAnchor;
172
 
    while (run)
173
 
    {
174
 
        tLocaleSubItem *r = run->items;
175
 
        bool ok = false;
176
 
        while (r)
177
 
        {
178
 
            if (r->language == currentLanguage)
179
 
                ok = true;
180
 
            r = r->Next();
181
 
        }
182
 
 
183
 
        if (!ok)
184
 
        {
185
 
            //                  con << "Identifier " << run->identifier << " not translated.\n";
186
 
            con << run->identifier << "\n";
187
 
        }
188
 
        run = run->Next();
189
 
    }
190
 
}
191
 
*/
192
 
 
193
 
tLocaleItem::operator const char *() const// return the version of this string in the favorite language
194
 
{
195
 
    static tLanguage * english = tLanguage::FindStrict( tString("British English") );
196
 
 
197
 
    tString *first = NULL, *second = NULL, *third = NULL, *fourth = NULL;
198
 
    const tString *ret = NULL;
199
 
 
200
 
    tLocaleSubItem *run = items;
201
 
    while (run)
202
 
    {
203
 
        if (st_firstLanguage && run->language == st_firstLanguage)
204
 
            first = &run->translation;
205
 
 
206
 
        if (st_secondLanguage && run->language == st_secondLanguage)
207
 
            second = &run->translation;
208
 
 
209
 
        if (run->language == english)
210
 
            third = &run->translation;
211
 
 
212
 
        fourth = &run->translation;
213
 
        run = run->Next();
214
 
    }
215
 
 
216
 
    if (first)
217
 
        ret = first;
218
 
    else if (second)
219
 
        ret = second;
220
 
    else
221
 
    {
222
 
        if (third)
223
 
            ret = third;
224
 
        else
225
 
        {
226
 
            // load english and try again
227
 
            static bool loadEnglish = true;
228
 
            if ( loadEnglish )
229
 
            {
230
 
                loadEnglish = false;
231
 
                english->Load();
232
 
                return *this;
233
 
            }
234
 
        }
235
 
 
236
 
        if (!ret && fourth)
237
 
            ret = fourth;
238
 
        if (!ret)
239
 
            ret = &identifier;
240
 
    }
241
 
 
242
 
    if (!istemplate)
243
 
        return *ret;   // no template replacements need to be made
244
 
    else
245
 
    {
246
 
        const tString& temp = *ret;
247
 
        static tString        replaced;
248
 
        replaced.Clear();
249
 
        for(int i = 0; i < temp.Len(); i++)
250
 
        {
251
 
            char c = temp(i);
252
 
            if (c != '\\')
253
 
                replaced += c;
254
 
            else if (i < temp.Len() - 1)
255
 
            {
256
 
                c = temp(i+1);
257
 
                if (c == 'g')
258
 
                    replaced << s_gameName;
259
 
                else
260
 
                {
261
 
                    int index = c-'0';
262
 
                    if (index > 0 && index < 10)
263
 
                        replaced << st_TemplateParameters[index];
264
 
                    else if (temp(i+1) == '\\')
265
 
                        replaced << '\n';
266
 
                }
267
 
                i++;
268
 
            }
269
 
        }
270
 
 
271
 
        return replaced;
272
 
    }
273
 
}
274
 
 
275
 
 
276
 
tLocaleItem::tLocaleItem(const char *id) // constructor taking the string identifier
277
 
//:tListItem<tLocaleItem>(st_localeAnchor),
278
 
        :identifier(id), items(NULL), istemplate(false)
279
 
{
280
 
}
281
 
 
282
 
tLocaleItem::~tLocaleItem()
283
 
{
284
 
    while (items)
285
 
        delete (items);
286
 
}
287
 
 
288
 
 
289
 
void tLocaleItem::Clear()
290
 
{
291
 
    //while (st_localeAnchor)
292
 
    //    delete (st_localeAnchor);
293
 
 
294
 
    while (st_languageAnchor)
295
 
        delete (st_languageAnchor);
296
 
}
297
 
 
298
 
 
299
 
tLocaleItem& tLocaleItem::Find(const char *nn)
300
 
{
301
 
    /*
302
 
    tLocaleItem *ret = st_localeAnchor;
303
 
     tString n(nn);
304
 
 
305
 
    while (ret)
306
 
    {
307
 
        if (ret->identifier == n)
308
 
            return *ret;
309
 
        ret = ret->Next();
310
 
    }
311
 
 
312
 
 
313
 
    return *tNEW(tLocaleItem(n));
314
 
    */
315
 
    static tLocaleItemMap    st_localeMap;
316
 
 
317
 
    tJUST_CONTROLLED_PTR< tLocaleItem > & ret = st_localeMap[ nn ];
318
 
 
319
 
    if ( !ret )
320
 
        ret = tNEW(tLocaleItem(nn));
321
 
 
322
 
    return *ret;
323
 
}
324
 
 
325
 
static const tString LANGUAGE("language");
326
 
static const tString INCLUDE("include");
327
 
// static const tString CHECK("check");
328
 
 
329
 
void tLocaleItem::Load(const char *file, bool complete)  // load the language definitions from a file
330
 
{
331
 
    // bool check = false;
332
 
    {
333
 
        tString f;
334
 
 
335
 
        f <<  "language/" << file;
336
 
 
337
 
        std::ifstream s;
338
 
        if ( tDirectories::Data().Open( s, f ) )
339
 
        {
340
 
            while (!s.eof() && s.good())
341
 
            {
342
 
                tString id;
343
 
                s >> id;
344
 
 
345
 
                if (id.Len() <= 1 )
346
 
                {
347
 
                    continue;
348
 
                }
349
 
 
350
 
                if(id[0] == '#')
351
 
                {
352
 
                    tString dummy;
353
 
                    dummy.ReadLine(s);
354
 
                    continue;
355
 
                }
356
 
 
357
 
                if (LANGUAGE == id)
358
 
                {
359
 
                    tString lang;
360
 
                    lang.ReadLine(s);
361
 
                    currentLanguage = tLanguage::Find(lang);
362
 
 
363
 
                    // delayed loading
364
 
                    if (!complete)
365
 
                    {
366
 
                        currentLanguage->LoadLater(file);
367
 
                        return;
368
 
                    }
369
 
                    continue;
370
 
                }
371
 
 
372
 
                if (INCLUDE == id)
373
 
                {
374
 
                    tString inc;
375
 
                    inc.ReadLine(s);
376
 
                    Load(inc, complete);
377
 
                    continue;
378
 
                }
379
 
 
380
 
                /*
381
 
                if (CHECK == id)
382
 
                {
383
 
                    check = true;
384
 
                    tString dummy;
385
 
                    dummy.ReadLine(s);
386
 
                    continue;
387
 
                }
388
 
                */
389
 
 
390
 
                // id is a true string identifier.
391
 
                tLocaleItem &li = Find(id);
392
 
                tLocaleSubItem *r = li.items;
393
 
                bool done = false;
394
 
                while (r && !done)
395
 
                {
396
 
                    if (r->language == currentLanguage)
397
 
                    {
398
 
                        // r->translation.ReadLine(s);
399
 
                        done = true;
400
 
                        continue;
401
 
                    }
402
 
                    r = r->Next();
403
 
                }
404
 
 
405
 
                if (!done)
406
 
                    r = tNEW(tLocaleSubItem)(&li);
407
 
                else
408
 
                {
409
 
                    // st_Breakpoint();
410
 
                    // con << "Locale item " << id << " defined twice in language "
411
 
                    // << currentLanguage->Name() << ".\n";
412
 
                }
413
 
 
414
 
                tString pre;
415
 
                pre.ReadLine(s);
416
 
                r->translation.Clear();
417
 
 
418
 
                for (int i=0; i< pre.Len(); i++)
419
 
                {
420
 
                    char c = pre(i);
421
 
                    if (c != '\\')
422
 
                        r->translation += c;
423
 
                    else if (i < pre.Len()-1)
424
 
                        switch (pre(i+1))
425
 
                        {
426
 
                        case 'n':
427
 
                            r->translation += '\n';
428
 
                            i++;
429
 
                            break;
430
 
 
431
 
                        case '1':
432
 
                        case '2':
433
 
                        case '3':
434
 
                        case '4':
435
 
                        case '5':
436
 
                        case '6':
437
 
                        case '7':
438
 
                        case '8':
439
 
                        case '9':
440
 
                        case 'g':
441
 
                            r->translation += '\\';
442
 
                            li.istemplate = true;
443
 
                            break;
444
 
 
445
 
                            /*
446
 
                                         case '\\':
447
 
                                         r->translation << "\\\\";
448
 
                                         i++;
449
 
                            */
450
 
 
451
 
                        default:
452
 
                            r->translation += '\\';
453
 
                            break;
454
 
                        }
455
 
                }
456
 
 
457
 
                r->language = currentLanguage;
458
 
                //      r->translation.ReadLine(s);
459
 
 
460
 
 
461
 
            }
462
 
        }
463
 
    }
464
 
 
465
 
    /*
466
 
    if (check)
467
 
        Check();
468
 
    */
469
 
}
470
 
 
471
 
class tOutputItemLocale: public tOutputItemBase
472
 
{
473
 
    const tLocaleItem *element;
474
 
public:
475
 
    tOutputItemLocale(tOutput& o, const tLocaleItem& e);
476
 
    virtual void Print(tString& target) const;
477
 
    virtual void Clone(tOutput& o)      const;
478
 
};
479
 
 
480
 
class tOutputItemSpace: public tOutputItemBase
481
 
{
482
 
public:
483
 
    tOutputItemSpace(tOutput& o);
484
 
    virtual void Print(tString& target) const;
485
 
    virtual void Clone(tOutput& o)      const;
486
 
};
487
 
 
488
 
 
489
 
class tOutputItemTemplate: public tOutputItemBase
490
 
{
491
 
    int       num;
492
 
    tString   parameter;
493
 
public:
494
 
    tOutputItemTemplate(tOutput& o, int n, const char *p);
495
 
    virtual void Print(tString& target) const;
496
 
    virtual void Clone(tOutput& o)      const;
497
 
};
498
 
 
499
 
 
500
 
tOutput::tOutput(): anchor(0){}
501
 
tOutput::~tOutput()
502
 
{
503
 
    while (anchor)
504
 
        delete anchor;
505
 
}
506
 
 
507
 
void tOutput::Clear()
508
 
{
509
 
    while (anchor)
510
 
        delete anchor;
511
 
}
512
 
 
513
 
 
514
 
static void getstring(tString &target, tOutputItemBase *item)
515
 
{
516
 
    if (!item)
517
 
        return;
518
 
    getstring(target, item->Next());
519
 
    item->Print(target);
520
 
}
521
 
 
522
 
/*
523
 
tOutput::operator tString() const
524
 
{
525
 
#ifdef DEBUG
526
 
#ifndef WIN32
527
 
        static bool recursion = false;
528
 
        if (recursion)
529
 
    {
530
 
                tERR_ERROR_INT("Locale Recursion!");
531
 
    }
532
 
        recursion = true;
533
 
#endif
534
 
#endif
535
 
 
536
 
        static tString x;
537
 
        x.Clear();
538
 
        getstring(x, anchor);
539
 
 
540
 
#ifdef DEBUG
541
 
#ifndef WIN32
542
 
        recursion = false;
543
 
#endif
544
 
#endif
545
 
 
546
 
        return x;
547
 
}
548
 
*/
549
 
 
550
 
tOutput::operator const char *() const
551
 
{
552
 
#ifdef DEBUG
553
 
#ifndef WIN32
554
 
    static bool recursion = false;
555
 
    if (recursion)
556
 
    {
557
 
        tERR_ERROR_INT("Locale Recursion!");
558
 
    }
559
 
    recursion = true;
560
 
#endif
561
 
#endif
562
 
 
563
 
    // get a relatively safe buffer to write to
564
 
    static const int maxstrings = 5;
565
 
    static int current = 0;
566
 
    static tString buffers[maxstrings];
567
 
    tString & x = buffers[current];
568
 
    current = ( current + 1 ) % maxstrings;
569
 
 
570
 
    x.Clear();
571
 
    getstring(x, anchor);
572
 
 
573
 
#ifdef DEBUG
574
 
#ifndef WIN32
575
 
    recursion = false;
576
 
#endif
577
 
#endif
578
 
 
579
 
    return x;
580
 
}
581
 
 
582
 
 
583
 
void tOutput::AddLiteral(const char *x)
584
 
{
585
 
    tNEW(tOutputItem<tString>)(*this, tString(x));
586
 
}
587
 
 
588
 
void tOutput::AddSpace()
589
 
{
590
 
    tNEW(tOutputItemSpace)(*this);
591
 
}
592
 
 
593
 
void tOutput::AddLocale(const char *x)
594
 
{
595
 
    tNEW(tOutputItemLocale)(*this, tLocale::Find(x));
596
 
}
597
 
 
598
 
 
599
 
tOutput & tOutput::SetTemplateParameter(int num, const char *parameter)
600
 
{
601
 
    tNEW(tOutputItemTemplate)(*this, num, parameter);
602
 
    return *this;
603
 
}
604
 
 
605
 
tOutput &  tOutput::SetTemplateParameter(int num, int parameter)
606
 
{
607
 
    tString p;
608
 
    p << parameter;
609
 
    tNEW(tOutputItemTemplate)(*this, num, p);
610
 
 
611
 
    return *this;
612
 
}
613
 
 
614
 
tOutput & tOutput::SetTemplateParameter(int num, float parameter)
615
 
{
616
 
    tString p;
617
 
    p << parameter;
618
 
    tNEW(tOutputItemTemplate)(*this, num, p);
619
 
 
620
 
    return *this;
621
 
}
622
 
 
623
 
 
624
 
tOutput::tOutput(const tString& x)
625
 
        :anchor(NULL)
626
 
{
627
 
    tNEW(tOutputItem<tString>)(*this, x);
628
 
}
629
 
 
630
 
tOutput::tOutput(const char * x)
631
 
        :anchor(NULL)
632
 
{
633
 
    *this << x;
634
 
}
635
 
 
636
 
 
637
 
tOutput::tOutput(const tLocaleItem &locale)
638
 
        :anchor(NULL)
639
 
{
640
 
    tNEW(tOutputItemLocale)(*this, locale);
641
 
}
642
 
 
643
 
 
644
 
static void copyrec(tOutput &targ, tOutputItemBase *it)
645
 
{
646
 
    if (!it)
647
 
        return;
648
 
 
649
 
    copyrec(targ, it->Next());
650
 
    it->Clone(targ);
651
 
}
652
 
 
653
 
tOutput::tOutput(const tOutput &o)
654
 
        :anchor(NULL)
655
 
{
656
 
    copyrec(*this, o.anchor);
657
 
}
658
 
 
659
 
tOutput& tOutput::operator=(const tOutput &o)
660
 
{
661
 
    Clear();
662
 
 
663
 
    copyrec(*this, o.anchor);
664
 
 
665
 
    return *this;
666
 
}
667
 
 
668
 
void tOutput::Append(const tOutput &o)
669
 
{
670
 
    copyrec(*this, o.anchor);
671
 
}
672
 
 
673
 
 
674
 
tOutputItemBase::tOutputItemBase(tOutput& o): tListItem<tOutputItemBase>(o.anchor){}
675
 
 
676
 
tOutputItemBase::~tOutputItemBase(){}
677
 
 
678
 
 
679
 
 
680
 
tOutputItemLocale::tOutputItemLocale(tOutput& o, const tLocaleItem& e)
681
 
        :tOutputItemBase(o),
682
 
        element(&e)
683
 
{
684
 
}
685
 
 
686
 
void tOutputItemLocale::Print(tString& target) const
687
 
{
688
 
    target << *element;
689
 
}
690
 
 
691
 
void tOutputItemLocale::Clone(tOutput& o)      const
692
 
{
693
 
    tNEW(tOutputItemLocale)(o, *element);
694
 
}
695
 
 
696
 
 
697
 
tOutputItemSpace::tOutputItemSpace(tOutput& o)
698
 
        :tOutputItemBase(o)
699
 
{}
700
 
 
701
 
void tOutputItemSpace::Print(tString& target) const
702
 
{
703
 
    target << ' ';
704
 
}
705
 
 
706
 
void tOutputItemSpace::Clone(tOutput& o)      const
707
 
{
708
 
    tNEW(tOutputItemSpace)(o);
709
 
}
710
 
 
711
 
 
712
 
tOutputItemTemplate::tOutputItemTemplate(tOutput& o, int n, const char *p)
713
 
        :tOutputItemBase(o), num(n), parameter(p)
714
 
{}
715
 
 
716
 
void tOutputItemTemplate::Print(tString& target) const
717
 
{
718
 
    st_TemplateParameters[num] = parameter;
719
 
}
720
 
 
721
 
void tOutputItemTemplate::Clone(tOutput& o)      const
722
 
{
723
 
    tNEW(tOutputItemTemplate)(o, num, parameter);
724
 
}
725
 
 
726
 
 
727
 
tOutput& operator << (tOutput &o, char *locale)
728
 
{
729
 
    return operator<<(o, static_cast<const char *>(locale));
730
 
}
731
 
 
732
 
// and a special implementation for the locales and strings:
733
 
tOutput& operator << (tOutput &o, const char *locale){
734
 
    int len = strlen(locale);
735
 
    if (len == 0)
736
 
        return o;
737
 
    if (len == 1 && locale[0] == ' ')
738
 
        tNEW(tOutputItemSpace)(o);
739
 
    else if (locale[0] == '$')
740
 
        tNEW(tOutputItemLocale)(o, tLocale::Find(locale+1));
741
 
    else
742
 
        tNEW(tOutputItem<tString>)(o, tString(locale));
743
 
 
744
 
    return o;
745
 
}
746
 
 
747
 
// output operators
748
 
std::ostream& operator<< (std::ostream& s, const tOutput& o)
749
 
{
750
 
    return s << tString(o);
751
 
}
752
 
 
753
 
/*
754
 
std::stringstream& operator<< (std::stringstream& s, const tOutput& o)
755
 
{
756
 
        static_cast<std::ostream&>(s) << static_cast<const char *>(o);
757
 
        return s;
758
 
}
759
 
*/
760
 
 
761
 
tString& operator<< (tString& s, const tOutput& o)
762
 
{
763
 
    s << tString(o);
764
 
    return s;
765
 
}
766
 
 
767
 
 
768
 
 
769
 
// interface class for locale items
770
 
const tLocaleItem& tLocale::Find(const char* id)
771
 
{
772
 
    return tLocaleItem::Find(id);
773
 
}
774
 
 
775
 
void               tLocale::Load(const char* filename)
776
 
{
777
 
    tLocaleItem::Load(filename, false);
778
 
 
779
 
    // determine the name of the game
780
 
    s_gameName.Clear();
781
 
    s_gameName << tOutput("$game_name");
782
 
}
783
 
 
784
 
void               tLocale::Clear()
785
 
{
786
 
    tLocaleItem::Clear();
787
 
}
788
 
 
789
 
/*
790
 
std::stringstream& operator<<(std::stringstream& s, const tLocaleItem &t)
791
 
{
792
 
        static_cast<std::ostream&>(s) << static_cast<const char*>(t);
793
 
        return s;
794
 
}
795
 
*/
796
 
 
797
 
std::ostream& operator<<(std::ostream& s, const tLocaleItem &t)
798
 
{
799
 
    return s << static_cast<const char*>(t);
800
 
}
801
 
 
802
 
tString& operator<< (tString& s, const tLocaleItem& o)
803
 
{
804
 
    s << static_cast<const char *>(o);
805
 
    return s;
806
 
}