/* $Id$ */ /* * Cantus Tag Editor * Copyright © 2002-2004 by Samuel Abels * Copyright © 2007 by Tim Huetz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see **/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /****************************************************************************** * STATICS ******************************************************************************/ /* * Uppercase a string. */ static void strtoupper(char *str) { if (!str) return; while (*str != '\0') { if (isalpha(*str)) *str = toupper(*str); str++; } } /* * Replace "from" by "to". */ static void str_replace(char *str, const char *from, const char *to, int maxlen) { char *pstr = str; int fromlen = strlen(from); int tolen = strlen(to); while (*pstr != '\0' && pstr - str < maxlen) { if (strncmp(pstr, from, fromlen) != 0) { *pstr++; continue; } memmove(pstr + tolen, pstr + fromlen, maxlen - ((pstr + tolen) - str) - 1); memcpy(pstr, to, tolen); pstr += tolen; } } /****************************************************************************** * END STATICS ******************************************************************************/ /* * This function will compare a shell pattern with a string. * TRUE if match. Otherwise FALSE. */ short int shellpattern_match(const char *string, const char *pattern, short int casess) { char *stringcp = NULL; char *patterncp = NULL; short int match = FALSE; if (!pattern || !string) return(FALSE); /* Create a duplicate of the string. */ stringcp = strdup(string); patterncp = strdup(pattern); /* If we are case insensitive, uppercase those strings now. */ if (!casess) { strtoupper(stringcp); strtoupper(patterncp); } match = (fnmatch(patterncp, stringcp, 0) == 0); free(patterncp); free(stringcp); return(match); } /* * This function will compare a list of shell patterns with a string. * TRUE if any of them matches, otherwise FALSE. */ short int shellpattern_match_any(const char *string, const char *pattern[], short int casess) { int i = -1; while (pattern[++i]) { if (shellpattern_match(string, pattern[i], casess)) return(TRUE); } return(FALSE); } /* * This function will compare a shell pattern with a string and * return the embraced glob "(*)" match or NULL. */ short int shellpattern_match_grab(const char *string, const char *pattern, short int casess, char **match) { regex_t preg; /* Pre-compiled pattern buffer. */ int numoffsets = 50; regmatch_t pmatch[numoffsets]; /* Substring addresses, filled by regexec. */ char regexp[1024]; char *result = NULL; int flags = 0; /* Translate the pattern into a regular expression. */ strncpy(regexp, pattern, 1023); str_replace(regexp, ".", "\\.", 1023); str_replace(regexp, "*", ".*", 1023); str_replace(regexp, "(", "\\(", 1023); str_replace(regexp, ")", "\\)", 1023); str_replace(regexp, "?", ".", 1023); str_replace(regexp, "[!", "[^", 1023); /* Compile the regular expression. */ flags = REG_NEWLINE; if (!casess) flags |= REG_ICASE; if (regcomp(&preg, regexp, flags) != 0) { fprintf(stderr, "Error: RegExp compilation failed: \"%s\"\n", regexp); return(-1); } /* Execute the regular expression. */ if (regexec(&preg, string, numoffsets, pmatch, REG_NOTBOL | REG_NOTEOL) != 0) return(1); result = (char*)calloc(sizeof(char), (pmatch[1].rm_eo - pmatch[1].rm_so) + 2); memcpy(result, string + pmatch[1].rm_so, (pmatch[1].rm_eo - pmatch[1].rm_so)); *match = result; return(0); } /* * Determine whether the pattern can be successfully compiled. * Returns TRUE if the pattern is valid, otherwise FALSE. */ short int shellpattern_is_valid(const char *pattern) { regex_t preg; /* Pre-compiled pattern buffer. */ char regexp[1024]; /* Translate the pattern into a regular expression. */ strncpy(regexp, pattern, 1023); str_replace(regexp, "*", ".*", 1023); str_replace(regexp, "(", "\\(", 1023); str_replace(regexp, ")", "\\)", 1023); str_replace(regexp, "?", ".", 1023); str_replace(regexp, "[!", "[^", 1023); /* Compile the regular expression. */ if (regcomp(&preg, regexp, REG_NEWLINE) != 0) return(FALSE); return(TRUE); } /* * Returns zero if the regular expression matches the string. * Returns -1 if the expression can't be compiled. * Returns 1 if it doesn't match. */ short int regexp_match(const char *string, const char *regexp, short int casess) { regex_t preg; /* Pre-compiled pattern buffer. */ int flags = 0; /* Compile the regular expression. */ flags = REG_NEWLINE | REG_EXTENDED; if (!casess) flags |= REG_ICASE; if (regcomp(&preg, regexp, flags) != 0) return(-1); /* Execute the regular expression. */ if (regexec(&preg, string, 0, NULL, REG_NOTBOL | REG_NOTEOL) != 0) return(1); return(0); } /* * Determine whether the regexp can be successfully compiled. * Returns TRUE if the regexp is valid, otherwise FALSE. */ short int regexp_is_valid(const char *regexp) { regex_t preg; /* Pre-compiled pattern buffer. */ /* Compile the regular expression. */ if (regcomp(&preg, regexp, REG_NEWLINE | REG_EXTENDED) != 0) return(FALSE); return(TRUE); } #ifdef __cplusplus } #endif