source: issm/trunk-jpl/src/c/objects/KML/KMLFileReadUtils.cpp@ 12365

Last change on this file since 12365 was 12365, checked in by Mathieu Morlighem, 13 years ago

Do not number folds (folding is automated)

File size: 16.1 KB
RevLine 
[8206]1/*!\file KMLFileUtils.cpp
2 * \brief: utilities for kml file reading.
3 */
4
5/*Headers:*/
[12365]6/*{{{*/
[8206]7#ifdef HAVE_CONFIG_H
[9320]8 #include <config.h>
[8206]9#else
10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11#endif
12
[9320]13#include <stdio.h>
[8206]14#include <string.h>
15#include "../objects.h"
16#include "../../shared/shared.h"
[9761]17#include "../../io/io.h"
[8206]18#include "../../Container/Container.h"
19#include "../../include/include.h"
20/*}}}*/
21
[12365]22/*FUNCTION KMLFileToken(FILE* fid,int* pncom=NULL,char*** ppcom=NULL) {{{*/
[10840]23char* KMLFileToken(FILE* fid,
24 int* pncom=NULL,char*** ppcom=NULL){
[8206]25
[10627]26/* get the next token (tag or field) in the file */
27
[8206]28 bool inew=1,itag=0,ifield=0;
29 int c;
30 int ibuf=0,buflen=1024,bufblk=1024;
[10627]31 char *buffer=NULL,*bufferc=NULL;
[8206]32
33 buffer=(char *) xmalloc(buflen*sizeof(char));
34 buffer[0]='\0';
35
[10627]36/* read kml file character-by-character */
[8206]37
38// note that fgets includes newline
39// fgets(buffer,buflen,fid);
40
41 while ((c=getc(fid)) != EOF) {
42 /* ignore leading blanks */
43 if (inew && isspace(c))
44 continue;
45
46 /* distinguish between tag or field */
47 if (!itag && !ifield) {
[10627]48
49 /* distinguish between tag or comment */
50 if (c == '<') {
51 ungetc(c,fid);
52 if (!(bufferc=KMLFileTokenComment(fid))) {
53 c=getc(fid);
54 itag=1;
55 }
56 else {
[10840]57 if (pncom && ppcom) {
58 (*pncom)++;
59 *ppcom=(char **) xrealloc(*ppcom,*pncom*sizeof(char*));
60 (*ppcom)[*pncom-1]=bufferc;
61 }
62 else
63 xfree((void**)&bufferc);
[10627]64 inew=1;
65 continue;
66 }
67 }
[8206]68 else
69 ifield=1;
70 inew=0;
71 KMLFileTokenBuffer(&buffer,&ibuf,&buflen,
72 c,
73 bufblk);
74 }
75
76 /* accumulate tag, not including newlines */
77 else if (itag) {
78 if (c != '\n') {
79 inew=0;
80 KMLFileTokenBuffer(&buffer,&ibuf,&buflen,
81 c,
82 bufblk);
83 if (c == '>')
84 break;
85 }
86 else
87 inew=1;
88 }
89
90 /* accumulate field, including newlines */
91 else if (ifield) {
[10840]92 /* distinguish between another tag or comment */
[8206]93 if (c == '<') {
94 ungetc(c,fid);
[10627]95 if (!(bufferc=KMLFileTokenComment(fid)))
96 break;
97 else
[10840]98 if (pncom && ppcom) {
99 (*pncom)++;
100 *ppcom=(char **) xrealloc(*ppcom,*pncom*sizeof(char*));
101 (*ppcom)[*pncom-1]=bufferc;
102 }
103 else
104 xfree((void**)&bufferc);
[8206]105 }
106 else {
107 inew=0;
108 KMLFileTokenBuffer(&buffer,&ibuf,&buflen,
109 c,
110 bufblk);
111 if (c == '\n')
112 inew=1;
113 }
114 }
115
116 }
117
118/* remove trailing blanks or newline */
119
120 while (ibuf > 0)
121 if (isspace(buffer[ibuf-1]))
122 ibuf--;
123 else {
124 buffer[ibuf]='\0';
125 break;
126 }
127
[10629]128// if (itag)
129// _printf_(true,"tag buffer (length=%d):\n",ibuf);
130// else if (ifield)
131// _printf_(true,"field buffer (length=%d):\n",ibuf);
132// _printf_(true,"%s\n",buffer);
[8206]133
134 if (!ibuf)
135 xfree((void**)&buffer);
136
137 return(buffer);
138}
139/*}}}*/
140
[12365]141/*FUNCTION KMLFileTokenComment(FILE* fid) {{{*/
[10627]142char* KMLFileTokenComment(FILE* fid){
143
144/* check for comment in the file and read it */
145
146 bool inew=1;
147 int i;
148 int c;
149 int ibuf=0,buflen=1024,bufblk=1024;
150 char* buffer=NULL;
151
152 buffer=(char *) xmalloc(buflen*sizeof(char));
153 buffer[0]='\0';
154
155/* read kml file character-by-character */
156
157 while ((c=getc(fid)) != EOF) {
158 /* ignore leading blanks */
159 if (inew && isspace(c))
160 continue;
161
162 inew=0;
163 KMLFileTokenBuffer(&buffer,&ibuf,&buflen,
164 c,
165 bufblk);
166
167 /* check for comment */
168 if (ibuf <= 4) {
169 if ((ibuf == 1 && buffer[0] != '<') ||
170 (ibuf == 2 && buffer[1] != '!') ||
171 (ibuf == 3 && buffer[2] != '-') ||
172 (ibuf == 4 && buffer[3] != '-')) {
173 for (i=ibuf-1; i>=0; i--)
174 ungetc(buffer[i],fid);
175 xfree((void**)&buffer);
176 return(buffer);
177 }
178 }
179
180 /* accumulate comment, including newlines */
181 else
182 if (buffer[ibuf-3]=='-' && buffer[ibuf-2]=='-' && buffer[ibuf-1]=='>')
183 break;
184 }
185
186/* remove trailing blanks or newline */
187
188 while (ibuf > 0)
189 if (isspace(buffer[ibuf-1]))
190 ibuf--;
191 else {
192 buffer[ibuf]='\0';
193 break;
194 }
195
[10629]196// _printf_(true,"comment buffer (length=%d):\n",ibuf);
197// _printf_(true,"%s\n",buffer);
[10627]198
199 if (!ibuf)
200 xfree((void**)&buffer);
201
202 return(buffer);
203}
204/*}}}*/
205
[12365]206/*FUNCTION KMLFileTokenBuffer {{{*/
[8206]207void KMLFileTokenBuffer(char** pbuffer,int* pibuf,int* pbuflen,
208 int c,
209 int bufblk){
210
[10627]211/* add the specified character to the token buffer */
212
[8206]213 char* buffer=NULL;
214
215/* check buffer length and realloc if necessary */
216
217 if (*pibuf+2 > *pbuflen) {
218 *pbuflen+=bufblk;
219 *pbuffer=(char *) xrealloc(*pbuffer,*pbuflen*sizeof(char));
220 }
221
222/* add character and terminator */
223
224 (*pbuffer)[(*pibuf)++]=c;
225 (*pbuffer)[ *pibuf ]='\0';
226
227 return;
228}
229/*}}}*/
230
[12365]231/*FUNCTION KMLFileTagName {{{*/
[11319]232char* KMLFileTagName(char* pname,
233 char* ktag){
234
235 return(KMLFileTagName(pname,NULL,0,
236 ktag));
237}
238/*}}}*/
239
[12365]240/*FUNCTION KMLFileTagName {{{*/
[11319]241char* KMLFileTagName(char* pname,int *m,int maxlen,
242 char* ktag){
243
244/* for the given tag buffer, read and store the name */
245
246 char* ktagi;
247 char* ktokn;
248
249 if (strncmp(&ktag[0],"<" ,1) || strncmp(&ktag[strlen(ktag)-1],">",1))
250 _error_("KMLFileTagName -- Missing tag delimiters in %s.\n",ktag);
251
252/* strtok modifies ktag, so work on copy */
253
254 ktagi=(char *) xmalloc((strlen(ktag)+1)*sizeof(char));
255 memcpy(ktagi,ktag,(strlen(ktag)+1)*sizeof(char));
256
257/* skip opening delimeter and find subsequent blank or closing delimiter */
258
259 ktokn=strtok(ktagi,"< >");
260// _printf_(true,"KMLFileTagName -- initial token=\"%s\".\n",ktokn);
261
262 if (!pname) {
263 if (maxlen)
264 pname=(char *) xmalloc((maxlen +1)*sizeof(char));
265 else
266 pname=(char *) xmalloc((strlen(ktokn)+1)*sizeof(char));
267 }
268
269 if (maxlen && (maxlen < strlen(ktokn))) {
270 _printf_(true,"KMLFileTagName -- string field too short for %s.\n",ktag);
271 _printf_(true,"KMLFileTagName -- \"%s\" truncated to %d characters.\n",ktokn,maxlen);
272 strncpy(pname,ktokn,maxlen);
273 }
274 else
275 memcpy(pname,ktokn,(strlen(ktokn)+1)*sizeof(char));
276
277 xfree((void**)&ktagi);
278
279 if (m)
280 *m=strlen(pname);
281
282 return(pname);
283}
284/*}}}*/
285
[12365]286/*FUNCTION KMLFileTagAttrib {{{*/
[10629]287int KMLFileTagAttrib(KML_Object* kobj,
288 char* ktag){
[8206]289
[10627]290/* for the given tag buffer, read and store the attributes */
291
[8206]292 char* ktagi;
[8461]293 char* ktokn;
294 char* ktokv;
[8206]295 char quote[]={'\"','\0'};
[10629]296 int isolo=0;
[8206]297
[8461]298/* strtok modifies ktag, so work on copy */
[8206]299
300 ktagi=(char *) xmalloc((strlen(ktag)+1)*sizeof(char));
[9336]301 memcpy(ktagi,ktag,(strlen(ktag)+1)*sizeof(char));
[8206]302
303/* loop through tag to find all attributes */
304
[10629]305 /* return first non blank and move past subsequent blank */
[8461]306 ktokn=strtok(ktagi," ");
[10629]307// _printf_(true,"KMLFileTagAttrib -- initial token=\"%s\".\n",ktokn);
[8206]308
[10629]309 /* return next non " =?/>" and move past subsequent " =?/>" */
310 while (ktokn=strtok(NULL," =?/>")) {
311
312 /* return next non quote and move past subsequent quote */
[8461]313 ktokv=strtok(NULL,quote);
[9214]314// _printf_(true,"KMLFileTagAttrib -- attribute %s=\"%s\".\n",ktokn,ktokv);
[8206]315
[8461]316/* add the attribute to the dataset */
[8206]317
[8461]318 if (kobj)
319 kobj->AddAttrib(ktokn,ktokv);
[8206]320 }
321
322 xfree((void**)&ktagi);
323
[10629]324/* check for xml declaration, dtd declaration, or solo tag */
325
326 if ((!strncmp(&ktag[0],"<?" ,2) && !strncmp(&ktag[strlen(ktag)-2],"?>",2)) ||
327 (!strncmp(&ktag[0],"<!DOCTYPE",9) && !strncmp(&ktag[strlen(ktag)-1], ">",1)) ||
328 (!strncmp(&ktag[0],"<" ,1) && !strncmp(&ktag[strlen(ktag)-2],"/>",2)))
329 isolo=1;
330// _printf_(true,"KMLFileTagAttrib -- isolo=%d.\n",isolo);
331
332 return(isolo);
[8206]333}
334/*}}}*/
335
[12365]336/*FUNCTION KMLFileTokenParse {{{*/
[8206]337int KMLFileTokenParse(int* pival,
338 char* ktag,
339 FILE* fid){
340
341 char* kstr;
342
343/* get next token and convert to appropriate format */
344
[10840]345 if (!(kstr=KMLFileToken(fid,
346 NULL,NULL)) ||
[8206]347 (kstr[0] == '<'))
348 _error_("KMLFileTokenParse -- Missing integer field for %s.\n",ktag);
349
350 sscanf(kstr,"%d",pival);
351 xfree((void**)&kstr);
352
353/* get additional token and compare to closing tag */
354
355 if (ktag)
[10840]356 if (!(kstr=KMLFileToken(fid,
357 NULL,NULL)) ||
[8206]358 (kstr[0] != '<') ||
359 (kstr[1] != '/') ||
360 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
361 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
362 else
363 xfree((void**)&kstr);
364
[8461]365// _printf_(true,"KMLFileTokenParse -- %s=%d.\n",ktag,*pival);
[8206]366
367 return(0);
368}
369/*}}}*/
370
[12365]371/*FUNCTION KMLFileTokenParse {{{*/
[8206]372int KMLFileTokenParse(bool* pbval,
373 char* ktag,
374 FILE* fid){
375
376 int ival;
377 char* kstr;
378
379/* get next token and convert to appropriate format */
380
[10840]381 if (!(kstr=KMLFileToken(fid,
382 NULL,NULL)) ||
[8206]383 (kstr[0] == '<'))
384 _error_("KMLFileTokenParse -- Missing bool field for %s.\n",ktag);
385
386 sscanf(kstr,"%d",&ival);
387 *pbval=(bool)ival;
388 xfree((void**)&kstr);
389
390/* get additional token and compare to closing tag */
391
392 if (ktag)
[10840]393 if (!(kstr=KMLFileToken(fid,
394 NULL,NULL)) ||
[8206]395 (kstr[0] != '<') ||
396 (kstr[1] != '/') ||
397 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
398 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
399 else
400 xfree((void**)&kstr);
401
[8461]402// _printf_(true,"KMLFileTokenParse -- %s=%s.\n",ktag,(*pbval ? "true" : "false"));
[8206]403
404 return(0);
405}
406/*}}}*/
407
[12365]408/*FUNCTION KMLFileTokenParse {{{*/
[11319]409char* KMLFileTokenParse(char* pstr,
410 char* ktag,
411 FILE* fid){
412
413 return(KMLFileTokenParse(pstr,NULL,0,
414 ktag,
415 fid));
416}
417/*}}}*/
418
[12365]419/*FUNCTION KMLFileTokenParse {{{*/
[8206]420char* KMLFileTokenParse(char* pstr,int *m,int maxlen,
421 char* ktag,
422 FILE* fid){
423
424 char* kstr;
425
426/* get next token and allocate if necessary */
427
[10840]428 if (!(kstr=KMLFileToken(fid,
429 NULL,NULL)) ||
[8206]430 (kstr[0] == '<'))
431 _error_("KMLFileTokenParse -- Missing string field for %s.\n",ktag);
432
433 if (!pstr) {
434 if (maxlen)
435 pstr=(char *) xmalloc((maxlen +1)*sizeof(char));
436 else
437 pstr=(char *) xmalloc((strlen(kstr)+1)*sizeof(char));
438 }
439
440 if (maxlen && (maxlen < strlen(kstr))) {
441 _printf_(true,"KMLFileTokenParse -- string field too short for %s.\n",ktag);
442 _printf_(true,"KMLFileTokenParse -- \"%s\" truncated to %d characters.\n",kstr,maxlen);
443 strncpy(pstr,kstr,maxlen);
444 }
445 else
[9336]446 memcpy(pstr,kstr,(strlen(kstr)+1)*sizeof(char));
447
[8206]448 xfree((void**)&kstr);
449
450 if (m)
451 *m=strlen(pstr);
452
453/* get additional token and compare to closing tag */
454
455 if (ktag)
[10840]456 if (!(kstr=KMLFileToken(fid,
457 NULL,NULL)) ||
[8206]458 (kstr[0] != '<') ||
459 (kstr[1] != '/') ||
460 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
461 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
462 else
463 xfree((void**)&kstr);
464
[8461]465// _printf_(true,"KMLFileTokenParse -- %s=\"%s\".\n",ktag,pstr);
[8206]466
[11319]467 return(pstr);
[8206]468}
469/*}}}*/
470
[12365]471/*FUNCTION KMLFileTokenParse {{{*/
[8461]472int KMLFileTokenParse(float* pfval,
473 char* ktag,
474 FILE* fid){
475
476 char* kstr;
477
478/* get next token and convert to appropriate format */
479
[10840]480 if (!(kstr=KMLFileToken(fid,
481 NULL,NULL)) ||
[8461]482 (kstr[0] == '<'))
483 _error_("KMLFileTokenParse -- Missing integer field for %s.\n",ktag);
484
485 sscanf(kstr,"%g",pfval);
486 xfree((void**)&kstr);
487
488/* get additional token and compare to closing tag */
489
490 if (ktag)
[10840]491 if (!(kstr=KMLFileToken(fid,
492 NULL,NULL)) ||
[8461]493 (kstr[0] != '<') ||
494 (kstr[1] != '/') ||
495 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
496 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
497 else
498 xfree((void**)&kstr);
499
500// _printf_(true,"KMLFileTokenParse -- %s=%g.\n",ktag,*pfval);
501
502 return(0);
503}
504/*}}}*/
505
[12365]506/*FUNCTION KMLFileTokenParse {{{*/
[8464]507int KMLFileTokenParse(double* pdval,
508 char* ktag,
509 FILE* fid){
510
511 char* kstr;
512
513/* get next token and convert to appropriate format */
514
[10840]515 if (!(kstr=KMLFileToken(fid,
516 NULL,NULL)) ||
[8464]517 (kstr[0] == '<'))
518 _error_("KMLFileTokenParse -- Missing integer field for %s.\n",ktag);
519
520 sscanf(kstr,"%lg",pdval);
521 xfree((void**)&kstr);
522
523/* get additional token and compare to closing tag */
524
525 if (ktag)
[10840]526 if (!(kstr=KMLFileToken(fid,
527 NULL,NULL)) ||
[8464]528 (kstr[0] != '<') ||
529 (kstr[1] != '/') ||
530 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
531 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
532 else
533 xfree((void**)&kstr);
534
535// _printf_(true,"KMLFileTokenParse -- %s=%g.\n",ktag,*pdval);
536
537 return(0);
538}
539/*}}}*/
540
[12365]541/*FUNCTION KMLFileTokenParse {{{*/
[10256]542int KMLFileTokenParse(double **pdval,int* m,int maxlen,
543 char* ktag,
544 FILE* fid){
545
546 int i=-1,j;
547 char* kstr;
548 char* ktok;
549 char delim[]={' ',',','\f','\n','\r','\t','\v','\0'};
550
551/* get next token and allocate if necessary */
552
[10840]553 if (!(kstr=KMLFileToken(fid,
554 NULL,NULL)) ||
[10256]555 (kstr[0] == '<'))
556 _error_("KMLFileTokenParse -- Missing double [m] field for %s.\n",ktag);
557
558 if (!*pdval)
559 if (maxlen)
560 *pdval=(double *) xmalloc(maxlen *sizeof(double));
561 else
562 *pdval=(double *) xmalloc(((strlen(kstr)+1)/2)*sizeof(double));
563
564/* loop through string to get all values */
565
566 ktok=strtok(kstr,delim);
567 while (ktok) {
568 i++;
569 if (maxlen && (maxlen < i+1))
570 _error_("KMLFileTokenParse -- Double [m] field too short for %s.\n",ktag);
571 sscanf(ktok,"%lg",&((*pdval)[i]));
572 ktok=strtok(NULL,delim);
573 }
574 xfree((void**)&kstr);
575
576 if (!maxlen)
577 *pdval=(double *) xrealloc(*pdval,(i+1)*sizeof(double));
578
579 if (m)
580 *m=i+1;
581
582/* get additional token and compare to closing tag */
583
584 if (ktag)
[10840]585 if (!(kstr=KMLFileToken(fid,
586 NULL,NULL)) ||
[10256]587 (kstr[0] != '<') ||
588 (kstr[1] != '/') ||
589 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
590 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
591 else
592 xfree((void**)&kstr);
593
594// _printf_(true,"KMLFileTokenParse -- %s=...\n",ktag);
595// for (j=0; j<=i; j++)
[10274]596// _printf_(true," [%d]: %lg\n",j,(*pdval)[j]);
[10256]597
598 return(0);
599}
600/*}}}*/
601
[12365]602/*FUNCTION KMLFileTokenParse {{{*/
[8206]603int KMLFileTokenParse(double (**pdval3)[3],int* m,int maxlen,
604 char* ktag,
605 FILE* fid){
606
607 int i=0,j=-1;
608 char* kstr;
609 char* ktok;
610 char delim[]={' ',',','\f','\n','\r','\t','\v','\0'};
611
612/* get next token and allocate if necessary */
613
[10840]614 if (!(kstr=KMLFileToken(fid,
615 NULL,NULL)) ||
[8206]616 (kstr[0] == '<'))
617 _error_("KMLFileTokenParse -- Missing double [m x 3] field for %s.\n",ktag);
618
619 if (!*pdval3)
620 if (maxlen)
621 *pdval3=(double (*)[3]) xmalloc((maxlen*3) *sizeof(double));
622 else
623 *pdval3=(double (*)[3]) xmalloc(((strlen(kstr)+1)/2)*sizeof(double));
624
625/* loop through string to get all values */
626
627 ktok=strtok(kstr,delim);
628 while (ktok) {
629 j++;
630 if (j == 3) {
631 i++;
632 j=0;
633 if (maxlen && (maxlen < i+1))
634 _error_("KMLFileTokenParse -- Double [m x 3] field too short for %s.\n",ktag);
635 }
636 sscanf(ktok,"%lg",&((*pdval3)[i][j]));
637 ktok=strtok(NULL,delim);
638 }
639 xfree((void**)&kstr);
640
641 if (!maxlen)
642 *pdval3=(double (*)[3]) xrealloc(*pdval3,((i+1)*3)*sizeof(double));
643
644 if (m)
645 *m=i+1;
646
647 if (j != 2)
648 _printf_(true,"KMLFileTokenParse -- Double [m x 3] field for %s does not have multiple of 3 values.\n",ktag);
649
650/* get additional token and compare to closing tag */
651
652 if (ktag)
[10840]653 if (!(kstr=KMLFileToken(fid,
654 NULL,NULL)) ||
[8206]655 (kstr[0] != '<') ||
656 (kstr[1] != '/') ||
657 (strncmp(&(kstr[2]),&(ktag[1]),strlen(ktag)-1)))
658 _error_("KMLFileTokenParse -- Missing closing tag for %s.\n",ktag);
659 else
660 xfree((void**)&kstr);
661
[8461]662// _printf_(true,"KMLFileTokenParse -- %s=...\n",ktag);
663// for (j=0; j<=i; j++)
[10274]664// _printf_(true," [%d][0-2]: %lg,%lg,%lg\n",j,(*pdval3)[j][0],(*pdval3)[j][1],(*pdval3)[j][2]);
[8206]665
666 return(0);
667}
668/*}}}*/
669
[12365]670/*FUNCTION KMLFileTagSkip {{{*/
[8206]671int KMLFileTagSkip(char* ktag,
672 FILE* fid){
673
674 char* kstr;
675
676/* note that tags of the same type can be nested inside each other, so for each
677 opening tag, must find corresponding closing tag */
678
679 _printf_(true,"KMLFileTagSkip -- input tag %s.\n",ktag);
680
681/* if next token is a closing tag, compare to input */
682
[10840]683 while (kstr=KMLFileToken(fid,
684 NULL,NULL)) {
[8206]685 if ((kstr[0] == '<') &&
686 (kstr[1] == '/') &&
687 (!strncmp(&(kstr[2]),&(ktag[1]),(strcspn(ktag," >")-1)/sizeof(char)))) {
688 _printf_(true,"KMLFileTagSkip -- closing tag %s.\n",kstr);
689 xfree((void**)&kstr);
690 return(0);
691 }
692
693/* if next token is an opening tag, call recursively */
694
695 else if ((kstr[0] == '<') &&
696 (kstr[1] != '/')) {
697 _printf_(true,"KMLFileTagSkip -- opening tag %s.\n",kstr);
698 KMLFileTagSkip(kstr,
699 fid);
700 }
701
702/* if next token is a closing tag, error out */
703
704 else if ((kstr[0] == '<') &&
705 (kstr[1] == '/')) {
706 _error_("KMLFileTagSkip -- Unexpected closing tag %s.\n",kstr);
707 }
708
709 xfree((void**)&kstr);
710 }
711
712 _error_("KMLFileTokenParse -- Corresponding closing tag for %s not found.\n",ktag);
713
714 return(0);
715}
716/*}}}*/
717
Note: See TracBrowser for help on using the repository browser.