# Testing for macros by name

I'm curious to know how I would go about testing for macros by name. I need to do something that would be the logical equivalent of the following:

\def\doit#1{%
\if#1==\foo I got a foo\fi
\if#1==\bar I got a bar\fi
}


Now, of course I'm aware that \if doesn't work that way. The notation == isn't actually a thing, and the fact that \if expands macros is undesirable for my purposes, because I might want to do \doit\foo without \foo even being defined. However, I hope that the above pseudo-code serves to illustrate my question nonetheless.

I'm aware that there are better ways to pass named "flags" to a macro than as control sequences, but for reasons I won't go into here I really am constrained to macro names, and I really do need to be able to check if, given two macro tokens, their names are both the same.

Note that I'm using Plain TeX, and I'm seeking a solution that uses only TeX primitives and/or Plain TeX macros.

• Will you always use it the way \doit\foo or would you want to also use it \doit{foo}? – Werner Apr 30 '14 at 5:23
• Always \doit\foo. Of course that's a contrived example, but in my actual code the project is such that I have \doit\foo, and I need to distinguish between \foo and \bar, even when neither is defined. – patrick-rutkowski Apr 30 '14 at 6:05
• Does Plain TeX know \pdfstrcmp? – Werner Apr 30 '14 at 6:24
• @rutski OK, this is a string-like test. Do you need it to be expandable? If so, are there likely to be spaces in the names (under 'edge case' circumstances)? – Joseph Wright Apr 30 '14 at 6:25
• @Werner Not a TeX90 or even e-TeX primitive. You can do an expandable string-based test using \if and some looping even without it: easier of course if the test does not need to be expandable. – Joseph Wright Apr 30 '14 at 6:26

If you don't need an expandable test, here's a possibility. I assume you have a finite set of flags.

% set the flags
\begingroup\escapechar=-1
\xdef\fooname{\string\foo}
\xdef\barname{\string\bar}
\endgroup

\def\nameequal#1#2{%
TT\fi
\begingroup
\escapechar=-1
\edef\nameequaltemp{\string#1}%
\expandafter\endgroup
\ifx\nameequaltemp#2}

\def\doit#1{%
\if\nameequal#1\fooname
I saw foo%
\else
\if\nameequal#1\barname
I saw bar%
\else
I saw rubbish%
\fi
\fi
}

\doit\foo

\doit\bar

\doit\foobar

\bye


• Why not just \edef\@tempa{\string#1}\edef\@tempb{\string#2}\ifx\@tempa\@tempb? – Joseph Wright Apr 30 '14 at 12:37
• @JosephWright I like it better to declare the admissible flags beforehand. – egreg Apr 30 '14 at 15:32