PageRenderTime 47ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/CS/tags/V1.2rc2/libs/csutil/regexp.cpp

#
C++ | 143 lines | 108 code | 18 blank | 17 comment | 23 complexity | 9886e2534b969bd584ad7c27c1d63691 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. Copyright (C) 2004 by Frank Richter
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public
  12. License along with this library; if not, write to the Free
  13. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "cssysdef.h"
  16. #include "csutil/regexp.h"
  17. #include "csutil/util.h"
  18. #include "regex_wrapper.h"
  19. static int exec_flags(int flags)
  20. {
  21. int execflags = 0;
  22. if (flags & csrxNotBOL) execflags |= REG_NOTBOL;
  23. if (flags & csrxNotEOL) execflags |= REG_NOTEOL;
  24. return execflags;
  25. }
  26. bool csRegExpMatcher::Compile (int flags, bool nosub)
  27. {
  28. int needFlags = 0;
  29. if (extendedRE) needFlags |= REG_EXTENDED;
  30. if (nosub) needFlags |= REG_NOSUB;
  31. if (flags & csrxIgnoreCase) needFlags |= REG_ICASE;
  32. if (flags & csrxNewLine) needFlags |= REG_NEWLINE;
  33. if ((regex == 0) ||
  34. ((needFlags & ~REG_NOSUB) != (compiledFlags & ~REG_NOSUB)) ||
  35. ((needFlags & REG_NOSUB) && !(compiledFlags & REG_NOSUB)))
  36. {
  37. if (regex != 0)
  38. regfree ((regex_t*)regex);
  39. else
  40. regex = new regex_t;
  41. int res = regcomp ((regex_t*)regex, pattern, needFlags);
  42. switch (res)
  43. {
  44. case 0: compileError = csrxNoError; break;
  45. case REG_BADBR: compileError = csrxBadBraces; break;
  46. case REG_BADPAT: compileError = csrxBadPattern; break;
  47. case REG_BADRPT: compileError = csrxBadRepetition; break;
  48. case REG_ECOLLATE: compileError = csrxErrCollate; break;
  49. case REG_ECTYPE: compileError = csrxErrCharType; break;
  50. case REG_EESCAPE: compileError = csrxErrEscape; break;
  51. case REG_ESUBREG: compileError = csrxErrSubReg; break;
  52. case REG_EBRACK: compileError = csrxErrBrackets; break;
  53. case REG_EPAREN: compileError = csrxErrParentheses; break;
  54. case REG_EBRACE: compileError = csrxErrBraces; break;
  55. case REG_ERANGE: compileError = csrxErrRange; break;
  56. case REG_ESPACE: compileError = csrxErrSpace; break;
  57. default: compileError = csrxErrUnknown; break;
  58. }
  59. }
  60. return (compileError == csrxNoError);
  61. }
  62. csRegExpMatcher::csRegExpMatcher (const char* pattern, bool extendedRE) :
  63. regex(0)
  64. {
  65. csRegExpMatcher::pattern = csStrNew (pattern);
  66. csRegExpMatcher::extendedRE = extendedRE;
  67. }
  68. csRegExpMatcher::csRegExpMatcher (const csRegExpMatcher& other) :
  69. regex (0)
  70. {
  71. pattern = csStrNew (other.pattern);
  72. extendedRE = other.extendedRE;
  73. }
  74. csRegExpMatcher::~csRegExpMatcher ()
  75. {
  76. if (regex)
  77. {
  78. regfree ((regex_t*)regex);
  79. delete (regex_t*)regex;
  80. }
  81. delete[] pattern;
  82. }
  83. csRegExpMatcher& csRegExpMatcher::operator= (const csRegExpMatcher &other)
  84. {
  85. if (regex)
  86. {
  87. regfree ((regex_t*)regex);
  88. delete (regex_t*)regex;
  89. regex = 0;
  90. }
  91. delete[] pattern;
  92. pattern = csStrNew (other.pattern);
  93. extendedRE = other.extendedRE;
  94. return *this;
  95. }
  96. csRegExpMatchError csRegExpMatcher::Match (const char* string, int flags)
  97. {
  98. if (!Compile (flags, true))
  99. return compileError;
  100. return (regexec ((regex_t*)regex, string, 0, 0, exec_flags(flags)) == 0) ?
  101. csrxNoError : csrxNoMatch;
  102. }
  103. csRegExpMatchError csRegExpMatcher::Match (const char* string,
  104. csArray<csRegExpMatch>& matches,
  105. int flags)
  106. {
  107. matches.Empty();
  108. if (!Compile (flags, false))
  109. return compileError;
  110. CS_ALLOC_STACK_ARRAY(regmatch_t, re_matches, ((regex_t*)regex)->re_nsub);
  111. if (regexec ((regex_t*)regex, string, ((regex_t*)regex)->re_nsub,
  112. re_matches, exec_flags(flags)) != 0)
  113. return csrxNoMatch;
  114. for (size_t i = 0; i < ((regex_t*)regex)->re_nsub; i++)
  115. {
  116. csRegExpMatch match;
  117. match.startOffset = re_matches[i].rm_so;
  118. match.endOffset = re_matches[i].rm_eo;
  119. matches.Push (match);
  120. }
  121. return csrxNoError;
  122. }