NeoMutt  2021-10-29-43-g6b8931
Teaching an old dog new tricks
DOXYGEN
query.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include "mutt/lib.h"
36 #include "query.h"
37 
49 {
50  if (!buf)
51  return NM_QUERY_TYPE_MESGS;
52 
53  enum NmQueryType query_type = NM_QUERY_TYPE_MESGS;
54 
55  size_t buf_len = mutt_str_len(buf);
56  const char *message_ptr = mutt_istrn_rfind(buf, buf_len, "type=messages");
57  const char *thread_ptr = mutt_istrn_rfind(buf, buf_len, "type=threads");
58 
59  // No valid type statement found.
60  if (!message_ptr && !thread_ptr)
61  return query_type;
62 
63  // Determine the last valid "type=" statement.
64  if ((!message_ptr && thread_ptr) || (thread_ptr > message_ptr))
65  {
66  query_type = NM_QUERY_TYPE_THREADS;
67  }
68  else
69  {
70  query_type = NM_QUERY_TYPE_MESGS;
71  }
72 
73  // Clean-up any valid "type=" statements.
74  // The six variations of how "type=" could appear.
75  const char *variants[6] = { "&type=threads", "&type=messages",
76  "type=threads&", "type=messages&",
77  "type=threads", "type=messages" };
78  int variants_size = mutt_array_size(variants);
79 
80  for (int i = 0; i < variants_size; i++)
81  {
82  mutt_istr_remall(buf, variants[i]);
83  }
84 
85  return query_type;
86 }
87 
95 const char *nm_query_type_to_string(enum NmQueryType query_type)
96 {
97  if (query_type == NM_QUERY_TYPE_THREADS)
98  return "threads";
99  return "messages";
100 }
101 
109 enum NmQueryType nm_string_to_query_type(const char *str)
110 {
111  enum NmQueryType query_type = nm_string_to_query_type_mapper(str);
112 
113  if (query_type == NM_QUERY_TYPE_UNKNOWN)
114  {
115  mutt_error(_("failed to parse notmuch query type: %s"), NONULL(str));
116  return NM_QUERY_TYPE_MESGS;
117  }
118 
119  return query_type;
120 }
121 
129 enum NmQueryType nm_string_to_query_type_mapper(const char *str)
130 {
131  if (mutt_str_equal(str, "threads"))
132  return NM_QUERY_TYPE_THREADS;
133  if (mutt_str_equal(str, "messages"))
134  return NM_QUERY_TYPE_MESGS;
135 
136  return NM_QUERY_TYPE_UNKNOWN;
137 }
138 
149 bool nm_query_window_check_timebase(const char *timebase)
150 {
151  if ((strcmp(timebase, "hour") == 0) || (strcmp(timebase, "day") == 0) ||
152  (strcmp(timebase, "week") == 0) || (strcmp(timebase, "month") == 0) ||
153  (strcmp(timebase, "year") == 0))
154  {
155  return true;
156  }
157  return false;
158 }
159 
205 enum NmWindowQueryRc
206 nm_windowed_query_from_query(char *buf, size_t buflen, const bool force_enable,
207  const short duration, const short cur_pos, const char *cur_search,
208  const char *timebase, const char *or_terms)
209 {
210  // if the duration is a non positive integer, disable the window unless the
211  // user explicitly enables windowed queries.
212  if (!force_enable && (duration <= 0))
213  {
215  }
216 
217  int beg = duration * (cur_pos + 1);
218  int end = duration * cur_pos;
219 
220  // If the duration is 0, we want to generate a query spanning a single timebase.
221  // For example, `date:1month..1month` spans the previous month.
222  if ((duration == 0) && (cur_pos != 0))
223  {
224  end = cur_pos;
225  beg = end;
226  }
227 
228  if (!nm_query_window_check_timebase(timebase))
229  {
231  }
232 
233  size_t length = 0;
234  if (end == 0)
235  {
236  // Open-ended date allows mail from the future.
237  // This may occur is the sender's time settings are off.
238  length = snprintf(buf, buflen, "date:%d%s..", beg, timebase);
239  }
240  else
241  {
242  length = snprintf(buf, buflen, "date:%d%s..%d%s", beg, timebase, end, timebase);
243  }
244 
245  if (!mutt_str_equal(or_terms, ""))
246  {
247  char *date_part = mutt_str_dup(buf);
248  length = snprintf(buf, buflen, "(%s or (%s))", date_part, or_terms);
249  FREE(&date_part);
250  }
251 
252  // Add current search to window query.
253  snprintf(buf + length, buflen, " and %s", cur_search);
254 
256 }
#define mutt_error(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
#define mutt_array_size(x)
Definition: memory.h:33
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
const char * mutt_istrn_rfind(const char *haystack, size_t haystack_length, const char *needle)
Find last instance of a substring, ignoring case.
Definition: string.c:448
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715
int mutt_istr_remall(char *str, const char *target)
Remove all occurrences of substring, ignoring case.
Definition: string.c:881
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
enum NmQueryType nm_string_to_query_type(const char *str)
Lookup a query type.
Definition: query.c:109
const char * nm_query_type_to_string(enum NmQueryType query_type)
Turn a query type into a string.
Definition: query.c:95
enum NmQueryType nm_string_to_query_type_mapper(const char *str)
Lookup a query type.
Definition: query.c:129
bool nm_query_window_check_timebase(const char *timebase)
Checks if a given timebase string is valid.
Definition: query.c:149
enum NmQueryType nm_parse_type_from_query(char *buf)
Parse a query type out of a query.
Definition: query.c:48
enum NmWindowQueryRc nm_windowed_query_from_query(char *buf, size_t buflen, const bool force_enable, const short duration, const short cur_pos, const char *cur_search, const char *timebase, const char *or_terms)
Windows buf with notmuch date: search term.
Definition: query.c:206
Notmuch query functions.
NmWindowQueryRc
Return codes for nm_windowed_query_from_query()
Definition: query.h:45
@ NM_WINDOW_QUERY_SUCCESS
Query was successful.
Definition: query.h:46
@ NM_WINDOW_QUERY_INVALID_DURATION
Invalid duration.
Definition: query.h:48
@ NM_WINDOW_QUERY_INVALID_TIMEBASE
Invalid timebase.
Definition: query.h:47
NmQueryType
Notmuch Query Types.
Definition: query.h:35
@ NM_QUERY_TYPE_UNKNOWN
Unknown query type. Error in notmuch query.
Definition: query.h:38
@ NM_QUERY_TYPE_THREADS
Whole threads.
Definition: query.h:37
@ NM_QUERY_TYPE_MESGS
Default: Messages only.
Definition: query.h:36
#define NONULL(x)
Definition: string2.h:37