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.

139 lines
4.2 KiB

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