anchor.diff:      _ -> exit({cannot_open,FN})
     end.
   
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -%%% pack the cnf record into a proplist for prf consumption
  -%%% Proplist = list({Tag,Val})
  -%%% Tag = time | flags | rtps | procs | where
  -%%% Where = {term_buffer,{Pid,Count,MaxQueue,MaxSize}} |
  -%%%         {term_stream,{Pid,Count,MaxQueue,MaxSize}} |
  -%%%         {file,File,Size,Count} |
  -%%%         {ip,Port,Queue}
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -pack(Cnf) ->
  -  {Flags,RTPs} = foldl(fun chk_trc/2,{[],[]},slist(Cnf#cnf.trc)),
  -  dict:from_list([{time,chk_time(Cnf#cnf.time)},
  -                  {flags,[call,timestamp|maybe_arity(Cnf,Flags)]},
  -                  {rtps,RTPs},
  -                  {procs,chk_proc(Cnf#cnf.proc)},
  -                  {where,where(Cnf)}]).
  -
  -where(Cnf) ->
  -  case Cnf#cnf.file of
  -    "" -> conf_term(Cnf);
  -    _  -> conf_file(Cnf)
  -  end.
  -
  -conf_file(Cnf) ->
  -  {file,Cnf#cnf.file,Cnf#cnf.file_size,Cnf#cnf.file_count}.
  -
  -conf_term(Cnf) ->
  -  {chk_buffered(Cnf#cnf.buffered),
  -   {Cnf#cnf.print_pid,
  -    chk_msgs(Cnf#cnf.msgs),
  -    Cnf#cnf.max_queue,
  -    Cnf#cnf.max_msg_size}}.
  -
  -maybe_arity(#cnf{arity=true},Flags) -> [arity|Flags];
  -maybe_arity(_,Flags)                -> Flags.
  -
  -chk_time(Time) when is_integer(Time) -> Time;
  -chk_time(X) -> exit({bad_time,X}).
  -
  -chk_buffered(yes) -> term_buffer;
  -chk_buffered(no) -> term_stream.
  -
  -chk_proc(Pid) when is_pid(Pid) -> Pid;
  -chk_proc(Atom) when is_atom(Atom)-> Atom;
  -chk_proc({pid,I1,I2}) when is_integer(I1), is_integer(I2) -> {pid,I1,I2};
  -chk_proc(X) -> exit({bad_proc,X}).
  -
  -chk_msgs(Msgs) when is_integer(Msgs) -> Msgs;
  -chk_msgs(X) -> exit({bad_msgs,X}).
  -
  --define(is_string(Str), (Str=="" orelse (9=<hd(Str) andalso hd(Str)=<255))).
  -
  -chk_trc('send',{Flags,RTPs})                   -> {['send'|Flags],RTPs};
  -chk_trc('receive',{Flags,RTPs})                -> {['receive'|Flags],RTPs};
  -chk_trc('arity',{Flags,RTPs})                  -> {['arity'|Flags],RTPs};
  -chk_trc(RTP,{Flags,RTPs}) when ?is_string(RTP) -> {Flags,[chk_rtp(RTP)|RTPs]};
  -chk_trc(RTP,{Flags,RTPs}) when is_tuple(RTP)   -> {Flags,[chk_rtp(RTP)|RTPs]};
  -chk_trc(X,_)                                   -> exit({bad_trc,X}).
  -
  --define(is_aal(M,F,MS), is_atom(M),is_atom(F),is_list(MS)).
  -
  -chk_rtp(Str) when ?is_string(Str)      -> redbug_msc:transform(Str);
  -chk_rtp({M})                           -> chk_rtp({M,'_',[]});
  -chk_rtp({M,F}) when is_atom(F)         -> chk_rtp({M,F,[]});
  -chk_rtp({M,L}) when is_list(L)         -> chk_rtp({M,'_',L});
  -chk_rtp({'_',_,_})                     -> exit(dont_wildcard_module);
  -chk_rtp({M,F,MS}) when ?is_aal(M,F,MS) -> {{M,F,'_'},ms(MS),[local]};
  -chk_rtp(X)                             -> exit({bad_rtp,X}).
  -
  -ms(MS) -> foldl(fun msf/2, [{'_',[],[]}], MS).
  -
  -msf(stack,[{Head,Cond,Body}]) -> [{Head,Cond,[{message,{process_dump}}|Body]}];
  -msf(return,[{Head,Cond,Body}])-> [{Head,Cond,[{return_trace}|Body]}];
  -msf(Ari, [{_,Cond,Body}]) when is_integer(Ari)-> [{mk_head(Ari),Cond,Body}];
  -msf({Head,Cond},[{_,_,Body}]) when is_tuple(Head)->[{Head,slist(Cond),Body}];
  -msf(Head, [{_,Cond,Body}]) when is_tuple(Head)-> [{Head,Cond,Body}];
  -msf(X,_) -> exit({bad_match_spec,X}).
  -
  -mk_head(N) -> erlang:make_tuple(N,'_').
  -
  -slist(S) when ?is_string(S) -> [S];
  -slist(L) when is_list(L) -> usort(L);
  -slist(X) -> [X].
  -
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -print_init(PrintFun,Pdepth,Pmsec) ->
  -  receive
  -    {trace_consumer,TC} ->
  -      erlang:monitor(process,TC),
  -      print_loop(PrintFun,Pdepth,Pmsec)
  -  end.
  -
  -print_loop(PrintFun,Pdepth,Pmsec) ->
  -  receive
  -    {'DOWN',_,_,_,R} -> io:fwrite("quitting: ~p~n",[R]);
  -    X -> outer(PrintFun,Pdepth,Pmsec,X),
  -         print_loop(PrintFun,Pdepth,Pmsec)
  -  end.
  -
  -outer(_,_,_,[]) -> ok;
  -outer(PrintFun,Pdepth,Pmsec,[Msg|Msgs]) ->
  +fix_ts(MS,TS) ->
  +  case MS of
  +    true -> ts(TS);
  +    false-> ts_ms(TS)
  +  end.
  +
  +ts({H,M,S,_Us}) -> flat("~2.2.0w:~2.2.0w:~2.2.0w",[H,M,S]).
  +ts_ms({H,M,S,Us}) -> flat("~2.2.0w:~2.2.0w:~2.2.0w.~3.3.0w",[H,M,S,Us div 1000]).
  +
  +flat(Form,List) -> flatten(io_lib:fwrite(Form,List)).
  +
  +outer(_,[]) -> ok;
  +outer(OutFun,[Msg|Msgs]) ->
     case Msg of
       {'call',{MFA,Bin},PI,TS} ->
  -      PrintFun(flat("~n~s <~p> ~P",[ts(TS,Pmsec),PI,MFA,Pdepth])),
  -      foreach(fun(L)->PrintFun(flat("  ~P",[L,Pdepth])) end, stak(Bin));
  +      OutFun("~n~s <~p> ~P",[TS,PI,MFA]),
  +      foreach(fun(L)->OutFun(" ",[L]) end, stak(Bin));
       {'retn',{MFA,Val},PI,TS} ->
  -      PrintFun(flat("~n~s <~p> ~p -> ~P",[ts(TS,Pmsec),PI,MFA,Val,Pdepth]));
  +      OutFun("~n~s <~p> ~p -> ~P",[TS,PI,MFA,Val]);
       {'send',{MSG,To},PI,TS} ->
  -      PrintFun(flat("~n~s <~p> <~p> <<< ~P",[ts(TS,Pmsec),PI,To,MSG,Pdepth]));
  +      OutFun("~n~s <~p> <~p> <<< ~P",[TS,PI,To,MSG]);
       {'recv',MSG,PI,TS} ->
  -      PrintFun(flat("~n~s <~p> <<< ~P",[ts(TS,Pmsec),PI,MSG,Pdepth]));
  +      OutFun("~n~s <~p> <<< ~P",[TS,PI,MSG]);
       _ ->
  -      PrintFun(flat("~n~P", [Msg,Pdepth]))
  +      OutFun("~n~P", [Msg])
     end,
  -  outer(PrintFun,Pdepth,Pmsec,Msgs).
  -
  -ts({H,M,S,_Us},false) -> flat("~2.2.0w:~2.2.0w:~2.2.0w",[H,M,S]);
  -ts({H,M,S,Us},_) -> flat("~2.2.0w:~2.2.0w:~2.2.0w.~3.3.0w",[H,M,S,Us div 1000]).
  -
  -flat(Form,List) -> flatten(io_lib:fwrite(Form,List)).
  +  outer(OutFun,Msgs).
   
   %%% call stack handler
   stak(Bin) ->
  
positive.code: 
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  print_fun(FD,Form) -> fun(Str) -> io:fwrite(FD,Form,[Str]) end.
  
  help() ->
    foreach(print_fun(standard_io,"~s~n"),
            ["redbug - the (sensibly) Restrictive Debugger"
             , ""
             , "  redbug:start(Trc) -> start(Trc,[])."
  
negative.code:     false-> Cnf#cnf{target=to_atom(Str++"@"++element(2,inet:gethostname()))}
    end.
  
  
  assert_print_fun(Cnf) -> Cnf#cnf{print_fun=def_print_fun(Cnf)}.
  
  spawn_printer(Cnf) ->
    Cnf#cnf{print_pid=spawn_link(fun()->print_init(Cnf#cnf.print_fun) end)}.
  
  def_print_fun(#cnf{print_fun=PF}) when is_function(PF) -> PF;
  def_print_fun(Cnf) ->
    OutFun = mk_out(Cnf),
    fun(Msgs) -> outer(OutFun,Msgs) end.
  
  mk_out(#cnf{file=[_|_]}) ->
    fun(_,_) -> ok end;
  mk_out(#cnf{print_re=RE,print_file=File,print_depth=D,print_msec=MS}) ->
    fun(F,A) ->
        Str=flat(F,[fix_ts(MS,hd(A))|tl(A)]++[D]),
        case RE =:= "" andalso re:run(Str,RE) =:= nomatch of
          true  -> ok;
          false -> io:fwrite(get_fd(File),"~s~n",Str)
        end
    end.
  
  