From 5210341783f4c3ca9611c7ea5e630fde4d067f10 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 2 Dec 2010 21:02:12 +0100 Subject: Really time to go home checkin. --- lib/snmp/src/compile/snmpc.erl | 50 +++++++++- lib/snmp/src/compile/snmpc.hrl | 19 +++- lib/snmp/src/compile/snmpc_lib.erl | 5 +- lib/snmp/src/compile/snmpc_mib_gram.yrl | 131 +++++++++++++++++++++++++-- lib/snmp/src/compile/snmpc_tok.erl | 9 +- lib/snmp/test/modules.mk | 1 + lib/snmp/test/snmp_compiler_test.erl | 15 +++ lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib | 131 +++++++++++++++++++++++++++ 8 files changed, 344 insertions(+), 17 deletions(-) create mode 100644 lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib (limited to 'lib/snmp') diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index 0f90d541e8..84c9c46fc9 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -921,10 +921,42 @@ definitions_loop([{#mc_notification{name = TrapName, snmpc_lib:add_cdata(#cdata.traps, [Notif]), definitions_loop(T, Data); -definitions_loop([{#mc_agent_capabilities{name = Name},Line}|T], Data) -> - ?vlog2("defloop -> agent_capabilities:" - "~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 Parent: ~p" + "~n SubIndex: ~p", + [Name, Status, Desc, Parent, SubIdx], Line), ensure_macro_imported('AGENT-CAPABILITIES', Line), + 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]), definitions_loop(T, Data); definitions_loop([{#mc_module_compliance{name = Name},Line}|T], Data) -> @@ -1334,22 +1366,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) -> @@ -1357,7 +1393,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}; @@ -1449,6 +1485,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 5dd8d9a139..254ede51af 100644 --- a/lib/snmp/src/compile/snmpc.hrl +++ b/lib/snmp/src/compile/snmpc.hrl @@ -109,11 +109,28 @@ status, description, reference, - module, + modules, name_assign } ). +-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, diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 4490412e84..4f71c47bfa 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -306,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]), diff --git a/lib/snmp/src/compile/snmpc_mib_gram.yrl b/lib/snmp/src/compile/snmpc_mib_gram.yrl index 3536b538df..7af27ba816 100644 --- a/lib/snmp/src/compile/snmpc_mib_gram.yrl +++ b/lib/snmp/src/compile/snmpc_mib_gram.yrl @@ -59,7 +59,7 @@ newtypename objectidentifier objectname objecttypev1 -prodrelpart +prodrel range_num referpart size @@ -103,6 +103,17 @@ objectgroup notificationgroup modulecompliance agentcapabilities +ac_status +ac_modulepart +ac_modules +ac_module +ac_modulenamepart +ac_variationpart +ac_variations +ac_variation +ac_accesspart +ac_access +ac_creationpart modulepart modules module @@ -165,6 +176,10 @@ integer variable atom string quote '{' '}' '::=' ':' '=' ',' '.' '(' ')' ';' '|' 'NOTIFICATION-TYPE' 'PRODUCT-RELEASE' 'AGENT-CAPABILITIES' +'INCLUDES' +'SUPPORTS' +'VARIATION' +'CREATION-REQUIRES' 'MODULE-COMPLIANCE' 'OBJECT-GROUP' 'NOTIFICATION-GROUP' @@ -255,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' @@ -545,14 +562,56 @@ modulecompliance -> objectname 'MODULE-COMPLIANCE' 'STATUS' statusv2 '$7', '$8'), {MC, line_of('$2')}. + agentcapabilities -> objectname 'AGENT-CAPABILITIES' - 'PRODUCT-RELEASE' prodrelpart 'STATUS' statusv2 - description referpart modulepart nameassign : - MC = make_agent_capabilities('$1', '$4', '$6', '$7', - '$8', '$9', '$10'), - {MC, line_of('$2')}. + '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 : lists:reverse(val('$1')). + +ac_status -> atom : ac_status('$1'). + +ac_modulepart -> ac_modules : lists:reverse('$1'). +ac_modulepart -> '$empty' : []. + +ac_modules -> ac_module : ['$1']. +ac_modules -> ac_modules ac_module : ['$2' | '$1']. + +ac_module -> 'SUPPORTS' ac_modulenamepart 'INCLUDES' '{' objects '}' ac_variationpart : + {'$2', '$5', '$7'}. + +ac_modulenamepart -> mibname : '$1'. +ac_modulenamepart -> '$empty' : undefined. + +ac_variationpart -> '$empty' : []. +ac_variationpart -> ac_variations : lists:reverse('$1'). + +ac_variations -> ac_variation : ['$1']. +ac_variations -> ac_variations ac_variation : ['$2' | '$1']. + +%% 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_objectvariation -> 'VARIATION' objectname syntaxpart writesyntaxpart ac_accesspart ac_creationpart ac_defvalpart description : +%% make_ac_object_variation('$2', '$3', '$4', '$5', '$6', '$7', '$8'). + +%% ac_notificationvariation -> 'VARIATION' objectname ac_accesspart description : +%% make_ac_notification_variation('$2', '$3', '$4'). + +ac_accesspart -> 'ACCESS' ac_access : '$2'. +ac_accesspart -> '$empty' : undefined. + +ac_access -> atom: ac_access('$1'). -prodrelpart -> string : $1. +ac_creationpart -> 'CREATION-REQUIRES' '{' objects '}' : lists:reverse('$3'). +ac_creationpart -> '$empty' : []. modulepart -> '$empty'. modulepart -> modules. @@ -669,6 +728,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'; @@ -690,6 +757,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 %% --------------------------------------------------------------------- @@ -758,15 +837,49 @@ make_notification(Name, Vars, Status, Desc, Ref, NA) -> reference = Ref, name_assign = NA}. -make_agent_capabilities(Name, ProdRel, 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, - module = Mod, + 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_module_compliance(Name, Status, Desc, Ref, Mod, NA) -> #mc_module_compliance{name = Name, status = Status, 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. diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk index 6a0c3e9481..b90c6af482 100644 --- a/lib/snmp/test/modules.mk +++ b/lib/snmp/test/modules.mk @@ -62,6 +62,7 @@ COMPILER_MIB_FILES = \ OTP8574-MIB MIB_FILES = \ + AC-TEST-MIB.mib \ OLD-SNMPEA-MIB.mib \ OLD-SNMPEA-MIB-v2.mib \ Klas1.mib \ diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl index ad77b01362..e2925ed6ed 100644 --- a/lib/snmp/test/snmp_compiler_test.erl +++ b/lib/snmp/test/snmp_compiler_test.erl @@ -44,6 +44,7 @@ oid_conflicts/1, imports/1, module_identity/1, + agent_capabilities/1, tickets/1, otp_6150/1, @@ -96,6 +97,7 @@ all(suite) -> oid_conflicts, imports, module_identity, + agent_capabilities, tickets ]. @@ -169,6 +171,19 @@ module_identity(Config) when is_list(Config) -> ?SKIP(not_yet_implemented). +agent_capabilities(suite) -> + []; +agent_capabilities(Config) when is_list(Config) -> + put(tname,agent_capabilities), + p("starting with Config: ~p~n", [Config]), + + Dir = ?config(comp_dir, Config), + Mib = join(Dir,"AC-TEST-MIB.mib"), + ?line {ok, Mib} = snmpc:compile(Mib, [{outdir, Dir}, {verbosity,trace}]), + io:format("agent_capabilities -> Mib: ~n~p~n", [Mib]), + ok. + + otp_6150(suite) -> []; otp_6150(Config) when is_list(Config) -> diff --git a/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib b/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib new file mode 100644 index 0000000000..58defbe1cf --- /dev/null +++ b/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib @@ -0,0 +1,131 @@ +-- +-- AC-TEST-MIB.mib +-- MIB generated by MG-SOFT Visual MIB Builder Version 5.0 Build 250 +-- Tuesday, November 30, 2010 at 23:03:18 +-- + + AC-TEST-MIB DEFINITIONS ::= BEGIN + + IMPORTS + otpExpr + FROM OTP-REG + OBJECT-GROUP, AGENT-CAPABILITIES + FROM SNMPv2-CONF + Integer32, OBJECT-TYPE, MODULE-IDENTITY, OBJECT-IDENTITY + FROM SNMPv2-SMI; + + + acTestModule MODULE-IDENTITY + LAST-UPDATED "201011302230Z" -- November 30, 2010 at 22:30 GMT + ORGANIZATION + "Ac Test Co." + CONTACT-INFO + "developer@small.company." + DESCRIPTION + "Ac Test module." + ::= { reg 1 } + + + +-- +-- Node definitions +-- + + acTest OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Test area." + ::= { otpExpr 4321 } + + + reg OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Registrations." + ::= { acTest 1 } + + + mib OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Objects." + ::= { acTest 2 } + + + someObject OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "Description." + ::= { mib 1 } + + + oneMore OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "Description." + ::= { mib 2 } + + + grp OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Groups + ." + ::= { acTest 3 } + + + basicGrp OBJECT-GROUP + OBJECTS { someObject } + STATUS current + DESCRIPTION + "Basic set of objects." + ::= { grp 1 } + + + allObjects OBJECT-GROUP + OBJECTS { someObject, oneMore } + STATUS current + DESCRIPTION + "Complete set." + ::= { grp 2 } + + + cap OBJECT-IDENTITY + STATUS current + DESCRIPTION + "Capabilities." + ::= { acTest 5 } + + + basicAgent AGENT-CAPABILITIES + PRODUCT-RELEASE + "Product release v1." + STATUS current + DESCRIPTION + "Basic agent." + SUPPORTS AC-TEST-MIB + INCLUDES { basicGrp } + ::= { cap 1 } + + + fullAgent AGENT-CAPABILITIES + PRODUCT-RELEASE + "Product release v2." + STATUS current + DESCRIPTION + "Full featured agent." + SUPPORTS AC-TEST-MIB + INCLUDES { allObjects } + ::= { cap 2 } + + + + END + +-- +-- AC-TEST-MIB.mib +-- -- cgit v1.2.3