~ubuntu-branches/ubuntu/vivid/libxml-bare-perl/vivid

« back to all changes in this revision

Viewing changes to .pc/pointer_from_integer.patch/parser.c

  • Committer: Package Import Robot
  • Author(s): Nuno Carvalho, gregor herrmann, Salvatore Bonaccorso, Axel Beckert, Nuno Carvalho
  • Date: 2013-09-17 15:54:28 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130917155428-4d0xb5cissw2323f
Tags: 0.53-1
* Team upload.

[ gregor herrmann ]
* debian/control: update {versioned,alternative} (build) dependencies.

[ Salvatore Bonaccorso ]
* Change Vcs-Git to canonical URI (git://anonscm.debian.org)
* Change search.cpan.org based URIs to metacpan.org based URIs

[ Axel Beckert ]
* debian/copyright: migrate pre-1.0 format to 1.0 using "cme fix dpkg-
  copyright"

[ Nuno Carvalho ]
* New upstream release.
* debian/copyright: update copyright years.
* debian/control: update standards version.
* debian/control: update debhelper required version, in order to pass all
  the hardening flags to EUMM.
* Add lintian override to apparently false-positive warning.
* Add set of patches accepted upstream but still not included in this
  release, visit https://rt.cpan.org/Public/Bug/Display.html?id=88155
  for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "parser.h"
 
2
#include<stdio.h>
 
3
#include "stdlib.h"
 
4
#ifdef NOSTRING
 
5
  void memset(char *s, int c, int n) {
 
6
    char *se = s + n;
 
7
    while(s < se)       *s++ = c;
 
8
        }
 
9
#else
 
10
  #include <string.h>
 
11
#endif
 
12
 
 
13
int dh_memcmp(char *a,char *b,int n) {
 
14
  int c = 0;
 
15
  while( c < n ) {
 
16
    if( *a != *b ) return c+1;
 
17
    a++; b++; c++;
 
18
  }
 
19
  return 0;
 
20
}
 
21
 
 
22
struct nodec *new_nodecp( struct nodec *newparent ) {
 
23
  static int pos = 0;
 
24
  int size = sizeof( struct nodec );
 
25
  struct nodec *self = (struct nodec *) malloc( size );
 
26
  memset( (char *) self, 0, size );
 
27
  self->parent      = newparent;
 
28
  self->pos = ++pos;
 
29
  return self;
 
30
}
 
31
 
 
32
struct nodec *new_nodec() {
 
33
  int size = sizeof( struct nodec );
 
34
  struct nodec *self = (struct nodec *) malloc( size );
 
35
  memset( (char *) self, 0, size );
 
36
  return self;
 
37
}
 
38
 
 
39
void del_nodec( struct nodec *node ) {
 
40
  struct nodec *curnode;
 
41
  struct attc *curatt;
 
42
  struct nodec *next;
 
43
  struct attc *nexta;
 
44
  curnode = node->firstchild;
 
45
  while( curnode ) {
 
46
    next = curnode->next;
 
47
    del_nodec( curnode );
 
48
    if( !next ) break;
 
49
    curnode = next;
 
50
  }
 
51
  curatt = node->firstatt;
 
52
  while( curatt ) {
 
53
    nexta = curatt->next;
 
54
    free( curatt );
 
55
    curatt = nexta;
 
56
  }
 
57
  free( node );
 
58
}
 
59
 
 
60
struct attc* new_attc( struct nodec *newparent ) {
 
61
  int size = sizeof( struct attc );
 
62
  struct attc *self = (struct attc *) malloc( size );
 
63
  memset( (char *) self, 0, size );
 
64
  self->parent  = newparent;
 
65
  return self;
 
66
}
 
67
 
 
68
//#define DEBUG
 
69
 
 
70
#define ST_val_1 1
 
71
#define ST_val_x 2
 
72
#define ST_comment_1dash 3
 
73
#define ST_comment_2dash 4
 
74
#define ST_comment 5
 
75
#define ST_comment_x 6
 
76
#define ST_pi 7
 
77
#define ST_bang 24
 
78
#define ST_cdata 8
 
79
#define ST_name_1 9
 
80
#define ST_name_x 10
 
81
#define ST_name_gap 11
 
82
#define ST_att_name1 12
 
83
#define ST_att_space 13
 
84
#define ST_att_name 14
 
85
#define ST_att_nameqs 15
 
86
#define ST_att_nameqsdone 16
 
87
#define ST_att_eq1 17
 
88
#define ST_att_eqx 18
 
89
#define ST_att_quot 19
 
90
#define ST_att_quots 20
 
91
#define ST_att_tick 21
 
92
#define ST_ename_1 22
 
93
#define ST_ename_x 23
 
94
 
 
95
int parserc_parse( struct parserc *self, char *xmlin ) {
 
96
    // Variables that represent current 'state'
 
97
    struct nodec *root    = NULL;
 
98
    char  *tagname        = NULL; int    tagname_len    = 0;
 
99
    char  *attname        = NULL; int    attname_len    = 0;
 
100
    char  *attval         = NULL; int    attval_len     = 0;
 
101
    int    att_has_val    = 0;
 
102
    struct nodec *curnode = NULL;
 
103
    struct attc  *curatt  = NULL;
 
104
    int    last_state     = 0;
 
105
    self->rootpos = xmlin;
 
106
    
 
107
    // Variables used temporarily during processing
 
108
    struct nodec *temp;
 
109
    char   *cpos          = &xmlin[0];
 
110
    int    res            = 0;
 
111
    int    dent;
 
112
    register int let;
 
113
    
 
114
    if( self->last_state ) {
 
115
      #ifdef DEBUG
 
116
      printf( "Resuming parse in state %i\n", self->last_state );
 
117
      #endif
 
118
      self->err = 0;
 
119
      root = self->rootnode;
 
120
      curnode = self->curnode;
 
121
      curatt = self->curatt;
 
122
      tagname = self->tagname; tagname_len = self->tagname_len;
 
123
      attname = self->attname; attname_len = self->attname_len;
 
124
      attval = self->attval; attval_len = self->attval_len;
 
125
      att_has_val = self->att_has_val;
 
126
      switch( self->last_state ) {
 
127
        case ST_val_1: goto val_1;
 
128
        case ST_val_x: goto val_x;
 
129
        case ST_comment_1dash: goto comment_1dash;
 
130
        case ST_comment_2dash: goto comment_2dash;
 
131
        case ST_comment: goto comment;
 
132
        case ST_comment_x: goto comment_x;
 
133
        case ST_pi: goto pi;
 
134
        case ST_bang: goto bang;
 
135
        case ST_cdata: goto cdata;
 
136
        case ST_name_1: goto name_1;
 
137
        case ST_name_x: goto name_x;
 
138
        case ST_name_gap: goto name_gap;
 
139
        case ST_att_name1: goto att_name1;
 
140
        case ST_att_space: goto att_space;
 
141
        case ST_att_name: goto att_name;
 
142
        case ST_att_nameqs: goto att_nameqs;
 
143
        case ST_att_nameqsdone: goto att_nameqsdone;
 
144
        case ST_att_eq1: goto att_eq1;
 
145
        case ST_att_eqx: goto att_eqx;
 
146
        case ST_att_quot: goto att_quot;
 
147
        case ST_att_quots: goto att_quots;
 
148
        case ST_att_tick: goto att_tick;
 
149
        case ST_ename_1: goto ename_1;
 
150
        case ST_ename_x: goto ename_x;
 
151
      }
 
152
    }
 
153
    else {
 
154
      self->err = 0;
 
155
      curnode = root = self->rootnode = new_nodec();
 
156
    }
 
157
    
 
158
    #ifdef DEBUG
 
159
    printf("Entry to C Parser\n");
 
160
    #endif
 
161
    
 
162
    val_1:
 
163
      #ifdef DEBUG
 
164
      printf("val_1: %c\n", *cpos);
 
165
      #endif
 
166
      let = *cpos;
 
167
      switch( let ) {
 
168
        case 0: last_state = ST_val_1; goto done;
 
169
        case '<': goto val_x;
 
170
      }
 
171
      if( !curnode->numvals ) {
 
172
        curnode->value = cpos;
 
173
        curnode->vallen = 1;
 
174
      }
 
175
      curnode->numvals++;
 
176
      cpos++;
 
177
      
 
178
    val_x:
 
179
      #ifdef DEBUG
 
180
      printf("val_x: %c\n", *cpos);
 
181
      #endif
 
182
      let = *cpos;
 
183
      switch( let ) {
 
184
        case 0: last_state = ST_val_x; goto done;
 
185
        case '<':
 
186
          switch( *(cpos+1) ) {
 
187
            case '!':
 
188
              if( *(cpos+2) == '[' ) { // <![
 
189
                //if( !strncmp( cpos+3, "CDATA", 5 ) ) {
 
190
                if( *(cpos+3) == 'C' &&
 
191
                    *(cpos+4) == 'D' &&
 
192
                    *(cpos+5) == 'A' &&
 
193
                    *(cpos+6) == 'T' &&
 
194
                    *(cpos+7) == 'A'    ) {
 
195
                  cpos += 9;
 
196
                  curnode->type = 1;
 
197
                  goto cdata;
 
198
                }
 
199
                else {
 
200
                  cpos++; cpos++;
 
201
                  goto val_x;//actually goto error...
 
202
                }
 
203
              }
 
204
              else if( *(cpos+2) == '-' && // <!--
 
205
                *(cpos+3) == '-' ) {
 
206
                  cpos += 4;
 
207
                  goto comment;
 
208
              }
 
209
              else {
 
210
                cpos++;
 
211
                goto bang;
 
212
              }
 
213
            case '?':
 
214
              cpos+=2;
 
215
              goto pi;
 
216
          }
 
217
          tagname_len = 0; // for safety
 
218
          cpos++;
 
219
          goto name_1;
 
220
      }
 
221
      if( curnode->numvals == 1 ) curnode->vallen++;
 
222
      cpos++;
 
223
      goto val_x;
 
224
      
 
225
    comment_1dash:
 
226
      cpos++;
 
227
      let = *cpos;
 
228
      if( let == '-' ) goto comment_2dash;
 
229
      if( !let ) { last_state = ST_comment_1dash; goto done; }
 
230
      goto comment_x;
 
231
      
 
232
    comment_2dash:
 
233
      cpos++;
 
234
      let = *cpos;
 
235
      if( let == '>' ) {
 
236
        cpos++;
 
237
        goto val_1;
 
238
      }
 
239
      if( !let ) { last_state = ST_comment_2dash; goto done; }
 
240
      goto comment_x;
 
241
      
 
242
    comment:
 
243
      let = *cpos;
 
244
      switch( let ) {
 
245
        case 0:   last_state = ST_comment; goto done;
 
246
        case '-': goto comment_1dash;
 
247
      }
 
248
      if( !curnode->numcoms ) {
 
249
        curnode->comment = cpos;
 
250
        curnode->comlen = 1;
 
251
      }
 
252
      curnode->numcoms++;
 
253
      cpos++;
 
254
    
 
255
    comment_x:
 
256
      let = *cpos;
 
257
      switch( let ) {
 
258
        case 0: last_state = ST_comment_x; goto done;
 
259
        case '-': goto comment_1dash;
 
260
      }
 
261
      if( curnode->numcoms == 1 ) curnode->comlen++;
 
262
      cpos++;
 
263
      goto comment_x;
 
264
      
 
265
    pi:
 
266
      let = *cpos;
 
267
      if( let == '?' && *(cpos+1) == '>' ) {
 
268
        cpos += 2;
 
269
        goto val_1;
 
270
      }
 
271
      if( !let ) { last_state = ST_pi; goto done; }
 
272
      cpos++;
 
273
      goto pi;
 
274
 
 
275
    bang:
 
276
      let = *cpos;
 
277
      if( let == '>' ) {
 
278
        cpos++;
 
279
        goto val_1;
 
280
      }
 
281
      if( !let ) { last_state = ST_bang; goto done; }
 
282
      cpos++;
 
283
      goto bang;
 
284
    
 
285
    cdata:
 
286
      let = *cpos;
 
287
      if( !let ) { last_state = ST_cdata; goto done; }
 
288
      if( let == ']' && *(cpos+1) == ']' && *(cpos+2) == '>' ) {
 
289
        cpos += 3;
 
290
        goto val_1;
 
291
      }
 
292
      if( !curnode->numvals ) {
 
293
        curnode->value = cpos;
 
294
        curnode->vallen = 0;
 
295
        curnode->numvals = 1;
 
296
      }
 
297
      if( curnode->numvals == 1 ) curnode->vallen++;
 
298
      cpos++;
 
299
      goto cdata;
 
300
      
 
301
    name_1:
 
302
      #ifdef DEBUG
 
303
      printf("name_1: %c\n", *cpos);
 
304
      #endif
 
305
      let = *cpos;
 
306
      switch( let ) {
 
307
        case 0: last_state = ST_name_1; goto done;        
 
308
        case ' ':
 
309
        case 0x0d:
 
310
        case 0x0a:
 
311
          cpos++;
 
312
          goto name_1;
 
313
        case '/': // regular closing tag
 
314
          tagname_len = 0; // needed to reset
 
315
          cpos++;
 
316
          goto ename_1;
 
317
      }
 
318
      tagname       = cpos;
 
319
      tagname_len   = 1;
 
320
      cpos++;
 
321
      goto name_x;
 
322
      
 
323
    name_x:
 
324
      #ifdef DEBUG
 
325
      printf("name_x: %c\n", *cpos);
 
326
      #endif
 
327
      let = *cpos;
 
328
      switch( let ) {
 
329
        case 0: last_state = ST_name_x; goto done;
 
330
        case ' ':
 
331
        case 0x0d:
 
332
        case 0x0a:
 
333
          curnode     = nodec_addchildr( curnode, tagname, tagname_len );
 
334
          attname_len = 0;
 
335
          cpos++;
 
336
          goto name_gap;
 
337
        case '>':
 
338
          curnode     = nodec_addchildr( curnode, tagname, tagname_len );
 
339
          cpos++;
 
340
          goto val_1;
 
341
        case '/': // self closing
 
342
          temp = nodec_addchildr( curnode, tagname, tagname_len );
 
343
          temp->z = cpos +1 - xmlin;
 
344
          tagname_len            = 0;
 
345
          cpos+=2;
 
346
          goto val_1;
 
347
      }
 
348
      
 
349
      tagname_len++;
 
350
      cpos++;
 
351
      goto name_x;
 
352
          
 
353
    name_gap:
 
354
      let = *cpos;
 
355
      switch( *cpos ) {
 
356
        case 0: last_state = ST_name_gap; goto done;
 
357
        case ' ':
 
358
        case 0x0d:
 
359
        case 0x0a:
 
360
          cpos++;
 
361
          goto name_gap;
 
362
        case '>':
 
363
          cpos++;
 
364
          goto val_1;
 
365
        case '/': // self closing
 
366
          curnode->z = cpos+1-xmlin;
 
367
          curnode = curnode->parent;
 
368
          if( !curnode ) goto done;
 
369
          cpos+=2; // am assuming next char is >
 
370
          goto val_1;
 
371
        case '=':
 
372
          cpos++;
 
373
          goto name_gap;//actually goto error
 
374
      }
 
375
        
 
376
    att_name1:
 
377
      #ifdef DEBUG
 
378
      printf("attname1: %c\n", *cpos);
 
379
      #endif
 
380
      att_has_val = 0;
 
381
      let = *cpos;
 
382
      switch( let ) {
 
383
        case 0: last_state = ST_att_name1; goto done;
 
384
        case 0x27://'
 
385
          cpos++;
 
386
          attname = cpos;
 
387
          attname_len = 0;
 
388
          goto att_nameqs;
 
389
      }
 
390
      attname = cpos;
 
391
      attname_len = 1;
 
392
      cpos++;
 
393
      goto att_name;
 
394
      
 
395
    att_space:
 
396
      let = *cpos;
 
397
      switch( let ) {
 
398
        case 0: last_state = ST_att_space; goto done;
 
399
        case ' ':
 
400
        case 0x0d:
 
401
        case 0x0a:
 
402
          cpos++;
 
403
          goto att_space;
 
404
        case '=':
 
405
          att_has_val = 1;
 
406
          cpos++;
 
407
          goto att_eq1;
 
408
      }
 
409
      // we have another attribute name, so continue
 
410
      
 
411
    att_name:
 
412
      #ifdef DEBUG
 
413
      printf("attname: %c\n", *cpos);
 
414
      #endif
 
415
      let = *cpos;
 
416
      switch( let ) {
 
417
        case 0: last_state = ST_att_name; goto done;
 
418
        case '/': // self closing     !! /> is assumed !!
 
419
          curatt = nodec_addattr( curnode, attname, attname_len );
 
420
          if( !att_has_val ) { curatt->value = -1; curatt->vallen = 0; }
 
421
          attname_len            = 0;
 
422
          
 
423
          curnode->z = cpos+1-xmlin;
 
424
          curnode = curnode->parent;
 
425
          if( !curnode ) goto done;
 
426
          cpos += 2;
 
427
          goto val_1;
 
428
        case ' ':
 
429
          if( *(cpos+1) == '=' ) {
 
430
            cpos++;
 
431
            goto att_name;
 
432
          }
 
433
          curatt = nodec_addattr( curnode, attname, attname_len );
 
434
          attname_len = 0;
 
435
          cpos++;
 
436
          goto att_space;
 
437
        case '>':
 
438
          curatt = nodec_addattr( curnode, attname, attname_len );
 
439
          if( !att_has_val ) { curatt->value = -1; curatt->vallen = 0; }
 
440
          attname_len = 0;
 
441
          cpos++;
 
442
          goto val_1;
 
443
        case '=':
 
444
          attval_len = 0;
 
445
          curatt = nodec_addattr( curnode, attname, attname_len );
 
446
          attname_len = 0;
 
447
          cpos++;
 
448
          goto att_eq1;
 
449
      }
 
450
      
 
451
      if( !attname_len ) attname = cpos;
 
452
      attname_len++;
 
453
      cpos++;
 
454
      goto att_name;
 
455
      
 
456
    att_nameqs:
 
457
      #ifdef DEBUG
 
458
      printf("nameqs: %c\n", *cpos);
 
459
      #endif
 
460
      let = *cpos;
 
461
      switch( let ) {
 
462
        case 0: last_state = ST_att_nameqs; goto done;
 
463
        case 0x27://'
 
464
          cpos++;
 
465
          goto att_nameqsdone;
 
466
      }
 
467
      attname_len++;
 
468
      cpos++;
 
469
      goto att_nameqs;
 
470
      
 
471
    att_nameqsdone:
 
472
      #ifdef DEBUG
 
473
      printf("nameqsdone: %c\n", *cpos);
 
474
      #endif
 
475
      let = *cpos;
 
476
      switch( let ) {
 
477
        case 0: last_state = ST_att_nameqsdone; goto done;
 
478
        case '=':
 
479
          attval_len = 0;
 
480
          curatt = nodec_addattr( curnode, attname, attname_len );
 
481
          attname_len = 0;
 
482
          cpos++;
 
483
          goto att_eq1;
 
484
      }
 
485
      goto att_nameqsdone;
 
486
      
 
487
    att_eq1:
 
488
      let = *cpos;
 
489
      switch( let ) {
 
490
        case 0: last_state = ST_att_eq1; goto done;
 
491
        case '/': // self closing
 
492
          if( *(cpos+1) == '>' ) {
 
493
            curnode->z = cpos+1-xmlin;
 
494
            curnode = curnode->parent;
 
495
            if( !curnode ) goto done;
 
496
            cpos+=2;
 
497
            goto att_eq1;
 
498
          }
 
499
          break;
 
500
        case '"':  cpos++; goto att_quot;
 
501
        case 0x27: cpos++; goto att_quots; //'
 
502
        case '`':  cpos++; goto att_tick;
 
503
        case '>':  cpos++; goto val_1;
 
504
        case ' ':  cpos++; goto att_eq1;
 
505
      }  
 
506
      if( !attval_len ) attval = cpos;
 
507
      attval_len++;
 
508
      cpos++;
 
509
      goto att_eqx;
 
510
      
 
511
    att_eqx:
 
512
      let = *cpos;
 
513
      switch( let ) {
 
514
        case 0: last_state = ST_att_eqx; goto done;
 
515
        case '/': // self closing
 
516
          if( *(cpos+1) == '>' ) {
 
517
            curnode->z = cpos+1-xmlin;
 
518
            curnode = curnode->parent;
 
519
            if( !curnode ) goto done; // bad error condition
 
520
            curatt->value = attval;
 
521
            curatt->vallen = attval_len;
 
522
            attval_len    = 0;
 
523
            cpos += 2;
 
524
            goto val_1;
 
525
          }
 
526
          break;
 
527
        case '>':
 
528
          curatt->value = attval;
 
529
          curatt->vallen = attval_len;
 
530
          attval_len    = 0;
 
531
          cpos++;
 
532
          goto val_1;
 
533
        case ' ':
 
534
          curatt->value = attval;
 
535
          curatt->vallen = attval_len;
 
536
          attval_len    = 0;
 
537
          cpos++;
 
538
          goto name_gap;
 
539
      }
 
540
      
 
541
      if( !attval_len ) attval = cpos;
 
542
      attval_len++;
 
543
      cpos++;
 
544
      goto att_eqx;
 
545
      
 
546
    att_quot:
 
547
      let = *cpos;
 
548
      
 
549
      if( let == '"' ) {
 
550
        if( attval_len ) {
 
551
          curatt->value = attval;
 
552
          curatt->vallen = attval_len;
 
553
          attval_len = 0;
 
554
        }
 
555
        cpos++;
 
556
        goto name_gap;
 
557
      }
 
558
      if( !let ) { last_state = ST_att_quot; goto done; }
 
559
      if( !attval_len ) attval = cpos;
 
560
      attval_len++;
 
561
      cpos++;
 
562
      goto att_quot;
 
563
      
 
564
    att_quots:
 
565
      let = *cpos;
 
566
      
 
567
      if( let == 0x27 ) { // '
 
568
        if( attval_len ) {
 
569
          curatt->value = attval;
 
570
          curatt->vallen = attval_len;
 
571
          attval_len = 0;
 
572
        }
 
573
        cpos++;
 
574
        goto name_gap;
 
575
      }
 
576
      if( !let ) { last_state = ST_att_quots; goto done; }
 
577
      
 
578
      if( !attval_len ) attval = cpos;
 
579
      attval_len++;
 
580
      cpos++;
 
581
      goto att_quots;
 
582
      
 
583
    att_tick:
 
584
      let = *cpos;
 
585
      
 
586
      if( let == '`' ) {
 
587
        if( attval_len ) {
 
588
          curatt->value = attval;
 
589
          curatt->vallen = attval_len;
 
590
          attval_len = 0;
 
591
        }
 
592
        cpos++;
 
593
        goto name_gap;
 
594
      }
 
595
      if( !let ) { last_state = ST_att_tick; goto done; }
 
596
      
 
597
      if( !attval_len ) attval = cpos;
 
598
      attval_len++;
 
599
      cpos++;
 
600
      goto att_tick;
 
601
      
 
602
    ename_1:
 
603
      let = *cpos;
 
604
      if( let == '>' ) {
 
605
        curnode->namelen = tagname_len;
 
606
        curnode->z = cpos-xmlin;
 
607
        curnode = curnode->parent; // jump up
 
608
        if( !curnode ) goto done;
 
609
        tagname_len++;
 
610
        cpos++;
 
611
        root->err = -1;
 
612
        goto error;
 
613
      }
 
614
      if( !let ) { last_state = ST_ename_1; goto done; }
 
615
      tagname       = cpos;
 
616
      tagname_len   = 1;
 
617
      cpos++;
 
618
      // continue
 
619
      
 
620
    ename_x: // ending name
 
621
      let = *cpos;
 
622
      if( let == '>' ) {
 
623
        if( curnode->namelen != tagname_len ) {
 
624
          goto error;
 
625
        }
 
626
        if( res = dh_memcmp( curnode->name, tagname, tagname_len ) ) {
 
627
          #ifdef DEBUG
 
628
          printf("Closing node not equal: curnode->name=%.*s - opening tag=%.*s\n", tagname_len, curnode->name, tagname_len, tagname );
 
629
          #endif
 
630
          cpos -= tagname_len;
 
631
          cpos += res - 1;
 
632
          goto error;
 
633
        }
 
634
        curnode->z = cpos-xmlin;
 
635
        curnode = curnode->parent; // jump up
 
636
        if( !curnode ) goto done;
 
637
        tagname_len++;
 
638
        cpos++;
 
639
        
 
640
        goto val_1;
 
641
      }
 
642
      if( !let ) { last_state = ST_ename_x; goto done; }
 
643
      tagname_len++;
 
644
      cpos++;
 
645
      goto ename_x;
 
646
    error:
 
647
      self->err = - ( int ) ( cpos - &xmlin[0] );
 
648
      return self->err;
 
649
    done:
 
650
      #ifdef DEBUG
 
651
      printf("done\n", *cpos);
 
652
      #endif
 
653
      
 
654
      // store the current state of the parser
 
655
      self->last_state = last_state;
 
656
      self->curnode = curnode;
 
657
      self->curatt = curatt;
 
658
      self->tagname = tagname; self->tagname_len = tagname_len;
 
659
      self->attname = attname; self->attname_len = attname_len;
 
660
      self->attval  = attval;  self->attval_len  = attval_len;
 
661
      self->att_has_val = att_has_val;
 
662
      
 
663
      #ifdef DEBUG
 
664
      printf("returning\n", *cpos);
 
665
      #endif
 
666
      return 0;//no error
 
667
}
 
668
 
 
669
int parserc_parse_unsafely( struct parserc *self, char *xmlin ) {
 
670
    // Variables that represent current 'state'
 
671
    struct nodec *root    = NULL;
 
672
    char  *tagname        = NULL; int    tagname_len    = 0;
 
673
    char  *attname        = NULL; int    attname_len    = 0;
 
674
    char  *attval         = NULL; int    attval_len     = 0;
 
675
    int    att_has_val    = 0;
 
676
    struct nodec *curnode = NULL;
 
677
    struct attc  *curatt  = NULL;
 
678
    int    last_state     = 0;
 
679
    self->rootpos = xmlin;
 
680
    
 
681
    // Variables used temporarily during processing
 
682
    struct nodec *temp;
 
683
    char   *cpos          = &xmlin[0];
 
684
    int    res            = 0;
 
685
    int    dent;
 
686
    register int let;
 
687
    
 
688
    if( self->last_state ) {
 
689
      return -1; // unsafe doesn't support this
 
690
    }
 
691
    else {
 
692
      self->err = 0;
 
693
      curnode = root = self->rootnode = new_nodec();
 
694
    }
 
695
    
 
696
    #ifdef DEBUG
 
697
    printf("Entry to C Parser\n");
 
698
    #endif
 
699
    
 
700
    u_val_1: // content
 
701
      #ifdef DEBUG
 
702
      printf("val_1: %c\n", *cpos);
 
703
      #endif
 
704
      switch( *cpos ) {
 
705
        case 0: last_state = ST_val_1; goto u_done;
 
706
        case '<': goto u_val_x;
 
707
      }
 
708
      if( !curnode->numvals ) {
 
709
        curnode->value = cpos;
 
710
        curnode->vallen = 1;
 
711
      }
 
712
      curnode->numvals++;
 
713
      cpos++;
 
714
      
 
715
    u_val_x: // content
 
716
      #ifdef DEBUG
 
717
      printf("val_x: %c\n", *cpos);
 
718
      #endif
 
719
      switch( *cpos ) {
 
720
        case 0: last_state = ST_val_x; goto u_done;
 
721
        case '<':
 
722
          if( *(cpos+1) == '!' &&
 
723
              *(cpos+2) == '[' &&
 
724
              *(cpos+3) == 'C' &&
 
725
              *(cpos+4) == 'D' &&
 
726
              *(cpos+5) == 'A' &&
 
727
              *(cpos+6) == 'T' &&
 
728
              *(cpos+7) == 'A'    ) {
 
729
            cpos += 9;
 
730
            curnode->type = 1;
 
731
            goto u_cdata;
 
732
          }
 
733
          
 
734
          tagname_len = 0; // for safety
 
735
          cpos++;
 
736
          goto u_name_1;
 
737
      }
 
738
      if( curnode->numvals == 1 ) curnode->vallen++;
 
739
      cpos++;
 
740
      goto u_val_x;
 
741
    
 
742
    u_cdata:
 
743
      if( *cpos == ']' && *(cpos+1) == ']' && *(cpos+2) == '>' ) {
 
744
        cpos += 3;
 
745
        goto u_val_1;
 
746
      }
 
747
      if( !curnode->numvals ) {
 
748
        curnode->value = cpos;
 
749
        curnode->vallen = 0;
 
750
        curnode->numvals = 1;
 
751
      }
 
752
      if( curnode->numvals == 1 ) curnode->vallen++;
 
753
      cpos++;
 
754
      goto u_cdata;
 
755
      
 
756
    u_name_1: // node name
 
757
      #ifdef DEBUG
 
758
      printf("name_1: %c\n", *cpos);
 
759
      #endif
 
760
      switch( *cpos ) {
 
761
        case '/': // regular closing tag
 
762
          tagname_len = 0; // needed to reset
 
763
          cpos++;
 
764
          goto u_ename_1;
 
765
      }
 
766
      tagname       = cpos;
 
767
      tagname_len   = 1;
 
768
      cpos++;
 
769
      goto u_name_x;
 
770
      
 
771
    u_name_x: // node name
 
772
      #ifdef DEBUG
 
773
      printf("name_x: %c\n", *cpos);
 
774
      #endif
 
775
      switch( *cpos ) {
 
776
        case ' ':
 
777
          curnode     = nodec_addchildr( curnode, tagname, tagname_len );
 
778
          attname_len = 0;
 
779
          cpos++;
 
780
          goto u_name_gap;
 
781
        case '>':
 
782
          curnode     = nodec_addchildr( curnode, tagname, tagname_len );
 
783
          cpos++;
 
784
          goto u_val_1;
 
785
        case '/': // self closing
 
786
          temp = nodec_addchildr( curnode, tagname, tagname_len );
 
787
          tagname_len = 0;
 
788
          cpos+=2;
 
789
          goto u_val_1;
 
790
      }
 
791
      
 
792
      tagname_len++;
 
793
      cpos++;
 
794
      goto u_name_x;
 
795
          
 
796
    u_name_gap: // node name gap
 
797
      switch( *cpos ) {
 
798
        case ' ':
 
799
        case '>':
 
800
          cpos++;
 
801
          goto u_val_1;
 
802
        case '/': // self closing
 
803
          curnode = curnode->parent;
 
804
          if( !curnode ) goto u_done;
 
805
          cpos += 2; // am assuming next char is >
 
806
          goto u_val_1;
 
807
      }
 
808
        
 
809
    u_att_name1:
 
810
      #ifdef DEBUG
 
811
      printf("attname1: %c\n", *cpos);
 
812
      #endif
 
813
      att_has_val = 0;
 
814
      attname = cpos;
 
815
      attname_len = 1;
 
816
      cpos++;
 
817
      goto u_att_name;
 
818
      
 
819
    u_att_space:
 
820
      if( *cpos == '=' ) {
 
821
          att_has_val = 1;
 
822
          cpos++;
 
823
          goto u_att_eq1;
 
824
      }
 
825
      // we have another attribute name, so continue
 
826
      
 
827
    u_att_name:
 
828
      #ifdef DEBUG
 
829
      printf("attname: %c\n", *cpos);
 
830
      #endif
 
831
      let = *cpos;
 
832
      switch( let ) {
 
833
        case '/': // self closing     !! /> is assumed !!
 
834
          curatt = nodec_addattr( curnode, attname, attname_len );
 
835
          if( !att_has_val ) { curatt->value = -1; curatt->vallen = 0; }
 
836
          attname_len = 0;
 
837
          
 
838
          curnode = curnode->parent;
 
839
          if( !curnode ) goto u_done;
 
840
          cpos += 2;
 
841
          goto u_val_1;
 
842
        case ' ':
 
843
          if( *(cpos+1) == '=' ) {
 
844
            cpos++;
 
845
            goto u_att_name;
 
846
          }
 
847
          curatt = nodec_addattr( curnode, attname, attname_len );
 
848
          attname_len = 0;
 
849
          cpos++;
 
850
          goto u_att_space;
 
851
        case '>':
 
852
          curatt = nodec_addattr( curnode, attname, attname_len );
 
853
          if( !att_has_val ) { curatt->value = -1; curatt->vallen = 0; }
 
854
          attname_len = 0;
 
855
          cpos++;
 
856
          goto u_val_1;
 
857
        case '=':
 
858
          attval_len = 0;
 
859
          curatt = nodec_addattr( curnode, attname, attname_len );
 
860
          attname_len = 0;
 
861
          cpos++;
 
862
          goto u_att_eq1;
 
863
      }
 
864
      
 
865
      if( !attname_len ) attname = cpos;
 
866
      attname_len++;
 
867
      cpos++;
 
868
      goto u_att_name;
 
869
      
 
870
    u_att_eq1:
 
871
      switch( *cpos ) {
 
872
        case '/': // self closing
 
873
          if( *(cpos+1) == '>' ) {
 
874
            curnode = curnode->parent;
 
875
            if( !curnode ) goto u_done;
 
876
            cpos += 2;
 
877
            goto u_att_eq1;
 
878
          }
 
879
          break;
 
880
        case '"':  cpos++; goto u_att_quot;
 
881
        case 0x27: cpos++; goto u_att_quots; //'
 
882
        case '>':  cpos++; goto u_val_1;
 
883
        case ' ':  cpos++; goto u_att_eq1;
 
884
      }  
 
885
      if( !attval_len ) attval = cpos;
 
886
      attval_len++;
 
887
      cpos++;
 
888
      goto u_att_eqx;
 
889
      
 
890
    u_att_eqx:
 
891
      switch( *cpos ) {
 
892
        case '/': // self closing
 
893
          if( *(cpos+1) == '>' ) {
 
894
            curnode = curnode->parent;
 
895
            if( !curnode ) goto u_done; // bad error condition
 
896
            curatt->value = attval;
 
897
            curatt->vallen = attval_len;
 
898
            attval_len    = 0;
 
899
            cpos += 2;
 
900
            goto u_val_1;
 
901
          }
 
902
          break;
 
903
        case '>':
 
904
          curatt->value = attval;
 
905
          curatt->vallen = attval_len;
 
906
          attval_len    = 0;
 
907
          cpos++;
 
908
          goto u_val_1;
 
909
        case ' ':
 
910
          curatt->value = attval;
 
911
          curatt->vallen = attval_len;
 
912
          attval_len    = 0;
 
913
          cpos++;
 
914
          goto u_name_gap;
 
915
      }
 
916
      
 
917
      if( !attval_len ) attval = cpos;
 
918
      attval_len++;
 
919
      cpos++;
 
920
      goto u_att_eqx;
 
921
      
 
922
    u_att_quot:
 
923
      if( *cpos == '"' ) {
 
924
        if( attval_len ) {
 
925
          curatt->value = attval;
 
926
          curatt->vallen = attval_len;
 
927
          attval_len = 0;
 
928
        }
 
929
        cpos++;
 
930
        goto u_name_gap;
 
931
      }
 
932
      if( !attval_len ) attval = cpos;
 
933
      attval_len++;
 
934
      cpos++;
 
935
      goto u_att_quot;
 
936
      
 
937
    u_att_quots:
 
938
      if( *cpos == 0x27 ) { // '
 
939
        if( attval_len ) {
 
940
          curatt->value = attval;
 
941
          curatt->vallen = attval_len;
 
942
          attval_len = 0;
 
943
        }
 
944
        cpos++;
 
945
        goto u_name_gap;
 
946
      }
 
947
      if( !attval_len ) attval = cpos;
 
948
      attval_len++;
 
949
      cpos++;
 
950
      goto u_att_quots;
 
951
      
 
952
    u_ename_1:
 
953
      tagname       = cpos;
 
954
      tagname_len   = 1;
 
955
      cpos++;
 
956
      // continue
 
957
      
 
958
    u_ename_x: // ending name
 
959
      let = *cpos;
 
960
      if( let == '>' ) {
 
961
        curnode->z = cpos-xmlin;
 
962
        curnode = curnode->parent; // jump up
 
963
        if( !curnode ) goto u_done;
 
964
        tagname_len++;
 
965
        cpos++;
 
966
        
 
967
        goto u_val_1;
 
968
      }
 
969
      tagname_len++;
 
970
      cpos++;
 
971
      goto u_ename_x;
 
972
    
 
973
    u_done:
 
974
      #ifdef DEBUG
 
975
      printf("done\n", *cpos);
 
976
      #endif
 
977
      
 
978
      // store the current state of the parser
 
979
      self->last_state = last_state;
 
980
      self->curnode = curnode;
 
981
      self->curatt = curatt;
 
982
      self->tagname = tagname; self->tagname_len = tagname_len;
 
983
      self->attname = attname; self->attname_len = attname_len;
 
984
      self->attval  = attval;  self->attval_len  = attval_len;
 
985
      self->att_has_val = att_has_val;
 
986
      
 
987
      #ifdef DEBUG
 
988
      printf("returning\n", *cpos);
 
989
      #endif
 
990
      return 0;//no error
 
991
}
 
992
 
 
993
struct utfchar {
 
994
  char high;
 
995
  char low;
 
996
};
 
997
 
 
998
struct nodec *nodec_addchildr(  struct nodec *self, char *newname, int newnamelen ) {
 
999
  struct nodec *newnode = new_nodecp( self );
 
1000
  newnode->name    = newname;
 
1001
  newnode->namelen = newnamelen;
 
1002
  if( self->numchildren == 0 ) {
 
1003
    self->firstchild = newnode;
 
1004
    self->lastchild  = newnode;
 
1005
    self->numchildren++;
 
1006
    return newnode;
 
1007
  }
 
1008
  else {
 
1009
    self->lastchild->next = newnode;
 
1010
    self->lastchild = newnode;
 
1011
    self->numchildren++;
 
1012
    return newnode;
 
1013
  }
 
1014
}
 
1015
 
 
1016
struct attc *nodec_addattr( struct nodec *self, char *newname, int newnamelen ) {
 
1017
  struct attc *newatt = new_attc( self );
 
1018
  newatt->name    = newname;
 
1019
  newatt->namelen = newnamelen;
 
1020
  
 
1021
  if( !self->numatt ) {
 
1022
    self->firstatt = newatt;
 
1023
    self->lastatt  = newatt;
 
1024
    self->numatt++;
 
1025
    return newatt;
 
1026
  }
 
1027
  else {
 
1028
    self->lastatt->next = newatt;
 
1029
    self->lastatt = newatt;
 
1030
    self->numatt++;
 
1031
    return newatt;
 
1032
  }
 
1033
}