⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pattern.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
    min->tm_mon = max->tm_mon;    max->tm_mon = tmp;          tmp = min->tm_mday;    min->tm_mday = max->tm_mday;    max->tm_mday = tmp;        min->tm_hour = min->tm_min = min->tm_sec = 0;    max->tm_hour = 23;    max->tm_min = max->tm_sec = 59;  }}static const char * parse_date_range (const char* pc, struct tm *min,    struct tm *max, int haveMin, struct tm *baseMin, BUFFER *err){  int flag = M_PDR_NONE;	  while (*pc && ((flag & M_PDR_DONE) == 0))  {    const char *pt;    char ch = *pc++;    SKIPWS (pc);    switch (ch)    {      case '-':      {	/* try a range of absolute date minus offset of Ndwmy */	pt = get_offset (min, pc, -1);	if (pc == pt)	{	  if (flag == M_PDR_NONE)	  { /* nothing yet and no offset parsed => absolute date? */	    if (!getDate (pc, max, err))	      flag |= (M_PDR_ABSOLUTE | M_PDR_ERRORDONE);  /* done bad */	    else	    {	      /* reestablish initial base minimum if not specified */	      if (!haveMin)		memcpy (min, baseMin, sizeof(struct tm));	      flag |= (M_PDR_ABSOLUTE | M_PDR_DONE);  /* done good */	    }	  }	  else	    flag |= M_PDR_ERRORDONE;	}	else	{	  pc = pt;	  if (flag == M_PDR_NONE && !haveMin)	  { /* the very first "-3d" without a previous absolute date */	    max->tm_year = min->tm_year;	    max->tm_mon = min->tm_mon;	    max->tm_mday = min->tm_mday;	  }	  flag |= M_PDR_MINUS;	}      }      break;      case '+':      { /* enlarge plusRange */	pt = get_offset (max, pc, 1);	if (pc == pt)	  flag |= M_PDR_ERRORDONE;	else	{	  pc = pt;	  flag |= M_PDR_PLUS;	}      }      break;      case '*':      { /* enlarge window in both directions */	pt = get_offset (min, pc, -1);	if (pc == pt)	  flag |= M_PDR_ERRORDONE;	else	{	  pc = get_offset (max, pc, 1);	  flag |= M_PDR_WINDOW;	}      }      break;      default:	flag |= M_PDR_ERRORDONE;    }    SKIPWS (pc);  }  if ((flag & M_PDR_ERROR) && !(flag & M_PDR_ABSOLUTE))  { /* getDate has its own error message, don't overwrite it here */    snprintf (err->data, err->dsize, _("Invalid relative date: %s"), pc-1);  }  return ((flag & M_PDR_ERROR) ? NULL : pc);}static int eat_date (pattern_t *pat, BUFFER *s, BUFFER *err){  BUFFER buffer;  struct tm min, max;  memset (&buffer, 0, sizeof (buffer));  if (mutt_extract_token (&buffer, s, M_TOKEN_COMMENT | M_TOKEN_PATTERN) != 0      || !buffer.data)  {    strfcpy (err->data, _("error in expression"), err->dsize);    return (-1);  }  memset (&min, 0, sizeof (min));  /* the `0' time is Jan 1, 1970 UTC, so in order to prevent a negative time     when doing timezone conversion, we use Jan 2, 1970 UTC as the base     here */  min.tm_mday = 2;  min.tm_year = 70;  memset (&max, 0, sizeof (max));  /* Arbitrary year in the future.  Don't set this too high     or mutt_mktime() returns something larger than will     fit in a time_t on some systems */  max.tm_year = 130;  max.tm_mon = 11;  max.tm_mday = 31;  max.tm_hour = 23;  max.tm_min = 59;  max.tm_sec = 59;  if (strchr ("<>=", buffer.data[0]))  {    /* offset from current time       <3d	less than three days ago       >3d	more than three days ago       =3d	exactly three days ago */    time_t now = time (NULL);    struct tm *tm = localtime (&now);    int exact = 0;    if (buffer.data[0] == '<')    {      memcpy (&min, tm, sizeof (min));      tm = &min;    }    else    {      memcpy (&max, tm, sizeof (max));      tm = &max;      if (buffer.data[0] == '=')	exact++;    }    tm->tm_hour = 23;    tm->tm_min = tm->tm_sec = 59;    /* force negative offset */    get_offset (tm, buffer.data + 1, -1);    if (exact)    {      /* start at the beginning of the day in question */      memcpy (&min, &max, sizeof (max));      min.tm_hour = min.tm_sec = min.tm_min = 0;    }  }  else  {    const char *pc = buffer.data;    int haveMin = FALSE;    int untilNow = FALSE;    if (isdigit ((unsigned char)*pc))    {      /* mininum date specified */      if ((pc = getDate (pc, &min, err)) == NULL)      {	FREE (&buffer.data);	return (-1);      }      haveMin = TRUE;      SKIPWS (pc);      if (*pc == '-')      {        const char *pt = pc + 1;	SKIPWS (pt);	untilNow = (*pt == '\0');      }    }    if (!untilNow)    { /* max date or relative range/window */      struct tm baseMin;      if (!haveMin)      { /* save base minimum and set current date, e.g. for "-3d+1d" */	time_t now = time (NULL);	struct tm *tm = localtime (&now);	memcpy (&baseMin, &min, sizeof(baseMin));	memcpy (&min, tm, sizeof (min));	min.tm_hour = min.tm_sec = min.tm_min = 0;      }            /* preset max date for relative offsets,	 if nothing follows we search for messages on a specific day */      max.tm_year = min.tm_year;      max.tm_mon = min.tm_mon;      max.tm_mday = min.tm_mday;      if (!parse_date_range (pc, &min, &max, haveMin, &baseMin, err))      { /* bail out on any parsing error */	FREE (&buffer.data);	return (-1);      }    }  }  /* Since we allow two dates to be specified we'll have to adjust that. */  adjust_date_range (&min, &max);  pat->min = mutt_mktime (&min, 1);  pat->max = mutt_mktime (&max, 1);  FREE (&buffer.data);  return 0;}static int patmatch (const pattern_t* pat, const char* buf){  if (pat->stringmatch)    return !strstr (buf, pat->p.str);  else if (pat->groupmatch)    return !mutt_group_match (pat->p.g, buf);  else    return regexec (pat->p.rx, buf, 0, NULL, 0);}static struct pattern_flags *lookup_tag (char tag){  int i;  for (i = 0; Flags[i].tag; i++)    if (Flags[i].tag == tag)      return (&Flags[i]);  return NULL;}static /* const */ char *find_matching_paren (/* const */ char *s){  int level = 1;  for (; *s; s++)  {    if (*s == '(')      level++;    else if (*s == ')')    {      level--;      if (!level)	break;    }  }  return s;}void mutt_pattern_free (pattern_t **pat){  pattern_t *tmp;  while (*pat)  {    tmp = *pat;    *pat = (*pat)->next;    if (tmp->stringmatch)      FREE (&tmp->p.str);    else if (tmp->groupmatch)      tmp->p.g = NULL;    else if (tmp->p.rx)    {      regfree (tmp->p.rx);      FREE (&tmp->p.rx);    }    if (tmp->child)      mutt_pattern_free (&tmp->child);    FREE (&tmp);  }}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 alladdr = 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 = mutt_strlen (s);  while (*ps.dptr)  {    SKIPWS (ps.dptr);    switch (*ps.dptr)    {      case '^':	ps.dptr++;	alladdr = !alladdr;	break;      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;	alladdr = 0;	break;      case '%':      case '=':      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;	tmp->alladdr = alladdr;        tmp->stringmatch = (*ps.dptr == '=') ? 1 : 0;        tmp->groupmatch  = (*ps.dptr == '%') ? 1 : 0;	not = 0;	alladdr = 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;	tmp->alladdr |= alladdr;	not = 0;	alladdr = 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);}static intperform_and (pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr){  for (; pat; pat = pat->next)    if (mutt_pattern_exec (pat, flags, ctx, hdr) <= 0)      return 0;  return 1;}static intperform_or (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr){  for (; pat; pat = pat->next)    if (mutt_pattern_exec (pat, flags, ctx, hdr) > 0)      return 1;  return 0;}static int match_adrlist (pattern_t *pat, int match_personal, int n, ...){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -