~ubuntu-branches/ubuntu/raring/simutrans/raring-proposed

« back to all changes in this revision

Viewing changes to dataobj/loadsave.cc

  • Committer: Bazaar Package Importer
  • Author(s): Ansgar Burchardt
  • Date: 2010-03-12 09:23:35 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312092335-nb88gufrs0nfi4pv
Tags: 102.2.2~ds1-1
* New upstream release.
  + debian/rules: Update get-orig-source target.
  + debian/rules: Add build-dep on libbz2-dev.
  + debian/rules: Bump dependency on simutrans-pak64 to 102.2.1.
    See also #565493.
  + Refresh patches.
* Update translations.
  + debian/rules: Update list of excluded languages.
* Correct spelling errors.
  + new patch: spelling.patch
* Bump Standards-Version to 3.8.4 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
#include <zlib.h>
18
18
 
19
 
loadsave_t::mode_t loadsave_t::save_mode = zipped;      // default to use for saving
 
19
loadsave_t::mode_t loadsave_t::save_mode = bzip2;       // default to use for saving
20
20
 
21
21
loadsave_t::loadsave_t() : filename()
22
22
{
 
23
        mode = 0;
 
24
        saving = false;
23
25
        fp = NULL;
 
26
        bzfp = NULL;
 
27
        bse = BZ_OK+1;
24
28
}
25
29
 
26
30
loadsave_t::~loadsave_t()
33
37
        close();
34
38
 
35
39
        version = 0;
36
 
        fp = (FILE *)gzopen(filename, "rb");
37
 
        if(!fp) {
 
40
        mode = zipped;
 
41
        fp = (FILE *)fopen( filename, "rb" );
 
42
        if(  fp==NULL  ) {
 
43
                // most likely not existing
38
44
                return false;
39
45
        }
40
 
        saving = false;
41
 
 
 
46
        // now check for BZ2 format
42
47
        char buf[80];
43
 
        gzgets(fp, buf, 80);
44
 
        mode = zipped;
 
48
        if(  fread( buf, 1, 80, fp )==80  ) {
 
49
                if(  buf[0]=='B'  &&  buf[1]=='Z'  ) {
 
50
                        mode = bzip2;
 
51
                }
 
52
                fseek(fp,0,SEEK_SET);
 
53
        }
 
54
 
 
55
        if(  mode==bzip2  ) {
 
56
                bse = BZ_OK+1;
 
57
                bzfp = NULL;
 
58
                bzfp = BZ2_bzReadOpen( &bse, fp, 0, 0, NULL, 0 );
 
59
                bool ok = false;
 
60
                if(  bse==BZ_OK  ) {
 
61
                        // else: use zlib
 
62
                        memset( buf, 0, 80 );
 
63
                        if(  BZ2_bzRead( &bse, bzfp, buf, sizeof(SAVEGAME_PREFIX) )==sizeof(SAVEGAME_PREFIX)  &&  bse==BZ_OK  ) {
 
64
                                // get the rest of the string
 
65
                                for(  int i=sizeof(SAVEGAME_PREFIX);  buf[i-1]>=32  &&  i<79;  i++  ) {
 
66
                                        buf[i] = lsgetc();
 
67
                                }
 
68
                                ok = bse==BZ_OK;
 
69
                        }
 
70
                }
 
71
                // BZ-Header but wrong data ...
 
72
                if(  !ok  ) {
 
73
                        close();
 
74
                        return false;
 
75
                }
 
76
        }
 
77
 
 
78
        if(  mode!=bzip2  ) {
 
79
                fclose(fp);
 
80
                // and now with zlib ...
 
81
                fp = (FILE *)gzopen(filename, "rb");
 
82
                if(fp==NULL) {
 
83
                        return false;
 
84
                }
 
85
                gzgets(fp, buf, 80);
 
86
        }
 
87
        saving = false;
45
88
 
46
89
        if(strncmp(buf, SAVEGAME_PREFIX, sizeof(SAVEGAME_PREFIX) - 1)) {
47
90
                if(strncmp(buf, XML_SAVEGAME_PREFIX, sizeof(XML_SAVEGAME_PREFIX)-1)!=0) {
82
125
                                *s++ = c;
83
126
                        }
84
127
                        *s = 0;
85
 
                        while(  lsgetc()!='>'  );
 
128
                        while(  lsgetc()!='>'  )  ;
86
129
                }
87
130
        }
88
131
        else {
93
136
                dbg->error("loadsave_t::rd_open()","text mode no longer supported." );
94
137
                return false;
95
138
        }
96
 
        mode |= zipped;
97
139
 
98
 
        /*
99
 
        if(mode != zipped) {
100
 
                gzclose(fp);
101
 
                fp = fopen(filename, "rb");
102
 
                fgets(buf, 80, fp);
103
 
        }
104
 
        */
105
140
        if(*pak_extension==0) {
106
141
                strcpy( pak_extension, "(unknown)" );
107
142
        }
116
151
        mode = m;
117
152
        close();
118
153
 
119
 
        if(  mode & zipped  ) {
 
154
        if(  is_zipped()  ) {
 
155
                // using zlib
120
156
                fp = (FILE *)gzopen(filename, "wb");
121
157
        }
122
 
        else if(  mode & binary ) {
123
 
                fp = fopen(filename, "wb");
 
158
        else if(  mode==binary  ) {
 
159
                // no compression
 
160
                fp = fopen(filename, "wb");
 
161
        }
 
162
        else if(  is_bzip2()  ) {
 
163
                // XML or bzip ...
 
164
                fp = fopen(filename, "wb");
 
165
                // the additional magic for bzip2
 
166
                bse = BZ_OK+1;
 
167
                bzfp = NULL;
 
168
                if(  fp  ) {
 
169
                        bzfp = BZ2_bzWriteOpen( &bse, fp, 9, 0, 30 /* default is 30 */ );
 
170
                        if(  bse!=BZ_OK  ) {
 
171
                                return false;
 
172
                        }
 
173
                }
124
174
        }
125
175
        else {
126
 
                fp = fopen(filename, "w");
 
176
                // uncompressed xml should be here ...
 
177
                assert(  mode==xml  );
 
178
                fp = fopen(filename, "wb");
127
179
        }
128
180
 
129
181
        if(!fp) {
147
199
        // delete trailing path seperator
148
200
        this->pak_extension[strlen(this->pak_extension)-1] = 0;
149
201
 
 
202
        version = int_version(SAVEGAME_VER_NR, NULL, NULL );
 
203
 
150
204
        if(  !is_xml()  ) {
151
 
                if(is_zipped()) {
152
 
                        gzprintf(fp, "%s%s%s\n", SAVEGAME_VERSION, "zip", this->pak_extension);
 
205
                char str[4096];
 
206
                size_t len;
 
207
                if(  version<=102002  ) {
 
208
                        len = sprintf( str, "%s%s%s\n", SAVEGAME_VERSION, "zip", this->pak_extension );
153
209
                }
154
210
                else {
155
 
                        fprintf(fp, "%s%s%s\n", SAVEGAME_VERSION, mode == binary ? "bin" : "", this->pak_extension);
 
211
                        len = sprintf( str, "%s-%s\n", SAVEGAME_VERSION, this->pak_extension );
156
212
                }
 
213
                write( str, len );
157
214
        }
158
215
        else {
159
216
                char str[4096];
162
219
                ident = 1;
163
220
        }
164
221
 
165
 
        version = int_version(SAVEGAME_VER_NR, NULL, NULL );
166
222
        this->mode = mode;
167
223
        this->filename = filename;
168
224
 
174
230
{
175
231
        const char *success = NULL;
176
232
        if(fp != NULL) {
177
 
                if(  is_xml()  ) {
 
233
                if(  is_xml()  &&  saving  &&  fp!=NULL  &&  (!is_bzip2()  ||  bse==BZ_OK)  ) {
 
234
                        // only write when close and no error occurred
178
235
                        const char *end = "\n</Simutrans>\n";
179
236
                        write( end, strlen(end) );
180
237
                }
186
243
                        }
187
244
                        gzclose(fp);
188
245
                }
 
246
                else if(  is_bzip2()  ) {
 
247
                        if(   saving  ) {
 
248
                                BZ2_bzWriteClose( &bse, bzfp, 0, NULL, NULL );
 
249
                        }
 
250
                        else {
 
251
                                BZ2_bzReadClose( &bse, bzfp );
 
252
                        }
 
253
                        fclose( fp );
 
254
                        bzfp = fp = NULL;
 
255
                        bse = BZ_STREAM_END;
 
256
                }
189
257
                else {
190
258
                        int err_no = ferror(fp);
191
259
                        fclose(fp);
199
267
}
200
268
 
201
269
 
 
270
/************* from here on the actual data in/out routines ****************/
 
271
 
202
272
/**
203
273
 * Checks end-of-file
204
274
 * @author Hj. Malthaner
205
275
 */
206
276
bool loadsave_t::is_eof()
207
277
{
208
 
        if(is_zipped()) {
 
278
        if(is_bzip2()) {
 
279
                // any error is EOF ...
 
280
                return bse!=BZ_OK;
 
281
        }
 
282
        else {
209
283
                return gzeof(fp) != 0;
210
284
        }
211
 
        else {
212
 
                return feof(fp) != 0;
213
 
        }
214
285
}
215
286
 
216
287
 
217
 
int loadsave_t::lsputc(int c)
 
288
void loadsave_t::lsputc(int c)
218
289
{
219
290
        if(is_zipped()) {
220
 
                return gzputc(fp, c);
 
291
                gzputc(fp, c);
 
292
        }
 
293
        else if(is_bzip2()) {
 
294
                uint8 ch = c;
 
295
                write( &ch, 1 );
221
296
        }
222
297
        else {
223
 
                return fputc(c, fp);
 
298
                fputc(c, fp);
224
299
        }
225
300
}
226
301
 
227
302
int loadsave_t::lsgetc()
228
303
{
229
 
        if(is_zipped()) {
 
304
        if(is_bzip2()) {
 
305
                uint8 c[2];
 
306
                if(  bse==BZ_OK  ) {
 
307
                        BZ2_bzRead( &bse, bzfp, c, 1);
 
308
                }
 
309
                return bse==BZ_OK ? c[0] : -1;
 
310
        }
 
311
        else {
230
312
                return gzgetc(fp);
231
313
        }
232
 
        else {
233
 
                return fgetc(fp);
234
 
        }
235
314
}
236
315
 
237
316
long loadsave_t::write(const void *buf, size_t len)
239
318
        if(is_zipped()) {
240
319
                return gzwrite(fp, const_cast<void *>(buf), len);
241
320
        }
 
321
        else if(is_bzip2()) {
 
322
                BZ2_bzWrite( &bse, bzfp, const_cast<void *>(buf), len);
 
323
                assert(bse==BZ_OK);
 
324
                return (long)len;
 
325
        }
242
326
        else {
243
327
                return (long)fwrite(buf, 1, len, fp);
244
328
        }
246
330
 
247
331
long loadsave_t::read(void *buf, size_t len)
248
332
{
249
 
        if(is_zipped()) {
 
333
        if(is_bzip2()) {
 
334
                if(  bse==BZ_OK  ) {
 
335
                        BZ2_bzRead( &bse, bzfp, const_cast<void *>(buf), len);
 
336
                }
 
337
                // little trick: zero if not ok ...
 
338
                return (long)len&~(bse-BZ_OK);
 
339
        }
 
340
        else {
250
341
                return gzread(fp, buf, len);
251
342
        }
252
 
        else {
253
 
                return (long)fread(buf, 1, len, fp);
254
 
        }
255
343
}
256
344
 
257
345
 
258
 
/* read data types (should check also for Intel/Motorola) etc */
 
346
/*************** High level routines to read/write data types *************
 
347
 * (check also for Intel/Motorola) etc
 
348
 */
 
349
 
 
350
 
 
351
 
259
352
void loadsave_t::rdwr_byte(sint8 &c, const char *)
260
353
{
261
354
        if(!is_xml()) {
281
374
}
282
375
 
283
376
 
284
 
/* shorts */
285
377
void loadsave_t::rdwr_short(sint16 &i, const char *)
286
378
{
287
379
        if(!is_xml()) {
319
411
}
320
412
 
321
413
 
322
 
/* long words*/
323
414
void loadsave_t::rdwr_long(sint32 &l, const char *)
324
415
{
325
416
        if(!is_xml()) {
356
447
        l = (uint32)ll;
357
448
}
358
449
 
359
 
/* long long (64 Bit) */
 
450
 
360
451
void loadsave_t::rdwr_longlong(sint64 &ll, const char *)
361
452
{
362
453
        if(!is_xml()) {
384
475
        }
385
476
}
386
477
 
387
 
 
388
 
 
389
478
void loadsave_t::rdwr_double(double &dbl)
390
479
{
391
480
        if(!is_xml()) {
405
494
}
406
495
 
407
496
 
408
 
 
409
497
void loadsave_t::rdwr_bool(bool &i, const char *)
410
498
{
411
499
        if(  !is_xml()  ) {
417
505
                }
418
506
        }
419
507
        else {
420
 
                // boll xml
 
508
                // bool xml
421
509
                if(saving) {
422
 
                        if(is_zipped()) {
423
 
                                gzprintf(fp, "%*s<bool>%s</bool>\n", ident, "", i ? "true" : "false" );
 
510
                        write( "                                                                ", min(64,ident) );
 
511
                        if(  i  ) {
 
512
                                write( "<bool>true</bool>\n", sizeof("<bool>true</bool>\n")-1 );
424
513
                        }
425
514
                        else {
426
 
                                fprintf(fp, "%*s<bool>%s</bool>\n", ident, "", i ? "true" : "false" );
 
515
                                write( "<bool>false</bool>\n", sizeof("<bool>false</bool>\n")-1 );
427
516
                        }
428
517
                }
429
518
                else {
450
539
}
451
540
 
452
541
 
453
 
 
454
542
void loadsave_t::rdwr_xml_number(sint64 &s, const char *typ)
455
543
{
456
544
        if(saving) {
457
545
                static char nr[256];
458
 
                sprintf( nr, "%*s<%s>%.0lf</%s>\n", ident, "", typ, (double)s, typ );
459
 
                this->write( nr, strlen(nr) );
 
546
                size_t len = sprintf( nr, "%*s<%s>%.0f</%s>\n", ident, "", typ, (double)s, typ );
 
547
                write( nr, len );
460
548
        }
461
549
        else {
462
550
                const int len = (int)strlen(typ);
470
558
                if(  strcmp(typ,buffer)!=0  ) {
471
559
                        dbg->fatal( "loadsave_t::rdwr_str()","expected \"<%s>\", got \"<%s>\"", typ, buffer );
472
560
                }
473
 
                while(  lsgetc()!='>'  );
 
561
                while(  lsgetc()!='>'  )  ;
474
562
                // read number;
475
563
                s = 0;
476
564
                bool minus = false;
513
601
                if(  strcmp(typ,buffer)!=0  ) {
514
602
                        dbg->fatal( "loadsave_t::rdwr_str()","expected \"</%s>\", got \"</%s>\"", typ, buffer );
515
603
                }
516
 
                while(  lsgetc()!='>'  );
 
604
                while(  lsgetc()!='>'  )  ;
517
605
        }
518
606
}
519
607
 
520
608
 
521
 
 
522
 
 
523
609
// s is a malloc-ed string (will be freed and newly allocated on load time!)
524
610
void loadsave_t::rdwr_str(const char *&s)
525
611
{
564
650
        else {
565
651
                // use CDATA tag: <![CDATA[%s]]>
566
652
                if(saving) {
567
 
                        const char *str = s ? s: "";
568
 
                        if(is_zipped()) {
569
 
                                gzprintf(fp, "%*s<![CDATA[%s]]>\n", ident, "", str );
570
 
                        }
571
 
                        else {
572
 
                                fprintf(fp, "%*s<![CDATA[%s]]>\n", ident, "", str );
573
 
                        }
 
653
                        write( "                                                                ", min(64,ident) );
 
654
                        write( "<![CDATA[", 9 );
 
655
                        if(s) {
 
656
                                write( s, strlen(s) );
 
657
                        }
 
658
                        write( "]]>\n", 4 );
574
659
                }
575
660
                else {
576
661
                        char buffer[4096];
584
669
}
585
670
 
586
671
 
587
 
 
588
672
// read a string into a preallocated buffer
589
673
void loadsave_t::rdwr_str(char *s, int size)
590
674
{
617
701
        else {
618
702
                // use CDATA tag: <![CDATA[%s]]>
619
703
                if(saving) {
620
 
                        const char *str = s ? s: "";
621
 
                        if(is_zipped()) {
622
 
                                gzprintf(fp, "%*s<![CDATA[%s]]>\n", ident, "", str );
623
 
                        }
624
 
                        else {
625
 
                                fprintf(fp, "%*s<![CDATA[%s]]>\n", ident, "", str );
626
 
                        }
 
704
                        write( "                                                                ", min(64,ident) );
 
705
                        write( "<![CDATA[", 9 );
 
706
                        if(s) {
 
707
                                write( s, strlen(s) );
 
708
                        }
 
709
                        write( "]]>\n", 4 );
627
710
                }
628
711
                else {
629
712
                        // find start of tag
659
742
                                *s = 0;
660
743
                                // go until closing
661
744
                                if(  ptr==0  ||  *ptr!=0  ) {
662
 
                                        while(  lsgetc()!='>'  );
 
745
                                        while(  lsgetc()!='>'  )  ;
663
746
                                }
664
747
                        }
665
748
                        else {
695
778
}
696
779
 
697
780
 
 
781
void loadsave_t::start_tag(const char *tag)
 
782
{
 
783
        if(  is_xml()  ) {
 
784
                if(saving) {
 
785
                        write( "                                                                ", min(64,ident) );
 
786
                        write( "<", 1 );
 
787
                        write( tag, strlen(tag) );
 
788
                        write( ">\n", 2 );
 
789
                        ident ++;
 
790
                }
 
791
                else {
 
792
                        char buf[256];
 
793
                        const size_t len = strlen(tag);
 
794
                        // find start of tag
 
795
                        while(  lsgetc()!='<'  ) { /* nothing */ }
 
796
                        read( buf, len );
 
797
                        if(  strncmp(buf,tag,len)!=0  ) {
 
798
                                dbg->fatal( "loadsave_t::start_tag()","expected \"%s\", got \"%s\"", tag, buf );
 
799
                        }
 
800
                        while(  lsgetc()!='>'  )  ;
 
801
                }
 
802
        }
 
803
}
 
804
 
 
805
 
 
806
void loadsave_t::end_tag(const char *tag)
 
807
{
 
808
        if(  is_xml()  ) {
 
809
                if(saving) {
 
810
                        ident --;
 
811
                        write( "                                                                ", min(64,ident) );
 
812
                        write( "</", 2 );
 
813
                        write( tag, strlen(tag) );
 
814
                        write( ">\n", 2 );
 
815
                }
 
816
                else {
 
817
                        // just use start tag with the end character ...
 
818
                        char buf[256];
 
819
                        tstrncpy( buf+1, tag, 254 );
 
820
                        buf[0] = '/';
 
821
                        start_tag(buf);
 
822
                }
 
823
        }
 
824
}
 
825
 
 
826
 
698
827
void loadsave_t::wr_obj_id(sint16 id)
699
828
{
700
829
        if(saving) {
701
830
                if(!is_xml()) {
702
 
                        uint8 idc = (uint8)id;
703
 
                        write(&idc, sizeof(uint8));
 
831
                        lsputc( id );
704
832
                }
705
833
                else {
706
834
                        sint64 ll=id;
733
861
{
734
862
        if(saving) {
735
863
                if(  !is_xml()  ) {
736
 
                        if(is_zipped()) {
737
 
                                gzprintf(fp, "%s\n", id_text);
738
 
                        }
739
 
                        else {
740
 
                                fprintf(fp, "%s\n", id_text);
741
 
                        }
 
864
                        write( id_text, strlen(id_text) );
 
865
                        lsputc( 10 );
742
866
                }
743
867
                else {
744
 
                        if(is_zipped()) {
745
 
                                gzprintf(fp, "<id=\"%s\"/>\n", id_text);
746
 
                        }
747
 
                        else {
748
 
                                fprintf(fp, "<id=\"%s\"/>\n", id_text);
749
 
                        }
 
868
                        write( "<id=\"", 5 );
 
869
                        write( id_text, strlen(id_text) );
 
870
                        write( "\">\n", 3 );
750
871
                }
751
872
        }
752
873
}
756
877
{
757
878
        if(!saving) {
758
879
                if(  !is_xml()  ) {
759
 
                        if(is_zipped()) {
760
 
                                gzgets(fp, id_buf, size);
761
 
                        }
762
 
                        else {
763
 
                                fgets(id_buf, size, fp);
764
 
                        }
765
 
                        id_buf[strlen(id_buf) - 1] = '\0';
 
880
                        int i=0;
 
881
                        *id_buf = 0;
 
882
                        while(  i<size  &&  id_buf[i-1]!=10  ) {
 
883
                                id_buf[i++] = lsgetc();
 
884
                        }
 
885
                        id_buf[i-1] = 0;
766
886
                }
767
887
                else {
768
888
                        char buf[6];
793
913
}
794
914
 
795
915
 
796
 
uint32 loadsave_t::int_version(const char *version_text, int *mode, char *pak_extension)
 
916
 
 
917
uint32 loadsave_t::int_version(const char *version_text, int * /*mode*/, char *pak_extension_str)
797
918
{
798
919
        // major number (0..)
799
920
        uint32 v0 = atoi(version_text);
817
938
        uint32 v2 = atoi(version_text);
818
939
        uint32 version = v0 * 1000000 + v1 * 1000 + v2;
819
940
 
820
 
        if(mode) {
821
 
                while(*version_text && *version_text != 'b' && *version_text != 'z') {
822
 
                        version_text++;
823
 
                }
 
941
        while(  isdigit(*version_text)  ) {
 
942
                version_text++;
 
943
        }
 
944
 
 
945
        if(  version<=102002  ) {
 
946
                /* the compression and the mode we determined already ourselves (otherwise we cannot read this
 
947
                 * => leave the mode alone but for unknown modes!
 
948
                 */
824
949
                if(!strncmp(version_text, "bin", 3)) {
825
 
                        *mode = binary;
 
950
                        //*mode = binary;
 
951
                        version_text += 3;
826
952
                }
827
953
                else if(!strncmp(version_text, "zip", 3)) {
828
 
                        *mode = zipped;
829
 
                }
830
 
                else {
831
 
                        *mode = text;
832
 
                }
 
954
                        //*mode = zipped;
 
955
                        version_text += 3;
 
956
                }
 
957
                else if(  *version_text  ) {
 
958
                        // illegal version ...
 
959
                        version = 999999999;
 
960
                }
 
961
        }
 
962
        else {
 
963
                // skip the minus sign
 
964
                if (*version_text=='-') {
 
965
                        version_text++;
 
966
                }
 
967
        }
833
968
 
834
 
                // also pak extension was saved
835
 
                if(version>=99008) {
836
 
                        if(*mode!=text) {
837
 
                                version_text += 3;
838
 
                        }
839
 
                        while(*version_text && *version_text>=32) {
840
 
                                *pak_extension++ = *version_text++;
 
969
        if(  pak_extension_str  ) {
 
970
                if(  *version_text  )  {
 
971
                        // also pak extension was saved
 
972
                        if(version>=99008) {
 
973
                                while(  *version_text>=32  ) {
 
974
                                        *pak_extension_str = *version_text;
 
975
                                        pak_extension_str++;
 
976
                                        version_text++;
 
977
                                }
841
978
                        }
842
979
                }
843
 
                *pak_extension = 0;
 
980
                *pak_extension_str = 0;
844
981
        }
845
982
 
846
983
        return version;
848
985
 
849
986
 
850
987
 
851
 
void loadsave_t::start_tag(const char *tag)
852
 
{
853
 
        if(  is_xml()  ) {
854
 
                if(saving) {
855
 
                        if(is_zipped()) {
856
 
                                gzprintf(fp, "%*s<%s>\n", ident, "", tag);
857
 
                        }
858
 
                        else {
859
 
                                fprintf(fp, "%*s<%s>\n", ident, "", tag);
860
 
                        }
861
 
                        ident ++;
862
 
                }
863
 
                else {
864
 
                        char buf[256];
865
 
                        const size_t len = strlen(tag);
866
 
                        // find start of tag
867
 
                        while(  lsgetc()!='<'  ) { /* nothing */ }
868
 
                        read( buf, len );
869
 
                        if(  strncmp(buf,tag,len)!=0  ) {
870
 
                                dbg->fatal( "loadsave_t::start_tag()","expected \"%s\", got \"%s\"", tag, buf );
871
 
                        }
872
 
                        while(  lsgetc()!='>'  );
873
 
                }
874
 
        }
875
 
}
876
 
 
877
 
 
878
 
void loadsave_t::end_tag(const char *tag)
879
 
{
880
 
        if(  is_xml()  ) {
881
 
                if(saving) {
882
 
                        ident --;
883
 
                        if(is_zipped()) {
884
 
                                gzprintf(fp, "%*s</%s>\n", ident, "", tag);
885
 
                        }
886
 
                        else {
887
 
                                fprintf(fp, "%*s</%s>\n", ident, "", tag);
888
 
                        }
889
 
                }
890
 
                else {
891
 
                        // just use start tag with the end character ...
892
 
                        char buf[256];
893
 
                        tstrncpy( buf+1, tag, 254 );
894
 
                        buf[0] = '/';
895
 
                        start_tag(buf);
896
 
                }
897
 
        }
898
 
}
899
 
 
900