search.sl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % Search.SL - Search utilities
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 23 August 1982
  8. %
  9. % Adapted from Will Galway's EMODE
  10. %
  11. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  12. % These routines to implement minimal string searches for EMODE. Searches
  13. % are non-incremental, limited to single line patterns, and always ignore
  14. % case.
  15. (CompileTime (load objects fast-strings fast-int))
  16. (fluid '(last-search-string))
  17. (setf last-search-string NIL)
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. (de forward-string-search ()
  20. % Invoked from keyboard, search forward from point for string, leave
  21. % "point" unchanged if not found.
  22. (let ((strng (prompt-for-string "Forward search: " last-search-string)))
  23. (setf last-search-string strng)
  24. (if (buffer-search strng 1)
  25. (for (from i 0 (string-upper-bound strng))
  26. (do (move-forward))
  27. )
  28. % else
  29. (write-prompt "Search failed.")
  30. (Ding)
  31. )))
  32. (de reverse-string-search ()
  33. % Invoked from keyboard, search backwards from point for string, leave
  34. % "point unchanged if not found.
  35. (let ((strng (prompt-for-string "Reverse search: " last-search-string)))
  36. (setf last-search-string strng)
  37. (move-backward)
  38. (if (not (buffer-search strng -1))
  39. (progn (move-forward) (write-prompt "Search failed.") (Ding)))
  40. ))
  41. (de buffer-search (pattern dir)
  42. % Search in buffer for the specified pattern. Dir should be +1 for forward,
  43. % -1 for backward. If the pattern is found, the buffer cursor will be set to
  44. % the beginning of the matching string and T will be returned. Otherwise,
  45. % the buffer cursor will remain unchanged and NIL will be returned.
  46. (setf pattern (string-upcase pattern))
  47. (if (> dir 0)
  48. (forward-search pattern)
  49. (reverse-search pattern)
  50. ))
  51. (de forward-search (pattern)
  52. % Search forward in the current buffer for the specified pattern.
  53. % If the pattern is found, the buffer cursor will be set to
  54. % the beginning of the matching string and T will be returned. Otherwise,
  55. % the buffer cursor will remain unchanged and NIL will be returned.
  56. (let ((line-pos (current-line-pos))
  57. (char-pos (current-char-pos))
  58. (limit (current-buffer-size))
  59. found-pos
  60. )
  61. (while
  62. (and (< line-pos limit)
  63. (not (setf found-pos
  64. (forward-search-on-line line-pos char-pos pattern)))
  65. )
  66. (setf line-pos (+ line-pos 1))
  67. (setf char-pos NIL)
  68. )
  69. (if found-pos
  70. (progn (current-buffer-goto line-pos found-pos) T)))
  71. ))
  72. (de forward-search-on-line (line-pos char-pos pattern)
  73. % Search on the current line for the specified string. If CHAR-POS is
  74. % non-NIL, then begin at that location, otherwise begin at the beginning of
  75. % the line. We look to see if the string lies to the right of the current
  76. % search location. If we find it, we return the CHAR-POS of the first
  77. % matching character. Otherwise, we return NIL.
  78. (let* ((line (current-buffer-fetch line-pos))
  79. (pattern-length (string-length pattern))
  80. (limit (- (string-length line) pattern-length))
  81. )
  82. (if (null char-pos) (setf char-pos 0))
  83. (while (<= char-pos limit)
  84. (if (pattern-matches-in-line pattern line char-pos)
  85. (exit char-pos)
  86. )
  87. (setf char-pos (+ char-pos 1))
  88. )))
  89. (de reverse-search (pattern)
  90. % Search backward in the current buffer for the specified pattern.
  91. % If the pattern is found, the buffer cursor will be set to
  92. % the beginning of the matching string and T will be returned. Otherwise,
  93. % the buffer cursor will remain unchanged and NIL will be returned.
  94. (let ((line-pos (current-line-pos))
  95. (char-pos (current-char-pos))
  96. found-pos
  97. )
  98. (while
  99. (and (>= line-pos 0)
  100. (not (setf found-pos
  101. (reverse-search-on-line line-pos char-pos pattern)))
  102. )
  103. (setf line-pos (- line-pos 1))
  104. (setf char-pos NIL)
  105. )
  106. (if found-pos
  107. (progn (current-buffer-goto line-pos found-pos) T)))
  108. ))
  109. (de reverse-search-on-line (line-pos char-pos pattern)
  110. % Search on the current line for the specified string. If CHAR-POS is
  111. % non-NIL, then begin at that location, otherwise begin at the end of
  112. % the line. We look to see if the string lies to the right of the current
  113. % search location. If we find it, we return the CHAR-POS of the first
  114. % matching character. Otherwise, we return NIL.
  115. (let* ((line (current-buffer-fetch line-pos))
  116. (pattern-length (string-length pattern))
  117. (limit (- (string-length line) pattern-length))
  118. )
  119. (if (or (null char-pos) (> char-pos limit))
  120. (setf char-pos limit))
  121. (while (>= char-pos 0)
  122. (if (pattern-matches-in-line pattern line char-pos)
  123. (exit char-pos)
  124. )
  125. (setf char-pos (- char-pos 1))
  126. )))
  127. (de pattern-matches-in-line (pattern line pos)
  128. % Return T if PATTERN occurs as substring of LINE, starting at POS.
  129. % Ignore case differences. No bounds checking is performed on LINE.
  130. (let ((i 0) (patlimit (string-upper-bound pattern)))
  131. (while (and (<= i patlimit)
  132. (= (string-fetch pattern i)
  133. (char-upcase (string-fetch line (+ i pos))))
  134. )
  135. (setf i (+ i 1))
  136. )
  137. (> i patlimit) % T if all chars matched, NIL otherwise
  138. ))