TikZ: pgfutil-common: pgfutil@in@ - how does it work?

Having been writing small lib for TikZ, I tried to use this macro in order to search for @. Code compiled, but the result was false, despite that I was sure it was in tested string. So, I decided to look into an implementation of this macro, but it breaks my brain by self-recursive usage of pgfutil@in@ and pgfutil@in@@. Could someone explain how that manages to work? And, furthermore, if it can be changed to make search for @ applicable?

% pgfutil@in@

\newif\ifpgfutil@in@

% Usage:
% \pgfutil@in@{one}{three two one}
% \ifpgfutil@in@
%   -> will be true!
% \else
% \fi
%
% \pgfutil@in@{,}{1234,456567}
% \ifpgfutil@in@
%   -> will be true!
% \else
% \fi
\def\pgfutil@in@#1#2{%
\def\pgfutil@in@@##1#1##2##3\pgfutil@in@@{%
\ifx\pgfutil@in@##2\pgfutil@in@false\else\pgfutil@in@true\fi}%
\pgfutil@in@@#2#1\pgfutil@in@\pgfutil@in@@}


I expect that there must be some way to tweak it by means of catcode...

EDIT:

Usage example:

\edef \pgf@marshal{\noexpand \pgfutil@in@{@}{\tikz@temp}}%
\pgf@marshal%


EDIT 2:

I discovered that using \pgfutil@in@{@}{\tikz@temp} from document context with set \makeatletter I don't encounter any problems even with searching for @ directly.

Having investigated into how TikZ includes libraries, I found that it saves category code for @, sets it to 11, includes library, then restores the category code for @. So it's ok to define macroses with @ in the name.

But before executing \pgfutil@in@{@}{\tikz@temp} (now inside some macros in my library) I do:

\c@pgf@counta = \catcode\@%
\showthe \c@pgf@counta%


and see that pdflatex outputs 12. Hmmm... I guess this is due to that macroses in my library are just read and saved for later use. They're executed inside the document environment, when the category code for @ is already 12. Made such a suggestion I tried to put \makeatletter just before the \begin{document} and it worked like a charm!

So, is there a way to somehow alter the category code for @ just in place where it should be 11 by the time of execution?

Another suggestion is that by the time the macros is read the category code for @ is 11, but when being executed, the expanded value of \tikz@temp contains @ of category code 12. So, they will never match, unless I do \makeatletter at the document context.

-
I think an example of how you used it might be handy: I suspect you got the catcode of @ wrong somewhere. – Joseph Wright May 4 '11 at 15:02
@Joseph: I edited my question in order to include example of usage. – Dmitry Volosnykh May 4 '11 at 15:25
@Dmitry: I've edited the answer to cover that case – Joseph Wright May 4 '11 at 15:36
@Dmitry: The issue of category codes for @ really deserves a separate question. I suggest you post one, linking to this question for context. (We like to keep each question focussed, where possible.) – Joseph Wright May 4 '11 at 17:45
@Joseph: I've just started to compose one :) Also, there will be the minimalistic example, so that you're able to see what's happening. – Dmitry Volosnykh May 4 '11 at 17:51

The macros are pretty simple and use standard TeX argument delimiting. The fact that the same macro names are reused makes the code a little less clear, but does not alter the effect. To make life easier, we could write the same concept out using some additional markers:

\def\pgfutil@in@#1#2{%
\def\pgfutil@in@@##1#1##2##3\pgfutil@stop{%
\ifx\pgfutil@marker##2\pgfutil@in@false\else\pgfutil@in@true\fi
}%
\pgfutil@in@@#2#1\pgfutil@marker\pgfutil@stop
}
\def\pgfutil@marker{\pgfutil@marker}


The idea is then that the auxiliary function \pgfutil@in@@ is defined so that its argument has to contain #1, and will be stopped by \pgfutil@stop (\pgfutil@in@@ in the original).

\pgfutil@in@@ is then used so that it will always be followed by at least one #1, which will be immediately followed by a marker (\pgfutil@in@ in the original, \pgfutil@marker in my version). If #1 is not in #2, then ##1 will be #2, ##2 will be the marker and ##3 will be empty. The \ifx test will be TRUE, and the flag is set FALSE. On the other hand, if #1 is in #2, then ##1 will be the part of #2 before the first #1, ##2 will not be the marker and ##3 will tidy up. The \ifx will be FALSE and so the flag will be set TRUE.

This all relies on the category code of #1 matching the occurrence in #2. We are talking about @, and so it's possible to do something like

\makeatletter
\def\myfunction#1{%
\pgfutil@in@{@}{#1}%
...
}
\makeatother


and to get the wrong result. That's because the hard-coded @ is a 'letter' while any in #1 will (probably) be 'other'. That can be avoided using a bit of \lowercase trickery.

\makeatletter
\begingroup
\lccode\*=\@\relax
\lowercase{%
\endgroup
\def\myfunction#1{%
\pgfutil@in@{*}{#1}%
...
}
}
\makeatother


where the idea is that * acts as a substitute for @: it has category code 'other' but is turned into a @ by the \lowercase.

For the edited question, the correct approach would be

\begingroup
\lccode\*=\@\relax
\lowercase{%
\endgroup
\edef\pgf@marshal{\noexpand\pgfutil@in@{*}{\tikz@temp}}%
}
\pgf@marshal

-
at the top of pgfutil-common.tex there's statement \catcode\@=11\relax. And then there's a plenty of macroses, which contain @ in the name. So, it looks unnecessary to \makeatletter. – Dmitry Volosnykh May 4 '11 at 15:27
@Dmitry: My assumption was that you were using things in a document context, hence the guards. – Joseph Wright May 4 '11 at 15:33
I should add that the general point is the same: if @ is a letter, you need to take care when searching for @ as an 'other' character. – Joseph Wright May 4 '11 at 15:37
please read EDIT 2 section of my question. Thanks for the current help and in advance. – Dmitry Volosnykh May 4 '11 at 17:09
Great answer, Joseph – Matthew Leingang May 4 '11 at 17:10