Skip to content

Commit

Permalink
remove PERL_STRICT_CR
Browse files Browse the repository at this point in the history
Background:
-----------

Before perl 5.004, the perl parser would skip over CR (carriage return)
between tokens in source files, treating it as whitespace, but would
retain CRs in quoted constructs such as multi-line strings and
here-documents.

In 5.004, the behavior was changed to make CR in source files a fatal
error ("Illegal character %s (carriage return)") to avoid surprises with
unexpected literal CRs in string constants when scripts were copied from
DOS/Windows without newline conversion.

In 5.005, the behavior changed again. Now CR was back to being ignored,
but harder: Even in quoted constructs, CR was ignored when immediately
followed by a newline. However, the 5.004 behavior could be restored by
compiling perl with the `PERL_STRICT_CR` macro defined (e.g. with
`./Configure -A ccflags=-DPERL_STRICT_CR ...`). This option was
undocumented except for a brief note in perl5005delta. (Also, the
"Illegal character ..." error was changed to a warning, but perldiag
wasn't updated and so still listed the message as "fatal" (F).)

And that's how things have been ever since 1998.

Foreground:
-----------

This patch removes all checks for PERL_STRICT_CR entirely, treating it
as always off.

Rationale: It simplifies the code and reduces clutter. (Plus I don't see
the need to perpetually maintain an undocumented configuration option
that enables compatibility with an ancient perl version used sometime
around 1997-1998.)

References:
-----------

- 4fdae80 ("Make \r in script an error (per Larry)")
- ff0cee6 ("Fix carriage-return message")
- 5431012 ("Improve diagnostic on \r in program text")
- 2db4f57
- f63a84b
- 637e912
- b8957cf
- 6a27c18
  • Loading branch information
mauke committed Nov 24, 2024
1 parent f0e1638 commit 94caec9
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 44 deletions.
4 changes: 0 additions & 4 deletions perl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2231,9 +2231,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
reswitch:
switch ((c = *s)) {
case 'C':
#ifndef PERL_STRICT_CR
case '\r':
#endif
case ' ':
case '0':
case 'F':
Expand Down Expand Up @@ -3955,9 +3953,7 @@ Perl_moreswitches(pTHX_ const char *s)
break;
case '-':
case 0:
#if defined(WIN32) || !defined(PERL_STRICT_CR)
case '\r':
#endif
case '\n':
case '\t':
break;
Expand Down
14 changes: 14 additions & 0 deletions pod/perldelta.pod
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,20 @@ L</Platform Support> section, instead.

XXX

=item *

The (mostly undocumented) configuration macro C<PERL_STRICT_CR> has been
removed. When enabled (e.g. with C<./Configure -A ccflags=-DPERL_STRICT_CR>),
it would make the perl parser throw a fatal error when it encountered a CR
(carriage return) character in source files. The default (and now only)
behavior of the perl parser is to strip CRs paired with newline characters and
otherwise treat them as whitespace.

(C<PERL_STRICT_CR> was originally introduced in perl 5.005 to optionally
restore backward compatibility with perl 5.004, which had made CR in source
files an error. Before that, CR was accepted, but retained literally in quoted
multi-line constructs such as here-documents, even at the end of a line.)

=back

=head1 Testing
Expand Down
8 changes: 0 additions & 8 deletions pod/perldiag.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2889,14 +2889,6 @@ declaration. The '_' in a prototype must be followed by a ';',
indicating the rest of the parameters are optional, or one of '@'
or '%', since those two will accept 0 or more final parameters.

=item Illegal character \%o (carriage return)

(F) Perl normally treats carriage returns in the program text as
it would any other whitespace, which means you should never see
this error when Perl was built using standard options. For some
reason, your version of Perl appears to have been built without
this support. Talk to your Perl administrator.

=item Illegal character following sigil in a subroutine signature

(F) A parameter in a subroutine signature contained an unexpected character
Expand Down
3 changes: 0 additions & 3 deletions t/porting/diag.t
Original file line number Diff line number Diff line change
Expand Up @@ -740,9 +740,6 @@ Wrong syntax (suid) fd script name "%s"
__CATEGORIES__
# This is a warning, but is currently followed immediately by a croak (toke.c)
Illegal character \%o (carriage return)
# Because uses WARN_MISSING as a synonym for WARN_UNINITIALIZED (sv.c)
Missing argument in %s
Expand Down
31 changes: 2 additions & 29 deletions toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -9244,13 +9244,7 @@ yyl_try(pTHX_ char *s)
return tok;
goto retry_bufptr;

case '\r':
#ifdef PERL_STRICT_CR
Perl_warn(aTHX_ "Illegal character \\%03o (carriage return)", '\r');
Perl_croak(aTHX_
"\t(Maybe you didn't strip carriage returns after a network transfer?)\n");
#endif
case ' ': case '\t': case '\f': case '\v':
case ' ': case '\t': case '\f': case '\r': case '\v':
s++;
goto retry;

Expand Down Expand Up @@ -9394,11 +9388,7 @@ yyl_try(pTHX_ char *s)
}
if (PL_expect == XBLOCK) {
const char *t = s;
while (SPACE_OR_TAB(*t)
#ifndef PERL_STRICT_CR
|| *t == '\r'
#endif
)
while (SPACE_OR_TAB(*t) || *t == '\r')
t++;
if (*t == '\n' || *t == '#') {
ENTER_with_name("lex_format");
Expand Down Expand Up @@ -9460,11 +9450,7 @@ yyl_try(pTHX_ char *s)

case '.':
if (PL_lex_formbrack && PL_lex_brackets == PL_lex_formbrack
#ifdef PERL_STRICT_CR
&& s[1] == '\n'
#else
&& (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))
#endif
&& (s == PL_linestart || s[-1] == '\n') )
{
PL_expect = XSTATE;
Expand Down Expand Up @@ -11016,7 +11002,6 @@ S_scan_heredoc(pTHX_ char *s)
*d = '\0';
len = d - PL_tokenbuf;

#ifndef PERL_STRICT_CR
d = (char *) memchr(s, '\r', PL_bufend - s);
if (d) {
char * const olds = s;
Expand All @@ -11039,7 +11024,6 @@ S_scan_heredoc(pTHX_ char *s)
SvCUR_set(PL_linestr, PL_bufend - SvPVX_const(PL_linestr));
s = olds;
}
#endif

tmpstr = newSV_type(SVt_PVIV);
if (term == '\'') {
Expand Down Expand Up @@ -11245,7 +11229,6 @@ S_scan_heredoc(pTHX_ char *s)
PL_parser->herelines++;
PL_last_lop = PL_last_uni = NULL;

#ifndef PERL_STRICT_CR
if (PL_bufend - PL_linestart >= 2) {
if ( (PL_bufend[-2] == '\r' && PL_bufend[-1] == '\n')
|| (PL_bufend[-2] == '\n' && PL_bufend[-1] == '\r'))
Expand All @@ -11259,7 +11242,6 @@ S_scan_heredoc(pTHX_ char *s)
}
else if (PL_bufend - PL_linestart == 1 && PL_bufend[-1] == '\r')
PL_bufend[-1] = '\n';
#endif

if (indented && (PL_bufend-s) >= len) {
char * found = ninstr(s, PL_bufend, (PL_tokenbuf + 1), (PL_tokenbuf +1 + len));
Expand Down Expand Up @@ -11852,7 +11834,6 @@ Perl_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int
if (s < PL_bufend)
break; /* handle case where we are done yet :-) */

#ifndef PERL_STRICT_CR
if (to - SvPVX_const(sv) >= 2) {
if ( (to[-2] == '\r' && to[-1] == '\n')
|| (to[-2] == '\n' && to[-1] == '\r'))
Expand All @@ -11866,7 +11847,6 @@ Perl_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int
}
else if (to - SvPVX_const(sv) == 1 && to[-1] == '\r')
to[-1] = '\n';
#endif

/* if we're out of file, or a read fails, bail and reset the current
line marker so we can report where the unterminated string began
Expand Down Expand Up @@ -12611,13 +12591,8 @@ S_scan_formline(pTHX_ char *s)
char *eol;
if (*s == '.') {
char *t = s+1;
#ifdef PERL_STRICT_CR
while (SPACE_OR_TAB(*t))
t++;
#else
while (SPACE_OR_TAB(*t) || *t == '\r')
t++;
#endif
if (*t == '\n' || t == PL_bufend) {
eofmt = TRUE;
break;
Expand All @@ -12642,14 +12617,12 @@ S_scan_formline(pTHX_ char *s)
}
if (eol > s) {
sv_catpvn(stuff, s, eol-s);
#ifndef PERL_STRICT_CR
if (eol-s > 1 && eol[-2] == '\r' && eol[-1] == '\n') {
char *end = SvPVX(stuff) + SvCUR(stuff);
end[-2] = '\n';
end[-1] = '\0';
SvCUR_set(stuff, SvCUR(stuff) - 1);
}
#endif
}
else
break;
Expand Down

0 comments on commit 94caec9

Please sign in to comment.