mad_repl.erl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. -module(mad_repl).
  2. -copyright('Maxim Sokhatsky').
  3. -compile(export_all).
  4. disabled() -> [wx,webtool,ssl,runtime_tools,public_key,observer,inets,asn1,et,eunit,hipe].
  5. system() -> [compiler,syntax_tools,sasl,tools,mnesia,reltool,xmerl,crypto,kernel,stdlib].
  6. local_app() ->
  7. case filename:basename(filelib:wildcard("ebin/*.app"),".app") of
  8. [] -> [];
  9. A -> [list_to_atom(A)] end.
  10. applist() ->
  11. Name = ".applist",
  12. case file:read_file(Name) of
  13. {ok,Binary} -> parse_applist(Binary);
  14. {error,_} ->
  15. case mad_repl:load_file(Name) of
  16. {error,_} -> mad_plan:main([]);
  17. {ok,Plan} -> parse_applist(Plan) end end.
  18. wildcards(List) -> lists:concat([filelib:wildcard(X)||X<-List]).
  19. parse_applist(AppList) ->
  20. Res = string:tokens(string:strip(string:strip(binary_to_list(AppList),right,$]),left,$[),","),
  21. [ list_to_atom(R) || R <-Res ] -- disabled().
  22. load_config() ->
  23. Config = wildcards(["sys.config"]),
  24. Apps = case Config of
  25. [] -> case mad_repl:load_file("sys.config") of
  26. {error,_} -> [];
  27. {ok,Bin} -> parse(binary_to_list(Bin)) end;
  28. File ->
  29. case file:consult(File) of
  30. {error,_} -> [];
  31. {ok,[A]} -> A end
  32. end,
  33. io:format("Configuration: ~p\n\r",[Apps]),
  34. [ begin
  35. % io:format("\t~p: ~p\n\r",[App,Cfg]),
  36. [ application:set_env(App,K,V) || {K,V} <- Cfg ],
  37. {App,Cfg}
  38. end || {App,Cfg} <- Apps ].
  39. load_apps([],_) -> [ begin
  40. case lists:member(A,system()) of
  41. true -> application:start(A);
  42. _ ->
  43. Cfg = load_config(A),
  44. case Cfg of [] -> application:start(A);
  45. E ->
  46. % io:format("User Application Start: ~p~n\r",[A]),
  47. application:start(E) end end
  48. end || A <- applist()];
  49. load_apps(["applist"],Config) -> load_apps([],Config);
  50. load_apps(Params,_) -> [ application:ensure_all_started(list_to_atom(A))||A<-Params].
  51. cwd() -> {ok, Cwd} = file:get_cwd(), Cwd.
  52. main(Params) ->
  53. SystemPath = filelib:wildcard(code:root_dir() ++
  54. "/lib/{"++ string:join([atom_to_list(X)||X<-mad_repl:system()],",") ++ "}-*/ebin"),
  55. UserPath = wildcards(["{apps,deps}/*/ebin","ebin"]),
  56. code:set_path(SystemPath++UserPath),
  57. code:add_path(filename:join([cwd(),filename:basename(escript:script_name())])),
  58. load(),
  59. io:format("Applications: ~p\n\r",[applist()]),
  60. Config = load_config(),
  61. % trick user_drv into starting group.erl's output handler
  62. unregister(user),
  63. case os:type() of
  64. {win32,nt} -> shell:start();
  65. _ -> user_drv:start() end,
  66. load_apps(Params,Config),
  67. case Params of
  68. ["applist"] -> skip;
  69. _ -> timer:sleep(infinity) end.
  70. load() ->
  71. ets_created(),
  72. {ok,Sections} = escript:extract(escript:script_name(),[]),
  73. [Bin] = [B||{archive,B}<-Sections],
  74. unfold_zips(Bin).
  75. unfold_zips(Bin) ->
  76. {ok,Unzip} = zip:unzip(Bin,[memory]),
  77. [ begin
  78. % io:format("Unzip: ~p~n\r",[U]),
  79. ets:insert(filesystem,{U,FileBin}),
  80. case U of
  81. "static.gz" -> unfold_zips(FileBin);
  82. _ -> skip end
  83. end || {U,FileBin} <- Unzip].
  84. ets_created() ->
  85. case ets:info(filesystem) of
  86. undefined -> ets:new(filesystem,[set,named_table,{keypos,1},public]);
  87. _ -> skip end.
  88. load_file(Name) ->
  89. ets_created(),
  90. case ets:lookup(filesystem,Name) of
  91. [{Name,Bin}] -> {ok,Bin};
  92. _ -> {error,etsfs} end.
  93. load_config(A) when is_atom(A) -> load_config(atom_to_list(A));
  94. load_config(A) when is_list(A) ->
  95. AppFile = A ++".app",
  96. Name = wildcards(["{apps,deps}/*/ebin/"++AppFile,"ebin/"++AppFile]),
  97. case file:read_file(Name) of
  98. {ok,Bin} -> parse(binary_to_list(Bin));
  99. {error,_} -> case ets:lookup(filesystem,AppFile) of
  100. [{Name,Bin}] -> parse(binary_to_list(Bin));
  101. _ -> [] end end.
  102. parse(String) ->
  103. {ok,Tokens,_EndLine} = erl_scan:string(String),
  104. {ok,AbsForm} = erl_parse:parse_exprs(Tokens),
  105. {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()),
  106. Value.