libmp3splt
|
00001 /********************************************************** 00002 * 00003 * libmp3splt -- library based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright (c) 2010-2011 Alexandru Munteanu - io_fx@yahoo.fr 00007 * 00008 * http://mp3splt.sourceforge.net 00009 * 00010 *********************************************************/ 00011 00012 /********************************************************** 00013 * 00014 * This program is free software; you can redistribute it and/or 00015 * modify it under the terms of the GNU General Public License 00016 * as published by the Free Software Foundation; either version 2 00017 * of the License, or (at your option) any later version. 00018 * 00019 * This program is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License 00025 * along with this program; if not, write to the Free Software 00026 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 * 02111-1307, 00028 * USA. 00029 * 00030 *********************************************************/ 00031 00032 #ifndef NO_PCRE 00033 00034 #include <string.h> 00035 #include <pcre.h> 00036 00037 #include "splt.h" 00038 00039 static char *splt_fr_get_pattern(pcre *re, const char *filename, int *ovector, 00040 int rc, char *key); 00041 static void splt_fr_copy_pattern_to_tags(pcre *re, const char *filename, 00042 int *ovector, int rc, char *key, int tags_field, splt_tags *tags, 00043 int format, int replace_underscores, int *error); 00044 static int splt_fr_get_int_pattern(pcre *re, const char *filename, 00045 int *ovector, int rc, char *key); 00046 static void splt_fr_set_char_field_on_tags_and_convert(splt_tags *tags, 00047 int tags_field, char *pattern, int format, int replace_underscores, int *error); 00048 00054 splt_tags *splt_fr_parse_from_state(splt_state *state, int *error) 00055 { 00056 const char *filename_to_split = splt_t_get_filename_to_split(state); 00057 char *regex = splt_t_get_input_filename_regex(state); 00058 char *default_comment = splt_t_get_default_comment_tag(state); 00059 char *default_genre = splt_t_get_default_genre_tag(state); 00060 00061 char *filename = splt_su_get_fname_without_path_and_extension(filename_to_split, error); 00062 if (*error < 0) 00063 { 00064 return NULL; 00065 } 00066 00067 splt_tags *tags = splt_fr_parse(state, filename, regex, default_comment, default_genre, error); 00068 00069 if (filename) 00070 { 00071 free(filename); 00072 filename = NULL; 00073 } 00074 00075 return tags; 00076 } 00077 00078 splt_tags *splt_fr_parse(splt_state *state, const char *filename, const char *regex, 00079 const char *default_comment, const char *default_genre, int *error) 00080 { 00081 const char *errorbits; 00082 int erroroffset; 00083 00084 splt_d_print_debug(state, "filename for regex = _%s_\n", filename); 00085 splt_d_print_debug(state, "regex = _%s_\n", regex); 00086 00087 if (regex == NULL) 00088 { 00089 *error = SPLT_INVALID_REGEX; 00090 splt_e_set_error_data(state, _("no regular expression provided")); 00091 return NULL; 00092 } 00093 00094 pcre *re = pcre_compile(regex, PCRE_CASELESS | PCRE_UTF8, &errorbits, &erroroffset, NULL); 00095 if (!re) 00096 { 00097 *error = SPLT_INVALID_REGEX; 00098 char *message = splt_su_get_formatted_message(state, "@%u: %s", 00099 erroroffset, errorbits); 00100 splt_e_set_error_data(state, message); 00101 return NULL; 00102 } 00103 00104 int ovector[90] = {0,}; 00105 const size_t ovsize = sizeof(ovector)/sizeof(*ovector); 00106 00107 int rc = pcre_exec(re, NULL, filename, strlen(filename), 0, 0, ovector, ovsize); 00108 if (rc == PCRE_ERROR_NOMATCH) 00109 { 00110 *error = SPLT_REGEX_NO_MATCH; 00111 pcre_free(re); 00112 return NULL; 00113 } 00114 00115 splt_tags *tags = splt_tu_new_tags(state, error); 00116 if (*error < 0) 00117 { 00118 pcre_free(re); 00119 return NULL; 00120 } 00121 splt_tu_reset_tags(tags); 00122 00123 int replace_underscores = 00124 splt_o_get_int_option(state, SPLT_OPT_REPLACE_UNDERSCORES_TAG_FORMAT); 00125 00126 int format = splt_o_get_int_option(state, SPLT_OPT_ARTIST_TAG_FORMAT); 00127 splt_fr_copy_pattern_to_tags(re, filename, ovector, rc, "artist", 00128 SPLT_TAGS_ARTIST, tags, format, replace_underscores, error); 00129 if (*error < 0) { goto error; } 00130 00131 format = splt_o_get_int_option(state, SPLT_OPT_ALBUM_TAG_FORMAT); 00132 splt_fr_copy_pattern_to_tags(re, filename, ovector, rc, "album", 00133 SPLT_TAGS_ALBUM, tags, format, replace_underscores, error); 00134 if (*error < 0) { goto error; } 00135 00136 splt_fr_copy_pattern_to_tags(re, filename, ovector, rc, "year", 00137 SPLT_TAGS_YEAR, tags, SPLT_NO_CONVERSION, SPLT_FALSE, error); 00138 if (*error < 0) { goto error; } 00139 00140 char *pattern = NULL; 00141 format = splt_o_get_int_option(state, SPLT_OPT_COMMENT_TAG_FORMAT); 00142 pattern = splt_fr_get_pattern(re, filename, ovector, rc, "comment"); 00143 if (pattern) 00144 { 00145 splt_fr_set_char_field_on_tags_and_convert(tags, SPLT_TAGS_COMMENT, 00146 pattern, format, replace_underscores, error); 00147 pcre_free_substring(pattern); 00148 if (*error < 0) { goto error; } 00149 } 00150 else 00151 { 00152 splt_tu_set_field_on_tags(tags, SPLT_TAGS_COMMENT, default_comment); 00153 } 00154 00155 int track = splt_fr_get_int_pattern(re, filename, ovector, rc, "tracknum"); 00156 if (track != -1) 00157 { 00158 splt_tu_set_field_on_tags(tags, SPLT_TAGS_TRACK, &track); 00159 } 00160 00161 //TODO: total tracks support 00162 int total_tracks = splt_fr_get_int_pattern(re, filename, ovector, rc, "tracks"); 00163 00164 format = splt_o_get_int_option(state, SPLT_OPT_TITLE_TAG_FORMAT); 00165 char *title = splt_fr_get_pattern(re, filename, ovector, rc, "title"); 00166 if (title) 00167 { 00168 splt_fr_set_char_field_on_tags_and_convert(tags, SPLT_TAGS_TITLE, 00169 title, format, replace_underscores, error); 00170 pcre_free_substring(title); 00171 if (*error < 0) { goto error; } 00172 } 00173 else 00174 { 00175 if (track != -1 && total_tracks != -1) 00176 { 00177 title = splt_su_get_formatted_message(state, "Track %d of %d", track, total_tracks); 00178 } 00179 else if (track != -1 && total_tracks == -1) 00180 { 00181 title = splt_su_get_formatted_message(state, "Track %d", track); 00182 } 00183 00184 if (title) 00185 { 00186 splt_fr_set_char_field_on_tags_and_convert(tags, SPLT_TAGS_TITLE, title, 00187 SPLT_NO_CONVERSION, SPLT_FALSE, error); 00188 00189 free(title); 00190 title = NULL; 00191 00192 if (*error < 0) { goto error; } 00193 } 00194 } 00195 00196 char *genre = splt_fr_get_pattern(re, filename, ovector, rc, "genre"); 00197 if (genre) 00198 { 00199 splt_tu_set_field_on_tags(tags, SPLT_TAGS_GENRE, genre); 00200 pcre_free_substring(genre); 00201 if (*error < 0) { goto error; } 00202 } 00203 else 00204 { 00205 splt_tu_set_field_on_tags(tags, SPLT_TAGS_GENRE, default_genre); 00206 } 00207 00208 pcre_free(re); 00209 00210 *error = SPLT_REGEX_OK; 00211 00212 return tags; 00213 00214 error: 00215 pcre_free(re); 00216 splt_tu_free_one_tags(&tags); 00217 return NULL; 00218 } 00219 00220 static void splt_fr_copy_pattern_to_tags(pcre *re, const char *filename, 00221 int *ovector, int rc, char *key, int tags_field, splt_tags *tags, 00222 int format, int replace_underscores, int *error) 00223 { 00224 char *pattern = NULL; 00225 pattern = splt_fr_get_pattern(re, filename, ovector, rc, key); 00226 00227 splt_fr_set_char_field_on_tags_and_convert(tags, tags_field, pattern, 00228 format, replace_underscores, error); 00229 00230 if (pattern) 00231 { 00232 pcre_free_substring(pattern); 00233 } 00234 } 00235 00236 static int splt_fr_get_int_pattern(pcre *re, const char *filename, 00237 int *ovector, int rc, char *key) 00238 { 00239 int value = -1; 00240 00241 char *pattern = NULL; 00242 pattern = splt_fr_get_pattern(re, filename, ovector, rc, key); 00243 if (pattern) 00244 { 00245 value = atoi(pattern); 00246 pcre_free_substring(pattern); 00247 } 00248 00249 return value; 00250 } 00251 00252 static char *splt_fr_get_pattern(pcre *re, const char *filename, int *ovector, 00253 int rc, char *key) 00254 { 00255 char *pattern = NULL; 00256 00257 if (pcre_get_named_substring(re, filename, ovector, rc, key, 00258 (const char**)&pattern) == PCRE_ERROR_NOSUBSTRING) 00259 { 00260 return NULL; 00261 } 00262 else 00263 { 00264 return pattern; 00265 } 00266 } 00267 00268 static void splt_fr_set_char_field_on_tags_and_convert(splt_tags *tags, 00269 int tags_field, char *pattern, int format, int replace_underscores, int *error) 00270 { 00271 if (replace_underscores) 00272 { 00273 splt_su_replace_all_char(pattern, '_', ' '); 00274 } 00275 00276 char *converted_pattern = splt_su_convert(pattern, format, error); 00277 if (*error < 0) { return; } 00278 00279 splt_tu_set_field_on_tags(tags, tags_field, converted_pattern); 00280 00281 if (converted_pattern) 00282 { 00283 free(converted_pattern); 00284 converted_pattern = NULL; 00285 } 00286 } 00287 00288 #endif 00289