From: epg@pretzelnet.org <> Date: Mon, 13 Jan 2014 06:56:18 +0000 (-0800) Subject: switch to regex.h X-Git-Url: https://diplodocus.org/git/flac-archive/commitdiff_plain/d90f13125178aee109dc251e3641c6086b444902?hp=2ad4f7ba7b34e3bbbdf4f1e1de18810d92cebd4b switch to regex.h --- diff --git a/id3v2-grep.cc b/id3v2-grep.cc index be463ce..549644e 100644 --- a/id3v2-grep.cc +++ b/id3v2-grep.cc @@ -1,4 +1,5 @@ extern "C" { +#include #include } @@ -24,12 +25,11 @@ static enum { PRINT_BOTH, PRINT_FILE, PRINT_MATCH, PRINT_NONE, PRINT_DEFAULT } print = PRINT_DEFAULT; static enum { GREP_BOTH, GREP_ID, GREP_TEXT } grep_frame = GREP_BOTH; -// TODO: use regexec(3) -static bool -grep(const string &pattern, TagLib::MPEG::File &file, const char *fn) +static int +grep(const regex_t ®ex, TagLib::MPEG::File &file, const char *fn) { if (!file.hasID3v2Tag()) { - return false; + return REG_NOMATCH; } bool found = false; for (const auto *frame : file.ID3v2Tag()->frameList()) { @@ -46,9 +46,13 @@ grep(const string &pattern, TagLib::MPEG::File &file, const char *fn) break; } const string &s = sstream.str(); - if (s.find(pattern, 0) == string::npos) { + int status = regexec(®ex, s.c_str(), 0, nullptr, 0); + if (status == REG_NOMATCH) { continue; } + if (status != 0) { + return status; + } found = true; if (print == PRINT_BOTH) { cout << fn << ":" << s << endl; @@ -59,18 +63,33 @@ grep(const string &pattern, TagLib::MPEG::File &file, const char *fn) if (found && print == PRINT_FILE) { cout << fn << endl; } - return found; + return found ? 0 : REG_NOMATCH; +} + +static void +regex_error(int status, const regex_t ®ex) +{ + char message[512]; + regerror(status, ®ex, message, sizeof(message)); + cerr << message << endl; } int main(int argc, char **argv) { - char *pattern_c = nullptr; + bool ignore_case = false, use_ere = false; + char *pattern = nullptr; int c; - while ((c = getopt(argc, argv, "e:HhlqsQ:")) != -1) { + while ((c = getopt(argc, argv, "Eie:HhlqsQ:")) != -1) { switch (c) { + case 'E': + use_ere = true; + break; + case 'i': + ignore_case = true; + break; case 'e': - pattern_c = optarg; + pattern = optarg; break; case 'H': print = PRINT_BOTH; @@ -105,15 +124,23 @@ main(int argc, char **argv) argc -= optind; argv += optind; // TODO: multiple patterns - if (pattern_c == nullptr) { + if (pattern == nullptr) { if (argc == 0) { cerr << "no pattern" << endl; return 2; } - pattern_c = *argv++; + pattern = *argv++; argc--; } - string pattern(pattern_c); + int cflags = REG_NOSUB; + if (ignore_case) cflags |= REG_ICASE; + if (use_ere) cflags |= REG_EXTENDED; + regex_t regex; + int status = regcomp(®ex, pattern, cflags); + if (status != 0) { + regex_error(status, regex); + return 3; + } if (print == PRINT_DEFAULT) { print = argc > 1 ? PRINT_BOTH : PRINT_MATCH; @@ -131,11 +158,17 @@ main(int argc, char **argv) bad_files++; continue; } - found |= grep(pattern, f, fn); + int status = grep(regex, f, fn); + if (status == 0) { + found = true; + } else if (status != REG_NOMATCH) { + regex_error(status, regex); + return 3; + } } if (bad_files > 0) { - return 3; + return 4; } if (found) { return 0;