PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/CS/migrated/tags/PRE_EVENT_UNION_REMOVAL/libs/csutil/regexp.cpp

#
C++ | 120 lines | 89 code | 14 blank | 17 comment | 22 complexity | ef16802a760461d9369c6429e677cec3 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 ()
  69. {
  70. if (regex)
  71. {
  72. regfree ((regex_t*)regex);
  73. delete (regex_t*)regex;
  74. }
  75. delete[] pattern;
  76. }
  77. csRegExpMatchError csRegExpMatcher::Match (const char* string, int flags)
  78. {
  79. if (!Compile (flags, true))
  80. return compileError;
  81. return (regexec ((regex_t*)regex, string, 0, 0, exec_flags(flags)) == 0) ?
  82. csrxNoError : csrxNoMatch;
  83. }
  84. csRegExpMatchError csRegExpMatcher::Match (const char* string,
  85. csArray<csRegExpMatch>& matches,
  86. int flags)
  87. {
  88. matches.Empty();
  89. if (!Compile (flags, false))
  90. return compileError;
  91. CS_ALLOC_STACK_ARRAY(regmatch_t, re_matches, ((regex_t*)regex)->re_nsub);
  92. if (regexec ((regex_t*)regex, string, ((regex_t*)regex)->re_nsub,
  93. re_matches, exec_flags(flags)) != 0)
  94. return csrxNoMatch;
  95. for (size_t i = 0; i < ((regex_t*)regex)->re_nsub; i++)
  96. {
  97. csRegExpMatch match;
  98. match.startOffset = re_matches[i].rm_so;
  99. match.endOffset = re_matches[i].rm_eo;
  100. matches.Push (match);
  101. }
  102. return csrxNoError;
  103. }