home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / src / find.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  22KB  |  780 lines

  1. /* find.c -- Searching and replacing
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4. This file is part of Jade.
  5.  
  6. Jade is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. Jade is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with Jade; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22. #include "regexp/regexp.h"
  23.  
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27.  
  28. _PR bool findnext(TX *, u_char *, POS *, bool);
  29. _PR bool findprev(TX *, u_char *, POS *, bool);
  30. _PR bool findstrnext(TX *, u_char *, POS *);
  31. _PR bool findstrprev(TX *, u_char *, POS *);
  32. _PR bool findcharnext(TX *, u_char, POS *);
  33. _PR bool findcharprev(TX *, u_char, POS *);
  34. _PR bool replaceit(TX *, u_char *, u_char *, POS *, bool);
  35. _PR bool replaceitstr(TX *, u_char *, u_char *, POS *);
  36. _PR bool mystrcmp(u_char *, u_char *);
  37. _PR bool mystricmp(u_char *, u_char *);
  38. _PR u_char *strrstrn(u_char *, u_char *, int);
  39. _PR u_char *strrchrn(u_char *, u_char, int);
  40. _PR void find_init(void);
  41.  
  42. POS LastFindStart, LastFindEnd;
  43.  
  44. _PR VALUE cmd_find_next_regexp(VALUE re, VALUE pos, VALUE tx, VALUE nocase_p);
  45. DEFUN("find-next-regexp", cmd_find_next_regexp, subr_find_next_regexp, (VALUE re, VALUE pos, VALUE tx, VALUE nocase_p), V_Subr4, DOC_find_next_regexp) /*
  46. ::doc:find_next_regexp::
  47. (find-next-regexp REGEXP [POS] [BUFFER] [IGNORE-CASE-P])
  48. Scans forwards from POS (or the cursor), in BUFFER, looking for a match
  49. with REGEXP. Returns the position of the next match or nil.
  50.  
  51. When IGNORE-CASE-P is non-nil the case of matched strings are ignored. Note
  52. that character classes are still case-significant.
  53. ::end:: */
  54. {
  55.     POS res;
  56.     DECLARE1(re, STRINGP);
  57.     if(POSP(pos))
  58.     res = VPOS(pos);
  59.     else
  60.     res = CurrVW->vw_CursorPos;
  61.     if(!BUFFERP(tx))
  62.     tx = CurrVW->vw_Tx;
  63.     checkpos(VTX(tx), &res);
  64.     if(findnext(VTX(tx), VSTR(re), &res, !NILP(nocase_p)))
  65.     return(newlpos(&res));
  66.     return(sym_nil);
  67. }
  68. _PR VALUE cmd_find_prev_regexp(VALUE re, VALUE pos, VALUE tx, VALUE nocase_p);
  69. DEFUN("find-prev-regexp", cmd_find_prev_regexp, subr_find_prev_regexp, (VALUE re, VALUE pos, VALUE tx, VALUE nocase_p), V_Subr4, DOC_find_prev_regexp) /*
  70. ::doc:find_prev_regexp::
  71. (find-prev-regexp REGEXP [POS] [BUFFER] [IGNORE-CASE-P])
  72. Scans backwards from POS (or the cursor), in BUFFER, looking for a match
  73. with REGEXP. Returns the position of the next match or nil.
  74.  
  75. When IGNORE-CASE-P is non-nil the case of matched strings are ignored. Note
  76. that character classes are still case-significant.
  77. ::end:: */
  78. {
  79.     POS res;
  80.     DECLARE1(re, STRINGP);
  81.     if(POSP(pos))
  82.     res = VPOS(pos);
  83.     else
  84.     res = CurrVW->vw_CursorPos;
  85.     if(!BUFFERP(tx))
  86.     tx = CurrVW->vw_Tx;
  87.     checkpos(VTX(tx), &res);
  88.     if(findprev(VTX(tx), VSTR(re), &res, !NILP(nocase_p)))
  89.     return(newlpos(&res));
  90.     return(sym_nil);
  91. }
  92. _PR VALUE cmd_find_next_string(VALUE str, VALUE pos, VALUE tx);
  93. DEFUN("find-next-string", cmd_find_next_string, subr_find_next_string, (VALUE str, VALUE pos, VALUE tx), V_Subr3, DOC_find_next_string) /*
  94. ::doc:find_next_string::
  95. (find-next-string STRING [POS] [BUFFER])
  96. Scans forwards from POS (or the cursor), in BUFFER, looking for a match
  97. with STRING. Returns the position of the next match or nil.
  98. ::end:: */
  99. {
  100.     POS res;
  101.     DECLARE1(str, STRINGP);
  102.     if(POSP(pos))
  103.     res = VPOS(pos);
  104.     else
  105.     res = CurrVW->vw_CursorPos;
  106.     if(!BUFFERP(tx))
  107.     tx = CurrVW->vw_Tx;
  108.     checkpos(VTX(tx), &res);
  109.     if(findstrnext(VTX(tx), VSTR(str), &res))
  110.     return(newlpos(&res));
  111.     return(sym_nil);
  112. }
  113. _PR VALUE cmd_find_prev_string(VALUE str, VALUE pos, VALUE tx);
  114. DEFUN("find-prev-string", cmd_find_prev_string, subr_find_prev_string, (VALUE str, VALUE pos, VALUE tx), V_Subr3, DOC_find_prev_string) /*
  115. ::doc:find_prev_string::
  116. (find-prev-string STRING [POS] [BUFFER])
  117. Scans backwards from POS (or the cursor), in BUFFER, looking for a match
  118. with STRING. Returns the position of the next match or nil.
  119. ::end:: */
  120. {
  121.     POS res;
  122.     DECLARE1(str, STRINGP);
  123.     if(POSP(pos))
  124.     res = VPOS(pos);
  125.     else
  126.     res = CurrVW->vw_CursorPos;
  127.     if(!BUFFERP(tx))
  128.     tx = CurrVW->vw_Tx;
  129.     checkpos(VTX(tx), &res);
  130.     if(findstrprev(VTX(tx), VSTR(str), &res))
  131.     return(newlpos(&res));
  132.     return(sym_nil);
  133. }
  134. _PR VALUE cmd_find_next_char(VALUE ch, VALUE pos, VALUE tx);
  135. DEFUN("find-next-char", cmd_find_next_char, subr_find_next_char, (VALUE ch, VALUE pos, VALUE tx), V_Subr3, DOC_find_next_char) /*
  136. ::doc:find_next_char::
  137. (find-next-char CHAR [POS] [BUFFER])
  138. Scans forwards from POS (or the cursor), in BUFFER, looking for a match
  139. with CHAR. Returns the position of the next match or nil.
  140. ::end:: */
  141. {
  142.     POS res;
  143.     DECLARE1(ch, CHARP);
  144.     if(POSP(pos))
  145.     res = VPOS(pos);
  146.     else
  147.     res = CurrVW->vw_CursorPos;
  148.     if(!BUFFERP(tx))
  149.     tx = CurrVW->vw_Tx;
  150.     checkpos(VTX(tx), &res);
  151.     if(findcharnext(VTX(tx), VCHAR(ch), &res))
  152.     return(newlpos(&res));
  153.     return(sym_nil);
  154. }
  155. _PR VALUE cmd_find_prev_char(VALUE ch, VALUE pos, VALUE tx);
  156. DEFUN("find-prev-char", cmd_find_prev_char, subr_find_prev_char, (VALUE ch, VALUE pos, VALUE tx), V_Subr3, DOC_find_prev_char) /*
  157. ::doc:find_prev_char::
  158. (find-prev-char CHAR [POS] [BUFFER])
  159. Scans backwards from POS (or the cursor), in BUFFER, looking for a match
  160. with CHAR. Returns the position of the next match or nil.
  161. ::end:: */
  162. {
  163.     POS res;
  164.     DECLARE1(ch, CHARP);
  165.     if(POSP(pos))
  166.     res = VPOS(pos);
  167.     else
  168.     res = CurrVW->vw_CursorPos;
  169.     if(!BUFFERP(tx))
  170.     tx = CurrVW->vw_Tx;
  171.     checkpos(VTX(tx), &res);
  172.     if(findcharprev(VTX(tx), VCHAR(ch), &res))
  173.     return(newlpos(&res));
  174.     return(sym_nil);
  175. }
  176.  
  177. _PR VALUE cmd_replace_regexp(VALUE re, VALUE tplt, VALUE pos, VALUE tx, VALUE nocase_p);
  178. DEFUN("replace-regexp", cmd_replace_regexp, subr_replace_regexp, (VALUE re, VALUE tplt, VALUE pos, VALUE tx, VALUE nocase_p), V_Subr5, DOC_replace_regexp) /*
  179. ::doc:replace_regexp::
  180. (replace-regexp REGEXP TEMPLATE [POS] [BUFFER] [IGNORE-CASE-P])
  181. If the text at POS or the cursor, matches REGEXP replace it with TEMPLATE,
  182. this is a string that can have the following escape characters,
  183.   \0, \&   whole string matched by REGEXP
  184.   \N       N'th parenthensized expression (1 <= N <= 9)
  185.  
  186. When IGNORE-CASE-P is non-nil the case of matched strings are ignored. Note
  187. that character classes are still case-significant.
  188. ::end:: */
  189. {
  190.     POS res;
  191.     DECLARE1(re, STRINGP);
  192.     DECLARE2(tplt, STRINGP);
  193.     if(POSP(pos))
  194.     res = VPOS(pos);
  195.     else
  196.     res = CurrVW->vw_CursorPos;
  197.     if(!BUFFERP(tx))
  198.     tx = CurrVW->vw_Tx;
  199.     checkpos(VTX(tx), &res);
  200.     if(!readonly(VTX(tx)) && replaceit(VTX(tx), VSTR(re), VSTR(tplt),
  201.                        &res, !NILP(nocase_p)))
  202.     return(newlpos(&res));
  203.     return(sym_nil);
  204. }
  205. _PR VALUE cmd_replace_string(VALUE orig, VALUE new, VALUE pos, VALUE tx);
  206. DEFUN("replace-string", cmd_replace_string, subr_replace_string, (VALUE orig, VALUE new, VALUE pos, VALUE tx), V_Subr4, DOC_replace_string) /*
  207. ::doc:replace_string::
  208. (replace-string ORIGINAL NEW [POS] [BUFFER])
  209. If the text at POS, or the cursor, matches ORIGINAL, replace it with the
  210. string NEW.
  211. ::end:: */
  212. {
  213.     POS res;
  214.     DECLARE1(orig, STRINGP);
  215.     DECLARE2(new, STRINGP);
  216.     if(POSP(pos))
  217.     res = VPOS(pos);
  218.     else
  219.     res = CurrVW->vw_CursorPos;
  220.     if(!BUFFERP(tx))
  221.     tx = CurrVW->vw_Tx;
  222.     checkpos(VTX(tx), &res);
  223.     if(!readonly(VTX(tx)) && replaceitstr(VTX(tx), VSTR(orig), VSTR(new), &res))
  224.     return(newlpos(&res));
  225.     return(sym_nil);
  226. }
  227.  
  228. _PR VALUE cmd_regexp_expand(VALUE re, VALUE match, VALUE tplt, VALUE nocase_p);
  229. DEFUN("regexp-expand", cmd_regexp_expand, subr_regexp_expand, (VALUE re, VALUE match, VALUE tplt, VALUE nocase_p), V_Subr4, DOC_regexp_expand) /*
  230. ::doc:regexp_expand::
  231. (regexp-expand REGEXP MATCHSTR TEMPLATE [IGNORE-CASE-P])
  232. If REGEXP matches MATCHSTR then return the string made by expanding the
  233. string