File indexing completed on 2023-03-17 10:51:38
0001 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0002
0003 #include <ostream>
0004
0005 #include "DetectorDescription/Core/interface/DDMaterial.h"
0006 #include "DetectorDescription/Core/interface/DDSolid.h"
0007 #include "DetectorDescription/Core/interface/LogicalPart.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009
0010 class DDValue;
0011
0012 void DD_NC(const DDName& n) {
0013 auto& ns = LPNAMES::instance()[n.name()];
0014
0015 bool alreadyIn(false);
0016 for (const auto& p : ns) {
0017 if (p.ns() == n.ns()) {
0018 alreadyIn = true;
0019 break;
0020 }
0021 }
0022 if (!alreadyIn) {
0023 ns.emplace_back(n);
0024 }
0025 }
0026
0027 std::ostream& operator<<(std::ostream& os, const DDLogicalPart& part) {
0028 DDBase<DDName, DDI::LogicalPart*>::def_type defined(part.isDefined());
0029 if (defined.first) {
0030 os << *(defined.first) << " ";
0031 if (defined.second) {
0032 part.rep().stream(os);
0033 } else {
0034 os << "* logicalpart not defined * ";
0035 }
0036 } else {
0037 os << "* logicalpart not declared * ";
0038 }
0039 return os;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 DDLogicalPart::DDLogicalPart(const DDName& name) : DDBase<DDName, std::unique_ptr<DDI::LogicalPart> >() {
0091 create(name);
0092 DD_NC(name);
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 DDLogicalPart::DDLogicalPart(const DDName& ddname,
0108 const DDMaterial& material,
0109 const DDSolid& solid,
0110 DDEnums::Category cat)
0111 : DDBase<DDName, std::unique_ptr<DDI::LogicalPart> >() {
0112 create(ddname, std::make_unique<DDI::LogicalPart>(material, solid, cat));
0113 DD_NC(ddname);
0114 }
0115
0116 DDEnums::Category DDLogicalPart::category() const { return rep().category(); }
0117
0118 const DDMaterial& DDLogicalPart::material() const { return rep().material(); }
0119
0120 const DDSolid& DDLogicalPart::solid() const { return rep().solid(); }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 std::vector<const DDsvalues_type*> DDLogicalPart::specifics() const {
0176 std::vector<const DDsvalues_type*> result;
0177 rep().specificsV(result);
0178 return result;
0179 }
0180
0181 DDsvalues_type DDLogicalPart::mergedSpecifics() const {
0182 DDsvalues_type result;
0183 rep().mergedSpecificsV(result);
0184 return result;
0185 }
0186
0187
0188 void DDLogicalPart::addSpecifics(const std::pair<const DDPartSelection*, const DDsvalues_type*>& s) {
0189 rep().addSpecifics(s);
0190 }
0191
0192 void DDLogicalPart::removeSpecifics(const std::pair<DDPartSelection*, DDsvalues_type*>& s) { rep().removeSpecifics(s); }
0193
0194 bool DDLogicalPart::hasDDValue(const DDValue& v) const { return rep().hasDDValue(v); }
0195
0196
0197
0198
0199
0200
0201 #include <regex.h>
0202 #include <cstddef>
0203
0204 namespace {
0205 struct Regex {
0206 explicit Regex(const std::string& s) : m_ok(false), me(s) {
0207 size_t p = me.find('.');
0208 m_ok = p != std::string::npos;
0209 if (m_ok) {
0210 if (p > 0) {
0211 m_range.first = me.substr(0, p);
0212 m_range.second = m_range.first + "{";
0213 }
0214 me = "^" + me + "$";
0215 regcomp(&m_regex, me.c_str(), 0);
0216 }
0217 }
0218
0219 ~Regex(void) {
0220 if (m_ok)
0221 regfree(&m_regex);
0222 }
0223
0224 bool empty(void) const { return me.empty(); }
0225
0226 bool notRegex(void) const { return !m_ok; }
0227
0228 const std::string& value(void) const { return me; }
0229
0230 bool match(const std::string& s) const {
0231 if (m_ok)
0232 return !regexec(&m_regex, s.c_str(), 0, nullptr, 0);
0233 else
0234 return me == s;
0235 }
0236
0237 const std::pair<std::string, std::string>& range(void) const { return m_range; }
0238
0239 private:
0240 bool m_ok;
0241 regex_t m_regex;
0242 std::string me;
0243
0244 std::pair<std::string, std::string> m_range;
0245 };
0246 }
0247
0248 std::pair<bool, std::string> DDIsValid(const std::string& ns,
0249 const std::string& nm,
0250 std::vector<DDLogicalPart>& result,
0251 bool doRegex) {
0252 if (!doRegex) {
0253 DDName ddnm(nm, ns);
0254 result.emplace_back(DDLogicalPart(ddnm));
0255 return std::make_pair(true, "");
0256 }
0257 std::string status;
0258 Regex aRegex(nm);
0259 Regex aNsRegex(ns);
0260 bool emptyNs = aNsRegex.empty();
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()), ed(LPNAMES::instance().end());
0272 typedef std::vector<LPNAMES::value_type::const_iterator> Candidates;
0273 Candidates candidates;
0274 if (aRegex.notRegex()) {
0275 LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
0276 if (it != ed)
0277 candidates.emplace_back(it);
0278 } else {
0279 if (!aRegex.range().first.empty()) {
0280 bn = LPNAMES::instance().lower_bound(aRegex.range().first);
0281 ed = LPNAMES::instance().upper_bound(aRegex.range().second);
0282 }
0283 for (LPNAMES::value_type::const_iterator it = bn; it != ed; ++it)
0284 if (aRegex.match(it->first))
0285 candidates.emplace_back(it);
0286 }
0287 for (const auto& it : candidates) {
0288
0289 std::vector<DDName>::size_type sz = it->second.size();
0290 if (emptyNs && (sz == 1)) {
0291 result.emplace_back(it->second[0]);
0292
0293
0294
0295
0296
0297 } else if (!emptyNs) {
0298 std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
0299 for (; nsit != nsed; ++nsit) {
0300
0301 bool another_doit = aNsRegex.match(nsit->ns());
0302 if (another_doit) {
0303
0304 result.emplace_back(DDLogicalPart(*nsit));
0305 }
0306 }
0307 } else {
0308 std::string message = "DDLogicalPart-name \"" + it->first + "\" matching regex \"" + nm +
0309 "\" has been found at least in following namespaces:\n";
0310 std::vector<DDName>::const_iterator vit = it->second.begin();
0311 for (; vit != it->second.end(); ++vit) {
0312 message += vit->ns();
0313 message += " ";
0314 }
0315 message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
0316 return std::make_pair(false, message);
0317 }
0318 }
0319 bool flag = true;
0320 std::string message;
0321
0322
0323 if (!result.empty()) {
0324 std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
0325 for (; lpit != lped; ++lpit) {
0326
0327 if (!lpit->isDefined().second) {
0328 message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
0329 flag = false;
0330 }
0331 }
0332 } else {
0333 flag = false;
0334 message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
0335 }
0336
0337 return std::make_pair(flag, message);
0338 }
0339
0340 const std::vector<std::pair<const DDPartSelection*, const DDsvalues_type*> >& DDLogicalPart::attachedSpecifics(
0341 void) const {
0342 return rep().attachedSpecifics();
0343 }