#undef PACKAGE_NAME
#undef NULL_LITERAL
#undef NULL_LITERAL_LENGTH
#undef SCALAR_NUMBER
#undef SCALAR_STRING
#undef SCALAR_QUOTED
#undef SCALAR_UTF8
#undef SEQ_NONE
#undef MAP_NONE
#undef IS_UTF8
#undef TYPE_IS_NULL
#undef OBJOF
#undef PERL_SYCK_PARSER_HANDLER
#undef PERL_SYCK_EMITTER_HANDLER
#undef PERL_SYCK_INDENT_LEVEL
#undef PERL_SYCK_MARK_EMITTER
#ifdef YAML_IS_JSON
# define PACKAGE_NAME "JSON::Syck"
# define NULL_LITERAL "null"
# define NULL_LITERAL_LENGTH 4
# define SCALAR_NUMBER scalar_none
char json_quote_char = '"';
static enum scalar_style json_quote_style = scalar_2quote;
# define SCALAR_STRING json_quote_style
# define SCALAR_QUOTED json_quote_style
# define SCALAR_UTF8 scalar_fold
# define SEQ_NONE seq_inline
# define MAP_NONE map_inline
# define IS_UTF8(x) TRUE
# define TYPE_IS_NULL(x) ((x == NULL) || strEQ( x, "str" ))
# define OBJOF(a) (a)
# define PERL_SYCK_PARSER_HANDLER json_syck_parser_handler
# define PERL_SYCK_EMITTER_HANDLER json_syck_emitter_handler
# define PERL_SYCK_MARK_EMITTER json_syck_mark_emitter
# define PERL_SYCK_INDENT_LEVEL 0
#else
# define PACKAGE_NAME "YAML::Syck"
# define REF_LITERAL "="
# define REF_LITERAL_LENGTH 1
# define NULL_LITERAL "~"
# define NULL_LITERAL_LENGTH 1
# define SCALAR_NUMBER scalar_none
# define SCALAR_STRING scalar_none
# define SCALAR_QUOTED scalar_1quote
# define SCALAR_UTF8 scalar_fold
# define SEQ_NONE seq_none
# define MAP_NONE map_none
#ifdef SvUTF8
# define IS_UTF8(x) (SvUTF8(sv))
#else
# define IS_UTF8(x) (FALSE)
#endif
# define TYPE_IS_NULL(x) (x == NULL)
# define OBJOF(a) (*tag ? tag : a)
# define PERL_SYCK_PARSER_HANDLER yaml_syck_parser_handler
# define PERL_SYCK_EMITTER_HANDLER yaml_syck_emitter_handler
# define PERL_SYCK_MARK_EMITTER yaml_syck_mark_emitter
# define PERL_SYCK_INDENT_LEVEL 2
#endif
#define TRACK_OBJECT(sv) (av_push(((struct parser_xtra *)p->bonus)->objects, sv))
#define USE_OBJECT(sv) (SvREFCNT_inc(sv))
SYMID
#ifdef YAML_IS_JSON
json_syck_parser_handler
#else
yaml_syck_parser_handler
#endif
(SyckParser *p, SyckNode *n) {
SV *sv;
AV *seq;
HV *map;
long i;
char *id = n->type_id;
#ifndef YAML_IS_JSON
struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
bool load_code = bonus->load_code;
#endif
while (id && (*id == '!')) { id++; }
switch (n->kind) {
case syck_str_kind:
if (TYPE_IS_NULL(id)) {
if (strnEQ( n->data.str->ptr, NULL_LITERAL, 1+NULL_LITERAL_LENGTH)
&& (n->data.str->style == scalar_plain)) {
sv = newSV(0);
}
else {
sv = newSVpvn(n->data.str->ptr, n->data.str->len);
CHECK_UTF8;
}
} else if (strEQ( id, "null" )) {
sv = newSV(0);
} else if (strEQ( id, "bool#yes" )) {
sv = newSVsv(&PL_sv_yes);
} else if (strEQ( id, "bool#no" )) {
sv = newSVsv(&PL_sv_no);
} else if (strEQ( id, "default" )) {
sv = newSVpvn(n->data.str->ptr, n->data.str->len);
CHECK_UTF8;
} else if (strEQ( id, "float#base60" )) {
char *ptr, *end;
UV sixty = 1;
NV 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 )
{
NV bnum = 0;
char *colon = end - 1;
while ( colon >= ptr && *colon != ':' )
{
colon--;
}
if ( *colon == ':' ) *colon = '\0';
bnum = strtod( colon + 1, NULL );
total += bnum * sixty;
sixty *= 60;
end = colon;
}
sv = newSVnv(total);
#ifdef NV_NAN
} else if (strEQ( id, "float#nan" )) {
sv = newSVnv(NV_NAN);
#endif
#ifdef NV_INF
} else if (strEQ( id, "float#inf" )) {
sv = newSVnv(NV_INF);
} else if (strEQ( id, "float#neginf" )) {
sv = newSVnv(-NV_INF);
#endif
} else if (strnEQ( id, "float", 5 )) {
NV f;
syck_str_blow_away_commas( n );
f = strtod( n->data.str->ptr, NULL );
sv = newSVnv( f );
} else if (strEQ( id, "int#base60" )) {
char *ptr, *end;
UV sixty = 1;
UV 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 == ':' ) *colon = '\0';
bnum = strtol( colon + 1, NULL, 10 );
total += bnum * sixty;
sixty *= 60;
end = colon;
}
sv = newSVuv(total);
} else if (strEQ( id, "int#hex" )) {
I32 flags = 0;
STRLEN len = n->data.str->len;
syck_str_blow_away_commas( n );
sv = newSVuv( grok_hex( n->data.str->ptr, &len, &flags, NULL) );
} else if (strEQ( id, "int#oct" )) {
I32 flags = 0;
STRLEN len = n->data.str->len;
syck_str_blow_away_commas( n );
sv = newSVuv( grok_oct( n->data.str->ptr, &len, &flags, NULL) );
} else if (strEQ( id, "int" ) ) {
UV uv = 0;
syck_str_blow_away_commas( n );
if (grok_number( n->data.str->ptr, n->data.str->len, &uv) & IS_NUMBER_NEG) {
sv = newSViv(-uv);
}
else {
sv = newSVuv(uv);
}
} else if (strEQ( id, "binary" )) {
long len = 0;
char *blob = syck_base64dec(n->data.str->ptr, n->data.str->len, &len);
sv = newSVpv(blob, len);
#ifdef PERL_LOADMOD_NOIMPORT
#ifndef YAML_IS_JSON
} else if (load_code && (strEQ(id, "perl/code") || strnEQ(id, "perl/code:", 10))) {
SV *cv;
SV *text, *sub;
char *pkg = id + 10;
text = newSVpvn(n->data.str->ptr, n->data.str->len);
sub = newSVpvn("sub ", 4);
sv_catpv(sub, SvPV_nolen(text));
SvREFCNT_dec(text);
ENTER;
SAVETMPS;
cv = eval_pv(SvPV_nolen(sub), TRUE);
sv_2mortal(sub);
if (cv && SvROK(cv) && SvTYPE(SvRV(cv)) == SVt_PVCV) {
sv = cv;
} else {
croak("code %s did not evaluate to a subroutine reference\n", SvPV_nolen(sub));
}
if ( (*(pkg - 1) != '\0') && (*pkg != '\0') ) {
sv_bless(sv, gv_stashpv(pkg, TRUE));
}
SvREFCNT_inc(sv);
FREETMPS;
LEAVE;
} else if (strnEQ( n->data.str->ptr, REF_LITERAL, 1+REF_LITERAL_LENGTH)) {
char *lang = strtok(id, "/:");
char *type = strtok(NULL, "");
if (lang == NULL || (strEQ(lang, "perl"))) {
sv = newSVpv(type, 0);
}
else {
sv = newSVpv(form((type == NULL) ? "%s" : "%s::%s", lang, type), 0);
}
} else if ( strEQ( id, "perl/scalar" ) || strnEQ( id, "perl/scalar:", 12 ) ) {
char *pkg = id + 12;
if (strnEQ( n->data.str->ptr, NULL_LITERAL, 1+NULL_LITERAL_LENGTH)
&& (n->data.str->style == scalar_plain)) {
sv = newSV(0);
}
else {
sv = newSVpvn(n->data.str->ptr, n->data.str->len);
CHECK_UTF8;
}
sv = newRV_inc(sv);
if ( (*(pkg - 1) != '\0') && (*pkg != '\0') ) {
sv_bless(sv, gv_stashpv(id + 12, TRUE));
}
#endif
#endif
} else {
sv = newSVpvn(n->data.str->ptr, n->data.str->len);
CHECK_UTF8;
}
break;
case syck_seq_kind:
seq = newAV();
for (i = 0; i < n->data.list->idx; i++) {
SV *a = perl_syck_lookup_sym(p, syck_seq_read(n, i));
av_push(seq, a);
USE_OBJECT(a);
}
sv = newRV_noinc((SV*)seq);
#ifndef YAML_IS_JSON
if (id) {
char *lang = strtok(id, "/:");
char *type = strtok(NULL, "");
if ( type != NULL ) {
if (strnEQ(type, "array:", 6)) {
type += 6;
}
while ( *type == '@' ) { type++; }
}
if (lang == NULL || (strEQ(lang, "perl"))) {
if ( (type != NULL) && strNE(type, "array") && *type != '\0' ) {
sv_bless(sv, gv_stashpv(type, TRUE));
}
}
else {
sv_bless(sv, gv_stashpv(form((type == NULL) ? "%s" : "%s::%s", lang, type), TRUE));
}
}
#endif
break;
case syck_map_kind:
#ifndef YAML_IS_JSON
if ( (id != NULL) && (strEQ(id, "perl/ref") || strnEQ( id, "perl/ref:", 9 ) ) ) {
SV* key = perl_syck_lookup_sym(p, syck_map_read(n, map_key, 0));
SV* val = perl_syck_lookup_sym(p, syck_map_read(n, map_value, 0));
char *ref_type = SvPVX(key);
sv = newRV_noinc(val);
USE_OBJECT(val);
if (strnNE(ref_type, REF_LITERAL, REF_LITERAL_LENGTH+1)) {
sv_bless(sv, gv_stashpv(ref_type, TRUE));
}
else {
char *lang = strtok(id, "/:");
char *type = strtok(NULL, "");
if ( type != NULL && strnEQ(type, "ref:", 4)) {
type += 4;
}
if (lang == NULL || (strEQ(lang, "perl"))) {
if ( (type != NULL) && strNE(type, "ref") && (*type != '\0')) {
sv_bless(sv, gv_stashpv(type, TRUE));
}
}
else {
sv_bless(sv, gv_stashpv(form((type == NULL) ? "%s" : "%s::%s", lang, type), TRUE));
}
}
}
else
#endif
{
map = newHV();
for (i = 0; i < n->data.pairs->idx; i++) {
SV* key = perl_syck_lookup_sym(p, syck_map_read(n, map_key, i));
SV* val = perl_syck_lookup_sym(p, syck_map_read(n, map_value, i));
if (hv_store_ent(map, key, val, 0) != NULL)
USE_OBJECT(val);
}
sv = newRV_noinc((SV*)map);
#ifndef YAML_IS_JSON
if (id) {
char *lang = strtok(id, "/:");
char *type = strtok(NULL, "");
if ( type != NULL ) {
if (strnEQ(type, "hash:", 5)) {
type += 5;
}
while ( *type == '%' ) { type++; }
}
if (lang == NULL || (strEQ(lang, "perl"))) {
if ( (type != NULL) && strNE(type, "hash") && *type != '\0' ) {
sv_bless(sv, gv_stashpv(type, TRUE));
}
} else {
sv_bless(sv, gv_stashpv(form((type == NULL) ? "%s" : "%s::%s", lang, type), TRUE));
}
}
#endif
}
break;
}
#ifndef YAML_IS_JSON
if (n->id) {
sv_setsv( perl_syck_lookup_sym(p, n->id), sv );
}
#endif
TRACK_OBJECT(sv);
return syck_add_sym(p, (char *)sv);
}
#ifdef YAML_IS_JSON
static char* perl_json_preprocess(char *s) {
int i;
char *out;
char ch;
bool in_string = 0;
bool in_quote = 0;
char *pos;
STRLEN len = strlen(s);
New(2006, out, len*2+1, char);
pos = out;
for (i = 0; i < len; i++) {
ch = *(s+i);
*pos++ = ch;
if (in_quote) {
in_quote = !in_quote;
if (ch == '\'') {
*(pos - 2) = '\'';
}
}
else if (ch == '\\') {
in_quote = 1;
}
else if (ch == json_quote_char) {
in_string = !in_string;
}
else if ((ch == ':' || ch == ',') && !in_string) {
*pos++ = ' ';
}
}
*pos = '\0';
return out;
}
void perl_json_postprocess(SV *sv) {
int i;
char ch;
bool in_string = 0;
bool in_quote = 0;
char *pos;
char *s = SvPVX(sv);
STRLEN len = sv_len(sv);
STRLEN final_len = len;
pos = s;
if ( (json_quote_char == '\'') && (len > 1) && (*s == '\"') && (*(s+len-2) == '\"') ) {
*s = '\'';
*(s+len-2) = '\'';
}
for (i = 0; i < len; i++) {
ch = *(s+i);
*pos++ = ch;
if (in_quote) {
in_quote = !in_quote;
}
else if (ch == '\\') {
in_quote = 1;
}
else if (ch == json_quote_char) {
in_string = !in_string;
}
else if ((ch == ':' || ch == ',') && !in_string) {
i++;
final_len--;
}
}
if (final_len > 0) {
final_len--; pos--;
}
*pos = '\0';
SvCUR_set(sv, final_len);
}
#endif
#ifdef YAML_IS_JSON
static SV * LoadJSON (char *s) {
#else
static SV * LoadYAML (char *s) {
#endif
SYMID v;
SyckParser *parser;
struct parser_xtra bonus;
SV *obj = &PL_sv_undef;
SV *implicit = GvSV(gv_fetchpv(form("%s::ImplicitTyping", PACKAGE_NAME), TRUE, SVt_PV));
SV *use_code = GvSV(gv_fetchpv(form("%s::UseCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *load_code = GvSV(gv_fetchpv(form("%s::LoadCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_unicode = GvSV(gv_fetchpv(form("%s::ImplicitUnicode", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_binary = GvSV(gv_fetchpv(form("%s::ImplicitBinary", PACKAGE_NAME), TRUE, SVt_PV));
SV *singlequote = GvSV(gv_fetchpv(form("%s::SingleQuote", PACKAGE_NAME), TRUE, SVt_PV));
json_quote_char = (SvTRUE(singlequote) ? '\'' : '"' );
json_quote_style = (SvTRUE(singlequote) ? scalar_1quote : scalar_2quote );
ENTER; SAVETMPS;
if (*s == '\0') { return &PL_sv_undef; }
#ifdef YAML_IS_JSON
s = perl_json_preprocess(s);
#else
if (strnEQ( s, "--- #YAML:1.0", 13)) {
s[4] = '%';
}
#endif
parser = syck_new_parser();
syck_parser_str_auto(parser, s, NULL);
syck_parser_handler(parser, PERL_SYCK_PARSER_HANDLER);
syck_parser_error_handler(parser, perl_syck_error_handler);
syck_parser_bad_anchor_handler( parser, perl_syck_bad_anchor_handler );
syck_parser_implicit_typing(parser, SvTRUE(implicit));
syck_parser_taguri_expansion(parser, 0);
bonus.objects = (AV*)sv_2mortal((SV*)newAV());
bonus.implicit_unicode = SvTRUE(implicit_unicode);
bonus.load_code = SvTRUE(use_code) || SvTRUE(load_code);
parser->bonus = &bonus;
#ifndef YAML_IS_JSON
if (GIMME_V == G_ARRAY) {
SYMID prev_v = 0;
obj = (SV*)newAV();
while ((v = syck_parse(parser)) && (v != prev_v)) {
SV *cur = &PL_sv_undef;
if (!syck_lookup_sym(parser, v, (char **)&cur)) {
break;
}
av_push((AV*)obj, cur);
USE_OBJECT(cur);
prev_v = v;
}
obj = newRV_noinc(obj);
}
else
#endif
{
v = syck_parse(parser);
if (syck_lookup_sym(parser, v, (char **)&obj)) {
USE_OBJECT(obj);
}
}
syck_free_parser(parser);
#ifdef YAML_IS_JSON
Safefree(s);
#endif
FREETMPS; LEAVE;
return obj;
}
void
#ifdef YAML_IS_JSON
json_syck_mark_emitter
#else
yaml_syck_mark_emitter
#endif
(SyckEmitter *e, SV *sv) {
if (syck_emitter_mark_node(e, (st_data_t)sv) == 0) {
#ifdef YAML_IS_JSON
croak("Dumping circular structures is not supported with JSON::Syck");
#endif
return;
}
if (SvROK(sv)) {
PERL_SYCK_MARK_EMITTER(e, SvRV(sv));
#ifdef YAML_IS_JSON
st_insert(e->markers, (st_data_t)sv, 0);
#endif
return;
}
switch (SvTYPE(sv)) {
case SVt_PVAV: {
I32 len, i;
len = av_len((AV*)sv) + 1;
for (i = 0; i < len; i++) {
SV** sav = av_fetch((AV*)sv, i, 0);
if (sav != NULL) {
PERL_SYCK_MARK_EMITTER( e, *sav );
}
}
break;
}
case SVt_PVHV: {
I32 len, i;
#ifdef HAS_RESTRICTED_HASHES
len = HvTOTALKEYS((HV*)sv);
#else
len = HvKEYS((HV*)sv);
#endif
hv_iterinit((HV*)sv);
for (i = 0; i < len; i++) {
#ifdef HV_ITERNEXT_WANTPLACEHOLDERS
HE *he = hv_iternext_flags((HV*)sv, HV_ITERNEXT_WANTPLACEHOLDERS);
#else
HE *he = hv_iternext((HV*)sv);
#endif
SV *val = hv_iterval((HV*)sv, he);
PERL_SYCK_MARK_EMITTER( e, val );
}
break;
}
}
#ifdef YAML_IS_JSON
st_insert(e->markers, (st_data_t)sv, 0);
#endif
}
void
#ifdef YAML_IS_JSON
json_syck_emitter_handler
#else
yaml_syck_emitter_handler
#endif
(SyckEmitter *e, st_data_t data) {
I32 len, i;
SV* sv = (SV*)data;
struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
char* tag = bonus->tag;
svtype ty = SvTYPE(sv);
#ifndef YAML_IS_JSON
char dump_code = bonus->dump_code;
char implicit_binary = bonus->implicit_binary;
char* ref = NULL;
#endif
#define OBJECT_TAG "tag:!perl:"
if (SvMAGICAL(sv)) {
mg_get(sv);
}
#ifndef YAML_IS_JSON
if (sv_isobject(sv)) {
ref = savepv(sv_reftype(SvRV(sv), TRUE));
*tag = '\0';
strcat(tag, OBJECT_TAG);
switch (SvTYPE(SvRV(sv))) {
case SVt_PVAV: { strcat(tag, "array:"); break; }
case SVt_PVHV: { strcat(tag, "hash:"); break; }
case SVt_PVCV: { strcat(tag, "code:"); break; }
case SVt_PVGV: { strcat(tag, "glob:"); break; }
case SVt_PVMG: {
if ( !SvROK(SvRV(sv)) ) {
strcat(tag, "scalar:");
sv = SvRV(sv);
ty = SvTYPE(sv);
break;
} else {
strcat(tag, "ref:");
break;
}
}
}
strcat(tag, ref);
}
#endif
if (SvROK(sv)) {
#ifdef YAML_IS_JSON
PERL_SYCK_EMITTER_HANDLER(e, (st_data_t)SvRV(sv));
#else
switch (SvTYPE(SvRV(sv))) {
case SVt_PVAV:
case SVt_PVHV:
case SVt_PVCV: {
e->indent = 0;
syck_emit_item(e, (st_data_t)SvRV(sv));
e->indent = PERL_SYCK_INDENT_LEVEL;
break;
}
default: {
syck_emit_map(e, OBJOF("tag:!perl:ref"), MAP_NONE);
*tag = '\0';
syck_emit_item( e, (st_data_t)newSVpvn_share(REF_LITERAL, REF_LITERAL_LENGTH, 0) );
syck_emit_item( e, (st_data_t)SvRV(sv) );
syck_emit_end(e);
}
}
#endif
}
else if (ty == SVt_NULL) {
syck_emit_scalar(e, "str", scalar_none, 0, 0, 0, NULL_LITERAL, NULL_LITERAL_LENGTH);
}
else if ((ty == SVt_PVMG) && !SvOK(sv)) {
syck_emit_scalar(e, OBJOF("str"), scalar_none, 0, 0, 0, NULL_LITERAL, NULL_LITERAL_LENGTH);
}
else if (SvNIOKp(sv) && (sv_len(sv) != 0)) {
syck_emit_scalar(e, OBJOF("str"), SCALAR_NUMBER, 0, 0, 0, SvPV_nolen(sv), sv_len(sv));
}
else if (SvPOKp(sv)) {
STRLEN len = sv_len(sv);
if (len == 0) {
syck_emit_scalar(e, OBJOF("str"), SCALAR_QUOTED, 0, 0, 0, "", 0);
}
#ifndef YAML_IS_JSON
else if (strEQ(SvPV_nolen(sv), NULL_LITERAL)) {
syck_emit_scalar(e, OBJOF("str"), SCALAR_QUOTED, 0, 0, 0, NULL_LITERAL, 1);
}
#endif
else if (IS_UTF8(sv)) {
enum scalar_style old_s = e->style;
e->style = SCALAR_UTF8;
syck_emit_scalar(e, OBJOF("str"), SCALAR_STRING, 0, 0, 0, SvPV_nolen(sv), len);
e->style = old_s;
}
#ifndef YAML_IS_JSON
else if (implicit_binary) {
bool is_ascii = TRUE;
char *str = SvPV_nolen(sv);
STRLEN len = sv_len(sv);
for (i = 0; i < len; i++) {
if (*(str + i) & 0x80) {
char *base64 = syck_base64enc( str, len );
syck_emit_scalar(e, "tag:yaml.org,2002:binary", SCALAR_STRING, 0, 0, 0, base64, strlen(base64));
is_ascii = FALSE;
break;
}
}
if (is_ascii) {
syck_emit_scalar(e, OBJOF("str"), SCALAR_STRING, 0, 0, 0, str, len);
}
}
#endif
else {
syck_emit_scalar(e, OBJOF("str"), SCALAR_STRING, 0, 0, 0, SvPV_nolen(sv), len);
}
}
else {
switch (ty) {
case SVt_PVAV: {
syck_emit_seq(e, OBJOF("array"), SEQ_NONE);
e->indent = PERL_SYCK_INDENT_LEVEL;
*tag = '\0';
len = av_len((AV*)sv) + 1;
for (i = 0; i < len; i++) {
SV** sav = av_fetch((AV*)sv, i, 0);
if (sav == NULL) {
syck_emit_item( e, (st_data_t)(&PL_sv_undef) );
}
else {
syck_emit_item( e, (st_data_t)(*sav) );
}
}
syck_emit_end(e);
return;
}
case SVt_PVHV: {
HV *hv = (HV*)sv;
syck_emit_map(e, OBJOF("hash"), MAP_NONE);
e->indent = PERL_SYCK_INDENT_LEVEL;
*tag = '\0';
#ifdef HAS_RESTRICTED_HASHES
len = HvTOTALKEYS((HV*)sv);
#else
len = HvKEYS((HV*)sv);
#endif
hv_iterinit((HV*)sv);
if (e->sort_keys) {
AV *av = (AV*)sv_2mortal((SV*)newAV());
for (i = 0; i < len; i++) {
#ifdef HAS_RESTRICTED_HASHES
HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
#else
HE *he = hv_iternext(hv);
#endif
SV *key = hv_iterkeysv(he);
av_store(av, AvFILLp(av)+1, key);
}
STORE_HASH_SORT;
for (i = 0; i < len; i++) {
#ifdef HAS_RESTRICTED_HASHES
int placeholders = (int)HvPLACEHOLDERS_get(hv);
#endif
SV *key = av_shift(av);
HE *he = hv_fetch_ent(hv, key, 0, 0);
SV *val = HeVAL(he);
if (val == NULL) { val = &PL_sv_undef; }
syck_emit_item( e, (st_data_t)key );
syck_emit_item( e, (st_data_t)val );
}
}
else {
for (i = 0; i < len; i++) {
#ifdef HV_ITERNEXT_WANTPLACEHOLDERS
HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
#else
HE *he = hv_iternext(hv);
#endif
SV *key = hv_iterkeysv(he);
SV *val = hv_iterval(hv, he);
syck_emit_item( e, (st_data_t)key );
syck_emit_item( e, (st_data_t)val );
}
}
syck_emit_end(e);
return;
}
case SVt_PVCV: {
#ifdef YAML_IS_JSON
syck_emit_scalar(e, "str", scalar_none, 0, 0, 0, NULL_LITERAL, NULL_LITERAL_LENGTH);
#else
if ( !dump_code ) {
syck_emit_scalar(e, OBJOF("tag:!perl:code:"), SCALAR_QUOTED, 0, 0, 0, "{ \"DUMMY\" }", 11);
}
else {
dSP;
I32 len;
int count, reallen;
SV *text;
CV *cv = (CV*)sv;
SV *bdeparse = GvSV(gv_fetchpv(form("%s::DeparseObject", PACKAGE_NAME), TRUE, SVt_PV));
if (!SvTRUE(bdeparse)) {
croak("B::Deparse initialization failed -- cannot dump code object");
}
ENTER;
SAVETMPS;
PUSHMARK(sp);
XPUSHs(bdeparse);
XPUSHs(sv_2mortal(newRV_inc((SV*)cv)));
PUTBACK;
count = call_method("coderef2text", G_SCALAR);
SPAGAIN;
if (count != 1) {
croak("Unexpected return value from B::Deparse::coderef2text\n");
}
text = POPs;
len = SvLEN(text);
reallen = strlen(SvPV_nolen(text));
if (len == 0 || *(SvPV_nolen(text)+reallen-1) == ';') {
croak("The result of B::Deparse::coderef2text was empty - maybe you're trying to serialize an XS function?\n");
}
syck_emit_scalar(e, OBJOF("tag:!perl:code:"), SCALAR_UTF8, 0, 0, 0, SvPV_nolen(text), reallen);
FREETMPS;
LEAVE;
}
#endif
*tag = '\0';
break;
}
case SVt_PVGV:
case SVt_PVFM: {
syck_emit_scalar(e, OBJOF("str"), SCALAR_STRING, 0, 0, 0, SvPV_nolen(sv), sv_len(sv));
break;
}
case SVt_PVIO: {
syck_emit_scalar(e, OBJOF("str"), SCALAR_STRING, 0, 0, 0, SvPV_nolen(sv), sv_len(sv));
break;
}
default: {
syck_emit_scalar(e, "str", scalar_none, 0, 0, 0, NULL_LITERAL, NULL_LITERAL_LENGTH);
}
}
}
*tag = '\0';
}
SV*
#ifdef YAML_IS_JSON
DumpJSON
#else
DumpYAML
#endif
(SV *sv) {
struct emitter_xtra bonus;
SV* out = newSVpvn("", 0);
SyckEmitter *emitter = syck_new_emitter();
SV *headless = GvSV(gv_fetchpv(form("%s::Headless", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_unicode = GvSV(gv_fetchpv(form("%s::ImplicitUnicode", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_binary = GvSV(gv_fetchpv(form("%s::ImplicitBinary", PACKAGE_NAME), TRUE, SVt_PV));
SV *use_code = GvSV(gv_fetchpv(form("%s::UseCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *dump_code = GvSV(gv_fetchpv(form("%s::DumpCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *sortkeys = GvSV(gv_fetchpv(form("%s::SortKeys", PACKAGE_NAME), TRUE, SVt_PV));
#ifdef YAML_IS_JSON
SV *singlequote = GvSV(gv_fetchpv(form("%s::SingleQuote", PACKAGE_NAME), TRUE, SVt_PV));
json_quote_char = (SvTRUE(singlequote) ? '\'' : '"' );
json_quote_style = (SvTRUE(singlequote) ? scalar_1quote : scalar_2quote );
emitter->indent = PERL_SYCK_INDENT_LEVEL;
#endif
ENTER; SAVETMPS;
#ifndef YAML_IS_JSON
if (SvTRUE(use_code) || SvTRUE(dump_code)) {
SV *bdeparse = GvSV(gv_fetchpv(form("%s::DeparseObject", PACKAGE_NAME), TRUE, SVt_PV));
if (!SvTRUE(bdeparse)) {
eval_pv(form(
"local $@; require B::Deparse; $%s::DeparseObject = B::Deparse->new",
PACKAGE_NAME
), 1);
}
}
#endif
emitter->headless = SvTRUE(headless);
emitter->sort_keys = SvTRUE(sortkeys);
emitter->anchor_format = "%d";
bonus.port = out;
New(801, bonus.tag, 512, char);
*(bonus.tag) = '\0';
bonus.dump_code = SvTRUE(use_code) || SvTRUE(dump_code);
bonus.implicit_binary = SvTRUE(implicit_binary);
emitter->bonus = &bonus;
syck_emitter_handler( emitter, PERL_SYCK_EMITTER_HANDLER );
syck_output_handler( emitter, perl_syck_output_handler );
PERL_SYCK_MARK_EMITTER( emitter, sv );
#ifdef YAML_IS_JSON
st_free_table(emitter->markers);
emitter->markers = st_init_numtable();
#endif
syck_emit( emitter, (st_data_t)sv );
syck_emitter_flush( emitter, 0 );
syck_free_emitter( emitter );
Safefree(bonus.tag);
#ifdef YAML_IS_JSON
if (SvCUR(out) > 0) {
perl_json_postprocess(out);
}
#endif
#ifdef SvUTF8_on
if (SvTRUE(implicit_unicode)) {
SvUTF8_on(out);
}
#endif
FREETMPS; LEAVE;
return out;
}