warn on C<my($foo,$foo)>
[p5sagit/p5-mst-13.2.git] / util.c
diff --git a/util.c b/util.c
index 13590c0..5be4969 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1408,6 +1408,94 @@ warn(const char* pat,...)
     (void)PerlIO_flush(PerlIO_stderr());
 }
 
+void
+warner(U32  err, const char* pat,...)
+{
+    dTHR;
+    va_list args;
+    char *message;
+    HV *stash;
+    GV *gv;
+    CV *cv;
+
+    va_start(args, pat);
+    message = mess(pat, &args);
+    va_end(args);
+
+    if (ckDEAD(err)) {
+#ifdef USE_THREADS
+        DEBUG_S(PerlIO_printf(PerlIO_stderr(), "croak: 0x%lx %s", (unsigned long) thr, message));
+#endif /* USE_THREADS */
+        if (PL_diehook) {
+            /* sv_2cv might call croak() */
+            SV *olddiehook = PL_diehook;
+            ENTER;
+            SAVESPTR(PL_diehook);
+            PL_diehook = Nullsv;
+            cv = sv_2cv(olddiehook, &stash, &gv, 0);
+            LEAVE;
+            if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) {
+                dSP;
+                SV *msg;
+                ENTER;
+                msg = newSVpv(message, 0);
+                SvREADONLY_on(msg);
+                SAVEFREESV(msg);
+                PUSHMARK(sp);
+                XPUSHs(msg);
+                PUTBACK;
+                perl_call_sv((SV*)cv, G_DISCARD);
+                LEAVE;
+            }
+        }
+        if (PL_in_eval) {
+            PL_restartop = die_where(message);
+            JMPENV_JUMP(3);
+        }
+        PerlIO_puts(PerlIO_stderr(),message);
+        (void)PerlIO_flush(PerlIO_stderr());
+        my_failure_exit();
+
+    }
+    else {
+        if (PL_warnhook) {
+            /* sv_2cv might call warn() */
+            dTHR;
+            SV *oldwarnhook = PL_warnhook;
+            ENTER;
+            SAVESPTR(PL_warnhook);
+            PL_warnhook = Nullsv;
+            cv = sv_2cv(oldwarnhook, &stash, &gv, 0);
+                LEAVE;
+            if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) {
+                dSP;
+                SV *msg;
+                ENTER;
+                msg = newSVpv(message, 0);
+                SvREADONLY_on(msg);
+                SAVEFREESV(msg);
+                PUSHMARK(sp);
+                XPUSHs(msg);
+                PUTBACK;
+                perl_call_sv((SV*)cv, G_DISCARD);
+                LEAVE;
+                return;
+            }
+        }
+        PerlIO_puts(PerlIO_stderr(),message);
+#ifdef LEAKTEST
+        DEBUG_L(xstat());
+#endif
+        (void)PerlIO_flush(PerlIO_stderr());
+    }
+}
+
 #ifndef VMS  /* VMS' my_setenv() is in VMS.c */
 #ifndef WIN32
 void
@@ -2342,8 +2430,11 @@ scan_oct(char *start, I32 len, I32 *retlen)
        retval = n | (*s++ - '0');
        len--;
     }
-    if (PL_dowarn && len && (*s == '8' || *s == '9'))
-       warn("Illegal octal digit ignored");
+    if (len && (*s == '8' || *s == '9')) {
+       dTHR;
+       if (ckWARN(WARN_OCTAL))
+           warner(WARN_OCTAL, "Illegal octal digit ignored");
+    }
     *retlen = s - start;
     return retval;
 }
@@ -2355,18 +2446,27 @@ scan_hex(char *start, I32 len, I32 *retlen)
     register UV retval = 0;
     bool overflowed = FALSE;
     char *tmp = s;
+    register UV n;
 
-    while (len-- && *s && (tmp = strchr((char *) PL_hexdigit, *s))) {
-       register UV n = retval << 4;
+    while (len-- && *s) {
+       tmp = strchr((char *) PL_hexdigit, *s++);
+       if (!tmp) {
+           if (*s == '_')
+               continue;
+           else {
+               dTHR;
+               --s;
+               if (ckWARN(WARN_UNSAFE))
+                   warner(WARN_UNSAFE,"Illegal hex digit ignored");
+               break;
+           }
+       }
+       n = retval << 4;
        if (!overflowed && (n >> 4) != retval) {
            warn("Integer overflow in hex number");
            overflowed = TRUE;
        }
        retval = n | ((tmp - PL_hexdigit) & 15);
-       s++;
-    }
-    if (PL_dowarn && !tmp) {
-       warn("Illegal hex digit ignored");
     }
     *retlen = s - start;
     return retval;