strfcpy (err->data, "empty pattern", err->dsize);
strfcpy (err->data, _("empty pattern"), err->dsize);
pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err){  pattern_t *curlist = NULL;  pattern_t *tmp;  pattern_t *last = NULL;  int not = 0;  int or = 0;  int implicit = 1;	/* used to detect logical AND operator */  struct pattern_flags *entry;  char *p;  char *buf;  BUFFER ps;  memset (&ps, 0, sizeof (ps));  ps.dptr = s;  ps.dsize = strlen (s);  while (*ps.dptr)  {    SKIPWS (ps.dptr);    switch (*ps.dptr)    {      case '!':	ps.dptr++;	not = !not;	break;      case '|':	if (!or)	{	  if (!curlist)	  {	    snprintf (err->data, err->dsize, "error in pattern at: %s", ps.dptr);	    return NULL;	  }	  if (curlist->next)	  {	    /* A & B | C == (A & B) | C */	    tmp = new_pattern ();	    tmp->op = M_AND;	    tmp->child = curlist;	    curlist = tmp;	    last = curlist;	  }	  or = 1;	}	ps.dptr++;	implicit = 0;	not = 0;	break;      case '~':	if (implicit && or)	{	  /* A | B & C == (A | B) & C */	  tmp = new_pattern ();	  tmp->op = M_OR;	  tmp->child = curlist;	  curlist = tmp;	  last = tmp;	  or = 0;	}	tmp = new_pattern ();	tmp->not = not;	not = 0;	if (last)	  last->next = tmp;	else	  curlist = tmp;	last = tmp;	ps.dptr++; /* move past the ~ */	if ((entry = lookup_tag (*ps.dptr)) == NULL)	{	  snprintf (err->data, err->dsize, "%c: invalid command", *ps.dptr);	  mutt_pattern_free (&curlist);	  return NULL;	}	if (entry->class && (flags & entry->class) == 0)	{	  snprintf (err->data, err->dsize, "%c: not supported in this mode", *ps.dptr);	  mutt_pattern_free (&curlist);	  return NULL;	}	tmp->op = entry->op;	ps.dptr++; /* eat the operator and any optional whitespace */	SKIPWS (ps.dptr);	if (entry->eat_arg)	{	  if (!*ps.dptr)	  {	    snprintf (err->data, err->dsize, "missing parameter");	    mutt_pattern_free (&curlist);	    return NULL;	  }	  if (entry->eat_arg (tmp, &ps, err) == -1)	  {	    mutt_pattern_free (&curlist);	    return NULL;	  }	}	implicit = 1;	break;      case '(':	p = find_matching_paren (ps.dptr + 1);	if (*p != ')')	{	  snprintf (err->data, err->dsize, "mismatched parenthesis: %s", ps.dptr);	  mutt_pattern_free (&curlist);	  return NULL;	}	/* compile the sub-expression */	buf = mutt_substrdup (ps.dptr + 1, p);	if ((tmp = mutt_pattern_comp (buf, flags, err)) == NULL)	{	  FREE (&buf);	  mutt_pattern_free (&curlist);	  return NULL;	}	FREE (&buf);	if (last)	  last->next = tmp;	else	  curlist = tmp;	last = tmp;	tmp->not = not;	not = 0;	ps.dptr = p + 1; /* restore location */	break;      default:	snprintf (err->data, err->dsize, "error in pattern at: %s", ps.dptr);	mutt_pattern_free (&curlist);	return NULL;    }  }  if (!curlist)  {    strfcpy (err->data, "empty pattern", err->dsize);    return NULL;  }  if (curlist->next)  {    tmp = new_pattern ();    tmp->op = or ? M_OR : M_AND;    tmp->child = curlist;    curlist = tmp;  }  return (curlist);}