PageRenderTime 62ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/CS/tags/V1.4.0rc1/libs/csutil/regexp.cpp

#
C++ | 133 lines | 98 code | 18 blank | 17 comment | 21 complexity | 62cc2ea981ef57e9d27803c18112b0e2 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. static int exec_flags(int flags)
  19. {
  20. int execflags = 0;
  21. if (flags & csrxNotBOL) execflags |= REG_NOTBOL;
  22. if (flags & csrxNotEOL) execflags |= REG_NOTEOL;
  23. return execflags;
  24. }
  25. bool csRegExpMatcher::Compile (int flags, bool nosub)
  26. {
  27. int needFlags = 0;
  28. if (extendedRE) needFlags |= REG_EXTENDED;
  29. if (nosub) needFlags |= REG_NOSUB;
  30. if (flags & csrxIgnoreCase) needFlags |= REG_ICASE;
  31. if (flags & csrxNewLine) needFlags |= REG_NEWLINE;
  32. if ((!regexpSetup) ||
  33. ((needFlags & ~REG_NOSUB) != (compiledFlags & ~REG_NOSUB)) ||
  34. ((needFlags & REG_NOSUB) && !(compiledFlags & REG_NOSUB)))
  35. {
  36. if (regexpSetup)
  37. regfree (&regex);
  38. int res = regcomp (&regex, pattern, needFlags);
  39. regexpSetup = true;
  40. switch (res)
  41. {
  42. case 0: compileError = csrxNoError; break;
  43. case REG_BADBR: compileError = csrxBadBraces; break;
  44. case REG_BADPAT: compileError = csrxBadPattern; break;
  45. case REG_BADRPT: compileError = csrxBadRepetition; break;
  46. case REG_ECOLLATE: compileError = csrxErrCollate; break;
  47. case REG_ECTYPE: compileError = csrxErrCharType; break;
  48. case REG_EESCAPE: compileError = csrxErrEscape; break;
  49. case REG_ESUBREG: compileError = csrxErrSubReg; break;
  50. case REG_EBRACK: compileError = csrxErrBrackets; break;
  51. case REG_EPAREN: compileError = csrxErrParentheses; break;
  52. case REG_EBRACE: compileError = csrxErrBraces; break;
  53. case REG_ERANGE: compileError = csrxErrRange; break;
  54. case REG_ESPACE: compileError = csrxErrSpace; break;
  55. default: compileError = csrxErrUnknown; break;
  56. }
  57. }
  58. return (compileError == csrxNoError);
  59. }
  60. csRegExpMatcher::csRegExpMatcher (const char* pattern, bool extendedRE) :
  61. pattern (CS::StrDup (pattern)), regexpSetup (false), extendedRE (extendedRE)
  62. {
  63. }
  64. csRegExpMatcher::csRegExpMatcher (const csRegExpMatcher& other) :
  65. pattern (CS::StrDup (other.pattern)), regexpSetup (false),
  66. extendedRE (other.extendedRE)
  67. {
  68. }
  69. csRegExpMatcher::~csRegExpMatcher ()
  70. {
  71. if (regexpSetup) regfree (&regex);
  72. cs_free (pattern);
  73. }
  74. csRegExpMatcher& csRegExpMatcher::operator= (const csRegExpMatcher &other)
  75. {
  76. if (regexpSetup)
  77. {
  78. regfree (&regex);
  79. regexpSetup = false;
  80. }
  81. cs_free (pattern);
  82. pattern = CS::StrDup (other.pattern);
  83. extendedRE = other.extendedRE;
  84. return *this;
  85. }
  86. csRegExpMatchError csRegExpMatcher::Match (const char* string, int flags)
  87. {
  88. if (!Compile (flags, true))
  89. return compileError;
  90. return (regexec (&regex, string, 0, 0, exec_flags(flags)) == 0) ?
  91. csrxNoError : csrxNoMatch;
  92. }
  93. csRegExpMatchError csRegExpMatcher::Match (const char* string,
  94. csArray<csRegExpMatch>& matches,
  95. int flags)
  96. {
  97. matches.Empty();
  98. if (!Compile (flags, false))
  99. return compileError;
  100. CS_ALLOC_STACK_ARRAY(regmatch_t, re_matches, regex.re_nsub);
  101. if (regexec (&regex, string, regex.re_nsub,
  102. re_matches, exec_flags(flags)) != 0)
  103. return csrxNoMatch;
  104. for (size_t i = 0; i < regex.re_nsub; i++)
  105. {
  106. csRegExpMatch match;
  107. match.startOffset = re_matches[i].rm_so;
  108. match.endOffset = re_matches[i].rm_eo;
  109. matches.Push (match);
  110. }
  111. return csrxNoError;
  112. }