%%------------------------------------------------------------------- %% File : con2hrl.erl %% Author : Ulf Wiger %% Description : %% %% Created : 7 Apr 2003 by Ulf Wiger %%------------------------------------------------------------------- %% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ulf Wiger.'' -module(con2hrl). -export([file/1, file/2]). -import(proplists, [get_value/2]). file(ContractF) -> file(ContractF, []). %% Mode : abort | overwrite %% file(ContractF0, Opts0) -> ContractF = to_string(ContractF0), Opts = default_opts(ContractF, Opts0), OutFile = get_value(outfile, Opts), case {file:read_file_info(OutFile),get_value(overwrite, Opts)} of {{ok, _}, false} -> exit(hrl_exists); _ -> {ok,Contract} = contract_parser:file1(ContractF), {ok,Fd} = file:open(OutFile, [write]), write_hrl(Contract, OutFile, Fd), file:close(Fd) end. write_hrl({contract,Name,Vsn, Types, States, AnyState}, File, Fd) -> io:fwrite(Fd, "%% File: ~s~n" "%% Date: ~s~n" "%% Description: Generated from ~s.con~n", [filename:basename(File), format_date(), Name]), make_records(Types, Fd). make_records([{Type, {tuple, [{constant,Type}|Rest]},_}|Types], Fd) -> case lists:foldr( fun(_, false) -> false; ({prim,Attr}, Acc) -> case lists:member(Attr, Acc) of true -> false; false -> [Attr | Acc] end; (_, Acc) -> false end, [], Rest) of false -> skip; Attrs -> Head = "-record(" ++ atom_to_list(Type) ++ ", {", Pad = lists:duplicate(length(Head), $\s), Tail = case Attrs of [Attr] -> atom_to_list(Attr) ++ "}).\n"; [H|T] -> atom_to_list(H) ++ [[",\n", Pad, atom_to_list(Ax)] || Ax <- T] ++ "}).\n"; [] -> skip end, io:fwrite(Fd, "\n" ++ Head ++ Tail, []) end, make_records(Types, Fd); make_records([_|Types], Fd) -> make_records(Types, Fd); make_records([], Fd) -> ok. format_date() -> {Y,M,D} = date(), {HH,MM,SS} = time(), [il(Y),"-",il(M),"-",il(D),", ",il(HH),":",il(MM),":",il(SS)]. il(I) -> pad0(integer_to_list(I)). pad0([N]) -> [$0,N]; pad0(Other) -> Other. default_opts(ContractF, Opts) -> outfile(ContractF, Opts). outfile(CF, Opts0) -> Opts = case get_value(outfile, Opts0) of undefined -> OutF = case regexp:split(CF, "\\.") of {ok, [Base, "con"]} -> Base ++ ".hrl"; Other -> exit({unexpected, Other}) end, [{outfile, OutF}|Opts0]; OutF -> lists:keyreplace( outfile, 1, Opts0, {outfile, to_string(OutF)}) end, overwrite(CF, Opts). overwrite(CF, Opts0) -> case get_value(overwrite, Opts0) of undefined -> [{overwrite, true}|Opts0]; _ -> Opts0 end. to_string(A) when is_atom(A) -> atom_to_list(A); to_string(S) when is_list(S) -> S.