Here is a \providelength command that will define a new length if not already defined, but also checks whether the command passed as argument has been defined with \newlength, in order to issue an error message if you try to use, say, \providelength{\textit}.
\documentclass{article}
\makeatletter
\newcommand{\providelength}[1]{%
\@ifundefined{\expandafter\@gobble\string#1}
{% if #1 is undefined, do \newlength
\typeout{\string\providelength: making new length \string#1}%
\newlength{#1}%
}
{% else check whether #1 is actually a length
\sdaau@checkforlength{#1}%
}%
}
\newcommand{\sdaau@checkforlength}[1]{%
% get the first five characters from \meaning#1
\edef\sdaau@temp{\expandafter\sdaau@getfive\meaning#1TTTTT$}%
% compare with the string "\skip"
\ifx\sdaau@temp\sdaau@skipstring
\typeout{\string\providelength: \string#1 already a length}%
\else
\@latex@error
{\string#1 illegal in \string\providelength}
{\string#1 is defined, but not with \string\newlength}%
\fi
}
\def\sdaau@getfive#1#2#3#4#5#6${#1#2#3#4#5}
\edef\sdaau@skipstring{\string\skip}
\makeatother
\begin{document}
\providelength{\foo}
\providelength{\foo}
\providelength{\textit}
\stop
Here is the terminal output:
\providelength: making new length \foo
\providelength: \foo already a length
! LaTeX Error: \textit illegal in \providelength.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.31 \providelength{\textit}
? h
\textit is defined, but not with \newlength
?
A version with expl3, that avoids the trick for finding if the command is already a length.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\providelength}{m}
{
\cs_if_exist:NTF #1
{
\sdaau_providelength_check:N #1
}
{
\msg_info:nnx { providelength } { making } { \token_to_str:N #1 }
\newlength{#1}
}
}
\cs_new_protected:Nn \sdaau_providelength_check:N
{
\token_if_skip_register:NTF #1
{
\msg_info:nnx { providelength } { not-making } { \token_to_str:N #1 }
}
{
\msg_error:nnx { providelength } { defined } { \token_to_str:N #1 }
}
}
\msg_new:nnn { providelength } { making }
{
\token_to_str:N \providelength :~making~new~length~#1
}
\msg_new:nnn { providelength } { not-making }
{
\token_to_str:N \providelength :~#1~is~already~a~length
}
\msg_new:nnnn { providelength } { defined }
{
#1~illegal~in~\token_to_str:N\providelength
}
{
#1~is~defined,~but~not~with~\token_to_str:N\newlength
}
\ExplSyntaxOff
\begin{document}
\providelength{\foo}
\providelength{\foo}
\providelength{\textit}
\stop
This is the excerpt from the log file
.................................................
. providelength info: "making"
.
. \providelength: making new length \foo
.................................................
\foo=\skip49
.................................................
. providelength info: "not-making"
.
. \providelength: \foo is already a length
.................................................
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! providelength error: "defined"
!
! \textit illegal in \providelength
!
! See the providelength documentation for further information.
!
! For immediate help type H <return>.
!...............................................
l.47 \providelength{\textit}
? h
|'''''''''''''''''''''''''''''''''''''''''''''''
| \textit is defined, but not with \newlength
|...............................................
etexshould be used to make them available. – Heiko Oberdiek Jun 15 '14 at 18:40\mytmplen, is repeatedly first\letto\relaxand then reissued as a length register via\newlength? – Mico Jun 15 '14 at 18:46\newlengthallocates a fresh new register, the name of the command sequence does not matter. If you can limit the code inside a group, then\locskipor\locdimenof packageetexcan be used instead. They are allocating locally and the registers are freed after the group is closed. – Heiko Oberdiek Jun 15 '14 at 18:54\newlengthdirectives... – Mico Jun 15 '14 at 19:48