X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=gv.c;h=1868114325b89095885d7fde2524f5385e845b83;hb=c9d5ac959cdfa7a668b3bfbbc2b56923c316ef43;hp=e5312049b1bd5f8f64d12b52ecd3b2bd14b935f9;hpb=cea2e8a9dd23747fd2b66edc86c58c64e9970321;p=p5sagit%2Fp5-mst-13.2.git diff --git a/gv.c b/gv.c index e531204..1868114 100644 --- a/gv.c +++ b/gv.c @@ -1,6 +1,6 @@ /* gv.c * - * Copyright (c) 1991-1999, Larry Wall + * Copyright (c) 1991-2000, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -59,6 +59,9 @@ Perl_gv_fetchfile(pTHX_ const char *name) STRLEN tmplen; GV *gv; + if (!PL_defstash) + return Nullgv; + tmplen = strlen(name) + 2; if (tmplen < sizeof smallbuf) tmpbuf = smallbuf; @@ -68,15 +71,14 @@ Perl_gv_fetchfile(pTHX_ const char *name) tmpbuf[1] = '<'; strcpy(tmpbuf + 2, name); gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE); - if (!isGV(gv)) + if (!isGV(gv)) { gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE); + sv_setpv(GvSV(gv), name); + if (PERLDB_LINE) + hv_magic(GvHVn(gv_AVadd(gv)), gv, 'L'); + } if (tmpbuf != smallbuf) Safefree(tmpbuf); - sv_setpv(GvSV(gv), name); - if (*name == '/' && (instr(name, "/lib/") || instr(name, ".pm"))) - GvMULTI_on(gv); - if (PERLDB_LINE) - hv_magic(GvHVn(gv_AVadd(gv)), gv, 'L'); return gv; } @@ -100,8 +102,8 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) Newz(602, gp, 1, GP); GvGP(gv) = gp_ref(gp); GvSV(gv) = NEWSV(72,0); - GvLINE(gv) = PL_curcop->cop_line; - GvFILEGV(gv) = PL_curcop->cop_filegv; + GvLINE(gv) = CopLINE(PL_curcop); + GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : ""; GvCVGEN(gv) = 0; GvEGV(gv) = gv; sv_magic((SV*)gv, (SV*)gv, '*', name, len); @@ -120,7 +122,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) PL_sub_generation++; CvGV(GvCV(gv)) = (GV*)SvREFCNT_inc(gv); - CvFILEGV(GvCV(gv)) = PL_curcop->cop_filegv; + CvFILE(GvCV(gv)) = CopFILE(PL_curcop); CvSTASH(GvCV(gv)) = PL_curstash; #ifdef USE_THREADS CvOWNER(GvCV(gv)) = 0; @@ -152,6 +154,27 @@ S_gv_init_sv(pTHX_ GV *gv, I32 sv_type) } } +/* +=for apidoc gv_fetchmeth + +Returns the glob with the given C and a defined subroutine or +C. The glob lives in the given C, or in the stashes +accessible via @ISA and @UNIVERSAL. + +The argument C should be either 0 or -1. If C, as a +side-effect creates a glob with the given C in the given C +which in the case of success contains an alias for the subroutine, and sets +up caching info for this glob. Similarly for all the searched stashes. + +This function grants C<"SUPER"> token as a postfix of the stash name. The +GV returned from C may be a method cache entry, which is not +visible to Perl code. So when calling C, you should not use +the GV directly; instead, you should use the method's CV, which can be +obtained from the GV with the C macro. + +=cut +*/ + GV * Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) { @@ -176,7 +199,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) topgv = *gvp; if (SvTYPE(topgv) != SVt_PVGV) gv_init(topgv, stash, name, len, TRUE); - if (cv = GvCV(topgv)) { + if ((cv = GvCV(topgv))) { /* If genuine method or valid cache entry, use it */ if (!GvCVGEN(topgv) || GvCVGEN(topgv) == PL_sub_generation) return topgv; @@ -242,9 +265,10 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) if (level == 0 || level == -1) { HV* lastchance; - if (lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE)) { - if (gv = gv_fetchmeth(lastchance, name, len, - (level >= 0) ? level + 1 : level - 1)) { + if ((lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE))) { + if ((gv = gv_fetchmeth(lastchance, name, len, + (level >= 0) ? level + 1 : level - 1))) + { gotcha: /* * Cache method in topgv if: @@ -256,7 +280,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) (cv = GvCV(gv)) && (CvROOT(cv) || CvXSUB(cv))) { - if (cv = GvCV(topgv)) + if ((cv = GvCV(topgv))) SvREFCNT_dec(cv); GvCV(topgv) = (CV*)SvREFCNT_inc(GvCV(gv)); GvCVGEN(topgv) = PL_sub_generation; @@ -273,12 +297,48 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) return 0; } +/* +=for apidoc gv_fetchmethod + +See L. + +=cut +*/ + GV * Perl_gv_fetchmethod(pTHX_ HV *stash, const char *name) { return gv_fetchmethod_autoload(stash, name, TRUE); } +/* +=for apidoc gv_fetchmethod_autoload + +Returns the glob which contains the subroutine to call to invoke the method +on the C. In fact in the presence of autoloading this may be the +glob for "AUTOLOAD". In this case the corresponding variable $AUTOLOAD is +already setup. + +The third parameter of C determines whether +AUTOLOAD lookup is performed if the given method is not present: non-zero +means yes, look for AUTOLOAD; zero means no, don't look for AUTOLOAD. +Calling C is equivalent to calling C +with a non-zero C parameter. + +These functions grant C<"SUPER"> token as a prefix of the method name. Note +that if you want to keep the returned glob for a long time, you need to +check for it being "AUTOLOAD", since at the later time the call may load a +different subroutine due to $AUTOLOAD changing its value. Use the glob +created via a side effect to do this. + +These functions have the same side-effects and as C with +C. C should be writable if contains C<':'> or C<' +''>. The warning against passing the GV returned by C to +C apply equally to these functions. + +=cut +*/ + GV * Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload) { @@ -301,7 +361,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload) if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) { /* ->SUPER::method should really be looked up in original stash */ SV *tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER", - HvNAME(PL_curcop->cop_stash))); + CopSTASHPV(PL_curcop))); stash = gv_stashpvn(SvPVX(tmpstr), SvCUR(tmpstr), TRUE); DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n", origname, HvNAME(stash), name) ); @@ -385,6 +445,17 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) return gv; } +/* +=for apidoc gv_stashpv + +Returns a pointer to the stash for a specified package. C should +be a valid UTF-8 string. If C is set then the package will be +created if it does not already exist. If C is not set and the +package does not exist then NULL is returned. + +=cut +*/ + HV* Perl_gv_stashpv(pTHX_ const char *name, I32 create) { @@ -420,6 +491,15 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create) return stash; } +/* +=for apidoc gv_stashsv + +Returns a pointer to the stash for a specified package, which must be a +valid UTF-8 string. See C. + +=cut +*/ + HV* Perl_gv_stashsv(pTHX_ SV *sv, I32 create) { @@ -440,14 +520,13 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) I32 len; register const char *namend; HV *stash = 0; - U32 add_gvflags = 0; if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */ name++; for (namend = name; *namend; namend++) { - if ((*namend == '\'' && namend[1]) || - (*namend == ':' && namend[1] == ':')) + if ((*namend == ':' && namend[1] == ':') + || (*namend == '\'' && namend[1])) { if (!stash) stash = PL_defstash; @@ -502,9 +581,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) /* No stash in name, so see how we can default */ if (!stash) { - if (isIDFIRST(*name) - || (IN_UTF8 && ((*name & 0xc0) == 0xc0) && isIDFIRST_utf8((U8*)name))) - { + if (isIDFIRST_lazy(name)) { bool global = FALSE; if (isUPPER(*name)) { @@ -544,22 +621,22 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) { stash = 0; } - else if (sv_type == SVt_PV && !GvIMPORTED_SV(*gvp) || - sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp) || - sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp) ) + else if ((sv_type == SVt_PV && !GvIMPORTED_SV(*gvp)) || + (sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp)) || + (sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp)) ) { Perl_warn(aTHX_ "Variable \"%c%s\" is not imported", sv_type == SVt_PVAV ? '@' : sv_type == SVt_PVHV ? '%' : '$', name); if (GvCVu(*gvp)) - Perl_warn(aTHX_ "(Did you mean &%s instead?)\n", name); + Perl_warn(aTHX_ "\t(Did you mean &%s instead?)\n", name); stash = 0; } } } else - stash = PL_curcop->cop_stash; + stash = CopSTASH(PL_curcop); } else stash = PL_defstash; @@ -568,26 +645,17 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) /* By this point we should have a stash and a name */ if (!stash) { - if (!add) - return Nullgv; - { - char sv_type_char = ((sv_type == SVt_PV) ? '$' - : (sv_type == SVt_PVAV) ? '@' - : (sv_type == SVt_PVHV) ? '%' - : 0); - if (sv_type_char) - Perl_warn(aTHX_ "Global symbol \"%c%s\" requires explicit package name", - sv_type_char, name); - else - Perl_warn(aTHX_ "Global symbol \"%s\" requires explicit package name", - name); + if (add) { + qerror(Perl_mess(aTHX_ + "Global symbol \"%s%s\" requires explicit package name", + (sv_type == SVt_PV ? "$" + : sv_type == SVt_PVAV ? "@" + : sv_type == SVt_PVHV ? "%" + : ""), name)); + stash = PL_nullstash; } - ++PL_error_count; - stash = PL_curstash ? PL_curstash : PL_defstash; /* avoid core dumps */ - add_gvflags = ((sv_type == SVt_PV) ? GVf_IMPORTED_SV - : (sv_type == SVt_PVAV) ? GVf_IMPORTED_AV - : (sv_type == SVt_PVHV) ? GVf_IMPORTED_HV - : 0); + else + return Nullgv; } if (!SvREFCNT(stash)) /* symbol table under destruction */ @@ -609,11 +677,13 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) /* Adding a new symbol */ - if (add & GV_ADDWARN) - Perl_warn(aTHX_ "Had to create %s unexpectedly", nambeg); + if (add & GV_ADDWARN && ckWARN_d(WARN_INTERNAL)) + Perl_warner(aTHX_ WARN_INTERNAL, "Had to create %s unexpectedly", nambeg); gv_init(gv, stash, name, len, add & GV_ADDMULTI); gv_init_sv(gv, sv_type); - GvFLAGS(gv) |= add_gvflags; + + if (isLEXWARN_on && isALPHA(name[0]) && ! ckWARN(WARN_ONCE)) + GvMULTI_on(gv) ; /* set up magic where warranted */ switch (*name) { @@ -660,39 +730,44 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) if (strEQ(name, "SIG")) { HV *hv; I32 i; - PL_siggv = gv; - GvMULTI_on(PL_siggv); - hv = GvHVn(PL_siggv); - hv_magic(hv, PL_siggv, 'S'); - for(i=1;PL_sig_name[i];i++) { + if (!PL_psig_ptr) { + int sig_num[] = { SIG_NUM }; + New(73, PL_psig_ptr, sizeof(sig_num)/sizeof(*sig_num), SV*); + New(73, PL_psig_name, sizeof(sig_num)/sizeof(*sig_num), SV*); + } + GvMULTI_on(gv); + hv = GvHVn(gv); + hv_magic(hv, gv, 'S'); + for (i = 1; PL_sig_name[i]; i++) { SV ** init; - init=hv_fetch(hv,PL_sig_name[i],strlen(PL_sig_name[i]),1); - if(init) - sv_setsv(*init,&PL_sv_undef); + init = hv_fetch(hv, PL_sig_name[i], strlen(PL_sig_name[i]), 1); + if (init) + sv_setsv(*init, &PL_sv_undef); PL_psig_ptr[i] = 0; PL_psig_name[i] = 0; } } break; + case 'V': + if (strEQ(name, "VERSION")) + GvMULTI_on(gv); + break; case '&': if (len > 1) break; - PL_ampergv = gv; PL_sawampersand = TRUE; goto ro_magicalize; case '`': if (len > 1) break; - PL_leftgv = gv; PL_sawampersand = TRUE; goto ro_magicalize; case '\'': if (len > 1) break; - PL_rightgv = gv; PL_sawampersand = TRUE; goto ro_magicalize; @@ -715,7 +790,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) break; if (sv_type > SVt_PV && PL_curcop != &PL_compiling) { HV* stash = gv_stashpvn("Errno",5,FALSE); - if(!stash || !(gv_fetchmethod(stash, "TIEHASH"))) { + if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) { dSP; PUTBACK; require_pv("Errno.pm"); @@ -753,25 +828,28 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) case '\\': case '/': case '|': - case '\001': - case '\002': - case '\003': - case '\004': - case '\005': - case '\006': - case '\010': - case '\011': /* NOT \t in EBCDIC */ - case '\017': - case '\020': - case '\024': - case '\027': + case '\001': /* $^A */ + case '\003': /* $^C */ + case '\004': /* $^D */ + case '\005': /* $^E */ + case '\006': /* $^F */ + case '\010': /* $^H */ + case '\011': /* $^I, NOT \t in EBCDIC */ + case '\017': /* $^O */ + case '\020': /* $^P */ + case '\024': /* $^T */ if (len > 1) break; goto magicalize; - case '\023': + case '\023': /* $^S */ if (len > 1) break; goto ro_magicalize; + case '\027': /* $^W & $^WARNING_BITS */ + if (len > 1 && strNE(name, "\027ARNING_BITS") + && strNE(name, "\027IDE_SYSTEM_CALLS")) + break; + goto magicalize; case '+': if (len > 1) @@ -796,7 +874,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) sv_magic(GvSV(gv), (SV*)gv, 0, name, len); break; - case '\014': + case '\014': /* $^L */ if (len > 1) break; sv_setpv(GvSV(gv),"\f"); @@ -811,11 +889,19 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) if (len == 1) { SV *sv = GvSV(gv); (void)SvUPGRADE(sv, SVt_PVNV); - sv_setpv(sv, PL_patchlevel); - (void)sv_2nv(sv); + SvNVX(sv) = SvNVX(PL_patchlevel); + SvNOK_on(sv); + (void)SvPV_nolen(sv); SvREADONLY_on(sv); } break; + case '\026': /* $^V */ + if (len == 1) { + SV *sv = GvSV(gv); + GvSV(gv) = SvREFCNT_inc(PL_patchlevel); + SvREFCNT_dec(sv); + } + break; } return gv; } @@ -825,7 +911,7 @@ Perl_gv_fullname3(pTHX_ SV *sv, GV *gv, const char *prefix) { HV *hv = GvSTASH(gv); if (!hv) { - SvOK_off(sv); + (void)SvOK_off(sv); return; } sv_setpv(sv, prefix ? prefix : ""); @@ -884,7 +970,6 @@ Perl_gv_check(pTHX_ HV *stash) register I32 i; register GV *gv; HV *hv; - GV *filegv; if (!HvARRAY(stash)) return; @@ -897,14 +982,25 @@ Perl_gv_check(pTHX_ HV *stash) gv_check(hv); /* nested package */ } else if (isALPHA(*HeKEY(entry))) { + char *file; gv = (GV*)HeVAL(entry); if (SvTYPE(gv) != SVt_PVGV || GvMULTI(gv)) continue; - PL_curcop->cop_line = GvLINE(gv); - filegv = GvFILEGV(gv); - PL_curcop->cop_filegv = filegv; - if (filegv && GvMULTI(filegv)) /* Filename began with slash */ + file = GvFILE(gv); + /* performance hack: if filename is absolute and it's a standard + * module, don't bother warning */ + if (file + && PERL_FILE_IS_ABSOLUTE(file) + && (instr(file, "/lib/") || instr(file, ".pm"))) + { continue; + } + CopLINE_set(PL_curcop, GvLINE(gv)); +#ifdef USE_ITHREADS + CopFILE(PL_curcop) = file; /* set for warning */ +#else + CopFILEGV(PL_curcop) = gv_fetchfile(file); +#endif Perl_warner(aTHX_ WARN_ONCE, "Name \"%s::%s\" used only once: possible typo", HvNAME(stash), GvNAME(gv)); @@ -925,6 +1021,8 @@ Perl_newGVgen(pTHX_ char *pack) GP* Perl_gp_ref(pTHX_ GP *gp) { + if (!gp) + return (GP*)NULL; gp->gp_refcnt++; if (gp->gp_cv) { if (gp->gp_cvgen) { @@ -944,13 +1042,15 @@ Perl_gp_ref(pTHX_ GP *gp) void Perl_gp_free(pTHX_ GV *gv) { + dTHR; GP* gp; - CV* cv; if (!gv || !(gp = GvGP(gv))) return; if (gp->gp_refcnt == 0) { - Perl_warn(aTHX_ "Attempt to free unreferenced glob pointers"); + if (ckWARN_d(WARN_INTERNAL)) + Perl_warner(aTHX_ WARN_INTERNAL, + "Attempt to free unreferenced glob pointers"); return; } if (gp->gp_cv) { @@ -1003,15 +1103,17 @@ register GV *gv; bool Perl_Gv_AMupdate(pTHX_ HV *stash) { - dTHR; - GV** gvp; - HV* hv; + dTHR; GV* gv; CV* cv; MAGIC* mg=mg_find((SV*)stash,'c'); AMT *amtp = (mg) ? (AMT*)mg->mg_ptr: (AMT *) NULL; AMT amt; STRLEN n_a; +#ifdef OVERLOAD_VIA_HASH + GV** gvp; + HV* hv; +#endif if (mg && amtp->was_ok_am == PL_amagic_generation && amtp->was_ok_sub == PL_sub_generation) @@ -1092,18 +1194,21 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) int i; const char *cp; SV* sv = NULL; - SV** svp; /* Work with "fallback" key, which we assume to be first in PL_AMG_names */ - if ( cp = PL_AMG_names[0] ) { + if ((cp = PL_AMG_names[0])) { /* Try to find via inheritance. */ gv = gv_fetchmeth(stash, "()", 2, -1); /* A cookie: "()". */ - if (gv) sv = GvSV(gv); - - if (!gv) goto no_table; - else if (SvTRUE(sv)) amt.fallback=AMGfallYES; - else if (SvOK(sv)) amt.fallback=AMGfallNEVER; + if (gv) + sv = GvSV(gv); + + if (!gv) + goto no_table; + else if (SvTRUE(sv)) + amt.fallback=AMGfallYES; + else if (SvOK(sv)) + amt.fallback=AMGfallNEVER; } for (i = 1; i < NofAMmeth; i++) { @@ -1259,7 +1364,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) } break; case neg_amg: - if (cv = cvp[off=subtr_amg]) { + if ((cv = cvp[off=subtr_amg])) { right = left; left = sv_2mortal(newSViv(0)); lr = 1; @@ -1348,7 +1453,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) if (amtp && amtp->fallback >= AMGfallYES) { DEBUG_o( Perl_deb(aTHX_ "%s", SvPVX(msg)) ); } else { - Perl_croak(aTHX_ "%_", msg); + Perl_croak(aTHX_ "%"SVf, msg); } return NULL; } @@ -1427,7 +1532,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) PUSHs((SV*)cv); PUTBACK; - if (PL_op = Perl_pp_entersub(aTHX)) + if ((PL_op = Perl_pp_entersub(aTHX))) CALLRUNOPS(aTHX); LEAVE; SPAGAIN; @@ -1462,7 +1567,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) case dec_amg: SvSetSV(left,res); return left; case not_amg: - ans=!SvOK(res); break; + ans=!SvTRUE(res); break; } return boolSV(ans); } else if (method==copy_amg) { @@ -1475,3 +1580,110 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) } } } + +/* +=for apidoc is_gv_magical + +Returns C if given the name of a magical GV. + +Currently only useful internally when determining if a GV should be +created even in rvalue contexts. + +C is not used at present but available for future extension to +allow selecting particular classes of magical variable. + +=cut +*/ +bool +Perl_is_gv_magical(pTHX_ char *name, STRLEN len, U32 flags) +{ + if (!len) + return FALSE; + + switch (*name) { + case 'I': + if (len == 3 && strEQ(name, "ISA")) + goto yes; + break; + case 'O': + if (len == 8 && strEQ(name, "OVERLOAD")) + goto yes; + break; + case 'S': + if (len == 3 && strEQ(name, "SIG")) + goto yes; + break; + case '\027': /* $^W & $^WARNING_BITS */ + if (len == 1 + || (len == 12 && strEQ(name, "\027ARNING_BITS")) + || (len == 17 && strEQ(name, "\027IDE_SYSTEM_CALLS"))) + { + goto yes; + } + break; + + case '&': + case '`': + case '\'': + case ':': + case '?': + case '!': + case '-': + case '#': + case '*': + case '[': + case '^': + case '~': + case '=': + case '%': + case '.': + case '(': + case ')': + case '<': + case '>': + case ',': + case '\\': + case '/': + case '|': + case '+': + case ';': + case ']': + case '\001': /* $^A */ + case '\003': /* $^C */ + case '\004': /* $^D */ + case '\005': /* $^E */ + case '\006': /* $^F */ + case '\010': /* $^H */ + case '\011': /* $^I, NOT \t in EBCDIC */ + case '\014': /* $^L */ + case '\017': /* $^O */ + case '\020': /* $^P */ + case '\023': /* $^S */ + case '\024': /* $^T */ + case '\026': /* $^V */ + if (len == 1) + goto yes; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (len > 1) { + char *end = name + len; + while (--end > name) { + if (!isDIGIT(*end)) + return FALSE; + } + } + yes: + return TRUE; + default: + break; + } + return FALSE; +}