From: Richard Russon Date: Wed, 1 Nov 2017 02:39:27 +0000 (+0000) Subject: regex obj to ptr X-Git-Tag: neomutt-20180223~57^2~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a45b5fde7fff32a0b79da0511dead2925ca11c5a;p=neomutt regex obj to ptr Change the backing variables for config from objects to pointers. --- diff --git a/browser.c b/browser.c index be42a3046..b3a623a81 100644 --- a/browser.c +++ b/browser.c @@ -737,7 +737,7 @@ static int examine_directory(struct Menu *menu, struct BrowserState *state, continue; if (prefix && *prefix && (strncmp(prefix, nntp_data->group, strlen(prefix)) != 0)) continue; - if (!((regexec(Mask.regex, nntp_data->group, 0, NULL, 0) == 0) ^ Mask.not)) + if (Mask && !((regexec(Mask->regex, nntp_data->group, 0, NULL, 0) == 0) ^ Mask->not)) continue; add_folder(menu, state, nntp_data->group, NULL, NULL, NULL, nntp_data); } @@ -795,7 +795,7 @@ static int examine_directory(struct Menu *menu, struct BrowserState *state, { continue; } - if (!((regexec(Mask.regex, de->d_name, 0, NULL, 0) == 0) ^ Mask.not)) + if (Mask && !((regexec(Mask->regex, de->d_name, 0, NULL, 0) == 0) ^ Mask->not)) continue; mutt_file_concat_path(buffer, d, de->d_name, sizeof(buffer)); @@ -1067,7 +1067,7 @@ static void init_menu(struct BrowserState *state, struct Menu *menu, mutt_str_strfcpy(path, LastDir, sizeof(path)); mutt_pretty_mailbox(path, sizeof(path)); snprintf(title, titlelen, _("Directory [%s], File mask: %s"), path, - NONULL(Mask.pattern)); + NONULL(Mask ? Mask->pattern : NULL)); } } @@ -1762,7 +1762,7 @@ void mutt_select_file(char *f, size_t flen, int flags, char ***files, int *numfi case OP_ENTER_MASK: - mutt_str_strfcpy(buf, NONULL(Mask.pattern), sizeof(buf)); + mutt_str_strfcpy(buf, NONULL(Mask ? Mask->pattern : NULL), sizeof(buf)); if (mutt_get_field(_("File Mask: "), buf, sizeof(buf), 0) == 0) { regex_t *rx = mutt_mem_malloc(sizeof(regex_t)); @@ -1790,11 +1790,18 @@ void mutt_select_file(char *f, size_t flen, int flags, char ***files, int *numfi } else { - mutt_str_replace(&Mask.pattern, buf); - regfree(Mask.regex); - FREE(&Mask.regex); - Mask.regex = rx; - Mask.not = not; + if (Mask) + { + regfree(Mask->regex); + FREE(&Mask->regex); + } + else + { + Mask = mutt_mem_calloc(1, sizeof(struct Regex *)); + } + mutt_str_replace(&Mask->pattern, buf); //QWQ + Mask->regex = rx; + Mask->not = not; destroy_state(&state); #ifdef USE_IMAP diff --git a/globals.h b/globals.h index b21f26cb8..8c20f6042 100644 --- a/globals.h +++ b/globals.h @@ -50,7 +50,7 @@ WHERE char *Attribution; WHERE char *AttributionLocale; WHERE char *AttachCharset; WHERE char *AttachFormat; -WHERE struct Regex AttachKeyword; +WHERE struct Regex *AttachKeyword; WHERE char *ComposeFormat; WHERE char *ConfigCharset; WHERE char *ContentType; @@ -265,8 +265,8 @@ WHERE struct Alias *Aliases; WHERE struct ListHead UserHeader INITVAL(STAILQ_HEAD_INITIALIZER(UserHeader)); /* -- formerly in pgp.h -- */ -WHERE struct Regex PgpGoodSign; -WHERE struct Regex PgpDecryptionOkay; +WHERE struct Regex *PgpGoodSign; +WHERE struct Regex *PgpDecryptionOkay; WHERE char *PgpSignAs; WHERE short PgpTimeout; WHERE char *PgpEntryFormat; @@ -320,11 +320,12 @@ WHERE int NmQueryWindowCurrentPosition; WHERE char *NmQueryWindowCurrentSearch; #endif -WHERE struct Regex Mask; -WHERE struct Regex QuoteRegexp; -WHERE struct Regex ReplyRegexp; -WHERE struct Regex Smileys; -WHERE struct Regex GecosMask; +/* These variables are backing for config items */ +WHERE struct Regex *GecosMask; +WHERE struct Regex *Mask; +WHERE struct Regex *QuoteRegexp; +WHERE struct Regex *ReplyRegexp; +WHERE struct Regex *Smileys; #ifdef MAIN_C const char *const BodyTypes[] = { diff --git a/imap/browse.c b/imap/browse.c index d4124a70b..411f8d7bc 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -95,7 +95,7 @@ static void add_folder(char delim, char *folder, int noselect, int noinferiors, /* apply filemask filter. This should really be done at menu setup rather * than at scan, since it's so expensive to scan. But that's big changes * to browser.c */ - if (!((regexec(Mask.regex, relpath, 0, NULL, 0) == 0) ^ Mask.not)) + if (Mask && !((regexec(Mask->regex, relpath, 0, NULL, 0) == 0) ^ Mask->not)) { FREE(&mx.mbox); return; diff --git a/init.c b/init.c index 354015bb8..0fc54dc78 100644 --- a/init.c +++ b/init.c @@ -175,50 +175,58 @@ static int parse_regex(int idx, struct Buffer *tmp, struct Buffer *err) int e, flags = 0; const char *p = NULL; regex_t *rx = NULL; - struct Regex *ptr = (struct Regex *) MuttVars[idx].data; + struct Regex *ptr = *(struct Regex **) MuttVars[idx].data; - if (!ptr->pattern || (mutt_str_strcmp(ptr->pattern, tmp->data) != 0)) + if (ptr) { - bool not = false; - - /* $mask is case-sensitive */ - if ((mutt_str_strcmp(MuttVars[idx].option, "mask") != 0) && mutt_mb_is_lower(tmp->data)) - flags |= REG_ICASE; + /* Same pattern as we already have */ + if (mutt_str_strcmp(ptr->pattern, tmp->data) != 0) + return 0; + } + else + { + ptr = mutt_mem_calloc(1, sizeof(struct Regex *)); + } - p = tmp->data; - if (mutt_str_strcmp(MuttVars[idx].option, "mask") == 0) - { - if (*p == '!') - { - not = true; - p++; - } - } + bool not = false; - rx = mutt_mem_malloc(sizeof(regex_t)); - e = REGCOMP(rx, p, flags); - if (e != 0) - { - regerror(e, rx, err->data, err->dsize); - FREE(&rx); - return 0; - } + /* Should we use smart case matching? */ + if (((MuttVars[idx].flags & DT_REGEX_MATCH_CASE) == 0) && mutt_mb_is_lower(tmp->data)) + flags |= REG_ICASE; - /* get here only if everything went smoothly */ - if (ptr->pattern) + p = tmp->data; + /* Is a prefix of '!' allowed? */ + if ((MuttVars[idx].flags & DT_REGEX_ALLOW_NOT) != 0) + { + if (*p == '!') { - FREE(&ptr->pattern); - regfree((regex_t *) ptr->regex); - FREE(&ptr->regex); + not = true; + p++; } + } - ptr->pattern = mutt_str_strdup(tmp->data); - ptr->regex = rx; - ptr->not = not; + rx = mutt_mem_malloc(sizeof(regex_t)); + e = REGCOMP(rx, p, flags); + if (e != 0) + { + regerror(e, rx, err->data, err->dsize); + FREE(&rx); + return 0; + } - return 1; + /* get here only if everything went smoothly */ + if (ptr->pattern) + { + FREE(&ptr->pattern); + regfree((regex_t *) ptr->regex); + FREE(&ptr->regex); } - return 0; + + ptr->pattern = mutt_str_strdup(tmp->data); + ptr->regex = rx; + ptr->not = not; + + return 1; } void set_quadoption(int opt, int flag) @@ -424,9 +432,11 @@ int mutt_option_set(const struct Option *val, struct Buffer *err) struct Envelope *e = Context->hdrs[i]->env; if (e && e->subject) { - e->real_subj = (regexec(ReplyRegexp.regex, e->subject, 1, pmatch, 0)) ? - e->subject : - e->subject + pmatch[0].rm_eo; + e->real_subj = + (ReplyRegexp && + (regexec(ReplyRegexp->regex, e->subject, 1, pmatch, 0))) ? + e->subject : + e->subject + pmatch[0].rm_eo; } } } @@ -737,7 +747,7 @@ int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags) static void free_opt(struct Option *p) { - struct Regex *pp = NULL; + struct Regex **pp = NULL; switch (DTYPE(p->type)) { @@ -745,12 +755,12 @@ static void free_opt(struct Option *p) mutt_addr_free((struct Address **) p->data); break; case DT_REGEX: - pp = (struct Regex *) p->data; - FREE(&pp->pattern); - if (pp->regex) + pp = (struct Regex **) p->data; + FREE(&(*pp)->pattern); + if ((*pp)->regex) { - regfree(pp->regex); - FREE(&pp->regex); + regfree((*pp)->regex); + FREE(&(*pp)->regex); } break; case DT_PATH: @@ -1990,23 +2000,28 @@ static void restore_default(struct Option *p) break; case DT_REGEX: { - struct Regex *pp = (struct Regex *) p->data; - int flags = 0; - - FREE(&pp->pattern); - if (pp->regex) + struct Regex **pp = (struct Regex **) p->data; + if (*pp) + { + FREE(&(*pp)->pattern); + if ((*pp)->regex) + { + regfree((*pp)->regex); + FREE(&(*pp)->regex); + } + } + else { - regfree(pp->regex); - FREE(&pp->regex); + *pp = mutt_mem_calloc(1, sizeof(struct Regex)); } if (p->init) { - int retval; + int flags = 0; char *s = (char *) p->init; - pp->regex = mutt_mem_calloc(1, sizeof(regex_t)); - pp->pattern = mutt_str_strdup((char *) p->init); + (*pp)->regex = mutt_mem_calloc(1, sizeof(regex_t)); + (*pp)->pattern = mutt_str_strdup((char *) p->init); if ((mutt_str_strcmp(p->option, "mask") != 0) && (mutt_mb_is_lower((const char *) p->init))) { @@ -2015,19 +2030,19 @@ static void restore_default(struct Option *p) if ((mutt_str_strcmp(p->option, "mask") == 0) && *s == '!') { s++; - pp->not = true; + (*pp)->not = true; } - retval = REGCOMP(pp->regex, s, flags); - if (retval != 0) + int rc = REGCOMP((*pp)->regex, s, flags); + if (rc != 0) { char msgbuf[STRING]; - regerror(retval, pp->regex, msgbuf, sizeof(msgbuf)); + regerror(rc, (*pp)->regex, msgbuf, sizeof(msgbuf)); fprintf(stderr, _("restore_default(%s): error in regex: %s\n"), - p->option, pp->pattern); + p->option, (*pp)->pattern); fprintf(stderr, "%s\n", msgbuf); mutt_sleep(0); - FREE(&pp->pattern); - FREE(&pp->regex); + FREE(&(*pp)->pattern); + FREE(&(*pp)->regex); } } } @@ -2642,8 +2657,9 @@ static int parse_set(struct Buffer *tmp, struct Buffer *s, unsigned long data, if (query || *s->dptr != '=') { /* user requested the value of this variable */ - struct Regex *ptr = (struct Regex *) MuttVars[idx].data; - pretty_var(err->data, err->dsize, MuttVars[idx].option, NONULL(ptr->pattern)); + struct Regex *ptr = *(struct Regex **) MuttVars[idx].data; + const char *value = ptr ? ptr->pattern : NULL; + pretty_var(err->data, err->dsize, MuttVars[idx].option, NONULL(value)); break; } @@ -2674,7 +2690,8 @@ static int parse_set(struct Buffer *tmp, struct Buffer *s, unsigned long data, struct Envelope *e = Context->hdrs[i]->env; if (e && e->subject) { - e->real_subj = (regexec(ReplyRegexp.regex, e->subject, 1, pmatch, 0)) ? + e->real_subj = (ReplyRegexp && + (regexec(ReplyRegexp->regex, e->subject, 1, pmatch, 0))) ? e->subject : e->subject + pmatch[0].rm_eo; } @@ -2953,7 +2970,7 @@ static int parse_set(struct Buffer *tmp, struct Buffer *s, unsigned long data, return r; } -/* FILO designed to contain the list of config files that have been sourced and +/* LIFO designed to contain the list of config files that have been sourced and * avoid cyclic sourcing */ static struct ListHead MuttrcStack = STAILQ_HEAD_INITIALIZER(MuttrcStack); diff --git a/mutt_options.h b/mutt_options.h index a487c50ef..1d5b0d6bb 100644 --- a/mutt_options.h +++ b/mutt_options.h @@ -52,6 +52,10 @@ struct Buffer; #define DT_SORT_AUX 0x80 #define DT_SORT_SIDEBAR 0x100 +/* ... DT_REGEX */ +#define DT_REGEX_MATCH_CASE 0x010 /**< Case-sensitive matching */ +#define DT_REGEX_ALLOW_NOT 0x020 /**< Regex can begin with '!' */ + /** * struct Option - Definition of a user-variable */ diff --git a/muttlib.c b/muttlib.c index 44372304c..ae6dad734 100644 --- a/muttlib.c +++ b/muttlib.c @@ -326,9 +326,9 @@ char *mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw) memset(dest, 0, destlen); - if (GecosMask.regex) + if (GecosMask) { - if (regexec(GecosMask.regex, pw->pw_gecos, 1, pat_match, 0) == 0) + if (regexec(GecosMask->regex, pw->pw_gecos, 1, pat_match, 0) == 0) mutt_str_strfcpy(dest, pw->pw_gecos + pat_match[0].rm_so, MIN(pat_match[0].rm_eo - pat_match[0].rm_so + 1, destlen)); } diff --git a/ncrypt/pgp.c b/ncrypt/pgp.c index 967916a35..8800db739 100644 --- a/ncrypt/pgp.c +++ b/ncrypt/pgp.c @@ -191,7 +191,7 @@ static int pgp_copy_checksig(FILE *fpin, FILE *fpout) { int rc = -1; - if (PgpGoodSign.pattern) + if (PgpGoodSign) { char *line = NULL; int lineno = 0; @@ -199,7 +199,7 @@ static int pgp_copy_checksig(FILE *fpin, FILE *fpout) while ((line = mutt_file_read_line(line, &linelen, fpin, &lineno, 0)) != NULL) { - if (regexec(PgpGoodSign.regex, line, 0, NULL, 0) == 0) + if (regexec(PgpGoodSign->regex, line, 0, NULL, 0) == 0) { mutt_debug(2, "\"%s\" matches regex.\n", line); rc = 0; @@ -235,7 +235,7 @@ static int pgp_check_decryption_okay(FILE *fpin) { int rc = -1; - if (PgpDecryptionOkay.pattern) + if (PgpDecryptionOkay) { char *line = NULL; int lineno = 0; @@ -243,7 +243,7 @@ static int pgp_check_decryption_okay(FILE *fpin) while ((line = mutt_file_read_line(line, &linelen, fpin, &lineno, 0)) != NULL) { - if (regexec(PgpDecryptionOkay.regex, line, 0, NULL, 0) == 0) + if (regexec(PgpDecryptionOkay->regex, line, 0, NULL, 0) == 0) { mutt_debug(2, "\"%s\" matches regex.\n", line); rc = 0; diff --git a/pager.c b/pager.c index 58524783e..673311a12 100644 --- a/pager.c +++ b/pager.c @@ -846,9 +846,9 @@ static void resolve_types(char *buf, char *raw, struct Line *line_info, int n, } else if (check_sig(buf, line_info, n - 1) == 0) line_info[n].type = MT_COLOR_SIGNATURE; - else if (regexec(QuoteRegexp.regex, buf, 1, pmatch, 0) == 0) + else if (QuoteRegexp && regexec(QuoteRegexp->regex, buf, 1, pmatch, 0) == 0) { - if ((regexec(Smileys.regex, buf, 1, smatch, 0) == 0)) + if (Smileys && (regexec(Smileys->regex, buf, 1, smatch, 0) == 0)) { if (smatch[0].rm_so > 0) { @@ -858,7 +858,7 @@ static void resolve_types(char *buf, char *raw, struct Line *line_info, int n, c = buf[smatch[0].rm_so]; buf[smatch[0].rm_so] = 0; - if (regexec(QuoteRegexp.regex, buf, 1, pmatch, 0) == 0) + if (QuoteRegexp && regexec(QuoteRegexp->regex, buf, 1, pmatch, 0) == 0) { if (q_classify && line_info[n].quote == NULL) line_info[n].quote = classify_quote(quote_list, buf + pmatch[0].rm_so, @@ -1490,7 +1490,7 @@ static int display_line(FILE *f, LOFF_T *last_pos, struct Line **line_info, (*last)--; goto out; } - if (regexec(QuoteRegexp.regex, (char *) fmt, 1, pmatch, 0) != 0) + if (QuoteRegexp && regexec(QuoteRegexp->regex, (char *) fmt, 1, pmatch, 0) != 0) goto out; (*line_info)[n].quote = classify_quote(quote_list, (char *) fmt + pmatch[0].rm_so, diff --git a/parse.c b/parse.c index 9485cb54e..fb4b86f21 100644 --- a/parse.c +++ b/parse.c @@ -1283,7 +1283,7 @@ struct Envelope *mutt_read_rfc822_header(FILE *f, struct Header *hdr, rfc2047_decode(&e->subject); - if (regexec(ReplyRegexp.regex, e->subject, 1, pmatch, 0) == 0) + if (ReplyRegexp && (regexec(ReplyRegexp->regex, e->subject, 1, pmatch, 0) == 0)) e->real_subj = e->subject + pmatch[0].rm_eo; else e->real_subj = e->subject; diff --git a/send.c b/send.c index 7531445a4..b05a5ec3c 100644 --- a/send.c +++ b/send.c @@ -1242,7 +1242,7 @@ static int is_reply(struct Header *reply, struct Header *orig) static int search_attach_keyword(char *filename) { /* Search for the regex in AttachKeyword within a file */ - if (!AttachKeyword.regex) + if (!AttachKeyword || !QuoteRegexp) return 0; FILE *attf = mutt_file_fopen(filename, "r"); @@ -1254,8 +1254,8 @@ static int search_attach_keyword(char *filename) while (!feof(attf)) { fgets(inputline, LONG_STRING, attf); - if (regexec(QuoteRegexp.regex, inputline, 0, NULL, 0) != 0 && - regexec(AttachKeyword.regex, inputline, 0, NULL, 0) == 0) + if (regexec(QuoteRegexp->regex, inputline, 0, NULL, 0) != 0 && + regexec(AttachKeyword->regex, inputline, 0, NULL, 0) == 0) { found = 1; break;