%% %% This is file `qstest.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% qstest.dtx (with options: `package,etex') %% %% IMPORTANT NOTICE: %% %% For the copyright see the source file. %% %% Any modified versions of this file must be renamed %% with new filenames distinct from qstest.sty. %% %% For distribution of the original source see the terms %% for copying and modification in the file qstest.dtx. %% %% This generated file may be distributed as long as the %% original source files, as listed above, are part of the %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) \errorcontextlines=\maxdimen %% %% Copyright (C) 2006, 2007 QuinScape GmbH %% http://www.quinscape.de \NeedsTeXFormat{LaTeX2e} \def\next$Id: #1.dtx #2 #3-#4-#5 #6${% \ProvidesPackage{#1}[#3/#4/#5 1.#2 QuinScape Unit Test Package] } \next $Id: qstest.dtx 7896 2007-02-21 14:03:26Z dkastrup $ \RequirePackage{makematch} \newtoks\qst@tmptoks \newcommand*{\TestErrors}{\MakeMatcher[,]\qst@errorcheck} \TestErrors{*, !fails} \newif\ifqst@error \def\qst@ifqst@error{\qst@errorcheck\qst@options \qst@errortrue\qst@errorfalse\ifqst@error} \long\def\qst@error#1{% \global\qst@testpassedfalse \global\let\qst@lastfailure\qst@testname \edef\qst@message{Failed: \qst@testname^^J#1}% \@onelevel@sanitize\qst@message \qst@failed} \newif\ifqst@testpassed \newcommand{\LogTests}[3]{% \ifcsname qst:log:#1\endcsname \else \expandafter\newwrite\csname qst:log:#1\endcsname \qst@gpush\qst@passed{\qst@logentry+{#1}}% \qst@gpush\qst@failed{\qst@logentry-{#1}}% \global\expandafter\let\csname qst:+log:#1\endcsname\qst@matchnever \global\expandafter\let\csname qst:-log:#1\endcsname\qst@matchnever \fi \expandafter\ifx \csname qst:+log:#1\endcsname \qst@matchnever \PackageInfo{qstest}{Logging on: \jobname.#1}% \ifnum\csname qst:log:#1\endcsname>\m@ne \immediate\openout\csname qst:log:#1\endcsname\jobname.#1\relax \fi \fi \MakeMatcher[,]\qst@tmp{#2}% \global\expandafter\let\csname qst:+log:#1\endcsname\qst@tmp \MakeMatcher[,]\qst@tmp{#3}% \global\expandafter\let\csname qst:-log:#1\endcsname\qst@tmp } \long\def\qst@gpush#1#2{\xdef#1{\unexpanded{#2}% \unexpanded\expandafter{#1}}} \def\qst@logentry#1#2{\qst@maybelog#1{#2}{% \immediate\write\csname qst:log:#2\endcsname{\qst@message}}} \def\qst@maybelog#1#2#3{\csname qst:#1log:#2\endcsname\qst@options {#3}{}} \expandafter\let\csname qst:log:log\endcsname\m@ne \global\expandafter\let\csname qst:+log:log\endcsname\qst@matchalways \global\expandafter\let\csname qst:-log:log\endcsname\qst@matchalways \def\qst@passed{\qst@maybelog+{log}% {\PackageInfo{qstest}{\qst@message}}} \def\qst@failed{\ifqst@error \PackageError{qstest}{\qst@message}{}% \else \qst@maybelog-{log}{\PackageWarning{qstest}{\qst@message}}% \fi} \newcommand*\LogClose[1]{% \expandafter\ifx \csname qst:+log:#1\endcsname\qst@matchnever \else \PackageInfo{qstest}{Logging off: \jobname.#1}% \ifnum\csname qst:log:#1\endcsname>\m@ne \immediate\closeout\csname qst:log:#1\endcsname \fi \global\expandafter\let\csname qst:+log:#1\endcsname\qst@matchnever \global\expandafter\let\csname qst:-log:#1\endcsname\qst@matchnever \fi } \def\IncludeTests{\MakeMatcher[,]\qst@includecheck} \let\qst@includecheck\qst@matchalways \RequirePackage{verbatim} \newenvironment{qstest}[2]{% \qst@testpassedtrue \edef\qst@testname{\detokenize{#1}}% \MakeMatchTarget[,]\qst@options{#2}% \let\ifqst@error\qst@ifqst@error \qst@includecheck\qst@options\ignorespaces{% \let\endqstest\endcomment}}% {\ifqst@testpassed \edef\qst@message{Passed: \qst@testname}% \qst@passed \else \ifx\qst@testname\qst@lastfailure \else \edef\qst@message{Failed: \qst@testname}% \qst@failed \fi \fi} \def\qst@testname{unspecified} \newcommand\Expect[1][]{% \edef\qst@tmpc{\unexpanded{#1}}% \qst@expectarg\qst@defaultvalue\qst@expecttwo} \def\qst@expectarg#1#2{% \@ifstar{\qst@expectargii\edef#1#2}{\qst@expectargii\def#1#2}} \def\qst@expectargii#1#2#3{\long\def\qst@tmp##1{% #1#2####1####2####3####4####5####6####7####8####9{##1}% \@onelevel@sanitize#2#3}% \afterassignment\qst@expectargiii \qst@tmptoks=} \def\qst@expectargiii{\expandafter \qst@tmp\expandafter{\the\qst@tmptoks}} \def\qst@expecttwo{% \ifx\qst@tmpc\@empty \edef\qst@tmpc{\the\qst@tmptoks}% \fi \qst@expectarg\qst@tmpb\qst@expectfinish} \def\qst@expectfinish{% \ifx\qst@defaultvalue\qst@tmpb \else \qst@error{ \string\Expect: \unexpanded\expandafter{\qst@tmpc}^^J <\qst@tmpb^^J >\qst@defaultvalue}% \fi} \def\InRange#1#2{% \ifcase \ifdim\qst@defaultvalue<#1\@ne\fi \ifdim\qst@defaultvalue>#2\@ne\fi \tw@ \or \qst@afterfi{{in [#1..#2]}}% \or \qst@afterfi{\expandafter{\qst@defaultvalue}}% \fi} \def\qst@afterfi#1#2\fi{\fi#1} \newcommand*\NearTo[1]{% \ifx[#1\expandafter\qst@nearto\expandafter[%]] \else \qst@afterfi{\qst@nearto[0.05pt]{#1}}% \fi} \def\qst@nearto[#1]#2{% \ifcase \ifdim\qst@defaultvalue>\dimexpr#2+(#1)\relax \@ne\fi \ifdim\qst@defaultvalue<\dimexpr#2-(#1)\relax \@ne\fi \tw@ \or \qst@afterfi{{near[#1] to #2}}% \or \qst@afterfi{\expandafter{\qst@defaultvalue}}% \fi} \newcommand\ExpectIfThen[1]{% \ifthenelse{#1}{}{% \qst@error{ \string\ExpectIfThen: \unexpanded{#1}% }}} \def\qst@advance#1{\edef#1{\number\numexpr(#1)+1}} \long\def\qst@csmaketransition#1#2#3#4.{% \qst@cssetstate{#1}% \expandafter \endgroup \csname qst@cstrans:#2\expandafter\endcsname \csname qst@cssaved\romannumeral\qst@csscope>\string#3\endcsname} \def\CalledName#1{\expandafter\expandafter\expandafter\@gobble \expandafter\strip@prefix\string#1} \def\qst@csstate{\csname qst@csstate\romannumeral \qst@csscope\endcsname} \def\qst@cssetstate#1{% \expandafter\expandafter\expandafter\xdef\qst@csstate{#1}} \long\def\qst@csmakewildcard#1#2#3{\ifx#3\endExpectCallSequence \else \def\qst@csnomatch{\qst@csmaketransition{#1}{#2}}% \fi \qst@tmp} \long\def\qst@cscheckempty#1#2{% \ifcase\qst@cslockout{#1}\z@ \expandafter\def\expandafter\qst@cslockout \expandafter##\expandafter1\expandafter{% \qst@cslockout{##1}\ifnum##1=#1\@ne\fi}% \expandafter\expandafter\expandafter\qst@tmp \csname qst@csstate:#1\expandafter\endcsname\expandafter#2% \or \expandafter\qst@tmp \fi} \long\def\qst@csnext#1#2{% \begingroup \edef\qst@csscope{#1}% \let\qst@csnomatch=\qst@csunexpected \def\qst@cslockout##1{\ifnum\qst@csstate=##1\@ne\fi}% \long\def\qst@tmp##1#2##2{##2#2}% \expandafter\expandafter\expandafter\qst@tmp \csname qst@csstate:\qst@csstate\endcsname#2% #2{\qst@csnomatch}.} \long\def\qst@csunexpected#1#2.{% \qst@error{ ExpectCallSequence: \string#1}% \expandafter\expandafter\expandafter \endgroup \qst@cssavedcs#1% } \long\def\qst@cssavedcs#1{% \csname qst@cssaved\romannumeral\qst@csscope>\string#1\endcsname} \long\def\qst@csaddstate#1#2{% \ifcsname qst@csstate:#1\endcsname \else \expandafter\let\csname qst@csstate:#1\endcsname \@gobble \fi \long\expandafter \def\csname qst@csstate:#1\expandafter\endcsname \expandafter##\expandafter1\expandafter{\romannumeral \expandafter\expandafter\expandafter\z@ \csname qst@csstate:#1\endcsname{##1}#2}} \def\qst@csaddempty#1#2{% \expandafter\qst@csaddstate\expandafter{\number#1\expandafter}% \expandafter{\expandafter##\expandafter1\expandafter{\expandafter \qst@cscheckempty\expandafter{\number#2}}}} \def\qst@csallocstate{0} \def\qst@csalloctrans{0} \def\qst@csscope{0} \newenvironment{ExpectCallSequence}[1] {% \qst@advance\qst@csscope \qst@cssetstate{\qst@csallocstate}% \let\qst@csgroupstate\qst@csallocstate \qst@advance\qst@csgroupstate \qst@advance\qst@csgroupstate \let\qst@csstack\@empty \qst@csparse.{}*(#1){...}% }{% \def\qst@cssavedcs{\@gobble}% \expandafter\qst@csnext\expandafter\qst@csscope \csname end {ExpectCallSequence}\endcsname} \long\def\qst@csparse#1{% \ifcsname qst@csparse:\string#1\endcsname \csname qst@csparse:\string#1\expandafter\expandafter\expandafter \endcsname \expandafter\@gobble \else \expandafter\qst@csparsedefault \fi{#1}} \expandafter\def\csname qst@cstrans:0\endcsname #1{\expandafter\let\csname\CalledName#1\endcsname= #1% \let#1=\@undefined \csname\CalledName#1\endcsname} \qst@csaddstate0{#1{\qst@csmakewildcard00}} \qst@csaddempty{0}{1} \expandafter\qst@csaddstate\expandafter1\expandafter{% \csname end {ExpectCallSequence}\endcsname{\qst@csmaketransition21}} \expandafter\let\csname qst@cstrans:1\endcsname\@gobble \def\qst@csalloctrans{2} \def\qst@csallocstate{3} \expandafter\let\csname end {ExpectCallSequence}\endcsname \endExpectCallSequence \expandafter\def\csname qst@csparse:...\endcsname{% \ifx\qst@csstack\@empty \else \PackageError{qstest}{Unmatched `(' in call sequence %) specification}{You need to fix this}% \loop \qst@csstack \ifx\qst@csstack\@empty \else \repeat \fi \qst@csaddempty{\qst@csallocstate}{0}% \qst@advance\qst@csallocstate \ignorespaces} \long\def\qst@csparsedefault#1{% \ifcsname qst@cssaved\romannumeral\qst@csscope>\string#1\endcsname \else \protected \edef\qst@tmp{\noexpand\qst@csnext \qst@csscope \noexpand#1}% \ifx#1\qst@tmp \else \expandafter\let \csname qst@cssaved\romannumeral\qst@csscope>\string#1\endcsname = #1% \let#1\qst@tmp \fi \fi \qst@csparsetransition{#1}\qst@csmaketransition} \long\def\qst@csparsetransition#1#2{% \let\qst@cslaststate\qst@csallocstate \qst@advance\qst@csallocstate \long\edef\qst@tmp##1##2{% \noexpand\qst@csaddstate{\qst@cslaststate}{% ##1{% ##2{\qst@csallocstate}% {\qst@csalloctrans}}}}% \qst@tmp{#1}{#2}% \expandafter\qst@advance\expandafter\qst@csalloctrans \expandafter\afterassignment\expandafter\qst@csparse \expandafter\long\expandafter\def \csname qst@cstrans:\qst@csalloctrans\endcsname} \expandafter\def\csname qst@csparse:.\endcsname{% \qst@csparsetransition{##1}\qst@csmakewildcard} \expandafter\def\csname qst@csparse:?\endcsname{% \qst@csensurelaststate?% \qst@csaddempty\qst@cslaststate\qst@csallocstate \let\qst@cslaststate\@undefined \qst@csparse} \def\qst@csensurelaststate#1{\ifx\qst@cslaststate\@undefined \PackageError{qstest}{Unexpected `#1' in call sequence}{% Expect chaos to ensue}% \def\qst@cslaststate{0}% \fi} \expandafter\def\csname qst@csparse:*\endcsname{% \qst@csensurelaststate*% \qst@csaddempty\qst@csallocstate\qst@cslaststate \qst@advance\qst@csallocstate \qst@csaddempty\qst@cslaststate\qst@csallocstate \let\qst@cslaststate\@undefined \qst@csparse} \expandafter\def\csname qst@csparse:+\endcsname{% \qst@csensurelaststate+% \qst@csaddempty\qst@csallocstate\qst@cslaststate \let\qst@cslaststate\qst@csallocstate \qst@advance\qst@csallocstate \qst@csaddempty\qst@cslaststate\qst@csallocstate \let\qst@cslaststate\@undefined \qst@csparse} \expandafter\def\csname qst@csparse:(\endcsname{% \edef\qst@csstack{\def\noexpand\qst@csstack{% \unexpanded\expandafter{\qst@csstack}% }% \def\noexpand\qst@csgroupstate{\qst@csgroupstate}}% \let\qst@csgroupstate\qst@csallocstate \qst@advance\qst@csallocstate \qst@csaddempty\qst@csgroupstate\qst@csallocstate \qst@csparse} \expandafter\def\csname qst@csparse:|\endcsname{% \let\qst@cslaststate\qst@csallocstate \edef\qst@csstack{\unexpanded\expandafter{\qst@csstack}% \noexpand\qst@csaddempty{\qst@cslaststate}% \noexpand\qst@csallocstate}% \qst@advance\qst@csallocstate \qst@csaddempty\qst@csgroupstate\qst@csallocstate \let\qst@cslaststate\@undefined \qst@csparse} \expandafter\def\csname qst@csparse:)\endcsname{% \let\qst@cslaststate\qst@csgroupstate \ifx\qst@csstack\@empty \PackageError{qstest}{Unmatched `)' in call sequence specification}{You need to fix this}% \fi \qst@csstack \qst@csparse } \expandafter\def\csname qst@csparse:`\endcsname{% \qst@cssetstate{\qst@csallocstate}% \let\qst@cslaststate\@undefined \qst@csparse} \expandafter\let\csname qst@csparse:^\expandafter\endcsname \csname qst@csparse:`\endcsname \expandafter\def\csname qst@csparse:'\endcsname{% \qst@csaddempty{\qst@csallocstate}{1}% \let\qst@cslaststate\qst@csallocstate \qst@advance\qst@csallocstate \qst@csparse} \expandafter\let\csname qst@csparse:$%$ \expandafter\endcsname\csname qst@csparse:'\endcsname \newcommand*\SaveValueFile[1]{% \ifnum\qst@savefile=\@auxout \newwrite\qst@savefile \else \immediate\closeout\qst@savefile \fi \immediate\openout\qst@savefile #1\relax} \def\qst@savefile{\@auxout} \newcommand*\CloseValueFile{% \ifnum\qst@savefile=\@auxout \else \immediate\closeout\qst@savefile \fi} \newcommand\SaveValue[1]{% \edef\qst@tmpc{\detokenize{#1}}% \ifnum\qst@savefile=\@auxout \ifx\@onlypreamble\AtBeginDocument \else \PackageError{qstest}{You need to specify \string\SaveValueFile^^J for test files without document.}{I can't use `\string\SaveValue' before either `\string\begin% {document}'^^J or `\string\SaveValueFile'}% \fi \fi \qst@expectarg\qst@defaultvalue\qst@saveval} \def\qst@saveval{% {\immediate\write\qst@savefile{\string\InternalSetValue^^J% \expandafter\qst@cleanlf\qst@tmpc\qst@endcleanlf^^J% \expandafter\qst@cleanlf\qst@defaultvalue\qst@endcleanlf^^J% \string\EndInternalSetValue^^J}}} \def\qst@cleanlf#1^^J{#1^% ^J\qst@cleanlf} \def\qst@endcleanlf^% ^J\qst@cleanlf{:^^J} \newcommand*\InternalSetValue{\begingroup \let\do\@makeother\dospecials \endlinechar`\^^J \catcode`\^7 \qst@setsavedii} \begingroup \catcode`\!=12 \lccode`\!=`\\ \lowercase{\endgroup \def\qst@setsavedii#1:^^J#2:^^J!}EndInternalSetValue^^J{\endgroup \expandafter\gdef\csname qst@value:\detokenize{#1}\endcsname{#2}} \newcommand*{\EndInternalSetValue}{% \PackageError{qstest}{\string\InternalSetValue\space got confused}% {You probably wrote something bad to the save file}} \def\SavedValue#1{% \ifcsname qst@value:\detokenize{#1}\endcsname \expandafter\expandafter\expandafter {\csname qst@value:\detokenize{#1}\expandafter\endcsname\expandafter}% \else \expandafter\expandafter\expandafter{\expandafter\qst@defaultvalue \expandafter}% \fi} \endinput %% %% End of file `qstest.sty'.