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

« back to all changes in this revision

Viewing changes to Bare.xs

  • Committer: Bazaar Package Importer
  • Author(s): Antonio Radici
  • Date: 2009-01-31 17:28:53 UTC
  • Revision ID: james.westby@ubuntu.com-20090131172853-hptyu448d89nsje4
Tags: upstream-0.40+dfsg.1
ImportĀ upstreamĀ versionĀ 0.40+dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// JEdit mode Line -> :folding=indent:mode=c++:indentSize=2:noTabs=true:tabSize=2:
 
2
#include "EXTERN.h"
 
3
#define PERL_IN_HV_C
 
4
#define PERL_HASH_INTERNAL_ACCESS
 
5
#define BLIND_PV(a,b) SV *sv;sv=newSV(0);SvUPGRADE(sv,SVt_PV);SvPV_set(sv,a);SvCUR_set(sv,b);SvPOK_only_UTF8(sv);
 
6
 
 
7
#include "perl.h"
 
8
#include "XSUB.h"
 
9
#include "parser.h"
 
10
 
 
11
 
 
12
struct nodec *root;
 
13
 
 
14
U32 vhash;
 
15
U32 chash;
 
16
U32 phash;
 
17
U32 ihash;
 
18
 
 
19
struct nodec *curnode;
 
20
char *rootpos;
 
21
  
 
22
SV *cxml2obj(pTHX_ int a) {
 
23
  HV *output = newHV();
 
24
  SV *outputref = newRV( (SV *) output );
 
25
  int i;
 
26
  struct attc *curatt;
 
27
  int numatts = curnode->numatt;
 
28
  SV *attval;
 
29
  SV *attatt;
 
30
      
 
31
  int length = curnode->numchildren;
 
32
  SV *svi = newSViv( curnode->pos );
 
33
  
 
34
  #ifdef DEBUG
 
35
  printf("[");
 
36
  #endif
 
37
  hv_store( output, "_pos", 4, svi, phash );
 
38
  hv_store( output, "_i", 2, newSViv( curnode->name - rootpos ), ihash );
 
39
  if( !length ) {
 
40
    if( curnode->vallen ) {
 
41
      SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
42
      //BLIND_PV( curnode->value, curnode->vallen );
 
43
      hv_store( output, "value", 5, sv, vhash );
 
44
    }
 
45
    if( curnode->comlen ) {
 
46
      SV * sv = newSVpvn( curnode->comment, curnode->comlen );
 
47
      hv_store( output, "comment", 7, sv, chash );
 
48
    }
 
49
  }
 
50
  else {
 
51
    if( curnode->vallen ) {
 
52
      SV *sv = newSVpvn( curnode->value, curnode->vallen );
 
53
      //BLIND_PV( curnode->value, curnode->vallen );
 
54
      hv_store( output, "value", 5, sv, vhash );
 
55
    }
 
56
    if( curnode->comlen ) {
 
57
      SV *sv = newSVpvn( curnode->comment, curnode->comlen );
 
58
      hv_store( output, "comment", 7, sv, chash );
 
59
    }
 
60
    
 
61
    curnode = curnode->firstchild;
 
62
    for( i = 0; i < length; i++ ) {
 
63
      SV *namesv = newSVpvn( curnode->name, curnode->namelen );
 
64
      
 
65
      SV **cur = hv_fetch( output, curnode->name, curnode->namelen, 0 );
 
66
      
 
67
      if( curnode->namelen > 6 ) {
 
68
        if( !strncmp( curnode->name, "multi_", 6 ) ) {
 
69
          char *subname = &curnode->name[6];
 
70
          int subnamelen = curnode->namelen-6;
 
71
          SV **old = hv_fetch( output, subname, subnamelen, 0 );
 
72
          AV *newarray = newAV();
 
73
          SV *newarrayref = newRV( (SV *) newarray );
 
74
          if( !old ) {
 
75
            hv_store( output, subname, subnamelen, newarrayref, 0 );
 
76
          }
 
77
          else {
 
78
            if( SvTYPE( SvRV(*old) ) == SVt_PVHV ) { // check for hash ref
 
79
              SV *newref = newRV( (SV *) SvRV(*old) );
 
80
              hv_delete( output, subname, subnamelen, 0 );
 
81
              hv_store( output, subname, subnamelen, newarrayref, 0 );
 
82
              av_push( newarray, newref );
 
83
            }
 
84
          }
 
85
        }
 
86
      }
 
87
      
 
88
      if( !cur ) {
 
89
        SV *ob = cxml2obj( aTHX_ 0 );
 
90
        hv_store( output, curnode->name, curnode->namelen, ob, 0 );
 
91
      }
 
92
      else {
 
93
        if( SvTYPE( SvRV(*cur) ) == SVt_PVHV ) {
 
94
          AV *newarray = newAV();
 
95
          SV *newarrayref = newRV( (SV *) newarray );
 
96
          SV *newref = newRV( (SV *) SvRV( *cur ) );
 
97
          hv_delete( output, curnode->name, curnode->namelen, 0 );
 
98
          hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
99
          av_push( newarray, newref );
 
100
          av_push( newarray, cxml2obj( aTHX_ 0 ) );
 
101
        }
 
102
        else {
 
103
          AV *av = (AV *) SvRV( *cur );
 
104
          av_push( av, cxml2obj( aTHX_ 0) );
 
105
        }
 
106
      }
 
107
      if( i != ( length - 1 ) ) curnode = curnode->next;
 
108
    }
 
109
    
 
110
    curnode = curnode->parent;
 
111
  }
 
112
  
 
113
  if( numatts ) {
 
114
    curatt = curnode->firstatt;
 
115
    for( i = 0; i < numatts; i++ ) {
 
116
      HV *atth = newHV();
 
117
      SV *atthref = newRV( (SV *) atth );
 
118
      hv_store( output, curatt->name, curatt->namelen, atthref, 0 );
 
119
      
 
120
      attval = newSVpvn( curatt->value, curatt->vallen );
 
121
      hv_store( atth, "value", 5, attval, vhash );
 
122
      attatt = newSViv( 1 );
 
123
      hv_store( atth, "att", 3, attatt, 0 );
 
124
      if( i != ( numatts - 1 ) ) curatt = curatt->next;
 
125
    }
 
126
  }
 
127
  return outputref;
 
128
}
 
129
 
 
130
SV *cxml2obj_simple(pTHX_ int a) {
 
131
  SV *outputref;
 
132
  int i;
 
133
  struct attc *curatt;
 
134
  int numatts = curnode->numatt;
 
135
  SV *attval;
 
136
  SV *attatt;
 
137
    
 
138
  int length = curnode->numchildren;
 
139
  if( ( length + numatts ) == 0 ) {
 
140
    if( curnode->vallen ) {
 
141
      SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
142
      return sv;
 
143
    }
 
144
    return 0;
 
145
  }
 
146
  {
 
147
    HV *output = newHV();
 
148
    SV *outputref = newRV( (SV *) output );
 
149
    
 
150
    if( length ) {
 
151
      curnode = curnode->firstchild;
 
152
      for( i = 0; i < length; i++ ) {
 
153
        SV *namesv = newSVpvn( curnode->name, curnode->namelen );
 
154
        
 
155
        SV **cur = hv_fetch( output, curnode->name, curnode->namelen, 0 );
 
156
        
 
157
        if( curnode->namelen > 6 ) {
 
158
          if( !strncmp( curnode->name, "multi_", 6 ) ) {
 
159
            char *subname = &curnode->name[6];
 
160
            int subnamelen = curnode->namelen-6;
 
161
            SV **old = hv_fetch( output, subname, subnamelen, 0 );
 
162
            AV *newarray = newAV();
 
163
            SV *newarrayref = newRV( (SV *) newarray );
 
164
            if( !old ) {
 
165
              hv_store( output, subname, subnamelen, newarrayref, 0 );
 
166
            }
 
167
            else {
 
168
              if( SvTYPE( SvRV(*old) ) == SVt_PVHV ) { // check for hash ref
 
169
                SV *newref = newRV( (SV *) SvRV(*old) );
 
170
                hv_delete( output, subname, subnamelen, 0 );
 
171
                hv_store( output, subname, subnamelen, newarrayref, 0 );
 
172
                av_push( newarray, newref );
 
173
              }
 
174
            }
 
175
          }
 
176
        }
 
177
          
 
178
        if( !cur ) {
 
179
          SV *ob = cxml2obj_simple( aTHX_ 0 );
 
180
          hv_store( output, curnode->name, curnode->namelen, ob, 0 );
 
181
        }
 
182
        else {
 
183
          if( SvROK( *cur ) ) {
 
184
            if( SvTYPE( SvRV(*cur) ) == SVt_PVHV ) {
 
185
              AV *newarray = newAV();
 
186
              SV *newarrayref = newRV( (SV *) newarray );
 
187
              SV *newref = newRV( (SV *) SvRV( *cur ) );
 
188
              hv_delete( output, curnode->name, curnode->namelen, 0 );
 
189
              hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
190
              av_push( newarray, newref );
 
191
              av_push( newarray, cxml2obj_simple( aTHX_ 0 ) );
 
192
            }
 
193
            else {
 
194
              AV *av = (AV *) SvRV( *cur );
 
195
              av_push( av, cxml2obj_simple( aTHX_ 0) );
 
196
            }
 
197
          }
 
198
          else {
 
199
            AV *newarray = newAV();
 
200
            SV *newarrayref = newRV( (SV *) newarray );
 
201
            
 
202
            STRLEN len;
 
203
            char *ptr = SvPV(*cur, len);
 
204
            SV *newsv = newSVpvn( ptr, len );
 
205
            
 
206
            av_push( newarray, newsv );
 
207
            hv_delete( output, curnode->name, curnode->namelen, 0 );
 
208
            hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
209
            av_push( newarray, cxml2obj_simple( aTHX_ 0 ) );
 
210
          }
 
211
        }
 
212
        if( i != ( length - 1 ) ) curnode = curnode->next;
 
213
      }
 
214
      curnode = curnode->parent;
 
215
    }
 
216
    
 
217
    if( numatts ) {
 
218
      curatt = curnode->firstatt;
 
219
      for( i = 0; i < numatts; i++ ) {
 
220
        attval = newSVpvn( curatt->value, curatt->vallen );
 
221
        hv_store( output, curatt->name, curatt->namelen, attval, 0 );
 
222
        if( i != ( numatts - 1 ) ) curatt = curatt->next;
 
223
      }
 
224
    }
 
225
    
 
226
    return outputref;
 
227
  }
 
228
}
 
229
 
 
230
struct parserc *parser = 0;
 
231
 
 
232
MODULE = XML::Bare         PACKAGE = XML::Bare
 
233
 
 
234
 
 
235
 
 
236
SV *
 
237
xml2obj()
 
238
  CODE:
 
239
    curnode = parser->pcurnode;
 
240
    //curnode = root;
 
241
    if( curnode->err ) RETVAL = newSViv( curnode->err );
 
242
    else RETVAL = cxml2obj(aTHX_ 0);
 
243
  OUTPUT:
 
244
    RETVAL
 
245
    
 
246
SV *
 
247
xml2obj_simple()
 
248
  CODE:
 
249
    curnode = parser->pcurnode;
 
250
    //curnode = root;
 
251
    //if( curnode->err ) RETVAL = 0;
 
252
    //else
 
253
    RETVAL = cxml2obj_simple(aTHX_ 0);
 
254
  OUTPUT:
 
255
    RETVAL
 
256
 
 
257
void
 
258
c_parse(text)
 
259
  char * text
 
260
  CODE:
 
261
    
 
262
    rootpos = text;
 
263
    #ifdef DEBUG
 
264
    //printf("About to parse\n");
 
265
    #endif
 
266
    PERL_HASH(vhash, "value", 5);
 
267
    PERL_HASH(chash, "comment", 7);
 
268
    PERL_HASH(phash, "_pos", 4);
 
269
    PERL_HASH(ihash, "_i", 2 );
 
270
    parser = (struct parserc *) malloc( sizeof( struct parserc ) );
 
271
    root = parserc_parse( parser, text );
 
272
    #ifdef DEBUG
 
273
    //printf("Returned from parser\n");
 
274
    #endif
 
275
    
 
276
    //root = parser->pcurnode;
 
277
    //this is wrong because parsing may halt in the middle; root= above is correct
 
278
    
 
279
    #ifdef DEBUG
 
280
    //printf("C Parsing done\b");
 
281
    #endif
 
282
    
 
283
void
 
284
c_parsefile(filename)
 
285
  char * filename
 
286
  CODE:
 
287
    PERL_HASH(vhash, "value", 5);
 
288
    PERL_HASH(chash, "comment", 7);
 
289
    PERL_HASH(phash, "_pos", 4);
 
290
    PERL_HASH(ihash, "_i", 2 );
 
291
    char *data;
 
292
    unsigned long len;
 
293
    FILE *handle;
 
294
    handle = fopen(filename,"r");
 
295
    
 
296
    fseek( handle, 0, SEEK_END );
 
297
    
 
298
    len = ftell( handle );
 
299
    
 
300
    fseek( handle, 0, SEEK_SET );
 
301
    data = (char *) malloc( len );
 
302
    rootpos = data;
 
303
    fread( data, 1, len, handle );
 
304
    fclose( handle );
 
305
    parser = (struct parserc *) malloc( sizeof( struct parserc ) );
 
306
    root = parserc_parse( parser, data );
 
307
    //root = parser->pcurnode;
 
308
 
 
309
SV *
 
310
get_root()
 
311
  CODE:
 
312
    RETVAL = newSVuv( PTR2UV( root ) );
 
313
  OUTPUT:
 
314
    RETVAL
 
315
 
 
316
void
 
317
free_tree_c( rootsv )
 
318
  SV *rootsv
 
319
  CODE:
 
320
    struct nodec *rootnode;
 
321
    rootnode = INT2PTR( struct nodec *, SvUV( rootsv ) );
 
322
    del_nodec( rootnode );
 
 
b'\\ No newline at end of file'