root / trunk / ext / yamlbyte / ybext.c

Revision 108, 6.6 kB (checked in by cce, 5 years ago)

syck to yaml bytecodes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1//
2// ybext.c
3//
4// $Author$
5// $Date$
6//
7// Copyright (C) 2003 why the lucky stiff, clark evans
8//
9//   WARNING WARNING WARNING  --- THIS IS *JUST* PLAYING
10//
11#include <syck.h>
12#include <assert.h>
13#define YAMLBYTE_UTF8
14#include "yamlbyte.h"
15
16#include <stdio.h>
17#define TRACE0(a)  \
18    do { printf(a); printf("\n"); fflush(stdout); } while(0)
19#define TRACE1(a,b) \
20    do { printf(a,b); printf("\n"); fflush(stdout); } while(0)
21#define TRACE2(a,b,c) \
22    do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0)
23#define TRACE3(a,b,c,d) \
24    do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0)
25
26/* Reinvent the wheel... */
27#define CHUNKSIZE 64
28#define HASH ((long)0xCAFECAFECAFECAFE)
29typedef struct {
30   long hash;
31   char *buffer;
32   long length;
33   long remaining;
34   int  printed;
35} bytestring_t;
36bytestring_t *bytestring_alloc() {
37    bytestring_t *ret;
38    //TRACE0("bytestring_alloc()");
39    ret = S_ALLOC(bytestring_t);
40    ret->hash   = HASH;
41    ret->length = CHUNKSIZE;
42    ret->remaining = ret->length;
43    ret->buffer = S_ALLOC_N(char, ret->length + 1 );
44    ret->buffer[0] = 0;
45    ret->printed = 0;
46    return ret;
47}
48void bytestring_append(bytestring_t *str, char code,
49                       char *start, char *finish)
50{
51    long grow;
52    long length = 2;   /* CODE + LF */
53    char *curr;
54    assert(str && HASH == str->hash);
55    //TRACE0("bytestring_append()");
56    if(start) {
57        if(!finish)
58            finish = start + strlen(start);
59        length += (finish-start);
60    }
61    if(length > str->remaining) {
62        grow = (length - str->remaining) + CHUNKSIZE;
63        str->remaining += grow;
64        str->length    += grow;
65        str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 );
66        assert(str->buffer);
67    }
68    curr = str->buffer + (str->length - str->remaining);
69    *curr = code;
70    curr += 1;
71    if(start)
72        while(start < finish)
73            *curr ++ = *start ++;
74    *curr = '\n';
75    curr += 1;
76    *curr = 0;
77    str->remaining = str->remaining - length;
78    assert( (str->buffer + str->length) - str->remaining );
79}
80void bytestring_extend(bytestring_t *str, bytestring_t *ext)
81{
82    char *from;
83    char *curr;
84    char *stop;
85    long grow;
86    long length;
87    assert(str && HASH == str->hash);
88    assert(ext && HASH == ext->hash);
89    if(ext->printed) {
90        assert(ext->buffer[0] ==YAMLBYTE_ANCHOR);
91        curr = ext->buffer;
92        while( '\n' != *curr)
93            curr++;
94        bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr);
95    } else {
96        ext->printed = 1;
97        length  = (ext->length - ext->remaining);
98        if(length > str->remaining) {
99            grow = (length - str->remaining) + CHUNKSIZE;
100            str->remaining += grow;
101            str->length    += grow;
102            str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 );
103        }
104        curr = str->buffer + (str->length - str->remaining);
105        from = ext->buffer;
106        stop = ext->buffer + length;
107        while( from < stop )
108            *curr ++ = *from ++;
109        *curr = 0;
110        str->remaining = str->remaining - length;
111        assert( (str->buffer + str->length) - str->remaining );
112    }
113}
114
115/* convert SyckNode into yamlbyte_buffer_t objects */
116SYMID
117  yb_handler(p, n)
118    SyckParser *p;
119    SyckNode *n;
120{
121    SYMID oid;
122    long i;
123    char ch;
124    char nextcode;
125    char *start;
126    char *current;
127    char *finish;
128    bytestring_t *val = NULL;
129    bytestring_t *sav = NULL;
130    //TRACE0("yb_handler()");
131    val = bytestring_alloc();
132    if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL);
133    if(n->type_id) bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL);
134    switch (n->kind)
135    {
136        case syck_str_kind:
137            nextcode = YAMLBYTE_SCALAR;
138            start  = n->data.str->ptr;
139            finish = start + n->data.str->len - 1;
140            current = start;
141            //TRACE2("SCALAR: %s %d", start, n->data.str->len);
142            while(1) {
143                ch = *current;
144                if('\n' == ch || 0 == ch || current > finish) {
145                    if(current > start) {
146                        bytestring_append(val, nextcode, start, current);
147                        nextcode = YAMLBYTE_CONTINUE;
148                        start = current + 1;
149                    }
150                    if(current > finish)
151                        break;
152                    else if('\n' == ch )
153                        bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL);
154                    else if(0 == ch)
155                        bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL);
156                    else
157                        assert("oops");
158                }
159                current += 1;
160            }
161        break;
162        case syck_seq_kind:
163            bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL);
164            for ( i = 0; i < n->data.list->idx; i++ )
165            {
166                oid = syck_seq_read( n, i );
167                syck_lookup_sym( p, oid, (char **)&sav );
168                bytestring_extend(val, sav);
169            }
170            bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
171        break;
172        case syck_map_kind:
173            bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL);
174            for ( i = 0; i < n->data.pairs->idx; i++ )
175            {
176                oid = syck_map_read( n, map_key, i );
177                syck_lookup_sym( p, oid, (char **)&sav );
178                bytestring_extend(val, sav);
179                oid = syck_map_read( n, map_value, i );
180                syck_lookup_sym( p, oid, (char **)&sav );
181                bytestring_extend(val, sav);
182            }
183            bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
184        break;
185    }
186    oid = syck_add_sym( p, (char *) val );
187    //TRACE1("Saving: %s", val->buffer );
188    return oid;
189}
190
191char *
192syck_bytecode(char *yamlstr)
193{
194    SYMID oid;
195    char *ret;
196    bytestring_t *sav;
197    SyckParser *parser = syck_new_parser();
198    syck_parser_str_auto( parser, yamlstr, NULL );
199    syck_parser_handler( parser, yb_handler );
200    syck_parser_error_handler( parser, NULL );
201    syck_parser_implicit_typing( parser, 1 );
202    syck_parser_taguri_expansion( parser, 1 );
203    oid = syck_parse( parser );
204    syck_lookup_sym( parser, oid, (char **)&sav );
205    ret = sav->buffer;
206    /* TODO: free up node stuff stored */
207    syck_free_parser( parser );
208    return ret;
209}
210
211#ifdef TEST_YBEXT
212#include <stdio.h>
213int main() {
214   char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3";
215   printf("--- # YAML \n");
216   printf(yaml);
217   printf("\n...\n");
218   printf(syck_bytecode(yaml));
219   return 0;
220}
221#endif
222
Note: See TracBrowser for help on using the browser.