Skip to content

Commit

Permalink
Implement the fc keyword and the \F string escape.
Browse files Browse the repository at this point in the history
Along with the simple_casefolding and full_casefolding features.

fc() stands for foldcase, a sort of pseudo case (like lowercase),
which is used to implement Unicode casefolding. It maps a string
to a form where all case differences are erased, so it's a
locale-independent way of checking if two strings are the same,
regardless of case.

This functionality was, and still is, available through the
regular expression engine -- /i matches would use casefolding
internally. The fc keyword merely exposes this for easier access.

Previously, one could attempt to case-insensitively test two strings
for equality by doing

   lc($a) eq lc($b)

But that might get you wrong results, for example in the case of
\x{DF}, LATIN SMALL LETTER SHARP S.
  • Loading branch information
Hugmeir authored and Karl Williamson committed Jan 29, 2012
1 parent 2a4315f commit 838f228
Show file tree
Hide file tree
Showing 18 changed files with 815 additions and 214 deletions.
10 changes: 8 additions & 2 deletions dist/B-Deparse/Deparse.pm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
CVf_METHOD CVf_LVALUE
PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED);
$VERSION = "1.11";
$VERSION = "1.12";
use strict;
use vars qw/$AUTOLOAD/;
use warnings ();
Expand Down Expand Up @@ -1674,6 +1674,7 @@ my %feature_keywords = (
break => 'switch',
evalbytes=>'evalbytes',
__SUB__ => '__SUB__',
fc => 'fc',
);

sub keyword {
Expand Down Expand Up @@ -2147,6 +2148,7 @@ sub pp_lcfirst { dq_unop(@_, "lcfirst") }
sub pp_uc { dq_unop(@_, "uc") }
sub pp_lc { dq_unop(@_, "lc") }
sub pp_quotemeta { maybe_targmy(@_, \&dq_unop, "quotemeta") }
sub pp_fc { dq_unop(@_, "fc") }

sub loopex {
my $self = shift;
Expand Down Expand Up @@ -4116,6 +4118,8 @@ sub dq {
return '\l' . $self->dq($op->first->sibling);
} elsif ($type eq "quotemeta") {
return '\Q' . $self->dq($op->first->sibling) . '\E';
} elsif ($type eq "fc") {
return '\F' . $self->dq($op->first->sibling) . '\E';
} elsif ($type eq "join") {
return $self->deparse($op->last, 26); # was join($", @ary)
} else {
Expand Down Expand Up @@ -4437,6 +4441,8 @@ sub re_dq {
return '\l' . $self->re_dq($op->first->sibling, $extended);
} elsif ($type eq "quotemeta") {
return '\Q' . $self->re_dq($op->first->sibling, $extended) . '\E';
} elsif ($type eq "fc") {
return '\F' . $self->re_dq($op->first->sibling, $extended) . '\E';
} elsif ($type eq "join") {
return $self->deparse($op->last, 26); # was join($", @ary)
} else {
Expand All @@ -4454,7 +4460,7 @@ sub pure_string {
if ($type eq 'const' || $type eq 'av2arylen') {
return 1;
}
elsif ($type =~ /^[ul]c(first)?$/ || $type eq 'quotemeta') {
elsif ($type =~ /^(?:[ul]c(first)?|fc)$/ || $type eq 'quotemeta') {
return $self->pure_string($op->first->sibling);
}
elsif ($type eq 'join') {
Expand Down
4 changes: 2 additions & 2 deletions dist/B-Deparse/t/core.t
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ my @nary = (
[qw( abs alarm break chr cos chop close chdir chomp chmod chown
chroot caller continue die dump exp exit exec endgrent
endpwent endnetent endhostent endservent
endprotoent evalbytes fork glob
endprotoent evalbytes fc fork glob
getppid getpwent getprotoent gethostent getnetent getservent
getgrent getlogin getc gmtime hex int lc log lstat length
lcfirst localtime mkdir ord oct pop quotemeta ref rand
Expand All @@ -31,7 +31,7 @@ my @nary = (
# unary
[qw( abs alarm bless binmode chr cos chop close chdir chomp
chmod chown chroot closedir die do dump exp exit exec
each evalbytes fileno getpgrp getpwnam getpwuid getpeername
each evalbytes fc fileno getpgrp getpwnam getpwuid getpeername
getprotobyname getprotobynumber gethostbyname
getnetbyname getsockname getgrnam getgrgid
getc glob gmtime hex int join keys kill lc
Expand Down
1 change: 1 addition & 0 deletions dist/B-Deparse/t/deparse.t
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@ CORE::given ($x) {
}
CORE::evalbytes '';
() = CORE::__SUB__;
() = CORE::fc $x;
####
# feature features when feature has been disabled by use VERSION
use feature (sprintf(":%vd", $^V));
Expand Down
4 changes: 2 additions & 2 deletions ext/Opcode/Opcode.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use strict;

our($VERSION, @ISA, @EXPORT_OK);

$VERSION = "1.22";
$VERSION = "1.23";

use Carp;
use Exporter ();
Expand Down Expand Up @@ -325,7 +325,7 @@ invert_opset function.
substr vec stringify study pos length index rindex ord chr
ucfirst lcfirst uc lc quotemeta trans transr chop schop chomp schomp
ucfirst lcfirst uc lc fc quotemeta trans transr chop schop chomp schomp
match split qr
Expand Down
12 changes: 10 additions & 2 deletions keywords.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)
goto unknown;
}

case 2: /* 18 tokens of length 2 */
case 2: /* 19 tokens of length 2 */
switch (name[0])
{
case 'd':
Expand All @@ -70,6 +70,14 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)

goto unknown;

case 'f':
if (name[1] == 'c')
{ /* fc */
return (all_keywords || FEATURE_FC_IS_ENABLED ? -KEY_fc : 0);
}

goto unknown;

case 'g':
switch (name[1])
{
Expand Down Expand Up @@ -3441,5 +3449,5 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)
}

/* Generated from:
* 29732a698b229f9e5f475fbb191f71c335c9e8d05b6168fe29e61c34c4f10bd2 regen/keywords.pl
* e5a540774760ea54c761ef17ee4a153cc264e9a700b817d561e390730c457406 regen/keywords.pl
* ex: set ro: */
Loading

0 comments on commit 838f228

Please sign in to comment.