www.gusucode.com > robotsimulink 工具箱 matlab源码程序 > robotsimulink/robotslros/+robotics/+slros/+internal/+bus/ReservedNamesChecker.m
classdef ReservedNamesChecker %This class is for internal use only. It may be removed in the future. % ReservedNamesChecker is a utility class for checking if a ROS % property name are on a "reserved name" list. Property names that % match a reserved name can be "mangled", which appends an underscore % to the name. % % Usage: % checker = robotics.slros.internal.bus.ReservedNamesChecker.getInstance; % checker.isReserved('Vector') % mangledName = checker.mangleNameIfNeeded('Vector') % returns 'Vector_' % Copyright 2016 The MathWorks, Inc. % Details: % When Simulink generates code for a bus structure, it errors out if % any of the bus fields match language keywords (for C, C++, TLC). % Bus property names such as "Vector" and "Matrix" are TLC language % keywords, and hence cause a code-generation error (see g1336418). % This matching is case-sensitive, e.g., bus elements with name % "vector" and "matrix" do NOT cause an error during code generation. % % The above error is an issue when mapping ROS messages to Simulink % buses, since ROS message properties can have arbitrary names. % % The strategy for dealing with this issue is the following: % - When creating a bus for a ROS message, check if each property % name is on a "reserved name" list. If it is, use a mangled % variant of the property name in the bus (e.g., the bus will have % an element "Vector_" intead of "Vector"). % - When converting a ROS message to/from Simulink buses, the % data for "reserved" property names is invisibly mapped to the % corresponding mangled name. % % The reserved name or "DefaultExclusionList" is based on the % list of reserved keywords specified in the following files (referred % to below as "Simulink Coder reserved words"): % matlab/src/simulink/sl_engin/rtwgen_ident_hash.cpp (search for "reservedIdents") % src/cgir_xform/dom_c/CReservedWords.cpp % % Two simplifying factors: % 1) The bus creation logic (for Simulink ROS) uses the property names % of MATLAB ROS messages. By design, these are all SentenceCased, % which means that we don't have to worry about Simulink Coder % reserved words that start with a lowercase letter. % 2) We can ignore Simulink Coder reserved words that are ALLUPPERCASE % as these are pretty obscure (and would only be an issue with % constant properties, which aren't supported in SLROS as of 16b). % % Following (1) and (2), the DefaultExclusionList below only includes % Simulink Coder reserved words that are SentencedCased. properties(Constant) DefaultExclusionList = { 'Vector', 'Matrix' 'BlockIO' 'ExternalInputs' 'ContinuousStates' ... 'StateDerivatives' 'StateDisabled' 'CstateAbsTol' 'ExternalOutputs' ... 'Parameters' 'ConstParam' 'ConstParamWithInit' } end properties(SetAccess=immutable) ExclusionList end methods(Access=private) function obj = ReservedNamesChecker(listToUse) obj.ExclusionList = listToUse; end function out = mangleName(obj, name) %#ok<INUSL> out = [name '_']; end end methods (Access = {?robotics.slros.internal.bus.ReservedNamesChecker,?matlab.unittest.TestCase}) function out = isMangledName(obj, name) % TF = isMangledName(obj, NAME) returns true if and only if % NAME has the format "<ReservedWord>_" out = name(end)=='_' && ismember(name(1:end-1), obj.ExclusionList); end end methods function out = isReserved(obj, name) % TF = isReserved(obj, NAME) returns true if and only if % NAME exactly (& case-sensitively) matches a reserved word out = ismember(name, obj.ExclusionList); end function [out, isReserved] = mangleNameIfNeeded(obj, name) % [MNAME, TF] = mangleNameIfNeeded(obj, NAME) returns the % mangled name, MNAME, if NAME matches a reserved word. If % NAME does not match a reserved word, MNAME is same as NAME. % TF is a boolean indicating if NAME is a reserved word (and % hence whether MNAME is a mangled name). isReserved = ismember(name, obj.ExclusionList); if isReserved out = obj.mangleName(name); else out = name; end end end methods(Static) function [isAvailable, list] = exclusionListForTesting(listToUse) % exclusionListForTesting(listToUse) overrides the exclusion list % that will be used in by ReservedNamesChecker in a subsequent % call to getInstance. listToUse should be a cell array of % strings. % % exclusionListForTesting([]) resets (i.e., removes) the override. persistent exclusionList if nargin > 0 % allow empty double [] (indicates "clear") assert(isempty(listToUse) || iscellstr(listToUse)); exclusionList = listToUse; end isAvailable = ~(isa(exclusionList,'double') && isempty(exclusionList)); list = exclusionList; end function obj = getInstance() [isAvailable, list] = robotics.slros.internal.bus.ReservedNamesChecker.exclusionListForTesting(); if isAvailable obj = robotics.slros.internal.bus.ReservedNamesChecker(list); else obj = robotics.slros.internal.bus.ReservedNamesChecker(... robotics.slros.internal.bus.ReservedNamesChecker.DefaultExclusionList); end end end end