1%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- 2%% ex: ts=4 sw=4 et 3%% ------------------------------------------------------------------- 4%% 5%% rebar: Erlang Build Tools 6%% 7%% Copyright (c) 2009, 2010 Dave Smith (dizzyd@dizzyd.com) 8%% 9%% Permission is hereby granted, free of charge, to any person obtaining a copy 10%% of this software and associated documentation files (the "Software"), to deal 11%% in the Software without restriction, including without limitation the rights 12%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13%% copies of the Software, and to permit persons to whom the Software is 14%% furnished to do so, subject to the following conditions: 15%% 16%% The above copyright notice and this permission notice shall be included in 17%% all copies or substantial portions of the Software. 18%% 19%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25%% THE SOFTWARE. 26%% ------------------------------------------------------------------- 27-module(rebar_dia_compiler). 28 29-export([compile/2, 30 clean/2]). 31 32%% for internal use only 33-export([info/2]). 34 35-include("rebar.hrl"). 36 37%% =================================================================== 38%% Public API 39%% =================================================================== 40 41-spec compile(rebar_config:config(), file:filename()) -> 'ok'. 42compile(Config, _AppFile) -> 43 DiaOpts = rebar_config:get(Config, dia_opts, []), 44 IncludeEbin = proplists:get_value(include, DiaOpts, []), 45 DiaFiles = filelib:wildcard("dia/*.dia"), 46 code:add_pathsz(["ebin" | IncludeEbin]), 47 FileSequence = case rebar_config:get(Config, dia_first_files, []) of 48 [] -> 49 DiaFiles; 50 CompileFirst -> 51 CompileFirst ++ 52 [F || F <- DiaFiles, not lists:member(F, CompileFirst)] 53 end, 54 rebar_base_compiler:run(Config, FileSequence, 55 "dia", ".dia", "src", ".erl", 56 fun compile_dia/3). 57 58-spec clean(rebar_config:config(), file:filename()) -> 'ok'. 59clean(Config, _AppFile) -> 60 DiaOpts = rebar_config:get(Config, dia_opts, []), 61 IncludeEbin = proplists:get_value(include, DiaOpts, []), 62 code:add_pathsz(["ebin" | IncludeEbin]), 63 GeneratedFiles = dia_generated_files("dia", "src", "include"), 64 ok = rebar_file_utils:delete_each(GeneratedFiles), 65 ok. 66 67%% =================================================================== 68%% Internal functions 69%% =================================================================== 70 71info(help, compile) -> 72 info_help("Build Diameter (*.dia) sources"); 73info(help, clean) -> 74 info_help("Delete generated Diameter files"). 75 76info_help(Description) -> 77 ?CONSOLE( 78 "~s.~n" 79 "~n" 80 "Valid rebar.config options:~n" 81 " {dia_opts, []} (options from diameter_make:codec/2 supported with~n" 82 " exception of inherits)~n" 83 " {dia_first_files, []} (files in sequence to compile first)~n", 84 [Description]). 85 86-spec compile_dia(file:filename(), file:filename(), 87 rebar_config:config()) -> ok. 88compile_dia(Source, Target, Config) -> 89 ok = filelib:ensure_dir(Target), 90 ok = filelib:ensure_dir(filename:join("include", "dummy.hrl")), 91 ok = filelib:ensure_dir(filename:join("ebin", "dummy.beam")), 92 true = code:add_path(filename:absname("ebin")), 93 Opts = [{outdir, "src"}] ++ rebar_config:get(Config, dia_opts, []), 94 case diameter_dict_util:parse({path, Source}, []) of 95 {ok, Spec} -> 96 FileName = dia_filename(Source, Spec), 97 _ = diameter_codegen:from_dict(FileName, Spec, Opts, erl), 98 _ = diameter_codegen:from_dict(FileName, Spec, Opts, hrl), 99 HrlFile = filename:join("src", FileName ++ ".hrl"), 100 ErlFile = filename:join("src", FileName ++ ".erl"), 101 ErlCOpts = [{outdir, "ebin"}] ++ 102 rebar_config:get(Config, erl_opts, []), 103 _ = compile:file(ErlFile, ErlCOpts), 104 case filelib:is_regular(HrlFile) of 105 true -> 106 ok = rebar_file_utils:mv(HrlFile, "include"); 107 false -> 108 ok 109 end; 110 {error, Reason} -> 111 ?ABORT( 112 "Compiling ~s failed: ~s~n", 113 [Source, diameter_dict_util:format_error(Reason)] 114 ) 115 end. 116 117dia_generated_files(DiaDir, SrcDir, IncDir) -> 118 F = fun(File, Acc) -> 119 case catch diameter_dict_util:parse({path, File}, []) of 120 {ok, Spec} -> 121 FileName = dia_filename(File, Spec), 122 [ 123 filename:join([IncDir, FileName ++ ".hrl"]) | 124 filelib:wildcard( 125 filename:join([SrcDir, FileName ++ ".*"]) 126 ) 127 ] ++ Acc; 128 _ -> 129 Acc 130 end 131 end, 132 lists:foldl(F, [], filelib:wildcard(filename:join([DiaDir, "*.dia"]))). 133 134dia_filename(File, Spec) -> 135 case proplists:get_value(name, Spec) of 136 undefined -> 137 filename:rootname(filename:basename(File)); 138 Name -> 139 Name 140 end. 141