# Trouble parsing filename in expl3

I am trying to parse the file extension of a user-given path in expl3. I have got the file extension, but I can not manage to compare it to the expected file extension. My MWE is

\documentclass[]{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
\ior_new:N \g_slo_input_stream_ior
\tl_new:N \l_slo_input_dir_tl
\tl_new:N \l_slo_input_base_tl
\tl_new:N \l_slo_input_ext_tl
\cs_generate_variant:Nn \tl_if_eq:nnTF { V }

\cs_new:Nn \slo_open_file:n {
\file_parse_full_name:nNNN { #1 } \l_slo_input_dir_tl \l_slo_input_base_tl \l_slo_input_ext_tl

\tl_if_eq:VnTF \l_slo_input_ext_tl { .abc } {
#1~is~.abc-file.
} {
#1~is~\l_slo_input_ext_tl-file,~expected~.abc-file.
}
}
\NewDocumentCommand { \abcfile } { m } { \slo_open_file:n { #1 } }
\ExplSyntaxOff

\begin{document}
\abcfile{example.test} \par
\abcfile{filename.abc}
\end{document}


which produces

example.test is .test-file, expected .abc-file.
filename.abc is .abc-file, expected .abc-file.


while I expected

example.test is .test-file, expected .abc-file.
filename.abc is .abc-file


As far as I understand, the comparison in \tl_if_eq fails. Why?

As documented, \file_parse_full_name:nNNN provides the 'retur' values as strings, not token lists. That is to say all characters have category code 12 ('other'), bar spaces which are category code 10 ('space'). The tl comparison checks tokens, so here category codes are important. Your literal '.abc' has category code 11 ('letter') abc, so the test fails.

Most of the time, and certainly here, you are likely better using the string-based tests for checking 'text'. This only look at character codes, so we don't have to worry about the category code business.

\cs_new_protected:Npn \slo_open_file:n #1
{
\file_parse_full_name:nNNN {#1}
\l__slo_input_dir_tl
\l__slo_input_base_tl
\l__slo_input_ext_tl
\str_if_eq:VnTF \l__slo_input_ext_tl { .abc }
{ #1 ~is~.abc~file. }
{ #1~is~\l__slo_input_ext_tl-file,~expected~.abc-file. }
}

• I assume your variables are internal, so I've adjusted the names. Your function is not expandable, so I've made it protected. Also, I favour \cs_new_protected:Npn over the :Nn version ... Feb 25, 2019 at 9:49