aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src/compile
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/src/compile')
-rw-r--r--lib/snmp/src/compile/Makefile21
-rw-r--r--lib/snmp/src/compile/depend.mk5
-rw-r--r--lib/snmp/src/compile/modules.mk5
-rw-r--r--lib/snmp/src/compile/snmpc.erl147
-rw-r--r--lib/snmp/src/compile/snmpc.hrl63
-rw-r--r--lib/snmp/src/compile/snmpc.src400
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl13
-rw-r--r--lib/snmp/src/compile/snmpc_lib.hrl15
-rw-r--r--lib/snmp/src/compile/snmpc_mib_gram.yrl330
-rw-r--r--lib/snmp/src/compile/snmpc_mib_to_hrl.erl5
-rw-r--r--lib/snmp/src/compile/snmpc_tok.erl9
11 files changed, 913 insertions, 100 deletions
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index 4be60e1835..627af6f185 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-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
@@ -20,6 +20,7 @@
include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
+BIN = ../../bin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -44,9 +45,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
include modules.mk
-ERL_FILES = $(MODULES:%=%.erl)
-
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
+ERL_FILES = $(MODULES:%=%.erl)
+EBIN_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+TARGET_FILES = $(EBIN_FILES) $(ESCRIPT_BIN)
GENERATED_PARSER = $(PARSER_MODULE:%=%.erl)
@@ -97,8 +99,12 @@ info:
@echo ""
@echo "EBIN: $(EBIN)"
@echo ""
+ @echo "ESCRIPT_SRC: $(ESCRIPT_SRC)"
+ @echo "ESCRIPT_BIN: $(ESCRIPT_BIN)"
+ @echo ""
@echo ""
+
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
@@ -107,6 +113,7 @@ parser: $(PARSER_TARGET)
$(GENERATED_PARSER): $(PARSER_SRC)
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -115,9 +122,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DIR) $(RELSYSDIR)/src/compiler
- $(INSTALL_DATA) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
+ $(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
$(INSTALL_DIR) $(RELSYSDIR)/ebin
- $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(EBIN_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/bin
+ $(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin
release_docs_spec:
diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk
index 75af1bf293..f7084f8bcd 100644
--- a/lib/snmp/src/compile/depend.mk
+++ b/lib/snmp/src/compile/depend.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+# Copyright Ericsson AB 2004-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
@@ -44,3 +44,6 @@ $(EBIN)/snmpc_mib_gram.$(EMULATOR): \
../../include/snmp_types.hrl \
snmpc_mib_gram.erl
+$(BIN)/snmpc: snmpc.src
+ $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
+ chmod 755 $@
diff --git a/lib/snmp/src/compile/modules.mk b/lib/snmp/src/compile/modules.mk
index 6365b0e694..399e4f865e 100644
--- a/lib/snmp/src/compile/modules.mk
+++ b/lib/snmp/src/compile/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+# Copyright Ericsson AB 2004-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
@@ -21,6 +21,9 @@ PARSER_SRC = snmpc_mib_gram.yrl
PARSER_MODULE = $(PARSER_SRC:%.yrl=%)
+ESCRIPT_SRC = \
+ snmpc.src
+
MODULES = \
$(PARSER_MODULE) \
snmpc \
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index a7f2cdc2bc..5e6b81f1ec 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -108,10 +108,13 @@ compile(FileName) ->
%% {i, [import_dir_string()]} ["./"]
%% {il, [import_lib_dir_string()]} []
%% {warnings, bool()} true
+%% warnings_as_errors
%% {outdir, string()} "./"
%% description
%% reference
%% imports
+%% agent_capabilities
+%% module_compliance
%% module_identity
%% {module, string()}
%% no_defs
@@ -197,12 +200,18 @@ get_options([reference|Opts], Formats, Args) ->
get_options(Opts, ["~n reference"|Formats], Args);
get_options([{warnings, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n warnings: ~w"|Formats], [Val|Args]);
+get_options([warnings_as_errors|Opts], Formats, Args) ->
+ get_options(Opts, ["~n warnings_as_errors"|Formats], Args);
get_options([{verbosity, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n verbosity: ~w"|Formats], [Val|Args]);
get_options([imports|Opts], Formats, Args) ->
get_options(Opts, ["~n imports"|Formats], Args);
get_options([module_identity|Opts], Formats, Args) ->
get_options(Opts, ["~n module_identity"|Formats], Args);
+get_options([module_compliance|Opts], Formats, Args) ->
+ get_options(Opts, ["~n module_compliance"|Formats], Args);
+get_options([agent_capabilities|Opts], Formats, Args) ->
+ get_options(Opts, ["~n agent_capabilities"|Formats], Args);
get_options([relaxed_row_name_assign_check|Opts], Formats, Args) ->
get_options(Opts, ["~n relaxed_row_name_assign_check"|Formats], Args);
get_options([_|Opts], Formats, Args) ->
@@ -255,6 +264,8 @@ check_options([{group_check, Atom} | T]) when is_atom(Atom) ->
check_options([{warnings, Bool} | T]) ->
check_bool(warnings, Bool),
check_options(T);
+check_options([warnings_as_errors | T]) ->
+ check_options(T);
check_options([{db, volatile} | T]) ->
check_options(T);
check_options([{db, persistent} | T]) ->
@@ -288,6 +299,10 @@ check_options([imports| T]) ->
check_options(T);
check_options([module_identity| T]) ->
check_options(T);
+check_options([module_compliance| T]) ->
+ check_options(T);
+check_options([agent_capabilities| T]) ->
+ check_options(T);
check_options([relaxed_row_name_assign_check| T]) ->
check_options(T);
check_options([{module, M} | T]) when is_atom(M) ->
@@ -315,6 +330,15 @@ get_description(Options) ->
get_reference(Options) ->
get_bool_option(reference, Options).
+get_agent_capabilities(Options) ->
+ get_bool_option(agent_capabilities, Options).
+
+get_module_compliance(Options) ->
+ get_bool_option(module_compliance, Options).
+
+get_warnings_as_errors(Options) ->
+ lists:member(warnings_as_errors, Options).
+
get_relaxed_row_name_assign_check(Options) ->
lists:member(relaxed_row_name_assign_check, Options).
@@ -387,10 +411,13 @@ get_verbosity(Options) ->
init(From, MibFileName, Options) ->
{A,B,C} = now(),
random:seed(A,B,C),
- put(options, Options),
- put(verbosity, get_verbosity(Options)),
- put(description, get_description(Options)),
- put(reference, get_reference(Options)),
+ put(options, Options),
+ put(verbosity, get_verbosity(Options)),
+ put(description, get_description(Options)),
+ put(reference, get_reference(Options)),
+ put(agent_capabilities, get_agent_capabilities(Options)),
+ put(module_compliance, get_module_compliance(Options)),
+ put(warnings_as_errors, get_warnings_as_errors(Options)),
File = filename:rootname(MibFileName, ".mib"),
put(filename, filename:basename(File ++ ".mib")),
R = case catch c_impl(File) of
@@ -876,12 +903,12 @@ definitions_loop([{#mc_object_type{name = NameOfEntry,
definitions_loop([{#mc_notification{name = TrapName,
status = deprecated}, Line}|T],
- false) ->
+ #dldata{deprecated = false} = Data) ->
?vinfo2("defloop -> notification ~w is deprecated => ignored",
[TrapName], Line),
update_status(TrapName, deprecated),
ensure_macro_imported('NOTIFICATION-TYPE', Line),
- definitions_loop(T, false);
+ definitions_loop(T, Data);
definitions_loop([{#mc_notification{name = TrapName,
status = obsolete}, Line}|T],
@@ -921,10 +948,96 @@ definitions_loop([{#mc_notification{name = TrapName,
snmpc_lib:add_cdata(#cdata.traps, [Notif]),
definitions_loop(T, Data);
-definitions_loop([{#mc_module_compliance{name = Name},Line}|T], Data) ->
- ?vlog2("defloop -> module_compliance:"
- "~n Name: ~p", [Name], Line),
+definitions_loop([{#mc_agent_capabilities{name = Name,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = {Parent, SubIdx}},Line}|T], Data) ->
+ ?vlog2("defloop -> agent_capabilities ~p:"
+ "~n Status: ~p"
+ "~n Desc: ~p"
+ "~n Ref: ~p"
+ "~n Mods: ~p"
+ "~n Parent: ~p"
+ "~n SubIndex: ~p",
+ [Name, Status, Desc, Ref, Mods, Parent, SubIdx], Line),
+ ensure_macro_imported('AGENT-CAPABILITIES', Line),
+ case get(agent_capabilities) of
+ true ->
+ update_status(Name, Status),
+ snmpc_lib:register_oid(Line, Name, Parent, SubIdx),
+ NewME = snmpc_lib:makeInternalNode2(false, Name),
+ Description = make_description(Desc),
+ Reference =
+ case Ref of
+ undefined ->
+ [];
+ _ ->
+ [{reference, Ref}]
+ end,
+ Modules =
+ case Mods of
+ undefined ->
+ [];
+ [] ->
+ [];
+ _ ->
+ [{modules, Mods}]
+ end,
+ AssocList = Reference ++ Modules,
+ NewME2 = NewME#me{description = Description,
+ assocList = AssocList},
+ snmpc_lib:add_cdata(#cdata.mes, [NewME2]);
+ _ ->
+ ok
+ end,
+ definitions_loop(T, Data);
+
+definitions_loop([{#mc_module_compliance{name = Name,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = {Parent, SubIdx}},Line}|T], Data) ->
+ ?vlog2("defloop -> module_compliance: ~p"
+ "~n Status: ~p"
+ "~n Desc: ~p"
+ "~n Ref: ~p"
+ "~n Mods: ~p"
+ "~n Parent: ~p"
+ "~n SubIndex: ~p",
+ [Name, Status, Desc, Ref, Mods, Parent, SubIdx], Line),
ensure_macro_imported('MODULE-COMPLIANCE', Line),
+ case get(module_compliance) of
+ true ->
+ update_status(Name, Status),
+ snmpc_lib:register_oid(Line, Name, Parent, SubIdx),
+ NewME = snmpc_lib:makeInternalNode2(false, Name),
+ Description = make_description(Desc),
+ Reference =
+ case Ref of
+ undefined ->
+ [];
+ _ ->
+ [{reference, Ref}]
+ end,
+ Modules =
+ case Mods of
+ undefined ->
+ [];
+ [] ->
+ [];
+ _ ->
+ [{modules, Mods}]
+ end,
+ AssocList = Reference ++ Modules,
+ NewME2 = NewME#me{description = Description,
+ assocList = AssocList},
+ snmpc_lib:add_cdata(#cdata.mes, [NewME2]);
+ _ ->
+ ok
+ end,
definitions_loop(T, Data);
definitions_loop([{#mc_object_group{name = Name,
@@ -1328,22 +1441,26 @@ save(Filename, MibName, Options) ->
parse(FileName) ->
+%% ?vtrace("parse -> start tokenizer for ~p", [FileName]),
case snmpc_tok:start_link(reserved_words(),
[{file, FileName ++ ".mib"},
{forget_stringdata, true}]) of
{error,ReasonStr} ->
snmpc_lib:error(lists:flatten(ReasonStr),[]);
{ok, TokPid} ->
+%% ?vtrace("parse -> tokenizer start, now get tokens", []),
Toks = snmpc_tok:get_all_tokens(TokPid),
+%% ?vtrace("parse -> tokens: ~p", [Toks]),
set_version(Toks),
- %% io:format("parse -> lexical analysis: ~n~p~n", [Toks]),
- %% t("parse -> lexical analysis: ~n~p", [Toks]),
+ %% ?vtrace("parse -> lexical analysis: ~n~p", [Toks]),
CDataArg =
case lists:keysearch(module, 1, get(options)) of
{value, {module, M}} -> {module, M};
_ -> {file, FileName ++ ".funcs"}
end,
put(cdata,snmpc_lib:make_cdata(CDataArg)),
+%% ?vtrace("parse -> stop tokenizer and then do the actual parse",
+%% []),
snmpc_tok:stop(TokPid),
Res = if
is_list(Toks) ->
@@ -1351,7 +1468,7 @@ parse(FileName) ->
true ->
Toks
end,
- %% t("parse -> parsed: ~n~p", [Res]),
+%% ?vtrace("parse -> parsed result: ~n~p", [Res]),
case Res of
{ok, PData} ->
{ok, PData};
@@ -1443,6 +1560,10 @@ reserved_words() ->
'NOTIFICATION-GROUP',
'NOTIFICATIONS',
'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES',
+ 'PRODUCT-RELEASE',
+ 'SUPPORTS',
+ 'INCLUDES',
'MODULE',
'MANDATORY-GROUPS',
'GROUP',
diff --git a/lib/snmp/src/compile/snmpc.hrl b/lib/snmp/src/compile/snmpc.hrl
index eb896cde6b..1c0808d065 100644
--- a/lib/snmp/src/compile/snmpc.hrl
+++ b/lib/snmp/src/compile/snmpc.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -103,16 +103,75 @@
).
+-record(mc_agent_capabilities,
+ {name,
+ product_release,
+ status,
+ description,
+ reference,
+ modules,
+ name_assign
+ }
+ ).
+
+-record(mc_ac_module,
+ {name,
+ groups,
+ variation
+ }
+ ).
+
+-record(mc_ac_object_variation,
+ {name,
+ syntax,
+ write_syntax,
+ access,
+ creation,
+ default_value,
+ description
+ }
+ ).
+
+-record(mc_ac_notification_variation,
+ {name,
+ access,
+ description
+ }
+ ).
+
+
-record(mc_module_compliance,
{name,
status,
description,
reference,
- module,
+ modules,
name_assign
}
).
+-record(mc_mc_compliance_group,
+ {name,
+ description
+ }
+ ).
+
+-record(mc_mc_object,
+ {name,
+ syntax,
+ write_syntax,
+ access,
+ description
+ }
+ ).
+
+-record(mc_mc_module,
+ {name,
+ mandatory,
+ compliance
+ }
+ ).
+
-record(mc_object_group,
{name,
diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src
new file mode 100644
index 0000000000..f993335b89
--- /dev/null
+++ b/lib/snmp/src/compile/snmpc.src
@@ -0,0 +1,400 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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%
+%%
+%% SNMP MIB compiler frontend
+%%
+
+-mode(compile).
+
+-include_lib("kernel/include/file.hrl").
+-include_lib("snmp/include/snmp_types.hrl").
+
+
+-record(state,
+ {
+ version = "%VSN%",
+ mfv,
+ file, % .mib or .bin depending on which are compiled
+ outdir = "./",
+ db = volatile,
+ include_dirs = ["./"],
+ include_lib_dirs = [],
+ deprecated = false,
+ group_check = true,
+ description = false,
+ reference = false,
+ imports = false,
+ module_identity = false,
+ module_compliance = false,
+ agent_capabilities = false,
+ module,
+ no_defaults = false,
+ relaxed_row_name_assign_check = false,
+ %% The default verbosity (silence) will be filled in
+ %% during argument processing.
+ verbosity,
+ warnings = false,
+ warnings_as_errors = false
+ }).
+
+
+%% ------------------------------------------------------------------------
+%% Valid arguments:
+%% --o Dir [defaults to "./"]
+%% --i Dir [defaults to "./"]
+%% --il Dir
+%% --sgc
+%% --db DB [defaults to volatile]
+%% --dep
+%% --desc
+%% --ref
+%% --imp
+%% --mi
+%% --mc
+%% --ac
+%% --mod Mod
+%% --nd
+%% --rrnac
+%% --version
+%% --verbosity V
+%% --warnings
+%% --Werror | --wae | --warnings_as_errors
+main(Args) when is_list(Args) ->
+ case (catch process_args(Args)) of
+ ok ->
+ usage();
+ {ok, State} when is_record(State, state) ->
+ compile(State);
+ {ok, Str} when is_list(Str) ->
+ io:format("~s~n~n", [Str]),
+ halt(1);
+ {error, ReasonStr} ->
+ usage(ReasonStr)
+ end;
+main(_) ->
+ usage().
+
+compile(State) ->
+ %% io:format("snmpc: ~p~n", [State]),
+ case mk_file(State) of
+ {mib, File} ->
+ Options = mk_mib_options(State),
+ case mib2bin(File, Options) of
+ {ok, _BinFileName} ->
+ ok;
+ {error, Reason} ->
+ io:format("ERROR: Failed compiling mib: "
+ "~n ~p~n", [Reason]),
+ halt(1)
+ end;
+ {bin, File} ->
+ Options = mk_hrl_options(State),
+ case bin2hrl(File, Options) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ io:format("ERROR: Failed generating hrl from mib: "
+ "~n ~p~n", [Reason]),
+ halt(1)
+ end
+ end.
+
+mib2bin(MibFileName, Options) ->
+ snmpc:compile(MibFileName, Options).
+
+bin2hrl(BinFileName, {OutDir, Verbosity}) ->
+ MibName = filename:basename(BinFileName),
+ BinFile = BinFileName ++ ".bin",
+ HrlFile = filename:join(OutDir, MibName) ++ ".hrl",
+ put(verbosity, Verbosity),
+ snmpc_mib_to_hrl:convert(BinFile, HrlFile, MibName).
+
+
+mk_file(#state{file = MIB}) ->
+ DirName = filename:dirname(MIB),
+ case filename:extension(MIB) of
+ ".mib" ->
+ BaseName = filename:basename(MIB, ".mib"),
+ {mib, filename:join(DirName, BaseName)};
+ ".bin" ->
+ BaseName = filename:basename(MIB, ".bin"),
+ {bin, filename:join(DirName, BaseName)};
+ BadExt ->
+ e(lists:flatten(io_lib:format("Unsupported file type: ~s", [BadExt])))
+ end.
+
+mk_mib_options(#state{outdir = OutDir,
+ db = DB,
+ include_dirs = IDs,
+ include_lib_dirs = ILDs,
+ deprecated = Dep,
+ group_check = GC,
+ description = Desc,
+ reference = Ref,
+ imports = Imp,
+ module_identity = MI,
+ module_compliance = MC,
+ agent_capabilities = AC,
+ module = Mod,
+ no_defaults = ND,
+ relaxed_row_name_assign_check = RRNAC,
+ %% The default verbosity (silence) will be filled in
+ %% during argument processing.
+ verbosity = V,
+ warnings = W,
+ warnings_as_errors = WAE}) ->
+ [{outdir, OutDir},
+ {db, DB},
+ {i, IDs},
+ {il, ILDs},
+ {group_check, GC},
+ {verbosity, V},
+ {warnings, W},
+ {deprecated, Dep}] ++
+ if
+ (Mod =/= undefined) ->
+ [{module, Mod}];
+ true ->
+ []
+ end ++
+ maybe_option(ND, no_defs) ++
+ maybe_option(RRNAC, relaxed_row_name_assign_check) ++
+ maybe_option(Desc, description) ++
+ maybe_option(Ref, reference) ++
+ maybe_option(Imp, imports) ++
+ maybe_option(MI, module_identity) ++
+ maybe_option(MC, module_compliance) ++
+ maybe_option(AC, agent_capabilities) ++
+ maybe_option(WAE, warnings_as_errors).
+
+maybe_option(true, Opt) -> [Opt];
+maybe_option(_, _) -> [].
+
+
+mk_hrl_options(#state{outdir = OutDir,
+ verbosity = Verbosity}) ->
+ {OutDir, Verbosity}.
+
+
+process_args([]) ->
+ e("No input file");
+process_args(Args) ->
+ #mib{mib_format_version = MFV} = #mib{},
+ State = #state{},
+ process_args(Args, State#state{mfv = MFV}).
+
+process_args([], #state{verbosity = Verbosity0, file = MIB} = State) ->
+ if
+ (MIB =:= undefined) ->
+ e("No input file");
+ true ->
+ Verbosity =
+ case Verbosity0 of
+ undefined ->
+ silence;
+ _ ->
+ Verbosity0
+ end,
+ IPath = lists:reverse(State#state.include_dirs),
+ IlPath = lists:reverse(State#state.include_lib_dirs),
+ {ok, State#state{verbosity = Verbosity,
+ include_dirs = IPath,
+ include_lib_dirs = IlPath}}
+ end;
+process_args(["--help"|_Args], _State) ->
+ ok;
+process_args(["--version"|_Args], #state{version = Version, mfv = MFV} = _State) ->
+ {ok, lists:flatten(io_lib:format("snmpc ~s (~s)", [Version, MFV]))};
+process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State)
+ when (V =:= undefined) ->
+ Verbosity = list_to_atom(Verbosity0),
+ case lists:member(Verbosity, [trace,debug,log,info,silence]) of
+ true ->
+ process_args(Args, State#state{verbosity = Verbosity});
+ false ->
+ e(lists:flatten(io_lib:format("Unknown verbosity: ~s", [Verbosity0])))
+ end;
+process_args(["--verbosity"|_Args], #state{verbosity = V})
+ when (V =/= undefined) ->
+ e(lists:flatten(io_lib:format("Verbosity already set to ~w", [V])));
+process_args(["--w"|Args], State) ->
+ process_args(Args, State#state{warnings = true});
+process_args(["--warnings"|Args], State) ->
+ process_args(Args, State#state{warnings = true});
+process_args(["--o", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ process_args(Args, State#state{outdir = Dir});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--i", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ IPath = [Dir | State#state.include_dirs],
+ process_args(Args, State#state{include_dirs = IPath});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--il", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ IlPath = [Dir | State#state.include_lib_dirs],
+ process_args(Args, State#state{include_lib_dirs = IlPath});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--db", DB0|Args], State) ->
+ DB = list_to_atom(DB0),
+ case lists:member(DB, [volatile,persistent,mnesia]) of
+ true ->
+ process_args(Args, State#state{db = DB});
+ false ->
+ e(lists:flatten(io_lib:format("Invalid db: ~s", [DB0])))
+ end;
+process_args(["--dep"|Args], State) ->
+ process_args(Args, State#state{deprecated = true});
+process_args(["--sgc"|Args], State) ->
+ process_args(Args, State#state{group_check = false});
+process_args(["--desc"|Args], State) ->
+ process_args(Args, State#state{description = true});
+process_args(["--ref"|Args], State) ->
+ process_args(Args, State#state{reference = true});
+process_args(["--imp"|Args], State) ->
+ process_args(Args, State#state{imports = true});
+process_args(["--mi"|Args], State) ->
+ process_args(Args, State#state{module_identity = true});
+process_args(["--mod", Module0|Args], #state{module = M} = State)
+ when (M =:= undefined) ->
+ Module = list_to_atom(Module0),
+ process_args(Args, State#state{module = Module});
+process_args(["--mod"|_Args], #state{module = M})
+ when (M =/= undefined) ->
+ e(lists:flatten(io_lib:format("Module already set to ~w", [M])));
+process_args(["--nd"|Args], State) ->
+ process_args(Args, State#state{no_defaults = true});
+process_args(["--rrnac"|Args], State) ->
+ process_args(Args, State#state{relaxed_row_name_assign_check = true});
+process_args(["--Werror"|Args], State) ->
+ process_args(Args, State#state{warnings_as_errors = true});
+process_args(["--wae"|Args], State) ->
+ process_args(Args, State#state{warnings_as_errors = true});
+process_args(["--warnings_as_errors"|Args], State) ->
+ process_args(Args, State#state{warnings_as_errors = true});
+process_args([MIB], State) ->
+ Ext = filename:extension(MIB),
+ if
+ ((Ext =:= ".mib") orelse (Ext =:= ".bin")) ->
+ case (catch file:read_file_info(MIB)) of
+ {ok, #file_info{type = regular}} ->
+ process_args([], State#state{file = MIB});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("~s not a file: ~w", [MIB, BadType])));
+ {error, enoent} ->
+ e(lists:flatten(io_lib:format("No such file: ~s", [MIB])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad file: ~s", [MIB])))
+ end;
+ true ->
+ e(lists:flatten(io_lib:format("Unknown option: ~s", [MIB])))
+ end;
+process_args([Arg|Args], _State) when Args =/= [] ->
+ e(lists:flatten(io_lib:format("Unknown option: ~s", [Arg]))).
+
+usage(ReasonStr) ->
+ io:format("ERROR: ~s~n", [ReasonStr]),
+ usage().
+
+usage() ->
+ io:format("Usage: snmpc [options] MIB.mib|MIB.bin"
+ "~nCompile a MIB (.mib -> .bin) or generate an erlang header "
+ "~nfile from a compiled MIB file (.bin -> .hrl)"
+ "~nOptions:"
+ "~n --help - Prints this info."
+ "~n --version - Prints compiler version."
+ "~n --verbosity <verbosity> - Print debug info."
+ "~n verbosity = trace | debug | log | info | silence"
+ "~n Defaults to silence."
+ "~n --warnings | --W - Print warning messages."
+ "~n --o <output dir> - The output dir."
+ "~n Defaults to current working dir."
+ "~n --i <include dir> - Add this dir to the list of dirs that will be"
+ "~n searched for imported (compiled) MIB files."
+ "~n The current workin dir will always be included. "
+ "~n --il <include_lib dir> - Add this dir to the list of dirs that will be"
+ "~n searched for imported (compiled) MIB files."
+ "~n It assumes that the first element in the dir "
+ "~n name correspond to an OTP application. "
+ "~n For example snmp/mibs/ "
+ "~n The current workin dir and the "
+ "~n <snmp-home>/priv/mibs "
+ "~n are always listed last the includ path. "
+ "~n --db <DB> - Database to used for the default instrumentation."
+ "~n Defaults to volatile."
+ "~n --sgc - This option (skip group check), if present, "
+ "~n disables the \"group check\" of the mib compiler. "
+ "~n That is, should the OBJECT-GROUP and the "
+ "~n NOTIFICATION-GROUP macro(s) be checked for "
+ "~n correctness or not. "
+ "~n By default the check is done. "
+ "~n --dep - Keep deprecated definition(s)."
+ "~n If not specified the compiler will ignore"
+ "~n deprecated definitions."
+ "~n --desc - The DESCRIPTION field will be included."
+ "~n --ref - The REFERENCE field will be included."
+ "~n --imp - The IMPORTS field will be included."
+ "~n --mi - The MODULE-IDENTITY field will be included."
+ "~n --mc - The MODULE-COMPLIANCE field will be included."
+ "~n --ac - The AGENT-CAPABILITIES field will be included."
+ "~n --mod <module> - The module which implements all the "
+ "~n instrumentation functions. "
+ "~n The name of all instrumentation functions must"
+ "~n be the same as the corresponding managed object"
+ "~n it implements."
+ "~n --nd - The default instrumentation functions will *not* "
+ "~n be used if a managed object have no "
+ "~n instrumentation function. Instead this will be "
+ "~n reported as an error, and the compilation aborts. "
+ "~n --rrnac - This option, if present, specifies that the row "
+ "~n name assign check shall not be done strictly "
+ "~n according to the SMI (which allows only the "
+ "~n value 1). With this option, all values greater "
+ "~n than zero is allowed (>= 1). "
+ "~n This means that the error will be converted to "
+ "~n a warning. "
+ "~n By default it is not included, but if this "
+ "~n option is present it will be. "
+ "~n --wae | --Werror - Warnings as errors. "
+ "~n Indicates that warnings shall be treated as "
+ "~n errors. "
+ "~n "
+ "~n", []),
+ halt(1).
+
+
+e(Reason) ->
+ throw({error, Reason}).
+
diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index 4e5bc69f81..38bb8f3ac6 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -20,6 +20,8 @@
-module(snmpc_lib).
%% API
+%% Avoid warning for local function error/2 clashing with autoimported BIF.
+-compile({no_auto_import,[error/2]}).
-export([test_father/4, make_ASN1type/1, import/1, makeInternalNode2/2,
is_consistent/1, resolve_defval/1, make_variable_info/1,
check_trap_name/3, make_table_info/4, get_final_mib/2, set_dir/2,
@@ -304,7 +306,10 @@ import_mib({{'SNMPv2-TC', ImportsFromMib},Line}) ->
Macros = ['TEXTUAL-CONVENTION'],
import_built_in_loop(ImportsFromMib,Nodes,Types,Macros,'SNMPv2-TC',Line);
import_mib({{'SNMPv2-CONF', ImportsFromMib},Line}) ->
- Macros = ['OBJECT-GROUP','NOTIFICATION-GROUP','MODULE-COMPLIANCE'],
+ Macros = ['OBJECT-GROUP',
+ 'NOTIFICATION-GROUP',
+ 'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES'],
import_built_in_loop(ImportsFromMib,[],[],Macros,'SNMPv2-CONF',Line);
import_mib({{'RFC1155-SMI', ImportsFromMib},Line}) ->
Nodes = [makeInternalNode(internet, [1,3,6,1]),
@@ -1749,12 +1754,12 @@ error(FormatStr, Data, Line) when is_list(FormatStr) ->
exit(error).
print_error(FormatStr, Data) when is_list(FormatStr) ->
- ok = io:format("~s: Error: " ++ FormatStr,[get(filename)|Data]),
+ ok = io:format("~s: " ++ FormatStr,[get(filename)|Data]),
put(errors,yes),
io:format("~n").
print_error(FormatStr, Data,Line) when is_list(FormatStr) ->
- ok = io:format("~s: ~w: Error: " ++ FormatStr,[get(filename), Line |Data]),
+ ok = io:format("~s: ~w: " ++ FormatStr,[get(filename), Line |Data]),
put(errors,yes),
io:format("~n").
diff --git a/lib/snmp/src/compile/snmpc_lib.hrl b/lib/snmp/src/compile/snmpc_lib.hrl
index 000486e728..35ec9abd03 100644
--- a/lib/snmp/src/compile/snmpc_lib.hrl
+++ b/lib/snmp/src/compile/snmpc_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% Copyright Ericsson AB 2009-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
@@ -20,8 +20,17 @@
-ifndef(snmpc_lib).
-define(snmpc_lib, true).
--define(vwarning(F, A), ?verbosity(warning, F, A, ignore)).
--define(vwarning2(F, A, MibLine), ?verbosity(warning, F, A, MibLine)).
+-define(vwarning(F, A),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A);
+ _ -> ?verbosity(warning, F, A, ignore)
+ end).
+
+-define(vwarning2(F, A, MibLine),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A, MibLine);
+ _ -> ?verbosity(warning, F, A, MibLine)
+ end).
-define(vinfo(F, A), ?verbosity(info, F, A, ignore)).
-define(vinfo2(F, A, MibLine), ?verbosity(info, F, A, MibLine)).
-define(vlog(F, A), ?verbosity(log, F, A, ignore)).
diff --git a/lib/snmp/src/compile/snmpc_mib_gram.yrl b/lib/snmp/src/compile/snmpc_mib_gram.yrl
index 1957f52936..74b9ddaa25 100644
--- a/lib/snmp/src/compile/snmpc_mib_gram.yrl
+++ b/lib/snmp/src/compile/snmpc_mib_gram.yrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -59,6 +59,7 @@ newtypename
objectidentifier
objectname
objecttypev1
+prodrel
range_num
referpart
size
@@ -79,7 +80,7 @@ revisions
listofdefinitionsv2
mibid
last_updated
-oranization
+organization
contact_info
revision
revision_string
@@ -101,19 +102,31 @@ textualconvention
objectgroup
notificationgroup
modulecompliance
-modulepart
-modules
-module
-modulenamepart
-mandatorypart
-compliancepart
-compliances
-compliance
-compliancegroup
-object
+mc_modulepart
+mc_modules
+mc_module
+mc_modulenamepart
+mc_mandatorypart
+mc_compliancepart
+mc_compliances
+mc_compliance
+mc_compliancegroup
+mc_object
+mc_accesspart
+agentcapabilities
+ac_status
+ac_modulepart
+ac_modules
+ac_module
+ac_modulenamepart
+ac_variationpart
+ac_variations
+ac_variation
+ac_accesspart
+ac_access
+ac_creationpart
syntaxpart
writesyntaxpart
-accesspart
fsyntax
defbitsvalue
defbitsnames
@@ -161,6 +174,12 @@ integer variable atom string quote '{' '}' '::=' ':' '=' ',' '.' '(' ')' ';' '|'
'CONTACT-INFO'
'MODULE-IDENTITY'
'NOTIFICATION-TYPE'
+'PRODUCT-RELEASE'
+'AGENT-CAPABILITIES'
+'INCLUDES'
+'SUPPORTS'
+'VARIATION'
+'CREATION-REQUIRES'
'MODULE-COMPLIANCE'
'OBJECT-GROUP'
'NOTIFICATION-GROUP'
@@ -212,8 +231,8 @@ mib -> mibname 'DEFINITIONS' implies 'BEGIN'
defs = Defs}.
v1orv2 -> moduleidentity listofdefinitionsv2 :
- {v2_mib, ['$1'|lists:reverse('$2')]}.
-v1orv2 -> listofdefinitions : {v1_mib, lists:reverse('$1')}.
+ {v2_mib, ['$1'|lreverse(v1orv2_mod, '$2')]}.
+v1orv2 -> listofdefinitions : {v1_mib, lreverse(v1orv2_list, '$1')}.
definition -> objectidentifier : '$1'.
definition -> objecttypev1 : '$1'.
@@ -231,7 +250,7 @@ imports -> imports_from_one_mib : ['$1'].
imports -> imports_from_one_mib imports : ['$1' | '$2'].
imports_from_one_mib -> listofimports 'FROM' variable :
- {{val('$3'), lists:reverse('$1')}, line_of('$2')}.
+ {{val('$3'), lreverse(imports_from_one_mib, '$1')}, line_of('$2')}.
listofimports -> import_stuff : ['$1'].
listofimports -> listofimports ',' import_stuff : ['$3' | '$1'].
@@ -251,6 +270,8 @@ import_stuff -> 'MODULE-IDENTITY'
: ensure_ver(2,'$1'), {builtin, 'MODULE-IDENTITY'}.
import_stuff -> 'NOTIFICATION-TYPE'
: ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-TYPE'}.
+import_stuff -> 'AGENT-CAPABILITIES'
+ : ensure_ver(2,'$1'), {builtin, 'AGENT-CAPABILITIES'}.
import_stuff -> 'MODULE-COMPLIANCE'
: ensure_ver(2,'$1'), {builtin, 'MODULE-COMPLIANCE'}.
import_stuff -> 'NOTIFICATION-GROUP'
@@ -296,7 +317,7 @@ import_stuff -> 'TAddress'
traptype -> objectname 'TRAP-TYPE' 'ENTERPRISE' objectname varpart
description referpart implies integer :
- Trap = make_trap('$1', '$4', lists:reverse('$5'),
+ Trap = make_trap('$1', '$4', lreverse(traptype, '$5'),
'$6', '$7', val('$9')),
{Trap, line_of('$2')}.
@@ -324,7 +345,7 @@ newtype -> newtypename implies syntax :
{NT, line_of('$2')}.
tableentrydefinition -> newtypename implies 'SEQUENCE' '{' fields '}' :
- Seq = make_sequence('$1', lists:reverse('$5')),
+ Seq = make_sequence('$1', lreverse(tableentrydefinition, '$5')),
{Seq, line_of('$3')}.
% returns: list of {<fieldname>, <asn1_type>}
@@ -408,9 +429,9 @@ variables -> variables ',' objectname : ['$3' | '$1'].
implies -> '::=' : '$1'.
implies -> ':' ':' '=' : w("Sloppy asignment on line ~p", [line_of('$1')]), '$1'.
-descriptionfield -> string : lists:reverse(val('$1')).
+descriptionfield -> string : lreverse(descriptionfield, val('$1')).
descriptionfield -> '$empty' : undefined.
-description -> 'DESCRIPTION' string : lists:reverse(val('$2')).
+description -> 'DESCRIPTION' string : lreverse(description, val('$2')).
description -> '$empty' : undefined.
displaypart -> 'DISPLAY-HINT' string : display_hint('$2') .
@@ -418,7 +439,7 @@ displaypart -> '$empty' : undefined .
% returns: {indexes, undefined}
% | {indexes, IndexList} where IndexList is a list of aliasnames.
-indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lists:reverse('$3')}.
+indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lreverse(indexpartv1, '$3')}.
indexpartv1 -> '$empty' : {indexes, undefined}.
indextypesv1 -> indextypev1 : ['$1'].
@@ -436,14 +457,16 @@ parentintegers -> atom '(' integer ')' parentintegers : [val('$3') | '$5'].
defvalpart -> 'DEFVAL' '{' integer '}' : {defval, val('$3')}.
defvalpart -> 'DEFVAL' '{' atom '}' : {defval, val('$3')}.
defvalpart -> 'DEFVAL' '{' '{' defbitsvalue '}' '}' : {defval, '$4'}.
-defvalpart -> 'DEFVAL' '{' quote atom '}'
- : {defval, make_defval_for_string(line_of('$1'), lists:reverse(val('$3')),
- val('$4'))}.
-defvalpart -> 'DEFVAL' '{' quote variable '}'
- : {defval, make_defval_for_string(line_of('$1'), lists:reverse(val('$3')),
- val('$4'))}.
-defvalpart -> 'DEFVAL' '{' string '}'
- : {defval, lists:reverse(val('$3'))}.
+defvalpart -> 'DEFVAL' '{' quote atom '}' :
+ {defval, make_defval_for_string(line_of('$1'),
+ lreverse(defvalpart_quote_atom, val('$3')),
+ val('$4'))}.
+defvalpart -> 'DEFVAL' '{' quote variable '}' :
+ {defval, make_defval_for_string(line_of('$1'),
+ lreverse(defvalpart_quote_variable, val('$3')),
+ val('$4'))}.
+defvalpart -> 'DEFVAL' '{' string '}' :
+ {defval, lreverse(defvalpart_string, val('$3'))}.
defvalpart -> '$empty' : undefined.
defbitsvalue -> defbitsnames : '$1'.
@@ -461,7 +484,7 @@ accessv1 -> atom: accessv1('$1').
statusv1 -> atom : statusv1('$1').
-referpart -> 'REFERENCE' string : lists:reverse(val('$2')).
+referpart -> 'REFERENCE' string : lreverse(referpart, val('$2')).
referpart -> '$empty' : undefined.
@@ -471,7 +494,7 @@ referpart -> '$empty' : undefined.
%%----------------------------------------------------------------------
moduleidentity -> mibid 'MODULE-IDENTITY'
'LAST-UPDATED' last_updated
- 'ORGANIZATION' oranization
+ 'ORGANIZATION' organization
'CONTACT-INFO' contact_info
'DESCRIPTION' descriptionfield
revisionpart nameassign :
@@ -480,20 +503,20 @@ moduleidentity -> mibid 'MODULE-IDENTITY'
{MI, line_of('$2')}.
mibid -> atom : val('$1').
-last_updated -> string : lists:reverse(val('$1')) .
-oranization -> string : lists:reverse(val('$1')) .
-contact_info -> string : lists:reverse(val('$1')) .
+last_updated -> string : lreverse(last_updated, val('$1')) .
+organization -> string : lreverse(organization, val('$1')) .
+contact_info -> string : lreverse(contact_info, val('$1')) .
revisionpart -> '$empty' : [] .
-revisionpart -> revisions : lists:reverse('$1') .
+revisionpart -> revisions : lreverse(revisionpart, '$1') .
revisions -> revision : ['$1'] .
revisions -> revisions revision : ['$2' | '$1'] .
revision -> 'REVISION' revision_string 'DESCRIPTION' revision_desc :
make_revision('$2', '$4') .
-revision_string -> string : lists:reverse(val('$1')) .
-revision_desc -> string : lists:reverse(val('$1')) .
+revision_string -> string : lreverse(revision_string, val('$1')) .
+revision_desc -> string : lreverse(revision_desc, val('$1')) .
definitionv2 -> objectidentifier : '$1'.
definitionv2 -> objecttypev2 : '$1'.
@@ -505,6 +528,7 @@ definitionv2 -> notification : '$1'.
definitionv2 -> objectgroup : '$1'.
definitionv2 -> notificationgroup : '$1'.
definitionv2 -> modulecompliance : '$1'.
+definitionv2 -> agentcapabilities : '$1'.
listofdefinitionsv2 -> '$empty' : [] .
listofdefinitionsv2 -> listofdefinitionsv2 definitionv2 : ['$2' | '$1'].
@@ -535,46 +559,127 @@ notificationgroup -> objectname 'NOTIFICATION-GROUP' 'NOTIFICATIONS' '{'
{NG, line_of('$2')}.
modulecompliance -> objectname 'MODULE-COMPLIANCE' 'STATUS' statusv2
- description referpart modulepart nameassign :
+ description referpart mc_modulepart nameassign :
+%% io:format("modulecompliance -> "
+%% "~n '$1': ~p"
+%% "~n '$4': ~p"
+%% "~n '$5': ~p"
+%% "~n '$6': ~p"
+%% "~n '$7': ~p"
+%% "~n '$8': ~p"
+%% "~n", ['$1', '$4', '$5', '$6', '$7', '$8']),
MC = make_module_compliance('$1', '$4', '$5', '$6',
'$7', '$8'),
+%% io:format("modulecompliance -> "
+%% "~n MC: ~p"
+%% "~n", [MC]),
{MC, line_of('$2')}.
-modulepart -> '$empty'.
-modulepart -> modules.
-modules -> module.
-modules -> modules module.
+agentcapabilities -> objectname 'AGENT-CAPABILITIES'
+ 'PRODUCT-RELEASE' prodrel
+ 'STATUS' ac_status
+ description referpart ac_modulepart nameassign :
+ AC = make_agent_capabilities('$1', '$4', '$6', '$7',
+ '$8', '$9', '$10'),
+ {AC, line_of('$2')}.
+
+prodrel -> string : lreverse(prodrel, val('$1')).
+
+ac_status -> atom : ac_status('$1').
+
+ac_modulepart -> ac_modules :
+ lreverse(ac_modulepart, '$1').
+ac_modulepart -> '$empty' :
+ [].
+
+ac_modules -> ac_module :
+ ['$1'].
+ac_modules -> ac_module ac_modules :
+ ['$1' | '$2'].
+
+ac_module -> 'SUPPORTS' ac_modulenamepart 'INCLUDES' '{' objects '}' ac_variationpart :
+ make_ac_module('$2', '$5', '$7').
+
+ac_modulenamepart -> mibname : '$1'.
+ac_modulenamepart -> '$empty' : undefined.
+
+ac_variationpart -> '$empty' :
+ [].
+ac_variationpart -> ac_variations :
+ lreverse(ac_variationpart, '$1').
+
+ac_variations -> ac_variation :
+ ['$1'].
+ac_variations -> ac_variation ac_variations :
+ ['$1' | '$2'].
+
+%% ac_variation -> ac_objectvariation.
+%% ac_variation -> ac_notificationvariation.
+
+ac_variation -> 'VARIATION' objectname syntaxpart writesyntaxpart ac_accesspart ac_creationpart defvalpart description :
+ make_ac_variation('$2', '$3', '$4', '$5', '$6', '$7', '$8').
+
+ac_accesspart -> 'ACCESS' ac_access : '$2'.
+ac_accesspart -> '$empty' : undefined.
+
+ac_access -> atom: ac_access('$1').
+
+ac_creationpart -> 'CREATION-REQUIRES' '{' objects '}' :
+ lreverse(ac_creationpart, '$3').
+ac_creationpart -> '$empty' :
+ [].
+
+mc_modulepart -> '$empty' :
+ [].
+mc_modulepart -> mc_modules :
+ lreverse(mc_modulepart, '$1').
+
+mc_modules -> mc_module :
+ ['$1'].
+mc_modules -> mc_module mc_modules :
+ ['$1' | '$2'].
-module -> 'MODULE' modulenamepart mandatorypart compliancepart.
+mc_module -> 'MODULE' mc_modulenamepart mc_mandatorypart mc_compliancepart :
+ make_mc_module('$2', '$3', '$4').
-modulenamepart -> mibname.
-modulenamepart -> '$empty'.
+mc_modulenamepart -> mibname : '$1'.
+mc_modulenamepart -> '$empty' : undefined.
-mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}'.
-mandatorypart -> '$empty'.
+mc_mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}' :
+ lreverse(mc_mandatorypart, '$3').
+mc_mandatorypart -> '$empty' :
+ [].
-compliancepart -> compliances.
-compliancepart -> '$empty'.
+mc_compliancepart -> mc_compliances :
+ lreverse(mc_compliancepart, '$1').
+mc_compliancepart -> '$empty' :
+ [].
-compliances -> compliance.
-compliances -> compliances compliance.
+mc_compliances -> mc_compliance :
+ ['$1'].
+mc_compliances -> mc_compliance mc_compliances :
+ ['$1' | '$2'].
-compliance -> compliancegroup.
-compliance -> object.
+mc_compliance -> mc_compliancegroup :
+ '$1'.
+mc_compliance -> mc_object :
+ '$1'.
-compliancegroup -> 'GROUP' objectname description.
+mc_compliancegroup -> 'GROUP' objectname description :
+ make_mc_compliance_group('$2', '$3').
-object -> 'OBJECT' objectname syntaxpart writesyntaxpart accesspart description.
+mc_object -> 'OBJECT' objectname syntaxpart writesyntaxpart mc_accesspart description :
+ make_mc_object('$2', '$3', '$4', '$5', '$6').
-syntaxpart -> 'SYNTAX' syntax.
-syntaxpart -> '$empty'.
+syntaxpart -> 'SYNTAX' syntax : '$2'.
+syntaxpart -> '$empty' : undefined.
-writesyntaxpart -> 'WRITE-SYNTAX' syntax.
-writesyntaxpart -> '$empty'.
+writesyntaxpart -> 'WRITE-SYNTAX' syntax : '$2'.
+writesyntaxpart -> '$empty' : undefined.
-accesspart -> 'MIN-ACCESS' accessv2.
-accesspart -> '$empty'.
+mc_accesspart -> 'MIN-ACCESS' accessv2 : '$2'.
+mc_accesspart -> '$empty' : undefined.
objecttypev2 -> objectname 'OBJECT-TYPE'
'SYNTAX' syntax
@@ -589,7 +694,7 @@ objecttypev2 -> objectname 'OBJECT-TYPE'
'$11', '$12', Kind, '$15'),
{OT, line_of('$2')}.
-indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lists:reverse('$3')}.
+indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lreverse(indexpartv2, '$3')}.
indexpartv2 -> 'AUGMENTS' '{' entry '}' : {augments, '$3'}.
indexpartv2 -> '$empty' : {indexes, undefined}.
@@ -614,7 +719,7 @@ notification -> objectname 'NOTIFICATION-TYPE' objectspart
Not = make_notification('$1','$3','$5', '$7', '$8', '$9'),
{Not, line_of('$2')}.
-objectspart -> 'OBJECTS' '{' objects '}' : lists:reverse('$3').
+objectspart -> 'OBJECTS' '{' objects '}' : lreverse(objectspart, '$3').
objectspart -> '$empty' : [].
objects -> objectname : ['$1'].
@@ -655,6 +760,14 @@ statusv2(Tok) ->
"syntax error before: " ++ atom_to_list(Else))
end.
+ac_status(Tok) ->
+ case val(Tok) of
+ current -> current;
+ obsolete -> obsolete;
+ Else -> return_error(line_of(Tok),
+ "syntax error before: " ++ atom_to_list(Else))
+ end.
+
accessv1(Tok) ->
case val(Tok) of
'read-only' -> 'read-only';
@@ -676,6 +789,18 @@ accessv2(Tok) ->
"syntax error before: " ++ atom_to_list(Else))
end.
+ac_access(Tok) ->
+ case val(Tok) of
+ 'not-implemented' -> 'not-implemented'; % only for notifications
+ 'accessible-for-notify' -> 'accessible-for-notify';
+ 'read-only' -> 'read-only';
+ 'read-write' -> 'read-write';
+ 'read-create' -> 'read-create';
+ 'write-only' -> 'write-only'; % for backward-compatibility only
+ Else -> return_error(line_of(Tok),
+ "syntax error before: " ++ atom_to_list(Else))
+ end.
+
%% ---------------------------------------------------------------------
%% Various basic record build functions
%% ---------------------------------------------------------------------
@@ -744,14 +869,79 @@ make_notification(Name, Vars, Status, Desc, Ref, NA) ->
reference = Ref,
name_assign = NA}.
-make_module_compliance(Name, Status, Desc, Ref, Mod, NA) ->
+make_agent_capabilities(Name, ProdRel, Status, Desc, Ref, Mods, NA) ->
+ #mc_agent_capabilities{name = Name,
+ product_release = ProdRel,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = NA}.
+
+make_ac_variation(Name,
+ undefined = _Syntax,
+ undefined = _WriteSyntax,
+ Access,
+ undefined = _Creation,
+ undefined = _DefVal,
+ Desc) ->
+%% io:format("make_ac_variation -> entry with"
+%% "~n Name: ~p"
+%% "~n Access: ~p"
+%% "~n Desc: ~p"
+%% "~n", [Name, Access, Desc]),
+ #mc_ac_notification_variation{name = Name,
+ access = Access,
+ description = Desc};
+
+make_ac_variation(Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc) ->
+%% io:format("make_ac_variation -> entry with"
+%% "~n Name: ~p"
+%% "~n Syntax: ~p"
+%% "~n WriteSyntax: ~p"
+%% "~n Access: ~p"
+%% "~n Creation: ~p"
+%% "~n DefVal: ~p"
+%% "~n Desc: ~p"
+%% "~n", [Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc]),
+ #mc_ac_object_variation{name = Name,
+ syntax = Syntax,
+ write_syntax = WriteSyntax,
+ access = Access,
+ creation = Creation,
+ default_value = DefVal,
+ description = Desc}.
+
+make_ac_module(Name, Grps, Var) ->
+ #mc_ac_module{name = Name,
+ groups = Grps,
+ variation = Var}.
+
+
+make_module_compliance(Name, Status, Desc, Ref, Mods, NA) ->
#mc_module_compliance{name = Name,
status = Status,
description = Desc,
reference = Ref,
- module = Mod,
+ modules = Mods,
name_assign = NA}.
+make_mc_module(Name, Mand, Compl) ->
+ #mc_mc_module{name = Name,
+ mandatory = Mand,
+ compliance = Compl}.
+
+make_mc_compliance_group(Name, Desc) ->
+ #mc_mc_compliance_group{name = Name,
+ description = Desc}.
+
+make_mc_object(Name, Syntax, WriteSyntax, Access, Desc) ->
+ #mc_mc_object{name = Name,
+ syntax = Syntax,
+ write_syntax = WriteSyntax,
+ access = Access,
+ description = Desc}.
+
make_object_group(Name, Objs, Status, Desc, Ref, NA) ->
#mc_object_group{name = Name,
objects = Objs,
@@ -968,6 +1158,12 @@ filter_v2imports(_,Type) -> {type, Type}.
w(F, A) ->
?vwarning(F, A).
-%i(F, A) ->
-% io:format("~w:" ++ F ++ "~n", [?MODULE|A]).
+lreverse(_Tag, L) when is_list(L) ->
+ lists:reverse(L);
+lreverse(Tag, X) ->
+ exit({bad_list, Tag, X}).
+
+
+%% i(F, A) ->
+%% io:format("~w:" ++ F ++ "~n", [?MODULE|A]).
diff --git a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
index 07bd29231b..e8c46a0521 100644
--- a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
+++ b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -24,7 +24,8 @@
-include("snmpc_lib.hrl").
%% External exports
--export([convert/1, compile/3]).
+-export([convert/1, convert/3, compile/3]).
+
%%-----------------------------------------------------------------
%% Func: convert/1
diff --git a/lib/snmp/src/compile/snmpc_tok.erl b/lib/snmp/src/compile/snmpc_tok.erl
index 6b99e7ae43..e238b256d0 100644
--- a/lib/snmp/src/compile/snmpc_tok.erl
+++ b/lib/snmp/src/compile/snmpc_tok.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. 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
@@ -37,6 +37,8 @@
-export([null_get_line/0, format_error/1, terminate/2, handle_call/3, init/1,
test/0]).
+-include("snmpc_lib.hrl").
+
%%----------------------------------------------------------------------
%% Reserved_words: list of KeyWords. Example: ['IF', 'BEGIN', ..., 'GOTO']
@@ -130,6 +132,10 @@ test() ->
'current','deprecated','not-accessible','obsolete',
'read-create','read-only','read-write', 'IMPORTS', 'FROM',
'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES',
+ 'PRODUCT-RELEASE',
+ 'SUPPORTS',
+ 'INCLUDES',
'DisplayString',
'PhysAddress',
'MacAddress',
@@ -225,6 +231,7 @@ get_all_tokens(Str,Toks) ->
case catch tokenise(Str) of
{error, ErrorInfo} -> {error, ErrorInfo};
{Token, RestChars} when is_tuple(Token) ->
+ %% ?vtrace("get_all_tokens -> Token: ~p", [Token]),
get_all_tokens(RestChars, [Token|Toks])
end.