/[mailutils]/mailutils/mh/mh_msgset.c
ViewVC logotype

Diff of /mailutils/mh/mh_msgset.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by gray, Wed Sep 18 21:19:55 2002 UTC revision 1.3 by gray, Thu Sep 19 14:53:45 2002 UTC
# Line 136  static struct msgset_keyword { Line 136  static struct msgset_keyword {
136  };  };
137    
138  static char *  static char *
139  msgset_preproc (mailbox_t mbox, char *arg)  msgset_preproc_part (mailbox_t mbox, char *arg, char **rest)
140  {  {
141    struct msgset_keyword *p;    struct msgset_keyword *p;
142      
143    for (p = keywords; p->name; p++)    for (p = keywords; p->name; p++)
144      if (strncmp (arg, p->name, strlen (p->name)) == 0)      if (strncmp (arg, p->name, strlen (p->name)) == 0)
145        {        {
# Line 157  msgset_preproc (mailbox_t mbox, char *ar Line 157  msgset_preproc (mailbox_t mbox, char *ar
157              exit (1);              exit (1);
158            }            }
159          message_get_uid (msg, &uid);          message_get_uid (msg, &uid);
160          asprintf (&ret, "%lu%s", (unsigned long) uid, arg + strlen (p->name));          asprintf (&ret, "%lu", (unsigned long) uid);
161            *rest = arg + strlen (p->name);
162          return ret;          return ret;
163        }        }
164      *rest = arg + strlen (arg);
165    return strdup (arg);    return strdup (arg);
166  }  }
167    
168    static char *
169    msgset_preproc (mailbox_t mbox, char *arg)
170    {
171      char *buf, *tail;
172      
173      if (strcmp (arg, "all") == 0)
174        {
175          /* Special case */
176          arg = "first-last";
177        }
178    
179      buf = msgset_preproc_part (mbox, arg, &tail);
180      if (tail[0] == '-')
181        {
182          char *rest = msgset_preproc_part (mbox, tail+1, &tail);
183          char *p = NULL;
184          asprintf (&p, "%s-%s", buf, rest);
185          free (rest);
186          free (buf);
187          buf = p;
188        }
189      
190      if (tail[0])
191        {
192          char *p = NULL;
193          asprintf (&p, "%s%s", buf, tail);
194          free (buf);
195          buf = p;
196        }
197      return buf;
198    }
199    
200  static int  static int
201  comp_mesg (const void *a, const void *b)  comp_mesg (const void *a, const void *b)
202  {  {
# Line 195  mh_msgset_parse (mailbox_t mbox, mh_msgs Line 229  mh_msgset_parse (mailbox_t mbox, mh_msgs
229      {      {
230        char *p = NULL;        char *p = NULL;
231        size_t start, end;        size_t start, end;
232          size_t msg_first, n;
233        long num;        long num;
234        char *arg = msgset_preproc (mbox, argv[i]);        char *arg = msgset_preproc (mbox, argv[i]);
235        start = strtoul (arg, &p, 0);        start = strtoul (arg, &p, 0);
236        switch (*p)        switch (*p)
237          {          {
238          case 0:          case 0:
239            msglist[msgno++] = start;            n = mh_get_message (mbox, start, NULL);
240              if (!n)
241                {
242                  mh_error ("message %d does not exist", start);
243                  exit (1);
244                }
245              msglist[msgno++] = n;
246            break;            break;
247                        
248          case '-':          case '-':
# Line 215  mh_msgset_parse (mailbox_t mbox, mh_msgs Line 256  mh_msgset_parse (mailbox_t mbox, mh_msgs
256                end = t;                end = t;
257              }              }
258            _expand (&msgcnt, &msglist, end - start);            _expand (&msgcnt, &msglist, end - start);
259              msg_first  = msgno;
260            for (; start <= end; start++)            for (; start <= end; start++)
261              msglist[msgno++] = start;              {
262                  n = mh_get_message (mbox, start, NULL);
263                  if (n)
264                    msglist[msgno++] = n;
265                }
266              if (msgno == msg_first)
267                {
268                  mh_error ("no messages in range %s", argv[i]);
269                  exit (1);
270                }
271            break;            break;
272                        
273          case ':':          case ':':
# Line 227  mh_msgset_parse (mailbox_t mbox, mh_msgs Line 278  mh_msgset_parse (mailbox_t mbox, mh_msgs
278            if (end < start)            if (end < start)
279              {              {
280                size_t t = start;                size_t t = start;
281                start = end;                start = end + 1;
282                end = t;                end = t;
283              }              }
284              else
285                end--;
286            _expand (&msgcnt, &msglist, end - start);            _expand (&msgcnt, &msglist, end - start);
287              msg_first  = msgno;
288            for (; start <= end; start++)            for (; start <= end; start++)
289              msglist[msgno++] = start;              {
290                  n = mh_get_message (mbox, start, NULL);
291                  if (n)
292                    msglist[msgno++] = n;
293                }
294              if (msgno == msg_first)
295                {
296                  mh_error ("no messages in range %s", argv[i]);
297                  exit (1);
298                }
299            break;            break;
300                        
301          default:          default:
# Line 241  mh_msgset_parse (mailbox_t mbox, mh_msgs Line 304  mh_msgset_parse (mailbox_t mbox, mh_msgs
304        free (arg);        free (arg);
305      }      }
306    
307      msgcnt = msgno;
308      
309    /* Sort the resulting message set */    /* Sort the resulting message set */
310    qsort (msglist, msgcnt, sizeof (*msglist), comp_mesg);    qsort (msglist, msgcnt, sizeof (*msglist), comp_mesg);
311    
# Line 265  mh_msgset_member (mh_msgset_t *msgset, s Line 330  mh_msgset_member (mh_msgset_t *msgset, s
330        return i + 1;        return i + 1;
331    return 0;    return 0;
332  }  }
333    
334    /* Auxiliary function. Performs binary search for a message with the
335       given sequence number */
336    static size_t
337    mh_search_message (mailbox_t mbox, size_t start, size_t stop,
338                       size_t seqno, message_t *mesg)
339    {
340      message_t mid_msg = NULL;
341      size_t num = 0, middle;
342    
343      middle = (start + stop) / 2;
344      if (mailbox_get_message (mbox, middle, &mid_msg)
345          || mh_message_number (mid_msg, &num))
346        return 0;
347    
348      if (num == seqno)
349        {
350          if (mesg)
351            *mesg = mid_msg;
352          return middle;
353        }
354          
355      if (start >= stop)
356        return 0;
357    
358      if (num > seqno)
359        return mh_search_message (mbox, start, middle-1, seqno, mesg);
360      else /*if (num < seqno)*/
361        return mh_search_message (mbox, middle+1, stop, seqno, mesg);
362    }
363    
364    /* Retrieve the message with the given sequence number.
365       Returns ordinal number of the message in the mailbox if found,
366       zero otherwise. The retrieved message is stored in the location
367       pointed to by mesg, unless it is NULL. */
368      
369    size_t
370    mh_get_message (mailbox_t mbox, size_t seqno, message_t *mesg)
371    {
372      size_t num, count;
373      message_t msg;
374    
375      if (mailbox_get_message (mbox, 1, &msg)
376          || mh_message_number (msg, &num))
377        return 0;
378      if (seqno < num)
379        return 0;
380      else if (seqno == num)
381        {
382          if (mesg)
383            *mesg = msg;
384          return 1;
385        }
386    
387      if (mailbox_messages_count (mbox, &count)
388          || mailbox_get_message (mbox, count, &msg)
389          || mh_message_number (msg, &num))
390        return 0;
391      if (seqno > num)
392        return 0;
393      else if (seqno == num)
394        {
395          if (mesg)
396            *mesg = msg;
397          return count;
398        }
399    
400      return mh_search_message (mbox, 1, count, seqno, mesg);
401    }
402    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26