File indexing completed on 2026-04-09 07:49:41
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <cstring>
0017 #include <vector>
0018 #include <string>
0019 #include <sstream>
0020 #include <iostream>
0021 #include <iomanip>
0022 #include <fstream>
0023 #include <algorithm>
0024
0025 #include "spath.h"
0026 #include "sstr.h"
0027
0028
0029 enum { SName_EXACT, SName_START, SName_CONTAIN } ;
0030
0031 struct SName
0032 {
0033 static constexpr const bool VERBOSE = false ;
0034 static constexpr const char* EXACT = "EXACT" ;
0035 static constexpr const char* START = "START" ;
0036 static constexpr const char* CONTAIN = "CONTAIN" ;
0037
0038
0039 static constexpr const char* STARTING_ = "^" ;
0040 static bool Has_STARTING(const char* str);
0041 static bool Has_STARTING(const std::vector<std::string>& qq);
0042
0043 static unsigned QType(char qt);
0044 static const char* QLabel(unsigned qtype);
0045 static const char* QTypeLabel(char qt);
0046 static bool Match( const char* n, const char* q, unsigned qtype );
0047
0048 static SName* Load(const char* path);
0049 static constexpr const char* GEOMLoadPath = "$CFBaseFromGEOM/CSGFoundry/meshname.txt" ;
0050 static SName* GEOMLoad();
0051
0052 static constexpr const char* parseArg_ALL = "ALL" ;
0053 static const bool dump = false ;
0054 static int ParseIntString(const char* arg, int fallback=-1);
0055 static void ParseSOPR(int& solidIdx, int& primIdxRel, const char* sopr );
0056
0057
0058 const std::vector<std::string>& name ;
0059
0060 SName(const std::vector<std::string>& name );
0061
0062 std::string desc() const ;
0063 std::string detail() const ;
0064
0065 unsigned getNumName() const;
0066 const char* getName(unsigned idx) const ;
0067 const char* getAbbr(unsigned idx) const ;
0068
0069
0070 int findIndexWithName(const char* qname, bool startswith) const ;
0071
0072 int getIndex( const char* name , unsigned& count) const ;
0073 int findIndex(const char* q, unsigned& count, int max_count=-1, bool starting=false, std::ostream* out=nullptr ) const ;
0074 int findIndex(const char* q, bool starting, std::ostream* out ) const ;
0075
0076 void findIndicesStarting(std::vector<unsigned>& idxs, const char* name_start ) const ;
0077 void findIndicesFromNames(std::vector<unsigned>& idxs, const std::vector<std::string>& qq, std::vector<std::string>* qq_missing, std::ostream* out ) const ;
0078
0079 static void SortUnique( std::vector<unsigned>& v );
0080
0081
0082 bool hasName( const char* q, bool starting, std::ostream* out=nullptr ) const ;
0083 bool hasNames( const char* qq, char delim=',', const char* prefix=nullptr, std::vector<std::string>* qq_missing=nullptr, std::ostream* out=nullptr ) const ;
0084 bool hasNames( const std::vector<std::string>& qq, std::vector<std::string>* qq_missing=nullptr, std::ostream* out=nullptr ) const ;
0085
0086
0087 void findIndicesMatch(std::vector<unsigned>& idxs, const char* query, char qt='S' ) const ;
0088 std::string descIndices(const std::vector<unsigned>& idxs) const ;
0089
0090
0091 const char* getIDXListFromNames( const char* qq, char delim=',' , const char* prefix=nullptr, std::vector<std::string>* qq_missing=nullptr, std::ostream* out=nullptr ) const ;
0092 const char* getIDXListFromNames( const std::vector<std::string>& qq, const char* prefix=nullptr, std::vector<std::string>* qq_missing=nullptr, std::ostream* out=nullptr ) const ;
0093 const char* getIDXListFromContaining( const char* names_containing="_virtual0x", const char* prefix=nullptr ) const;
0094 static const char* IDXList(const std::vector<unsigned>& idxs, const char* prefix=nullptr );
0095
0096
0097 int parseArg(const char* arg, unsigned& count ) const ;
0098 void parseMOI(int& midx, int& mord, int& iidx, const char* moi) const ;
0099
0100 };
0101
0102
0103 inline bool SName::Has_STARTING(const char* str)
0104 {
0105 if(!str) return false ;
0106 if(!STARTING_) return false ;
0107 bool one = strlen(STARTING_) == 1 ;
0108 return one ? str[0] == STARTING_[0] : ( nullptr != strstr( str, STARTING_ )) ;
0109 }
0110 inline bool SName::Has_STARTING(const std::vector<std::string>& qq)
0111 {
0112 int count = 0 ;
0113 for(size_t i=0 ; i < qq.size() ; i++ ) if(Has_STARTING(qq[i].c_str())) count += 1 ;
0114 return count > 0 ;
0115 }
0116
0117
0118 inline SName* SName::Load(const char* path_)
0119 {
0120 const char* path = spath::Resolve(path_);
0121 if(path == nullptr)
0122 {
0123 std::cerr
0124 << "SName::Load FAILED to Resolve["
0125 << ( path_ ? path_ : "-" )
0126 << std::endl
0127 ;
0128 return nullptr ;
0129 }
0130
0131 typedef std::vector<std::string> VS ;
0132 VS* names = new VS ;
0133
0134 std::ifstream ifs(path);
0135 std::string line;
0136 while(std::getline(ifs, line)) names->push_back(line) ;
0137
0138 SName* id = new SName(*names) ;
0139 return id ;
0140 }
0141
0142 inline SName* SName::GEOMLoad(){ return Load(GEOMLoadPath); }
0143
0144
0145 inline SName::SName( const std::vector<std::string>& name_ )
0146 :
0147 name(name_)
0148 {
0149 }
0150
0151 inline std::string SName::desc() const
0152 {
0153 unsigned num_name = getNumName() ;
0154 std::stringstream ss ;
0155 ss << "SName::desc numName " << num_name ; ;
0156 if( num_name > 0 ) ss << " name[0] " << getName(0) << " name[-1] " << getName(num_name-1 ) ;
0157 std::string s = ss.str();
0158 return s ;
0159 }
0160
0161 inline std::string SName::detail() const
0162 {
0163 unsigned num_name = getNumName() ;
0164 std::stringstream ss ;
0165 ss << "SName::detail num_name " << num_name << std::endl ;
0166 for(unsigned i=0 ; i < num_name ; i++) ss << getName(i) << std::endl ;
0167 std::string s = ss.str();
0168 return s ;
0169 }
0170
0171
0172 inline unsigned SName::getNumName() const
0173 {
0174 return name.size();
0175 }
0176 inline const char* SName::getName(unsigned idx) const
0177 {
0178 return idx < name.size() ? name[idx].c_str() : nullptr ;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 inline const char* SName::getAbbr(unsigned idx) const
0190 {
0191 const char* name = getName(idx);
0192
0193 unsigned count = 0 ;
0194 int idx0 = getIndex(name, count) ;
0195
0196 if( idx0 != int(idx) ) return nullptr ;
0197
0198
0199 char* sname = strdup(name);
0200 int nj = int(strlen(sname));
0201
0202 if( idx == 0 )
0203 {
0204 std::cout
0205 << " idx " << idx
0206 << " idx0 " << idx0
0207 << " count " << count
0208 << " name " << name
0209 << " sname " << sname
0210 << " nj " << nj
0211 << std::endl
0212 ;
0213 }
0214
0215
0216 unsigned max_count = 2 ;
0217 for(int j=0 ; j < nj ; j++)
0218 {
0219 sname[nj-1-j] = '\0' ;
0220 count = 0 ;
0221 int idx1 = findIndex(sname, count, max_count );
0222
0223 if( idx == 0 )
0224 std::cout
0225 << " j " << j
0226 << " sname " << sname
0227 << " idx1 " << idx1
0228 << std::endl
0229 ;
0230
0231
0232 if(idx1 != int(idx) )
0233 {
0234 sname[nj-1-j] = name[nj-1-j] ;
0235 break ;
0236 }
0237 }
0238 return sname ;
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 inline int SName::findIndexWithName(const char* qname, bool startswith) const
0252 {
0253 unsigned count = 0 ;
0254 int max_count = -1 ;
0255 return startswith ? findIndex(qname, count, max_count) : getIndex( qname, count ) ;
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 inline int SName::getIndex(const char* query, unsigned& count) const
0273 {
0274 int result(-1);
0275 count = 0 ;
0276 for(unsigned i=0 ; i < name.size() ; i++)
0277 {
0278 const char* k = name[i].c_str() ;
0279 if(strcmp(k, query) == 0 )
0280 {
0281 if(count == 0) result = i ;
0282 count += 1 ;
0283 }
0284 }
0285 return result ;
0286 }
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 inline int SName::findIndex(const char* q, unsigned& count, int max_count, bool starting, std::ostream* out ) const
0334 {
0335 int result(-1);
0336 count = 0 ;
0337 for(unsigned i=0 ; i < name.size() ; i++)
0338 {
0339 const char* k = name[i].c_str() ;
0340 if( sstr::Match( k, q, starting ))
0341 {
0342 if(count == 0) result = i ;
0343 count += 1 ;
0344 }
0345 }
0346 bool count_ok = max_count == -1 || count <= unsigned(max_count) ;
0347 int idx = count_ok ? result : -1 ;
0348
0349 if(out && idx < 0) *out
0350 << "[SName::findIndex.0"
0351 << " q [" << ( q ? q : "-" ) << "]"
0352 << " count_ok " << ( count_ok ? "YES" : "NO " )
0353 << " count " << count
0354 << " max_count " << max_count
0355 << " result " << result
0356 << " idx " << idx
0357 << "]\n"
0358 ;
0359
0360 return idx ;
0361
0362 }
0363
0364 inline void SName::findIndicesStarting(std::vector<unsigned>& idxs, const char* name_start ) const
0365 {
0366 bool starting = true ;
0367 for(unsigned i=0 ; i < name.size() ; i++)
0368 {
0369 const char* k = name[i].c_str() ;
0370 if( sstr::Match( k, name_start, starting ))
0371 {
0372 idxs.push_back(i) ;
0373 }
0374 }
0375 }
0376
0377
0378
0379 inline int SName::findIndex(const char* q, bool starting, std::ostream* out ) const
0380 {
0381 unsigned count = 0 ;
0382 int max_count = -1 ;
0383 int idx = findIndex(q, count, max_count, starting, out );
0384 if(out && idx < 0) *out << "[SName::findIndex.1"
0385 << " q [" << ( q ? q : "-" )
0386 << " count " << count
0387 << " max_count " << max_count
0388 << " idx " << idx
0389 << "]\n"
0390 ;
0391
0392 return idx ;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 inline void SName::findIndicesFromNames(std::vector<unsigned>& idxs, const std::vector<std::string>& qq, std::vector<std::string>* qq_missing, std::ostream* out ) const
0406 {
0407 unsigned nqq = qq.size();
0408
0409 if(out) *out
0410 << "[SName::findIndicesFromNames"
0411 << " qq.size " << nqq
0412 << "\n"
0413 ;
0414
0415 if(VERBOSE) for(unsigned i=0 ; i < nqq ; i++ ) std::cerr << qq[i] << std::endl ;
0416
0417 bool with_STARTING = false ;
0418
0419 for(unsigned i=0 ; i < nqq ; i++)
0420 {
0421 const char* q = qq[i].c_str();
0422 bool q_starting = 0 == strncmp(q, STARTING_, strlen(STARTING_) );
0423
0424 if( q_starting == false )
0425 {
0426 int idx = findIndex(q, false, out ) ;
0427 bool found = idx > -1 ;
0428 if(found)
0429 {
0430 idxs.push_back(idx) ;
0431 }
0432 else
0433 {
0434 if(qq_missing) qq_missing->push_back(q);
0435 }
0436 }
0437 else
0438 {
0439 const char* q_unprefixed = q + strlen(STARTING_);
0440 findIndicesStarting(idxs, q_unprefixed );
0441 with_STARTING = true ;
0442 }
0443 }
0444
0445 if(with_STARTING)
0446 {
0447 SortUnique(idxs);
0448 }
0449
0450
0451 if(out) *out
0452 << "]SName::findIndicesFromNames"
0453 << " qq.size " << nqq
0454 << "\n"
0455 ;
0456
0457
0458
0459 }
0460
0461
0462
0463 inline void SName::SortUnique( std::vector<unsigned>& v )
0464 {
0465 std::sort(v.begin(), v.end());
0466 auto last = std::unique(v.begin(), v.end());
0467 v.erase(last, v.end());
0468 }
0469
0470
0471 inline bool SName::hasName( const char* q, bool starting, std::ostream* out ) const
0472 {
0473 int idx = findIndex(q, starting, out );
0474 bool has = idx > -1 ;
0475 return has ;
0476 }
0477
0478
0479
0480 inline bool SName::hasNames( const char* qq_, char delim, const char* prefix, std::vector<std::string>* qq_missing, std::ostream* out ) const
0481 {
0482 const char* uqq = qq_ + ( prefix ? strlen(prefix) : 0 ) ;
0483 if(out) *out
0484 << "SName::hasNames.qq.d.p "
0485 << " prefix " << ( prefix ? prefix : "-" )
0486 << " qq_ [" << ( qq_ ? qq_ : "-" ) << "]\n"
0487 << " uqq [" << ( uqq ? uqq : "-" ) << "]\n"
0488 ;
0489
0490 std::vector<std::string> qq;
0491 sstr::SplitTrimSuppress( uqq, delim, qq );
0492 return hasNames(qq, qq_missing, out );
0493 }
0494
0495
0496 inline bool SName::hasNames( const std::vector<std::string>& qq, std::vector<std::string>* qq_missing, std::ostream* out) const
0497 {
0498 std::vector<unsigned> idxs ;
0499 findIndicesFromNames(idxs, qq, qq_missing, out );
0500 bool has_all = qq.size() == idxs.size() ;
0501 if(out) *out
0502 << "SName::hasNames.qq "
0503 << " qq.size " << qq.size()
0504 << " idxs.size " << idxs.size()
0505 << " qq_missing " << ( qq_missing ? "YES" : "NO" )
0506 << " qq_missing.size " << ( qq_missing ? qq_missing->size() : -1 )
0507 << " has_all " << has_all
0508 << std::endl
0509 ;
0510 return has_all ;
0511 }
0512
0513
0514
0515
0516
0517
0518
0519 inline const char* SName::QLabel(unsigned qtype)
0520 {
0521 const char* s = nullptr ;
0522 switch(qtype)
0523 {
0524 case SName_EXACT : s = EXACT ; break ;
0525 case SName_START : s = START ; break ;
0526 case SName_CONTAIN : s = CONTAIN ; break ;
0527 }
0528 return s ;
0529 }
0530
0531 inline unsigned SName::QType(char qt)
0532 {
0533 unsigned qtype = SName_EXACT ;
0534 switch(qt)
0535 {
0536 case 'E': qtype = SName_EXACT ; break ;
0537 case 'S': qtype = SName_START ; break ;
0538 case 'C': qtype = SName_CONTAIN ; break ;
0539 }
0540 return qtype ;
0541 }
0542 inline const char* SName::QTypeLabel(char qt)
0543 {
0544 unsigned qtype = QType(qt);
0545 return QLabel(qtype);
0546 }
0547
0548
0549 inline bool SName::Match( const char* n, const char* q, unsigned qtype )
0550 {
0551 bool match = false ;
0552 switch( qtype )
0553 {
0554 case SName_EXACT: match = strcmp(n,q) == 0 ; break ;
0555 case SName_START: match = sstr::MatchStart(n,q) ; break ;
0556 case SName_CONTAIN: match = sstr::Contains(n,q) ; break ;
0557 }
0558 return match ;
0559 }
0560
0561 inline void SName::findIndicesMatch(std::vector<unsigned>& idxs, const char* q, char qt ) const
0562 {
0563 unsigned qtype = QType(qt);
0564 for(unsigned i=0 ; i < name.size() ; i++)
0565 {
0566 const char* n = name[i].c_str() ;
0567 if(Match(n,q,qtype)) idxs.push_back(i) ;
0568 }
0569 }
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 inline const char* SName::getIDXListFromNames( const char* names_, char delim, const char* prefix, std::vector<std::string>* qq_missing, std::ostream* out ) const
0580 {
0581 const char* unames = prefix == nullptr ? names_ : names_ + strlen(prefix ) ;
0582 std::vector<std::string> names ;
0583 sstr::SplitTrimSuppress(unames, delim, names);
0584
0585
0586 return getIDXListFromNames( names, prefix, qq_missing, out );
0587 }
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 inline const char* SName::getIDXListFromNames( const std::vector<std::string>& qq, const char* prefix, std::vector<std::string>* qq_missing, std::ostream* out ) const
0601 {
0602 bool require_all_names = !Has_STARTING(qq) && qq_missing == nullptr ;
0603
0604 std::vector<unsigned> idxs ;
0605 findIndicesFromNames(idxs, qq, qq_missing, out );
0606
0607 if(require_all_names)
0608 {
0609 bool found_all_names = qq.size() == idxs.size() ;
0610 if(!found_all_names) std::cerr
0611 << "SName::getIDXListFromNames !found_all_names "
0612 << " qq.size " << qq.size()
0613 << " idxs.size " << idxs.size()
0614 << " require_all_names " << ( require_all_names ? "YES" : "NO " )
0615 << std::endl
0616 ;
0617 assert( found_all_names );
0618 }
0619
0620 return IDXList(idxs, prefix);
0621 }
0622 inline const char* SName::getIDXListFromContaining( const char* names_containing, const char* prefix) const
0623 {
0624 std::vector<unsigned> idxs ;
0625 findIndicesMatch(idxs, names_containing, 'C' );
0626 return IDXList(idxs, prefix);
0627 }
0628 inline const char* SName::IDXList(const std::vector<unsigned>& idxs, const char* prefix )
0629 {
0630 unsigned num_idx = idxs.size() ;
0631 std::stringstream ss ;
0632 if(prefix) ss << prefix ;
0633 for(unsigned i=0 ; i < num_idx ; i++) ss << idxs[i] << ( i < num_idx - 1 ? "," : "" ) ;
0634 std::string s = ss.str();
0635 return strdup(s.c_str());
0636 }
0637
0638
0639 inline std::string SName::descIndices(const std::vector<unsigned>& idxs) const
0640 {
0641 std::stringstream ss ;
0642 for(unsigned i=0 ; i < idxs.size() ; i++)
0643 {
0644 unsigned idx = idxs[i] ;
0645 ss << std::setw(4) << idx << " : " << name[idx] << std::endl ;
0646 }
0647 std::string s = ss.str();
0648 return s ;
0649 }
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 inline int SName::parseArg(const char* arg, unsigned& count) const
0665 {
0666 count = 0 ;
0667
0668 int fallback = -1 ;
0669 int idx = fallback ;
0670
0671 bool is_all = strcmp( arg, parseArg_ALL) == 0 ? true : false ;
0672 if(is_all)
0673 {
0674 count = 1 ;
0675 }
0676 else
0677 {
0678 idx = ParseIntString(arg, fallback ) ;
0679 if(idx == fallback)
0680 {
0681 int max_count = -1 ;
0682 bool starting = true ;
0683 idx = findIndex(arg, count, max_count, starting );
0684 }
0685 else
0686 {
0687 count = 1 ;
0688 }
0689 }
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 return idx ;
0703 }
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 inline int SName::ParseIntString(const char* arg, int fallback)
0715 {
0716 char* end ;
0717 char** endptr = &end ;
0718 int base = 10 ;
0719 unsigned long int uli = strtoul(arg, endptr, base);
0720 bool end_points_to_terminator = end == arg + strlen(arg) ;
0721 int result = int(uli) ;
0722 int ret = end_points_to_terminator ? result : fallback ;
0723
0724 if(dump) std::cout
0725 << " arg [" << arg << "] "
0726 << " uli " << uli
0727 << " end_points_to_terminator " << end_points_to_terminator
0728 << " result " << result
0729 << " ret " << ret
0730 << std::endl
0731 ;
0732
0733 return ret ;
0734 }
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 inline void SName::ParseSOPR(int& solidIdx, int& primIdxRel, const char* sopr_ )
0749 {
0750 const char* sopr = sstr::ReplaceChars(sopr_, "_", ':');
0751
0752 std::stringstream ss;
0753 ss.str(sopr) ;
0754 std::string s;
0755 char delim = ':' ;
0756 std::vector<std::string> elem ;
0757 while (std::getline(ss, s, delim)) elem.push_back(s) ;
0758
0759 unsigned num_elem = elem.size();
0760
0761 solidIdx = num_elem > 0 ? ParseIntString( elem[0].c_str() ) : 0 ;
0762 primIdxRel = num_elem > 1 ? ParseIntString( elem[1].c_str() ) : 0 ;
0763
0764 if(dump) std::cout
0765 << " sopr_ " << sopr_
0766 << " sopr " << sopr
0767 << " solidIdx " << solidIdx
0768 << " primIdxRel " << primIdxRel
0769 << std::endl
0770 ;
0771 }
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808 inline void SName::parseMOI(int& midx, int& mord, int& iidx, const char* moi ) const
0809 {
0810 std::stringstream ss;
0811 ss.str(moi) ;
0812 std::string s;
0813 char delim = ':' ;
0814 std::vector<std::string> elem ;
0815 while (std::getline(ss, s, delim)) elem.push_back(s) ;
0816
0817 unsigned num_elem = elem.size();
0818
0819 unsigned count = 0 ;
0820 midx = num_elem > 0 ? parseArg( elem[0].c_str(), count) : 0 ;
0821 mord = num_elem > 1 ? ParseIntString( elem[1].c_str() ) : 0 ;
0822 iidx = num_elem > 2 ? ParseIntString( elem[2].c_str() ) : 0 ;
0823
0824
0825 if(dump) std::cout
0826 << " moi " << moi
0827 << " num_elem " << num_elem
0828 << " count " << count
0829 << " midx " << midx
0830 << " mord " << mord
0831 << " iidx " << iidx
0832 << " name.size " << name.size()
0833 << std::endl
0834 ;
0835 }
0836
0837
0838