The vbs tools - vbs_ls, vbs_rm, vbs_fs - for listing, removing and mounting vbs and Mark6 format scattered VLBI recordings on FlexBuff and Mark6 systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

156 lines
4.8 KiB

  1. // Implementation of the RegularExpression class
  2. #include <regular_expression.h>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cstdlib>
  6. #include <cstring>
  7. using std::cerr;
  8. using std::endl;
  9. using std::flush;
  10. using std::string;
  11. DEFINE_EZEXCEPT(Regular_Expression_Exception)
  12. // support classes
  13. pcintregmatch_t::pcintregmatch_t() {
  14. this->::regmatch_t::rm_so = -1;
  15. this->::regmatch_t::rm_eo = -1;
  16. }
  17. pcintregmatch_t::pcintregmatch_t( const ::regmatch_t& rm ) {
  18. this->::regmatch_t::rm_so = rm.rm_so;
  19. this->::regmatch_t::rm_eo = rm.rm_eo;
  20. }
  21. pcintregmatch_t::operator bool() const {
  22. return (rm_so!=-1 && rm_eo!=-1);
  23. }
  24. matchresult::matchresult()
  25. {}
  26. matchresult::matchresult( const matchresult::matchvec_t& mv,
  27. const char* os ):
  28. __matches( mv ),
  29. __org_string( os )
  30. {}
  31. matchresult::matchresult( const matchresult::matchvec_t& mv,
  32. const std::string& os ):
  33. __matches( mv ),
  34. __org_string( os )
  35. {}
  36. matchresult::operator bool() const {
  37. return (__matches.size()!=0);
  38. }
  39. matchresult::matchvec_t::value_type matchresult::operator[]( unsigned int m ) const {
  40. if( m>=__matches.size() ) {
  41. THROW_EZEXCEPT(Regular_Expression_Exception,
  42. "requesting group " << m << ", but only " << __matches.size() << " groups matched");
  43. }
  44. return __matches[m];
  45. }
  46. std::string matchresult::operator[]( const matchvec_t::value_type& m ) const {
  47. if( !m ) {
  48. THROW_EZEXCEPT(Regular_Expression_Exception,
  49. "requesting string from invalid group");
  50. }
  51. return __org_string.substr(m.rm_so, (m.rm_eo-m.rm_so));
  52. }
  53. std::string matchresult::group( unsigned int m ) const {
  54. return (*this)[(*this)[m]];
  55. }
  56. bool operator==( const char* tocheck, const Regular_Expression& against ) {
  57. return against.matches( tocheck );
  58. }
  59. bool operator!=( const char* tocheck, const Regular_Expression& against ) {
  60. return !(against.matches( tocheck ));
  61. }
  62. bool operator==( const string& s, const Regular_Expression& against ) {
  63. return against.matches( s.c_str() );
  64. }
  65. bool operator!=( const string& s, const Regular_Expression& against ) {
  66. return !(against.matches(s.c_str()));
  67. }
  68. Regular_Expression::Regular_Expression( const char* pattern_text, int flags ) :
  69. myOriginalPattern( ((pattern_text!=0)?(strdup(pattern_text)):(strdup(""))) )
  70. {
  71. // Compile the pattern....
  72. int r;
  73. char errbuf[ 512 ];
  74. if( (r=::regcomp(&myCompiledExpression,
  75. myOriginalPattern,
  76. flags))!=0 ) {
  77. ::regerror(r, &myCompiledExpression, errbuf, sizeof(errbuf));
  78. THROW_EZEXCEPT(Regular_Expression_Exception,
  79. "Failed to compile RegEx(" << myOriginalPattern << "): " << errbuf);
  80. }
  81. // After compiling the regexp, the re_nsub member informs how many
  82. // sub expressions/match groups there were. Together with the zeroth
  83. // group (the whole) match, we know how many there are in total
  84. mySubexprs = new ::regmatch_t[ 1 + myCompiledExpression.re_nsub ];
  85. }
  86. Regular_Expression::Regular_Expression( const string& pattern_text, int flags ) :
  87. myOriginalPattern( ((pattern_text.size()!=0)?(strdup(pattern_text.c_str())):(strdup(""))) )
  88. {
  89. // Compile the pattern....
  90. int r;
  91. char errbuf[ 512 ];
  92. if( (r=::regcomp(&myCompiledExpression,
  93. myOriginalPattern,
  94. flags))!=0 ) {
  95. ::regerror(r, &myCompiledExpression, errbuf, sizeof(errbuf));
  96. THROW_EZEXCEPT(Regular_Expression_Exception,
  97. "Failed to compile RegEx(" << myOriginalPattern << "): " << errbuf);
  98. }
  99. // After compiling the regexp, the re_nsub member informs how many
  100. // sub expressions/match groups there were. Together with the zeroth
  101. // group (the whole) match, we know how many there are in total
  102. mySubexprs = new ::regmatch_t[ 1 + myCompiledExpression.re_nsub ];
  103. }
  104. matchresult Regular_Expression::matches( const char* s ) const {
  105. matchresult rv;
  106. if( !s )
  107. return rv;
  108. if( ::regexec(&myCompiledExpression, s, (size_t)(1+myCompiledExpression.re_nsub), mySubexprs, 0)==0 ) {
  109. // The "+1" is from the zeroth sub expression (the whole match)
  110. rv = matchresult(matchresult::matchvec_t(mySubexprs, mySubexprs+myCompiledExpression.re_nsub+1), s);
  111. }
  112. return rv;
  113. }
  114. matchresult Regular_Expression::matches( const string& s ) const {
  115. return this->matches( s.c_str() );
  116. }
  117. string Regular_Expression::pattern( void ) const {
  118. return myOriginalPattern;
  119. }
  120. Regular_Expression::~Regular_Expression() {
  121. if( myOriginalPattern )
  122. ::free( myOriginalPattern );
  123. ::regfree( &myCompiledExpression );
  124. delete [] mySubexprs;
  125. }