1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#!/usr/bin/env escript
%% -*- erlang -*-
main(Args) ->
[AppSrc,AppF,Vsn,Modules] = Args,
{Comments, L, App} = parse_appsrc(AppSrc),
{application, A, Attrs} = App,
Attrs1 = [vsn(Vsn, Attrs),
descr(Attrs),
{modules, lists:sort([list_to_atom(M) || M <- string:tokens(Modules," ")])} |
[Attr || {K,_} = Attr <- Attrs,
not lists:member(K, [vsn, modules, description])]],
write_app(AppF, Comments, L, {application, A, Attrs1}).
write_app(F, Comments, TermL, App) ->
case file:open(F, [write]) of
{ok, Fd} ->
try L = write_comments(Comments, Fd),
write_term(App, L, TermL, Fd)
after
file:close(Fd)
end;
Error ->
error(Error)
end.
parse_appsrc(F) ->
case file:read_file(F) of
{ok, B} ->
case erl_scan:string(binary_to_list(B), 1) of
{ok, Toks, _} ->
Comments = lists:takewhile(
fun({comment,_,_}) -> true;
(_) -> false
end, Toks),
TermToks = [T || T <- Toks, element(1,T) =/= comment],
TermL = element(2, hd(TermToks)),
case erl_parse:parse_term(TermToks) of
{ok, {application, _A, _Attrs} = App} ->
{Comments, TermL, App};
Error ->
error(Error)
end;
ScanErr ->
error(ScanErr)
end;
ReadErr ->
error(ReadErr)
end.
write_comments(Comments, Fd) ->
lists:foldl(
fun({comment, L, C}, L0) ->
S = ["\n" || _ <- lists:seq(1,L-L0)] ++ C,
io:put_chars(Fd, S),
L
end, 1, Comments).
write_term(T, L0, TermL, Fd) ->
case ["\n" || _ <- lists:seq(1,TermL-L0)] of
[] -> ok;
S -> io:put_chars(Fd, S)
end,
io:fwrite(Fd, "~p.~n", [T]).
vsn(Vsn, Attrs) when Vsn =:= '' orelse Vsn =:= "" orelse Vsn =:= "default" ->
{vsn, "1.3"}; %% By inspection
vsn(Vsn, _Attrs) ->
{vsn, Vsn}.
descr(Attrs) ->
{description, "MochiMedia Web Server"}. %% By inspection
error(E) ->
io:fwrite("*** ~p~n", [E]),
halt(1).
|