aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/compiler/diameter_make.erl
blob: 4431b88c4d3dbddd87712b9d414d0b40ad62efc4 (plain) (blame)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
%% 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 online 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.
%%
%% %CopyrightEnd%
%%

%%
%% Driver for the encoder generator utility.
%%

-module(diameter_make).

-export([spec/0,
         hrl/0,
         erl/0]).

-spec spec() -> no_return().
-spec hrl()  -> no_return().
-spec erl()  -> no_return().

spec() ->
    make(spec).

hrl() ->
    make(hrl).

erl() ->
    make(erl).

%% make/1

make(Mode) ->
    Args = init:get_plain_arguments(),
    Opts = try options(Args) catch throw: help -> help(Mode) end,
    Files = proplists:get_value(files, Opts, []),
    lists:foreach(fun(F) -> from_file(F, Mode, Opts) end, Files),
    halt(0).

%% from_file/3

from_file(F, Mode, Opts) ->
    try to_spec(F, Mode, Opts) of
        Spec ->
            from_spec(F, Spec, Mode, Opts)
    catch
        error: Reason ->
            io:format("==> ~p parse failure:~n~p~n",
                      [F, {Reason, erlang:get_stacktrace()}]),
            halt(1)
    end.

%% to_spec/2

%% Try to read the input as an already parsed file or else parse it.
to_spec(F, spec, Opts) ->
    diameter_spec_util:parse(F, Opts);
to_spec(F, _, _) ->
    {ok, [Spec]} = file:consult(F),
    Spec.

%% from_spec/4

from_spec(File, Spec, Mode, Opts) ->
    try
        diameter_codegen:from_spec(File, Spec, Opts, Mode)
    catch
        error: Reason ->
            io:format("==> ~p codegen failure:~n~p~n~p~n",
                      [Mode, File, {Reason, erlang:get_stacktrace()}]),
            halt(1)
    end.

%% options/1

options(["-v" | Rest]) ->
    [verbose | options(Rest)];

options(["-o", Outdir | Rest]) ->
    [{outdir, Outdir} | options(Rest)];

options(["-i", Incdir | Rest]) ->
    [{include, Incdir} | options(Rest)];

options(["-h" | _]) ->
    throw(help);

options(["--" | Fs]) ->
    [{files, Fs}];

options(["-" ++ _ = Opt | _]) ->
    io:fwrite("==> unknown option: ~s~n", [Opt]),
    throw(help);

options(Fs) ->  %% trailing arguments
    options(["--" | Fs]).

%% help/1

help(M) ->
    io:fwrite("Usage: ~p ~p [Options] [--] File ...~n"
              "Options:~n"
              " -v              verbose output~n"
              " -h              shows this help message~n"
              " -o OutDir       where to put the output files~n"
              " -i IncludeDir   where to search for beams to import~n",
              [?MODULE, M]),
    halt(1).