- if(!newname && gv) {
- SV * const namesv = sv_newmortal();
- STRLEN len;
- gv_fullname4(namesv, gv, NULL, 0);
- if(gv_fetchsv(namesv, GV_NOADD_NOINIT, SVt_PVGV) != gv) return;
- newname = SvPV_const(namesv, len);
- newname_len = len - 2; /* skip trailing :: */
+ if(!(flags & 1)) {
+ SV **svp;
+ if(
+ !GvSTASH(gv) || !HvENAME(GvSTASH(gv)) ||
+ !(svp = hv_fetch(GvSTASH(gv), GvNAME(gv),
+ GvNAMEUTF8(gv) ? -GvNAMELEN(gv) : GvNAMELEN(gv), 0)) ||
+ *svp != (SV *)gv
+ ) return;
+ }
+ assert(SvOOK(GvSTASH(gv)));
+ assert(GvNAMELEN(gv));
+ assert(GvNAME(gv)[GvNAMELEN(gv) - 1] == ':');
+ assert(GvNAMELEN(gv) == 1 || GvNAME(gv)[GvNAMELEN(gv) - 2] == ':');
+ name_count = HvAUX(GvSTASH(gv))->xhv_name_count;
+ if (!name_count) {
+ name_count = 1;
+ namep = &HvAUX(GvSTASH(gv))->xhv_name_u.xhvnameu_name;
+ }
+ else {
+ namep = HvAUX(GvSTASH(gv))->xhv_name_u.xhvnameu_names;
+ if (name_count < 0) ++namep, name_count = -name_count - 1;
+ }
+ if (name_count == 1) {
+ if (HEK_LEN(*namep) == 4 && strnEQ(HEK_KEY(*namep), "main", 4)) {
+ namesv = GvNAMELEN(gv) == 1
+ ? newSVpvs_flags(":", SVs_TEMP)
+ : newSVpvs_flags("", SVs_TEMP);
+ }
+ else {
+ namesv = sv_2mortal(newSVhek(*namep));
+ if (GvNAMELEN(gv) == 1) sv_catpvs(namesv, ":");
+ else sv_catpvs(namesv, "::");
+ }
+ if (GvNAMELEN(gv) != 1) {
+ sv_catpvn_flags(
+ namesv, GvNAME(gv), GvNAMELEN(gv) - 2,
+ /* skip trailing :: */
+ GvNAMEUTF8(gv) ? SV_CATUTF8 : SV_CATBYTES
+ );
+ }
+ }
+ else {
+ SV *aname;
+ namesv = sv_2mortal((SV *)newAV());
+ while (name_count--) {
+ if(HEK_LEN(*namep) == 4 && strnEQ(HEK_KEY(*namep), "main", 4)){
+ aname = GvNAMELEN(gv) == 1
+ ? newSVpvs(":")
+ : newSVpvs("");
+ namep++;
+ }
+ else {
+ aname = newSVhek(*namep++);
+ if (GvNAMELEN(gv) == 1) sv_catpvs(aname, ":");
+ else sv_catpvs(aname, "::");
+ }
+ if (GvNAMELEN(gv) != 1) {
+ sv_catpvn_flags(
+ aname, GvNAME(gv), GvNAMELEN(gv) - 2,
+ /* skip trailing :: */
+ GvNAMEUTF8(gv) ? SV_CATUTF8 : SV_CATBYTES
+ );
+ }
+ av_push((AV *)namesv, aname);
+ }