Ruby  1.9.3p484(2013-11-22revision43786)
yaml2byte.c
Go to the documentation of this file.
1 /*
2  * yaml2byte.c
3  *
4  * $Author: nobu $
5  *
6  * Copyright (C) 2003 why the lucky stiff, clark evans
7  *
8  * WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING
9  * ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING!
10  */
11 #include "ruby/ruby.h"
12 #include <syck.h>
13 #include <assert.h>
14 #define YAMLBYTE_UTF8
15 #include "yamlbyte.h"
16 
17 #include <stdio.h>
18 #define TRACE0(a) \
19  do { printf(a); printf("\n"); fflush(stdout); } while(0)
20 #define TRACE1(a,b) \
21  do { printf(a,b); printf("\n"); fflush(stdout); } while(0)
22 #define TRACE2(a,b,c) \
23  do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0)
24 #define TRACE3(a,b,c,d) \
25  do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0)
26 
27 /* Reinvent the wheel... */
28 #define CHUNKSIZE 64
29 #define HASH ((long)0xCAFECAFE)
30 typedef struct {
31  long hash;
32  char *buffer;
33  long length;
34  long remaining;
35  int printed;
36 } bytestring_t;
38  bytestring_t *ret;
39  /*TRACE0("bytestring_alloc()");*/
40  ret = S_ALLOC(bytestring_t);
41  ret->hash = HASH;
42  ret->length = CHUNKSIZE;
43  ret->remaining = ret->length;
44  ret->buffer = S_ALLOC_N(char, ret->length + 1 );
45  ret->buffer[0] = 0;
46  ret->printed = 0;
47  return ret;
48 }
49 void bytestring_append(bytestring_t *str, char code,
50  char *start, char *finish)
51 {
52  long grow;
53  long length = 2; /* CODE + LF */
54  char *curr;
55  assert(str && HASH == str->hash);
56  /*TRACE0("bytestring_append()");*/
57  if(start) {
58  if(!finish)
59  finish = start + strlen(start);
60  length += (finish-start);
61  }
62  if(length > str->remaining) {
63  grow = (length - str->remaining) + CHUNKSIZE;
64  str->remaining += grow;
65  str->length += grow;
66  S_REALLOC_N( str->buffer, char, str->length + 1 );
67  assert(str->buffer);
68  }
69  curr = str->buffer + (str->length - str->remaining);
70  *curr = code;
71  curr += 1;
72  if(start)
73  while(start < finish)
74  *curr ++ = *start ++;
75  *curr = '\n';
76  curr += 1;
77  *curr = 0;
78  str->remaining = str->remaining - length;
79  assert( (str->buffer + str->length) - str->remaining );
80 }
82 {
83  char *from;
84  char *curr;
85  char *stop;
86  long grow;
87  long length;
88  assert(str && HASH == str->hash);
89  assert(ext && HASH == ext->hash);
90  if(ext->printed) {
91  assert(ext->buffer[0] ==YAMLBYTE_ANCHOR);
92  curr = ext->buffer;
93  while( '\n' != *curr)
94  curr++;
95  bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr);
96  } else {
97  ext->printed = 1;
98  length = (ext->length - ext->remaining);
99  if(length > str->remaining) {
100  grow = (length - str->remaining) + CHUNKSIZE;
101  str->remaining += grow;
102  str->length += grow;
103  S_REALLOC_N( str->buffer, char, str->length + 1 );
104  }
105  curr = str->buffer + (str->length - str->remaining);
106  from = ext->buffer;
107  stop = ext->buffer + length;
108  while( from < stop )
109  *curr ++ = *from ++;
110  *curr = 0;
111  str->remaining = str->remaining - length;
112  assert( (str->buffer + str->length) - str->remaining );
113  }
114 }
115 
116 /* convert SyckNode into yamlbyte_buffer_t objects */
117 SYMID
119  SyckParser *p;
120  SyckNode *n;
121 {
122  SYMID oid;
123  long i;
124  char ch;
125  char nextcode;
126  char *start;
127  char *current;
128  char *finish;
129  bytestring_t *val = NULL;
130  bytestring_t *sav = NULL;
131  void *data;
132  /*TRACE0("syck_yaml2byte_handler()");*/
133  val = bytestring_alloc();
135  if ( n->type_id )
136  {
137  if ( p->taguri_expansion )
138  {
140  }
141  else
142  {
143  char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 );
144  type_tag[0] = '\0';
145  strcat( type_tag, "!" );
146  strcat( type_tag, n->type_id );
147  bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL);
148  S_FREE(type_tag);
149  }
150  }
151  switch (n->kind)
152  {
153  case syck_str_kind:
154  nextcode = YAMLBYTE_SCALAR;
155  start = n->data.str->ptr;
156  finish = start + n->data.str->len - 1;
157  current = start;
158  /*TRACE2("SCALAR: %s %d", start, n->data.str->len); */
159  while(1) {
160  ch = *current;
161  if('\n' == ch || 0 == ch || current > finish) {
162  if(current >= start) {
163  bytestring_append(val, nextcode, start, current);
164  nextcode = YAMLBYTE_CONTINUE;
165  }
166  start = current + 1;
167  if(current > finish)
168  {
169  break;
170  }
171  else if('\n' == ch )
172  {
174  }
175  else if(0 == ch)
176  {
178  }
179  else
180  {
181  assert("oops");
182  }
183  }
184  current += 1;
185  }
186  break;
187  case syck_seq_kind:
189  for ( i = 0; i < n->data.list->idx; i++ )
190  {
191  oid = syck_seq_read( n, i );
192  if (syck_lookup_sym( p, oid, &data )) sav = data;
193  bytestring_extend(val, sav);
194  }
196  break;
197  case syck_map_kind:
199  for ( i = 0; i < n->data.pairs->idx; i++ )
200  {
201  oid = syck_map_read( n, map_key, i );
202  if (syck_lookup_sym( p, oid, &data )) sav = data;
203  bytestring_extend(val, sav);
204  oid = syck_map_read( n, map_value, i );
205  if (syck_lookup_sym( p, oid, &data )) sav = data;
206  bytestring_extend(val, sav);
207  }
209  break;
210  }
211  oid = syck_add_sym( p, (char *) val );
212  /*TRACE1("Saving: %s", val->buffer );*/
213  return oid;
214 }
215 
216 char *
217 syck_yaml2byte(char *yamlstr)
218 {
219  SYMID oid;
220  char *ret;
221  bytestring_t *sav;
222  void *data;
223 
224  SyckParser *parser = syck_new_parser();
225  syck_parser_str_auto( parser, yamlstr, NULL );
227  syck_parser_error_handler( parser, NULL );
228  syck_parser_implicit_typing( parser, 1 );
229  syck_parser_taguri_expansion( parser, 1 );
230  oid = syck_parse( parser );
231 
232  if ( syck_lookup_sym( parser, oid, &data ) ) {
233  sav = data;
234  ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 );
235  ret[0] = '\0';
236  strcat( ret, "D\n" );
237  strcat( ret, sav->buffer );
238  }
239  else
240  {
241  ret = NULL;
242  }
243 
244  syck_free_parser( parser );
245  return ret;
246 }
247 
248 #ifdef TEST_YBEXT
249 #include <stdio.h>
250 int main() {
251  char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3";
252  printf("--- # YAML \n");
253  printf(yaml);
254  printf("\n...\n");
255  printf(syck_yaml2byte(yaml));
256  return 0;
257 }
258 #endif
259 
260