%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1996-2009. 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% %% %%---------------------------------------------------------------------- %% Number of expected shift/reduce warnings %% This is ugly but... %%---------------------------------------------------------------------- Expect 2. %% ---------------------------------------------------------------------- Nonterminals %% ---------------------------------------------------------------------- accessv1 definition defvalpart description descriptionfield displaypart entry namedbits fatherobjectname fieldname fields implies import import_stuff imports imports_from_one_mib index indexpartv1 indextypev1 indextypesv1 parentintegers listofdefinitions listofimports mib mibname nameassign newtype newtypename objectidentifier objectname objecttypev1 range_num referpart size sizedescr statusv1 syntax tableentrydefinition traptype type usertype variables varpart %v2 moduleidentity revisionpart revisions listofdefinitionsv2 mibid last_updated oranization contact_info revision revision_string revision_desc v1orv2 objectidentity objecttypev2 unitspart indexpartv2 indextypesv2 indextypev2 statusv2 accessv2 notification objectspart objects definitionv2 textualconvention objectgroup notificationgroup modulecompliance modulepart modules module modulenamepart mandatorypart compliancepart compliances compliance compliancegroup object syntaxpart writesyntaxpart accesspart fsyntax defbitsvalue defbitsnames . %% ---------------------------------------------------------------------- Terminals %% ---------------------------------------------------------------------- integer variable atom string quote '{' '}' '::=' ':' '=' ',' '.' '(' ')' ';' '|' 'ACCESS' 'BEGIN' 'BIT' 'Counter' 'DEFINITIONS' 'DEFVAL' 'DESCRIPTION' 'DISPLAY-HINT' 'END' 'ENTERPRISE' 'FROM' 'Gauge' 'IDENTIFIER' 'IMPORTS' 'INDEX' 'INTEGER' 'IpAddress' 'NetworkAddress' 'OBJECT' 'OBJECT-TYPE' 'OCTET' 'OF' 'Opaque' 'REFERENCE' 'SEQUENCE' 'SIZE' 'STATUS' 'STRING' 'SYNTAX' 'TRAP-TYPE' 'TimeTicks' 'VARIABLES' %v2 'LAST-UPDATED' 'ORGANIZATION' 'CONTACT-INFO' 'MODULE-IDENTITY' 'NOTIFICATION-TYPE' 'MODULE-COMPLIANCE' 'OBJECT-GROUP' 'NOTIFICATION-GROUP' 'REVISION' 'OBJECT-IDENTITY' 'MAX-ACCESS' 'UNITS' 'AUGMENTS' 'IMPLIED' 'OBJECTS' 'TEXTUAL-CONVENTION' 'NOTIFICATIONS' 'MODULE' 'MANDATORY-GROUPS' 'GROUP' 'WRITE-SYNTAX' 'MIN-ACCESS' 'BITS' 'DisplayString' 'PhysAddress' 'MacAddress' 'TruthValue' 'TestAndIncr' 'AutonomousType' 'InstancePointer' 'VariablePointer' 'RowPointer' 'RowStatus' 'TimeStamp' 'TimeInterval' 'DateAndTime' 'StorageType' 'TDomain' 'TAddress' . Rootsymbol mib. Endsymbol '$end'. % ********************************************************************** mib -> mibname 'DEFINITIONS' implies 'BEGIN' import v1orv2 'END' : {Version, Defs} = '$6', #pdata{mib_version = Version, mib_name = '$1', imports = '$5', defs = Defs}. v1orv2 -> moduleidentity listofdefinitionsv2 : {v2_mib, ['$1'|lists:reverse('$2')]}. v1orv2 -> listofdefinitions : {v1_mib, lists:reverse('$1')}. definition -> objectidentifier : '$1'. definition -> objecttypev1 : '$1'. definition -> newtype : '$1'. definition -> tableentrydefinition : '$1'. definition -> traptype : '$1'. listofdefinitions -> definition : ['$1'] . listofdefinitions -> listofdefinitions definition : ['$2' | '$1']. import -> '$empty' : []. import -> 'IMPORTS' imports ';' : '$2'. 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')}. listofimports -> import_stuff : ['$1']. listofimports -> listofimports ',' import_stuff : ['$3' | '$1']. import_stuff -> 'OBJECT-TYPE' : {builtin, 'OBJECT-TYPE'}. import_stuff -> 'TRAP-TYPE' : {builtin, 'TRAP-TYPE'}. import_stuff -> 'NetworkAddress' : {builtin, 'NetworkAddress'}. import_stuff -> 'TimeTicks' : {builtin, 'TimeTicks'}. import_stuff -> 'IpAddress' : {builtin, 'IpAddress'}. import_stuff -> 'Counter' : {builtin, 'Counter'}. import_stuff -> 'Gauge' : {builtin, 'Gauge'}. import_stuff -> 'Opaque' : {builtin, 'Opaque'}. import_stuff -> variable : filter_v2imports(get(snmp_version), val('$1')). import_stuff -> atom : {node, val('$1')}. %%v2 import_stuff -> 'MODULE-IDENTITY' : ensure_ver(2,'$1'), {builtin, 'MODULE-IDENTITY'}. import_stuff -> 'NOTIFICATION-TYPE' : ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-TYPE'}. import_stuff -> 'MODULE-COMPLIANCE' : ensure_ver(2,'$1'), {builtin, 'MODULE-COMPLIANCE'}. import_stuff -> 'NOTIFICATION-GROUP' : ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-GROUP'}. import_stuff -> 'OBJECT-GROUP' : ensure_ver(2,'$1'), {builtin, 'OBJECT-GROUP'}. import_stuff -> 'OBJECT-IDENTITY' : ensure_ver(2,'$1'), {builtin, 'OBJECT-IDENTITY'}. import_stuff -> 'TEXTUAL-CONVENTION' : ensure_ver(2,'$1'), {builtin, 'TEXTUAL-CONVENTION'}. import_stuff -> 'DisplayString' : ensure_ver(2,'$1'), {builtin, 'DisplayString'}. import_stuff -> 'PhysAddress' : ensure_ver(2,'$1'), {builtin, 'PhysAddress'}. import_stuff -> 'MacAddress' : ensure_ver(2,'$1'), {builtin, 'MacAddress'}. import_stuff -> 'TruthValue' : ensure_ver(2,'$1'), {builtin, 'TruthValue'}. import_stuff -> 'TestAndIncr' : ensure_ver(2,'$1'), {builtin, 'TestAndIncr'}. import_stuff -> 'AutonomousType' : ensure_ver(2,'$1'), {builtin, 'AutonomousType'}. import_stuff -> 'InstancePointer' : ensure_ver(2,'$1'), {builtin, 'InstancePointer'}. import_stuff -> 'VariablePointer' : ensure_ver(2,'$1'), {builtin, 'VariablePointer'}. import_stuff -> 'RowPointer' : ensure_ver(2,'$1'), {builtin, 'RowPointer'}. import_stuff -> 'RowStatus' : ensure_ver(2,'$1'), {builtin, 'RowStatus'}. import_stuff -> 'TimeStamp' : ensure_ver(2,'$1'), {builtin, 'TimeStamp'}. import_stuff -> 'TimeInterval' : ensure_ver(2,'$1'), {builtin, 'TimeInterval'}. import_stuff -> 'DateAndTime' : ensure_ver(2,'$1'), {builtin, 'DateAndTime'}. import_stuff -> 'StorageType' : ensure_ver(2,'$1'), {builtin, 'StorageType'}. import_stuff -> 'TDomain' : ensure_ver(2,'$1'), {builtin, 'TDomain'}. import_stuff -> 'TAddress' : ensure_ver(2,'$1'), {builtin, 'TAddress'}. traptype -> objectname 'TRAP-TYPE' 'ENTERPRISE' objectname varpart description referpart implies integer : Trap = make_trap('$1', '$4', lists:reverse('$5'), '$6', '$7', val('$9')), {Trap, line_of('$2')}. % defines a name to an internal node. objectidentifier -> objectname 'OBJECT' 'IDENTIFIER' nameassign : {Parent, SubIndex} = '$4', Int = make_internal('$1', dummy, Parent, SubIndex), {Int, line_of('$2')}. % defines name, access and type for a variable. objecttypev1 -> objectname 'OBJECT-TYPE' 'SYNTAX' syntax 'ACCESS' accessv1 'STATUS' statusv1 'DESCRIPTION' descriptionfield referpart indexpartv1 defvalpart nameassign : Kind = kind('$13', '$12'), OT = make_object_type('$1', '$4', '$6', '$8', '$10', '$11', Kind, '$14'), {OT, line_of('$2')}. newtype -> newtypename implies syntax : NT = make_new_type('$1', dummy, '$3'), {NT, line_of('$2')}. tableentrydefinition -> newtypename implies 'SEQUENCE' '{' fields '}' : Seq = make_sequence('$1', lists:reverse('$5')), {Seq, line_of('$3')}. % returns: list of {, } fields -> fieldname fsyntax : [{val('$1'), '$2'}]. fields -> fields ',' fieldname fsyntax : [{val('$3'), '$4'} | '$1']. fsyntax -> 'BITS' : {{bits,[{dummy,0}]},line_of('$1')}. fsyntax -> syntax : '$1'. fieldname -> atom : '$1'. syntax -> usertype : {{type, val('$1')}, line_of('$1')}. syntax -> type : {{type, cat('$1')},line_of('$1')}. syntax -> type size : {{type_with_size, cat('$1'), '$2'},line_of('$1')}. syntax -> usertype size : {{type_with_size,val('$1'), '$2'},line_of('$1')}. syntax -> 'INTEGER' '{' namedbits '}' : {{integer_with_enum, 'INTEGER', '$3'}, line_of('$1')}. syntax -> 'BITS' '{' namedbits '}' : ensure_ver(2,'$1'), {{bits, '$3'}, line_of('$1')}. syntax -> 'SEQUENCE' 'OF' usertype : {{sequence_of,val('$3')},line_of('$1')}. size -> '(' sizedescr ')' : make_range('$2'). size -> '(' 'SIZE' '(' sizedescr ')' ')' : make_range('$4'). %% Returns a list of integers describing a range. sizedescr -> range_num '.' '.' range_num : ['$1', '$4']. sizedescr -> range_num '.' '.' range_num sizedescr :['$1', '$4' |'$5']. sizedescr -> range_num : ['$1']. sizedescr -> sizedescr '|' sizedescr : ['$1', '$3']. range_num -> integer : val('$1') . range_num -> quote atom : make_range_integer(val('$1'), val('$2')) . range_num -> quote variable : make_range_integer(val('$1'), val('$2')) . namedbits -> atom '(' integer ')' : [{val('$1'), val('$3')}]. namedbits -> namedbits ',' atom '(' integer ')' : [{val('$3'), val('$5')} | '$1']. usertype -> variable : '$1'. type -> 'OCTET' 'STRING' : {'OCTET STRING', line_of('$1')}. type -> 'BIT' 'STRING' : {'BIT STRING', line_of('$1')}. type -> 'OBJECT' 'IDENTIFIER' : {'OBJECT IDENTIFIER', line_of('$1')}. type -> 'INTEGER' : '$1'. type -> 'NetworkAddress' : '$1'. type -> 'IpAddress' : '$1'. type -> 'Counter' : ensure_ver(1,'$1'),'$1'. type -> 'Gauge' : ensure_ver(1,'$1'),'$1'. type -> 'TimeTicks' : '$1'. type -> 'Opaque' : '$1'. type -> 'DisplayString' : ensure_ver(2,'$1'), '$1'. type -> 'PhysAddress' : ensure_ver(2,'$1'), '$1'. type -> 'MacAddress' : ensure_ver(2,'$1'), '$1'. type -> 'TruthValue' : ensure_ver(2,'$1'), '$1'. type -> 'TestAndIncr' : ensure_ver(2,'$1'), '$1'. type -> 'AutonomousType' : ensure_ver(2,'$1'), '$1'. type -> 'InstancePointer' : ensure_ver(2,'$1'), '$1'. type -> 'VariablePointer' : ensure_ver(2,'$1'), '$1'. type -> 'RowPointer' : ensure_ver(2,'$1'), '$1'. type -> 'RowStatus' : ensure_ver(2,'$1'), '$1'. type -> 'TimeStamp' : ensure_ver(2,'$1'), '$1'. type -> 'TimeInterval' : ensure_ver(2,'$1'), '$1'. type -> 'DateAndTime' : ensure_ver(2,'$1'), '$1'. type -> 'StorageType' : ensure_ver(2,'$1'), '$1'. type -> 'TDomain' : ensure_ver(2,'$1'), '$1'. type -> 'TAddress' : ensure_ver(2,'$1'), '$1'. % Returns: {FatherName, SubIndex} (the parent) nameassign -> implies '{' fatherobjectname parentintegers '}' : {'$3', '$4' }. nameassign -> implies '{' parentintegers '}' : { root, '$3'}. varpart -> '$empty' : []. varpart -> 'VARIABLES' '{' variables '}' : '$3'. variables -> objectname : ['$1']. 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 -> '$empty' : undefined. description -> 'DESCRIPTION' string : lists:reverse(val('$2')). description -> '$empty' : undefined. displaypart -> 'DISPLAY-HINT' string : display_hint('$2') . displaypart -> '$empty' : undefined . % returns: {indexes, undefined} % | {indexes, IndexList} where IndexList is a list of aliasnames. indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lists:reverse('$3')}. indexpartv1 -> '$empty' : {indexes, undefined}. indextypesv1 -> indextypev1 : ['$1']. indextypesv1 -> indextypesv1 ',' indextypev1 : ['$3' | '$1']. indextypev1 -> index : '$1'. index -> objectname : '$1'. parentintegers -> integer : [val('$1')]. parentintegers -> atom '(' integer ')' : [val('$3')]. parentintegers -> integer parentintegers : [val('$1') | '$2']. 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 -> '$empty' : undefined. defbitsvalue -> defbitsnames : '$1'. defbitsvalue -> '$empty' : []. defbitsnames -> atom : [val('$1')]. defbitsnames -> defbitsnames ',' atom : [val('$3') | '$1']. objectname -> atom : val('$1'). mibname -> variable : val('$1'). fatherobjectname -> objectname : '$1'. newtypename -> variable : val('$1'). accessv1 -> atom: accessv1('$1'). statusv1 -> atom : statusv1('$1'). referpart -> 'REFERENCE' string : lists:reverse(val('$2')). referpart -> '$empty' : undefined. %%---------------------------------------------------------------------- %% SNMPv2 grammatics %%v2 %%---------------------------------------------------------------------- moduleidentity -> mibid 'MODULE-IDENTITY' 'LAST-UPDATED' last_updated 'ORGANIZATION' oranization 'CONTACT-INFO' contact_info 'DESCRIPTION' descriptionfield revisionpart nameassign : MI = make_module_identity('$1', '$4', '$6', '$8', '$10', '$11', '$12'), {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')) . revisionpart -> '$empty' : [] . revisionpart -> revisions : lists:reverse('$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')) . definitionv2 -> objectidentifier : '$1'. definitionv2 -> objecttypev2 : '$1'. definitionv2 -> textualconvention : '$1'. definitionv2 -> objectidentity : '$1'. definitionv2 -> newtype : '$1'. definitionv2 -> tableentrydefinition : '$1'. definitionv2 -> notification : '$1'. definitionv2 -> objectgroup : '$1'. definitionv2 -> notificationgroup : '$1'. definitionv2 -> modulecompliance : '$1'. listofdefinitionsv2 -> '$empty' : [] . listofdefinitionsv2 -> listofdefinitionsv2 definitionv2 : ['$2' | '$1']. textualconvention -> newtypename implies 'TEXTUAL-CONVENTION' displaypart 'STATUS' statusv2 description referpart 'SYNTAX' syntax : NT = make_new_type('$1', 'TEXTUAL-CONVENTION', '$4', '$6', '$7', '$8', '$10'), {NT, line_of('$3')}. objectidentity -> objectname 'OBJECT-IDENTITY' 'STATUS' statusv2 'DESCRIPTION' string referpart nameassign : {Parent, SubIndex} = '$8', Int = make_internal('$1', 'OBJECT-IDENTITY', Parent, SubIndex), {Int, line_of('$2')}. objectgroup -> objectname 'OBJECT-GROUP' objectspart 'STATUS' statusv2 description referpart nameassign : OG = make_object_group('$1', '$3', '$5', '$6', '$7', '$8'), {OG, line_of('$2')}. notificationgroup -> objectname 'NOTIFICATION-GROUP' 'NOTIFICATIONS' '{' objects '}' 'STATUS' statusv2 description referpart nameassign : NG = make_notification_group('$1', '$5', '$8', '$9', '$10', '$11'), {NG, line_of('$2')}. modulecompliance -> objectname 'MODULE-COMPLIANCE' 'STATUS' statusv2 description referpart modulepart nameassign : MC = make_module_compliance('$1', '$4', '$5', '$6', '$7', '$8'), {MC, line_of('$2')}. modulepart -> '$empty'. modulepart -> modules. modules -> module. modules -> modules module. module -> 'MODULE' modulenamepart mandatorypart compliancepart. modulenamepart -> mibname. modulenamepart -> '$empty'. mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}'. mandatorypart -> '$empty'. compliancepart -> compliances. compliancepart -> '$empty'. compliances -> compliance. compliances -> compliances compliance. compliance -> compliancegroup. compliance -> object. compliancegroup -> 'GROUP' objectname description. object -> 'OBJECT' objectname syntaxpart writesyntaxpart accesspart description. syntaxpart -> 'SYNTAX' syntax. syntaxpart -> '$empty'. writesyntaxpart -> 'WRITE-SYNTAX' syntax. writesyntaxpart -> '$empty'. accesspart -> 'MIN-ACCESS' accessv2. accesspart -> '$empty'. objecttypev2 -> objectname 'OBJECT-TYPE' 'SYNTAX' syntax unitspart 'MAX-ACCESS' accessv2 'STATUS' statusv2 'DESCRIPTION' descriptionfield referpart indexpartv2 defvalpart nameassign : Kind = kind('$14', '$13'), OT = make_object_type('$1', '$4', '$5', '$7', '$9', '$11', '$12', Kind, '$15'), {OT, line_of('$2')}. indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lists:reverse('$3')}. indexpartv2 -> 'AUGMENTS' '{' entry '}' : {augments, '$3'}. indexpartv2 -> '$empty' : {indexes, undefined}. indextypesv2 -> indextypev2 : ['$1']. indextypesv2 -> indextypesv2 ',' indextypev2 : ['$3' | '$1']. indextypev2 -> 'IMPLIED' index : {implied,'$2'}. indextypev2 -> index : '$1'. entry -> objectname : '$1'. unitspart -> '$empty' : undefined. unitspart -> 'UNITS' string : units('$2') . statusv2 -> atom : statusv2('$1'). accessv2 -> atom: accessv2('$1'). notification -> objectname 'NOTIFICATION-TYPE' objectspart 'STATUS' statusv2 'DESCRIPTION' descriptionfield referpart nameassign : Not = make_notification('$1','$3','$5', '$7', '$8', '$9'), {Not, line_of('$2')}. objectspart -> 'OBJECTS' '{' objects '}' : lists:reverse('$3'). objectspart -> '$empty' : []. objects -> objectname : ['$1']. objects -> objects ',' objectname : ['$3'|'$1']. %%---------------------------------------------------------------------- Erlang code. %%---------------------------------------------------------------------- -include("snmp_types.hrl"). -include("snmpc_lib.hrl"). -include("snmpc.hrl"). % value val(Token) -> element(3, Token). line_of(Token) -> element(2, Token). %% category cat(Token) -> element(1, Token). statusv1(Tok) -> case val(Tok) of mandatory -> mandatory; optional -> optional; obsolete -> obsolete; deprecated -> deprecated; Else -> return_error(line_of(Tok), "syntax error before: " ++ atom_to_list(Else)) end. statusv2(Tok) -> case val(Tok) of current -> current; deprecated -> deprecated; 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'; 'read-write' -> 'read-write'; 'write-only' -> 'write-only'; 'not-accessible' -> 'not-accessible'; Else -> return_error(line_of(Tok), "syntax error before: " ++ atom_to_list(Else)) end. accessv2(Tok) -> case val(Tok) of 'not-accessible' -> 'not-accessible'; 'accessible-for-notify' -> 'accessible-for-notify'; 'read-only' -> 'read-only'; 'read-write' -> 'read-write'; 'read-create' -> 'read-create'; Else -> return_error(line_of(Tok), "syntax error before: " ++ atom_to_list(Else)) end. %% --------------------------------------------------------------------- %% Various basic record build functions %% --------------------------------------------------------------------- make_module_identity(Name, LU, Org, CI, Desc, Revs, NA) -> #mc_module_identity{name = Name, last_updated = LU, organization = Org, contact_info = CI, description = Desc, revisions = Revs, name_assign = NA}. make_revision(Rev, Desc) -> #mc_revision{revision = Rev, description = Desc}. make_object_type(Name, Syntax, MaxAcc, Status, Desc, Ref, Kind, NA) -> #mc_object_type{name = Name, syntax = Syntax, max_access = MaxAcc, status = Status, description = Desc, reference = Ref, kind = Kind, name_assign = NA}. make_object_type(Name, Syntax, Units, MaxAcc, Status, Desc, Ref, Kind, NA) -> #mc_object_type{name = Name, syntax = Syntax, units = Units, max_access = MaxAcc, status = Status, description = Desc, reference = Ref, kind = Kind, name_assign = NA}. make_new_type(Name, Macro, Syntax) -> #mc_new_type{name = Name, macro = Macro, syntax = Syntax}. make_new_type(Name, Macro, DisplayHint, Status, Desc, Ref, Syntax) -> #mc_new_type{name = Name, macro = Macro, status = Status, description = Desc, reference = Ref, display_hint = DisplayHint, syntax = Syntax}. make_trap(Name, Ent, Vars, Desc, Ref, Num) -> #mc_trap{name = Name, enterprise = Ent, vars = Vars, description = Desc, reference = Ref, num = Num}. make_notification(Name, Vars, Status, Desc, Ref, NA) -> #mc_notification{name = Name, vars = Vars, status = Status, description = Desc, reference = Ref, name_assign = NA}. make_module_compliance(Name, Status, Desc, Ref, Mod, NA) -> #mc_module_compliance{name = Name, status = Status, description = Desc, reference = Ref, module = Mod, name_assign = NA}. make_object_group(Name, Objs, Status, Desc, Ref, NA) -> #mc_object_group{name = Name, objects = Objs, status = Status, description = Desc, reference = Ref, name_assign = NA}. make_notification_group(Name, Objs, Status, Desc, Ref, NA) -> #mc_notification_group{name = Name, objects = Objs, status = Status, description = Desc, reference = Ref, name_assign = NA}. make_sequence(Name, Fields) -> #mc_sequence{name = Name, fields = Fields}. make_internal(Name, Macro, Parent, SubIdx) -> #mc_internal{name = Name, macro = Macro, parent = Parent, sub_index = SubIdx}. %% --------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Purpose: Find how much room needs to be allocated for the data type %% (when sending it in a PDU (the maximum difference will be %% the size allocated)). %% This is applicable for OCTET STRINGs and OBJECT IDENTIFIERs. %% %% Or : Find the range of integers in the integer list. %% This is applicable for INTEGERs %% %% Arg: A list of integers. %%---------------------------------------------------------------------- make_range_integer(RevHexStr, h) -> erlang:list_to_integer(lists:reverse(RevHexStr), 16); make_range_integer(RevHexStr, 'H') -> erlang:list_to_integer(lists:reverse(RevHexStr), 16); make_range_integer(RevBitStr, b) -> erlang:list_to_integer(lists:reverse(RevBitStr), 2); make_range_integer(RevBitStr, 'B') -> erlang:list_to_integer(lists:reverse(RevBitStr), 2); make_range_integer(RevStr, Base) -> throw({error, {invalid_base, Base, lists:reverse(RevStr)}}). make_range(XIntList) -> IntList = lists:flatten(XIntList), {range, lists:min(IntList), lists:max(IntList)}. make_defval_for_string(Line, Str, Atom) -> case lists:member(Atom, [h, 'H', b, 'B']) of true -> case catch make_defval_for_string2(Str, Atom) of Defval when is_list(Defval) -> Defval; {error, ErrStr} -> snmpc_lib:print_error("Bad DEFVAL ~w string ~p - ~s", [Atom, Str, ErrStr], Line), ""; _Else -> snmpc_lib:print_error("Bad DEFVAL ~w string ~p", [Atom, Str], Line), "" end; false -> snmpc_lib:print_error("Bad DEFVAL string type ~w for ~p", [Atom, Str], Line), "" end. make_defval_for_string2([], h) -> []; make_defval_for_string2([X16,X|HexString], h) -> lists:append(hex_to_bytes(snmpc_misc:to_upper([X16,X])), make_defval_for_string2(HexString, h)); make_defval_for_string2([_Odd], h) -> throw({error, "odd number of bytes in hex string"}); make_defval_for_string2(HexString, 'H') -> make_defval_for_string2(HexString,h); make_defval_for_string2(BitString, 'B') -> bits_to_bytes(BitString); make_defval_for_string2(BitString, b) -> make_defval_for_string2(BitString, 'B'). bits_to_bytes(BitStr) -> lists:reverse(bits_to_bytes(lists:reverse(BitStr), 1, 0)). bits_to_bytes([], 1, _Byte) -> % empty bitstring []; bits_to_bytes([], 256, _Byte) -> % correct; multiple of 8 []; % If we are to support arbitrary length of bitstrings. This migth % be needed in the new SMI. %bits_to_bytes([], N, Byte) -> % [Byte]; bits_to_bytes([], _N, _Byte) -> throw({error, "not a multiple of eight bits in bitstring"}); bits_to_bytes(Rest, 256, Byte) -> [Byte | bits_to_bytes(Rest, 1, 0)]; bits_to_bytes([$1 | T], N, Byte) -> bits_to_bytes(T, N*2, N + Byte); bits_to_bytes([$0 | T], N, Byte) -> bits_to_bytes(T, N*2, Byte); bits_to_bytes([_BadChar | _T], _N, _Byte) -> throw({error, "bad character in bit string"}). %%---------------------------------------------------------------------- %% These HEX conversion routines are stolen from module asn1_bits by %% klacke@erix.ericsson.se %% I didn't want to ship the entire asn1-compiler so I used cut-and-paste. %%---------------------------------------------------------------------- %% hex_to_bytes(HexNumber) when is_atom(HexNumber) -> %% hex_to_bytes(atom_to_list(HexNumber)); hex_to_bytes(HexNumber) -> case length(HexNumber) rem 2 of 1 -> %% Odd hex_to_bytes(lists:append(HexNumber,[$0]),[]); 0 -> %% even hex_to_bytes(HexNumber,[]) end. hex_to_bytes([],R) -> lists:reverse(R); hex_to_bytes([Hi,Lo|Rest],Res) -> hex_to_bytes(Rest,[hex_to_byte(Hi,Lo)|Res]). hex_to_four_bits(Hex) -> if Hex == $0 -> 0; Hex == $1 -> 1; Hex == $2 -> 2; Hex == $3 -> 3; Hex == $4 -> 4; Hex == $5 -> 5; Hex == $6 -> 6; Hex == $7 -> 7; Hex == $8 -> 8; Hex == $9 -> 9; Hex == $A -> 10; Hex == $B -> 11; Hex == $C -> 12; Hex == $D -> 13; Hex == $E -> 14; Hex == $F -> 15; true -> throw({error, "bad hex character"}) end. hex_to_byte(Hi,Lo) -> (hex_to_four_bits(Hi) bsl 4) bor hex_to_four_bits(Lo). kind(DefValPart,IndexPart) -> case DefValPart of undefined -> case IndexPart of {indexes, undefined} -> {variable, []}; {indexes, Indexes} -> {table_entry, {indexes, Indexes}}; {augments,Table} -> {table_entry,{augments,Table}} end; {defval, DefVal} -> {variable, [{defval, DefVal}]} end. display_hint(Val) -> case val(Val) of Str when is_list(Str) -> lists:reverse(Str); _ -> throw({error, {invalid_display_hint, Val}}) end. units(Val) -> case val(Val) of Str when is_list(Str) -> lists:reverse(Str); _ -> throw({error, {invalid_units, Val}}) end. ensure_ver(Ver, Line, What) -> case get(snmp_version) of Ver -> ok; _Other -> snmpc_lib:print_error( "~s is only allowed in SNMPv~p.",[What,Ver],Line) end. ensure_ver(Ver,Token) -> ensure_ver(Ver,line_of(Token), atom_to_list(cat(Token))). filter_v2imports(2,'Integer32') -> {builtin, 'Integer32'}; filter_v2imports(2,'Counter32') -> {builtin, 'Counter32'}; filter_v2imports(2,'Gauge32') -> {builtin, 'Gauge32'}; filter_v2imports(2,'Unsigned32') -> {builtin, 'Unsigned32'}; filter_v2imports(2,'Counter64') -> {builtin, 'Counter64'}; filter_v2imports(_,Type) -> {type, Type}. w(F, A) -> ?vwarning(F, A). %i(F, A) -> % io:format("~w:" ++ F ++ "~n", [?MODULE|A]).