%D \module
%D   [       file=core-sys, % moved from main-001
%D        version=1997.03.31,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=System,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{Context Core Macros (System)}

\unprotect

%D Version checking:

\def\newcontextversion#1%
  {\doifelse{#1}\contextversion
      {\let\newcontextversion\gobbleoneargument}
      {\writeline
       \writestatus{Fatal    Error}{Your format does not match the base files!}%
       \writeline
       \writestatus{Format Version}{\contextversion\space\contextmark}%
       \writestatus{Files  Version}{#1}%
       \batchmode
       \normalend}}

%D End of lines to the output. \TEX\ will map this onto the platform specific
%D line ending. I hate this mess.

%newlinechar=10   \def\outputnewlinechar{\rawcharacter{10}}
\newlinechar=10  \edef\outputnewlinechar{^^J}

% in case formats are shared:

\appendtoks
    \bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup
\to \everyjob

%D Job names.

\def\outputfilename {\@@svfile}
\def\inputfilename  {\@@svinputfile}
\def\operatingsystem{\@@svtype}

\let\jobfilename  \jobname
\let\jobfilesuffix\c!tex

\def\splitjobfilename % todo: mkiv
  {\resetsystemmode{suffix-\jobfilesuffix}%
   \edef\ascii{\inputfilename}\convertcommand\ascii\to\ascii
   \splitstring\ascii\at.\to\jobfilename\and\jobfilesuffix
   \lowercasestring\jobfilesuffix\to\jobfilesuffix
   \doifnothing\jobfilename  {\let\jobfilename  \jobname}%
   % todo and totest: \convertcommand\jobfilename\to\jobfilename
   \doifnothing\jobfilesuffix{\let\jobfilesuffix\c!tex}%
   \setsystemmode{suffix-\jobfilesuffix}}

\appendtoks \splitjobfilename \to \everyjob

% Some mechanisms (see x-res-01) use either \jobfilename or
% \jobfilename.somesuffix, in which case we need to use the
% full name if given or a default (like \jobfilename.xml);
% this comes down to replacing the default tex suffix.

\def\jobfullname{\jobfilename.\jobfilesuffix}

\def\setjobfullname#1% #1 = default if not given
  {\doifelsenothing\jobfilename
     {\let\jobfullname\empty}
     {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}}

% ...

\def\dosetupsystem[#1]%
  {\getparameters[\??sv][#1]%
   \setuprandomize[\@@svrandom]%
   \beforesplitstring\@@svresolution\at dpi\to\@@svresolution
   \let\outputresolution\@@svresolution
   \ifcase\@@svn
     %                        % 0 : unknown
   \or
     \setsystemmode\v!first   % 1 : first run
   \or
     %                        % 2 : successive run
   \or
     \setsystemmode\v!first   % 3 : first and only run
   \or
     \setsystemmode\v!last    % 4 : (extra) last run
   \fi
%    \processaction
%      [\@@svtype]
%     %[     mswin=>\edef\@@svline{\rawcharacter{13}\rawcharacter{10}}, % crlf
%      [     mswin=>\edef\@@svline{\rawcharacter{13}},                  % cr % crlf
%           darwin=>\edef\@@svline{\rawcharacter{13}},                  % cr
%       \s!unknown=>\edef\@@svline{\rawcharacter{10}}]%                 % lf
   \splitjobfilename}

% \edef\@@svline{\rawcharacter{10}} % unix is the most critical/sensitive system

\let\systemendofline\outputnewlinechar % will become obsolete

\def\setupsystem
  {\dosingleargument\dosetupsystem}

\def\systemparameter#1{\executeifdefined{\??sv#1}\empty}

%D The system modes set by the setup command can be used in
%D situations like:
%D
%D \starttyping
%D \startmode[*first]
%D   \executesystemcommand{cleanupxml text.xml clean-text.xml}
%D \stopmode
%D
%D \starttext
%D   \typefile{clean-text.xml}
%D \stoptext
%D \stoptyping

\def\setuprandomize[#1]%
  {\doifsomething{#1}
     {\bgroup
      % tex's time is in minutes
      \scratchcounter\normaltime
      \processaction
        [#1]
        [  \v!small=>\divide\scratchcounter 15, %  900,
          \v!medium=>\divide\scratchcounter 30, % 1800,
             \v!big=>\divide\scratchcounter 60, % 3600,
          \v!normal=>\getnewrandomseed\scratchcounter,
         \s!default=>\getnewrandomseed\scratchcounter,
         \s!unknown=>\scratchcounter#1]%
      \expanded{\setrandomseed{\the\scratchcounter}}%
      \egroup}}

\setupsystem
  [\c!directory=,
   \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run
   \c!resolution=600dpi,
   \c!random=,
   \c!file=\jobname,
   \c!inputfile=\outputfilename,
   \c!type=unix, % windows is normally less sensitive to handle
   \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders

%D Remark: windows programs normally handle \type {cr|lf|crlf} but unix
%D is more picky, so we default to the \type {cr}. I never understood why
%D \type {crlf} was not used in all systems, since it makes most sense.

\def\dostartglobaldefs#1#2%
  {\edef\!!stringa{\the\globaldefs}%
   \ifnum\globaldefs#10
     \globaldefs-\globaldefs
   \fi
   \advance\globaldefs #21
   \setevalue{@gd@\the\globaldefs}{\!!stringa}}

\def\dostopglobaldefs
  {\doifdefinedelse{@gd@\the\globaldefs}
     {\globaldefs\getvalue{@gd@\the\globaldefs}\relax}
     {\globaldefs\zerocount}}

\def\startlocal  {\dostartglobaldefs>-}
\def\stoplocal   {\dostopglobaldefs}
\def\startglobal {\dostartglobaldefs<+}
\def\stopglobal  {\dostopglobaldefs}

\def\complexstart[#1]{\bgroup\getvalue{\e!start#1}}
\def\complexstop [#1]{\getvalue{\e!stop #1}\egroup}

\let\simplestart\bgroup
\let\simplestop \egroup

\definecomplexorsimple\start
\definecomplexorsimple\stop

\def\dododefinestartstop[#1][#2]% todo: use indirect commands
  {\getparameters
     [\??be#1]
     [\c!before=,
      \c!after=,
      \c!inbetween=,
      \c!commands=,
      \c!style=,
      #2]%
   \unexpanded\setvalue{#1}%
     {\groupedcommand
        {\getvalue{\??be#1\c!commands}%
         \dostartattributes{\??be#1}\c!style\c!color}
        {\dostopattributes
         \getvalue{\??be#1\c!inbetween}}}%
   \setvalue{\e!start#1}%
     {\getvalue{\??be#1\c!before}%
      \bgroup
      \getvalue{\??be#1\c!commands}%
      \dostartattributes{\??be#1}\c!style\c!color\empty}%
   \setvalue{\e!stop#1}%
     {\dostopattributes
      \egroup
      \getvalue{\??be#1\c!after}}}

\def\dodefinestartstop[#1][#2]%
  {\def\docommand##1{\dododefinestartstop[##1][#2]}%
   \processcommalist[#1]\docommand}

\def\definestartstop
  {\dodoubleargument\dodefinestartstop}

\def\dosetupstartstop[#1][#2]%
  {\def\docommand##1{\getparameters[\??be##1][#2]}%
   \processcommalist[#1]\docommand}

\def\setupstartstop
  {\dodoubleargument\dosetupstartstop}

% \docommand kan niet worden gebruikt omdat deze macro
%  soms lokaal wordt gebruikt

% te zijner tijd:
%
% \definevariable {pc}  % ProtectedCommand
%
% \def\executeprotected#1%
%   {\csname\??pc\string#1\endcsname}
%
% \def\defineprotected#1#2%
%   {\expandafter\def\csname\??pc\string#2\endcsname}
%
% \def\defineunprotected#1%
%   {\def#1}
%
% \def\doprotected%
%   {\ifx\next\define
%      \let\next=\defineprotected
%    \else
%      \let\next=\executeprotected
%    \fi
%    \next}
%
% \def\unexpanded%
%   {\futurelet\next\doprotected}
%
% \unexpanded\define\ziezo{ziezo}
%
% \unexpanded\ziezo

\def\complexdefine[#1]#2#3%
  {\ifx#2\undefined
   \else
     \showmessage\m!systems4{\string#2}%
   \fi
   \ifcase0#1\def#2{#3}%
   \or\def#2##1{#3}%
   \or\def#2##1##2{#3}%
   \or\def#2##1##2##3{#3}%
   \or\def#2##1##2##3##4{#3}%
   \or\def#2##1##2##3##4##5{#3}%
   \or\def#2##1##2##3##4##5##6{#3}%
   \or\def#2##1##2##3##4##5##6##7{#3}%
   \or\def#2##1##2##3##4##5##6##7##8{#3}%
   \or\def#2##1##2##3##4##5##6##7##8##9{#3}%
   \else\def#2{#3}%
   \fi}

\definecomplexorsimpleempty\define

\unexpanded\def\macroname#1% brrr
  {\executeifdefined{#1}\empty}

\def\usecommands#1%
  {\bgroup
   \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}%
   \processcommalist[#1]\docommand
   \egroup}

\newif\ifforcefileexpansion % handy for document level overload

%D The next implementation is about 4 times as faster than a
%D processaction alternative on an string of average length.
%D Since this feature is used in XML processing, it made sense
%D to support this faster alternative. It's installable as well.

\def\installexpander#1#2{\setvalue{\s!do\c!expansion#1}{#2}}

% \long\def\convertexpanded#1#2#3% hm, first we need to make sure
%   {\csname   % that we assign all exp a value
%      \s!do\c!expansion
%      \ifforcefileexpansion
%        \v!yes
%      \else\@EA\ifx\csname\s!do\c!expansion\csname#1\c!expansion\endcsname\endcsname\relax
%        \s!default
%      \else
%        \csname#1\c!expansion\endcsname
%      \fi\fi
%    \endcsname#2\to#3}

\long\def\convertexpanded#1#2#3% hm, first we need to make sure
  {\csname   % that we assign all exp a value
     \s!do\c!expansion
     \ifforcefileexpansion
       \v!yes
     \else\@EA\ifx\csname\s!do\c!expansion#1\endcsname\relax
       \s!default
     \else
       #1%
     \fi\fi
   \endcsname#2\to#3}

\installexpander\v!command{\convertcommand }
\installexpander\s!default{\convertargument}
\installexpander\empty    {\convertargument}
\installexpander\v!no     {\convertargument}
\installexpander\v!yes    {\convertmeaning }
\installexpander\v!yes    {\convertmeaning } % something lost ?
\installexpander\v!strict {\reduceargument }
\installexpander {utf}    {\reducetoutf}
%installexpander {xml}    {see xtag-ext}

\def\convertmeaning#1\to % watch the double expansion !
  {\bgroup
     \honorunexpanded
     \convertencodedtokens % can be overloaded
     \xdef\@@globalexpanded{#1}%
     \xdef\@@globalexpanded{\@@globalexpanded}%
   \egroup
   \convertcommand\@@globalexpanded\to}

\def\reduceargument#1\to#2%
  {\begingroup
   \reducetocoding[raw]%
   \edef\ascii{#1}%
   \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}

% \setupindex[expansion=utf]\index{\eacute}

\def\reducetoutf#1\to#2%
  {\begingroup
   \reducetocoding[uc]%
   \let\uchar\uchartoutf
   \let\unicodechar\numbertoutf
   \edef\ascii{#1}%
   \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}

% \setvalue{statevalue\v!stop   }{0}
% \setvalue{statevalue\v!start  }{1}
% \setvalue{statevalue\v!normaal}{2}
% \setvalue{statevalue\v!leeg   }{3}
% \setvalue{statevalue\v!geen   }{4}
%
% \def\setcurrentstate#1%
%   {\chardef\currentstate=0\getvalue{statevalue\getvalue{#1\c!state}\relax}
%
% \ifcase\currentstate ...

\def\redo{\dorepeat} % [n*10], kind of obsolete

% obsolete, use \dorecurse instead
%
% \def\herhaler           {\repeater}
% \def\herhaalmetcommando {\dorepeatwithcommand}

%D Plugins

\loadmarkfile{core-sys}

\protect \endinput
