static JSBool perlarray_get( JSContext *cx, JSObject *obj, jsval id, jsval *vp ) { dTHX; SV *ref = (SV *)JS_GetPrivate(cx, obj); AV *av = (AV *)SvRV(ref); JSBool ok = JS_TRUE; PJS_ARRAY_CHECK if(JSVAL_IS_INT(id)) { I32 ix = JSVAL_TO_INT(id); SV **v; ENTER; SAVETMPS; v = av_fetch(av, ix, 0); if(v) { if(SvGMAGICAL(*v)) mg_get(*v); ok = PJS_ReflectPerl2JS(aTHX_ cx, obj, sv_mortalcopy(*v), vp); } else { JS_ReportError(cx, "Failed to retrieve element at index: %d", ix); ok = JS_FALSE; } FREETMPS; LEAVE; } return ok; }
bool Perl_sv_derived_from(pTHX_ SV *sv, const char *name) { char *type; HV *stash; stash = Nullhv; type = Nullch; if (SvGMAGICAL(sv)) mg_get(sv) ; if (SvROK(sv)) { sv = SvRV(sv); type = sv_reftype(sv,0); if (SvOBJECT(sv)) stash = SvSTASH(sv); } else { stash = gv_stashsv(sv, FALSE); } return (type && strEQ(type,name)) || (stash && isa_lookup(stash, name, strlen(name), 0) == &PL_sv_yes) ? TRUE : FALSE ; }
/* getcode関数 */ SV* xs_getcode(SV* sv_str) { int matches; CodeCheck check[cc_tmpl_max]; if( sv_str==&PL_sv_undef ) { return new_SV_UNDEF(); } if( SvGMAGICAL(sv_str) ) { mg_get(sv_str); } if( !SvOK(sv_str) ) { return newSVsv(&PL_sv_undef); } matches = getcode_list(sv_str, check); if( matches>0 ) { int index = 0; #if TEST && GC_DISP fprintf(stderr,"<selected>\n"); fprintf(stderr," %d of 0..%d\n",index,matches-1); fprintf(stderr," %s\n",charcodeToStr(check[index].code)); #endif switch(check[index].code) { case cc_unknown: return new_CC_UNKNOWN(); case cc_ascii: return new_CC_ASCII(); case cc_sjis: return new_CC_SJIS(); case cc_eucjp: return new_CC_EUCJP(); case cc_jis: return new_CC_JIS(); case cc_jis_au: return new_CC_JIS_AU(); case cc_jis_jsky: return new_CC_JIS_JSKY(); case cc_utf8: return new_CC_UTF8(); case cc_utf16: return new_CC_UTF16(); case cc_utf32: return new_CC_UTF32(); case cc_utf32_be: return new_CC_UTF32_BE(); case cc_utf32_le: return new_CC_UTF32_LE(); case cc_sjis_jsky: return new_CC_SJIS_JSKY(); case cc_sjis_imode: return new_CC_SJIS_IMODE(); case cc_sjis_doti: return new_CC_SJIS_DOTI(); case cc_sjis_au: return new_CC_SJIS_AU(); default: #ifdef TEST return NULL; #else return new_CC_UNKNOWN(); #endif } }else { return new_CC_UNKNOWN(); } }
/* getcode_list関数 */ int xs_getcode_list(SV* sv_str) { int matches; CodeCheck check[cc_tmpl_max]; int i; dSP; dMARK; dAX; /* XSARGS; - items */ if( sv_str==&PL_sv_undef ) { return 0; } if( SvGMAGICAL(sv_str) ) { mg_get(sv_str); } if( !SvOK(sv_str) ) { return 0; } matches = getcode_list(sv_str, check); if( matches<=0 ) { return 0; } EXTEND(SP, matches); for( i=0; i<matches; ++i ) { switch(check[i].code) { case cc_unknown: ST(i) = sv_2mortal( new_CC_UNKNOWN() ); break; case cc_ascii: ST(i) = sv_2mortal( new_CC_ASCII() ); break; case cc_sjis: ST(i) = sv_2mortal( new_CC_SJIS() ); break; case cc_eucjp: ST(i) = sv_2mortal( new_CC_EUCJP() ); break; case cc_jis: ST(i) = sv_2mortal( new_CC_JIS() ); break; case cc_jis_au: ST(i) = sv_2mortal( new_CC_JIS_AU() ); break; case cc_jis_jsky: ST(i) = sv_2mortal( new_CC_JIS_JSKY() ); break; case cc_utf8: ST(i) = sv_2mortal( new_CC_UTF8() ); break; case cc_utf16: ST(i) = sv_2mortal( new_CC_UTF16() ); break; case cc_utf32: ST(i) = sv_2mortal( new_CC_UTF32() ); break; case cc_utf32_be: ST(i) = sv_2mortal( new_CC_UTF32_BE() ); break; case cc_utf32_le: ST(i) = sv_2mortal( new_CC_UTF32_LE() ); break; case cc_sjis_jsky: ST(i) = sv_2mortal( new_CC_SJIS_JSKY() ); break; case cc_sjis_imode: ST(i) = sv_2mortal( new_CC_SJIS_IMODE() ); break; case cc_sjis_doti: ST(i) = sv_2mortal( new_CC_SJIS_DOTI() ); break; default: ST(i) = sv_2mortal( new_CC_UNKNOWN() ); break; } } return matches; }
static SV * ForceScalar(pTHX_ SV *sv) { if (SvGMAGICAL(sv)) mg_get(sv); if (SvTYPE(sv) == SVt_PVAV) { AV *av = (AV *) sv; SV *newsv = newSVpv("",0); Scalarize(aTHX_ newsv, (AV *) av); av_clear(av); av_store(av,0,newsv); return newsv; } else { if (SvROK(sv) && !SvOBJECT(SvRV(sv)) && SvTYPE(SvRV(sv)) == SVt_PVAV) { /* Callbacks and lists often get stringified by mistake due to Tcl/Tk's string fixation - don't change the real value */ SV *newsv = newSVpv("",0); Scalarize(aTHX_ newsv, (AV *) SvRV(sv)); return sv_2mortal(newsv); } else if (!SvOK(sv)) { /* Map undef to null string */ if (SvREADONLY(sv)) { SV *newsv = newSVpv("",0); return sv_2mortal(newsv); } else sv_setpvn(sv,"",0); } return sv; } }
static int getcode_list(SV* sv_str, CodeCheck* check) { unsigned char* src; STRLEN len; const unsigned char* src_end; int cc_max; if( sv_str==&PL_sv_undef ) { return 0; } if( SvGMAGICAL(sv_str) ) { mg_get(sv_str); } if( !SvOK(sv_str) ) { return 0; } src = (unsigned char*)SvPV(sv_str, len); src_end = src+len; /* empty string */ /* (jp:) 空文字列は unknown */ if( len==0 ) { return 0; } /* BOM of UTF32 */ if( (len%4)==0 && len>=4 && ( memcmp(src,RE_BOM4_BE,4)==0 || memcmp(src,RE_BOM4_LE,4)==0 ) ) { check[0].code = cc_utf32; return 1; } /* BOM of UTF16 */ if( (len%2)==0 && len>=2 && ( memcmp(src,RE_BOM2_BE,2)==0 || memcmp(src,RE_BOM2_LE,2)==0 ) ) { check[0].code = cc_utf16; return 1; } /* fprintf(stderr,"Unicode::Japanese::(xs)getcode[%d]\n",len); */ /* fprintf(stderr,">>%s<<\n",src); */ /* bin_dump("in ",src,len); */ memcpy(check,cc_tmpl,sizeof(cc_tmpl)); cc_max = cc_tmpl_max; for( ; src<src_end; ++src ) { int invalids; int i; #if TEST && GC_DISP fprintf(stderr,"[%d] '%c' 0x%02x (%d)\n",len-(src_end-src),(0x20<=*src&&*src<=0x7f?*src:'.'),*src,*src); #endif /* 遷移を1つ進める〜 */ invalids = 0; for( i=0; i<cc_max; ++i ) { int nxt = check[i].table[*src]; #if TEST && GC_DISP fprintf(stderr," %s : %d (%s)\n",charcodeToStr(check[i].code),nxt,nxt!=map_invalid?check[i].msg[nxt]:"invalid"); #endif if( nxt!=map_invalid ) { check[i].table = check[i].base+nxt*256; }else { ++invalids; check[i].table = NULL; } } if( invalids==0 ) { /* 全部継続 */ continue; }else if( cc_max-invalids>0 ) { /* まだあり〜 */ int rd = 0; int wr = 0; for( ;rd<cc_max; ++rd ) { if( check[rd].table ) { if( rd!=wr ) { check[wr] = check[rd]; } ++wr; } } cc_max = wr; }else { /* 全部だめ〜 */ return 0; } } /* check if we have stopped at a valid (final?) state */ { int wr = 0; int i; for( i=0; i<cc_max; ++i ) { if( check[i].table == check[i].base || _is_acceptable_state(&check[i]) ) { if( wr!=i ) { check[wr] = check[i]; } ++wr; } } cc_max = wr; } #if TEST && GC_DISP fprintf(stderr,"<availables>\n"); { int i; for( i=0; i<cc_max; ++i ) { fprintf(stderr," %s\n",charcodeToStr(check[i].code)); } } #endif return cc_max; }