anchor.diff:  compiler(".py") ->     {asn1ct,          compile_py};
   compiler(_) ->         no.
   
  -%% Entry from command line.
  -
   -type cmd_line_arg() :: atom() | string().
   
  +%% Run a compilation based on the command line arguments and then halt.
  +%% Intended for one-off compilation by erlc.
   -spec compile_cmdline() -> no_return().
  -
   compile_cmdline() ->
  +    cmdline_init(),
       List = init:get_plain_arguments(),
  -    case compile(List) of
  -	ok -> my_halt(0);
  -	error -> my_halt(1);
  -	_ -> my_halt(2)
  -    end.
  -
  --spec my_halt(_) -> no_return().
  -my_halt(Reason) ->
  -    erlang:halt(Reason).
  -
  -%% Run the the compiler in a separate process, trapping EXITs.
  -
  -compile(List) ->
  -    process_flag(trap_exit, true),
  -    Pid = spawn_link(compiler_runner(List)),
  +    compile_cmdline1(List).
  +
  +%% Run a compilation. Meant to be used by the compilation server.
  +-spec compile(list(), file:filename()) -> 'ok' | {'error', binary()}.
  +compile(Args, Cwd) ->
  +    try compile1(Args, #options{outdir=Cwd,cwd=Cwd}) of
  +        ok ->
  +            ok
  +    catch
  +        throw:{error, Output} ->
  +            {error, unicode:characters_to_binary(Output)};
  +        C:E:Stk ->
  +            {crash, {C,E,Stk}}
  +    end.
  +
  +%% Run the the compiler in a separate process.
  +compile_cmdline1(Args) ->
  +    {ok, Cwd} = file:get_cwd(),
  +    {Pid,Ref} = spawn_monitor(fun() -> exit(compile(Args, Cwd)) end),
       receive
  -	{'EXIT', Pid, {compiler_result, Result}} ->
  -	    Result;
  -	{'EXIT', Pid, {compiler_error, Error}} ->
  -	    io:put_chars(?STDERR, Error),
  -	    io:nl(?STDERR),
  -	    error;
  -	{'EXIT', Pid, Reason} ->
  -	    io:format(?STDERR, "Runtime error: ~tp~n", [Reason]),
  -	    error
  -    end.
  -
  --spec compiler_runner([cmd_line_arg()]) -> fun(() -> no_return()).
  -
  -compiler_runner(List) ->
  -    fun() ->
  -            %% We don't want the current directory in the code path.
  -            %% Remove it.
  -            Path = [D || D <- code:get_path(), D =/= "."],
  -            true = code:set_path(Path),
  -            exit({compiler_result, compile1(List)})
  -    end.
  -
  -%% Parses the first part of the option list.
  -
  -compile1(Args) ->
  -    {ok, Cwd} = file:get_cwd(),
  -    compile1(Args, #options{outdir=Cwd,cwd=Cwd}).
  -
  -%% Parses all options.
  -
  +        {'DOWN', Ref, process, Pid, Result} ->
  +            case Result of
  +                ok ->
  +                    halt(0);
  +                {error, Output} ->
  +                    io:put_chars(standard_error, Output),
  +                    halt(1);
  +                {crash, {C,E,Stk}} ->
  +                    io:format(standard_error, "Crash: ~p:~tp\n~tp\n",
  +                              [C,E,Stk]),
  +                    halt(2)
  +            end
  +    end.
  +
  +cmdline_init() ->
  +    %% We don't want the current directory in the code path.
  +    %% Remove it.
  +    Path = [D || D <- code:get_path(), D =/= "."],
  +    true = code:set_path(Path),
  +    ok.
  +
  +%% Parse all options.
   compile1(["--"|Files], Opts) ->
       compile2(Files, Opts);
   compile1(["-"++Option|T], Opts) ->
  
positive.code:     AbsDir = filename:absname(Dir, Cwd),
      compile1(T, Opts#options{includes=[AbsDir|Opts#options.includes]});
  parse_generic_option("M"++Opt, T0, #options{specific=Spec}=Opts) ->
      case parse_dep_option(Opt, T0) of
  	error ->
  	    error;
  	{SpecOpts,T} ->
  	    compile1(T, Opts#options{specific=SpecOpts++Spec})
      end;
  parse_generic_option("o"++Opt, T0, #options{cwd=Cwd}=Opts) ->
      {Dir,T} = get_option("o", Opt, T0),
      AbsName = filename:absname(Dir, Cwd),
  
negative.code: 	    end
      end.
  
  %% Make an Erlang term given a string.
  make_term(Str) ->
      case erl_scan:string(Str) of
  	{ok, Tokens, _} ->
  	    case erl_parse:parse_term(Tokens ++ [{dot, erl_anno:new(1)}]) of
  		{ok, Term} ->
                      Term;
  		{error, {_,_,Reason}} ->
  		    throw({error, io_lib:format("~ts: ~ts~n", [Reason, Str])})
  	    end;
  	{error, {_,_,Reason}, _} ->
  	    throw({error, io_lib:format("~ts: ~ts~n", [Reason, Str])})
      end.
  