Team Fortress 2 Source Code as on 22/4/2020
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.

112 lines
2.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. /*
  9. *
  10. * Copyright (c) 1998-9
  11. * Dr John Maddock
  12. *
  13. * Permission to use, copy, modify, distribute and sell this software
  14. * and its documentation for any purpose is hereby granted without fee,
  15. * provided that the above copyright notice appear in all copies and
  16. * that both that copyright notice and this permission notice appear
  17. * in supporting documentation. Dr John Maddock makes no representations
  18. * about the suitability of this software for any purpose.
  19. * It is provided "as is" without express or implied warranty.
  20. *
  21. */
  22. /*
  23. * FILE re_kmp.h
  24. * VERSION 2.12
  25. * Knuth-Morris-Pratt search.
  26. */
  27. #ifndef __RE_KMP_H
  28. #define __RE_KMP_H
  29. #ifdef JM_CFG_H
  30. #include <jm/jm_cfg.h>
  31. #endif
  32. JM_NAMESPACE(__JM)
  33. template <class charT>
  34. struct kmp_info
  35. {
  36. unsigned int size;
  37. unsigned int len;
  38. const charT* pstr;
  39. int kmp_next[1];
  40. };
  41. template <class charT, class Allocator>
  42. void kmp_free(kmp_info<charT>* pinfo, Allocator a)
  43. {
  44. typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
  45. atype(a).deallocate((char*)pinfo, pinfo->size);
  46. }
  47. template <class iterator, class charT, class Trans, class Allocator>
  48. kmp_info<charT>* kmp_compile(iterator first, iterator last, charT, Trans translate, Allocator a
  49. #ifdef RE_LOCALE_CPP
  50. , const __JM_STD::locale& l
  51. #endif
  52. )
  53. {
  54. typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
  55. int i, j, m;
  56. i = 0;
  57. m = 0;
  58. JM_DISTANCE(first, last, m);
  59. ++m;
  60. unsigned int size = sizeof(kmp_info<charT>) + sizeof(int)*m + sizeof(charT)*m;
  61. --m;
  62. //
  63. // allocate struct and fill it in:
  64. //
  65. kmp_info<charT>* pinfo = (kmp_info<charT>*)atype(a).allocate(size);
  66. pinfo->size = size;
  67. pinfo->len = m;
  68. charT* p = (charT*)((char*)pinfo + sizeof(kmp_info<charT>) + sizeof(int)*(m+1));
  69. pinfo->pstr = p;
  70. while(first != last)
  71. {
  72. *p = translate(*first MAYBE_PASS_LOCALE(l));
  73. ++first;
  74. ++p;
  75. }
  76. *p = 0;
  77. //
  78. // finally do regular kmp compile:
  79. //
  80. j = pinfo->kmp_next[0] = -1;
  81. while (i < m)
  82. {
  83. while ((j > -1) && (pinfo->pstr[i] != pinfo->pstr[j]))
  84. j = pinfo->kmp_next[j];
  85. ++i;
  86. ++j;
  87. if (pinfo->pstr[i] == pinfo->pstr[j])
  88. pinfo->kmp_next[i] = pinfo->kmp_next[j];
  89. else
  90. pinfo->kmp_next[i] = j;
  91. }
  92. return pinfo;
  93. }
  94. JM_END_NAMESPACE // namespace regex
  95. #endif // __RE_KMP_H