summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doio.c2
-rw-r--r--ext/DynaLoader/dlutils.c2
-rw-r--r--locale.c3
-rw-r--r--malloc.c4
-rw-r--r--perl.c24
-rw-r--r--pp_sys.c2
-rw-r--r--regcomp.c51
-rw-r--r--toke.c2
-rw-r--r--util.c24
9 files changed, 69 insertions, 45 deletions
diff --git a/doio.c b/doio.c
index 46d07966a6..a631eeb038 100644
--- a/doio.c
+++ b/doio.c
@@ -391,7 +391,7 @@ Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len,
num_svs = 0;
}
else if (isDIGIT(*type)) {
- wanted_fd = atoi(type);
+ wanted_fd = grok_atou(type, NULL);
}
else {
const IO* thatio;
diff --git a/ext/DynaLoader/dlutils.c b/ext/DynaLoader/dlutils.c
index 29d9b91784..dea981a32d 100644
--- a/ext/DynaLoader/dlutils.c
+++ b/ext/DynaLoader/dlutils.c
@@ -104,7 +104,7 @@ dl_generic_private_init(pTHX) /* called by dl_*.xs dl_private_init() */
}
#endif
if ( (perl_dl_nonlazy = getenv("PERL_DL_NONLAZY")) != NULL )
- dl_nonlazy = atoi(perl_dl_nonlazy);
+ dl_nonlazy = grok_atou(perl_dl_nonlazy, NULL);
if (dl_nonlazy)
DLDEBUG(1,PerlIO_printf(Perl_debug_log, "DynaLoader bind mode is 'non-lazy'\n"));
#ifdef DL_LOADONCEONLY
diff --git a/locale.c b/locale.c
index 85c438c685..84ff0de3bd 100644
--- a/locale.c
+++ b/locale.c
@@ -527,7 +527,8 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
char *p;
const bool locwarn = (printwarn > 1 ||
(printwarn &&
- (!(p = PerlEnv_getenv("PERL_BADLANG")) || atoi(p))));
+ (!(p = PerlEnv_getenv("PERL_BADLANG")) ||
+ grok_atou(p, NULL))));
bool done = FALSE;
#ifdef WIN32
/* In some systems you can find out the system default locale
diff --git a/malloc.c b/malloc.c
index a99663ef56..73a0480f52 100644
--- a/malloc.c
+++ b/malloc.c
@@ -1824,7 +1824,7 @@ Perl_mfree(Malloc_t where)
if (bad_free_warn == -1) {
dTHX;
char *pbf = PerlEnv_getenv("PERL_BADFREE");
- bad_free_warn = (pbf) ? atoi(pbf) : 1;
+ bad_free_warn = (pbf) ? grok_atou(pbf, NULL) : 1;
}
if (!bad_free_warn)
return;
@@ -1922,7 +1922,7 @@ Perl_realloc(void *mp, size_t nbytes)
if (bad_free_warn == -1) {
dTHX;
char *pbf = PerlEnv_getenv("PERL_BADFREE");
- bad_free_warn = (pbf) ? atoi(pbf) : 1;
+ bad_free_warn = (pbf) ? grok_atou(pbf, NULL) : 1;
}
if (!bad_free_warn)
return NULL;
diff --git a/perl.c b/perl.c
index 6e09931281..e84f1d53ae 100644
--- a/perl.c
+++ b/perl.c
@@ -546,7 +546,12 @@ perl_destruct(pTHXx)
{
const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
if (s) {
- const int i = atoi(s);
+ int i;
+ if (strEQ(s, "-1")) { /* Special case: modperl folklore. */
+ i = -1;
+ } else {
+ i = grok_atou(s, NULL);
+ }
#ifdef DEBUGGING
if (destruct_level < i) destruct_level = i;
#endif
@@ -1451,7 +1456,7 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
{
const char * const s = PerlEnv_getenv("PERL_HASH_SEED_DEBUG");
- if (s && (atoi(s) == 1)) {
+ if (s && (grok_atou(s, NULL) == 1)) {
unsigned char *seed= PERL_HASH_SEED;
unsigned char *seed_end= PERL_HASH_SEED + PERL_HASH_SEED_BYTES;
PerlIO_printf(Perl_debug_log, "HASH_FUNCTION = %s HASH_SEED = 0x", PERL_HASH_FUNC);
@@ -2285,8 +2290,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
#ifdef MYMALLOC
{
const char *s;
- if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
- dump_mstats("after compilation:");
+ if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && grok_atou(s, NULL) >= 2)
+ dump_mstats("after compilation:");
}
#endif
@@ -3042,7 +3047,10 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
}
}
else if (isDIGIT(**s)) {
- i = atoi(*s);
+ const char* e;
+ i = grok_atou(*s, &e);
+ if (e)
+ *s = e;
for (; isWORDCHAR(**s); (*s)++) ;
}
else if (givehelp) {
@@ -3650,9 +3658,9 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript)
if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
const char *s = scriptname + 8;
- fdscript = atoi(s);
- while (isDIGIT(*s))
- s++;
+ const char* e;
+ fdscript = grok_atou(s, &e);
+ s = e;
if (*s) {
/* PSz 18 Feb 04
* Tell apart "normal" usage of fdscript, e.g.
diff --git a/pp_sys.c b/pp_sys.c
index 54c12b30f1..501146e3c6 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3295,7 +3295,7 @@ PP(pp_fttty)
if (GvIO(gv) && IoIFP(GvIOp(gv)))
fd = PerlIO_fileno(IoIFP(GvIOp(gv)));
else if (name && isDIGIT(*name))
- fd = atoi(name);
+ fd = grok_atou(name, NULL);
else
FT_RETURNUNDEF;
if (fd < 0) {
diff --git a/regcomp.c b/regcomp.c
index 3d4d3482a8..0f70a9e5f9 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -9605,6 +9605,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
else if (*RExC_parse == '?') { /* (?...) */
bool is_logical = 0;
const char * const seqstart = RExC_parse;
+ const char * endptr;
if (has_intervening_patws) {
RExC_parse++;
vFAIL("In '(?...)', the '(' and '?' must be adjacent");
@@ -9814,12 +9815,21 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
case '5': case '6': case '7': case '8': case '9':
RExC_parse--;
parse_recursion:
- num = atoi(RExC_parse);
- parse_start = RExC_parse - 1; /* MJD */
- if (*RExC_parse == '-')
- RExC_parse++;
- while (isDIGIT(*RExC_parse))
- RExC_parse++;
+ {
+ bool is_neg = FALSE;
+ parse_start = RExC_parse - 1; /* MJD */
+ if (*RExC_parse == '-') {
+ RExC_parse++;
+ is_neg = TRUE;
+ }
+ num = grok_atou(RExC_parse, &endptr);
+ if (endptr)
+ RExC_parse = (char*)endptr;
+ if (is_neg) {
+ /* Some limit for num? */
+ num = -num;
+ }
+ }
if (*RExC_parse!=')')
vFAIL("Expecting close bracket");
@@ -9996,9 +10006,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
RExC_parse++;
parno = 0;
if (RExC_parse[0] >= '1' && RExC_parse[0] <= '9' ) {
- parno = atoi(RExC_parse++);
- while (isDIGIT(*RExC_parse))
- RExC_parse++;
+ parno = grok_atou(RExC_parse, &endptr);
+ if (endptr)
+ RExC_parse = (char*)endptr;
} else if (RExC_parse[0] == '&') {
SV *sv_dat;
RExC_parse++;
@@ -10015,10 +10025,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
/* (?(1)...) */
char c;
char *tmp;
- parno = atoi(RExC_parse++);
-
- while (isDIGIT(*RExC_parse))
- RExC_parse++;
+ parno = grok_atou(RExC_parse, &endptr);
+ if (endptr)
+ RExC_parse = (char*)endptr;
ret = reganode(pRExC_state, GROUPP, parno);
insert_if_check_paren:
@@ -10492,15 +10501,16 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
next++;
}
if (*next == '}') { /* got one */
+ const char* endptr;
if (!maxpos)
maxpos = next;
RExC_parse++;
- min = atoi(RExC_parse);
+ min = grok_atou(RExC_parse, &endptr);
if (*maxpos == ',')
maxpos++;
else
maxpos = RExC_parse;
- max = atoi(maxpos);
+ max = grok_atou(maxpos, &endptr);
if (!max && *maxpos != '0')
max = REG_INFTY; /* meaning "infinity" */
else if (max >= REG_INFTY)
@@ -11147,18 +11157,17 @@ S_alloc_maybe_populate_EXACT(pTHX_ RExC_state_t *pRExC_state,
}
-/* return atoi(p), unless it's too big to sensibly be a backref,
+/* Parse backref decimal value, unless it's too big to sensibly be a backref,
* in which case return I32_MAX (rather than possibly 32-bit wrapping) */
static I32
S_backref_value(char *p)
{
- char *q = p;
-
- for (;isDIGIT(*q); q++) {} /* calculate length of num */
- if (q - p == 0 || q - p > 9)
+ const char* endptr;
+ Size_t val = grok_atou(p, &endptr);
+ if (endptr == p || endptr == NULL || val > 999999999)
return I32_MAX;
- return atoi(p);
+ return val;
}
diff --git a/toke.c b/toke.c
index 2842115574..cb379ef6d8 100644
--- a/toke.c
+++ b/toke.c
@@ -1686,7 +1686,7 @@ S_incline(pTHX_ const char *s)
if (*e != '\n' && *e != '\0')
return; /* false alarm */
- line_num = atoi(n)-1;
+ line_num = grok_atou(n, &e) - 1;
if (t - s > 0) {
const STRLEN len = t - s;
diff --git a/util.c b/util.c
index 4b48e623d2..9c28f9e66c 100644
--- a/util.c
+++ b/util.c
@@ -1380,7 +1380,7 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
int wi;
/* The PERL_C_BACKTRACE_ON_WARN must be an integer of one or more. */
if ((ws = PerlEnv_getenv("PERL_C_BACKTRACE_ON_ERROR")) &&
- (wi = atoi(ws)) > 0) {
+ (wi = grok_atou(ws, NULL)) > 0) {
Perl_dump_c_backtrace(aTHX_ Perl_debug_log, wi, 1);
}
}
@@ -4381,9 +4381,9 @@ Perl_parse_unicode_opts(pTHX_ const char **popt)
if (*p) {
if (isDIGIT(*p)) {
- opt = (U32) atoi(p);
- while (isDIGIT(*p))
- p++;
+ const char* endptr;
+ opt = (U32) grok_atou(p, &endptr);
+ p = endptr;
if (*p && *p != '\n' && *p != '\r') {
if(isSPACE(*p)) goto the_end_of_the_opts_parser;
else
@@ -4698,7 +4698,7 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
* The default implementation reads a single env var, PERL_MEM_LOG,
* expecting one or more of the following:
*
- * \d+ - fd fd to write to : must be 1st (atoi)
+ * \d+ - fd fd to write to : must be 1st (grok_atou)
* 'm' - memlog was PERL_MEM_LOG=1
* 's' - svlog was PERL_SV_LOG=1
* 't' - timestamp was PERL_MEM_LOG_TIMESTAMP=1
@@ -4766,7 +4766,8 @@ S_mem_log_common(enum mem_log_type mlt, const UV n,
* timeval. */
{
STRLEN len;
- int fd = atoi(pmlenv);
+ const char* endptr;
+ int fd = grok_atou(pmlenv, &endptr); /* Ignore endptr. */
if (!fd)
fd = PERL_MEM_LOG_FD;
@@ -5695,12 +5696,12 @@ static void atos_update(atos_context* ctx,
/* Given an output buffer end |p| and its |start|, matches
* for the atos output, extracting the source code location
- * if possible, returning NULL otherwise. */
+ * and returning non-NULL if possible, returning NULL otherwise. */
static const char* atos_parse(const char* p,
const char* start,
STRLEN* source_name_size,
STRLEN* source_line) {
- /* atos() outputs is something like:
+ /* atos() output is something like:
* perl_parse (in miniperl) (perl.c:2314)\n\n".
* We cannot use Perl regular expressions, because we need to
* stay low-level. Therefore here we have a rolled-out version
@@ -5710,11 +5711,14 @@ static const char* atos_parse(const char* p,
* The matched regular expression is roughly "\(.*:\d+\)\s*$" */
const char* source_number_start;
const char* source_name_end;
+ const char* source_line_end;
+ const char* close_paren;
/* Skip trailing whitespace. */
while (p > start && isspace(*p)) p--;
/* Now we should be at the close paren. */
if (p == start || *p != ')')
return NULL;
+ close_paren = p;
p--;
/* Now we should be in the line number. */
if (p == start || !isdigit(*p))
@@ -5735,7 +5739,9 @@ static const char* atos_parse(const char* p,
return NULL;
p++;
*source_name_size = source_name_end - p;
- *source_line = atoi(source_number_start);
+ *source_line = grok_atou(source_number_start, &source_line_end);
+ if (source_line_end != close_paren)
+ return NULL;
return p;
}