tin  2.4.4
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.4.4.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

search.c
Go to the documentation of this file.
1 /*
2  * Project : tin - a Usenet reader
3  * Module : search.c
4  * Author : I. Lea & R. Skrenta
5  * Created : 1991-04-01
6  * Updated : 2018-01-29
7  * Notes :
8  *
9  * Copyright (c) 1991-2020 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.com>
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution.
22  *
23  * 3. Neither the name of the copyright holder nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44 
45 
46 /*
47  * local prototypes
48  */
49 static char *get_search_pattern(t_bool *forward, t_bool repeat, const char *fwd_msg, const char *bwd_msg, char *def, int which_hist);
50 static int author_search(int i, char *searchbuf);
51 static int body_search(int i, char *searchbuf);
52 static int subject_search(int i, char *searchbuf);
53 static int search_group(t_bool forward, int current_art, char *searchbuff, int (*search_func) (int i, char *searchbuff));
54 
55 
56 /*
57  * Kludge to maintain some internal state for body search
58  */
59 int srch_lineno = -1;
60 static int total_cnt = 0, curr_cnt = 0;
61 
62 /*
63  * Used by article and body search - this saves passing around large numbers
64  * of parameters all the time
65  */
66 static int srch_offsets[6];
68 static struct regex_cache search_regex = { NULL, NULL };
69 
70 
71 /*
72  * Obtain the search pattern, save it in the default buffer.
73  * Return NULL if no pattern could be found
74  */
75 static char *
77  t_bool *forward,
78  t_bool repeat,
79  const char *fwd_msg,
80  const char *bwd_msg,
81  char *def,
82  int which_hist)
83 {
84  static char tmpbuf[LEN]; /* Hold the last pattern used */
85  static char last_pattern[LEN]; /* last search pattern used; for repeated search */
86  static t_bool last_forward;
87 
88  if (repeat) {
89  *forward = last_forward;
90  my_strncpy(def, last_pattern, LEN);
91  } else {
92  snprintf(tmpbuf, sizeof(tmpbuf), (*forward ? fwd_msg : bwd_msg), def);
93 
94  if (!prompt_string_default(tmpbuf, def, _(txt_no_search_string), which_hist))
95  return NULL;
96 
97  last_forward = *forward;
98  my_strncpy(last_pattern, def, LEN);
99 
100  /* HIST_BODY_SEARCH doesn't exist, hence last_search is set directly in search_body() */
101  if (which_hist == HIST_AUTHOR_SEARCH)
103  else
105  }
106 
108 
109  stow_cursor();
110 
111 #ifdef HAVE_UNICODE_NORMALIZATION
112  /* normalize search pattern */
113  if (IS_LOCAL_CHARSET("UTF-8")) {
114  char *tmp;
115 
116  tmp = normalize(def);
117  my_strncpy(def, tmp, LEN);
118  free(tmp);
119  }
120 #endif /* HAVE_UNICODE_NORMALIZATION */
121 
122  if (tinrc.wildcard) { /* ie, not wildmat() */
123  strcpy(def, quote_wild_whitespace(def));
124  return def;
125  }
126 
127  /*
128  * A gross hack to simulate substrings with wildmat()
129  */
130 /* TODO: somehow use REGEX_FMT here? */
131  snprintf(tmpbuf, sizeof(tmpbuf), "*%s*", def);
132  return tmpbuf;
133 }
134 
135 
136 /*
137  * called by config.c
138  */
139 enum option_enum
141  t_bool forward,
142  t_bool repeat,
143  enum option_enum current,
144  enum option_enum last)
145 {
146  char *pattern, *buf;
147  enum option_enum n = current;
148  enum option_enum result = current;
149 
151  return result;
152 
153  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
154  return result;
155 
156  do {
157  if (n == 0 && !forward)
158  n = last;
159  else {
160  if (n == last && forward)
161  n = 0;
162  else
163  n += (forward ? 1 : -1);
164  }
165  /* search only visible options */
166  if (option_is_visible(n)) {
167 #ifdef HAVE_UNICODE_NORMALIZATION
168  if (IS_LOCAL_CHARSET("UTF-8"))
169  buf = normalize(_(option_table[n].txt->opt));
170  else
171 #endif /* HAVE_UNICODE_NORMALIZATION */
172  buf = my_strdup(_(option_table[n].txt->opt));
173 
174  if (match_regex(buf, pattern, &search_regex, TRUE)) {
175  result = n;
176  free(buf);
177  break;
178  }
179  free(buf);
180  }
181  } while (n != current);
182 
183  clear_message();
184  if (tinrc.wildcard) {
187  }
188  return result;
189 }
190 
191 
192 /*
193  * called by save.c (search for attachment) and page.c (search for URL)
194  */
195 int
197  t_bool forward,
198  t_bool repeat,
199  int current,
200  int last,
201  int level)
202 {
203  char *pattern;
204  char buf[BUFSIZ];
205  const char *name, *charset;
206  int n = current;
207  int result = current;
208  t_bool found = FALSE;
209  t_part *part;
210  t_url *urlptr;
211 
213  return result;
214 
215  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
216  return result;
217 
218  do {
219  if (n == 0 && !forward)
220  n = last;
221  else {
222  if (n == last && forward)
223  n = 0;
224  else
225  n += (forward ? 1 : -1);
226  }
227  switch (level) {
228  case ATTACHMENT_LEVEL:
229  part = get_part(n);
230  if (!(name = get_filename(part->params))) {
231  if (!(name = part->description))
233  }
234  charset = get_param(part->params, "charset");
235  snprintf(buf, sizeof(buf), "%s %s/%s %s, %s", name, content_types[part->type], part->subtype, content_encodings[part->encoding], charset ? charset : "");
236  break;
237 
238  case URL_LEVEL:
239  urlptr = find_url(n);
240  snprintf(buf, sizeof(buf), "%s", urlptr->url);
241  break;
242 
243  default:
244  buf[0] = '\0';
245  break;
246  }
247  if (match_regex(buf, pattern, &search_regex, TRUE)) {
248  result = n;
249  found = TRUE;
250  break;
251  }
252  } while (n != current);
253 
254  clear_message();
255  if (tinrc.wildcard) {
258  }
259  if (!found)
261 
262  return result;
263 }
264 
265 
266 /*
267  * Search active[] looking for a groupname
268  * Called by select.c
269  * Return index into active of matching groupname or -1
270  */
271 int
273  t_bool forward,
274  t_bool repeat)
275 {
276  char *buf;
277  char *ptr;
278  char buf2[LEN];
279  int i;
280 
281  if (!selmenu.max) {
283  return -1;
284  }
285 
287  return -1;
288 
290  return -1;
291 
292  i = selmenu.curr;
293 
294  do {
295  if (forward) {
296  if (++i >= selmenu.max)
297  i = 0;
298  } else {
299  if (--i < 0)
300  i = selmenu.max - 1;
301  }
302 
303  /*
304  * Get the group name & description into buf2
305  */
306  if (show_description && active[my_group[i]].description) {
307  snprintf(buf2, sizeof(buf2), "%s %s", active[my_group[i]].name, active[my_group[i]].description);
308  ptr = buf2;
309  } else
310  ptr = active[my_group[i]].name;
311 
312  if (match_regex(ptr, buf, &search_regex, TRUE)) {
313  if (tinrc.wildcard) {
316  }
317  return i;
318  }
319  } while (i != selmenu.curr);
320 
321  if (tinrc.wildcard) {
324  }
326  return -1;
327 }
328 
329 
330 /*
331  * Scan the body of an arts[i] for searchbuf
332  * used only by search_body()
333  * Returns: 1 String found
334  * 0 Not found
335  * -1 User aborted search
336  */
337 static int
339  int i,
340  char *searchbuf)
341 {
342  static char msg[LEN]; /* show_progress needs a constant message buffer */
343  char *line, *tmp;
344  t_openartinfo artinfo;
345 
346  switch (art_open(TRUE, &arts[i], curr_group, &artinfo, FALSE, NULL)) {
347  case ART_ABORT: /* User 'q'uit */
348  art_close(&artinfo);
349  return -1;
350 
351  case ART_UNAVAILABLE: /* Treat as string not present */
352  art_close(&artinfo);
354  return 0;
355  }
356 
357  /*
358  * Skip the header - is this right ?
359  */
360  for (i = 0; artinfo.cookl[i].flags & C_HEADER; ++i)
361  ;
362  if (fseek(artinfo.cooked, artinfo.cookl[i].offset, SEEK_SET) != 0) {
363  art_close(&artinfo);
364  return -1;
365  }
366 
367  /*
368  * Now search the body
369  */
370  snprintf(msg, sizeof(msg), _(txt_searching_body), ++curr_cnt, total_cnt);
372  while ((tmp = tin_fgets(artinfo.cooked, FALSE)) != NULL) {
373 #ifdef HAVE_UNICODE_NORMALIZATION
374  if (IS_LOCAL_CHARSET("UTF-8"))
375  line = normalize(tmp);
376  else
377 #endif /* HAVE_UNICODE_NORMALIZATION */
378  line = my_strdup(tmp);
379 
380  if (tinrc.wildcard) {
382  srch_lineno = i;
383  art_close(&pgart); /* Switch the pager over to matched art */
384  pgart = artinfo;
385 #ifdef DEBUG
386  if (debug & DEBUG_MISC)
387  fprintf(stderr, "art_switch(%p = %p)\n", (void *) &pgart, (void *) &artinfo);
388 #endif /* DEBUG */
389  free(line);
390 
391  return 1;
392  }
393  } else {
394  if (wildmatpos(line, searchbuf, TRUE, srch_offsets, srch_offsets_size)) {
395  srch_lineno = i;
396  art_close(&pgart); /* Switch the pager over to matched art */
397  pgart = artinfo;
398  free(line);
399  return 1;
400  }
401  }
402  i++;
403  free(line);
404  }
405 
406  if (tin_errno != 0) { /* User abort */
407  art_close(&artinfo);
408  return -1;
409  }
410 
411  art_close(&artinfo);
412 /* info_message(_(txt_no_match)); */
413  return 0;
414 }
415 
416 
417 /*
418  * Match searchbuff against the From: information in arts[i]
419  * 1 = found, 0 = not found
420  */
421 static int
423  int i,
424  char *searchbuf)
425 {
426  char *buf, *tmp;
427 
428  if (arts[i].name == NULL)
429  tmp = my_strdup(arts[i].from);
430  else {
431  size_t len = strlen(arts[i].from) + strlen(arts[i].name) + 4;
432 
433  tmp = my_malloc(len);
434  snprintf(tmp, len, "%s <%s>", arts[i].name, arts[i].from);
435  }
436 
437 #ifdef HAVE_UNICODE_NORMALIZATION
438  if (IS_LOCAL_CHARSET("UTF-8")) {
439  buf = normalize(tmp);
440  free(tmp);
441  } else
442 #endif /* HAVE_UNICODE_NORMALIZATION */
443  buf = tmp;
444 
445  if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
446  free(buf);
447  return 1;
448  }
449 
450  free(buf);
451  return 0;
452 }
453 
454 
455 /*
456  * Match searchbuff against the Subject: information in arts[i]
457  * 1 = found, 0 = not found
458  */
459 static int
461  int i,
462  char *searchbuf)
463 {
464  char *buf;
465 
466 #ifdef HAVE_UNICODE_NORMALIZATION
467  if (IS_LOCAL_CHARSET("UTF-8"))
468  buf = normalize(arts[i].subject);
469  else
470 #endif /* HAVE_UNICODE_NORMALIZATION */
471  buf = my_strdup(arts[i].subject);
472 
473  if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
474  free(buf);
475  return 1;
476  }
477 
478  free(buf);
479  return 0;
480 }
481 
482 
483 /*
484  * Returns index into arts[] of matching article or -1
485  */
486 static int
488  t_bool forward,
489  int current_art,
490  char *searchbuff,
491  int (*search_func) (int i, char *searchbuff))
492 {
493  int i, ret;
494 
495  if (grpmenu.curr < 0) {
497  return -1;
498  }
499 
500  /*
501  * precompile if we're using full regex
502  */
503  if (tinrc.wildcard && !(compile_regex(searchbuff, &search_regex, PCRE_CASELESS)))
504  return -1;
505 
506  i = current_art;
507 
508  do {
509  if (forward) {
510  if ((i = next_response(i)) < 0)
511  i = base[0];
512  } else {
513  if ((i = prev_response(i)) < 0)
515  }
516 
517  /* Only search displayed articles */
519  continue;
520 
521  ret = search_func(i, searchbuff);
522  if (tinrc.wildcard && (ret == 1 || ret == -1)) {
523  /* we will exit soon, clean up */
526  }
527  switch (ret) {
528  case 1: /* Found */
529  clear_message();
530  return i;
531 
532  case -1: /* User abort */
533  return -1;
534  }
535  } while (i != current_art);
536 
537  if (tinrc.wildcard) {
540  }
542  return -1;
543 }
544 
545 
546 /*
547  * Generic entry point to search for fields in arts[]
548  * Returns index into arts[] of matching article or -1
549  */
550 int
552  t_function func,
553  int current_art,
554  t_bool repeat)
555 {
556  char *buf = NULL;
557  int (*search_func) (int i, char *searchbuff) = author_search;
558  t_bool forward;
559 
561  forward = TRUE;
562  else
563  forward = FALSE;
564 
565  switch (func) {
569  return -1;
570  search_func = subject_search;
571  break;
572 
575  default:
577  return -1;
578  search_func = author_search;
579  break;
580  }
581  return (search_group(forward, current_art, buf, search_func));
582 }
583 
584 
585 /*
586  * page.c (search current article body)
587  * Return line number that matches or -1
588  * If using regex's return vector of character offsets
589  */
590 int
592  t_bool forward,
593  t_bool repeat,
594  int start_line,
595  int lines,
596  t_lineinfo *line,
598  FILE *fp)
599 {
600  char *pattern, *ptr, *tmp;
601  int i = start_line;
602  int tmp_srch_offsets[2] = {0, 0};
603  t_bool wrap = FALSE;
604  t_bool match = FALSE;
605 
607  return 0;
608 
609  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
610  return -1;
611 
612  srch_lineno = -1;
613 
614  forever {
615  if (i == start_line && wrap)
616  break;
617 
618  /*
619  * TODO: consider not searching some line types?
620  * 'B'ody search skips hdrs, '/' inside article does not.
621  */
622  if (fseek(fp, line[i].offset, SEEK_SET) != 0)
623  return -1;
624 
625  /* Don't search beyond ^L if hiding is enabled */
626  if ((line[i].flags & C_CTRLL) && i > reveal_ctrl_l_lines)
627  break;
628 
629  if ((tmp = tin_fgets(fp, FALSE)) == NULL)
630  return -1;
631  if (!forward && srch_offsets[0] >= 0) {
632  tmp[srch_offsets[0]] = '\0'; /* ignore anything on this line after the last match */
633  srch_offsets[1] = 0; /* start backwards search at the beginning of the line */
634  }
635 
636 #ifdef HAVE_UNICODE_NORMALIZATION
637  if (IS_LOCAL_CHARSET("UTF-8"))
638  ptr = normalize(tmp);
639  else
640 #endif /* HAVE_UNICODE_NORMALIZATION */
641  ptr = my_strdup(tmp);
642 
643  if (tinrc.wildcard) {
645  match = TRUE;
646  if (forward)
647  break;
648  else {
649  tmp_srch_offsets[0] = srch_offsets[0];
650  tmp_srch_offsets[1] = srch_offsets[1];
651  }
652  }
653  if (match) {
654  if (!forward) {
655  srch_offsets[0] = tmp_srch_offsets[0];
656  srch_offsets[1] = tmp_srch_offsets[1];
657  }
658  srch_lineno = i;
661  free(ptr);
662  return i;
663  }
664  } else {
665  if (wildmatpos(ptr, pattern, TRUE, srch_offsets, srch_offsets_size)) {
666  srch_lineno = i;
667  free(ptr);
668  return i;
669  }
670  }
671  free(ptr);
672 
673  if (forward) {
674  if (i >= lines - 1) {
675  i = 0;
676  wrap = TRUE;
677  } else
678  i++;
679  } else {
680  if (i <= 0) {
681  i = lines - 1;
682  wrap = TRUE;
683  } else
684  i--;
685  }
686 
687  /* search at the beginning of the line */
688  srch_offsets[1] = 0;
689  }
690 
692  if (tinrc.wildcard) {
695  }
696  return -1;
697 }
698 
699 
700 /*
701  * Search the bodies of all the articles in current group
702  * Start the search at the current article
703  * A match will replace the context of the article open in the pager
704  * Save the line # that matched (and the start/end vector for regex)
705  * for later retrieval
706  * Return index in arts[] of article that matched or -1
707  */
708 int
710  struct t_group *group,
711  int current_art,
712  t_bool repeat)
713 {
714  char *buf;
715  int i;
716  t_bool forward_fake = TRUE;
717 
718  if (!(buf = get_search_pattern(
719  &forward_fake, /* we pass a dummy var since body search has no `forward' */
720  repeat,
725  ))) return -1;
726 
727  last_search = GLOBAL_SEARCH_BODY; /* store last search type for repeated search */
728  total_cnt = curr_cnt = 0; /* Reset global counter of articles done */
729 
730  /*
731  * Count up the articles to be processed for the progress meter
732  */
733  if (group->attribute->show_only_unread_arts) {
734  for (i = 0; i < grpmenu.max; i++)
735  total_cnt += new_responses(i);
736  } else {
737  for_each_art(i) {
738  if (!IGNORE_ART(i))
739  total_cnt++;
740  }
741  }
742 
743  srch_lineno = -1;
744  return search_group(1, current_art, buf, body_search);
745 }
746 
747 
748 /*
749  * Return the saved line & start/end info from previous successful
750  * regex search
751  */
752 int
754  int *start,
755  int *end)
756 {
757  int i = srch_lineno;
758 
759  *start = srch_offsets[0];
760  *end = srch_offsets[1];
761  srch_lineno = -1; /* We can only retrieve this info once */
762  return i;
763 }
764 
765 
766 /*
767  * Reset offsets so that the next search starts at the beginning of the line.
768  * This function is needed to access srch_offsets from within other modules.
769  */
770 void
772  void)
773 {
774  srch_offsets[0] = srch_offsets[1] = 0;
775 }
name
const char * name
Definition: signal.c:117
t_config::wildcard
int wildcard
Definition: tinrc.h:155
txt_searching
constext txt_searching[]
Definition: lang.c:834
get_filename
const char * get_filename(t_param *ptr)
Definition: cook.c:353
t_config::default_search_config
char default_search_config[LEN]
Definition: tinrc.h:88
search_article
int search_article(t_bool forward, t_bool repeat, int start_line, int lines, t_lineinfo *line, int reveal_ctrl_l_lines, FILE *fp)
Definition: search.c:591
DEBUG_MISC
#define DEBUG_MISC
Definition: debug.h:54
_
#define _(Text)
Definition: tin.h:94
HIST_GROUP_SEARCH
@ HIST_GROUP_SEARCH
Definition: extern.h:1542
author_search
static int author_search(int i, char *searchbuf)
Definition: search.c:422
search_regex
static struct regex_cache search_regex
Definition: search.c:68
GLOBAL_SEARCH_AUTHOR_FORWARD
@ GLOBAL_SEARCH_AUTHOR_FORWARD
Definition: keymap.h:218
my_strdup
char * my_strdup(const char *str)
Definition: string.c:133
t_group
Definition: tin.h:1772
reveal_ctrl_l_lines
static int reveal_ctrl_l_lines
Definition: page.c:82
pcre_exec
int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
Definition: pcre_exec.c:3690
txt_attachment_no_name
constext txt_attachment_no_name[]
Definition: lang.c:86
GLOBAL_SEARCH_SUBJECT_FORWARD
@ GLOBAL_SEARCH_SUBJECT_FORWARD
Definition: keymap.h:220
find_url
t_url * find_url(int n)
Definition: page.c:2542
content_encodings
constext * content_encodings[]
Definition: lang.c:1448
base
t_artnum * base
Definition: memory.c:65
openartinfo
Definition: rfc2046.h:183
last_search
t_function last_search
Definition: init.c:117
lineinfo::flags
int flags
Definition: rfc2046.h:176
body_search
static int body_search(int i, char *searchbuf)
Definition: search.c:338
grpmenu
t_menu grpmenu
Definition: group.c:83
show_description
t_bool show_description
Definition: init.c:152
tinrc
struct t_config tinrc
Definition: init.c:191
wait_message
void wait_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:133
FreeAndNull
#define FreeAndNull(p)
Definition: tin.h:2204
curr_group
struct t_group * curr_group
Definition: group.c:55
get_search_pattern
static char * get_search_pattern(t_bool *forward, t_bool repeat, const char *fwd_msg, const char *bwd_msg, char *def, int which_hist)
Definition: search.c:76
ART_UNAVAILABLE
#define ART_UNAVAILABLE
Definition: tin.h:1323
lineinfo
Definition: rfc2046.h:173
regex_cache::extra
pcre_extra * extra
Definition: tin.h:1919
txt_author_search_forwards
constext txt_author_search_forwards[]
Definition: lang.c:105
txt_search_body
constext txt_search_body[]
Definition: lang.c:832
URL_LEVEL
#define URL_LEVEL
Definition: tin.h:1110
end
static char * end
Definition: plp_snprintf.c:205
t_menu::max
int max
Definition: tin.h:2007
info_message
void info_message(const char *fmt,...)
Definition: screen.c:102
get_param
const char * get_param(t_param *list, const char *name)
Definition: rfc2046.c:568
tin.h
urllist
Definition: tin.h:2062
wildmatpos
t_bool wildmatpos(const char *text, char *p, t_bool icase, int *srch_offsets, int srch_offsets_size)
Definition: wildmat.c:164
num_of_responses
int num_of_responses(int n)
Definition: thread.c:1054
txt_search_backwards
constext txt_search_backwards[]
Definition: lang.c:831
show_progress
void show_progress(const char *txt, t_artnum count, t_artnum total)
Definition: screen.c:477
prev_response
int prev_response(int n)
Definition: thread.c:1247
openartinfo::cooked
FILE * cooked
Definition: rfc2046.h:189
C_HEADER
#define C_HEADER
Definition: rfc2046.h:152
option_table
struct t_option option_table[]
srch_lineno
int srch_lineno
Definition: search.c:59
prompt_string_default
char * prompt_string_default(const char *prompt, char *def, const char *failtext, int history)
Definition: prompt.c:558
forever
#define forever
Definition: tin.h:810
active
struct t_group * active
Definition: memory.c:66
tin_fgets
char * tin_fgets(FILE *fp, t_bool header)
Definition: read.c:320
srch_offsets_size
static int srch_offsets_size
Definition: search.c:67
find_response
int find_response(int i, int n)
Definition: thread.c:1268
part
Definition: rfc2046.h:92
txt_no_groups
constext txt_no_groups[]
Definition: lang.c:673
content_types
constext * content_types[]
Definition: lang.c:1453
get_part
t_part * get_part(int n)
Definition: save.c:1990
my_strncpy
void my_strncpy(char *p, const char *q, size_t n)
Definition: string.c:190
ART_ABORT
#define ART_ABORT
Definition: tin.h:1335
art_open
int art_open(t_bool wrap_lines, struct t_article *art, struct t_group *group, t_openartinfo *artinfo, t_bool show_progress_meter, const char *pmesg)
Definition: rfc2046.c:1547
C_CTRLL
#define C_CTRLL
Definition: rfc2046.h:166
t_config::default_search_author
char default_search_author[HEADER_LEN]
Definition: tinrc.h:87
reset_srch_offsets
void reset_srch_offsets(void)
Definition: search.c:771
generic_search
int generic_search(t_bool forward, t_bool repeat, int current, int last, int level)
Definition: search.c:196
part::description
char * description
Definition: rfc2046.h:101
search_active
int search_active(t_bool forward, t_bool repeat)
Definition: search.c:272
buf
static char buf[16]
Definition: langinfo.c:50
t_config::default_search_subject
char default_search_subject[LEN]
Definition: tinrc.h:90
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: tin.h:2201
openartinfo::cookl
t_lineinfo * cookl
Definition: rfc2046.h:191
t_attribute::show_only_unread_arts
unsigned show_only_unread_arts
Definition: tin.h:1627
offset
static int offset
Definition: read.c:62
PCRE_CASELESS
#define PCRE_CASELESS
Definition: pcre.h:98
stow_cursor
void stow_cursor(void)
Definition: screen.c:59
ATTACHMENT_LEVEL
#define ATTACHMENT_LEVEL
Definition: tin.h:1109
GLOBAL_SEARCH_SUBJECT_BACKWARD
@ GLOBAL_SEARCH_SUBJECT_BACKWARD
Definition: keymap.h:219
LEN
#define LEN
Definition: tin.h:854
t_article::status
unsigned int status
Definition: tin.h:1529
GLOBAL_SEARCH_AUTHOR_BACKWARD
@ GLOBAL_SEARCH_AUTHOR_BACKWARD
Definition: keymap.h:217
t_function
enum defined_functions t_function
Definition: keymap.h:373
subject_search
static int subject_search(int i, char *searchbuf)
Definition: search.c:460
part::type
unsigned type
Definition: rfc2046.h:94
t_config::default_search_group
char default_search_group[HEADER_LEN]
Definition: tinrc.h:89
new_responses
int new_responses(int thread)
Definition: thread.c:975
HIST_AUTHOR_SEARCH
@ HIST_AUTHOR_SEARCH
Definition: extern.h:1540
compile_regex
t_bool compile_regex(const char *regex, struct regex_cache *cache, int options)
Definition: regex.c:111
regex_cache::re
pcre * re
Definition: tin.h:1918
SEEK_SET
#define SEEK_SET
Definition: tin.h:2441
curr_cnt
static int curr_cnt
Definition: search.c:60
HIST_CONFIG_SEARCH
@ HIST_CONFIG_SEARCH
Definition: extern.h:1555
HIST_SUBJECT_SEARCH
@ HIST_SUBJECT_SEARCH
Definition: extern.h:1554
IGNORE_ART
#define IGNORE_ART(i)
Definition: tin.h:1018
PCRE_ERROR_NOMATCH
#define PCRE_ERROR_NOMATCH
Definition: pcre.h:125
match
match
Definition: save.c:1378
t_menu::curr
int curr
Definition: tin.h:2006
t_group::name
char * name
Definition: tin.h:1773
search_body
int search_body(struct t_group *group, int current_art, t_bool repeat)
Definition: search.c:709
txt_no_search_string
constext txt_no_search_string[]
Definition: lang.c:688
srch_offsets
static int srch_offsets[6]
Definition: search.c:66
FALSE
#define FALSE
Definition: bool.h:70
debug
unsigned short debug
Definition: debug.c:51
txt_no_match
constext txt_no_match[]
Definition: lang.c:678
regex_cache
Definition: tin.h:1917
txt_author_search_backwards
constext txt_author_search_backwards[]
Definition: lang.c:104
ART_UNREAD
#define ART_UNREAD
Definition: tin.h:1321
snprintf
#define snprintf
Definition: tin.h:2417
next_response
int next_response(int n)
Definition: thread.c:1206
my_group
int * my_group
Definition: memory.c:64
t_config::default_search_art
char default_search_art[LEN]
Definition: tinrc.h:86
search
int search(t_function func, int current_art, t_bool repeat)
Definition: search.c:551
t_group::attribute
struct t_attribute * attribute
Definition: tin.h:1790
art_close
void art_close(t_openartinfo *artinfo)
Definition: rfc2046.c:1604
get_search_vectors
int get_search_vectors(int *start, int *end)
Definition: search.c:753
selmenu
t_menu selmenu
Definition: select.c:85
IS_LOCAL_CHARSET
#define IS_LOCAL_CHARSET(c)
Definition: tin.h:776
txt_searching_body
constext txt_searching_body[]
Definition: lang.c:835
option_is_visible
t_bool option_is_visible(enum option_enum option)
Definition: options_menu.c:187
t_bool
unsigned t_bool
Definition: bool.h:77
match_regex
t_bool match_regex(const char *string, char *pattern, struct regex_cache *cache, t_bool icase)
Definition: regex.c:59
TRUE
#define TRUE
Definition: bool.h:74
for_each_art
#define for_each_art(x)
Definition: tin.h:2211
total_cnt
static int total_cnt
Definition: search.c:60
part::params
t_param * params
Definition: rfc2046.h:102
tin_errno
int tin_errno
Definition: read.c:59
urllist::url
char * url
Definition: tin.h:2063
arts
struct t_article * arts
Definition: memory.c:69
GLOBAL_SEARCH_BODY
@ GLOBAL_SEARCH_BODY
Definition: keymap.h:215
part::encoding
unsigned encoding
Definition: rfc2046.h:95
HIST_ART_SEARCH
@ HIST_ART_SEARCH
Definition: extern.h:1539
quote_wild_whitespace
char * quote_wild_whitespace(char *str)
Definition: misc.c:2340
pgart
t_openartinfo pgart
Definition: page.c:63
lineinfo::offset
long offset
Definition: rfc2046.h:175
clear_message
void clear_message(void)
Definition: screen.c:243
txt_no_arts
constext txt_no_arts[]
Definition: lang.c:667
txt_search_forwards
constext txt_search_forwards[]
Definition: lang.c:833
part::subtype
char * subtype
Definition: rfc2046.h:100
search_config
enum option_enum search_config(t_bool forward, t_bool repeat, enum option_enum current, enum option_enum last)
Definition: search.c:140
my_malloc
#define my_malloc(size)
Definition: tin.h:2196
search_group
static int search_group(t_bool forward, int current_art, char *searchbuff, int(*search_func)(int i, char *searchbuff))
Definition: search.c:487