diff options
Diffstat (limited to 'trunk/ext/syck')
-rw-r--r-- | trunk/ext/syck/.cvsignore | 4 | ||||
-rw-r--r-- | trunk/ext/syck/bytecode.c | 1165 | ||||
-rw-r--r-- | trunk/ext/syck/depend | 12 | ||||
-rw-r--r-- | trunk/ext/syck/emitter.c | 1247 | ||||
-rw-r--r-- | trunk/ext/syck/extconf.rb | 5 | ||||
-rw-r--r-- | trunk/ext/syck/gram.c | 1894 | ||||
-rw-r--r-- | trunk/ext/syck/gram.h | 79 | ||||
-rw-r--r-- | trunk/ext/syck/handler.c | 173 | ||||
-rw-r--r-- | trunk/ext/syck/implicit.c | 2990 | ||||
-rw-r--r-- | trunk/ext/syck/node.c | 407 | ||||
-rw-r--r-- | trunk/ext/syck/rubyext.c | 2284 | ||||
-rw-r--r-- | trunk/ext/syck/syck.c | 524 | ||||
-rw-r--r-- | trunk/ext/syck/syck.h | 454 | ||||
-rw-r--r-- | trunk/ext/syck/token.c | 2724 | ||||
-rw-r--r-- | trunk/ext/syck/yaml2byte.c | 259 | ||||
-rw-r--r-- | trunk/ext/syck/yamlbyte.h | 170 |
16 files changed, 14391 insertions, 0 deletions
diff --git a/trunk/ext/syck/.cvsignore b/trunk/ext/syck/.cvsignore new file mode 100644 index 0000000000..814345ece8 --- /dev/null +++ b/trunk/ext/syck/.cvsignore @@ -0,0 +1,4 @@ +Makefile +mkmf.log +*.def +extconf.h diff --git a/trunk/ext/syck/bytecode.c b/trunk/ext/syck/bytecode.c new file mode 100644 index 0000000000..25ba678300 --- /dev/null +++ b/trunk/ext/syck/bytecode.c @@ -0,0 +1,1165 @@ +/* Generated by re2c 0.9.10 on Mon Sep 19 23:21:26 2005 */ +#line 1 "bytecode.re" +/* + * bytecode.re + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" +#include "syck.h" +#include "gram.h" + +#define QUOTELEN 128 + +/* + * They do my bidding... + */ +#define YYCTYPE char +#define YYCURSOR parser->cursor +#define YYMARKER parser->marker +#define YYLIMIT parser->limit +#define YYTOKEN parser->token +#define YYTOKTMP parser->toktmp +#define YYLINEPTR parser->lineptr +#define YYLINECTPTR parser->linectptr +#define YYLINE parser->linect +#define YYFILL(n) syck_parser_read(parser) + +extern SyckParser *syck_parser_ptr; + +char *get_inline( SyckParser *parser ); + +/* + * Repositions the cursor at `n' offset from the token start. + * Only works in `Header' and `Document' sections. + */ +#define YYPOS(n) YYCURSOR = YYTOKEN + n + +/* + * Track line numbers + */ +#define CHK_NL(ptr) if ( *( ptr - 1 ) == '\n' && ptr > YYLINECTPTR ) { YYLINEPTR = ptr; YYLINE++; YYLINECTPTR = YYLINEPTR; } + +/* + * I like seeing the level operations as macros... + */ +#define ADD_LEVEL(len, status) syck_parser_add_level( parser, len, status ) +#define POP_LEVEL() syck_parser_pop_level( parser ) +#define CURRENT_LEVEL() syck_parser_current_level( parser ) + +/* + * Force a token next time around sycklex() + */ +#define FORCE_NEXT_TOKEN(tok) parser->force_token = tok; + +/* + * Adding levels in bytecode requires us to make sure + * we've got all our tokens worked out. + */ +#define ADD_BYTE_LEVEL(lvl, len, s ) \ + switch ( lvl->status ) \ + { \ + case syck_lvl_seq: \ + lvl->ncount++; \ + ADD_LEVEL(len, syck_lvl_open); \ + YYPOS(0); \ + return '-'; \ + \ + case syck_lvl_map: \ + lvl->ncount++; \ + ADD_LEVEL(len, s); \ + break; \ + \ + case syck_lvl_open: \ + lvl->status = s; \ + break; \ + \ + default: \ + ADD_LEVEL(len, s); \ + break; \ + } + +/* + * Nice little macro to ensure we're YAML_IOPENed to the current level. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IOPEN(last_lvl, lvl_type, to_len, reset) \ + if ( last_lvl->spaces < to_len ) \ + { \ + if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \ + { \ + goto Document; \ + } \ + else \ + { \ + ADD_LEVEL( to_len, lvl_type ); \ + if ( reset == 1 ) YYPOS(0); \ + return YAML_IOPEN; \ + } \ + } + +/* + * Nice little macro to ensure closure of levels. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IEND(last_lvl, to_len) \ + if ( last_lvl->spaces > to_len ) \ + { \ + syck_parser_pop_level( parser ); \ + YYPOS(0); \ + return YAML_IEND; \ + } + +/* + * Concatenates string items and manages allocation + * to the string + */ +#define CAT(s, c, i, l) \ + { \ + if ( i + 1 >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + s[i++] = l; \ + s[i] = '\0'; \ + } + +/* + * Parser for standard YAML Bytecode [UTF-8] + */ +int +sycklex_bytecode_utf8( YYSTYPE *sycklval, SyckParser *parser ) +{ + SyckLevel *lvl; + syck_parser_ptr = parser; + if ( YYCURSOR == NULL ) + { + syck_parser_read( parser ); + } + + if ( parser->force_token != 0 ) + { + int t = parser->force_token; + parser->force_token = 0; + return t; + } + +#line 172 "bytecode.re" + + + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_doc ) + { + goto Document; + } + +/* Header: */ + + YYTOKEN = YYCURSOR; + + +#line 165 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy2; + case 'D': goto yy3; + default: goto yy5; + } +yy2: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy4; + } +yy3: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy6; + case 0x0D: goto yy8; + default: goto yy4; + } +yy4: +#line 199 "bytecode.re" +{ YYPOS(0); + goto Document; + } +#line 195 "<stdout>" +yy5: yych = *++YYCURSOR; + goto yy4; +yy6: ++YYCURSOR; + goto yy7; +yy7: +#line 186 "bytecode.re" +{ if ( lvl->status == syck_lvl_header ) + { + CHK_NL(YYCURSOR); + goto Directive; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + } +#line 214 "<stdout>" +yy8: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy6; + default: goto yy2; + } +} +#line 203 "bytecode.re" + + +Document: + { + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + lvl->status = syck_lvl_doc; + } + + YYTOKEN = YYCURSOR; + + +#line 235 "<stdout>" +{ + YYCTYPE yych; + goto yy9; + ++YYCURSOR; +yy9: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy30; + case 0x0A: goto yy27; + case 0x0D: goto yy29; + case 'A': goto yy19; + case 'D': goto yy12; + case 'E': goto yy16; + case 'M': goto yy14; + case 'P': goto yy13; + case 'Q': goto yy15; + case 'R': goto yy21; + case 'S': goto yy17; + case 'T': goto yy23; + case 'c': goto yy25; + default: goto yy11; + } +yy11:yy12: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + case 0x0D: goto yy44; + default: goto yy11; + } +yy13: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + case 0x0D: goto yy43; + default: goto yy11; + } +yy14: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy38; + case 0x0D: goto yy40; + default: goto yy11; + } +yy15: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy35; + case 0x0D: goto yy37; + default: goto yy11; + } +yy16: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy32; + case 0x0D: goto yy34; + default: goto yy11; + } +yy17: ++YYCURSOR; + goto yy18; +yy18: +#line 288 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str); + goto Scalar; + } +#line 296 "<stdout>" +yy19: ++YYCURSOR; + goto yy20; +yy20: +#line 292 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open); + sycklval->name = get_inline( parser ); + syck_hdlr_remove_anchor( parser, sycklval->name ); + CHK_NL(YYCURSOR); + return YAML_ANCHOR; + } +#line 307 "<stdout>" +yy21: ++YYCURSOR; + goto yy22; +yy22: +#line 299 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str); + sycklval->name = get_inline( parser ); + POP_LEVEL(); + if ( *( YYCURSOR - 1 ) == '\n' ) YYCURSOR--; + return YAML_ALIAS; + } +#line 318 "<stdout>" +yy23: ++YYCURSOR; + goto yy24; +yy24: +#line 306 "bytecode.re" +{ char *qstr; + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open); + qstr = get_inline( parser ); + CHK_NL(YYCURSOR); + if ( qstr[0] == '!' ) + { + int qidx = strlen( qstr ); + if ( qstr[1] == '\0' ) + { + free( qstr ); + return YAML_ITRANSFER; + } + + lvl = CURRENT_LEVEL(); + + /* + * URL Prefixing + */ + if ( qstr[1] == '^' ) + { + sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, qstr + 2, qidx - 2 ); + free( qstr ); + } + else + { + char *carat = qstr + 1; + char *qend = qstr + qidx; + while ( (++carat) < qend ) + { + if ( *carat == '^' ) + break; + } + + if ( carat < qend ) + { + free( lvl->domain ); + lvl->domain = syck_strndup( qstr + 1, carat - ( qstr + 1 ) ); + sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 ); + free( qstr ); + } + else + { + sycklval->name = S_ALLOC_N( char, strlen( qstr ) ); + sycklval->name[0] = '\0'; + S_MEMCPY( sycklval->name, qstr + 1, char, strlen( qstr ) ); + free( qstr ); + } + } + return YAML_TRANSFER; + } + sycklval->name = qstr; + return YAML_TAGURI; + } +#line 382 "<stdout>" +yy25: ++YYCURSOR; + goto yy26; +yy26: +#line 366 "bytecode.re" +{ goto Comment; } +#line 388 "<stdout>" +yy27: ++YYCURSOR; + goto yy28; +yy28: +#line 368 "bytecode.re" +{ CHK_NL(YYCURSOR); + if ( lvl->status == syck_lvl_seq ) + { + return YAML_INDENT; + } + else if ( lvl->status == syck_lvl_map ) + { + if ( lvl->ncount % 2 == 1 ) return ':'; + else return YAML_INDENT; + } + goto Document; + } +#line 405 "<stdout>" +yy29: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy27; + default: goto yy11; + } +yy30: ++YYCURSOR; + goto yy31; +yy31: +#line 381 "bytecode.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 419 "<stdout>" +yy32: ++YYCURSOR; + goto yy33; +yy33: +#line 252 "bytecode.re" +{ if ( lvl->status == syck_lvl_seq && lvl->ncount == 0 ) + { + lvl->ncount++; + YYPOS(0); + FORCE_NEXT_TOKEN( ']' ); + return '['; + } + else if ( lvl->status == syck_lvl_map && lvl->ncount == 0 ) + { + lvl->ncount++; + YYPOS(0); + FORCE_NEXT_TOKEN( '}' ); + return '{'; + } + + POP_LEVEL(); + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_seq ) + { + FORCE_NEXT_TOKEN(YAML_INDENT); + } + else if ( lvl->status == syck_lvl_map ) + { + if ( lvl->ncount % 2 == 1 ) + { + FORCE_NEXT_TOKEN(':'); + } + else + { + FORCE_NEXT_TOKEN(YAML_INDENT); + } + } + CHK_NL(YYCURSOR); + return YAML_IEND; + } +#line 459 "<stdout>" +yy34: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy32; + default: goto yy11; + } +yy35: ++YYCURSOR; + goto yy36; +yy36: +#line 237 "bytecode.re" +{ int complex = 0; + if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) ) + { + complex = 1; + } + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_seq); + CHK_NL(YYCURSOR); + if ( complex ) + { + FORCE_NEXT_TOKEN( YAML_IOPEN ); + return '?'; + } + return YAML_IOPEN; + } +#line 483 "<stdout>" +yy37: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy35; + default: goto yy11; + } +yy38: ++YYCURSOR; + goto yy39; +yy39: +#line 222 "bytecode.re" +{ int complex = 0; + if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) ) + { + complex = 1; + } + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_map); + CHK_NL(YYCURSOR); + if ( complex ) + { + FORCE_NEXT_TOKEN( YAML_IOPEN ); + return '?'; + } + return YAML_IOPEN; + } +#line 507 "<stdout>" +yy40: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy38; + default: goto yy11; + } +yy41: ++YYCURSOR; + goto yy42; +yy42: +#line 217 "bytecode.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 521 "<stdout>" +yy43: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + default: goto yy11; + } +yy44: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy41; + default: goto yy11; + } +} +#line 386 "bytecode.re" + + + } + +Directive: + { + YYTOKEN = YYCURSOR; + + +#line 543 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy45; + ++YYCURSOR; +yy45: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy47; + case 'V': goto yy48; + default: goto yy50; + } +yy47: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy49; + } +yy48: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy51; + default: goto yy49; + } +yy49: +#line 399 "bytecode.re" +{ YYCURSOR = YYTOKEN; + return YAML_DOCSEP; + } +#line 646 "<stdout>" +yy50: yych = *++YYCURSOR; + goto yy49; +yy51: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy52; +yy52: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy51; + case ':': goto yy53; + default: goto yy47; + } +yy53: yych = *++YYCURSOR; + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy54; + default: goto yy47; + } +yy54: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy55; +yy55: switch(yych){ + case 0x0A: goto yy56; + case 0x0D: goto yy58; + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy54; + default: goto yy47; + } +yy56: ++YYCURSOR; + goto yy57; +yy57: +#line 396 "bytecode.re" +{ CHK_NL(YYCURSOR); + goto Directive; } +#line 899 "<stdout>" +yy58: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy56; + default: goto yy47; + } +} +#line 402 "bytecode.re" + + + } + +Comment: + { + YYTOKEN = YYCURSOR; + + +#line 916 "<stdout>" +{ + YYCTYPE yych; + goto yy59; + ++YYCURSOR; +yy59: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy61; + case 0x0A: goto yy62; + case 0x0D: goto yy64; + default: goto yy66; + } +yy61:yy62: ++YYCURSOR; + goto yy63; +yy63: +#line 412 "bytecode.re" +{ CHK_NL(YYCURSOR); + goto Document; } +#line 936 "<stdout>" +yy64: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy67; + default: goto yy65; + } +yy65: +#line 415 "bytecode.re" +{ goto Comment; } +#line 945 "<stdout>" +yy66: yych = *++YYCURSOR; + goto yy65; +yy67: ++YYCURSOR; + yych = *YYCURSOR; + goto yy63; +} +#line 417 "bytecode.re" + + + } + +Scalar: + { + int idx = 0; + int cap = 100; + char *str = S_ALLOC_N( char, cap ); + char *tok; + + str[0] = '\0'; + +Scalar2: + tok = YYCURSOR; + + +#line 970 "<stdout>" +{ + YYCTYPE yych; + goto yy68; + ++YYCURSOR; +yy68: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy74; + case 0x0A: goto yy70; + case 0x0D: goto yy72; + default: goto yy76; + } +yy70: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 'C': goto yy78; + case 'N': goto yy80; + case 'Z': goto yy83; + default: goto yy71; + } +yy71: +#line 461 "bytecode.re" +{ YYCURSOR = tok; + goto ScalarEnd; + } +#line 996 "<stdout>" +yy72: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy77; + default: goto yy73; + } +yy73: +#line 469 "bytecode.re" +{ CAT(str, cap, idx, tok[0]); + goto Scalar2; + } +#line 1007 "<stdout>" +yy74: ++YYCURSOR; + goto yy75; +yy75: +#line 465 "bytecode.re" +{ YYCURSOR = tok; + goto ScalarEnd; + } +#line 1015 "<stdout>" +yy76: yych = *++YYCURSOR; + goto yy73; +yy77: yych = *++YYCURSOR; + switch(yych){ + case 'C': goto yy78; + case 'N': goto yy80; + case 'Z': goto yy83; + default: goto yy71; + } +yy78: ++YYCURSOR; + goto yy79; +yy79: +#line 435 "bytecode.re" +{ CHK_NL(tok+1); + goto Scalar2; } +#line 1031 "<stdout>" +yy80: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy81; +yy81: switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy80; + default: goto yy82; + } +yy82: +#line 438 "bytecode.re" +{ CHK_NL(tok+1); + if ( tok + 2 < YYCURSOR ) + { + char *count = tok + 2; + int total = strtod( count, NULL ); + int i; + for ( i = 0; i < total; i++ ) + { + CAT(str, cap, idx, '\n'); + } + } + else + { + CAT(str, cap, idx, '\n'); + } + goto Scalar2; + } +#line 1068 "<stdout>" +yy83: ++YYCURSOR; + goto yy84; +yy84: +#line 456 "bytecode.re" +{ CHK_NL(tok+1); + CAT(str, cap, idx, '\0'); + goto Scalar2; + } +#line 1077 "<stdout>" +} +#line 473 "bytecode.re" + + +ScalarEnd: + { + SyckNode *n = syck_alloc_str(); + n->data.str->ptr = str; + n->data.str->len = idx; + sycklval->nodeData = n; + POP_LEVEL(); + if ( parser->implicit_typing == 1 ) + { + try_tag_implicit( sycklval->nodeData, parser->taguri_expansion ); + } + return YAML_PLAIN; + } + } + +} + +char * +get_inline( SyckParser *parser ) +{ + int idx = 0; + int cap = 100; + char *str = S_ALLOC_N( char, cap ); + char *tok; + + str[0] = '\0'; + +Inline: + { + tok = YYCURSOR; + + +#line 1114 "<stdout>" +{ + YYCTYPE yych; + goto yy85; + ++YYCURSOR; +yy85: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy91; + case 0x0A: goto yy87; + case 0x0D: goto yy89; + default: goto yy93; + } +yy87: ++YYCURSOR; + goto yy88; +yy88: +#line 508 "bytecode.re" +{ CHK_NL(YYCURSOR); + return str; } +#line 1134 "<stdout>" +yy89: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy94; + default: goto yy90; + } +yy90: +#line 515 "bytecode.re" +{ CAT(str, cap, idx, tok[0]); + goto Inline; + } +#line 1145 "<stdout>" +yy91: ++YYCURSOR; + goto yy92; +yy92: +#line 511 "bytecode.re" +{ YYCURSOR = tok; + return str; + } +#line 1153 "<stdout>" +yy93: yych = *++YYCURSOR; + goto yy90; +yy94: ++YYCURSOR; + yych = *YYCURSOR; + goto yy88; +} +#line 519 "bytecode.re" + + + } + +} + diff --git a/trunk/ext/syck/depend b/trunk/ext/syck/depend new file mode 100644 index 0000000000..3eec4de72a --- /dev/null +++ b/trunk/ext/syck/depend @@ -0,0 +1,12 @@ +ruby_headers = $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \ + $(hdrdir)/missing.h $(hdrdir)/intern.h $(hdrdir)/st.h +bytecode.o: bytecode.c syck.h gram.h $(ruby_headers) +emitter.o: emitter.c syck.h $(ruby_headers) +gram.o: gram.c syck.h $(hdrdir)/st.h +handler.o: handler.c syck.h $(ruby_headers) +implicit.o: implicit.c syck.h $(ruby_headers) +node.o: node.c syck.h $(ruby_headers) +rubyext.o: rubyext.c syck.h $(ruby_headers) +syck.o: syck.c syck.h $(ruby_headers) +token.o: token.c syck.h gram.h $(ruby_headers) +yaml2byte.o: yaml2byte.c syck.h yamlbyte.h $(ruby_headers) diff --git a/trunk/ext/syck/emitter.c b/trunk/ext/syck/emitter.c new file mode 100644 index 0000000000..73ff5d7a0b --- /dev/null +++ b/trunk/ext/syck/emitter.c @@ -0,0 +1,1247 @@ +/* + * emitter.c + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + * + * All Base64 code from Ruby's pack.c. + * Ruby is Copyright (C) 1993-2007 Yukihiro Matsumoto + */ +#include "ruby/ruby.h" + +#include <stdio.h> +#include <string.h> + +#include "syck.h" + +#define DEFAULT_ANCHOR_FORMAT "id%03d" + +const char hex_table[] = +"0123456789ABCDEF"; +static char b64_table[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + * Built-in base64 (from Ruby's pack.c) + */ +char * +syck_base64enc( char *s, long len ) +{ + long i = 0; + int padding = '='; + char *buff = S_ALLOC_N(char, len * 4 / 3 + 6); + + while (len >= 3) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; + buff[i++] = b64_table[077 & s[2]]; + s += 3; + len -= 3; + } + if (len == 2) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))]; + buff[i++] = padding; + } + else if (len == 1) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))]; + buff[i++] = padding; + buff[i++] = padding; + } + buff[i++] = '\n'; + return buff; +} + +char * +syck_base64dec( char *s, long len ) +{ + int a = -1,b = -1,c = 0,d; + static int first = 1; + static int b64_xtable[256]; + char *ptr = syck_strndup( s, len ); + char *end = ptr; + char *send = s + len; + + if (first) { + int i; + first = 0; + + for (i = 0; i < 256; i++) { + b64_xtable[i] = -1; + } + for (i = 0; i < 64; i++) { + b64_xtable[(int)b64_table[i]] = i; + } + } + while (s < send) { + while (s[0] == '\r' || s[0] == '\n') { s++; } + if ((a = b64_xtable[(int)s[0]]) == -1) break; + if ((b = b64_xtable[(int)s[1]]) == -1) break; + if ((c = b64_xtable[(int)s[2]]) == -1) break; + if ((d = b64_xtable[(int)s[3]]) == -1) break; + *end++ = a << 2 | b >> 4; + *end++ = b << 4 | c >> 2; + *end++ = c << 6 | d; + s += 4; + } + if (a != -1 && b != -1) { + if (s + 2 < send && s[2] == '=') + *end++ = a << 2 | b >> 4; + if (c != -1 && s + 3 < send && s[3] == '=') { + *end++ = a << 2 | b >> 4; + *end++ = b << 4 | c >> 2; + } + } + *end = '\0'; + /*RSTRING_LEN(buf) = ptr - RSTRING_PTR(buf);*/ + return ptr; +} + +/* + * Allocate an emitter + */ +SyckEmitter * +syck_new_emitter(void) +{ + SyckEmitter *e; + e = S_ALLOC( SyckEmitter ); + e->headless = 0; + e->use_header = 0; + e->use_version = 0; + e->sort_keys = 0; + e->anchor_format = NULL; + e->explicit_typing = 0; + e->best_width = 80; + e->style = scalar_none; + e->stage = doc_open; + e->indent = 2; + e->level = -1; + e->anchors = NULL; + e->markers = NULL; + e->anchored = NULL; + e->bufsize = SYCK_BUFFERSIZE; + e->buffer = NULL; + e->marker = NULL; + e->bufpos = 0; + e->emitter_handler = NULL; + e->output_handler = NULL; + e->lvl_idx = 0; + e->lvl_capa = ALLOC_CT; + e->levels = S_ALLOC_N( SyckLevel, e->lvl_capa ); + syck_emitter_reset_levels( e ); + e->bonus = NULL; + return e; +} + +int +syck_st_free_anchors( char *key, char *name, char *arg ) +{ + S_FREE( name ); + return ST_CONTINUE; +} + +void +syck_emitter_st_free( SyckEmitter *e ) +{ + /* + * Free the anchor tables + */ + if ( e->anchors != NULL ) + { + st_foreach( e->anchors, syck_st_free_anchors, 0 ); + st_free_table( e->anchors ); + e->anchors = NULL; + } + + if ( e->anchored != NULL ) + { + st_free_table( e->anchored ); + e->anchored = NULL; + } + + /* + * Free the markers tables + */ + if ( e->markers != NULL ) + { + st_free_table( e->markers ); + e->markers = NULL; + } +} + +SyckLevel * +syck_emitter_current_level( SyckEmitter *e ) +{ + return &e->levels[e->lvl_idx-1]; +} + +SyckLevel * +syck_emitter_parent_level( SyckEmitter *e ) +{ + return &e->levels[e->lvl_idx-2]; +} + +void +syck_emitter_pop_level( SyckEmitter *e ) +{ + ASSERT( e != NULL ); + + /* The root level should never be popped */ + if ( e->lvl_idx <= 1 ) return; + + e->lvl_idx -= 1; + free( e->levels[e->lvl_idx].domain ); +} + +void +syck_emitter_add_level( SyckEmitter *e, int len, enum syck_level_status status ) +{ + ASSERT( e != NULL ); + if ( e->lvl_idx + 1 > e->lvl_capa ) + { + e->lvl_capa += ALLOC_CT; + S_REALLOC_N( e->levels, SyckLevel, e->lvl_capa ); + } + + ASSERT( len > e->levels[e->lvl_idx-1].spaces ); + e->levels[e->lvl_idx].spaces = len; + e->levels[e->lvl_idx].ncount = 0; + e->levels[e->lvl_idx].domain = syck_strndup( e->levels[e->lvl_idx-1].domain, strlen( e->levels[e->lvl_idx-1].domain ) ); + e->levels[e->lvl_idx].status = status; + e->levels[e->lvl_idx].anctag = 0; + e->lvl_idx += 1; +} + +void +syck_emitter_reset_levels( SyckEmitter *e ) +{ + while ( e->lvl_idx > 1 ) + { + syck_emitter_pop_level( e ); + } + + if ( e->lvl_idx < 1 ) + { + e->lvl_idx = 1; + e->levels[0].spaces = -1; + e->levels[0].ncount = 0; + e->levels[0].domain = syck_strndup( "", 0 ); + e->levels[0].anctag = 0; + } + e->levels[0].status = syck_lvl_header; +} + +void +syck_emitter_handler( SyckEmitter *e, SyckEmitterHandler hdlr ) +{ + e->emitter_handler = hdlr; +} + +void +syck_output_handler( SyckEmitter *e, SyckOutputHandler hdlr ) +{ + e->output_handler = hdlr; +} + +void +syck_free_emitter( SyckEmitter *e ) +{ + /* + * Free tables + */ + syck_emitter_st_free( e ); + syck_emitter_reset_levels( e ); + S_FREE( e->levels[0].domain ); + S_FREE( e->levels ); + if ( e->buffer != NULL ) + { + S_FREE( e->buffer ); + } + S_FREE( e ); +} + +void +syck_emitter_clear( SyckEmitter *e ) +{ + if ( e->buffer == NULL ) + { + e->buffer = S_ALLOC_N( char, e->bufsize ); + S_MEMZERO( e->buffer, char, e->bufsize ); + } + e->buffer[0] = '\0'; + e->marker = e->buffer; + e->bufpos = 0; +} + +/* + * Raw write to the emitter buffer. + */ +void +syck_emitter_write( SyckEmitter *e, const char *str, long len ) +{ + long at; + ASSERT( str != NULL ); + if ( e->buffer == NULL ) + { + syck_emitter_clear( e ); + } + + /* + * Flush if at end of buffer + */ + at = e->marker - e->buffer; + if ( len + at >= e->bufsize ) + { + syck_emitter_flush( e, 0 ); + for (;;) { + long rest = e->bufsize - (e->marker - e->buffer); + if (len <= rest) break; + S_MEMCPY( e->marker, str, char, rest ); + e->marker += rest; + str += rest; + len -= rest; + syck_emitter_flush( e, 0 ); + } + } + + /* + * Write to buffer + */ + S_MEMCPY( e->marker, str, char, len ); + e->marker += len; +} + +/* + * Write a chunk of data out. + */ +void +syck_emitter_flush( SyckEmitter *e, long check_room ) +{ + /* + * Check for enough space in the buffer for check_room length. + */ + if ( check_room > 0 ) + { + if ( e->bufsize > ( e->marker - e->buffer ) + check_room ) + { + return; + } + } + else + { + check_room = e->bufsize; + } + + /* + * Commit buffer. + */ + if ( check_room > e->marker - e->buffer ) + { + check_room = e->marker - e->buffer; + } + (e->output_handler)( e, e->buffer, check_room ); + e->bufpos += check_room; + e->marker -= check_room; +} + +/* + * Start emitting from the given node, check for anchoring and then + * issue the callback to the emitter handler. + */ +void +syck_emit( SyckEmitter *e, st_data_t n ) +{ + SYMID oid; + char *anchor_name = NULL; + int indent = 0; + long x = 0; + SyckLevel *lvl = syck_emitter_current_level( e ); + + /* + * Determine headers. + */ + if ( e->stage == doc_open && ( e->headless == 0 || e->use_header == 1 ) ) + { + if ( e->use_version == 1 ) + { + char *header = S_ALLOC_N( char, 64 ); + S_MEMZERO( header, char, 64 ); + sprintf( header, "--- %%YAML:%d.%d ", SYCK_YAML_MAJOR, SYCK_YAML_MINOR ); + syck_emitter_write( e, header, strlen( header ) ); + S_FREE( header ); + } + else + { + syck_emitter_write( e, "--- ", 4 ); + } + e->stage = doc_processing; + } + + /* Add new level */ + if ( lvl->spaces >= 0 ) { + indent = lvl->spaces + e->indent; + } + syck_emitter_add_level( e, indent, syck_lvl_open ); + lvl = syck_emitter_current_level( e ); + + /* Look for anchor */ + if ( e->anchors != NULL && + st_lookup( e->markers, n, (st_data_t *)&oid ) && + st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) ) + { + if ( e->anchored == NULL ) + { + e->anchored = st_init_numtable(); + } + + if ( ! st_lookup( e->anchored, (st_data_t)anchor_name, (st_data_t *)&x ) ) + { + char *an = S_ALLOC_N( char, strlen( anchor_name ) + 3 ); + sprintf( an, "&%s ", anchor_name ); + syck_emitter_write( e, an, strlen( anchor_name ) + 2 ); + free( an ); + + x = 1; + st_insert( e->anchored, (st_data_t)anchor_name, (st_data_t)x ); + lvl->anctag = 1; + } + else + { + char *an = S_ALLOC_N( char, strlen( anchor_name ) + 2 ); + sprintf( an, "*%s", anchor_name ); + syck_emitter_write( e, an, strlen( anchor_name ) + 1 ); + free( an ); + + goto end_emit; + } + } + + (e->emitter_handler)( e, n ); + + /* Pop the level */ +end_emit: + syck_emitter_pop_level( e ); + if ( e->lvl_idx == 1 ) { + syck_emitter_write( e, "\n", 1 ); + e->headless = 0; + e->stage = doc_open; + } +} + +/* + * Determine what tag needs to be written, based on the taguri of the node + * and the implicit tag which would be assigned to this node. If a tag is + * required, write the tag. + */ +void syck_emit_tag( SyckEmitter *e, const char *tag, const char *ignore ) +{ + SyckLevel *lvl; + if ( tag == NULL ) return; + if ( ignore != NULL && syck_tagcmp( tag, ignore ) == 0 && e->explicit_typing == 0 ) return; + lvl = syck_emitter_current_level( e ); + + /* implicit */ + if ( strlen( tag ) == 0 ) { + syck_emitter_write( e, "! ", 2 ); + + /* global types */ + } else if ( strncmp( tag, "tag:", 4 ) == 0 ) { + int taglen = strlen( tag ); + syck_emitter_write( e, "!", 1 ); + if ( strncmp( tag + 4, YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) { + int skip = 4 + strlen( YAML_DOMAIN ) + 1; + syck_emitter_write( e, tag + skip, taglen - skip ); + } else { + const char *subd = tag + 4; + while ( *subd != ':' && *subd != '\0' ) subd++; + if ( *subd == ':' ) { + if ( subd - tag > ( strlen( YAML_DOMAIN ) + 5 ) && + strncmp( subd - strlen( YAML_DOMAIN ), YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) { + syck_emitter_write( e, tag + 4, subd - strlen( YAML_DOMAIN ) - ( tag + 4 ) - 1 ); + syck_emitter_write( e, "/", 1 ); + syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) ); + } else { + syck_emitter_write( e, tag + 4, subd - ( tag + 4 ) ); + syck_emitter_write( e, "/", 1 ); + syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) ); + } + } else { + /* TODO: Invalid tag (no colon after domain) */ + return; + } + } + syck_emitter_write( e, " ", 1 ); + + /* private types */ + } else if ( strncmp( tag, "x-private:", 10 ) == 0 ) { + syck_emitter_write( e, "!!", 2 ); + syck_emitter_write( e, tag + 10, strlen( tag ) - 10 ); + syck_emitter_write( e, " ", 1 ); + } + lvl->anctag = 1; +} + +/* + * Emit a newline and an appropriately spaced indent. + */ +void syck_emit_indent( SyckEmitter *e ) +{ + int i; + SyckLevel *lvl = syck_emitter_current_level( e ); + if ( e->bufpos == 0 && ( e->marker - e->buffer ) == 0 ) return; + if ( lvl->spaces >= 0 ) { + char *spcs = S_ALLOC_N( char, lvl->spaces + 2 ); + + spcs[0] = '\n'; spcs[lvl->spaces + 1] = '\0'; + for ( i = 0; i < lvl->spaces; i++ ) spcs[i+1] = ' '; + syck_emitter_write( e, spcs, lvl->spaces + 1 ); + free( spcs ); + } +} + +/* Clear the scan */ +#define SCAN_NONE 0 +/* All printable characters? */ +#define SCAN_NONPRINT 1 +/* Any indented lines? */ +#define SCAN_INDENTED 2 +/* Larger than the requested width? */ +#define SCAN_WIDE 4 +/* Opens or closes with whitespace? */ +#define SCAN_WHITEEDGE 8 +/* Contains a newline */ +#define SCAN_NEWLINE 16 +/* Contains a single quote */ +#define SCAN_SINGLEQ 32 +/* Contains a double quote */ +#define SCAN_DOUBLEQ 64 +/* Starts with a token */ +#define SCAN_INDIC_S 128 +/* Contains a flow indicator */ +#define SCAN_INDIC_C 256 +/* Ends without newlines */ +#define SCAN_NONL_E 512 +/* Ends with many newlines */ +#define SCAN_MANYNL_E 1024 +/* Contains flow map indicators */ +#define SCAN_FLOWMAP 2048 +/* Contains flow seq indicators */ +#define SCAN_FLOWSEQ 4096 +/* Contains a valid doc separator */ +#define SCAN_DOCSEP 8192 + +/* + * Basic printable test for LATIN-1 characters. + */ +int +syck_scan_scalar( int req_width, const char *cursor, long len ) +{ + long i = 0, start = 0; + int flags = SCAN_NONE; + + if ( len < 1 ) return flags; + + /* c-indicators from the spec */ + if ( cursor[0] == '[' || cursor[0] == ']' || + cursor[0] == '{' || cursor[0] == '}' || + cursor[0] == '!' || cursor[0] == '*' || + cursor[0] == '&' || cursor[0] == '|' || + cursor[0] == '>' || cursor[0] == '\'' || + cursor[0] == '"' || cursor[0] == '#' || + cursor[0] == '%' || cursor[0] == '@' || + cursor[0] == '&' ) { + flags |= SCAN_INDIC_S; + } + if ( ( cursor[0] == '-' || cursor[0] == ':' || + cursor[0] == '?' || cursor[0] == ',' ) && + ( len == 1 || cursor[1] == ' ' || cursor[1] == '\n' ) ) + { + flags |= SCAN_INDIC_S; + } + + /* whitespace edges */ + if ( cursor[len-1] != '\n' ) { + flags |= SCAN_NONL_E; + } else if ( len > 1 && cursor[len-2] == '\n' ) { + flags |= SCAN_MANYNL_E; + } + if ( + ( len > 0 && ( cursor[0] == ' ' || cursor[0] == '\t' ) ) || + ( len > 1 && ( cursor[len-1] == ' ' || cursor[len-1] == '\t' ) ) + ) { + flags |= SCAN_WHITEEDGE; + } + + /* opening doc sep */ + if ( len >= 3 && strncmp( cursor, "---", 3 ) == 0 ) + flags |= SCAN_DOCSEP; + + /* scan string */ + for ( i = 0; i < len; i++ ) { + + if ( ! ( cursor[i] == 0x9 || + cursor[i] == 0xA || + cursor[i] == 0xD || + ( cursor[i] >= 0x20 && cursor[i] <= 0x7E ) ) + ) { + flags |= SCAN_NONPRINT; + } + else if ( cursor[i] == '\n' ) { + flags |= SCAN_NEWLINE; + if ( len - i >= 3 && strncmp( &cursor[i+1], "---", 3 ) == 0 ) + flags |= SCAN_DOCSEP; + if ( cursor[i+1] == ' ' || cursor[i+1] == '\t' ) + flags |= SCAN_INDENTED; + if ( req_width > 0 && i - start > req_width ) + flags |= SCAN_WIDE; + start = i; + } + else if ( cursor[i] == '\'' ) + { + flags |= SCAN_SINGLEQ; + } + else if ( cursor[i] == '"' ) + { + flags |= SCAN_DOUBLEQ; + } + else if ( cursor[i] == ']' ) + { + flags |= SCAN_FLOWSEQ; + } + else if ( cursor[i] == '}' ) + { + flags |= SCAN_FLOWMAP; + } + /* remember, if plain collections get implemented, to add nb-plain-flow-char */ + else if ( ( cursor[i] == ' ' && cursor[i+1] == '#' ) || + ( cursor[i] == ':' && + ( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) ) ) + { + flags |= SCAN_INDIC_C; + } + else if ( cursor[i] == ',' && + ( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) ) + { + flags |= SCAN_FLOWMAP; + flags |= SCAN_FLOWSEQ; + } + } + + /* printf( "---STR---\n%s\nFLAGS: %d\n", cursor, flags ); */ + return flags; +} +/* + * All scalars should be emitted through this function, which determines an appropriate style, + * tag and indent. + */ +void syck_emit_scalar( SyckEmitter *e, const char *tag, enum scalar_style force_style, int force_indent, int force_width, + char keep_nl, const char *str, long len ) +{ + enum scalar_style favor_style = scalar_literal; + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + int scan = 0; + const char *match_implicit; + char *implicit; + + if ( str == NULL ) str = ""; + + /* No empty nulls as map keys */ + if ( len == 0 && ( parent->status == syck_lvl_map || parent->status == syck_lvl_imap ) && + parent->ncount % 2 == 1 && syck_tagcmp( tag, "tag:yaml.org,2002:null" ) == 0 ) + { + str = "~"; + len = 1; + } + + scan = syck_scan_scalar( force_width, str, len ); + match_implicit = syck_match_implicit( str, len ); + + /* quote strings which default to implicits */ + implicit = syck_taguri( YAML_DOMAIN, match_implicit, strlen( match_implicit ) ); + if ( syck_tagcmp( tag, implicit ) != 0 && syck_tagcmp( tag, "tag:yaml.org,2002:str" ) == 0 ) { + force_style = scalar_2quote; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 && + ( !( tag == NULL || + ( implicit != NULL && syck_tagcmp( tag, implicit ) == 0 && e->explicit_typing == 0 ) ) ) ) + { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + syck_emit_tag( e, tag, implicit ); + } + S_FREE( implicit ); + + /* if still arbitrary, sniff a good block style. */ + if ( force_style == scalar_none ) { + if ( scan & SCAN_NEWLINE ) { + force_style = scalar_literal; + } else { + force_style = scalar_plain; + } + } + + if ( e->style == scalar_fold ) { + favor_style = scalar_fold; + } + + /* Determine block style */ + if ( scan & SCAN_NONPRINT ) { + force_style = scalar_2quote; + } else if ( scan & SCAN_WHITEEDGE ) { + force_style = scalar_2quote; + } else if ( force_style != scalar_fold && ( scan & SCAN_INDENTED ) ) { + force_style = scalar_literal; + } else if ( force_style == scalar_plain && ( scan & SCAN_NEWLINE ) ) { + force_style = favor_style; + } else if ( force_style == scalar_plain && parent->status == syck_lvl_iseq && ( scan & SCAN_FLOWSEQ ) ) { + force_style = scalar_2quote; + } else if ( force_style == scalar_plain && parent->status == syck_lvl_imap && ( scan & SCAN_FLOWMAP ) ) { + force_style = scalar_2quote; + /* } else if ( force_style == scalar_fold && ( ! ( scan & SCAN_WIDE ) ) ) { + force_style = scalar_literal; */ + } else if ( force_style == scalar_plain && ( scan & SCAN_INDIC_S || scan & SCAN_INDIC_C ) ) { + if ( scan & SCAN_NEWLINE ) { + force_style = favor_style; + } else { + force_style = scalar_2quote; + } + } + + if ( force_indent > 0 ) { + lvl->spaces = parent->spaces + force_indent; + } else if ( scan & SCAN_DOCSEP ) { + lvl->spaces = parent->spaces + e->indent; + } + + /* For now, all ambiguous keys are going to be double-quoted */ + if ( ( parent->status == syck_lvl_map || parent->status == syck_lvl_mapx ) && parent->ncount % 2 == 1 ) { + if ( force_style != scalar_plain ) { + force_style = scalar_2quote; + } + } + + /* If the parent is an inline, double quote anything complex */ + if ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) { + if ( force_style != scalar_plain && force_style != scalar_1quote ) { + force_style = scalar_2quote; + } + } + + /* Fix the ending newlines */ + if ( scan & SCAN_NONL_E ) { + keep_nl = NL_CHOMP; + } else if ( scan & SCAN_MANYNL_E ) { + keep_nl = NL_KEEP; + } + + /* Write the text node */ + switch ( force_style ) + { + case scalar_1quote: + syck_emit_1quoted( e, force_width, str, len ); + break; + + case scalar_none: + case scalar_2quote: + syck_emit_2quoted( e, force_width, str, len ); + break; + + case scalar_fold: + syck_emit_folded( e, force_width, keep_nl, str, len ); + break; + + case scalar_literal: + syck_emit_literal( e, keep_nl, str, len ); + break; + + case scalar_plain: + syck_emitter_write( e, str, len ); + break; + } + + if ( parent->status == syck_lvl_mapx ) + { + syck_emitter_write( e, "\n", 1 ); + } +} + +void +syck_emitter_escape( SyckEmitter *e, const char *src, long len ) +{ + int i; + for( i = 0; i < len; i++ ) + { + if( (src[i] < 0x20) || (0x7E < src[i]) ) + { + syck_emitter_write( e, "\\", 1 ); + if( '\0' == src[i] ) + syck_emitter_write( e, "0", 1 ); + else + { + syck_emitter_write( e, "x", 1 ); + syck_emitter_write( e, (const char *)hex_table + ((src[i] & 0xF0) >> 4), 1 ); + syck_emitter_write( e, (const char *)hex_table + (src[i] & 0x0F), 1 ); + } + } + else + { + syck_emitter_write( e, src + i, 1 ); + if( '\\' == src[i] ) + syck_emitter_write( e, "\\", 1 ); + } + } +} + +/* + * Outputs a single-quoted block. + */ +void +syck_emit_1quoted( SyckEmitter *e, int width, const char *str, long len ) +{ + char do_indent = 0; + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "'", 1 ); + while ( mark < str + len ) { + if ( do_indent ) { + syck_emit_indent( e ); + do_indent = 0; + } + switch ( *mark ) { + case '\'': syck_emitter_write( e, "'", 1 ); break; + + case '\n': + end = mark + 1; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) { + syck_emitter_write( e, "\n\n", 2 ); + } else { + syck_emitter_write( e, "\n", 1 ); + } + do_indent = 1; + start = mark + 1; + break; + + case ' ': + if ( width > 0 && *start != ' ' && mark - end > width ) { + do_indent = 1; + end = mark + 1; + } else { + syck_emitter_write( e, " ", 1 ); + } + break; + + default: + syck_emitter_write( e, mark, 1 ); + break; + } + mark++; + } + syck_emitter_write( e, "'", 1 ); +} + +/* + * Outputs a double-quoted block. + */ +void +syck_emit_2quoted( SyckEmitter *e, int width, const char *str, long len ) +{ + char do_indent = 0; + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "\"", 1 ); + while ( mark < str + len ) { + if ( do_indent > 0 ) { + if ( do_indent == 2 ) { + syck_emitter_write( e, "\\", 1 ); + } + syck_emit_indent( e ); + do_indent = 0; + } + switch ( *mark ) { + + /* Escape sequences allowed within double quotes. */ + case '"': syck_emitter_write( e, "\\\"", 2 ); break; + case '\\': syck_emitter_write( e, "\\\\", 2 ); break; + case '\0': syck_emitter_write( e, "\\0", 2 ); break; + case '\a': syck_emitter_write( e, "\\a", 2 ); break; + case '\b': syck_emitter_write( e, "\\b", 2 ); break; + case '\f': syck_emitter_write( e, "\\f", 2 ); break; + case '\r': syck_emitter_write( e, "\\r", 2 ); break; + case '\t': syck_emitter_write( e, "\\t", 2 ); break; + case '\v': syck_emitter_write( e, "\\v", 2 ); break; + case 0x1b: syck_emitter_write( e, "\\e", 2 ); break; + + case '\n': + end = mark + 1; + syck_emitter_write( e, "\\n", 2 ); + do_indent = 2; + start = mark + 1; + if ( start < str + len && ( *start == ' ' || *start == '\n' ) ) { + do_indent = 0; + } + break; + + case ' ': + if ( width > 0 && *start != ' ' && mark - end > width ) { + do_indent = 1; + end = mark + 1; + } else { + syck_emitter_write( e, " ", 1 ); + } + break; + + default: + syck_emitter_escape( e, mark, 1 ); + break; + } + mark++; + } + syck_emitter_write( e, "\"", 1 ); +} + +/* + * Outputs a literal block. + */ +void +syck_emit_literal( SyckEmitter *e, char keep_nl, const char *str, long len ) +{ + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "|", 1 ); + if ( keep_nl == NL_CHOMP ) { + syck_emitter_write( e, "-", 1 ); + } else if ( keep_nl == NL_KEEP ) { + syck_emitter_write( e, "+", 1 ); + } + syck_emit_indent( e ); + while ( mark < str + len ) { + if ( *mark == '\n' ) { + end = mark; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) end += 1; + syck_emitter_write( e, start, end - start ); + if ( mark + 1 == str + len ) { + if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 ); + } else { + syck_emit_indent( e ); + } + start = mark + 1; + } + mark++; + } + end = str + len; + if ( start < end ) { + syck_emitter_write( e, start, end - start ); + } +} + +/* + * Outputs a folded block. + */ +void +syck_emit_folded( SyckEmitter *e, int width, char keep_nl, const char *str, long len ) +{ + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, ">", 1 ); + if ( keep_nl == NL_CHOMP ) { + syck_emitter_write( e, "-", 1 ); + } else if ( keep_nl == NL_KEEP ) { + syck_emitter_write( e, "+", 1 ); + } + syck_emit_indent( e ); + if ( width <= 0 ) width = e->best_width; + while ( mark < str + len ) { + switch ( *mark ) { + case '\n': + syck_emitter_write( e, end, mark - end ); + end = mark + 1; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) { + syck_emitter_write( e, "\n", 1 ); + } + if ( mark + 1 == str + len ) { + if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 ); + } else { + syck_emit_indent( e ); + } + start = mark + 1; + break; + + case ' ': + if ( *start != ' ' ) { + if ( mark - end > width ) { + syck_emitter_write( e, end, mark - end ); + syck_emit_indent( e ); + end = mark + 1; + } + } + break; + } + mark++; + } + if ( end < mark ) { + syck_emitter_write( e, end, mark - end ); + } +} + +/* + * Begins emission of a sequence. + */ +void syck_emit_seq( SyckEmitter *e, const char *tag, enum seq_style style ) +{ + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + syck_emit_tag( e, tag, "tag:yaml.org,2002:seq" ); + if ( style == seq_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) { + syck_emitter_write( e, "[", 1 ); + lvl->status = syck_lvl_iseq; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + lvl->status = syck_lvl_seq; + } +} + +/* + * Begins emission of a mapping. + */ +void +syck_emit_map( SyckEmitter *e, const char *tag, enum map_style style ) +{ + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + syck_emit_tag( e, tag, "tag:yaml.org,2002:map" ); + if ( style == map_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) { + syck_emitter_write( e, "{", 1 ); + lvl->status = syck_lvl_imap; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + lvl->status = syck_lvl_map; + } +} + +/* + * Handles emitting of a collection item (for both + * sequences and maps) + */ +void syck_emit_item( SyckEmitter *e, st_data_t n ) +{ + SyckLevel *lvl = syck_emitter_current_level( e ); + switch ( lvl->status ) + { + case syck_lvl_seq: + { + SyckLevel *parent = syck_emitter_parent_level( e ); + + /* seq-in-map shortcut -- the lvl->anctag check should be unneccesary but + * there is a nasty shift/reduce in the parser on this point and + * i'm not ready to tickle it. */ + if ( lvl->anctag == 0 && parent->status == syck_lvl_map && lvl->ncount == 0 ) { + lvl->spaces = parent->spaces; + } + + /* seq-in-seq shortcut */ + else if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) { + int spcs = ( lvl->spaces - parent->spaces ) - 2; + if ( spcs >= 0 ) { + int i = 0; + for ( i = 0; i < spcs; i++ ) { + syck_emitter_write( e, " ", 1 ); + } + syck_emitter_write( e, "- ", 2 ); + break; + } + } + + syck_emit_indent( e ); + syck_emitter_write( e, "- ", 2 ); + } + break; + + case syck_lvl_iseq: + { + if ( lvl->ncount > 0 ) { + syck_emitter_write( e, ", ", 2 ); + } + } + break; + + case syck_lvl_map: + { + SyckLevel *parent = syck_emitter_parent_level( e ); + + /* map-in-seq shortcut */ + if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) { + int spcs = ( lvl->spaces - parent->spaces ) - 2; + if ( spcs >= 0 ) { + int i = 0; + for ( i = 0; i < spcs; i++ ) { + syck_emitter_write( e, " ", 1 ); + } + break; + } + } + + if ( lvl->ncount % 2 == 0 ) { + syck_emit_indent( e ); + } else { + syck_emitter_write( e, ": ", 2 ); + } + } + break; + + case syck_lvl_mapx: + { + if ( lvl->ncount % 2 == 0 ) { + syck_emit_indent( e ); + lvl->status = syck_lvl_map; + } else { + int i; + if ( lvl->spaces > 0 ) { + char *spcs = S_ALLOC_N( char, lvl->spaces + 1 ); + + spcs[lvl->spaces] = '\0'; + for ( i = 0; i < lvl->spaces; i++ ) spcs[i] = ' '; + syck_emitter_write( e, spcs, lvl->spaces ); + S_FREE( spcs ); + } + syck_emitter_write( e, ": ", 2 ); + } + } + break; + + case syck_lvl_imap: + { + if ( lvl->ncount > 0 ) { + if ( lvl->ncount % 2 == 0 ) { + syck_emitter_write( e, ", ", 2 ); + } else { + syck_emitter_write( e, ": ", 2 ); + } + } + } + break; + + default: break; + } + lvl->ncount++; + + syck_emit( e, n ); +} + +/* + * Closes emission of a collection. + */ +void syck_emit_end( SyckEmitter *e ) +{ + SyckLevel *lvl = syck_emitter_current_level( e ); + SyckLevel *parent = syck_emitter_parent_level( e ); + switch ( lvl->status ) + { + case syck_lvl_seq: + if ( lvl->ncount == 0 ) { + syck_emitter_write( e, "[]\n", 3 ); + } else if ( parent->status == syck_lvl_mapx ) { + syck_emitter_write( e, "\n", 1 ); + } + break; + + case syck_lvl_iseq: + syck_emitter_write( e, "]\n", 1 ); + break; + + case syck_lvl_map: + if ( lvl->ncount == 0 ) { + syck_emitter_write( e, "{}\n", 3 ); + } else if ( lvl->ncount % 2 == 1 ) { + syck_emitter_write( e, ":\n", 1 ); + } else if ( parent->status == syck_lvl_mapx ) { + syck_emitter_write( e, "\n", 1 ); + } + break; + + case syck_lvl_imap: + syck_emitter_write( e, "}\n", 1 ); + break; + + default: break; + } +} + +/* + * Fill markers table with emitter nodes in the + * soon-to-be-emitted tree. + */ +SYMID +syck_emitter_mark_node( SyckEmitter *e, st_data_t n ) +{ + SYMID oid = 0; + char *anchor_name = NULL; + + /* + * Ensure markers table is initialized. + */ + if ( e->markers == NULL ) + { + e->markers = st_init_numtable(); + } + + /* + * Markers table initially marks the string position of the + * object. Doesn't yet create an anchor, simply notes the + * position. + */ + if ( ! st_lookup( e->markers, n, (st_data_t *)&oid ) ) + { + /* + * Store all markers + */ + oid = e->markers->num_entries + 1; + st_insert( e->markers, n, (st_data_t)oid ); + } + else + { + if ( e->anchors == NULL ) + { + e->anchors = st_init_numtable(); + } + + if ( ! st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) ) + { + int idx = 0; + const char *anc = ( e->anchor_format == NULL ? DEFAULT_ANCHOR_FORMAT : e->anchor_format ); + + /* + * Second time hitting this object, let's give it an anchor + */ + idx = e->anchors->num_entries + 1; + anchor_name = S_ALLOC_N( char, strlen( anc ) + 10 ); + S_MEMZERO( anchor_name, char, strlen( anc ) + 10 ); + sprintf( anchor_name, anc, idx ); + + /* + * Insert into anchors table + */ + st_insert( e->anchors, (st_data_t)oid, (st_data_t)anchor_name ); + } + } + return oid; +} + diff --git a/trunk/ext/syck/extconf.rb b/trunk/ext/syck/extconf.rb new file mode 100644 index 0000000000..6c10448c70 --- /dev/null +++ b/trunk/ext/syck/extconf.rb @@ -0,0 +1,5 @@ +require 'mkmf' + +have_header( "st.h" ) +create_makefile( "syck" ) + diff --git a/trunk/ext/syck/gram.c b/trunk/ext/syck/gram.c new file mode 100644 index 0000000000..615a594f61 --- /dev/null +++ b/trunk/ext/syck/gram.c @@ -0,0 +1,1894 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ +#define yyparse syckparse +#define yylex sycklex +#define yyerror syckerror +#define yylval sycklval +#define yychar syckchar +#define yydebug syckdebug +#define yynerrs sycknerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + YAML_ANCHOR = 258, + YAML_ALIAS = 259, + YAML_TRANSFER = 260, + YAML_TAGURI = 261, + YAML_ITRANSFER = 262, + YAML_WORD = 263, + YAML_PLAIN = 264, + YAML_BLOCK = 265, + YAML_DOCSEP = 266, + YAML_IOPEN = 267, + YAML_INDENT = 268, + YAML_IEND = 269 + }; +#endif +#define YAML_ANCHOR 258 +#define YAML_ALIAS 259 +#define YAML_TRANSFER 260 +#define YAML_TAGURI 261 +#define YAML_ITRANSFER 262 +#define YAML_WORD 263 +#define YAML_PLAIN 264 +#define YAML_BLOCK 265 +#define YAML_DOCSEP 266 +#define YAML_IOPEN 267 +#define YAML_INDENT 268 +#define YAML_IEND 269 + + + + +/* Copy the first part of user declarations. */ +#line 14 "gram.y" + + +#include "syck.h" + +void apply_seq_in_map( SyckParser *parser, SyckNode *n ); + +#define YYPARSE_PARAM parser +#define YYLEX_PARAM parser + +#define NULL_NODE(parser, node) \ + SyckNode *node = syck_new_str( "", scalar_plain ); \ + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \ + { \ + node->type_id = syck_taguri( YAML_DOMAIN, "null", 4 ); \ + } \ + else \ + { \ + node->type_id = syck_strndup( "null", 4 ); \ + } + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 35 "gram.y" +typedef union YYSTYPE { + SYMID nodeId; + SyckNode *nodeData; + char *name; +} YYSTYPE; +/* Line 191 of yacc.c. */ +#line 140 "gram.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 152 "gram.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 52 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 396 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 23 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 29 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 79 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 128 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 269 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 21, 15, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, + 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 17, 2, 18, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 19, 2, 20, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 5, 8, 9, 11, 13, 15, 18, + 21, 24, 28, 30, 32, 36, 37, 40, 43, 46, + 49, 51, 54, 56, 58, 60, 63, 66, 69, 72, + 75, 77, 79, 81, 85, 87, 89, 91, 93, 95, + 99, 103, 106, 110, 113, 117, 120, 124, 127, 129, + 133, 136, 140, 143, 145, 149, 151, 153, 157, 161, + 165, 168, 172, 175, 179, 182, 184, 188, 190, 194, + 196, 200, 204, 207, 211, 215, 218, 220, 224, 226 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 24, 0, -1, 25, -1, 11, 27, -1, -1, 33, + -1, 26, -1, 34, -1, 5, 26, -1, 6, 26, + -1, 3, 26, -1, 29, 26, 32, -1, 25, -1, + 28, -1, 29, 28, 30, -1, -1, 7, 28, -1, + 5, 28, -1, 6, 28, -1, 3, 28, -1, 12, + -1, 29, 13, -1, 14, -1, 13, -1, 14, -1, + 31, 32, -1, 5, 33, -1, 6, 33, -1, 7, + 33, -1, 3, 33, -1, 4, -1, 8, -1, 9, + -1, 29, 33, 32, -1, 10, -1, 35, -1, 39, + -1, 42, -1, 49, -1, 29, 37, 30, -1, 29, + 38, 30, -1, 15, 27, -1, 5, 31, 38, -1, + 5, 37, -1, 6, 31, 38, -1, 6, 37, -1, + 3, 31, 38, -1, 3, 37, -1, 36, -1, 38, + 31, 36, -1, 38, 31, -1, 17, 40, 18, -1, + 17, 18, -1, 41, -1, 40, 21, 41, -1, 25, + -1, 48, -1, 29, 43, 30, -1, 29, 47, 30, + -1, 5, 31, 47, -1, 5, 43, -1, 6, 31, + 47, -1, 6, 43, -1, 3, 31, 47, -1, 3, + 43, -1, 33, -1, 22, 25, 31, -1, 27, -1, + 44, 16, 45, -1, 46, -1, 47, 31, 36, -1, + 47, 31, 46, -1, 47, 31, -1, 25, 16, 27, + -1, 19, 50, 20, -1, 19, 20, -1, 51, -1, + 50, 21, 51, -1, 25, -1, 48, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 56, 56, 60, 65, 70, 71, 74, 75, 80, + 85, 94, 100, 101, 104, 109, 113, 121, 126, 131, + 145, 146, 149, 152, 155, 156, 164, 169, 174, 182, + 186, 194, 207, 208, 218, 219, 220, 221, 222, 228, + 232, 238, 244, 249, 254, 259, 264, 268, 274, 278, + 283, 292, 296, 302, 306, 313, 314, 320, 325, 332, + 337, 342, 347, 352, 356, 362, 363, 369, 379, 396, + 397, 409, 417, 426, 434, 438, 444, 445, 454, 461 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "YAML_ANCHOR", "YAML_ALIAS", + "YAML_TRANSFER", "YAML_TAGURI", "YAML_ITRANSFER", "YAML_WORD", + "YAML_PLAIN", "YAML_BLOCK", "YAML_DOCSEP", "YAML_IOPEN", "YAML_INDENT", + "YAML_IEND", "'-'", "':'", "'['", "']'", "'{'", "'}'", "','", "'?'", + "$accept", "doc", "atom", "ind_rep", "atom_or_empty", "empty", + "indent_open", "indent_end", "indent_sep", "indent_flex_end", "word_rep", + "struct_rep", "implicit_seq", "basic_seq", "top_imp_seq", + "in_implicit_seq", "inline_seq", "in_inline_seq", "inline_seq_atom", + "implicit_map", "top_imp_map", "complex_key", "complex_value", + "complex_mapping", "in_implicit_map", "basic_mapping", "inline_map", + "in_inline_map", "inline_map_atom", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 45, 58, 91, 93, 123, + 125, 44, 63 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 23, 24, 24, 24, 25, 25, 26, 26, 26, + 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, + 29, 29, 30, 31, 32, 32, 33, 33, 33, 33, + 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, + 35, 36, 37, 37, 37, 37, 37, 37, 38, 38, + 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, + 43, 43, 43, 43, 43, 44, 44, 45, 46, 47, + 47, 47, 47, 48, 49, 49, 50, 50, 51, 51 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 2, 0, 1, 1, 1, 2, 2, + 2, 3, 1, 1, 3, 0, 2, 2, 2, 2, + 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, + 3, 2, 3, 2, 3, 2, 3, 2, 1, 3, + 2, 3, 2, 1, 3, 1, 1, 3, 3, 3, + 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, + 3, 3, 2, 3, 3, 2, 1, 3, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 4, 0, 30, 0, 0, 0, 31, 32, 34, 15, + 20, 0, 0, 0, 2, 6, 0, 5, 7, 35, + 36, 37, 38, 10, 29, 8, 26, 9, 27, 0, + 0, 0, 0, 28, 15, 15, 15, 15, 12, 3, + 13, 15, 52, 55, 0, 53, 56, 75, 78, 79, + 0, 76, 1, 0, 0, 0, 21, 15, 0, 0, + 65, 48, 0, 0, 0, 0, 69, 0, 0, 19, + 17, 18, 15, 15, 15, 16, 15, 15, 15, 15, + 0, 15, 51, 0, 74, 0, 23, 0, 47, 64, + 0, 43, 60, 0, 45, 62, 41, 0, 24, 0, + 11, 33, 22, 39, 40, 50, 57, 15, 58, 72, + 14, 73, 54, 77, 65, 46, 63, 42, 59, 44, + 61, 66, 25, 49, 67, 68, 70, 71 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 13, 38, 15, 39, 40, 16, 103, 99, 101, + 17, 18, 19, 61, 62, 63, 20, 44, 45, 21, + 64, 65, 125, 66, 67, 46, 22, 50, 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -97 +static const short int yypact[] = +{ + 250, 318, -97, 318, 318, 374, -97, -97, -97, 335, + -97, 267, 232, 7, -97, -97, 192, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, 374, + 374, 374, 352, -97, 335, 335, 335, 384, -97, -97, + -97, 212, -97, 10, 0, -97, -97, -97, 10, -97, + -4, -97, -97, 284, 284, 284, -97, 335, 318, 30, + 30, -97, -2, 36, -2, 16, -97, 36, 30, -97, + -97, -97, 384, 384, 384, -97, 363, 301, 301, 301, + -2, 335, -97, 318, -97, 318, -97, 158, -97, -97, + 158, -97, -97, 158, -97, -97, -97, 24, -97, 30, + -97, -97, -97, -97, -97, 26, -97, 335, -97, 158, + -97, -97, -97, -97, -97, 24, 24, 24, 24, 24, + 24, -97, -97, -97, -97, -97, -97, -97 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -97, -97, 8, 81, -56, 109, 33, -53, 74, -54, + -1, -97, -97, -96, -31, -32, -97, -97, -44, -97, + 77, -97, -97, -52, 9, -6, -97, -97, -29 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 24, 96, 26, 28, 33, 100, 49, 52, 14, 123, + 104, 106, 102, 126, 108, 60, 84, 85, 82, 43, + 48, 83, 88, 91, 94, 111, 81, 110, 24, 26, + 28, 68, 107, 24, 26, 28, 33, 86, 32, 112, + 60, 57, 41, 86, 98, 122, 88, 91, 94, 86, + 102, 124, 24, 26, 28, 115, 113, 127, 117, 0, + 0, 119, 32, 32, 32, 32, 97, 41, 41, 41, + 76, 24, 26, 28, 41, 68, 24, 26, 28, 49, + 0, 0, 23, 0, 25, 27, 114, 0, 0, 114, + 41, 43, 114, 48, 0, 0, 116, 59, 0, 118, + 0, 0, 120, 0, 0, 76, 76, 76, 114, 76, + 41, 41, 41, 0, 41, 23, 25, 27, 0, 0, + 32, 0, 59, 32, 0, 0, 32, 87, 90, 93, + 89, 92, 95, 0, 23, 25, 27, 105, 0, 0, + 41, 109, 32, 69, 70, 71, 75, 0, 0, 0, + 80, 87, 90, 93, 89, 92, 95, 0, 23, 25, + 27, 29, 2, 30, 31, 5, 6, 7, 0, 0, + 10, 121, 0, 57, 0, 0, 0, 0, 0, 0, + 58, 69, 70, 71, 0, 80, 69, 70, 71, 105, + 109, 105, 109, 105, 109, 53, 2, 54, 55, 5, + 6, 7, 8, 0, 10, 56, 0, 57, 0, 11, + 0, 12, 0, 0, 58, 77, 2, 78, 79, 37, + 6, 7, 8, 0, 10, 56, 0, 57, 0, 11, + 0, 12, 0, 0, 58, 1, 2, 3, 4, 5, + 6, 7, 8, 0, 10, 0, 0, 0, 0, 11, + 0, 12, 47, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 0, 0, 0, 0, 11, 0, 12, + 1, 2, 3, 4, 5, 6, 7, 8, 0, 10, + 0, 0, 0, 0, 11, 42, 12, 53, 2, 54, + 55, 5, 6, 7, 8, 0, 10, 86, 0, 0, + 0, 11, 0, 12, 77, 2, 78, 79, 37, 6, + 7, 8, 0, 10, 86, 0, 0, 0, 11, 0, + 12, 1, 2, 3, 4, 5, 6, 7, 8, 0, + 10, 0, 0, 0, 0, 11, 0, 12, 34, 2, + 35, 36, 37, 6, 7, 8, 0, 10, 0, 0, + 0, 0, 11, 0, 12, 29, 2, 30, 31, 5, + 6, 7, 0, 0, 10, 56, 72, 2, 73, 74, + 37, 6, 7, 0, 0, 10, 56, 29, 2, 30, + 31, 5, 6, 7, 0, 0, 10, 72, 2, 73, + 74, 37, 6, 7, 0, 0, 10 +}; + +static const yysigned_char yycheck[] = +{ + 1, 57, 3, 4, 5, 59, 12, 0, 0, 105, + 63, 64, 14, 109, 67, 16, 20, 21, 18, 11, + 12, 21, 53, 54, 55, 81, 16, 80, 29, 30, + 31, 32, 16, 34, 35, 36, 37, 13, 5, 83, + 41, 15, 9, 13, 14, 99, 77, 78, 79, 13, + 14, 107, 53, 54, 55, 87, 85, 109, 90, -1, + -1, 93, 29, 30, 31, 32, 58, 34, 35, 36, + 37, 72, 73, 74, 41, 76, 77, 78, 79, 85, + -1, -1, 1, -1, 3, 4, 87, -1, -1, 90, + 57, 83, 93, 85, -1, -1, 87, 16, -1, 90, + -1, -1, 93, -1, -1, 72, 73, 74, 109, 76, + 77, 78, 79, -1, 81, 34, 35, 36, -1, -1, + 87, -1, 41, 90, -1, -1, 93, 53, 54, 55, + 53, 54, 55, -1, 53, 54, 55, 63, -1, -1, + 107, 67, 109, 34, 35, 36, 37, -1, -1, -1, + 41, 77, 78, 79, 77, 78, 79, -1, 77, 78, + 79, 3, 4, 5, 6, 7, 8, 9, -1, -1, + 12, 97, -1, 15, -1, -1, -1, -1, -1, -1, + 22, 72, 73, 74, -1, 76, 77, 78, 79, 115, + 116, 117, 118, 119, 120, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, 13, -1, 15, -1, 17, + -1, 19, -1, -1, 22, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, 13, -1, 15, -1, 17, + -1, 19, -1, -1, 22, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, -1, -1, -1, -1, 17, + -1, 19, 20, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, -1, -1, -1, -1, 17, -1, 19, + 3, 4, 5, 6, 7, 8, 9, 10, -1, 12, + -1, -1, -1, -1, 17, 18, 19, 3, 4, 5, + 6, 7, 8, 9, 10, -1, 12, 13, -1, -1, + -1, 17, -1, 19, 3, 4, 5, 6, 7, 8, + 9, 10, -1, 12, 13, -1, -1, -1, 17, -1, + 19, 3, 4, 5, 6, 7, 8, 9, 10, -1, + 12, -1, -1, -1, -1, 17, -1, 19, 3, 4, + 5, 6, 7, 8, 9, 10, -1, 12, -1, -1, + -1, -1, 17, -1, 19, 3, 4, 5, 6, 7, + 8, 9, -1, -1, 12, 13, 3, 4, 5, 6, + 7, 8, 9, -1, -1, 12, 13, 3, 4, 5, + 6, 7, 8, 9, -1, -1, 12, 3, 4, 5, + 6, 7, 8, 9, -1, -1, 12 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 17, 19, 24, 25, 26, 29, 33, 34, 35, + 39, 42, 49, 26, 33, 26, 33, 26, 33, 3, + 5, 6, 29, 33, 3, 5, 6, 7, 25, 27, + 28, 29, 18, 25, 40, 41, 48, 20, 25, 48, + 50, 51, 0, 3, 5, 6, 13, 15, 22, 26, + 33, 36, 37, 38, 43, 44, 46, 47, 33, 28, + 28, 28, 3, 5, 6, 28, 29, 3, 5, 6, + 28, 16, 18, 21, 20, 21, 13, 31, 37, 43, + 31, 37, 43, 31, 37, 43, 27, 25, 14, 31, + 32, 32, 14, 30, 30, 31, 30, 16, 30, 31, + 30, 27, 41, 51, 33, 38, 47, 38, 47, 38, + 47, 31, 32, 36, 27, 45, 36, 46 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + ((Current).first_line = (Rhs)[1].first_line, \ + (Current).first_column = (Rhs)[1].first_column, \ + (Current).last_line = (Rhs)[N].last_line, \ + (Current).last_column = (Rhs)[N].last_column) +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + /* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 57 "gram.y" + { + ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 3: +#line 61 "gram.y" + { + ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 4: +#line 65 "gram.y" + { + ((SyckParser *)parser)->eof = 1; + } + break; + + case 8: +#line 76 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 9: +#line 81 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 10: +#line 86 "gram.y" + { + /* + * _Anchors_: The language binding must keep a separate symbol table + * for anchors. The actual ID in the symbol table is returned to the + * higher nodes, though. + */ + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 11: +#line 95 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 14: +#line 105 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 15: +#line 109 "gram.y" + { + NULL_NODE( parser, n ); + yyval.nodeData = n; + } + break; + + case 16: +#line 114 "gram.y" + { + if ( ((SyckParser *)parser)->implicit_typing == 1 ) + { + try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + } + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 17: +#line 122 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 18: +#line 127 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 19: +#line 132 "gram.y" + { + /* + * _Anchors_: The language binding must keep a separate symbol table + * for anchors. The actual ID in the symbol table is returned to the + * higher nodes, though. + */ + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 26: +#line 165 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 27: +#line 170 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 28: +#line 175 "gram.y" + { + if ( ((SyckParser *)parser)->implicit_typing == 1 ) + { + try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + } + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 29: +#line 183 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 30: +#line 187 "gram.y" + { + /* + * _Aliases_: The anchor symbol table is scanned for the anchor name. + * The anchor's ID in the language's symbol table is returned. + */ + yyval.nodeData = syck_hdlr_get_anchor( (SyckParser *)parser, yyvsp[0].name ); + } + break; + + case 31: +#line 195 "gram.y" + { + SyckNode *n = yyvsp[0].nodeData; + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + yyval.nodeData = n; + } + break; + + case 33: +#line 209 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 39: +#line 229 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 40: +#line 233 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 41: +#line 239 "gram.y" + { + yyval.nodeId = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 42: +#line 245 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 43: +#line 250 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 44: +#line 255 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 45: +#line 260 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 46: +#line 265 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData ); + } + break; + + case 47: +#line 269 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 48: +#line 275 "gram.y" + { + yyval.nodeData = syck_new_seq( yyvsp[0].nodeId ); + } + break; + + case 49: +#line 279 "gram.y" + { + syck_seq_add( yyvsp[-2].nodeData, yyvsp[0].nodeId ); + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 50: +#line 284 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 51: +#line 293 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 52: +#line 297 "gram.y" + { + yyval.nodeData = syck_alloc_seq(); + } + break; + + case 53: +#line 303 "gram.y" + { + yyval.nodeData = syck_new_seq( syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 54: +#line 307 "gram.y" + { + syck_seq_add( yyvsp[-2].nodeData, syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 57: +#line 321 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData ); + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 58: +#line 326 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData ); + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 59: +#line 333 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 60: +#line 338 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 61: +#line 343 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 62: +#line 348 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 63: +#line 353 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData ); + } + break; + + case 64: +#line 357 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 66: +#line 364 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 68: +#line 380 "gram.y" + { + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 70: +#line 398 "gram.y" + { + if ( yyvsp[-2].nodeData->shortcut == NULL ) + { + yyvsp[-2].nodeData->shortcut = syck_new_seq( yyvsp[0].nodeId ); + } + else + { + syck_seq_add( yyvsp[-2].nodeData->shortcut, yyvsp[0].nodeId ); + } + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 71: +#line 410 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-2].nodeData ); + syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData ); + syck_free_node( yyvsp[0].nodeData ); + yyvsp[0].nodeData = NULL; + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 72: +#line 418 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 73: +#line 427 "gram.y" + { + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 74: +#line 435 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 75: +#line 439 "gram.y" + { + yyval.nodeData = syck_alloc_map(); + } + break; + + case 77: +#line 446 "gram.y" + { + syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData ); + syck_free_node( yyvsp[0].nodeData ); + yyvsp[0].nodeData = NULL; + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 78: +#line 455 "gram.y" + { + NULL_NODE( parser, n ); + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, n ) ); + } + break; + + + } + +/* Line 1010 of yacc.c. */ +#line 1651 "gram.c" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + } + } + else + { + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + + yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 464 "gram.y" + + +void +apply_seq_in_map( SyckParser *parser, SyckNode *n ) +{ + long map_len; + if ( n->shortcut == NULL ) + { + return; + } + + map_len = syck_map_count( n ); + syck_map_assign( n, map_value, map_len - 1, + syck_hdlr_add_node( parser, n->shortcut ) ); + + n->shortcut = NULL; +} + + diff --git a/trunk/ext/syck/gram.h b/trunk/ext/syck/gram.h new file mode 100644 index 0000000000..547149ab4b --- /dev/null +++ b/trunk/ext/syck/gram.h @@ -0,0 +1,79 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + YAML_ANCHOR = 258, + YAML_ALIAS = 259, + YAML_TRANSFER = 260, + YAML_TAGURI = 261, + YAML_ITRANSFER = 262, + YAML_WORD = 263, + YAML_PLAIN = 264, + YAML_BLOCK = 265, + YAML_DOCSEP = 266, + YAML_IOPEN = 267, + YAML_INDENT = 268, + YAML_IEND = 269 + }; +#endif +#define YAML_ANCHOR 258 +#define YAML_ALIAS 259 +#define YAML_TRANSFER 260 +#define YAML_TAGURI 261 +#define YAML_ITRANSFER 262 +#define YAML_WORD 263 +#define YAML_PLAIN 264 +#define YAML_BLOCK 265 +#define YAML_DOCSEP 266 +#define YAML_IOPEN 267 +#define YAML_INDENT 268 +#define YAML_IEND 269 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 35 "gram.y" +typedef union YYSTYPE { + SYMID nodeId; + SyckNode *nodeData; + char *name; +} YYSTYPE; +/* Line 1285 of yacc.c. */ +#line 71 "gram.h" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + + + diff --git a/trunk/ext/syck/handler.c b/trunk/ext/syck/handler.c new file mode 100644 index 0000000000..d76a72e5cc --- /dev/null +++ b/trunk/ext/syck/handler.c @@ -0,0 +1,173 @@ +/* + * handler.c + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +SYMID +syck_hdlr_add_node( SyckParser *p, SyckNode *n ) +{ + SYMID id; + + if ( ! n->id ) + { + n->id = (p->handler)( p, n ); + } + id = n->id; + + if ( n->anchor == NULL ) + { + syck_free_node( n ); + } + return id; +} + +SyckNode * +syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n ) +{ + SyckNode *ntmp = NULL; + + n->anchor = a; + if ( p->bad_anchors != NULL ) + { + SyckNode *bad; + if ( st_lookup( p->bad_anchors, (st_data_t)a, (void *)&bad ) ) + { + if ( n->kind != syck_str_kind ) + { + n->id = bad->id; + (p->handler)( p, n ); + } + } + } + if ( p->anchors == NULL ) + { + p->anchors = st_init_strtable(); + } + if ( st_lookup( p->anchors, (st_data_t)a, (void *)&ntmp ) ) + { + if ( ntmp != (void *)1 ) + { + syck_free_node( ntmp ); + } + } + st_insert( p->anchors, (st_data_t)a, (st_data_t)n ); + return n; +} + +void +syck_hdlr_remove_anchor( SyckParser *p, char *a ) +{ + char *atmp = a; + SyckNode *ntmp; + if ( p->anchors == NULL ) + { + p->anchors = st_init_strtable(); + } + if ( st_delete( p->anchors, (void *)&atmp, (void *)&ntmp ) ) + { + if ( ntmp != (void *)1 ) + { + syck_free_node( ntmp ); + } + } + st_insert( p->anchors, (st_data_t)a, (st_data_t)1 ); +} + +SyckNode * +syck_hdlr_get_anchor( SyckParser *p, char *a ) +{ + SyckNode *n = NULL; + + if ( p->anchors != NULL ) + { + if ( st_lookup( p->anchors, (st_data_t)a, (void *)&n ) ) + { + if ( n != (void *)1 ) + { + S_FREE( a ); + return n; + } + else + { + if ( p->bad_anchors == NULL ) + { + p->bad_anchors = st_init_strtable(); + } + if ( ! st_lookup( p->bad_anchors, (st_data_t)a, (void *)&n ) ) + { + n = (p->bad_anchor_handler)( p, a ); + st_insert( p->bad_anchors, (st_data_t)a, (st_data_t)n ); + } + } + } + } + + if ( n == NULL ) + { + n = (p->bad_anchor_handler)( p, a ); + } + + if ( n->anchor ) + { + S_FREE( a ); + } + else + { + n->anchor = a; + } + + return n; +} + +void +syck_add_transfer( char *uri, SyckNode *n, int taguri ) +{ + if ( n->type_id != NULL ) + { + S_FREE( n->type_id ); + } + + if ( taguri == 0 ) + { + n->type_id = uri; + return; + } + + n->type_id = syck_type_id_to_uri( uri ); + S_FREE( uri ); +} + +char * +syck_xprivate( const char *type_id, int type_len ) +{ + char *uri = S_ALLOC_N( char, type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "x-private:" ); + strncat( uri, type_id, type_len ); + return uri; +} + +char * +syck_taguri( const char *domain, const char *type_id, int type_len ) +{ + char *uri = S_ALLOC_N( char, strlen( domain ) + type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "tag:" ); + strcat( uri, domain ); + strcat( uri, ":" ); + strncat( uri, type_id, type_len ); + return uri; +} + +int +syck_try_implicit( SyckNode *n ) +{ + return 1; +} + diff --git a/trunk/ext/syck/implicit.c b/trunk/ext/syck/implicit.c new file mode 100644 index 0000000000..126b896f18 --- /dev/null +++ b/trunk/ext/syck/implicit.c @@ -0,0 +1,2990 @@ +/* Generated by re2c 0.9.10 on Mon Sep 19 21:46:50 2005 */ +#line 1 "implicit.re" +/* + * implicit.re + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +#define YYCTYPE char +#define YYCURSOR cursor +#define YYMARKER marker +#define YYLIMIT limit +#define YYFILL(n) + +void +try_tag_implicit( SyckNode *n, int taguri ) +{ + const char *tid = ""; + switch ( n->kind ) + { + case syck_str_kind: + tid = syck_match_implicit( n->data.str->ptr, n->data.str->len ); + break; + + case syck_seq_kind: + tid = "seq"; + break; + + case syck_map_kind: + tid = "map"; + break; + } + if ( n->type_id != NULL ) S_FREE( n->type_id ); + if ( taguri == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, tid, strlen( tid ) ); + } else { + n->type_id = syck_strndup( tid, strlen( tid ) ); + } +} + +const char * +syck_match_implicit( const char *str, size_t len ) +{ + const char *cursor, *limit, *marker = 0; + cursor = str; + limit = str + len; + + +#line 55 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 26) YYFILL(26); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy6; + case '+': goto yy16; + case '-': goto yy17; + case '.': goto yy20; + case '0': goto yy18; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy19; + case '<': goto yy22; + case '=': goto yy21; + case 'F': goto yy15; + case 'N': goto yy5; + case 'O': goto yy13; + case 'T': goto yy11; + case 'Y': goto yy9; + case 'f': goto yy14; + case 'n': goto yy4; + case 'o': goto yy12; + case 't': goto yy10; + case 'y': goto yy8; + case '~': goto yy2; + default: goto yy23; + } +yy2: ++YYCURSOR; + if((yych = *YYCURSOR) <= 0x00) goto yy6; + goto yy3; +yy3: +#line 123 "implicit.re" +{ return "str"; } +#line 100 "<stdout>" +yy4: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'o': goto yy172; + case 'u': goto yy200; + default: goto yy3; + } +yy5: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'O': case 'o': goto yy172; + case 'U': goto yy195; + case 'u': goto yy196; + default: goto yy3; + } +yy6: ++YYCURSOR; + goto yy7; +yy7: +#line 85 "implicit.re" +{ return "null"; } +#line 121 "<stdout>" +yy8: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'e': goto yy194; + default: goto yy3; + } +yy9: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'E': goto yy192; + case 'e': goto yy193; + default: goto yy3; + } +yy10: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'r': goto yy190; + default: goto yy3; + } +yy11: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'R': goto yy186; + case 'r': goto yy187; + default: goto yy3; + } +yy12: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'f': goto yy185; + case 'n': goto yy182; + default: goto yy3; + } +yy13: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'F': goto yy180; + case 'N': case 'n': goto yy182; + case 'f': goto yy181; + default: goto yy3; + } +yy14: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'a': goto yy177; + default: goto yy3; + } +yy15: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'A': goto yy168; + case 'a': goto yy169; + default: goto yy3; + } +yy16: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy167; + case '0': goto yy158; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + default: goto yy3; + } +yy17: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy157; + case '0': goto yy158; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + default: goto yy3; + } +yy18: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x00: goto yy52; + case ',': goto yy142; + case '.': goto yy50; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy140; + case '8': + case '9': goto yy141; + case ':': goto yy49; + case 'x': goto yy144; + default: goto yy3; + } +yy19: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x00: goto yy52; + case ',': goto yy47; + case '.': goto yy50; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy46; + case ':': goto yy49; + default: goto yy3; + } +yy20: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'I': goto yy33; + case 'N': goto yy31; + case 'i': goto yy32; + case 'n': goto yy30; + default: goto yy3; + } +yy21: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy28; + goto yy3; +yy22: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '<': goto yy24; + default: goto yy3; + } +yy23: yych = *++YYCURSOR; + goto yy3; +yy24: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy26; + goto yy25; +yy25: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy3; + } +yy26: ++YYCURSOR; + goto yy27; +yy27: +#line 121 "implicit.re" +{ return "merge"; } +#line 279 "<stdout>" +yy28: ++YYCURSOR; + goto yy29; +yy29: +#line 119 "implicit.re" +{ return "default"; } +#line 285 "<stdout>" +yy30: yych = *++YYCURSOR; + switch(yych){ + case 'a': goto yy45; + default: goto yy25; + } +yy31: yych = *++YYCURSOR; + switch(yych){ + case 'A': goto yy40; + case 'a': goto yy41; + default: goto yy25; + } +yy32: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy39; + default: goto yy25; + } +yy33: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy34; + case 'n': goto yy35; + default: goto yy25; + } +yy34: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy36; + default: goto yy25; + } +yy35: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy36; + default: goto yy25; + } +yy36: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy37; +yy37: ++YYCURSOR; + goto yy38; +yy38: +#line 105 "implicit.re" +{ return "float#inf"; } +#line 326 "<stdout>" +yy39: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy36; + default: goto yy25; + } +yy40: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy42; + default: goto yy25; + } +yy41: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy42; + default: goto yy25; + } +yy42: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy43; +yy43: ++YYCURSOR; + goto yy44; +yy44: +#line 109 "implicit.re" +{ return "float#nan"; } +#line 350 "<stdout>" +yy45: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy42; + default: goto yy25; + } +yy46: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy74; + default: goto yy48; + } +yy47: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy48; +yy48: switch(yych){ + case 0x00: goto yy52; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + case '.': goto yy50; + case ':': goto yy49; + default: goto yy25; + } +yy49: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': goto yy66; + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy25; + } +yy50: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + goto yy51; +yy51: switch(yych){ + case 0x00: goto yy56; + case ',': goto yy54; + case '.': goto yy58; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy50; + case 'E': case 'e': goto yy60; + default: goto yy25; + } +yy52: ++YYCURSOR; + goto yy53; +yy53: +#line 97 "implicit.re" +{ return "int"; } +#line 432 "<stdout>" +yy54: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy55; +yy55: switch(yych){ + case 0x00: goto yy56; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy54; + default: goto yy25; + } +yy56: ++YYCURSOR; + goto yy57; +yy57: +#line 99 "implicit.re" +{ return "float#fix"; } +#line 456 "<stdout>" +yy58: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + goto yy59; +yy59: switch(yych){ + case '.': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'E': case 'e': goto yy60; + default: goto yy25; + } +yy60: yych = *++YYCURSOR; + switch(yych){ + case '+': case '-': goto yy61; + default: goto yy25; + } +yy61: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy25; + goto yy63; +yy62: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy63; +yy63: switch(yych){ + case 0x00: goto yy64; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy62; + default: goto yy25; + } +yy64: ++YYCURSOR; + goto yy65; +yy65: +#line 101 "implicit.re" +{ return "float#exp"; } +#line 506 "<stdout>" +yy66: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy70; + case '.': goto yy68; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + case ':': goto yy49; + default: goto yy25; + } +yy67: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy70; + case '.': goto yy68; + case ':': goto yy49; + default: goto yy25; + } +yy68: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy69; +yy69: switch(yych){ + case 0x00: goto yy72; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy68; + default: goto yy25; + } +yy70: ++YYCURSOR; + goto yy71; +yy71: +#line 95 "implicit.re" +{ return "int#base60"; } +#line 558 "<stdout>" +yy72: ++YYCURSOR; + goto yy73; +yy73: +#line 103 "implicit.re" +{ return "float#base60"; } +#line 564 "<stdout>" +yy74: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy75; + default: goto yy48; + } +yy75: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy48; + } +yy76: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy77; + default: goto yy25; + } +yy77: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy78; + default: goto yy25; + } +yy78: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy79; + default: goto yy25; + } +yy79: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy80; + default: goto yy25; + } +yy80: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy81; + default: goto yy25; + } +yy81: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy82; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + case 'T': goto yy84; + case 't': goto yy85; + default: goto yy87; + } +yy82: ++YYCURSOR; + goto yy83; +yy83: +#line 111 "implicit.re" +{ return "timestamp#ymd"; } +#line 667 "<stdout>" +yy84: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy126; + default: goto yy25; + } +yy85: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy108; + default: goto yy25; + } +yy86: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 9) YYFILL(9); + yych = *YYCURSOR; + goto yy87; +yy87: switch(yych){ + case 0x09: case ' ': goto yy86; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy88; + default: goto yy25; + } +yy88: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy89; + default: goto yy25; + } +yy89: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy90; + default: goto yy25; + } +yy90: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy25; + } +yy91: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy92; + default: goto yy25; + } +yy92: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy93; + default: goto yy25; + } +yy93: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy94; + default: goto yy25; + } +yy94: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy95; + default: goto yy25; + } +yy95: yych = *++YYCURSOR; + switch(yych){ + case 0x09: case ' ': goto yy98; + case '.': goto yy96; + default: goto yy25; + } +yy96: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy97; +yy97: switch(yych){ + case 0x09: case ' ': goto yy98; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy96; + default: goto yy25; + } +yy98: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy99; +yy99: switch(yych){ + case 0x09: case ' ': goto yy98; + case '+': case '-': goto yy101; + case 'Z': goto yy100; + default: goto yy25; + } +yy100: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy105; + goto yy25; +yy101: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy102; + default: goto yy25; + } +yy102: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy103; + default: goto yy25; + } +yy103: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy105; + case ':': goto yy104; + default: goto yy25; + } +yy104: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy107; + default: goto yy25; + } +yy105: ++YYCURSOR; + goto yy106; +yy106: +#line 115 "implicit.re" +{ return "timestamp#spaced"; } +#line 884 "<stdout>" +yy107: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy100; + default: goto yy25; + } +yy108: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy109; + default: goto yy25; + } +yy109: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy110; + default: goto yy25; + } +yy110: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy111; + default: goto yy25; + } +yy111: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy112; + default: goto yy25; + } +yy112: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy113; + default: goto yy25; + } +yy113: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy114; + default: goto yy25; + } +yy114: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy115; + default: goto yy25; + } +yy115: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy116; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + default: goto yy117; + } +yy116: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy117; +yy117: switch(yych){ + case '+': case '-': goto yy119; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy116; + case 'Z': goto yy118; + default: goto yy25; + } +yy118: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy123; + goto yy25; +yy119: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy120; + default: goto yy25; + } +yy120: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy121; + default: goto yy25; + } +yy121: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy123; + case ':': goto yy122; + default: goto yy25; + } +yy122: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy125; + default: goto yy25; + } +yy123: ++YYCURSOR; + goto yy124; +yy124: +#line 113 "implicit.re" +{ return "timestamp#iso8601"; } +#line 1069 "<stdout>" +yy125: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy118; + default: goto yy25; + } +yy126: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy127; + default: goto yy25; + } +yy127: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy128; + default: goto yy25; + } +yy128: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy129; + default: goto yy25; + } +yy129: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy130; + default: goto yy25; + } +yy130: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy131; + default: goto yy25; + } +yy131: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy132; + default: goto yy25; + } +yy132: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy133; + default: goto yy25; + } +yy133: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy134; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + case 'Z': goto yy136; + default: goto yy135; + } +yy134: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy135; +yy135: switch(yych){ + case '+': case '-': goto yy119; + case '0': goto yy134; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy138; + case 'Z': goto yy118; + default: goto yy25; + } +yy136: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy137; +yy137: yych = *++YYCURSOR; + goto yy124; +yy138: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy139; +yy139: switch(yych){ + case '+': case '-': goto yy119; + case '0': goto yy134; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy138; + case 'Z': goto yy136; + default: goto yy25; + } +yy140: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy155; + case '8': + case '9': goto yy153; + default: goto yy143; + } +yy141: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy153; + default: goto yy152; + } +yy142: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy143; +yy143: switch(yych){ + case 0x00: goto yy149; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy142; + case '.': goto yy50; + case '8': + case '9': goto yy151; + case ':': goto yy49; + default: goto yy25; + } +yy144: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy25; + goto yy146; +yy145: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy146; +yy146: switch(yych){ + case 0x00: goto yy147; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy145; + default: goto yy25; + } +yy147: ++YYCURSOR; + goto yy148; +yy148: +#line 91 "implicit.re" +{ return "int#hex"; } +#line 1307 "<stdout>" +yy149: ++YYCURSOR; + goto yy150; +yy150: +#line 93 "implicit.re" +{ return "int#oct"; } +#line 1313 "<stdout>" +yy151: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy152; +yy152: switch(yych){ + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy151; + case '.': goto yy50; + case ':': goto yy49; + default: goto yy25; + } +yy153: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy154; + default: goto yy152; + } +yy154: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy152; + } +yy155: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy156; + case '8': + case '9': goto yy154; + default: goto yy143; + } +yy156: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy143; + } +yy157: yych = *++YYCURSOR; + switch(yych){ + case 'I': goto yy160; + case 'i': goto yy159; + default: goto yy25; + } +yy158: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy52; + case 'x': goto yy144; + default: goto yy143; + } +yy159: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy166; + default: goto yy25; + } +yy160: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy161; + case 'n': goto yy162; + default: goto yy25; + } +yy161: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy163; + default: goto yy25; + } +yy162: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy163; + default: goto yy25; + } +yy163: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy164; +yy164: ++YYCURSOR; + goto yy165; +yy165: +#line 107 "implicit.re" +{ return "float#neginf"; } +#line 1412 "<stdout>" +yy166: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy163; + default: goto yy25; + } +yy167: yych = *++YYCURSOR; + switch(yych){ + case 'I': goto yy33; + case 'i': goto yy32; + default: goto yy25; + } +yy168: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy175; + default: goto yy25; + } +yy169: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy170; + default: goto yy25; + } +yy170: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy171; + default: goto yy25; + } +yy171: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy172; + default: goto yy25; + } +yy172: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy173; +yy173: ++YYCURSOR; + goto yy174; +yy174: +#line 89 "implicit.re" +{ return "bool#no"; } +#line 1452 "<stdout>" +yy175: yych = *++YYCURSOR; + switch(yych){ + case 'S': goto yy176; + default: goto yy25; + } +yy176: yych = *++YYCURSOR; + switch(yych){ + case 'E': goto yy172; + default: goto yy25; + } +yy177: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy178; + default: goto yy25; + } +yy178: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy179; + default: goto yy25; + } +yy179: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy172; + default: goto yy25; + } +yy180: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy172; + default: goto yy25; + } +yy181: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy172; + default: goto yy25; + } +yy182: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy183; +yy183: ++YYCURSOR; + goto yy184; +yy184: +#line 87 "implicit.re" +{ return "bool#yes"; } +#line 1496 "<stdout>" +yy185: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy172; + default: goto yy25; + } +yy186: yych = *++YYCURSOR; + switch(yych){ + case 'U': goto yy189; + default: goto yy25; + } +yy187: yych = *++YYCURSOR; + switch(yych){ + case 'u': goto yy188; + default: goto yy25; + } +yy188: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy182; + default: goto yy25; + } +yy189: yych = *++YYCURSOR; + switch(yych){ + case 'E': goto yy182; + default: goto yy25; + } +yy190: yych = *++YYCURSOR; + switch(yych){ + case 'u': goto yy191; + default: goto yy25; + } +yy191: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy182; + default: goto yy25; + } +yy192: yych = *++YYCURSOR; + switch(yych){ + case 'S': goto yy182; + default: goto yy25; + } +yy193: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy182; + default: goto yy25; + } +yy194: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy182; + default: goto yy25; + } +yy195: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy199; + default: goto yy25; + } +yy196: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy197; + default: goto yy25; + } +yy197: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy198; + default: goto yy25; + } +yy198: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy6; + goto yy25; +yy199: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy198; + default: goto yy25; + } +yy200: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy201; + default: goto yy25; + } +yy201: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 'l': goto yy198; + default: goto yy25; + } +} +#line 125 "implicit.re" + + +} + +/* Remove ending fragment and compare types */ +int +syck_tagcmp( const char *tag1, const char *tag2 ) +{ + if ( tag1 == tag2 ) return 1; + if ( tag1 == NULL || tag2 == NULL ) return 0; + else { + int i; + char *othorpe; + char *tmp1 = syck_strndup( tag1, strlen( tag1 ) ); + char *tmp2 = syck_strndup( tag2, strlen( tag2 ) ); + othorpe = strstr( tmp1, "#" ); + if ( othorpe != NULL ) { + othorpe[0] = '\0'; + } + othorpe = strstr( tmp2, "#" ); + if ( othorpe != NULL ) { + othorpe[0] = '\0'; + } + i = strcmp( tmp1, tmp2 ); + S_FREE( tmp1 ); S_FREE( tmp2 ); + return i; + } +} + +char * +syck_type_id_to_uri( const char *type_id ) +{ + const char *cursor, *limit, *marker = 0; + + cursor = type_id; + limit = type_id + strlen( type_id ); + + +#line 1620 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy202; + ++YYCURSOR; +yy202: + if((YYLIMIT - YYCURSOR) < 11) YYFILL(11); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy204; + case '!': goto yy208; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': case 'u': + case 'v': + case 'w': case 'y': + case 'z': goto yy210; + case 't': goto yy205; + case 'x': goto yy207; + default: goto yy211; + } +yy204: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy206; + } +yy205: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + case 'a': goto yy246; + default: goto yy206; + } +yy206: +#line 202 "implicit.re" +{ return syck_taguri( YAML_DOMAIN, type_id, strlen( type_id ) ); } +#line 1768 "<stdout>" +yy207: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy215; + case '-': goto yy236; + default: goto yy206; + } +yy208: ++YYCURSOR; + goto yy209; +yy209: +#line 176 "implicit.re" +{ return syck_xprivate( type_id + 1, strlen( type_id ) - 1 ); } +#line 1842 "<stdout>" +yy210: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy206; + } +yy211: yych = *++YYCURSOR; + goto yy206; +yy212: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy213; +yy213: switch(yych){ + case '-': goto yy212; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy204; + } +yy214: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy215; +yy215: switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy204; + } +yy216: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy224; + default: goto yy204; + } +yy217: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy218: ++YYCURSOR; + goto yy219; +yy219: +#line 178 "implicit.re" +{ char *domain = S_ALLOC_N( char, ( YYCURSOR - type_id ) + 15 ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + strcat( domain, "." ); + strcat( domain, YAML_DOMAIN ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +#line 2149 "<stdout>" +yy220: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 12) YYFILL(12); + yych = *YYCURSOR; + goto yy221; +yy221: switch(yych){ + case ',': goto yy216; + case '-': goto yy222; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy222: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy223; +yy223: switch(yych){ + case '-': goto yy222; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy224: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy225; + default: goto yy204; + } +yy225: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy226; + default: goto yy204; + } +yy226: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy227; + default: goto yy204; + } +yy227: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy228; + case '/': goto yy229; + default: goto yy204; + } +yy228: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy231; + default: goto yy204; + } +yy229: ++YYCURSOR; + goto yy230; +yy230: +#line 191 "implicit.re" +{ char *domain = S_ALLOC_N( char, YYCURSOR - type_id ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +#line 2365 "<stdout>" +yy231: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy232; + default: goto yy204; + } +yy232: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy233; + case '/': goto yy229; + default: goto yy204; + } +yy233: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy234; + default: goto yy204; + } +yy234: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy235; + default: goto yy204; + } +yy235: yych = *++YYCURSOR; + switch(yych){ + case '/': goto yy229; + default: goto yy204; + } +yy236: yych = *++YYCURSOR; + switch(yych){ + case 'p': goto yy237; + default: goto yy213; + } +yy237: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'r': goto yy238; + default: goto yy213; + } +yy238: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'i': goto yy239; + default: goto yy213; + } +yy239: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'v': goto yy240; + default: goto yy213; + } +yy240: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'a': goto yy241; + default: goto yy213; + } +yy241: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 't': goto yy242; + default: goto yy213; + } +yy242: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'e': goto yy243; + default: goto yy213; + } +yy243: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case ':': goto yy244; + default: goto yy213; + } +yy244: ++YYCURSOR; + goto yy245; +yy245: +#line 174 "implicit.re" +{ return syck_strndup( type_id, strlen( type_id ) ); } +#line 2485 "<stdout>" +yy246: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'g': goto yy247; + default: goto yy213; + } +yy247: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case ':': goto yy248; + default: goto yy213; + } +yy248: yych = *++YYCURSOR; + switch(yych){ + case ',': + case '-': + case '.': goto yy204; + default: goto yy250; + } +yy249: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy250; +yy250: switch(yych){ + case ',': goto yy253; + case '-': goto yy251; + case '.': goto yy254; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy249; + default: goto yy204; + } +yy251: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy252; +yy252: switch(yych){ + case '-': goto yy251; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy249; + default: goto yy204; + } +yy253: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy259; + default: goto yy204; + } +yy254: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy255: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 12) YYFILL(12); + yych = *YYCURSOR; + goto yy256; +yy256: switch(yych){ + case ',': goto yy253; + case '-': goto yy257; + case '.': goto yy254; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy257: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy258; +yy258: switch(yych){ + case '-': goto yy257; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy259: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy260; + default: goto yy204; + } +yy260: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy261; + default: goto yy204; + } +yy261: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy262; + default: goto yy204; + } +yy262: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy263; + case ':': goto yy264; + default: goto yy204; + } +yy263: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy266; + default: goto yy204; + } +yy264: ++YYCURSOR; + goto yy265; +yy265: +#line 172 "implicit.re" +{ return syck_strndup( type_id, strlen( type_id ) ); } +#line 2932 "<stdout>" +yy266: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy267; + default: goto yy204; + } +yy267: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy268; + case ':': goto yy264; + default: goto yy204; + } +yy268: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy269; + default: goto yy204; + } +yy269: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy270; + default: goto yy204; + } +yy270: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case ':': goto yy264; + default: goto yy204; + } +} +#line 204 "implicit.re" + + +} diff --git a/trunk/ext/syck/node.c b/trunk/ext/syck/node.c new file mode 100644 index 0000000000..890eba9d58 --- /dev/null +++ b/trunk/ext/syck/node.c @@ -0,0 +1,407 @@ +/* + * node.c + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +/* + * Node allocation functions + */ +SyckNode * +syck_alloc_node( enum syck_kind_tag type ) +{ + SyckNode *s; + + s = S_ALLOC( SyckNode ); + s->kind = type; + s->id = 0; + s->type_id = NULL; + s->anchor = NULL; + s->shortcut = NULL; + + return s; +} + +void +syck_free_node( SyckNode *n ) +{ + syck_free_members( n ); + if ( n->type_id != NULL ) + { + S_FREE( n->type_id ); + n->type_id = NULL; + } + if ( n->anchor != NULL ) + { + S_FREE( n->anchor ); + n->anchor = NULL; + } + S_FREE( n ); +} + +SyckNode * +syck_alloc_map(void) +{ + SyckNode *n; + struct SyckMap *m; + + m = S_ALLOC( struct SyckMap ); + m->style = map_none; + m->idx = 0; + m->capa = ALLOC_CT; + m->keys = S_ALLOC_N( SYMID, m->capa ); + m->values = S_ALLOC_N( SYMID, m->capa ); + + n = syck_alloc_node( syck_map_kind ); + n->data.pairs = m; + + return n; +} + +SyckNode * +syck_alloc_seq(void) +{ + SyckNode *n; + struct SyckSeq *s; + + s = S_ALLOC( struct SyckSeq ); + s->style = seq_none; + s->idx = 0; + s->capa = ALLOC_CT; + s->items = S_ALLOC_N( SYMID, s->capa ); + + n = syck_alloc_node( syck_seq_kind ); + n->data.list = s; + + return n; +} + +SyckNode * +syck_alloc_str(void) +{ + SyckNode *n; + struct SyckStr *s; + + s = S_ALLOC( struct SyckStr ); + s->len = 0; + s->ptr = NULL; + s->style = scalar_none; + + n = syck_alloc_node( syck_str_kind ); + n->data.str = s; + + return n; +} + +SyckNode * +syck_new_str( const char *str, enum scalar_style style ) +{ + return syck_new_str2( str, strlen( str ), style ); +} + +SyckNode * +syck_new_str2( const char *str, long len, enum scalar_style style ) +{ + SyckNode *n; + + n = syck_alloc_str(); + n->data.str->ptr = S_ALLOC_N( char, len + 1 ); + n->data.str->len = len; + n->data.str->style = style; + memcpy( n->data.str->ptr, str, len ); + n->data.str->ptr[len] = '\0'; + + return n; +} + +void +syck_replace_str( SyckNode *n, char *str, enum scalar_style style ) +{ + syck_replace_str2( n, str, strlen( str ), style ); +} + +void +syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style ) +{ + if ( n->data.str != NULL ) + { + S_FREE( n->data.str->ptr ); + n->data.str->ptr = NULL; + n->data.str->len = 0; + } + n->data.str->ptr = S_ALLOC_N( char, len + 1 ); + n->data.str->len = len; + n->data.str->style = style; + memcpy( n->data.str->ptr, str, len ); + n->data.str->ptr[len] = '\0'; +} + +void +syck_str_blow_away_commas( SyckNode *n ) +{ + char *go, *end; + + go = n->data.str->ptr; + end = go + n->data.str->len; + while ( *(++go) != '\0' ) + { + if ( *go == ',' ) + { + n->data.str->len -= 1; + memmove( go, go + 1, end - go ); + end -= 1; + } + } +} + +char * +syck_str_read( SyckNode *n ) +{ + ASSERT( n != NULL ); + return n->data.str->ptr; +} + +SyckNode * +syck_new_map( SYMID key, SYMID value ) +{ + SyckNode *n; + + n = syck_alloc_map(); + syck_map_add( n, key, value ); + + return n; +} + +void +syck_map_empty( SyckNode *n ) +{ + struct SyckMap *m; + ASSERT( n != NULL ); + ASSERT( n->data.list != NULL ); + + S_FREE( n->data.pairs->keys ); + S_FREE( n->data.pairs->values ); + m = n->data.pairs; + m->idx = 0; + m->capa = ALLOC_CT; + m->keys = S_ALLOC_N( SYMID, m->capa ); + m->values = S_ALLOC_N( SYMID, m->capa ); +} + +void +syck_map_add( SyckNode *map, SYMID key, SYMID value ) +{ + struct SyckMap *m; + long idx; + + ASSERT( map != NULL ); + ASSERT( map->data.pairs != NULL ); + + m = map->data.pairs; + idx = m->idx; + m->idx += 1; + if ( m->idx > m->capa ) + { + m->capa += ALLOC_CT; + S_REALLOC_N( m->keys, SYMID, m->capa ); + S_REALLOC_N( m->values, SYMID, m->capa ); + } + m->keys[idx] = key; + m->values[idx] = value; +} + +void +syck_map_update( SyckNode *map1, SyckNode *map2 ) +{ + struct SyckMap *m1, *m2; + long new_idx, new_capa; + ASSERT( map1 != NULL ); + ASSERT( map2 != NULL ); + + m1 = map1->data.pairs; + m2 = map2->data.pairs; + if ( m2->idx < 1 ) return; + + new_idx = m1->idx; + new_idx += m2->idx; + new_capa = m1->capa; + while ( new_idx > new_capa ) + { + new_capa += ALLOC_CT; + } + if ( new_capa > m1->capa ) + { + m1->capa = new_capa; + S_REALLOC_N( m1->keys, SYMID, m1->capa ); + S_REALLOC_N( m1->values, SYMID, m1->capa ); + } + for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ ) + { + m1->keys[m1->idx] = m2->keys[new_idx]; + m1->values[m1->idx] = m2->values[new_idx]; + } +} + +long +syck_map_count( SyckNode *map ) +{ + ASSERT( map != NULL ); + ASSERT( map->data.pairs != NULL ); + return map->data.pairs->idx; +} + +void +syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id ) +{ + struct SyckMap *m; + + ASSERT( map != NULL ); + m = map->data.pairs; + ASSERT( m != NULL ); + if ( p == map_key ) + { + m->keys[idx] = id; + } + else + { + m->values[idx] = id; + } +} + +SYMID +syck_map_read( SyckNode *map, enum map_part p, long idx ) +{ + struct SyckMap *m; + + ASSERT( map != NULL ); + m = map->data.pairs; + ASSERT( m != NULL ); + if ( p == map_key ) + { + return m->keys[idx]; + } + else + { + return m->values[idx]; + } +} + +SyckNode * +syck_new_seq( SYMID value ) +{ + SyckNode *n; + + n = syck_alloc_seq(); + syck_seq_add( n, value ); + + return n; +} + +void +syck_seq_empty( SyckNode *n ) +{ + struct SyckSeq *s; + ASSERT( n != NULL ); + ASSERT( n->data.list != NULL ); + + S_FREE( n->data.list->items ); + s = n->data.list; + s->idx = 0; + s->capa = ALLOC_CT; + s->items = S_ALLOC_N( SYMID, s->capa ); +} + +void +syck_seq_add( SyckNode *arr, SYMID value ) +{ + struct SyckSeq *s; + long idx; + + ASSERT( arr != NULL ); + ASSERT( arr->data.list != NULL ); + + s = arr->data.list; + idx = s->idx; + s->idx += 1; + if ( s->idx > s->capa ) + { + s->capa += ALLOC_CT; + S_REALLOC_N( s->items, SYMID, s->capa ); + } + s->items[idx] = value; +} + +long +syck_seq_count( SyckNode *seq ) +{ + ASSERT( seq != NULL ); + ASSERT( seq->data.list != NULL ); + return seq->data.list->idx; +} + +void +syck_seq_assign( SyckNode *seq, long idx, SYMID id ) +{ + struct SyckSeq *s; + + ASSERT( map != NULL ); + s = seq->data.list; + ASSERT( m != NULL ); + s->items[idx] = id; +} + +SYMID +syck_seq_read( SyckNode *seq, long idx ) +{ + struct SyckSeq *s; + + ASSERT( seq != NULL ); + s = seq->data.list; + ASSERT( s != NULL ); + return s->items[idx]; +} + +void +syck_free_members( SyckNode *n ) +{ + if ( n == NULL ) return; + + switch ( n->kind ) + { + case syck_str_kind: + if ( n->data.str != NULL ) + { + S_FREE( n->data.str->ptr ); + n->data.str->ptr = NULL; + n->data.str->len = 0; + S_FREE( n->data.str ); + n->data.str = NULL; + } + break; + + case syck_seq_kind: + if ( n->data.list != NULL ) + { + S_FREE( n->data.list->items ); + S_FREE( n->data.list ); + n->data.list = NULL; + } + break; + + case syck_map_kind: + if ( n->data.pairs != NULL ) + { + S_FREE( n->data.pairs->keys ); + S_FREE( n->data.pairs->values ); + S_FREE( n->data.pairs ); + n->data.pairs = NULL; + } + break; + } +} + diff --git a/trunk/ext/syck/rubyext.c b/trunk/ext/syck/rubyext.c new file mode 100644 index 0000000000..d5c6372076 --- /dev/null +++ b/trunk/ext/syck/rubyext.c @@ -0,0 +1,2284 @@ +/* -*- indent-tabs-mode: nil -*- */ +/* + * rubyext.c + * + * $Author$ + * + * Copyright (C) 2003-2005 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "ruby/encoding.h" +#include "syck.h" +#include <sys/types.h> +#include <time.h> + +typedef struct RVALUE { + union { +#if 0 + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; +#endif + struct RBasic basic; + struct RObject object; + struct RClass klass; + /*struct RFloat flonum;*/ + /*struct RString string;*/ + struct RArray array; + /*struct RRegexp regexp;*/ + struct RHash hash; + /*struct RData data;*/ + struct RStruct rstruct; + /*struct RBignum bignum;*/ + /*struct RFile file;*/ + } as; +} RVALUE; + +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; + +#define RUBY_DOMAIN "ruby.yaml.org,2002" + +/* + * symbols and constants + */ +static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each; +static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set; +static VALUE sym_model, sym_generic, sym_input, sym_bytecode; +static VALUE sym_scalar, sym_seq, sym_map; +static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline; +static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter; +static VALUE oDefaultResolver, oGenericResolver; + +/* + * my private collection of numerical oddities. + */ +static double S_zero(void) { return 0.0; } +static double S_one(void) { return 1.0; } +static double S_inf(void) { return S_one() / S_zero(); } +static double S_nan(void) { return S_zero() / S_zero(); } + +static VALUE syck_node_transform( VALUE ); + +/* + * handler prototypes + */ +SYMID rb_syck_load_handler _((SyckParser *, SyckNode *)); +void rb_syck_err_handler _((SyckParser *, const char *)); +SyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *)); +void rb_syck_output_handler _((SyckEmitter *, char *, long)); +void rb_syck_emitter_handler _((SyckEmitter *, st_data_t)); +int syck_parser_assign_io _((SyckParser *, VALUE *)); +VALUE syck_scalar_alloc _((VALUE class)); +VALUE syck_seq_alloc _((VALUE class)); +VALUE syck_map_alloc _((VALUE class)); + +struct parser_xtra { + VALUE data; /* Borrowed this idea from marshal.c to fix [ruby-core:8067] problem */ + VALUE proc; + VALUE resolver; + int taint; +}; + +struct emitter_xtra { + VALUE oid; + VALUE data; + VALUE port; +}; + +/* + * Convert YAML to bytecode + */ +VALUE +rb_syck_compile(VALUE self, VALUE port) +{ + SYMID oid; + int taint; + char *ret; + VALUE bc; + bytestring_t *sav = NULL; + void *data = NULL; + + SyckParser *parser = syck_new_parser(); + taint = syck_parser_assign_io(parser, &port); + syck_parser_handler( parser, syck_yaml2byte_handler ); + syck_parser_error_handler( parser, NULL ); + syck_parser_implicit_typing( parser, 0 ); + syck_parser_taguri_expansion( parser, 0 ); + oid = syck_parse( parser ); + if (!syck_lookup_sym( parser, oid, &data )) { + rb_raise(rb_eSyntaxError, "root node <%lx> not found", oid); + } + sav = data; + + ret = S_ALLOCA_N( char, strlen( sav->buffer ) + 3 ); + ret[0] = '\0'; + strcat( ret, "D\n" ); + strcat( ret, sav->buffer ); + + syck_free_parser( parser ); + + bc = rb_str_new2( ret ); + if ( taint ) OBJ_TAINT( bc ); + return bc; +} + +/* + * read from io. + */ +long +rb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip ) +{ + long len = 0; + + ASSERT( str != NULL ); + max_size -= skip; + + if ( max_size <= 0 ) max_size = 0; + else + { + /* + * call io#read. + */ + VALUE src = (VALUE)str->ptr; + VALUE n = LONG2NUM(max_size); + VALUE str2 = rb_funcall2(src, s_read, 1, &n); + if (!NIL_P(str2)) + { + StringValue(str2); + len = RSTRING_LEN(str2); + memcpy( buf + skip, RSTRING_PTR(str2), len ); + } + } + len += skip; + buf[len] = '\0'; + return len; +} + +/* + * determine: are we reading from a string or io? + * (returns tainted? boolean) + */ +int +syck_parser_assign_io(SyckParser *parser, VALUE *pport) +{ + int taint = Qtrue; + VALUE tmp, port = *pport; + if (!NIL_P(tmp = rb_check_string_type(port))) { + taint = OBJ_TAINTED(port); /* original taintedness */ + port = tmp; + syck_parser_str( parser, RSTRING_PTR(port), RSTRING_LEN(port), NULL ); + } + else if (rb_respond_to(port, s_read)) { + if (rb_respond_to(port, s_binmode)) { + rb_funcall2(port, s_binmode, 0, 0); + } + syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read ); + } + else { + rb_raise(rb_eTypeError, "instance of IO needed"); + } + *pport = port; + return taint; +} + +/* + * Get value in hash by key, forcing an empty hash if nil. + */ +VALUE +syck_get_hash_aref(VALUE hsh, VALUE key) +{ + VALUE val = rb_hash_aref( hsh, key ); + if ( NIL_P( val ) ) + { + val = rb_hash_new(); + rb_hash_aset(hsh, key, val); + } + return val; +} + +/* + * creating timestamps + */ +SYMID +rb_syck_mktime(char *str, long len) +{ + VALUE time; + char *ptr = str; + VALUE year = INT2FIX(0); + VALUE mon = INT2FIX(0); + VALUE day = INT2FIX(0); + VALUE hour = INT2FIX(0); + VALUE min = INT2FIX(0); + VALUE sec = INT2FIX(0); + long usec; + + /* Year*/ + if ( ptr[0] != '\0' && len > 0 ) { + year = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Month*/ + ptr += 4; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + mon = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Day*/ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + day = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Hour*/ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + hour = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Minute */ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + min = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Second */ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + sec = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Millisecond */ + ptr += 2; + if ( len > ptr - str && *ptr == '.' ) + { + char padded[] = "000000"; + char *end = ptr + 1; + char *p = end; + while ( isdigit( *end ) ) end++; + if (end - p < sizeof(padded)) { + MEMCPY(padded, ptr + 1, char, end - (ptr + 1)); + p = padded; + } + usec = strtol(p, NULL, 10); + } + else + { + usec = 0; + } + + /* Time Zone*/ + while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\0' ) ptr++; + if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) ) + { + time_t tz_offset = strtol(ptr, NULL, 10) * 3600; + time_t tmp; + + while ( *ptr != ':' && *ptr != '\0' ) ptr++; + if ( *ptr == ':' ) + { + ptr += 1; + if ( tz_offset < 0 ) + { + tz_offset -= strtol(ptr, NULL, 10) * 60; + } + else + { + tz_offset += strtol(ptr, NULL, 10) * 60; + } + } + + /* Make TZ time*/ + time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec); + tmp = NUM2LONG(rb_funcall(time, s_to_i, 0)) - tz_offset; + return rb_funcall(rb_cTime, s_at, 2, LONG2NUM(tmp), LONG2NUM(usec)); + } + else + { + /* Make UTC time*/ + return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, LONG2NUM(usec)); + } +} + +/* + * handles merging of an array of hashes + * (see http://www.yaml.org/type/merge/) + */ +VALUE +syck_merge_i(VALUE entry, VALUE hsh ) +{ + VALUE tmp; + if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, "Hash", "to_hash")) ) + { + entry = tmp; + rb_funcall( hsh, s_update, 1, entry ); + } + return Qnil; +} + +/* + * default handler for ruby.yaml.org types + */ +int +yaml_org_handler( SyckNode *n, VALUE *ref ) +{ + char *type_id = n->type_id; + int transferred = 0; + long i = 0; + VALUE obj = Qnil; + + if ( type_id != NULL && strncmp( type_id, "tag:yaml.org,2002:", 18 ) == 0 ) + { + type_id += 18; + } + + switch (n->kind) + { + case syck_str_kind: + transferred = 1; + if ( type_id == NULL ) + { + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "null" ) == 0 ) + { + obj = Qnil; + } + else if ( strcmp( type_id, "binary" ) == 0 ) + { + VALUE arr; + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_funcall( obj, s_tr_bang, 2, rb_str_new2( "\n\t " ), rb_str_new2( "" ) ); + arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( "m" ) ); + obj = rb_ary_shift( arr ); + } + else if ( strcmp( type_id, "bool#yes" ) == 0 ) + { + obj = Qtrue; + } + else if ( strcmp( type_id, "bool#no" ) == 0 ) + { + obj = Qfalse; + } + else if ( strcmp( type_id, "int#hex" ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 16 ); + } + else if ( strcmp( type_id, "int#oct" ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 8 ); + } + else if ( strcmp( type_id, "int#base60" ) == 0 ) + { + char *ptr, *end; + long sixty = 1; + long total = 0; + syck_str_blow_away_commas( n ); + ptr = n->data.str->ptr; + end = n->data.str->ptr + n->data.str->len; + while ( end > ptr ) + { + long bnum = 0; + char *colon = end - 1; + while ( colon >= ptr && *colon != ':' ) + { + colon--; + } + if ( colon >= ptr && *colon == ':' ) *colon = '\0'; + + bnum = strtol( colon + 1, NULL, 10 ); + total += bnum * sixty; + sixty *= 60; + end = colon; + } + obj = INT2FIX(total); + } + else if ( strncmp( type_id, "int", 3 ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 10 ); + } + else if ( strcmp( type_id, "float#base60" ) == 0 ) + { + char *ptr, *end; + long sixty = 1; + double total = 0.0; + syck_str_blow_away_commas( n ); + ptr = n->data.str->ptr; + end = n->data.str->ptr + n->data.str->len; + while ( end > ptr ) + { + double bnum = 0; + char *colon = end - 1; + while ( colon >= ptr && *colon != ':' ) + { + colon--; + } + if ( colon >= ptr && *colon == ':' ) *colon = '\0'; + + bnum = strtod( colon + 1, NULL ); + total += bnum * sixty; + sixty *= 60; + end = colon; + } + obj = rb_float_new( total ); + } + else if ( strcmp( type_id, "float#nan" ) == 0 ) + { + obj = rb_float_new( S_nan() ); + } + else if ( strcmp( type_id, "float#inf" ) == 0 ) + { + obj = rb_float_new( S_inf() ); + } + else if ( strcmp( type_id, "float#neginf" ) == 0 ) + { + obj = rb_float_new( -S_inf() ); + } + else if ( strncmp( type_id, "float", 5 ) == 0 ) + { + double f; + syck_str_blow_away_commas( n ); + f = strtod( n->data.str->ptr, NULL ); + obj = rb_float_new( f ); + } + else if ( strcmp( type_id, "timestamp#iso8601" ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "timestamp#spaced" ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "timestamp#ymd" ) == 0 ) + { + char *ptr = n->data.str->ptr; + VALUE year, mon, day; + + /* Year*/ + ptr[4] = '\0'; + year = INT2FIX(strtol(ptr, NULL, 10)); + + /* Month*/ + ptr += 4; + while ( !ISDIGIT( *ptr ) ) ptr++; + mon = INT2FIX(strtol(ptr, NULL, 10)); + + /* Day*/ + ptr += 2; + while ( !ISDIGIT( *ptr ) ) ptr++; + day = INT2FIX(strtol(ptr, NULL, 10)); + + if ( !cDate ) { + /* + * Load Date module + */ + rb_require( "date" ); + cDate = rb_const_get( rb_cObject, rb_intern("Date") ); + } + + obj = rb_funcall( cDate, s_new, 3, year, mon, day ); + } + else if ( strncmp( type_id, "timestamp", 9 ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strncmp( type_id, "merge", 5 ) == 0 ) + { + obj = rb_funcall( cMergeKey, s_new, 0 ); + } + else if ( strncmp( type_id, "default", 7 ) == 0 ) + { + obj = rb_funcall( cDefaultKey, s_new, 0 ); + } + else if ( n->data.str->style == scalar_plain && + n->data.str->len > 1 && + strncmp( n->data.str->ptr, ":", 1 ) == 0 ) + { + obj = rb_funcall( oDefaultResolver, s_transfer, 2, + rb_str_new2( "tag:ruby.yaml.org,2002:sym" ), + rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) ); + } + else if ( strcmp( type_id, "str" ) == 0 ) + { + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_enc_associate(obj, rb_utf8_encoding()); + } + else + { + transferred = 0; + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + } + break; + + case syck_seq_kind: + if ( type_id == NULL || strcmp( type_id, "seq" ) == 0 ) + { + transferred = 1; + } + obj = rb_ary_new2( n->data.list->idx ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_ary_store( obj, i, syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + if ( type_id == NULL || strcmp( type_id, "map" ) == 0 ) + { + transferred = 1; + } + obj = rb_hash_new(); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + VALUE k = syck_map_read( n, map_key, i ); + VALUE v = syck_map_read( n, map_value, i ); + int skip_aset = 0; + + /* + * Handle merge keys + */ + if ( rb_obj_is_kind_of( k, cMergeKey ) ) + { + VALUE tmp; + if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, "Hash", "to_hash")) ) + { + VALUE dup = rb_funcall( tmp, s_dup, 0 ); + rb_funcall( dup, s_update, 1, obj ); + obj = dup; + skip_aset = 1; + } + else if ( !NIL_P(tmp = rb_check_array_type(v)) ) + { + VALUE end = rb_ary_pop( tmp ); + VALUE tmph = rb_check_convert_type(end, T_HASH, "Hash", "to_hash"); + if ( !NIL_P(tmph) ) + { + VALUE dup = rb_funcall( tmph, s_dup, 0 ); + tmp = rb_ary_reverse( tmp ); + rb_ary_push( tmp, obj ); + rb_block_call( tmp, s_each, 0, 0, syck_merge_i, dup ); + obj = dup; + skip_aset = 1; + } + } + } + else if ( rb_obj_is_kind_of( k, cDefaultKey ) ) + { + rb_funcall( obj, s_default_set, 1, v ); + skip_aset = 1; + } + + if ( ! skip_aset ) + { + rb_hash_aset( obj, k, v ); + } + } + break; + } + + *ref = obj; + return transferred; +} + +static void syck_node_mark( SyckNode *n ); + +/* + * {native mode} node handler + * - Converts data into native Ruby types + */ +SYMID +rb_syck_load_handler(SyckParser *p, SyckNode *n) +{ + VALUE obj = Qnil; + struct parser_xtra *bonus = (struct parser_xtra *)p->bonus; + VALUE resolver = bonus->resolver; + if ( NIL_P( resolver ) ) + { + resolver = oDefaultResolver; + } + + /* + * Create node, + */ + obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) ); + + /* + * ID already set, let's alter the symbol table to accept the new object + */ + if (n->id > 0 && !NIL_P(obj)) + { + MEMCPY((void *)n->id, (void *)obj, RVALUE, 1); + MEMZERO((void *)obj, RVALUE, 1); + obj = n->id; + } + + if ( bonus->taint) OBJ_TAINT( obj ); + if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj); + + rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj); + return obj; +} + +/* + * friendly errors. + */ +void +rb_syck_err_handler(SyckParser *p, const char *msg) +{ + char *endl = p->cursor; + + while ( *endl != '\0' && *endl != '\n' ) + endl++; + + endl[0] = '\0'; + rb_raise(rb_eArgError, "%s on line %d, col %"PRIdPTRDIFF": `%s'", + msg, + p->linect, + p->cursor - p->lineptr, + p->lineptr); +} + +/* + * provide bad anchor object to the parser. + */ +SyckNode * +rb_syck_bad_anchor_handler(SyckParser *p, char *a) +{ + VALUE anchor_name = rb_str_new2( a ); + SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name ); + badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 53 ); + return badanc; +} + +/* + * data loaded based on the model requested. + */ +void +syck_set_model(VALUE p, VALUE input, VALUE model) +{ + SyckParser *parser; + Data_Get_Struct(p, SyckParser, parser); + syck_parser_handler( parser, rb_syck_load_handler ); + /* WARN: gonna be obsoleted soon!! */ + if ( model == sym_generic ) + { + rb_funcall( p, s_set_resolver, 1, oGenericResolver ); + } + syck_parser_implicit_typing( parser, 1 ); + syck_parser_taguri_expansion( parser, 1 ); + + if ( NIL_P( input ) ) + { + input = rb_ivar_get( p, s_input ); + } + if ( input == sym_bytecode ) + { + syck_parser_set_input_type( parser, syck_bytecode_utf8 ); + } + else + { + syck_parser_set_input_type( parser, syck_yaml_utf8 ); + } + syck_parser_error_handler( parser, rb_syck_err_handler ); + syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler ); +} + +static int +syck_st_mark_nodes( char *key, SyckNode *n, char *arg ) +{ + if ( n != (void *)1 ) syck_node_mark( n ); + return ST_CONTINUE; +} + +/* + * mark parser nodes + */ +static void +syck_mark_parser(SyckParser *parser) +{ + struct parser_xtra *bonus = (struct parser_xtra *)parser->bonus; + rb_gc_mark_maybe(parser->root); + rb_gc_mark_maybe(parser->root_on_error); + rb_gc_mark( bonus->data ); + rb_gc_mark( bonus->proc ); + rb_gc_mark( bonus->resolver ); + + if ( parser->anchors != NULL ) + { + st_foreach( parser->anchors, syck_st_mark_nodes, 0 ); + } + if ( parser->bad_anchors != NULL ) + { + st_foreach( parser->bad_anchors, syck_st_mark_nodes, 0 ); + } +} + +/* + * Free the parser and any bonus attachment. + */ +void +rb_syck_free_parser(SyckParser *p) +{ + S_FREE( p->bonus ); + syck_free_parser(p); +} + +/* + * YAML::Syck::Parser.allocate + */ +VALUE syck_parser_s_alloc _((VALUE)); +VALUE +syck_parser_s_alloc(VALUE class) +{ + VALUE pobj; + SyckParser *parser = syck_new_parser(); + + parser->bonus = S_ALLOC( struct parser_xtra ); + S_MEMZERO( parser->bonus, struct parser_xtra, 1 ); + + pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser ); + + syck_parser_set_root_on_error( parser, Qnil ); + + return pobj; +} + +/* + * YAML::Syck::Parser.initialize( resolver, options ) + */ +static VALUE +syck_parser_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE options; + if (rb_scan_args(argc, argv, "01", &options) == 0) + { + options = rb_hash_new(); + } + else + { + Check_Type(options, T_HASH); + } + rb_ivar_set(self, s_options, options); + rb_ivar_set(self, s_input, Qnil); + return self; +} + +/* + * YAML::Syck::Parser.bufsize = Integer + */ +static VALUE +syck_parser_bufsize_set(VALUE self, VALUE size) +{ + SyckParser *parser; + + if ( rb_respond_to( size, s_to_i ) ) { + int n = NUM2INT(rb_funcall(size, s_to_i, 0)); + Data_Get_Struct(self, SyckParser, parser); + parser->bufsize = n; + } + return self; +} + +/* + * YAML::Syck::Parser.bufsize => Integer + */ +static VALUE +syck_parser_bufsize_get(VALUE self) +{ + SyckParser *parser; + + Data_Get_Struct(self, SyckParser, parser); + return INT2FIX( parser->bufsize ); +} + +/* + * YAML::Syck::Parser.load( IO or String ) + */ +VALUE +syck_parser_load(int argc, VALUE *argv, VALUE self) +{ + VALUE port, proc, model, input; + SyckParser *parser; + struct parser_xtra *bonus; + + rb_scan_args(argc, argv, "11", &port, &proc); + + input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input ); + model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model ); + Data_Get_Struct(self, SyckParser, parser); + syck_set_model( self, input, model ); + + bonus = (struct parser_xtra *)parser->bonus; + bonus->taint = syck_parser_assign_io(parser, &port); + bonus->data = rb_hash_new(); + bonus->resolver = rb_attr_get( self, s_resolver ); + if ( NIL_P( proc ) ) bonus->proc = 0; + else bonus->proc = proc; + + return syck_parse( parser ); +} + +/* + * YAML::Syck::Parser.load_documents( IO or String ) { |doc| } + */ +VALUE +syck_parser_load_documents(int argc, VALUE *argv, VALUE self) +{ + VALUE port, proc, v, input, model; + SyckParser *parser; + struct parser_xtra *bonus; + + rb_scan_args(argc, argv, "1&", &port, &proc); + + input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input ); + model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model ); + Data_Get_Struct(self, SyckParser, parser); + syck_set_model( self, input, model ); + + bonus = (struct parser_xtra *)parser->bonus; + bonus->taint = syck_parser_assign_io(parser, &port); + bonus->resolver = rb_attr_get( self, s_resolver ); + bonus->proc = 0; + + while ( 1 ) + { + /* Reset hash for tracking nodes */ + bonus->data = rb_hash_new(); + + /* Parse a document */ + v = syck_parse( parser ); + if ( parser->eof == 1 ) + { + break; + } + + /* Pass document to block */ + rb_funcall( proc, s_call, 1, v ); + } + + return Qnil; +} + +/* + * YAML::Syck::Parser#set_resolver + */ +VALUE +syck_parser_set_resolver(VALUE self, VALUE resolver) +{ + rb_ivar_set( self, s_resolver, resolver ); + return self; +} + +/* + * YAML::Syck::Resolver.initialize + */ +static VALUE +syck_resolver_initialize(VALUE self) +{ + rb_ivar_set(self, s_tags, rb_hash_new()); + return self; +} + +/* + * YAML::Syck::Resolver#add_type + */ +VALUE +syck_resolver_add_type(VALUE self, VALUE taguri, VALUE cls) +{ + VALUE tags = rb_attr_get(self, s_tags); + rb_hash_aset( tags, taguri, cls ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#use_types_at + */ +VALUE +syck_resolver_use_types_at(VALUE self, VALUE hsh) +{ + rb_ivar_set( self, s_tags, hsh ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#detect_implicit + */ +VALUE +syck_resolver_detect_implicit(VALUE self, VALUE val) +{ + return rb_str_new2( "" ); +} + +/* + * YAML::Syck::Resolver#node_import + */ +VALUE +syck_resolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + VALUE obj = Qnil; + int i = 0; + Data_Get_Struct(node, SyckNode, n); + + switch (n->kind) + { + case syck_str_kind: + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + break; + + case syck_seq_kind: + obj = rb_ary_new2( n->data.list->idx ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_ary_store( obj, i, syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + obj = rb_hash_new(); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + VALUE k = syck_map_read( n, map_key, i ); + VALUE v = syck_map_read( n, map_value, i ); + int skip_aset = 0; + + /* + * Handle merge keys + */ + if ( rb_obj_is_kind_of( k, cMergeKey ) ) + { + if ( rb_obj_is_kind_of( v, rb_cHash ) ) + { + VALUE dup = rb_funcall( v, s_dup, 0 ); + rb_funcall( dup, s_update, 1, obj ); + obj = dup; + skip_aset = 1; + } + else if ( rb_obj_is_kind_of( v, rb_cArray ) ) + { + VALUE end = rb_ary_pop( v ); + if ( rb_obj_is_kind_of( end, rb_cHash ) ) + { + VALUE dup = rb_funcall( end, s_dup, 0 ); + v = rb_ary_reverse( v ); + rb_ary_push( v, obj ); + rb_block_call( v, s_each, 0, 0, syck_merge_i, dup ); + obj = dup; + skip_aset = 1; + } + } + } + else if ( rb_obj_is_kind_of( k, cDefaultKey ) ) + { + rb_funcall( obj, s_default_set, 1, v ); + skip_aset = 1; + } + + if ( ! skip_aset ) + { + rb_hash_aset( obj, k, v ); + } + } + break; + } + + if ( n->type_id != NULL ) + { + obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj ); + } + return obj; +} + +/* + * Set instance variables + */ +VALUE +syck_set_ivars(VALUE vars, VALUE obj) +{ + VALUE ivname = rb_ary_entry( vars, 0 ); + char *ivn; + StringValue( ivname ); + ivn = S_ALLOCA_N( char, RSTRING_LEN(ivname) + 2 ); + ivn[0] = '@'; + ivn[1] = '\0'; + strncat( ivn, RSTRING_PTR(ivname), RSTRING_LEN(ivname) ); + rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#const_find + */ +VALUE +syck_const_find(VALUE const_name) +{ + VALUE tclass = rb_cObject; + VALUE tparts = rb_str_split( const_name, "::" ); + int i = 0; + for ( i = 0; i < RARRAY_LEN(tparts); i++ ) { + VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) ); + if ( !rb_const_defined( tclass, tpart ) ) return Qnil; + tclass = rb_const_get( tclass, tpart ); + } + return tclass; +} + +/* + * YAML::Syck::Resolver#transfer + */ +VALUE +syck_resolver_transfer(VALUE self, VALUE type, VALUE val) +{ + if (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) + { + type = rb_funcall( self, s_detect_implicit, 1, val ); + } + + if ( ! (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) ) + { + VALUE str_xprivate = rb_str_new2( "x-private" ); + VALUE colon = rb_str_new2( ":" ); + VALUE tags = rb_attr_get(self, s_tags); + VALUE target_class = rb_hash_aref( tags, type ); + VALUE subclass = target_class; + VALUE obj = Qnil; + + /* + * Should no tag match exactly, check for subclass format + */ + if ( NIL_P( target_class ) ) + { + VALUE subclass_parts = rb_ary_new(); + VALUE parts = rb_str_split( type, ":" ); + + while ( RARRAY_LEN(parts) > 1 ) + { + VALUE partial; + rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) ); + partial = rb_ary_join( parts, colon ); + target_class = rb_hash_aref( tags, partial ); + if ( NIL_P( target_class ) ) + { + rb_str_append( partial, colon ); + target_class = rb_hash_aref( tags, partial ); + } + + /* + * Possible subclass found, see if it supports subclassing + */ + if ( ! NIL_P( target_class ) ) + { + subclass = target_class; + if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) && + RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) ) + { + VALUE subclass_v; + subclass = rb_ary_join( subclass_parts, colon ); + subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass ); + subclass_v = syck_const_find( subclass ); + + if ( subclass_v != Qnil ) + { + subclass = subclass_v; + } + else if ( rb_cObject == target_class && subclass_v == Qnil ) + { + target_class = cYObject; + type = subclass; + subclass = cYObject; + } + else /* workaround for SEGV. real fix please */ + { + rb_raise( rb_eTypeError, "invalid subclass" ); + } + } + break; + } + } + } + + /* rb_raise(rb_eTypeError, "invalid typing scheme: %s given", + * scheme); + */ + + if ( rb_respond_to( target_class, s_call ) ) + { + obj = rb_funcall( target_class, s_call, 2, type, val ); + } + else + { + if ( rb_respond_to( target_class, s_yaml_new ) ) + { + obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val ); + } + else if ( !NIL_P( target_class ) ) + { + if ( subclass == rb_cBignum ) + { + obj = rb_str2inum( val, 10 ); /* for yaml dumped by 1.8.3 [ruby-core:6159] */ + } + else + { + obj = rb_obj_alloc( subclass ); + } + + if ( rb_respond_to( obj, s_yaml_initialize ) ) + { + rb_funcall( obj, s_yaml_initialize, 2, type, val ); + } + else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) ) + { + rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj ); + } + } + else + { + VALUE parts = rb_str_split( type, ":" ); + VALUE scheme = rb_ary_shift( parts ); + if ( rb_str_cmp( scheme, str_xprivate ) == 0 ) + { + VALUE name = rb_ary_join( parts, colon ); + obj = rb_funcall( cPrivateType, s_new, 2, name, val ); + } + else + { + VALUE domain = rb_ary_shift( parts ); + VALUE name = rb_ary_join( parts, colon ); + obj = rb_funcall( cDomainType, s_new, 3, domain, name, val ); + } + } + } + val = obj; + } + + return val; +} + +/* + * YAML::Syck::Resolver#tagurize + */ +VALUE +syck_resolver_tagurize(VALUE self, VALUE val) +{ + VALUE tmp = rb_check_string_type(val); + + if ( !NIL_P(tmp) ) + { + char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) ); + val = rb_str_new2( taguri ); + S_FREE( taguri ); + } + + return val; +} + +/* + * YAML::Syck::DefaultResolver#detect_implicit + */ +VALUE +syck_defaultresolver_detect_implicit(VALUE self, VALUE val) +{ + const char *type_id; + VALUE tmp = rb_check_string_type(val); + + if ( !NIL_P(tmp) ) + { + val = tmp; + type_id = syck_match_implicit( RSTRING_PTR(val), RSTRING_LEN(val) ); + return rb_str_new2( type_id ); + } + + return rb_str_new2( "" ); +} + +/* + * YAML::Syck::DefaultResolver#node_import + */ +VALUE +syck_defaultresolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + VALUE obj; + Data_Get_Struct( node, SyckNode, n ); + if ( !yaml_org_handler( n, &obj ) ) + { + obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj ); + } + return obj; +} + +/* + * YAML::Syck::GenericResolver#node_import + */ +VALUE +syck_genericresolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + int i = 0; + VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil; + Data_Get_Struct(node, SyckNode, n); + + if ( n->type_id != NULL ) + { + t = rb_str_new2(n->type_id); + } + + switch (n->kind) + { + case syck_str_kind: + { + v = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_enc_associate(v, rb_utf8_encoding()); + if ( n->data.str->style == scalar_1quote ) + { + style = sym_1quote; + } + else if ( n->data.str->style == scalar_2quote ) + { + style = sym_2quote; + } + else if ( n->data.str->style == scalar_fold ) + { + style = sym_fold; + } + else if ( n->data.str->style == scalar_literal ) + { + style = sym_literal; + } + else if ( n->data.str->style == scalar_plain ) + { + style = sym_plain; + } + obj = rb_funcall( cScalar, s_new, 3, t, v, style ); + } + break; + + case syck_seq_kind: + v = rb_ary_new2( syck_seq_count( n ) ); + for ( i = 0; i < syck_seq_count( n ); i++ ) + { + rb_ary_store( v, i, syck_seq_read( n, i ) ); + } + if ( n->data.list->style == seq_inline ) + { + style = sym_inline; + } + obj = rb_funcall( cSeq, s_new, 3, t, v, style ); + rb_iv_set(obj, "@kind", sym_seq); + break; + + case syck_map_kind: + v = rb_hash_new(); + for ( i = 0; i < syck_map_count( n ); i++ ) + { + rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) ); + } + if ( n->data.pairs->style == map_inline ) + { + style = sym_inline; + } + obj = rb_funcall( cMap, s_new, 3, t, v, style ); + rb_iv_set(obj, "@kind", sym_map); + break; + } + + return obj; +} + +/* + * YAML::Syck::BadAlias.initialize + */ +VALUE +syck_badalias_initialize(VALUE self, VALUE val) +{ + rb_iv_set( self, "@name", val ); + return self; +} + +/* + * YAML::Syck::BadAlias.<=> + */ +VALUE +syck_badalias_cmp(VALUE alias1, VALUE alias2) +{ + VALUE str1 = rb_ivar_get( alias1, s_name ); + VALUE str2 = rb_ivar_get( alias2, s_name ); + VALUE val = rb_funcall( str1, s_cmp, 1, str2 ); + return val; +} + +/* + * YAML::DomainType.initialize + */ +VALUE +syck_domaintype_initialize(VALUE self, VALUE domain, VALUE type_id, VALUE val) +{ + rb_iv_set( self, "@domain", domain ); + rb_iv_set( self, "@type_id", type_id ); + rb_iv_set( self, "@value", val ); + return self; +} + +/* + * YAML::Object.initialize + */ +VALUE +syck_yobject_initialize(VALUE self, VALUE klass, VALUE ivars) +{ + rb_iv_set( self, "@class", klass ); + rb_iv_set( self, "@ivars", ivars ); + return self; +} + +/* + * YAML::PrivateType.initialize + */ +VALUE +syck_privatetype_initialize(VALUE self, VALUE type_id, VALUE val) +{ + rb_iv_set( self, "@type_id", type_id ); + rb_iv_set( self, "@value", val ); + return self; +} + +/* + * Mark node contents. + */ +static void +syck_node_mark(SyckNode *n) +{ + int i; + rb_gc_mark_maybe( n->id ); + switch ( n->kind ) + { + case syck_seq_kind: + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_gc_mark( syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + rb_gc_mark( syck_map_read( n, map_key, i ) ); + rb_gc_mark( syck_map_read( n, map_value, i ) ); + } + break; + + case syck_str_kind: + default: + /* nothing */ + break; + } +#if 0 /* maybe needed */ + if ( n->shortcut ) syck_node_mark( n->shortcut ); /* caution: maybe cyclic */ +#endif +} + +/* + * YAML::Syck::Scalar.allocate + */ +VALUE +syck_scalar_alloc(VALUE class) +{ + SyckNode *node = syck_alloc_str(); + VALUE obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Scalar.initialize + */ +VALUE +syck_scalar_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + rb_iv_set( self, "@kind", sym_scalar ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Scalar.style= + */ +VALUE +syck_scalar_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( NIL_P( style ) ) + { + node->data.str->style = scalar_none; + } + else if ( style == sym_1quote ) + { + node->data.str->style = scalar_1quote; + } + else if ( style == sym_2quote ) + { + node->data.str->style = scalar_2quote; + } + else if ( style == sym_fold ) + { + node->data.str->style = scalar_fold; + } + else if ( style == sym_literal ) + { + node->data.str->style = scalar_literal; + } + else if ( style == sym_plain ) + { + node->data.str->style = scalar_plain; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * YAML::Syck::Scalar.value= + */ +VALUE +syck_scalar_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + StringValue( val ); + node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) ); + node->data.str->len = RSTRING_LEN(val); + node->data.str->style = scalar_none; + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Seq.allocate + */ +VALUE +syck_seq_alloc(VALUE class) +{ + SyckNode *node; + VALUE obj; + node = syck_alloc_seq(); + obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Seq.initialize + */ +VALUE +syck_seq_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + rb_iv_set( self, "@kind", sym_seq ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Seq.value= + */ +VALUE +syck_seq_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + val = rb_check_array_type( val ); + if ( !NIL_P( val ) ) { + int i; + syck_seq_empty( node ); + for ( i = 0; i < RARRAY_LEN( val ); i++ ) + { + syck_seq_add( node, rb_ary_entry(val, i) ); + } + } + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Seq.add + */ +VALUE +syck_seq_add_m(VALUE self, VALUE val) +{ + SyckNode *node; + VALUE emitter = rb_ivar_get( self, s_emitter ); + Data_Get_Struct( self, SyckNode, node ); + + if ( rb_respond_to( emitter, s_node_export ) ) { + val = rb_funcall( emitter, s_node_export, 1, val ); + } + syck_seq_add( node, val ); + rb_ary_push( rb_ivar_get( self, s_value ), val ); + + return self; +} + +/* + * YAML::Syck::Seq.style= + */ +VALUE +syck_seq_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( style == sym_inline ) + { + node->data.list->style = seq_inline; + } + else + { + node->data.list->style = seq_none; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * YAML::Syck::Map.allocate + */ +VALUE +syck_map_alloc(VALUE class) +{ + SyckNode *node; + VALUE obj; + node = syck_alloc_map(); + obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Map.initialize + */ +VALUE +syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( !NIL_P( val ) ) + { + VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash"); + VALUE keys; + int i; + if ( NIL_P(hsh) ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + keys = rb_funcall( hsh, s_keys, 0 ); + for ( i = 0; i < RARRAY_LEN(keys); i++ ) + { + VALUE key = rb_ary_entry(keys, i); + syck_map_add( node, key, rb_hash_aref(hsh, key) ); + } + } + + rb_iv_set( self, "@kind", sym_seq ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Map.value= + */ +VALUE +syck_map_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( !NIL_P( val ) ) + { + VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash"); + VALUE keys; + int i; + if ( NIL_P(hsh) ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + syck_map_empty( node ); + keys = rb_funcall( hsh, s_keys, 0 ); + for ( i = 0; i < RARRAY_LEN(keys); i++ ) + { + VALUE key = rb_ary_entry(keys, i); + syck_map_add( node, key, rb_hash_aref(hsh, key) ); + } + } + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Map.add + */ +VALUE +syck_map_add_m(VALUE self, VALUE key, VALUE val) +{ + SyckNode *node; + VALUE emitter = rb_ivar_get( self, s_emitter ); + Data_Get_Struct( self, SyckNode, node ); + + if ( rb_respond_to( emitter, s_node_export ) ) { + key = rb_funcall( emitter, s_node_export, 1, key ); + val = rb_funcall( emitter, s_node_export, 1, val ); + } + syck_map_add( node, key, val ); + rb_hash_aset( rb_ivar_get( self, s_value ), key, val ); + + return self; +} + +/* + * YAML::Syck::Map.style= + */ +VALUE +syck_map_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( style == sym_inline ) + { + node->data.pairs->style = map_inline; + } + else + { + node->data.pairs->style = map_none; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * Cloning method for all node types + */ +VALUE +syck_node_init_copy(VALUE copy, VALUE orig) +{ + SyckNode *copy_n; + SyckNode *orig_n; + + if ( copy == orig ) + return copy; + + if ( TYPE( orig ) != T_DATA ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + Data_Get_Struct( orig, SyckNode, orig_n ); + Data_Get_Struct( copy, SyckNode, copy_n ); + MEMCPY( copy_n, orig_n, SyckNode, 1 ); + return copy; +} + +/* + * YAML::Syck::Node#type_id= + */ +VALUE +syck_node_type_id_set(VALUE self, VALUE type_id) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + S_FREE( node->type_id ); + + if ( !NIL_P( type_id ) ) { + StringValue( type_id ); + node->type_id = syck_strndup( RSTRING_PTR(type_id), RSTRING_LEN(type_id) ); + } + + rb_iv_set( self, "@type_id", type_id ); + return type_id; +} + +/* + * YAML::Syck::Node.transform + */ +VALUE +syck_node_transform(VALUE self) +{ + VALUE t; + SyckNode *n = NULL; + SyckNode *orig_n; + Data_Get_Struct(self, SyckNode, orig_n); + t = Data_Wrap_Struct( cNode, syck_node_mark, syck_free_node, 0 ); + + switch (orig_n->kind) + { + case syck_map_kind: + { + int i; + DATA_PTR(t) = n = syck_alloc_map(); + for ( i = 0; i < orig_n->data.pairs->idx; i++ ) + { + syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ), + rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) ); + } + } + break; + + case syck_seq_kind: + { + int i; + DATA_PTR(t) = n = syck_alloc_seq(); + for ( i = 0; i < orig_n->data.list->idx; i++ ) + { + syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) ); + } + } + break; + + case syck_str_kind: + DATA_PTR(t) = n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style ); + break; + } + + if ( orig_n->type_id != NULL ) + { + n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) ); + } + if ( orig_n->anchor != NULL ) + { + n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) ); + } + n->id = t; + return rb_funcall( oDefaultResolver, s_node_import, 1, t ); +} + +/* + * Emitter callback: assembles YAML document events from + * Ruby symbols. This is a brilliant way to do it. + * No one could possibly object. + */ +void +rb_syck_emitter_handler(SyckEmitter *e, st_data_t data) +{ + SyckNode *n; + Data_Get_Struct((VALUE)data, SyckNode, n); + + switch (n->kind) + { + case syck_map_kind: + { + int i; + syck_emit_map( e, n->type_id, n->data.pairs->style ); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + syck_emit_item( e, syck_map_read( n, map_key, i ) ); + syck_emit_item( e, syck_map_read( n, map_value, i ) ); + } + syck_emit_end( e ); + } + break; + + case syck_seq_kind: + { + int i; + syck_emit_seq( e, n->type_id, n->data.list->style ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + syck_emit_item( e, syck_seq_read( n, i ) ); + } + syck_emit_end( e ); + } + break; + + case syck_str_kind: + { + syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len ); + } + break; + } +} + +/* + * Handle output from the emitter + */ +void +rb_syck_output_handler(SyckEmitter * emitter, char *str, long len) +{ + struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus; + VALUE dest = bonus->port; + if (TYPE(dest) == T_STRING) { + rb_str_cat( dest, str, len ); + } else { + rb_io_write( dest, rb_str_new( str, len ) ); + } +} + +/* + * Helper function for marking nodes in the anchor + * symbol table. + */ +void +syck_out_mark(VALUE emitter, VALUE node) +{ + SyckEmitter *emitterPtr; + struct emitter_xtra *bonus; + Data_Get_Struct(emitter, SyckEmitter, emitterPtr); + bonus = (struct emitter_xtra *)emitterPtr->bonus; + rb_ivar_set( node, s_emitter, emitter ); + /* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */ + if ( !NIL_P( bonus->oid ) ) { + rb_hash_aset( bonus->data, bonus->oid, node ); + } +} + +/* + * Mark emitter values. + */ +static void +syck_mark_emitter(SyckEmitter *emitter) +{ + struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus; + rb_gc_mark( bonus->oid ); + rb_gc_mark( bonus->data ); + rb_gc_mark( bonus->port ); +} + +/* + * Free the emitter and any bonus attachment. + */ +void +rb_syck_free_emitter(SyckEmitter *e) +{ + S_FREE( e->bonus ); + syck_free_emitter(e); +} + +/* + * YAML::Syck::Emitter.allocate + */ +VALUE syck_emitter_s_alloc _((VALUE)); +VALUE +syck_emitter_s_alloc(VALUE class) +{ + VALUE pobj; + SyckEmitter *emitter = syck_new_emitter(); + + emitter->bonus = S_ALLOC( struct emitter_xtra ); + S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 ); + + pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter ); + syck_emitter_handler( emitter, rb_syck_emitter_handler ); + syck_output_handler( emitter, rb_syck_output_handler ); + + rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) ); + return pobj; +} + +/* + * YAML::Syck::Emitter.reset( options ) + */ +VALUE +syck_emitter_reset(int argc, VALUE *argv, VALUE self) +{ + VALUE options, tmp; + SyckEmitter *emitter; + struct emitter_xtra *bonus; + + Data_Get_Struct(self, SyckEmitter, emitter); + bonus = (struct emitter_xtra *)emitter->bonus; + + bonus->oid = Qnil; + bonus->port = rb_str_new2( "" ); + bonus->data = rb_hash_new(); + + if (rb_scan_args(argc, argv, "01", &options) == 0) + { + options = rb_hash_new(); + rb_ivar_set(self, s_options, options); + } + else if ( !NIL_P(tmp = rb_check_string_type(options)) ) + { + bonus->port = tmp; + } + else if ( rb_respond_to( options, s_write ) ) + { + bonus->port = options; + } + else + { + Check_Type(options, T_HASH); + rb_ivar_set(self, s_options, options); + } + + emitter->headless = 0; + rb_ivar_set(self, s_level, INT2FIX(0)); + rb_ivar_set(self, s_resolver, Qnil); + return self; +} + +/* + * YAML::Syck::Emitter.emit( object_id ) { |out| ... } + */ +VALUE +syck_emitter_emit(int argc, VALUE *argv, VALUE self) +{ + VALUE oid, proc; + SyckEmitter *emitter; + struct emitter_xtra *bonus; + SYMID symple; + int level = FIX2INT(rb_ivar_get(self, s_level)) + 1; + rb_ivar_set(self, s_level, INT2FIX(level)); + + rb_scan_args(argc, argv, "1&", &oid, &proc); + Data_Get_Struct(self, SyckEmitter, emitter); + bonus = (struct emitter_xtra *)emitter->bonus; + + /* Calculate anchors, normalize nodes, build a simpler symbol table */ + bonus->oid = oid; + if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) { + symple = rb_hash_aref( bonus->data, oid ); + } else { + symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) ); + } + syck_emitter_mark_node( emitter, (st_data_t)symple ); + + /* Second pass, build emitted string */ + level -= 1; + rb_ivar_set(self, s_level, INT2FIX(level)); + if ( level == 0 ) + { + syck_emit(emitter, (st_data_t)symple); + syck_emitter_flush(emitter, 0); + + return bonus->port; + } + + return symple; +} + +/* + * YAML::Syck::Emitter#node_export + */ +VALUE +syck_emitter_node_export(VALUE self, VALUE node) +{ + return rb_funcall( node, s_to_yaml, 1, self ); +} + +/* + * YAML::Syck::Emitter#set_resolver + */ +VALUE +syck_emitter_set_resolver(VALUE self, VALUE resolver) +{ + rb_ivar_set( self, s_resolver, resolver ); + return self; +} + +/* + * YAML::Syck::Out::initialize + */ +VALUE +syck_out_initialize(VALUE self, VALUE emitter) +{ + rb_ivar_set( self, s_emitter, emitter ); + return self; +} + +/* + * YAML::Syck::Out::map + */ +VALUE +syck_out_map(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, style, map; + if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) { + style = Qnil; + } + map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), map ); + rb_yield( map ); + return map; +} + +/* + * YAML::Syck::Out::seq + */ +VALUE +syck_out_seq(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, style, seq; + if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) { + style = Qnil; + } + seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), seq ); + rb_yield( seq ); + return seq; +} + +/* + * YAML::Syck::Out::scalar +syck_out_scalar( self, type_id, str, style ) + VALUE self, type_id, str, style; + */ +VALUE +syck_out_scalar(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, str, style, scalar; + rb_scan_args(argc, argv, "21", &type_id, &str, &style); + scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), scalar ); + return scalar; +} + +/* + * Initialize Syck extension + */ +void +Init_syck() +{ + VALUE rb_yaml = rb_define_module( "YAML" ); + VALUE rb_syck = rb_define_module_under( rb_yaml, "Syck" ); + rb_define_const( rb_syck, "VERSION", rb_str_new2( SYCK_VERSION ) ); + rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 ); + + /* + * Global symbols + */ + s_new = rb_intern("new"); + s_utc = rb_intern("utc"); + s_at = rb_intern("at"); + s_to_f = rb_intern("to_f"); + s_to_i = rb_intern("to_i"); + s_read = rb_intern("read"); + s_binmode = rb_intern("binmode"); + s_transfer = rb_intern("transfer"); + s_call = rb_intern("call"); + s_cmp = rb_intern("<=>"); + s_intern = rb_intern("intern"); + s_update = rb_intern("update"); + s_detect_implicit = rb_intern("detect_implicit"); + s_dup = rb_intern("dup"); + s_default_set = rb_intern("default="); + s_match = rb_intern("match"); + s_push = rb_intern("push"); + s_haskey = rb_intern("has_key?"); + s_keys = rb_intern("keys"); + s_node_import = rb_intern("node_import"); + s_tr_bang = rb_intern("tr!"); + s_unpack = rb_intern("unpack"); + s_write = rb_intern("write"); + s_tag_read_class = rb_intern( "yaml_tag_read_class" ); + s_tag_subclasses = rb_intern( "yaml_tag_subclasses?" ); + s_emitter = rb_intern( "emitter" ); + s_set_resolver = rb_intern( "set_resolver" ); + s_node_export = rb_intern( "node_export" ); + s_to_yaml = rb_intern( "to_yaml" ); + s_transform = rb_intern( "transform" ); + s_yaml_new = rb_intern("yaml_new"); + s_yaml_initialize = rb_intern("yaml_initialize"); + s_each = rb_intern("each"); + + s_tags = rb_intern("@tags"); + s_name = rb_intern("@name"); + s_options = rb_intern("@options"); + s_kind = rb_intern("@kind"); + s_type_id = rb_intern("@type_id"); + s_type_id_set = rb_intern("type_id="); + s_resolver = rb_intern("@resolver"); + s_level = rb_intern( "@level" ); + s_style = rb_intern("@style"); + s_style_set = rb_intern("style="); + s_value = rb_intern("@value"); + s_value_set = rb_intern("value="); + s_out = rb_intern("@out"); + s_input = rb_intern("@input"); + + sym_model = ID2SYM(rb_intern("Model")); + sym_generic = ID2SYM(rb_intern("Generic")); + sym_bytecode = ID2SYM(rb_intern("bytecode")); + sym_map = ID2SYM(rb_intern("map")); + sym_scalar = ID2SYM(rb_intern("scalar")); + sym_seq = ID2SYM(rb_intern("seq")); + sym_1quote = ID2SYM(rb_intern("quote1")); + sym_2quote = ID2SYM(rb_intern("quote2")); + sym_fold = ID2SYM(rb_intern("fold")); + sym_literal = ID2SYM(rb_intern("literal")); + sym_plain = ID2SYM(rb_intern("plain")); + sym_inline = ID2SYM(rb_intern("inline")); + + /* + * Define YAML::Syck::Resolver class + */ + cResolver = rb_define_class_under( rb_syck, "Resolver", rb_cObject ); + rb_define_attr( cResolver, "tags", 1, 1 ); + rb_define_method( cResolver, "initialize", syck_resolver_initialize, 0 ); + rb_define_method( cResolver, "add_type", syck_resolver_add_type, 2 ); + rb_define_method( cResolver, "use_types_at", syck_resolver_use_types_at, 1 ); + rb_define_method( cResolver, "detect_implicit", syck_resolver_detect_implicit, 1 ); + rb_define_method( cResolver, "transfer", syck_resolver_transfer, 2 ); + rb_define_method( cResolver, "node_import", syck_resolver_node_import, 1 ); + rb_define_method( cResolver, "tagurize", syck_resolver_tagurize, 1 ); + + rb_global_variable( &oDefaultResolver ); + oDefaultResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 ); + rb_define_singleton_method( oDefaultResolver, "node_import", syck_defaultresolver_node_import, 1 ); + rb_define_singleton_method( oDefaultResolver, "detect_implicit", syck_defaultresolver_detect_implicit, 1 ); + rb_define_const( rb_syck, "DefaultResolver", oDefaultResolver ); + rb_global_variable( &oGenericResolver ); + oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 ); + rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 ); + rb_define_const( rb_syck, "GenericResolver", oGenericResolver ); + + /* + * Define YAML::Syck::Parser class + */ + cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject ); + rb_define_attr( cParser, "options", 1, 1 ); + rb_define_attr( cParser, "resolver", 1, 1 ); + rb_define_attr( cParser, "input", 1, 1 ); + rb_define_alloc_func( cParser, syck_parser_s_alloc ); + rb_define_method(cParser, "initialize", syck_parser_initialize, -1 ); + rb_define_method(cParser, "bufsize=", syck_parser_bufsize_set, 1 ); + rb_define_method(cParser, "bufsize", syck_parser_bufsize_get, 0 ); + rb_define_method(cParser, "load", syck_parser_load, -1); + rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1); + rb_define_method(cParser, "set_resolver", syck_parser_set_resolver, 1); + + /* + * Define YAML::Syck::Node class + */ + cNode = rb_define_class_under( rb_syck, "Node", rb_cObject ); + rb_define_method( cNode, "initialize_copy", syck_node_init_copy, 1 ); + rb_define_attr( cNode, "emitter", 1, 1 ); + rb_define_attr( cNode, "resolver", 1, 1 ); + rb_define_attr( cNode, "kind", 1, 0 ); + rb_define_attr( cNode, "type_id", 1, 0 ); + rb_define_attr( cNode, "value", 1, 0 ); + rb_define_method( cNode, "type_id=", syck_node_type_id_set, 1 ); + rb_define_method( cNode, "transform", syck_node_transform, 0); + + /* + * Define YAML::Syck::Scalar, YAML::Syck::Seq, YAML::Syck::Map -- + * all are the publicly usable variants of YAML::Syck::Node + */ + cScalar = rb_define_class_under( rb_syck, "Scalar", cNode ); + rb_define_alloc_func( cScalar, syck_scalar_alloc ); + rb_define_method( cScalar, "initialize", syck_scalar_initialize, 3 ); + rb_define_method( cScalar, "value=", syck_scalar_value_set, 1 ); + rb_define_method( cScalar, "style=", syck_scalar_style_set, 1 ); + cSeq = rb_define_class_under( rb_syck, "Seq", cNode ); + rb_define_alloc_func( cSeq, syck_seq_alloc ); + rb_define_method( cSeq, "initialize", syck_seq_initialize, 3 ); + rb_define_method( cSeq, "value=", syck_seq_value_set, 1 ); + rb_define_method( cSeq, "add", syck_seq_add_m, 1 ); + rb_define_method( cSeq, "style=", syck_seq_style_set, 1 ); + cMap = rb_define_class_under( rb_syck, "Map", cNode ); + rb_define_alloc_func( cMap, syck_map_alloc ); + rb_define_method( cMap, "initialize", syck_map_initialize, 3 ); + rb_define_method( cMap, "value=", syck_map_value_set, 1 ); + rb_define_method( cMap, "add", syck_map_add_m, 2 ); + rb_define_method( cMap, "style=", syck_map_style_set, 1 ); + + /* + * Define YAML::PrivateType class + */ + cPrivateType = rb_define_class_under( rb_yaml, "PrivateType", rb_cObject ); + rb_define_attr( cPrivateType, "type_id", 1, 1 ); + rb_define_attr( cPrivateType, "value", 1, 1 ); + rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2); + + /* + * Define YAML::DomainType class + */ + cDomainType = rb_define_class_under( rb_yaml, "DomainType", rb_cObject ); + rb_define_attr( cDomainType, "domain", 1, 1 ); + rb_define_attr( cDomainType, "type_id", 1, 1 ); + rb_define_attr( cDomainType, "value", 1, 1 ); + rb_define_method( cDomainType, "initialize", syck_domaintype_initialize, 3); + + /* + * Define YAML::Object class + */ + cYObject = rb_define_class_under( rb_yaml, "Object", rb_cObject ); + rb_define_attr( cYObject, "class", 1, 1 ); + rb_define_attr( cYObject, "ivars", 1, 1 ); + rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2); + rb_define_method( cYObject, "yaml_initialize", syck_yobject_initialize, 2); + + /* + * Define YAML::Syck::BadAlias class + */ + cBadAlias = rb_define_class_under( rb_syck, "BadAlias", rb_cObject ); + rb_define_attr( cBadAlias, "name", 1, 1 ); + rb_define_method( cBadAlias, "initialize", syck_badalias_initialize, 1); + rb_define_method( cBadAlias, "<=>", syck_badalias_cmp, 1); + rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern("Comparable") ) ); + + /* + * Define YAML::Syck::MergeKey class + */ + cMergeKey = rb_define_class_under( rb_syck, "MergeKey", rb_cObject ); + + /* + * Define YAML::Syck::DefaultKey class + */ + cDefaultKey = rb_define_class_under( rb_syck, "DefaultKey", rb_cObject ); + + /* + * Define YAML::Syck::Out classes + */ + cOut = rb_define_class_under( rb_syck, "Out", rb_cObject ); + rb_define_attr( cOut, "emitter", 1, 1 ); + rb_define_method( cOut, "initialize", syck_out_initialize, 1 ); + rb_define_method( cOut, "map", syck_out_map, -1 ); + rb_define_method( cOut, "seq", syck_out_seq, -1 ); + rb_define_method( cOut, "scalar", syck_out_scalar, -1 ); + + /* + * Define YAML::Syck::Emitter class + */ + cEmitter = rb_define_class_under( rb_syck, "Emitter", rb_cObject ); + rb_define_attr( cEmitter, "level", 1, 1 ); + rb_define_alloc_func( cEmitter, syck_emitter_s_alloc ); + rb_define_method( cEmitter, "initialize", syck_emitter_reset, -1 ); + rb_define_method( cEmitter, "reset", syck_emitter_reset, -1 ); + rb_define_method( cEmitter, "emit", syck_emitter_emit, -1 ); + rb_define_method( cEmitter, "set_resolver", syck_emitter_set_resolver, 1); + rb_define_method( cEmitter, "node_export", syck_emitter_node_export, 1); +} + diff --git a/trunk/ext/syck/syck.c b/trunk/ext/syck/syck.c new file mode 100644 index 0000000000..92b7566d1a --- /dev/null +++ b/trunk/ext/syck/syck.c @@ -0,0 +1,524 @@ +/* + * syck.c + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" + +#include <stdio.h> +#include <string.h> + +#include "syck.h" + +void syck_parser_pop_level( SyckParser * ); + +/* + * Custom assert + */ +void +syck_assert( const char *file_name, unsigned line_num, const char *expr ) +{ + fflush( NULL ); + fprintf( stderr, "\nAssertion failed: %s, line %u: %s\n", + file_name, line_num, expr ); + fflush( stderr ); + abort(); +} + +/* + * Allocates and copies a string + */ +char * +syck_strndup( const char *buf, long len ) +{ + char *new = S_ALLOC_N( char, len + 1 ); + S_MEMZERO( new, char, len + 1 ); + S_MEMCPY( new, buf, char, len ); + return new; +} + +/* + * Default FILE IO function + */ +long +syck_io_file_read( char *buf, SyckIoFile *file, long max_size, long skip ) +{ + long len = 0; + + ASSERT( file != NULL ); + + max_size -= skip; + len = fread( buf + skip, sizeof( char ), max_size, file->ptr ); + len += skip; + buf[len] = '\0'; + + return len; +} + +/* + * Default string IO function + */ +long +syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip ) +{ + char *beg; + long len = 0; + + ASSERT( str != NULL ); + beg = str->ptr; + if ( max_size >= 0 ) + { + max_size -= skip; + if ( max_size <= 0 ) max_size = 0; + else str->ptr += max_size; + + if ( str->ptr > str->end ) + { + str->ptr = str->end; + } + } + else + { + /* Use exact string length */ + while ( str->ptr < str->end ) { + if (*(str->ptr++) == '\n') break; + } + } + if ( beg < str->ptr ) + { + len = ( str->ptr - beg ); + S_MEMCPY( buf + skip, beg, char, len ); + } + len += skip; + buf[len] = '\0'; + + return len; +} + +void +syck_parser_reset_levels( SyckParser *p ) +{ + while ( p->lvl_idx > 1 ) + { + syck_parser_pop_level( p ); + } + + if ( p->lvl_idx < 1 ) + { + p->lvl_idx = 1; + p->levels[0].spaces = -1; + p->levels[0].ncount = 0; + p->levels[0].domain = syck_strndup( "", 0 ); + } + p->levels[0].status = syck_lvl_header; +} + +void +syck_parser_reset_cursor( SyckParser *p ) +{ + if ( p->buffer == NULL ) + { + p->buffer = S_ALLOC_N( char, p->bufsize ); + S_MEMZERO( p->buffer, char, p->bufsize ); + } + p->buffer[0] = '\0'; + + p->cursor = NULL; + p->lineptr = NULL; + p->linectptr = NULL; + p->token = NULL; + p->toktmp = NULL; + p->marker = NULL; + p->limit = NULL; + + p->root = 0; + p->root_on_error = 0; + p->linect = 0; + p->eof = 0; + p->last_token = 0; + p->force_token = 0; +} + +/* + * Value to return on a parse error + */ +void +syck_parser_set_root_on_error( SyckParser *p, SYMID roer ) +{ + p->root_on_error = roer; +} + +/* + * Allocate the parser + */ +SyckParser * +syck_new_parser(void) +{ + SyckParser *p; + p = S_ALLOC( SyckParser ); + S_MEMZERO( p, SyckParser, 1 ); + p->lvl_capa = ALLOC_CT; + p->levels = S_ALLOC_N( SyckLevel, p->lvl_capa ); + p->input_type = syck_yaml_utf8; + p->io_type = syck_io_str; + p->io.str = NULL; + p->syms = NULL; + p->anchors = NULL; + p->bad_anchors = NULL; + p->implicit_typing = 1; + p->taguri_expansion = 0; + p->bufsize = SYCK_BUFFERSIZE; + p->buffer = NULL; + p->lvl_idx = 0; + syck_parser_reset_levels( p ); + return p; +} + +int +syck_add_sym( SyckParser *p, void *data ) +{ + SYMID id = 0; + if ( p->syms == NULL ) + { + p->syms = st_init_numtable(); + } + id = p->syms->num_entries + 1; + st_insert( p->syms, id, (st_data_t)data ); + return id; +} + +int +syck_lookup_sym( SyckParser *p, SYMID id, void **datap ) +{ + st_data_t data = (st_data_t)*datap; + int ret; + if ( p->syms == NULL ) return 0; + ret = st_lookup( p->syms, id, &data ); + *datap = (void *)data; + return ret; +} + +int +syck_st_free_nodes( char *key, SyckNode *n, char *arg ) +{ + if ( n != (void *)1 ) syck_free_node( n ); + n = NULL; + return ST_CONTINUE; +} + +void +syck_st_free( SyckParser *p ) +{ + /* + * Free the anchor tables + */ + if ( p->anchors != NULL ) + { + st_foreach( p->anchors, syck_st_free_nodes, 0 ); + st_free_table( p->anchors ); + p->anchors = NULL; + } + + if ( p->bad_anchors != NULL ) + { + st_foreach( p->bad_anchors, syck_st_free_nodes, 0 ); + st_free_table( p->bad_anchors ); + p->bad_anchors = NULL; + } +} + +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; + +int +syck_st_free_syms( void *key, bytestring_t *sav, void *dummy ) +{ + S_FREE(sav->buffer); + S_FREE(sav); + return ST_CONTINUE; +} + +void +syck_free_parser( SyckParser *p ) +{ + /* + * Free the adhoc symbol table + */ + if ( p->syms != NULL ) + { + st_foreach( p->syms, syck_st_free_syms, 0 ); + st_free_table( p->syms ); + p->syms = NULL; + } + + /* + * Free tables, levels + */ + syck_st_free( p ); + syck_parser_reset_levels( p ); + S_FREE( p->levels[0].domain ); + S_FREE( p->levels ); + + if ( p->buffer != NULL ) + { + S_FREE( p->buffer ); + } + free_any_io( p ); + S_FREE( p ); +} + +void +syck_parser_handler( SyckParser *p, SyckNodeHandler hdlr ) +{ + ASSERT( p != NULL ); + p->handler = hdlr; +} + +void +syck_parser_implicit_typing( SyckParser *p, int flag ) +{ + p->implicit_typing = ( flag == 0 ? 0 : 1 ); +} + +void +syck_parser_taguri_expansion( SyckParser *p, int flag ) +{ + p->taguri_expansion = ( flag == 0 ? 0 : 1 ); +} + +void +syck_parser_error_handler( SyckParser *p, SyckErrorHandler hdlr ) +{ + ASSERT( p != NULL ); + p->error_handler = hdlr; +} + +void +syck_parser_bad_anchor_handler( SyckParser *p, SyckBadAnchorHandler hdlr ) +{ + ASSERT( p != NULL ); + p->bad_anchor_handler = hdlr; +} + +void +syck_parser_set_input_type( SyckParser *p, enum syck_parser_input input_type ) +{ + ASSERT( p != NULL ); + p->input_type = input_type; +} + +void +syck_parser_file( SyckParser *p, FILE *fp, SyckIoFileRead read ) +{ + ASSERT( p != NULL ); + free_any_io( p ); + syck_parser_reset_cursor( p ); + p->io_type = syck_io_file; + p->io.file = S_ALLOC( SyckIoFile ); + p->io.file->ptr = fp; + if ( read != NULL ) + { + p->io.file->read = read; + } + else + { + p->io.file->read = syck_io_file_read; + } +} + +void +syck_parser_str( SyckParser *p, char *ptr, long len, SyckIoStrRead read ) +{ + ASSERT( p != NULL ); + free_any_io( p ); + syck_parser_reset_cursor( p ); + p->io_type = syck_io_str; + p->io.str = S_ALLOC( SyckIoStr ); + p->io.str->beg = ptr; + p->io.str->ptr = ptr; + p->io.str->end = ptr + len; + if ( read != NULL ) + { + p->io.str->read = read; + } + else + { + p->io.str->read = syck_io_str_read; + } +} + +void +syck_parser_str_auto( SyckParser *p, char *ptr, SyckIoStrRead read ) +{ + syck_parser_str( p, ptr, strlen( ptr ), read ); +} + +SyckLevel * +syck_parser_current_level( SyckParser *p ) +{ + return &p->levels[p->lvl_idx-1]; +} + +void +syck_parser_pop_level( SyckParser *p ) +{ + ASSERT( p != NULL ); + + /* The root level should never be popped */ + if ( p->lvl_idx <= 1 ) return; + + p->lvl_idx -= 1; + free( p->levels[p->lvl_idx].domain ); +} + +void +syck_parser_add_level( SyckParser *p, int len, enum syck_level_status status ) +{ + ASSERT( p != NULL ); + if ( p->lvl_idx + 1 > p->lvl_capa ) + { + p->lvl_capa += ALLOC_CT; + S_REALLOC_N( p->levels, SyckLevel, p->lvl_capa ); + } + + ASSERT( len > p->levels[p->lvl_idx-1].spaces ); + p->levels[p->lvl_idx].spaces = len; + p->levels[p->lvl_idx].ncount = 0; + p->levels[p->lvl_idx].domain = syck_strndup( p->levels[p->lvl_idx-1].domain, strlen( p->levels[p->lvl_idx-1].domain ) ); + p->levels[p->lvl_idx].status = status; + p->lvl_idx += 1; +} + +void +free_any_io( SyckParser *p ) +{ + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + if ( p->io.str != NULL ) + { + S_FREE( p->io.str ); + p->io.str = NULL; + } + break; + + case syck_io_file: + if ( p->io.file != NULL ) + { + S_FREE( p->io.file ); + p->io.file = NULL; + } + break; + } +} + +long +syck_move_tokens( SyckParser *p ) +{ + long count, skip; + ASSERT( p->buffer != NULL ); + + if ( p->token == NULL ) + return 0; + + skip = p->limit - p->token; + if ( ( count = p->token - p->buffer ) ) + { + if (skip > 0) + S_MEMMOVE( p->buffer, p->token, char, skip ); + p->token = p->buffer; + p->marker -= count; + p->cursor -= count; + p->toktmp -= count; + p->limit -= count; + p->lineptr -= count; + p->linectptr -= count; + } + return skip; +} + +void +syck_check_limit( SyckParser *p, long len ) +{ + if ( p->cursor == NULL ) + { + p->cursor = p->buffer; + p->lineptr = p->buffer; + p->linectptr = p->buffer; + p->marker = p->buffer; + } + p->limit = p->buffer + len; +} + +long +syck_parser_read( SyckParser *p ) +{ + long len = 0; + long skip = 0; + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + skip = syck_move_tokens( p ); + len = (p->io.str->read)( p->buffer, p->io.str, SYCK_BUFFERSIZE - 1, skip ); + break; + + case syck_io_file: + skip = syck_move_tokens( p ); + len = (p->io.file->read)( p->buffer, p->io.file, SYCK_BUFFERSIZE - 1, skip ); + break; + } + syck_check_limit( p, len ); + return len; +} + +long +syck_parser_readlen( SyckParser *p, long max_size ) +{ + long len = 0; + long skip = 0; + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + skip = syck_move_tokens( p ); + len = (p->io.str->read)( p->buffer, p->io.str, max_size, skip ); + break; + + case syck_io_file: + skip = syck_move_tokens( p ); + len = (p->io.file->read)( p->buffer, p->io.file, max_size, skip ); + break; + } + syck_check_limit( p, len ); + return len; +} + +SYMID +syck_parse( SyckParser *p ) +{ + ASSERT( p != NULL ); + + syck_st_free( p ); + syck_parser_reset_levels( p ); + syckparse( p ); + return p->root; +} + +void +syck_default_error_handler( SyckParser *p, const char *msg ) +{ + printf( "Error at [Line %d, Col %"PRIdPTRDIFF"]: %s\n", + p->linect, + p->cursor - p->lineptr, + msg ); +} + diff --git a/trunk/ext/syck/syck.h b/trunk/ext/syck/syck.h new file mode 100644 index 0000000000..81b3d67952 --- /dev/null +++ b/trunk/ext/syck/syck.h @@ -0,0 +1,454 @@ +/* + * syck.h + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#ifndef SYCK_H +#define SYCK_H + +#define SYCK_YAML_MAJOR 1 +#define SYCK_YAML_MINOR 0 + +#define SYCK_VERSION "0.60" +#define YAML_DOMAIN "yaml.org,2002" + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "ruby/st.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Memory Allocation + */ +#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +#include <alloca.h> +#endif + +#if DEBUG +void syck_assert( const char *, unsigned, const char * ); +# define ASSERT(f) \ + (( f ) ? (void)0 : syck_assert( __FILE__, __LINE__, #f )) +#else +# define ASSERT(f) ((void)0) +#endif + +#ifndef NULL +# define NULL (void *)0 +#endif + +#define ALLOC_CT 8 +#define SYCK_BUFFERSIZE 4096 +#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n)) +#define S_ALLOC(type) (type*)malloc(sizeof(type)) +#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n)) +#define S_FREE(n) if (n) { free(n); n = NULL; } + +#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n)) + +#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n)) +#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) +#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n)) +#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n)) + +#define BLOCK_FOLD 10 +#define BLOCK_LIT 20 +#define BLOCK_PLAIN 30 +#define NL_CHOMP 40 +#define NL_KEEP 50 + +/* + * Node definitions + */ +#ifndef ST_DATA_T_DEFINED +typedef long st_data_t; +#endif + +#define SYMID unsigned long + +typedef struct _syck_node SyckNode; + +enum syck_kind_tag { + syck_map_kind, + syck_seq_kind, + syck_str_kind +}; + +enum map_part { + map_key, + map_value +}; + +enum map_style { + map_none, + map_inline +}; + +enum seq_style { + seq_none, + seq_inline +}; + +enum scalar_style { + scalar_none, + scalar_1quote, + scalar_2quote, + scalar_fold, + scalar_literal, + scalar_plain +}; + +/* + * Node metadata struct + */ +struct _syck_node { + /* Symbol table ID */ + SYMID id; + /* Underlying kind */ + enum syck_kind_tag kind; + /* Fully qualified tag-uri for type */ + char *type_id; + /* Anchor name */ + char *anchor; + union { + /* Storage for map data */ + struct SyckMap { + enum map_style style; + SYMID *keys; + SYMID *values; + long capa; + long idx; + } *pairs; + /* Storage for sequence data */ + struct SyckSeq { + enum seq_style style; + SYMID *items; + long capa; + long idx; + } *list; + /* Storage for string data */ + struct SyckStr { + enum scalar_style style; + char *ptr; + long len; + } *str; + } data; + /* Shortcut node */ + void *shortcut; +}; + +/* + * Parser definitions + */ +typedef struct _syck_parser SyckParser; +typedef struct _syck_file SyckIoFile; +typedef struct _syck_str SyckIoStr; +typedef struct _syck_level SyckLevel; + +typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *); +typedef void (*SyckErrorHandler)(SyckParser *, const char *); +typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *); +typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); +typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long); + +enum syck_io_type { + syck_io_str, + syck_io_file +}; + +enum syck_parser_input { + syck_yaml_utf8, + syck_yaml_utf16, + syck_yaml_utf32, + syck_bytecode_utf8 +}; + +enum syck_level_status { + syck_lvl_header, + syck_lvl_doc, + syck_lvl_open, + syck_lvl_seq, + syck_lvl_map, + syck_lvl_block, + syck_lvl_str, + syck_lvl_iseq, + syck_lvl_imap, + syck_lvl_end, + syck_lvl_pause, + syck_lvl_anctag, + syck_lvl_mapx, + syck_lvl_seqx +}; + +/* + * Parser structs + */ +struct _syck_file { + /* File pointer */ + FILE *ptr; + /* Function which FILE -> buffer */ + SyckIoFileRead read; +}; + +struct _syck_str { + /* String buffer pointers */ + char *beg, *ptr, *end; + /* Function which string -> buffer */ + SyckIoStrRead read; +}; + +struct _syck_level { + /* Indent */ + int spaces; + /* Counts nodes emitted at this level, useful for parsing + * keys and pairs in bytecode */ + int ncount; + /* Does node have anchors or tags? */ + int anctag; + /* Domain prefixing at the given level */ + char *domain; + /* Keeps a node status */ + enum syck_level_status status; +}; + +struct _syck_parser { + /* Root node */ + SYMID root, root_on_error; + /* Implicit typing flag */ + int implicit_typing, taguri_expansion; + /* Scripting language function to handle nodes */ + SyckNodeHandler handler; + /* Error handler */ + SyckErrorHandler error_handler; + /* InvalidAnchor handler */ + SyckBadAnchorHandler bad_anchor_handler; + /* Parser input type */ + enum syck_parser_input input_type; + /* IO type */ + enum syck_io_type io_type; + /* Custom buffer size */ + size_t bufsize; + /* Buffer pointers */ + char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit; + /* Line counter */ + int linect; + /* Last token from yylex() */ + int last_token; + /* Force a token upon next call to yylex() */ + int force_token; + /* EOF flag */ + int eof; + union { + SyckIoFile *file; + SyckIoStr *str; + } io; + /* Symbol table for anchors */ + st_table *anchors, *bad_anchors; + /* Optional symbol table for SYMIDs */ + st_table *syms; + /* Levels of indentation */ + SyckLevel *levels; + int lvl_idx; + int lvl_capa; + /* Pointer for extension's use */ + void *bonus; +}; + +/* + * Emitter definitions + */ +typedef struct _syck_emitter SyckEmitter; +typedef struct _syck_emitter_node SyckEmitterNode; + +typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); +typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); + +enum doc_stage { + doc_open, + doc_processing +}; + +/* + * Emitter struct + */ +struct _syck_emitter { + /* Headerless doc flag */ + int headless; + /* Force header? */ + int use_header; + /* Force version? */ + int use_version; + /* Sort hash keys */ + int sort_keys; + /* Anchor format */ + char *anchor_format; + /* Explicit typing on all collections? */ + int explicit_typing; + /* Best width on folded scalars */ + int best_width; + /* Use literal[1] or folded[2] blocks on all text? */ + enum scalar_style style; + /* Stage of written document */ + enum doc_stage stage; + /* Level counter */ + int level; + /* Default indentation */ + int indent; + /* Object ignore ID */ + SYMID ignore_id; + /* Symbol table for anchors */ + st_table *markers, *anchors, *anchored; + /* Custom buffer size */ + size_t bufsize; + /* Buffer */ + char *buffer, *marker; + /* Absolute position of the buffer */ + long bufpos; + /* Handler for emitter nodes */ + SyckEmitterHandler emitter_handler; + /* Handler for output */ + SyckOutputHandler output_handler; + /* Levels of indentation */ + SyckLevel *levels; + int lvl_idx; + int lvl_capa; + /* Pointer for extension's use */ + void *bonus; +}; + +/* + * Emitter node metadata struct + */ +struct _syck_emitter_node { + /* Node buffer position */ + long pos; + /* Current indent */ + long indent; + /* Collection? */ + int is_shortcut; +}; + +/* + * Handler prototypes + */ +SYMID syck_hdlr_add_node( SyckParser *, SyckNode * ); +SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * ); +void syck_hdlr_remove_anchor( SyckParser *, char * ); +SyckNode *syck_hdlr_get_anchor( SyckParser *, char * ); +void syck_add_transfer( char *, SyckNode *, int ); +char *syck_xprivate( const char *, int ); +char *syck_taguri( const char *, const char *, int ); +int syck_tagcmp( const char *, const char * ); +int syck_add_sym( SyckParser *, void * ); +int syck_lookup_sym( SyckParser *, SYMID, void ** ); +int syck_try_implicit( SyckNode * ); +char *syck_type_id_to_uri( const char * ); +void try_tag_implicit( SyckNode *, int ); +const char *syck_match_implicit( const char *, size_t ); + +/* + * API prototypes + */ +char *syck_strndup( const char *, long ); +long syck_io_file_read( char *, SyckIoFile *, long, long ); +long syck_io_str_read( char *, SyckIoStr *, long, long ); +char *syck_base64enc( char *, long ); +char *syck_base64dec( char *, long ); +SyckEmitter *syck_new_emitter(void); +SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t ); +void syck_emitter_ignore_id( SyckEmitter *, SYMID ); +void syck_output_handler( SyckEmitter *, SyckOutputHandler ); +void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler ); +void syck_free_emitter( SyckEmitter * ); +void syck_emitter_clear( SyckEmitter * ); +void syck_emitter_write( SyckEmitter *, const char *, long ); +void syck_emitter_escape( SyckEmitter *, const char *, long ); +void syck_emitter_flush( SyckEmitter *, long ); +void syck_emit( SyckEmitter *, st_data_t ); +void syck_emit_scalar( SyckEmitter *, const char *, enum scalar_style, int, int, char, const char *, long ); +void syck_emit_1quoted( SyckEmitter *, int, const char *, long ); +void syck_emit_2quoted( SyckEmitter *, int, const char *, long ); +void syck_emit_folded( SyckEmitter *, int, char, const char *, long ); +void syck_emit_literal( SyckEmitter *, char, const char *, long ); +void syck_emit_seq( SyckEmitter *, const char *, enum seq_style ); +void syck_emit_item( SyckEmitter *, st_data_t ); +void syck_emit_map( SyckEmitter *, const char *, enum map_style ); +void syck_emit_end( SyckEmitter * ); +void syck_emit_tag( SyckEmitter *, const char *, const char * ); +void syck_emit_indent( SyckEmitter * ); +SyckLevel *syck_emitter_current_level( SyckEmitter * ); +SyckLevel *syck_emitter_parent_level( SyckEmitter * ); +void syck_emitter_pop_level( SyckEmitter * ); +void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status ); +void syck_emitter_reset_levels( SyckEmitter * ); +SyckParser *syck_new_parser(void); +void syck_free_parser( SyckParser * ); +void syck_parser_set_root_on_error( SyckParser *, SYMID ); +void syck_parser_implicit_typing( SyckParser *, int ); +void syck_parser_taguri_expansion( SyckParser *, int ); +int syck_scan_scalar( int, const char *, long ); +void syck_parser_handler( SyckParser *, SyckNodeHandler ); +void syck_parser_error_handler( SyckParser *, SyckErrorHandler ); +void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler ); +void syck_parser_set_input_type( SyckParser *, enum syck_parser_input ); +void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead ); +void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead ); +void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead ); +SyckLevel *syck_parser_current_level( SyckParser * ); +void syck_parser_add_level( SyckParser *, int, enum syck_level_status ); +void syck_parser_pop_level( SyckParser * ); +void free_any_io( SyckParser * ); +long syck_parser_read( SyckParser * ); +long syck_parser_readlen( SyckParser *, long ); +SYMID syck_parse( SyckParser * ); +void syck_default_error_handler( SyckParser *, const char * ); +SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * ); +char *syck_yaml2byte( char * ); + +/* + * Allocation prototypes + */ +SyckNode *syck_alloc_map(void); +SyckNode *syck_alloc_seq(void); +SyckNode *syck_alloc_str(void); +void syck_free_node( SyckNode * ); +void syck_free_members( SyckNode * ); +SyckNode *syck_new_str( const char *, enum scalar_style ); +SyckNode *syck_new_str2( const char *, long, enum scalar_style ); +void syck_replace_str( SyckNode *, char *, enum scalar_style ); +void syck_replace_str2( SyckNode *, char *, long, enum scalar_style ); +void syck_str_blow_away_commas( SyckNode * ); +char *syck_str_read( SyckNode * ); +SyckNode *syck_new_map( SYMID, SYMID ); +void syck_map_empty( SyckNode * ); +void syck_map_add( SyckNode *, SYMID, SYMID ); +SYMID syck_map_read( SyckNode *, enum map_part, long ); +void syck_map_assign( SyckNode *, enum map_part, long, SYMID ); +long syck_map_count( SyckNode * ); +void syck_map_update( SyckNode *, SyckNode * ); +SyckNode *syck_new_seq( SYMID ); +void syck_seq_empty( SyckNode * ); +void syck_seq_add( SyckNode *, SYMID ); +void syck_seq_assign( SyckNode *, long, SYMID ); +SYMID syck_seq_read( SyckNode *, long ); +long syck_seq_count( SyckNode * ); + +/* + * Lexer prototypes + */ +void syckerror( const char * ); +int syckparse( void * ); +union YYSTYPE; +int sycklex( union YYSTYPE *, SyckParser * ); + +#if defined(__cplusplus) +} /* extern "C" { */ +#endif + +#endif /* ifndef SYCK_H */ diff --git a/trunk/ext/syck/token.c b/trunk/ext/syck/token.c new file mode 100644 index 0000000000..1b26e66bdb --- /dev/null +++ b/trunk/ext/syck/token.c @@ -0,0 +1,2724 @@ +/* Generated by re2c 0.9.10 on Tue Sep 20 17:46:17 2005 */ +#line 1 "token.re" +/* + * token.re + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" +#include "syck.h" +#include "gram.h" + +/* + * Allocate quoted strings in chunks + */ +#define QUOTELEN 1024 + +/* + * They do my bidding... + */ +#define YYCTYPE char +#define YYCURSOR parser->cursor +#define YYMARKER parser->marker +#define YYLIMIT parser->limit +#define YYTOKEN parser->token +#define YYTOKTMP parser->toktmp +#define YYLINEPTR parser->lineptr +#define YYLINECTPTR parser->linectptr +#define YYLINE parser->linect +#define YYFILL(n) syck_parser_read(parser) + +/* + * Repositions the cursor at `n' offset from the token start. + * Only works in `Header' and `Document' sections. + */ +#define YYPOS(n) YYCURSOR = YYTOKEN + n + +/* + * Track line numbers + */ +#define NEWLINE(ptr) YYLINEPTR = ptr + newline_len(ptr); if ( YYLINEPTR > YYLINECTPTR ) { YYLINE++; YYLINECTPTR = YYLINEPTR; } + +/* + * I like seeing the level operations as macros... + */ +#define ADD_LEVEL(len, status) syck_parser_add_level( parser, len, status ) +#define POP_LEVEL() syck_parser_pop_level( parser ) +#define CURRENT_LEVEL() syck_parser_current_level( parser ) + +/* + * Force a token next time around sycklex() + */ +#define FORCE_NEXT_TOKEN(tok) parser->force_token = tok; + +/* + * Nice little macro to ensure we're YAML_IOPENed to the current level. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IOPEN(last_lvl, to_len, reset) \ + if ( last_lvl->spaces < to_len ) \ + { \ + if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \ + { \ + goto Document; \ + } \ + else \ + { \ + ADD_LEVEL( to_len, syck_lvl_doc ); \ + if ( reset == 1 ) YYPOS(0); \ + return YAML_IOPEN; \ + } \ + } + +/* + * Nice little macro to ensure closure of levels. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IEND(last_lvl, to_len) \ + if ( last_lvl->spaces > to_len ) \ + { \ + syck_parser_pop_level( parser ); \ + YYPOS(0); \ + return YAML_IEND; \ + } + +/* + * Concatenates quoted string items and manages allocation + * to the quoted string + */ +#define QUOTECAT(s, c, i, l) \ + { \ + if ( i + 1 >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + s[i++] = l; \ + s[i] = '\0'; \ + } + +#define QUOTECATS(s, c, i, cs, cl) \ + { \ + while ( i + cl >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + S_MEMCPY( s + i, cs, char, cl ); \ + i += cl; \ + s[i] = '\0'; \ + } + +/* + * Tags a plain scalar with a transfer method + * * Use only in "Plain" section * + */ +#define RETURN_IMPLICIT() \ + { \ + SyckNode *n = syck_alloc_str(); \ + YYCURSOR = YYTOKEN; \ + n->data.str->ptr = qstr; \ + n->data.str->len = qidx; \ + n->data.str->style = scalar_plain; \ + sycklval->nodeData = n; \ + if ( parser->implicit_typing == 1 ) \ + { \ + try_tag_implicit( sycklval->nodeData, parser->taguri_expansion ); \ + } \ + return YAML_PLAIN; \ + } + +/* concat the inline characters to the plain scalar */ +#define PLAIN_NOT_INL() \ + if ( *(YYCURSOR - 1) == ' ' || is_newline( YYCURSOR - 1 ) ) \ + { \ + YYCURSOR--; \ + } \ + QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN); \ + goto Plain2; + +/* trim spaces off the end in case of indent */ +#define PLAIN_IS_INL() \ + char *walker = qstr + qidx - 1; \ + while ( walker > qstr && ( *walker == '\n' || *walker == ' ' || *walker == '\t' ) ) \ + { \ + qidx--; \ + walker[0] = '\0'; \ + walker--; \ + } + +/* + * Keep or chomp block? + * * Use only in "ScalarBlock" section * + */ +#define RETURN_YAML_BLOCK() \ + { \ + SyckNode *n = syck_alloc_str(); \ + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \ + { \ + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); \ + } \ + else \ + { \ + n->type_id = syck_strndup( "str", 3 ); \ + } \ + n->data.str->ptr = qstr; \ + n->data.str->len = qidx; \ + if ( blockType == BLOCK_LIT ) { \ + n->data.str->style = scalar_literal; \ + } else { \ + n->data.str->style = scalar_fold; \ + } \ + if ( qidx > 0 ) \ + { \ + if ( nlDoWhat != NL_KEEP ) \ + { \ + char *fc = n->data.str->ptr + n->data.str->len - 1; \ + while ( is_newline( fc ) ) fc--; \ + if ( nlDoWhat != NL_CHOMP && fc < n->data.str->ptr + n->data.str->len - 1 ) \ + fc += 1; \ + n->data.str->len = fc - n->data.str->ptr + 1; \ + } \ + } \ + sycklval->nodeData = n; \ + return YAML_BLOCK; \ + } + +/* + * Handles newlines, calculates indent + */ +#define GOBBLE_UP_YAML_INDENT( ict, start ) \ + char *indent = start; \ + NEWLINE(indent); \ + while ( indent < YYCURSOR ) \ + { \ + if ( is_newline( ++indent ) ) \ + { \ + NEWLINE(indent); \ + } \ + } \ + ict = 0; \ + if ( *YYCURSOR == '\0' ) \ + { \ + ict = -1; \ + start = YYCURSOR - 1; \ + } \ + else if ( *YYLINEPTR == ' ' ) \ + { \ + ict = YYCURSOR - YYLINEPTR; \ + } + +/* + * If an indent exists at the current level, back up. + */ +#define GET_TRUE_YAML_INDENT(indt_len) \ + { \ + SyckLevel *lvl_deep = CURRENT_LEVEL(); \ + indt_len = lvl_deep->spaces; \ + if ( lvl_deep->status == syck_lvl_seq || ( indt_len == YYCURSOR - YYLINEPTR && lvl_deep->status != syck_lvl_map ) ) \ + { \ + SyckLevel *lvl_over; \ + parser->lvl_idx--; \ + lvl_over = CURRENT_LEVEL(); \ + indt_len = lvl_over->spaces; \ + parser->lvl_idx++; \ + } \ + } + +/* + * Argjh! I hate globals! Here for syckerror() only! + */ +SyckParser *syck_parser_ptr = NULL; + +/* + * Accessory funcs later in this file. + */ +void eat_comments( SyckParser * ); +char escape_seq( char ); +int is_newline( char *ptr ); +int newline_len( char *ptr ); +int sycklex_yaml_utf8( YYSTYPE *, SyckParser * ); +int sycklex_bytecode_utf8( YYSTYPE *, SyckParser * ); +int syckwrap(); + +/* + * My own re-entrant sycklex() using re2c. + * You really get used to the limited regexp. + * It's really nice to not rely on backtracking and such. + */ +int +sycklex( YYSTYPE *sycklval, SyckParser *parser ) +{ + switch ( parser->input_type ) + { + case syck_yaml_utf8: + return sycklex_yaml_utf8( sycklval, parser ); + + case syck_yaml_utf16: + syckerror( "UTF-16 is not currently supported in Syck.\nPlease contribute code to help this happen!" ); + break; + + case syck_yaml_utf32: + syckerror( "UTF-32 is not currently supported in Syck.\nPlease contribute code to help this happen!" ); + break; + + case syck_bytecode_utf8: + return sycklex_bytecode_utf8( sycklval, parser ); + } + return YAML_DOCSEP; +} + +/* + * Parser for standard YAML [UTF-8] + */ +int +sycklex_yaml_utf8( YYSTYPE *sycklval, SyckParser *parser ) +{ + int doc_level = 0; + syck_parser_ptr = parser; + if ( YYCURSOR == NULL ) + { + syck_parser_read( parser ); + } + + if ( parser->force_token != 0 ) + { + int t = parser->force_token; + parser->force_token = 0; + return t; + } + +#line 315 "token.re" + + + if ( YYLINEPTR != YYCURSOR ) + { + goto Document; + } + +Header: + + YYTOKEN = YYCURSOR; + + +#line 307 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy7; + case 0x09: case ' ': goto yy12; + case 0x0A: goto yy9; + case 0x0D: goto yy11; + case '#': goto yy5; + case '-': goto yy2; + case '.': goto yy4; + default: goto yy14; + } +yy2: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '-': goto yy28; + default: goto yy3; + } +yy3: +#line 374 "token.re" +{ YYPOS(0); + goto Document; + } +#line 337 "<stdout>" +yy4: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy21; + default: goto yy3; + } +yy5: ++YYCURSOR; + goto yy6; +yy6: +#line 356 "token.re" +{ eat_comments( parser ); + goto Header; + } +#line 351 "<stdout>" +yy7: ++YYCURSOR; + goto yy8; +yy8: +#line 360 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 361 "<stdout>" +yy9: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy18; +yy10: +#line 366 "token.re" +{ GOBBLE_UP_YAML_INDENT( doc_level, YYTOKEN ); + goto Header; + } +#line 370 "<stdout>" +yy11: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy17; + default: goto yy3; + } +yy12: ++YYCURSOR; + yych = *YYCURSOR; + goto yy16; +yy13: +#line 370 "token.re" +{ doc_level = YYCURSOR - YYLINEPTR; + goto Header; + } +#line 384 "<stdout>" +yy14: yych = *++YYCURSOR; + goto yy3; +yy15: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy16; +yy16: switch(yych){ + case 0x09: case ' ': goto yy15; + default: goto yy13; + } +yy17: yyaccept = 1; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy18; +yy18: switch(yych){ + case 0x0A: case ' ': goto yy17; + case 0x0D: goto yy19; + default: goto yy10; + } +yy19: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy17; + default: goto yy20; + } +yy20: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 1: goto yy10; + case 0: goto yy3; + } +yy21: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy22; + default: goto yy20; + } +yy22: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy23; + case 0x0D: goto yy27; + case ' ': goto yy25; + default: goto yy20; + } +yy23: ++YYCURSOR; + goto yy24; +yy24: +#line 342 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + goto Header; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + return 0; + } +#line 446 "<stdout>" +yy25: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy26; +yy26: switch(yych){ + case ' ': goto yy25; + default: goto yy24; + } +yy27: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy23; + default: goto yy20; + } +yy28: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy29; + default: goto yy20; + } +yy29: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy30; + case 0x0D: goto yy34; + case ' ': goto yy32; + default: goto yy20; + } +yy30: ++YYCURSOR; + goto yy31; +yy31: +#line 328 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + YYPOS(3); + goto Directive; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + } +#line 489 "<stdout>" +yy32: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy33; +yy33: switch(yych){ + case ' ': goto yy32; + default: goto yy31; + } +yy34: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy30; + default: goto yy20; + } +} +#line 378 "token.re" + + +Document: + { + SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + lvl->status = syck_lvl_doc; + } + + YYTOKEN = YYCURSOR; + + +#line 518 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy35; + ++YYCURSOR; +yy35: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy62; + case 0x09: case ' ': goto yy60; + case 0x0A: goto yy37; + case 0x0D: goto yy39; + case '!': goto yy51; + case '"': goto yy55; + case '#': goto yy58; + case '&': goto yy49; + case '\'': goto yy53; + case '*': goto yy50; + case ',': case ':': goto yy47; + case '-': case '?': goto yy48; + case '>': case '|': goto yy57; + case '[': goto yy41; + case ']': case '}': goto yy45; + case '{': goto yy43; + default: goto yy64; + } +yy37: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy92; +yy38: +#line 392 "token.re" +{ /* Isolate spaces */ + int indt_len; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + doc_level = 0; + + /* XXX: Comment lookahead */ + if ( *YYCURSOR == '#' ) + { + goto Document; + } + + /* Ignore indentation inside inlines */ + if ( lvl->status == syck_lvl_iseq || lvl->status == syck_lvl_imap ) + { + goto Document; + } + + /* Check for open indent */ + ENSURE_YAML_IEND(lvl, indt_len); + ENSURE_YAML_IOPEN(lvl, indt_len, 0); + if ( indt_len == -1 ) + { + return 0; + } + return YAML_INDENT; + } +#line 578 "<stdout>" +yy39: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy91; + default: goto yy40; + } +yy40: +#line 497 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto Plain; + } +#line 589 "<stdout>" +yy41: ++YYCURSOR; + goto yy42; +yy42: +#line 420 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + lvl = CURRENT_LEVEL(); + ADD_LEVEL(lvl->spaces + 1, syck_lvl_iseq); + return YYTOKEN[0]; + } +#line 599 "<stdout>" +yy43: ++YYCURSOR; + goto yy44; +yy44: +#line 426 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + lvl = CURRENT_LEVEL(); + ADD_LEVEL(lvl->spaces + 1, syck_lvl_imap); + return YYTOKEN[0]; + } +#line 609 "<stdout>" +yy45: ++YYCURSOR; + goto yy46; +yy46: +#line 432 "token.re" +{ POP_LEVEL(); + return YYTOKEN[0]; + } +#line 617 "<stdout>" +yy47: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy86; + case 0x0D: goto yy90; + case ' ': goto yy88; + default: goto yy40; + } +yy48: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy81; + case 0x0D: goto yy85; + case ' ': goto yy83; + default: goto yy40; + } +yy49: yych = *++YYCURSOR; + switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy78; + default: goto yy40; + } +yy50: yych = *++YYCURSOR; + switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy75; + default: goto yy40; + } +yy51: ++YYCURSOR; + goto yy52; +yy52: +#line 471 "token.re" +{ goto TransferMethod; } +#line 767 "<stdout>" +yy53: ++YYCURSOR; + goto yy54; +yy54: +#line 473 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto SingleQuote; } +#line 774 "<stdout>" +yy55: ++YYCURSOR; + goto yy56; +yy56: +#line 476 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto DoubleQuote; } +#line 781 "<stdout>" +yy57: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy70; + case 0x0D: goto yy74; + case ' ': goto yy72; + case '+': case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy40; + } +yy58: ++YYCURSOR; + goto yy59; +yy59: +#line 486 "token.re" +{ eat_comments( parser ); + goto Document; + } +#line 807 "<stdout>" +yy60: ++YYCURSOR; + yych = *YYCURSOR; + goto yy66; +yy61: +#line 490 "token.re" +{ goto Document; } +#line 814 "<stdout>" +yy62: ++YYCURSOR; + goto yy63; +yy63: +#line 492 "token.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 823 "<stdout>" +yy64: yych = *++YYCURSOR; + goto yy40; +yy65: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy66; +yy66: switch(yych){ + case 0x09: case ' ': goto yy65; + default: goto yy61; + } +yy67: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy68; +yy68: switch(yych){ + case 0x0A: goto yy70; + case 0x0D: goto yy74; + case ' ': goto yy72; + case '+': case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy69; + } +yy69: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy38; + case 1: goto yy40; + } +yy70: ++YYCURSOR; + goto yy71; +yy71: +#line 479 "token.re" +{ if ( is_newline( YYCURSOR - 1 ) ) + { + YYCURSOR--; + } + goto ScalarBlock; + } +#line 869 "<stdout>" +yy72: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy73; +yy73: switch(yych){ + case ' ': goto yy72; + default: goto yy71; + } +yy74: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy70; + default: goto yy69; + } +yy75: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy76; +yy76: switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy75; + default: goto yy77; + } +yy77: +#line 466 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 ); + return YAML_ALIAS; + } +#line 956 "<stdout>" +yy78: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy79; +yy79: switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy78; + default: goto yy80; + } +yy80: +#line 455 "token.re" +{ sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 ); + + /* + * Remove previous anchors of the same name. Since the parser will likely + * construct deeper nodes first, we want those nodes to be placed in the + * queue for matching at a higher level of indentation. + */ + syck_hdlr_remove_anchor(parser, sycklval->name); + return YAML_ANCHOR; + } +#line 1036 "<stdout>" +yy81: ++YYCURSOR; + goto yy82; +yy82: +#line 441 "token.re" +{ ENSURE_YAML_IOPEN(lvl, YYTOKEN - YYLINEPTR, 1); + FORCE_NEXT_TOKEN(YAML_IOPEN); + if ( *YYCURSOR == '#' || is_newline( YYCURSOR ) || is_newline( YYCURSOR - 1 ) ) + { + YYCURSOR--; + ADD_LEVEL((YYTOKEN + 1) - YYLINEPTR, syck_lvl_seq); + } + else /* spaces followed by content uses the space as indentation */ + { + ADD_LEVEL(YYCURSOR - YYLINEPTR, syck_lvl_seq); + } + return YYTOKEN[0]; + } +#line 1054 "<stdout>" +yy83: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy84; +yy84: switch(yych){ + case ' ': goto yy83; + default: goto yy82; + } +yy85: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy81; + default: goto yy69; + } +yy86: ++YYCURSOR; + goto yy87; +yy87: +#line 436 "token.re" +{ if ( *YYTOKEN == ':' && lvl->status != syck_lvl_imap ) lvl->status = syck_lvl_map; + YYPOS(1); + return YYTOKEN[0]; + } +#line 1076 "<stdout>" +yy88: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy89; +yy89: switch(yych){ + case ' ': goto yy88; + default: goto yy87; + } +yy90: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy86; + default: goto yy69; + } +yy91: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy92; +yy92: switch(yych){ + case 0x0A: case ' ': goto yy91; + case 0x0D: goto yy93; + default: goto yy38; + } +yy93: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy91; + default: goto yy69; + } +} +#line 501 "token.re" + + } + +Directive: + { + YYTOKTMP = YYCURSOR; + + +#line 1117 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy94; + ++YYCURSOR; +yy94: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy96; + case 0x09: case ' ': goto yy99; + case '%': goto yy97; + default: goto yy101; + } +yy96: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy98; + } +yy97: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy104; + default: goto yy98; + } +yy98: +#line 514 "token.re" +{ YYCURSOR = YYTOKTMP; + return YAML_DOCSEP; + } +#line 1221 "<stdout>" +yy99: ++YYCURSOR; + yych = *YYCURSOR; + goto yy103; +yy100: +#line 512 "token.re" +{ goto Directive; } +#line 1228 "<stdout>" +yy101: yych = *++YYCURSOR; + goto yy98; +yy102: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy103; +yy103: switch(yych){ + case 0x09: case ' ': goto yy102; + default: goto yy100; + } +yy104: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy105; +yy105: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy104; + case ':': goto yy106; + default: goto yy96; + } +yy106: yych = *++YYCURSOR; + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy107; + default: goto yy96; + } +yy107: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy108; +yy108: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy107; + default: goto yy109; + } +yy109: +#line 510 "token.re" +{ goto Directive; } +#line 1484 "<stdout>" +} +#line 517 "token.re" + + + } + +Plain: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + SyckLevel *plvl; + int parentIndent; + + YYCURSOR = YYTOKEN; + plvl = CURRENT_LEVEL(); + GET_TRUE_YAML_INDENT(parentIndent); + +Plain2: + YYTOKEN = YYCURSOR; + +Plain3: + + +#line 1509 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy110; + ++YYCURSOR; +yy110: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy124; + case 0x09: goto yy126; + case 0x0A: goto yy112; + case 0x0D: goto yy114; + case ' ': goto yy122; + case ',': goto yy117; + case ':': goto yy116; + case ']': goto yy120; + case '}': goto yy118; + default: goto yy127; + } +yy112: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy142; +yy113: +#line 540 "token.re" +{ int indt_len, nl_count = 0; + SyckLevel *lvl; + char *tok = YYTOKEN; + GOBBLE_UP_YAML_INDENT( indt_len, tok ); + lvl = CURRENT_LEVEL(); + + if ( indt_len <= parentIndent ) + { + RETURN_IMPLICIT(); + } + + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + goto Plain2; + } +#line 1570 "<stdout>" +yy114: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy141; + default: goto yy115; + } +yy115: +#line 627 "token.re" +{ QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN); + goto Plain2; + } +#line 1581 "<stdout>" +yy116: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy136; + case 0x0D: goto yy140; + case ' ': goto yy138; + default: goto yy115; + } +yy117: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy130; + case 0x0D: goto yy134; + case ' ': goto yy132; + default: goto yy115; + } +yy118: ++YYCURSOR; + goto yy119; +yy119: +#line 589 "token.re" +{ if ( plvl->status != syck_lvl_imap ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1612 "<stdout>" +yy120: ++YYCURSOR; + goto yy121; +yy121: +#line 600 "token.re" +{ if ( plvl->status != syck_lvl_iseq ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1627 "<stdout>" +yy122: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case '#': goto yy128; + default: goto yy123; + } +yy123: +#line 617 "token.re" +{ if ( qidx == 0 ) + { + goto Plain2; + } + else + { + goto Plain3; + } + } +#line 1644 "<stdout>" +yy124: ++YYCURSOR; + goto yy125; +yy125: +#line 615 "token.re" +{ RETURN_IMPLICIT(); } +#line 1650 "<stdout>" +yy126: yych = *++YYCURSOR; + goto yy123; +yy127: yych = *++YYCURSOR; + goto yy115; +yy128: ++YYCURSOR; + goto yy129; +yy129: +#line 611 "token.re" +{ eat_comments( parser ); + RETURN_IMPLICIT(); + } +#line 1662 "<stdout>" +yy130: ++YYCURSOR; + goto yy131; +yy131: +#line 578 "token.re" +{ if ( plvl->status != syck_lvl_iseq && plvl->status != syck_lvl_imap ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1677 "<stdout>" +yy132: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy133; +yy133: switch(yych){ + case ' ': goto yy132; + default: goto yy131; + } +yy134: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy130; + default: goto yy135; + } +yy135: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy113; + case 1: goto yy115; + } +yy136: ++YYCURSOR; + goto yy137; +yy137: +#line 576 "token.re" +{ RETURN_IMPLICIT(); } +#line 1701 "<stdout>" +yy138: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy139; +yy139: switch(yych){ + case ' ': goto yy138; + default: goto yy137; + } +yy140: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy136; + default: goto yy135; + } +yy141: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy142; +yy142: switch(yych){ + case 0x0A: case ' ': goto yy141; + case 0x0D: goto yy143; + default: goto yy113; + } +yy143: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy141; + default: goto yy135; + } +} +#line 631 "token.re" + + } + +SingleQuote: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +SingleQuote2: + YYTOKEN = YYCURSOR; + + +#line 1747 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy144; + ++YYCURSOR; +yy144: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy152; + case 0x0A: goto yy146; + case 0x0D: goto yy148; + case '\'': goto yy150; + default: goto yy153; + } +yy146: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy157; +yy147: +#line 645 "token.re" +{ int indt_len; + int nl_count = 0; + SyckLevel *lvl; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_str ) + { + ADD_LEVEL( indt_len, syck_lvl_str ); + } + else if ( indt_len < lvl->spaces ) + { + /* Error! */ + } + + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + goto SingleQuote2; + } +#line 1807 "<stdout>" +yy148: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy156; + default: goto yy149; + } +yy149: +#line 712 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto SingleQuote2; + } +#line 1818 "<stdout>" +yy150: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case '\'': goto yy154; + default: goto yy151; + } +yy151: +#line 689 "token.re" +{ SyckLevel *lvl; + SyckNode *n = syck_alloc_str(); + lvl = CURRENT_LEVEL(); + + if ( lvl->status == syck_lvl_str ) + { + POP_LEVEL(); + } + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + n->data.str->ptr = qstr; + n->data.str->len = qidx; + n->data.str->style = scalar_1quote; + sycklval->nodeData = n; + return YAML_PLAIN; + } +#line 1848 "<stdout>" +yy152: yych = *++YYCURSOR; + goto yy151; +yy153: yych = *++YYCURSOR; + goto yy149; +yy154: ++YYCURSOR; + goto yy155; +yy155: +#line 685 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, '\''); + goto SingleQuote2; + } +#line 1860 "<stdout>" +yy156: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy157; +yy157: switch(yych){ + case 0x0A: case ' ': goto yy156; + case 0x0D: goto yy158; + default: goto yy147; + } +yy158: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy156; + default: goto yy159; + } +yy159: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy147; + } +} +#line 716 "token.re" + + + } + + +DoubleQuote: + { + int keep_nl = 1; + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +DoubleQuote2: + YYTOKEN = YYCURSOR; + + + +#line 1901 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy160; + ++YYCURSOR; +yy160: + if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy167; + case 0x0A: goto yy162; + case 0x0D: goto yy164; + case '"': goto yy169; + case '\\': goto yy166; + default: goto yy170; + } +yy162: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy184; +yy163: +#line 734 "token.re" +{ int indt_len; + int nl_count = 0; + SyckLevel *lvl; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_str ) + { + ADD_LEVEL( indt_len, syck_lvl_str ); + } + else if ( indt_len < lvl->spaces ) + { + /* FIXME */ + } + + if ( keep_nl == 1 ) + { + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + } + + keep_nl = 1; + goto DoubleQuote2; + } +#line 1966 "<stdout>" +yy164: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy183; + default: goto yy165; + } +yy165: +#line 820 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto DoubleQuote2; + } +#line 1977 "<stdout>" +yy166: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy174; + case 0x0D: goto yy176; + case ' ': goto yy171; + case '"': case '0': case '\\': case 'a': + case 'b': case 'e': + case 'f': case 'n': case 'r': case 't': case 'v': goto yy178; + case 'x': goto yy177; + default: goto yy165; + } +yy167: ++YYCURSOR; + goto yy168; +yy168: +#line 797 "token.re" +{ SyckLevel *lvl; + SyckNode *n = syck_alloc_str(); + lvl = CURRENT_LEVEL(); + + if ( lvl->status == syck_lvl_str ) + { + POP_LEVEL(); + } + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + n->data.str->ptr = qstr; + n->data.str->len = qidx; + n->data.str->style = scalar_2quote; + sycklval->nodeData = n; + return YAML_PLAIN; + } +#line 2016 "<stdout>" +yy169: yych = *++YYCURSOR; + goto yy168; +yy170: yych = *++YYCURSOR; + goto yy165; +yy171: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy172; +yy172: switch(yych){ + case 0x0A: goto yy174; + case 0x0D: goto yy176; + case ' ': goto yy171; + default: goto yy173; + } +yy173: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy163; + case 1: goto yy165; + } +yy174: ++YYCURSOR; + goto yy175; +yy175: +#line 792 "token.re" +{ keep_nl = 0; + YYCURSOR--; + goto DoubleQuote2; + } +#line 2044 "<stdout>" +yy176: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy174; + default: goto yy173; + } +yy177: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy180; + default: goto yy173; + } +yy178: ++YYCURSOR; + goto yy179; +yy179: +#line 778 "token.re" +{ char ch = *( YYCURSOR - 1 ); + QUOTECAT(qstr, qcapa, qidx, escape_seq( ch )); + goto DoubleQuote2; + } +#line 2082 "<stdout>" +yy180: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy181; + default: goto yy173; + } +yy181: ++YYCURSOR; + goto yy182; +yy182: +#line 783 "token.re" +{ long ch; + char *chr_text = syck_strndup( YYTOKEN, 4 ); + chr_text[0] = '0'; + ch = strtol( chr_text, NULL, 16 ); + free( chr_text ); + QUOTECAT(qstr, qcapa, qidx, ch); + goto DoubleQuote2; + } +#line 2119 "<stdout>" +yy183: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy184; +yy184: switch(yych){ + case 0x0A: case ' ': goto yy183; + case 0x0D: goto yy185; + default: goto yy163; + } +yy185: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy183; + default: goto yy173; + } +} +#line 824 "token.re" + + } + +TransferMethod: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +TransferMethod2: + YYTOKTMP = YYCURSOR; + + +#line 2152 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy186; + ++YYCURSOR; +yy186: + if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy188; + case 0x0A: goto yy190; + case 0x0D: goto yy192; + case ' ': goto yy191; + case '\\': goto yy194; + default: goto yy195; + } +yy188: ++YYCURSOR; + goto yy189; +yy189: +#line 838 "token.re" +{ SyckLevel *lvl; + YYCURSOR = YYTOKTMP; + if ( YYCURSOR == YYTOKEN + 1 ) + { + free( qstr ); + return YAML_ITRANSFER; + } + + lvl = CURRENT_LEVEL(); + + /* + * URL Prefixing + */ + if ( *qstr == '^' ) + { + sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, qstr + 1, qidx - 1 ); + free( qstr ); + } + else + { + char *carat = qstr; + char *qend = qstr + qidx; + while ( (++carat) < qend ) + { + if ( *carat == '^' ) + break; + } + + if ( carat < qend ) + { + free( lvl->domain ); + lvl->domain = syck_strndup( qstr, carat - qstr ); + sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 ); + free( qstr ); + } + else + { + sycklval->name = qstr; + } + } + + return YAML_TRANSFER; + } +#line 2222 "<stdout>" +yy190: yych = *++YYCURSOR; + goto yy189; +yy191: yych = *++YYCURSOR; + goto yy204; +yy192: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy188; + default: goto yy193; + } +yy193: +#line 905 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto TransferMethod2; + } +#line 2237 "<stdout>" +yy194: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '"': case '0': case '\\': case 'a': + case 'b': case 'e': + case 'f': case 'n': case 'r': case 't': case 'v': goto yy198; + case 'x': goto yy196; + default: goto yy193; + } +yy195: yych = *++YYCURSOR; + goto yy193; +yy196: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy200; + default: goto yy197; + } +yy197: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy193; + } +yy198: ++YYCURSOR; + goto yy199; +yy199: +#line 891 "token.re" +{ char ch = *( YYCURSOR - 1 ); + QUOTECAT(qstr, qcapa, qidx, escape_seq( ch )); + goto TransferMethod2; + } +#line 2285 "<stdout>" +yy200: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy201; + default: goto yy197; + } +yy201: ++YYCURSOR; + goto yy202; +yy202: +#line 896 "token.re" +{ long ch; + char *chr_text = syck_strndup( YYTOKTMP, 4 ); + chr_text[0] = '0'; + ch = strtol( chr_text, NULL, 16 ); + free( chr_text ); + QUOTECAT(qstr, qcapa, qidx, ch); + goto TransferMethod2; + } +#line 2322 "<stdout>" +yy203: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy204; +yy204: switch(yych){ + case ' ': goto yy203; + default: goto yy189; + } +} +#line 910 "token.re" + + } + +ScalarBlock: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + int blockType = 0; + int nlDoWhat = 0; + int lastIndent = 0; + int forceIndent = -1; + char *yyt = YYTOKEN; + SyckLevel *lvl = CURRENT_LEVEL(); + int parentIndent = -1; + + switch ( *yyt ) + { + case '|': blockType = BLOCK_LIT; break; + case '>': blockType = BLOCK_FOLD; break; + } + + while ( ++yyt <= YYCURSOR ) + { + if ( *yyt == '-' ) + { + nlDoWhat = NL_CHOMP; + } + else if ( *yyt == '+' ) + { + nlDoWhat = NL_KEEP; + } + else if ( isdigit( *yyt ) ) + { + forceIndent = strtol( yyt, NULL, 10 ); + } + } + + qstr[0] = '\0'; + YYTOKEN = YYCURSOR; + +ScalarBlock2: + YYTOKEN = YYCURSOR; + + +#line 2378 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy205; + ++YYCURSOR; +yy205: + if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy213; + case 0x0A: goto yy207; + case 0x0D: goto yy209; + case '#': goto yy211; + case '-': goto yy215; + default: goto yy216; + } +yy207: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy226; +yy208: +#line 956 "token.re" +{ char *pacer; + char *tok = YYTOKEN; + int indt_len = 0, nl_count = 0, fold_nl = 0, nl_begin = 0; + GOBBLE_UP_YAML_INDENT( indt_len, tok ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_block ) + { + GET_TRUE_YAML_INDENT(parentIndent); + if ( forceIndent > 0 ) forceIndent += parentIndent; + if ( indt_len > parentIndent ) + { + int new_spaces = forceIndent > 0 ? forceIndent : indt_len; + ADD_LEVEL( new_spaces, syck_lvl_block ); + lastIndent = indt_len - new_spaces; + nl_begin = 1; + lvl = CURRENT_LEVEL(); + } + else + { + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + } + + /* + * Fold only in the event of two lines being on the leftmost + * indentation. + */ + if ( blockType == BLOCK_FOLD && lastIndent == 0 && ( indt_len - lvl->spaces ) == 0 ) + { + fold_nl = 1; + } + + pacer = YYTOKEN; + while ( pacer < YYCURSOR ) + { + int nl_len = newline_len( pacer++ ); + if ( nl_len ) + { + nl_count++; + pacer += nl_len - 1; + } + } + + if ( fold_nl == 1 || nl_begin == 1 ) + { + nl_count--; + } + + if ( nl_count < 1 && nl_begin == 0 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + lastIndent = indt_len - lvl->spaces; + YYCURSOR -= lastIndent; + + if ( indt_len < lvl->spaces ) + { + POP_LEVEL(); + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + goto ScalarBlock2; + } +#line 2474 "<stdout>" +yy209: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy225; + default: goto yy210; + } +yy210: +#line 1070 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + goto ScalarBlock2; + } +#line 2485 "<stdout>" +yy211: ++YYCURSOR; + goto yy212; +yy212: +#line 1032 "token.re" +{ lvl = CURRENT_LEVEL(); + if ( lvl->status != syck_lvl_block ) + { + eat_comments( parser ); + YYTOKEN = YYCURSOR; + } + else + { + QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + } + goto ScalarBlock2; + } +#line 2502 "<stdout>" +yy213: ++YYCURSOR; + goto yy214; +yy214: +#line 1046 "token.re" +{ YYCURSOR--; + POP_LEVEL(); + RETURN_YAML_BLOCK(); + } +#line 2511 "<stdout>" +yy215: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '-': goto yy217; + default: goto yy210; + } +yy216: yych = *++YYCURSOR; + goto yy210; +yy217: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy219; + default: goto yy218; + } +yy218: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy208; + case 1: goto yy210; + } +yy219: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy220; + case 0x0D: goto yy224; + case ' ': goto yy222; + default: goto yy218; + } +yy220: ++YYCURSOR; + goto yy221; +yy221: +#line 1051 "token.re" +{ if ( YYTOKEN == YYLINEPTR ) + { + if ( blockType == BLOCK_FOLD && qidx > 0 ) + { + qidx -= 1; + } + QUOTECAT(qstr, qcapa, qidx, '\n'); + POP_LEVEL(); + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + else + { + QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + YYCURSOR = YYTOKEN + 1; + goto ScalarBlock2; + } + } +#line 2559 "<stdout>" +yy222: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy223; +yy223: switch(yych){ + case ' ': goto yy222; + default: goto yy221; + } +yy224: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy220; + default: goto yy218; + } +yy225: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy226; +yy226: switch(yych){ + case 0x0A: case ' ': goto yy225; + case 0x0D: goto yy227; + default: goto yy208; + } +yy227: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy225; + default: goto yy218; + } +} +#line 1075 "token.re" + + } + + return 0; + +} + +void +eat_comments( SyckParser *parser ) +{ +Comment: + { + YYTOKEN = YYCURSOR; + + +#line 2607 "<stdout>" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy228; + ++YYCURSOR; +yy228: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy230; + case 0x0A: goto yy232; + case 0x0D: goto yy233; + default: goto yy235; + } +yy230: ++YYCURSOR; + goto yy231; +yy231: +#line 1091 "token.re" +{ YYCURSOR = YYTOKEN; + return; + } +#line 2629 "<stdout>" +yy232: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy237; +yy233: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy236; + default: goto yy234; + } +yy234: +#line 1095 "token.re" +{ goto Comment; + } +#line 2642 "<stdout>" +yy235: yych = *++YYCURSOR; + goto yy234; +yy236: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy237; +yy237: switch(yych){ + case 0x0A: goto yy236; + case 0x0D: goto yy238; + default: goto yy231; + } +yy238: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy236; + default: goto yy239; + } +yy239: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy231; + } +} +#line 1098 "token.re" + + + } + +} + +char +escape_seq( char ch ) +{ + switch ( ch ) + { + case '0': return '\0'; + case 'a': return 7; + case 'b': return '\010'; + case 'e': return '\033'; + case 'f': return '\014'; + case 'n': return '\n'; + case 'r': return '\015'; + case 't': return '\t'; + case 'v': return '\013'; + default: return ch; + } +} + +int +is_newline( char *ptr ) +{ + return newline_len( ptr ); +} + +int +newline_len( char *ptr ) +{ + if ( *ptr == '\n' ) + return 1; + + if ( *ptr == '\r' && *( ptr + 1 ) == '\n' ) + return 2; + + return 0; +} + +int +syckwrap() +{ + return 1; +} + +void +syckerror( const char *msg ) +{ + if ( syck_parser_ptr->error_handler == NULL ) + syck_parser_ptr->error_handler = syck_default_error_handler; + + syck_parser_ptr->root = syck_parser_ptr->root_on_error; + (syck_parser_ptr->error_handler)(syck_parser_ptr, msg); +} + diff --git a/trunk/ext/syck/yaml2byte.c b/trunk/ext/syck/yaml2byte.c new file mode 100644 index 0000000000..1b1ce26c49 --- /dev/null +++ b/trunk/ext/syck/yaml2byte.c @@ -0,0 +1,259 @@ +/* + * yaml2byte.c + * + * $Author$ + * + * Copyright (C) 2003 why the lucky stiff, clark evans + * + * WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING + * ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING! + */ +#include "ruby/ruby.h" +#include <syck.h> +#include <assert.h> +#define YAMLBYTE_UTF8 +#include "yamlbyte.h" + +#include <stdio.h> +#define TRACE0(a) \ + do { printf(a); printf("\n"); fflush(stdout); } while(0) +#define TRACE1(a,b) \ + do { printf(a,b); printf("\n"); fflush(stdout); } while(0) +#define TRACE2(a,b,c) \ + do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0) +#define TRACE3(a,b,c,d) \ + do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0) + +/* Reinvent the wheel... */ +#define CHUNKSIZE 64 +#define HASH ((long)0xCAFECAFE) +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; +bytestring_t *bytestring_alloc(void) { + bytestring_t *ret; + /*TRACE0("bytestring_alloc()");*/ + ret = S_ALLOC(bytestring_t); + ret->hash = HASH; + ret->length = CHUNKSIZE; + ret->remaining = ret->length; + ret->buffer = S_ALLOC_N(char, ret->length + 1 ); + ret->buffer[0] = 0; + ret->printed = 0; + return ret; +} +void bytestring_append(bytestring_t *str, char code, + char *start, char *finish) +{ + long grow; + long length = 2; /* CODE + LF */ + char *curr; + assert(str && HASH == str->hash); + /*TRACE0("bytestring_append()");*/ + if(start) { + if(!finish) + finish = start + strlen(start); + length += (finish-start); + } + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 ); + assert(str->buffer); + } + curr = str->buffer + (str->length - str->remaining); + *curr = code; + curr += 1; + if(start) + while(start < finish) + *curr ++ = *start ++; + *curr = '\n'; + curr += 1; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); +} +void bytestring_extend(bytestring_t *str, bytestring_t *ext) +{ + char *from; + char *curr; + char *stop; + long grow; + long length; + assert(str && HASH == str->hash); + assert(ext && HASH == ext->hash); + if(ext->printed) { + assert(ext->buffer[0] ==YAMLBYTE_ANCHOR); + curr = ext->buffer; + while( '\n' != *curr) + curr++; + bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr); + } else { + ext->printed = 1; + length = (ext->length - ext->remaining); + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 ); + } + curr = str->buffer + (str->length - str->remaining); + from = ext->buffer; + stop = ext->buffer + length; + while( from < stop ) + *curr ++ = *from ++; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); + } +} + +/* convert SyckNode into yamlbyte_buffer_t objects */ +SYMID +syck_yaml2byte_handler(p, n) + SyckParser *p; + SyckNode *n; +{ + SYMID oid; + long i; + char ch; + char nextcode; + char *start; + char *current; + char *finish; + bytestring_t *val = NULL; + bytestring_t *sav = NULL; + void *data; + /*TRACE0("syck_yaml2byte_handler()");*/ + val = bytestring_alloc(); + if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL); + if ( n->type_id ) + { + if ( p->taguri_expansion ) + { + bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL); + } + else + { + char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 ); + type_tag[0] = '\0'; + strcat( type_tag, "!" ); + strcat( type_tag, n->type_id ); + bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL); + S_FREE(type_tag); + } + } + switch (n->kind) + { + case syck_str_kind: + nextcode = YAMLBYTE_SCALAR; + start = n->data.str->ptr; + finish = start + n->data.str->len - 1; + current = start; + /*TRACE2("SCALAR: %s %d", start, n->data.str->len); */ + while(1) { + ch = *current; + if('\n' == ch || 0 == ch || current > finish) { + if(current >= start) { + bytestring_append(val, nextcode, start, current); + nextcode = YAMLBYTE_CONTINUE; + } + start = current + 1; + if(current > finish) + { + break; + } + else if('\n' == ch ) + { + bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL); + } + else if(0 == ch) + { + bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL); + } + else + { + assert("oops"); + } + } + current += 1; + } + break; + case syck_seq_kind: + bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL); + for ( i = 0; i < n->data.list->idx; i++ ) + { + oid = syck_seq_read( n, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + case syck_map_kind: + bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + oid = syck_map_read( n, map_key, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + oid = syck_map_read( n, map_value, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + } + oid = syck_add_sym( p, (char *) val ); + /*TRACE1("Saving: %s", val->buffer );*/ + return oid; +} + +char * +syck_yaml2byte(char *yamlstr) +{ + SYMID oid; + char *ret; + bytestring_t *sav; + void *data; + + SyckParser *parser = syck_new_parser(); + syck_parser_str_auto( parser, yamlstr, NULL ); + syck_parser_handler( parser, syck_yaml2byte_handler ); + syck_parser_error_handler( parser, NULL ); + syck_parser_implicit_typing( parser, 1 ); + syck_parser_taguri_expansion( parser, 1 ); + oid = syck_parse( parser ); + + if ( syck_lookup_sym( parser, oid, &data ) ) { + sav = data; + ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 ); + ret[0] = '\0'; + strcat( ret, "D\n" ); + strcat( ret, sav->buffer ); + } + else + { + ret = NULL; + } + + syck_free_parser( parser ); + return ret; +} + +#ifdef TEST_YBEXT +#include <stdio.h> +int main() { + char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3"; + printf("--- # YAML \n"); + printf(yaml); + printf("\n...\n"); + printf(syck_yaml2byte(yaml)); + return 0; +} +#endif + diff --git a/trunk/ext/syck/yamlbyte.h b/trunk/ext/syck/yamlbyte.h new file mode 100644 index 0000000000..0fe4e7b576 --- /dev/null +++ b/trunk/ext/syck/yamlbyte.h @@ -0,0 +1,170 @@ +/* yamlbyte.h + * + * The YAML bytecode "C" interface header file. See the YAML bytecode + * reference for bytecode sequence rules and for the meaning of each + * bytecode. + */ + +#ifndef YAMLBYTE_H +#define YAMLBYTE_H +#include <stddef.h> + +/* define what a character is */ +typedef unsigned char yamlbyte_utf8_t; +typedef unsigned short yamlbyte_utf16_t; +#ifdef YAMLBYTE_UTF8 + #ifdef YAMLBYTE_UTF16 + #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16 + #endif + typedef yamlbyte_utf8_t yamlbyte_char_t; +#else + #ifdef YAMLBYTE_UTF16 + typedef yamlbyte_utf16_t yamlbyte_char_t; + #else + #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16 + #endif +#endif + +/* specify list of bytecodes */ +#define YAMLBYTE_FINISH ((yamlbyte_char_t) 0) +#define YAMLBYTE_DOCUMENT ((yamlbyte_char_t)'D') +#define YAMLBYTE_DIRECTIVE ((yamlbyte_char_t)'V') +#define YAMLBYTE_PAUSE ((yamlbyte_char_t)'P') +#define YAMLBYTE_MAPPING ((yamlbyte_char_t)'M') +#define YAMLBYTE_SEQUENCE ((yamlbyte_char_t)'Q') +#define YAMLBYTE_END_BRANCH ((yamlbyte_char_t)'E') +#define YAMLBYTE_SCALAR ((yamlbyte_char_t)'S') +#define YAMLBYTE_CONTINUE ((yamlbyte_char_t)'C') +#define YAMLBYTE_NEWLINE ((yamlbyte_char_t)'N') +#define YAMLBYTE_NULLCHAR ((yamlbyte_char_t)'Z') +#define YAMLBYTE_ANCHOR ((yamlbyte_char_t)'A') +#define YAMLBYTE_ALIAS ((yamlbyte_char_t)'R') +#define YAMLBYTE_TRANSFER ((yamlbyte_char_t)'T') +/* formatting bytecodes */ +#define YAMLBYTE_COMMENT ((yamlbyte_char_t)'c') +#define YAMLBYTE_INDENT ((yamlbyte_char_t)'i') +#define YAMLBYTE_STYLE ((yamlbyte_char_t)'s') +/* other bytecodes */ +#define YAMLBYTE_LINE_NUMBER ((yamlbyte_char_t)'#') +#define YAMLBYTE_WHOLE_SCALAR ((yamlbyte_char_t)'<') +#define YAMLBYTE_NOTICE ((yamlbyte_char_t)'!') +#define YAMLBYTE_SPAN ((yamlbyte_char_t)')') +#define YAMLBYTE_ALLOC ((yamlbyte_char_t)'@') + +/* second level style bytecodes, ie "s>" */ +#define YAMLBYTE_FLOW ((yamlbyte_char_t)'>') +#define YAMLBYTE_LITERAL ((yamlbyte_char_t)'|') +#define YAMLBYTE_BLOCK ((yamlbyte_char_t)'b') +#define YAMLBYTE_PLAIN ((yamlbyte_char_t)'p') +#define YAMLBYTE_INLINE_MAPPING ((yamlbyte_char_t)'{') +#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[') +#define YAMLBYTE_SINGLE_QUOTED ((yamlbyte_char_t)39) +#define YAMLBYTE_DOUBLE_QUOTED ((yamlbyte_char_t)'"') + +/* + * The "C" API has two variants, one based on instructions, + * with events delivered via pointers; and the other one + * is character based where one or more instructions are + * serialized into a buffer. + * + * Note: In the instruction based API, WHOLE_SCALAR does + * not have the '<here' marshalling stuff. + */ + +typedef void * yamlbyte_consumer_t; +typedef void * yamlbyte_producer_t; + +/* push and pull APIs need a way to communicate results */ +typedef enum { + YAMLBYTE_OK = 0, /* proceed */ + YAMLBYTE_E_MEMORY = 'M', /* could not allocate memory */ + YAMLBYTE_E_READ = 'R', /* input stream read error */ + YAMLBYTE_E_WRITE = 'W', /* output stream write error */ + YAMLBYTE_E_OTHER = '?', /* some other error condition */ + YAMLBYTE_E_PARSE = 'P', /* parse error, check bytecodes */ +} yamlbyte_result_t; + +typedef const yamlbyte_char_t *yamlbyte_buff_t; + +/* + * The "Instruction" API + */ + +typedef struct yaml_instruction { + yamlbyte_char_t bytecode; + yamlbyte_buff_t start; + yamlbyte_buff_t finish; /* open range, *finish is _not_ part */ +} *yamlbyte_inst_t; + +/* producer pushes the instruction with one bytecode event to the + * consumer; if the consumer's result is not YAMLBYTE_OK, then + * the producer should stop */ +typedef + yamlbyte_result_t + (*yamlbyte_push_t)( + yamlbyte_consumer_t self, + yamlbyte_inst_t inst + ); + +/* consumer pulls a bytecode instruction from the producer; in this + * case the instruction (and is buffer) are owned by the producer and + * will remain valid till the pull function is called once again; + * if the instruction is NULL, then there are no more results; and + * it is important to call the pull function till it returns NULL so + * that the producer can clean up its memory allocations */ +typedef + yamlbyte_result_t + (*yamlbyte_pull_t)( + yamlbyte_producer_t self, + yamlbyte_inst_t *inst /* to be filled in by the producer */ + ); + +/* + * Buffer based API + */ + +/* producer pushes a null terminated buffer filled with one or more + * bytecode events to the consumer; if the consumer's result is not + * YAMLBYTE_OK, then the producer should stop */ +typedef + yamlbyte_result_t + (*yamlbyte_pushbuff_t)( + yamlbyte_consumer_t self, + yamlbyte_buff_t buff + ); + +/* consumer pulls bytecode events from the producer; in this case + * the buffer is owned by the producer, and will remain valid till + * the pull function is called once again; if the buffer pointer + * is set to NULL, then there are no more results; it is important + * to call the pull function till it returns NULL so that the + * producer can clean up its memory allocations */ +typedef + yamlbyte_result_t + (*yamlbyte_pullbuff_t)( + yamlbyte_producer_t self, + yamlbyte_buff_t *buff /* to be filled in by the producer */ + ); + +/* convert a pull interface to a push interface; the reverse process + * requires threads and thus is language dependent */ +#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result) \ + do { \ + yamlbyte_pullbuff_t _pull = (pull); \ + yamlbyte_pushbuff_t _push = (push); \ + yamlbyte_result_t _result = YAMLBYTE_OK; \ + yamlbyte_producer_t _producer = (producer); \ + yamlbyte_consumer_t _consumer = (consumer); \ + while(1) { \ + yamlbyte_buff_t buff = NULL; \ + _result = _pull(_producer,&buff); \ + if(YAMLBYTE_OK != result || NULL == buff) \ + break; \ + _result = _push(_consumer,buff); \ + if(YAMLBYTE_OK != result) \ + break; \ + } \ + (result) = _result; \ + } while(0) + +#endif |