regexec.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * the outer shell of regexec()
  3.  *
  4.  * This file includes engine.c *twice*, after muchos fiddling with the
  5.  * macros that code uses.  This lets the same code operate on two different
  6.  * representations for state sets.
  7.  */
  8. #include <my_global.h>
  9. #include <m_string.h>
  10. #include <m_ctype.h>
  11. #ifdef __WIN__
  12. #include  <limits.h>
  13. #endif
  14. #include "my_regex.h"
  15. #include "utils.h"
  16. #include "regex2.h"
  17. static int nope = 0; /* for use in asserts; shuts lint up */
  18. /* macros for manipulating states, small version */
  19. #define states long
  20. #define states1 states /* for later use in regexec() decision */
  21. #define CLEAR(v) ((v) = 0)
  22. #define SET0(v, n) ((v) &= ~((states) 1 << (n)))
  23. #define SET1(v, n) ((v) |= (states) 1 << (n))
  24. #define ISSET(v, n) ((v) & ((states) 1 << (n)))
  25. #define ASSIGN(d, s) ((d) = (s))
  26. #define EQ(a, b) ((a) == (b))
  27. #define STATEVARS int dummy /* dummy version */
  28. #define STATESETUP(m, n) /* nothing */
  29. #define STATETEARDOWN(m) /* nothing */
  30. #define SETUP(v) ((v) = 0)
  31. #define onestate long /* Changed from int by Monty */
  32. #define INIT(o, n) ((o) = (unsigned states)1 << (n))
  33. #define INC(o) ((o) <<= 1)
  34. #define ISSTATEIN(v, o) ((v) & (o))
  35. /* some abbreviations; note that some of these know variable names! */
  36. /* do "if I'm here, I can also be there" etc without branches */
  37. #define FWD(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) << (n))
  38. #define BACK(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) >> (n))
  39. #define ISSETBACK(v, n) ((v) & ((unsigned states)here >> (n)))
  40. /* function names */
  41. #define SNAMES /* engine.c looks after details */
  42. #include "engine.c"
  43. /* now undo things */
  44. #undef states
  45. #undef CLEAR
  46. #undef SET0
  47. #undef SET1
  48. #undef ISSET
  49. #undef ASSIGN
  50. #undef EQ
  51. #undef STATEVARS
  52. #undef STATESETUP
  53. #undef STATETEARDOWN
  54. #undef SETUP
  55. #undef onestate
  56. #undef INIT
  57. #undef INC
  58. #undef ISSTATEIN
  59. #undef FWD
  60. #undef BACK
  61. #undef ISSETBACK
  62. #undef SNAMES
  63. /* macros for manipulating states, large version */
  64. #define states char *
  65. #define CLEAR(v) memset(v, 0, m->g->nstates)
  66. #define SET0(v, n) ((v)[n] = 0)
  67. #define SET1(v, n) ((v)[n] = 1)
  68. #define ISSET(v, n) ((v)[n])
  69. #define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
  70. #define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
  71. #define STATEVARS int vn; char *space
  72. #define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); 
  73. if ((m)->space == NULL) return(REG_ESPACE); 
  74. (m)->vn = 0; }
  75. #define STATETEARDOWN(m) { free((m)->space); }
  76. #define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
  77. #define onestate int
  78. #define INIT(o, n) ((o) = (n))
  79. #define INC(o) ((o)++)
  80. #define ISSTATEIN(v, o) ((v)[o])
  81. /* some abbreviations; note that some of these know variable names! */
  82. /* do "if I'm here, I can also be there" etc without branches */
  83. #define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
  84. #define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
  85. #define ISSETBACK(v, n) ((v)[here - (n)])
  86. /* function names */
  87. #define LNAMES /* flag */
  88. #include "engine.c"
  89. /*
  90.  - regexec - interface for matching
  91.  = extern int regexec(const regex_t *, const char *, size_t, 
  92.  = regmatch_t [], int);
  93.  = #define REG_NOTBOL 00001
  94.  = #define REG_NOTEOL 00002
  95.  = #define REG_STARTEND 00004
  96.  = #define REG_TRACE 00400 // tracing of execution
  97.  = #define REG_LARGE 01000 // force large representation
  98.  = #define REG_BACKR 02000 // force use of backref code
  99.  *
  100.  * We put this here so we can exploit knowledge of the state representation
  101.  * when choosing which matcher to call.  Also, by this point the matchers
  102.  * have been prototyped.
  103.  */
  104. int /* 0 success, REG_NOMATCH failure */
  105. my_regexec(preg, str, nmatch, pmatch, eflags)
  106. const my_regex_t *preg;
  107. const char *str;
  108. size_t nmatch;
  109. my_regmatch_t pmatch[];
  110. int eflags;
  111. {
  112. register struct re_guts *g = preg->re_g;
  113. #ifdef REDEBUG
  114. # define GOODFLAGS(f) (f)
  115. #else
  116. # define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
  117. #endif
  118. if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
  119. return(REG_BADPAT);
  120. assert(!(g->iflags&BAD));
  121. if (g->iflags&BAD) /* backstop for no-debug case */
  122. return(REG_BADPAT);
  123. eflags = GOODFLAGS(eflags);
  124. if ((size_t) g->nstates <= CHAR_BIT*sizeof(states1) &&
  125.     !(eflags&REG_LARGE))
  126. return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
  127. else
  128. return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
  129. }