尝试改进 Encode::decode 警告消息:$SIG{__WARN__} 处理程序中的段错误

2023-12-23

我正在尝试改进发出的警告消息Encode::decode() https://metacpan.org/pod/Encode#FB_WARN。我希望它打印正在读取的文件的名称以及在该文件中找到格式错误的数据的行号,而不是打印模块的名称和模块中的行号。对于开发人员来说,原始消息可能很有用,但对于不熟悉 Perl 的最终用户来说,它可能毫无意义。最终用户可能更想知道哪个文件出现了问题。

我首先尝试使用$SIG{__WARN__} http://perldoc.perl.org/functions/warn.html处理程序(这可能不是一个好主意),但我遇到了段错误。可能是一个愚蠢的错误,但我无法弄清楚:

#! /usr/bin/env perl

use feature qw(say);
use strict;
use warnings;

use Encode ();

binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';

my $fn = 'test.txt';
write_test_file( $fn );

# Try to improve the Encode::FB_WARN fallback warning message :
#
#   utf8 "\xE5" does not map to Unicode at <module_name> line xx
#
# Rather we would like the warning to print the filename and the line number:
#
#   utf8 "\xE5" does not map to Unicode at line xx of file <filename>.

my $str = '';
open ( my $fh, "<:encoding(utf-8)", $fn ) or die "Could not open file '$fn': $!";
{
    local $SIG{__WARN__} = sub { my_warn_handler( $fn, $_[0] ) }; 
    $str = do { local $/; <$fh> };
}
close $fh;
say "Read string: '$str'";

sub my_warn_handler {
    my ( $fn, $msg ) = @_;

    if ( $msg =~ /\Qdoes not map to Unicode\E/ ) {
        recover_line_number_and_char_pos( $fn, $msg );
    }
    else {
        warn $msg;
    }
}

sub recover_line_number_and_char_pos {
    my ( $fn, $err_msg ) = @_;

    chomp $err_msg;
    $err_msg =~ s/(line \d+)\.$/$1/;  # Remove period at end of sentence.
    open ( $fh, "<:raw", $fn ) or die "Could not open file '$fn': $!";
    my $raw_data = do { local $/; <$fh> };
    close $fh;
    my $str = Encode::decode( 'utf-8', $raw_data, Encode::FB_QUIET );
    my ($header, $last_line) = $str =~ /^(.*\n)([^\n]*)$/s; 
    my $line_no = $str =~ tr/\n//;
    ++$line_no;
    my $pos = ( length $last_line ) + 1;
    warn "$err_msg, in file '$fn' (line: $line_no, pos: $pos)\n";
}

sub write_test_file {
    my ( $fn ) = @_;

    my $bytes = "Hello\nA\x{E5}\x{61}";  # 2 lines ending in iso 8859-1: åa
    open ( my $fh, '>:raw', $fn ) or die "Could not open file '$fn': $!";
    print $fh $bytes;
    close $fh;
}

Output:

utf8 "\xE5" does not map to Unicode at ./p.pl line 27
, in file 'test.txt' (line: 2, pos: 2)
Segmentation fault (core dumped)

这是定位警告触发位置的另一种方法,使用无缓冲sysread

use warnings;
use strict;

binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';

my $file = 'test.txt';
open my $fh, "<:encoding(UTF-8)", $file or die "Can't open $file: $!";

$SIG{__WARN__} = sub { print "\t==> WARN: @_" };

my $char_cnt = 0;    
my $char;

while (sysread($fh, $char, 1)) {
    ++$char_cnt;
    print "$char ($char_cnt)\n";
}

文件test.txt是由发布的程序编写的,只是我必须添加它才能重现该行为 - 它在 v5.10 和 v5.16 上运行时没有警告。我添加了\x{234234}到最后。可以通过以下方式跟踪行号$char =~ /\n/.

The sysread回报undef出错时。它可以被移动到身体里while (1)允许读取继续并捕获所有警告,突破0(在 EOF 时返回)。

这打印



H (1)
e (2)
l (3)
l (4)
o (5)

 (6)
A (7)
å (8)
a (9)
        ==> WARN: Code point 0x234234 is not Unicode, may not be portable at ...
 (10)
  

虽然这确实捕获了警告的字符,但使用以下命令重新读取文件Encode可能比伸手去拿更好sysread,特别是如果sysread uses Encode.

然而,Perl 是utf8在内部,我不确定sysread needs Encode.

笔记。该页面为sysread http://perldoc.perl.org/functions/sysread.html支持其在具有编码层的数据上的使用

请注意,如果文件句柄已标记为:utf8统一码 读取的是字符而不是字节(LENGTH、OFFSET 和 返回值sysread是 Unicode 字符)。这:encoding(...)层隐含地引入了:utf8层。 看binmode, open,以及open pragma.


Note显然,在某个版本之后事情已经发生了变化sysread不支持编码层。上面的链接对于旧版本(其中一个是 v5.10)确实显示了引用的内容,而新版本则告诉我们会有例外。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试改进 Encode::decode 警告消息:$SIG{__WARN__} 处理程序中的段错误 的相关文章

  • 如何在 BEGIN 块之外正确声明哈希?

    考虑这个简单的程序 您能解释一下为什么在取消注释前两行后输出会有所不同吗 我的哈希发生了什么use strict 如何修复程序以供使用use strict echo e key1 nkey2 nkey3 perl lne use stric
  • Perl 单元测试只针对模块,而不针对程序吗?

    我在网上找到的文档和我拥有的书 Perl测试 或者说或者建议 Perl 的单元测试通常是在创建模块时完成的 这是真的 有没有办法使用单元测试实际程序Test More和表兄弟姐妹 当然 您可以使用测试脚本测试 更多 http search
  • Moose:属性值更改时缓存的计算结果会过期吗?

    在我们的类中 我们有一个模式 我们创建一个属性来表示 计算值 出于显而易见的原因 我们想要缓存计算值 然后当基础值之一发生变化时使缓存失效 所以我们目前有这个 package FooBar use Moose has foo gt acce
  • 如何在 perl 程序中查找打开的全局文件句柄

    我刚刚发现一个问题 我必须关闭所有打开的文件句柄才能让我的 Apache cgi 脚本继续 我将问题追溯到 Parse RecDescent usr bin env perl use strict use warnings use feat
  • 如何在调试器模式下运行 perl 测试?

    我尝试在调试器下运行测试 perl d which prove t file t 但这没有任何效果 因为每个测试都是作为单独的作业运行的 我已经发现 exec选项 但是当我提供它时 我失去了任何选项 proverc文件和命令行 prove
  • 在 FOR 循环中打印唯一值

    我有两个文件 myresult 和 annotation 两个文件中的数据似乎是范围 但事实并非如此 这就是为什么我无法将其存储在数组中 我需要使用拆分运算符 以便我可以在 for 循环中使用它并进行比较 现在我需要打印 i myresul
  • 如何使用 Perl 正则表达式匹配字符串末尾/开头处的空格或单词?

    我想找到与我的正则表达式匹配的序列 它们应该位于由空格包围的字符串中间 末尾或开头或者是字符串中唯一的东西 Example 我们假设序列 qwe45rty 就是我们正在寻找的 我希望能够对所有这些因素都抱有积极的态度 qwe45rty qw
  • MIME::Lite - 无法发送邮件 [smtp.gmail.com 不支持 SMTP auth() 命令]

    use MIME Lite use warnings use MIME Base64 use Authen SASL use MIME Lite use MIME Base64 use Authen SASL use warnings us
  • Perl 是否有相当于 Python 的 `if __name__ == '__main__'` 的功能?

    有没有一种方法可以确定当前文件是否是 Perl 源中正在执行的文件 在 Python 中 我们使用以下结构来做到这一点 if name main This file is being executed raise NotImplemente
  • 如何对 Data::Dumper 的输出进行排序?

    我想转储对象和散列的值 但它总是乱序打印键 如何按 递归 排序顺序转储键 use Data Dumper print Dumper obj Set Data Dumper Sortkeys 1获取 Perl 的默认排序顺序 如果要自定义顺序
  • Perl:测试输入阅读器?

    有没有一种方法可以使用标准 Test 等模块自动测试 Perl 程序是否正在读取输入 例如标准输入正确吗 例如 测试一个从 STDIN 读取两个整数并打印它们之和的程序 这不是 100 清楚你的意思 我会回答假设你想编写一个测试脚本来测试你
  • Perl LWP GET 或 POST 到 SNI SSL URL

    我有一个使用 perl LWP 向客户发送数据的系统 他们可以选择 URL 以及是 POST 还是 GET 一位新客户最近抱怨该服务不起作用 他们怀疑这是因为他们的端点使用了 SNI SSL 查看日志 我看到的只是错误消息 证书验证失败 5
  • 客户端浏览器关闭时服务器端 Perl CGI 脚本中断

    我已经尝试解决一个小问题很长一段时间了 但似乎我无法解决 我编写了一个 HTML 页面 它在提交表单时调用 perl CGI 脚本 该 CGI 在服务器端执行一定数量的任务 我让脚本将这些任务的步骤打印到 HTML 页面上的 iframe
  • 如何在 Perl 中使用原始套接字?

    你怎样才能得到一个rawPerl 中的套接字 那么构建与其一起使用的数据包的最佳方法是什么 与在 C 中执行的操作相同 通过在创建套接字时设置套接字类型 在示例中CPAN http search cpan org rgarcia perl
  • 如何在 Perl 脚本中加密或隐藏密码?

    我正在研究 Perl 脚本 它使用Expect http search cpan org dist Expect通过 telnet 登录到远程计算机 不要问 必须使用 telnet 我还根据需要执行 perforce p4 登录操作 并使用
  • 如何忽略 perl 中的“证书验证失败”错误?

    我想访问一个无法验证证书的网站 我正在使用 WWW Mechanize 获取请求 那么如何忽略这一点并继续连接到该网站呢 use IO Socket SSL qw use WWW Mechanize qw my mech WWW Mecha
  • 从具有多行记录的文件中提取数据,将每个范围保存到单独的文件中

    我有一个看起来像这样的文件 TRANSACTION STARTED 020t CARD INSERTED 020tCARD 5845 DATE 01 02 16 TIME 05 45 52 05 46 26 GENAC 1 ARQC EXT
  • 如何在 Perl 中修改 Windows NTFS 权限?

    我在 Windows Server 2003 上使用 ActiveState Perl 我想在 Windows NTFS 分区上创建一个目录 然后授予 Windows NT 安全组对该文件夹的读取访问权限 这在 Perl 中可能吗 我必须使
  • perl - 子进程向父进程发送信号

    我编写了以下代码来测试孩子和父母之间的信号传递 理想情况下 当子进程向父进程发出 SIGINT 时 父进程应该在新的迭代中返回并等待用户输入 我在 perl 5 8 中观察到了这一点 但在 perl 5 6 1 我被要求使用 中 父级实际上
  • Perl 脚本的 shebang 行应该使用什么?

    哪一个用作 Perl 脚本的 shebang 行更好或更快 perl perl exe fullpath perl perl exe partialpath perl perl exe 并且 当使用 perl 当它在特定系统上运行时 我如何

随机推荐

  • 错误 1054。Insert 子句中的未知列

    我有这个问题 如果我编写以下查询 INSERT INTO prodotto Barcode InseritoDa DataInserimento UrlImage VALUES vfr ff 12 10 2012 vfr jpg 我收到此错
  • 自定义弹出菜单(布局)

    我正在尝试升级我的 PopupMenu 以便它带有图标和自定义样式 我为它创建了一个新的布局
  • 位置无关可执行文件的正确 Xcode 设置是什么

    最近刚刚开始收到一封应用商店提交后的电子邮件 其中包含以下建议 请确保您的构建设置已配置为创建 PIE 可执行文件 然而 XCode 中的设置看起来是正确的 在链接部分我发现 不创建位置无关的可执行文件 设置为 否 双重否定YUK 您收到此
  • Android排序数组

    我如何按日期或名称对该数组进行排序 String datetable new String 21 2 datetable 0 0 2011 01 01 datetable 0 1 Name1 datetable 1 0 2011 01 03
  • 为什么宽度/高度不适用于非定位伪元素?

    我想设置一个width of before伪元素达到80 如果我使用定位 那么一切都会正常 但如果我不使用它 那么一切都会失败 你能解释一下为什么百分比宽度在没有定位的情况下不起作用吗 如果可以的话 请添加一些对规范的引用 position
  • jQuery 方法链接是流畅编程的一个例子吗?

    我对 JavaScript jQuery 有点陌生 但是当我看到方法链接的示例时 我立即感到熟悉 其他接口 如 LINQ 执行类似的操作 其中一组方法的返回类型与它们所操作的类型相同 TweetSharp 执行的操作非常类似 这是流畅编程的
  • 从 CSV 文件批量插入 - 跳过重复项

    更新 最终使用了 Johnny Bubriski 创建的这个方法 然后对其进行了一些修改以跳过重复项 效果就像一个魅力 而且速度显然相当快 关联 http johnnycode com 2013 08 19 using c sharp sq
  • 向 Django FlatPages 添加功能,无需更改原始 Django 应用程序

    我想向 Django FlatPage 数据库模型添加一个字段 但我真的不知道如何在不编辑原始应用程序的情况下扩展它 我想要做的是将以下字段添加到模型中 from django db import models from django co
  • 在 nginx 上找不到 Laravel 路由

    当我尝试访问我的测试应用程序时 只有索引路由有效 malte italoborg es http malte italoborg es 如果我尝试访问另一条路线 例如 malte italoborg es admin http malte
  • 我可以使用 jQuery 检查是否至少有一个复选框被选中吗?

    我有以下 HTML 表单 其中可以有许多复选框 单击提交按钮时 我希望用户收到一个 javascript 警报 以检查至少一个复选框 如果未选中 有没有一种简单的方法可以使用 jQuery 来做到这一点
  • Android:API 级别低于 19 的远程 Webview 调试?

    据我所知 远程调试通过chrome inspect已在 API 级别 19 中添加用于 Web 视图 不过 我正在开发一个支持 17 设备的应用程序 只是在 API 19 上 我得到了02 28 00 31 16 569 12332 123
  • 在 R 中将 LASSO 与分类变量结合使用

    我有一个包含 1000 个观察值和 76 个变量的数据集 其中大约 20 个是分类变量 我想对整个数据集使用 LASSO 我知道通过 lars 或 glmnet 在 LASSO 中使用因子变量并不能真正起作用 但是变量太多 并且它们可以采用
  • 半六角形,只有一个元件

    我试图复制以下形状但没有成功 我想我需要一些 before and after伪元素以及以下 css pentagon position relative width 78px height 50px background 3a93d0 使
  • 当我在 Haskell 中编写“show”和“read”时发生了什么?

    以下是 GHCi 的简短文字记录 Prelude gt t read read Read a gt String gt a Prelude gt t show show Show a gt a gt String Prelude gt t
  • 使用计时器显示文本 3 秒?

    是否可以使用计时器在标签中显示文本 3 秒左右 F E 当您保存某些内容并且成功时 您会收到一条短信 成功 3秒后返回原页面 有人知道如何使用标签或消息框来做到这一点吗 是的 有可能 您可以在将标签文本设置为 成功 的位置启动计时器 并将其
  • elasticsearch 5.5突出显示字段不起作用

    我测试了弹性搜索突出显示字段功能 它工作正常 我用了弹性搜索2 4 4 and spring data elasticsearch 2 0 0 RELEASE 示例代码在下面的帖子中 如何使用 Spring data elasticsear
  • 如果该集合不可在进程之间整除,则使用 MPI_Scatter

    我有一个使用 MPI Scatter 和 MPI Gather 的程序 该程序将整数 N 作为输入 并返回从 2 到 N 的质数 我创建一个包含从 2 到 N 的数字的数组 并使用 MPI Scatter 将数组拆分为 N procs 数量
  • GCC 转储预处理器定义

    gcc g 有没有办法从命令行转储其默认预处理器定义 我的意思是像 GNUC STDC 等等 是的 使用 E dM选项而不是 c 示例 将它们输出到标准输出 echo gcc dM E echo clang dM E For C echo
  • Microsoft 整数文字扩展 - 在哪里记录?

    我在 Windows 安装的标准 stdint h 头文件中遇到了一些整数文字 文字具有以下形式的后缀 i8 ui8 i16 ui16 i32 ui32 i64 ui64 我以前遇到过 i64 形式的后缀 但从未遇到过任何其他形式的后缀 我
  • 尝试改进 Encode::decode 警告消息:$SIG{__WARN__} 处理程序中的段错误

    我正在尝试改进发出的警告消息Encode decode https metacpan org pod Encode FB WARN 我希望它打印正在读取的文件的名称以及在该文件中找到格式错误的数据的行号 而不是打印模块的名称和模块中的行号