% Definitions for the package Tcode specific to the C language. This file acts on top of Tcode.tex %

%The user may have redefined \ThisIsLanguage to ignore its argument. Therefore, in this file \TcodeLang may be C or empty.
\ThisIsLanguage{C}

\ifdefined\TcodeCcodeIncluded
  \ReloadLang@C
  \exP\endinput
\fi

\endlinechar=-1 %Do not insert anything at end of lines. Saves as plenty of % and possible bugs in the definitions that follow
\def\TcodeLang@C{C} %For testing against \TcodeLang in macros.

\newtoks\TcodeCcode@Reload@A
\newtoks\TcodeCcode@Reload@T
\newtoks\TcodeCcode@SavedCommands

%Redefined from Tcode
\TcodeCcode@Reload@T{
  \exP\def\exP\SetIdentCatcodes\exP{\SetIdentCatcodes \catcode`\#=11 } %Add # to the set of "letters".  \catcode`\#=12 would also work.
  \def\NumberCatcodes{\catcode`\_=12 \catcode`.=11 \catcode`\'=11} %Add ' as a valid character within numbers
}
\the\TcodeCcode@Reload@T

\input Tcode_Ccode-str.tex %Defines \TcodeCcode@Reload@A

\if*\TcodeLang*
  \def\CPreParenDefaultNone{\let\ApplyPreParenFormat\relax}
  \def\CPreParenDefaultFunction{\def\ApplyPreParenFormat{\def\FormatToApply{\FormatFunction}}}
  \def\CPreParenDefaultMacro{\def\ApplyPreParenFormat{\def\FormatToApply{\FormatMacro}}}
\else
  %Either apply it now or save it for the Reload
  \def\CPreParenDefaultNone{\ifx\TcodeLang\TcodeLang@C
  	\let\ApplyPreParenFormat\relax
  	\else \let\ApplyPreParenFormat@C\relax
  	\fi}
  \def\CPreParenDefaultFunction{\ifx\TcodeLang\TcodeLang@C
  	\def\ApplyPreParenFormat{\def\FormatToApply{\FormatCFunction}}
  	\else \def\ApplyPreParenFormat@C{\def\FormatToApply{\FormatCFunction}}
  	\fi}
  \def\CPreParenDefaultMacro{\ifx\TcodeLang\TcodeLang@C
  	\def\ApplyPreParenFormat{\def\FormatToApply{\FormatCMacro}}
  	\else \def\ApplyPreParenFormat@C{\def\FormatToApply{\FormatCMacro}}
  	\fi}
\fi
%By default, don't do anythig. It can become terribly frustrating when a package does something on its own that we don't want.
\CPreParenDefaultNone

%Names without "C", for single-language uses
\let\PreParenDefaultNone\CPreParenDefaultNone
\let\PreParenDefaultFunction\CPreParenDefaultFunction
\let\PreParenDefaultMacro\CPreParenDefaultMacro

%The prefixes are the same in both cases, so just for checking, the duplication would be superfluous.
%But we take advantage of the built cs-name, and reuse it later to set the formats.
\def\CheckCCharPrefix{\ifcsname CPrefix@\the\WordToPrint @'\endcsname \let\ifprefix\iftrue\let\fi\fi \fi}
\def\CheckCStrPrefix{\ifcsname CPrefix@\the\WordToPrint @"\endcsname \let\ifprefix\iftrue\let\fi\fi \fi}

%Modified from Tcode
\ifdefined\lastnamedcs %Luatex
  \def\PrePrintLongHook@C#1{
    \let\ifprefix\iffalse
    \ifx'#1\CheckCCharPrefix \else\ifx"#1\CheckCStrPrefix \fi\fi
    \ifprefix
  	\lastnamedcs \PrePrintCPrefixHook %The \lastnamedcs sets \FormatToApply and \FormatNext...
    \else
	\ifx\FormatToApply\undefined
	\ifx(#1\ApplyPreParenFormat
	\fi\fi
	\PrePrintHook
    \fi
  }
\else
  \def\PrePrintLongHook@C#1{
    \let\ifprefix\iffalse
    \ifx'#1\CheckCCharPrefix \else\ifx"#1\CheckCStrPrefix \fi\fi
    \ifprefix
  	\csname CPrefix@\the\WordToPrint @#1\endcsname
	\PrePrintCPrefixHook
    \else
	\ifx\FormatToApply\undefined
	\ifx(#1\ApplyPreParenFormat
	\fi\fi
	\PrePrintHook
    \fi
  }
\fi %Luatex
\let\PrePrintLongHook\PrePrintLongHook@C

%%%   # seen in input of the inline macros. If the next character is a letter, we interpret # as the first of a word.   %%%

{\catcode`#=12 \catcode`*=6
\gdef\temp*1{
  \ifcat\noexpand*1a\WordToPrint{#}\exP\NcodeParseWord
  \else #\exP\@parsecode \fi
  *1
}}
\let\NcodeCHash\temp

%%%   / seen in input. It may be a comment

\chardef\C@fwdSlash=`/ %Can be modified by syntax hiliting.

%This is executed after the first / is seen.
\ifdefined\lastnamedcs

\def\MaybeCComment#1{
\ifcsname CComment\string#1\endcsname \exP\lastnamedcs
\else
  \def\next{\C@fwdSlash\@parsecode #1}%Print the consumed / and let #1 be parsed again
  \exP\next
\fi
}

\else

\def\MaybeCComment#1{
\ifcsname CComment\string#1\endcsname
  \exP\exP\csname CComment\string#1\endcsname
\else
  \def\next{\C@fwdSlash\@parsecode #1}\exP\next
\fi
}

\fi %Luatex

%%%   Handling of NoLetter's   (TcodeLet places a @C in the name) %%%

\TcodeLetSpecial#=\NcodeCHash
\TcodeLetSpecial'=\NcodeParseCCharLiteral
\TcodeLetSpecial"=\NcodeParseCString
\TcodeLetSpecial/=\MaybeCComment

%%%%%********    Setup specific for the Code environment    ********%%%%%

% CodeDefineCommands. Modified from Tcode

\catcode`#=11
\catcode`"=11
\catcode`<=13 %It will *not* be active within the environment, except immediately after #include and #embed
\if*\TcodeLang*
   \def\CodeDefineCommands@C{
	\let\NcodeNoLetter@#=\undefined %And we leave its catcode as 12 (no letter)
	\let\NcodeNoLetter@"=\CodeParseCString
	\let\CCommentLine\CCommentLineM
	\def<{\let\parsecode\ParseIncludedString}% For #include <file> and #embed <file>
   }
\else
   \def\CodeDefineCommands@C{
	\let\NcodeNoLetterC@#=\undefined %And we leave its catcode as 12 (no letter)
	\let\NcodeNoLetterC@"=\CodeParseCString
	\let\CCommentLine\CCommentLineM
	\def<{\let\parsecode\ParseIncludedString}% For #include <file> and #embed <file>
   }
\fi
\catcode`<=12
\catcode`"=12
\catcode`#=6
\let\CodeDefineCommands\CodeDefineCommands@C

\input Tcode_Ccode-pp.tex %Defines \TcodeCcode@Reload@PP
\input Tcode_Ccode-com.tex


%%%%%%%*******  Saving for double inclusion  *******%%%%%%%

%Commands that the user can change
\def\UnloadLang@C{
  \let\ApplyPreParenFormat@C\ApplyPreParenFormat
}
\UnloadLang@C %Save them now, in case the user includes other language files after this one

\TcodeCcode@SavedCommands{
  \let\PrePrintLongHook\PrePrintLongHook@C
  \let\CodeDefineCommands\CodeDefineCommands@C
  \let\ApplyPreParenFormat\ApplyPreParenFormat@C
}

\edef\ReloadLang@C{
  \the\TcodeCcode@Reload@A
  \the\TcodeCcode@SavedCommands
  \expandonce\TcodeCcode@Reload@PP
}

\endlinechar=`\^^M % This ' ' prevented TeX from continuing expanding past the end of this file (new the final \let would stop it)

%%%*******  Provide defaults for the ones that are needed  *******%%%

\if*\TcodeLang*
  \unless\ifdefined\FormatString			\let\FormatString\relax\fi
  \unless\ifdefined\FormatStringWide		\def\FormatStringWide{\FormatString}\fi
  \unless\ifdefined\FormatCharLit			\def\FormatCharLit{\FormatString}\fi
  \unless\ifdefined\FormatCharLitW		\def\FormatCharLitW{\FormatCharLit}\fi
  \unless\ifdefined\FormatStrPrefix		\protected\def\FormatStrPrefix{\FormatString}\fi
  \unless\ifdefined\FormatStrWPrefix		\protected\def\FormatStrWPrefix{\FormatStringWide}\fi
  \unless\ifdefined\FormatCharPrefix		\protected\def\FormatCharPrefix{\FormatCharLit}\fi
  \unless\ifdefined\FormatCharWPrefix		\protected\def\FormatCharWPrefix{\FormatCharLitW}\fi
  %
  \unless\ifdefined\FormatComment		\let\FormatComment\relax\fi
  \unless\ifdefined\FormatCommentOld	\def\FormatCommentOld{\FormatComment}\fi
  \unless\ifdefined\FormatPPDirective		\let\FormatPPDirective\relax\fi
  \unless\ifdefined\FormatMacro			\let\FormatMacro\relax\fi
  \unless\ifdefined\FormatFunction		\let\FormatFunction\relax\fi
  \unless\ifdefined\HandleFileInclude		\def\HandleFileInclude#1{{\FormatString<#1>}}\fi
  \unless\ifdefined\HandleFileEmbed		\def\HandleFileEmbed#1{{\FormatString<#1>}}\fi
\else
  \unless\ifdefined\FormatCString			\let\FormatCString\relax\fi
  \unless\ifdefined\FormatCStringWide		\def\FormatCStringWide{\FormatCString}\fi
  \unless\ifdefined\FormatCCharLit		\def\FormatCCharLit{\FormatCString}\fi
  \unless\ifdefined\FormatCCharLitW		\def\FormatCCharLitW{\FormatCCharLit}\fi
  \unless\ifdefined\FormatCStrPrefix		\protected\def\FormatCStrPrefix{\FormatCString}\fi
  \unless\ifdefined\FormatCStrWPrefix		\protected\def\FormatCStrWPrefix{\FormatCStringWide}\fi
  \unless\ifdefined\FormatCCharPrefix		\protected\def\FormatCCharPrefix{\FormatCCharLit}\fi
  \unless\ifdefined\FormatCCharWPrefix	\protected\def\FormatCCharWPrefix{\FormatCCharLitW}\fi
  %
  \unless\ifdefined\FormatCComment		\let\FormatCComment\relax\fi
  \unless\ifdefined\FormatCCommentOld	\def\FormatCCommentOld{\FormatCComment}\fi
  \unless\ifdefined\FormatCPPDirective		\let\FormatCPPDirective\relax\fi
  \unless\ifdefined\FormatCMacro			\let\FormatCMacro\relax\fi
  \unless\ifdefined\FormatCFunction		\let\FormatCFunction\relax\fi
  \unless\ifdefined\HandleFileInclude		\def\HandleFileInclude#1{{\FormatCString<#1>}}\fi
  \unless\ifdefined\HandleFileEmbed		\def\HandleFileEmbed#1{{\FormatCString<#1>}}\fi
\fi

\let\TcodeCcodeIncluded\relax
