1 /*********************************************************
2  *
3  * libmp3splt -- library based on mp3splt,
4  *               for mp3/ogg splitting without decoding
5  *
6  * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
7  * Copyright (c) 2005-2014 Alexandru Munteanu - m@ioalex.net
8  *
9  * http://mp3splt.sourceforge.net
10  *
11  *********************************************************/
12 
13 /**********************************************************
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
28  * USA.
29  *
30  *********************************************************/
31 
32 /*! \file
33 
34   Parse tags (Artist, Album, Year,...)
35  */
36 #include <string.h>
37 #include <ctype.h>
38 
39 #include "splt.h"
40 
41 static void splt_tp_process_tags(const char *tags,
42     tags_parser_utils *tpu, splt_state *state, int *error);
43 static void splt_tp_process_tag_variable(const char *tag_variable_start, const char *end_paranthesis,
44     tags_parser_utils *tpu, splt_state *state, int *error);
45 static void splt_tp_process_str_tags_variable(const char *tag_variable_start,
46     const char *end_paranthesis, int tags_field,
47     tags_parser_utils *tpu, splt_state *state, int *error);
48 static void splt_tp_process_tracknumber_variable(const char *tag_variable_start,
49     const char *end_paranthesis, tags_parser_utils *tpu, splt_state *state,
50     int *error);
51 static void splt_tp_process_auto_increment_tracknumber_variable(
52     const char *tag_variable_start, const char *end_paranthesis,
53     tags_parser_utils *tpu, splt_state *state, int *error);
54 
55 static void splt_tp_check_ambigous_next_position(const char *tag_variable_start,
56     tags_parser_utils *tpu);
57 static void splt_tp_process_original_tags_variable(tags_parser_utils *tpu,
58     splt_state *state, int *error, int set_original_tags);
59 static void splt_tp_get_original_tags_and_append(splt_state *state, int *error);
60 static int splt_tp_tpu_has_one_current_tag_set(tags_parser_utils *tpu);
61 static char *splt_tp_look_for_end_paranthesis(tags_parser_utils *tpu);
62 static void splt_tp_look_for_all_tags_char(const char *tags,
63 tags_parser_utils *tpu, splt_state *state);
64 static void splt_tp_tpu_increment_tags_field_counter(tags_parser_utils *tpu,
65     int tags_field);
66 
67 static tags_parser_utils *splt_tp_tpu_new(splt_state *state, int *error);
68 static void splt_tp_tpu_reset_for_new_tags(splt_state *state, tags_parser_utils *tpu, int *error);
69 static void splt_tp_tpu_free(tags_parser_utils **tpu);
70 static void splt_tp_tpu_set_tracknumber(tags_parser_utils *tpu,
71     const char *tracknumber, int *error);
72 static const char *splt_tp_tpu_get_tracknumber(tags_parser_utils *tpu);
73 static void splt_tp_tpu_set_tags_value(tags_parser_utils *tpu,
74     int tags_field, const void *tag_value);
75 static void splt_tp_set_track_from_parsed_tracknumber(tags_parser_utils *tpu,
76     splt_state *state, int *error);
77 
splt_tp_put_tags_from_filename(splt_state * state,int * error)78 void splt_tp_put_tags_from_filename(splt_state *state, int *error)
79 {
80 #ifndef NO_PCRE
81   splt_tags *tags = splt_fr_parse_from_state(state, error);
82   if (*error < 0) { return; }
83 
84   char *tags_format = splt_su_get_formatted_message(state,
85       "%%[@o,@a=%s,@b=%s,@t=%s,@y=%s,@c=%s,@n=%d,@g=%s]",
86       tags->artist,
87       tags->album,
88       tags->title,
89       tags->year,
90       tags->comment,
91       tags->track,
92       tags->genre);
93 
94   if (tags_format == NULL)
95   {
96     *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
97     splt_tu_free_one_tags(&tags);
98     return;
99   }
100 
101   splt_tp_put_tags_from_string(state, tags_format, error);
102   free(tags_format);
103 
104   splt_tu_free_one_tags(&tags);
105 #else
106   splt_c_put_warning_message_to_client(state,
107       _(" warning: cannot set tags from filename regular expression - compiled without pcre support\n"));
108 #endif
109 }
110 
splt_tp_parse_tag_word(const char * cur_pos,const char * end_paranthesis,int * ambiguous,int * error)111 static char *splt_tp_parse_tag_word(const char *cur_pos,
112     const char *end_paranthesis, int *ambiguous, int *error)
113 {
114   char *word = NULL;
115   char *word_end = NULL;
116   char *word_end2 = NULL;
117   const char *equal_sign = NULL;
118 
119   if ((word_end = strchr(cur_pos,',')))
120   {
121     if ((word_end2 = strchr(cur_pos,']')) < word_end)
122     {
123       word_end = word_end2;
124       if ((strchr(word_end+1,']') && !strchr(word_end+1,'['))
125           || (strchr(word_end+1,']') < strchr(word_end+1,'[')))
126       {
127         *ambiguous = SPLT_TRUE;
128       }
129     }
130 
131     if (*word_end == ',')
132     {
133       if (*(word_end+1) != '@')
134       {
135         *ambiguous = SPLT_TRUE;
136       }
137     }
138   }
139   else
140   {
141     word_end = strchr(cur_pos,']');
142   }
143 
144   if (word_end <= end_paranthesis)
145   {
146     if (*(cur_pos+1) == '=')
147     {
148       equal_sign = cur_pos+1;
149       int string_length = word_end-(equal_sign+1);
150       if (string_length > 0)
151       {
152         word = malloc((string_length+1)*sizeof(char));
153         memset(word,'\0',(string_length+1)*sizeof(char));
154         if (word)
155         {
156           memcpy(word,equal_sign+1,string_length);
157           word[string_length] = '\0';
158         }
159         else
160         {
161           *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
162           return NULL;
163         }
164       }
165       else
166       {
167         *ambiguous = SPLT_TRUE;
168       }
169     }
170     else
171     {
172       *ambiguous = SPLT_TRUE;
173     }
174   }
175 
176   return word;
177 }
178 
splt_tp_put_tags_from_string(splt_state * state,const char * tags,int * error)179 int splt_tp_put_tags_from_string(splt_state *state, const char *tags, int *error)
180 {
181   if (tags == NULL)
182   {
183     return SPLT_FALSE;
184   }
185 
186   tags_parser_utils *tpu = splt_tp_tpu_new(state, error);
187   if (*error < 0) { goto end; }
188 
189   tpu->position = tags;
190   while ((tpu->position = strchr(tpu->position, '[')))
191   {
192     splt_tp_process_tags(tags, tpu, state, error);
193     if (*error < 0) { goto end; }
194 
195     splt_tu_append_tags_to_state(state, tpu->current_tags,
196         !tpu->original_tags_found, tpu->original_tags_value, SPLT_FALSE, error);
197     if (*error < 0) { goto end; }
198 
199     if (tpu->set_all_tags)
200     {
201       tpu->we_had_all_tags = SPLT_TRUE;
202       tpu->set_all_tags = SPLT_FALSE;
203       splt_tu_copy_tags(tpu->all_tags, splt_tu_get_tags_like_x(state), error);
204       if (*error < 0) { goto end; }
205     }
206     else if (tpu->we_had_all_tags && !tpu->original_tags_found)
207     {
208       int real_tags_number = 0;
209       if (state->split.tags_group)
210       {
211         real_tags_number = state->split.tags_group->real_tagsnumber;
212       }
213 
214       int index = real_tags_number - 1;
215       splt_tu_set_new_tags_where_current_tags_are_null(state,
216           tpu->current_tags, tpu->all_tags, index, error);
217       if (*error < 0) { goto end; }
218     }
219 
220     tpu->tags_counter++;
221   }
222 
223 end:
224   ;
225   int ambigous = tpu->ambigous;
226   splt_tp_tpu_free(&tpu);
227 
228   return ambigous;
229 }
230 
splt_tp_tpu_set_ambigous_if_more_than_one_variable(tags_parser_utils * tpu)231 static void splt_tp_tpu_set_ambigous_if_more_than_one_variable(tags_parser_utils *tpu)
232 {
233   if ((tpu->title_counter > 1) ||
234       (tpu->artist_counter > 1) ||
235       (tpu->album_counter > 1) ||
236       (tpu->performer_counter > 1) ||
237       (tpu->year_counter > 1) ||
238       (tpu->comment_counter > 1) ||
239       (tpu->tracknumber_counter > 1) ||
240       (tpu->genre_counter > 1))
241   {
242     tpu->ambigous = SPLT_TRUE;
243   }
244 }
245 
splt_tp_find_tag_start(const char * position,const char * end_paranthesis)246 static char *splt_tp_find_tag_start(const char *position, const char *end_paranthesis)
247 {
248   const char *ptr = position;
249 
250   int comma_or_open_bracket_found = SPLT_FALSE;
251 
252   while (ptr <= end_paranthesis)
253   {
254     if (*ptr == ',' || *ptr == '[')
255     {
256       comma_or_open_bracket_found = SPLT_TRUE;
257       break;
258     }
259     ptr++;
260   }
261 
262   if (!comma_or_open_bracket_found)
263   {
264     return NULL;
265   }
266 
267   return strchr(ptr, '@');
268 }
269 
splt_tp_process_tags(const char * tags,tags_parser_utils * tpu,splt_state * state,int * error)270 static void splt_tp_process_tags(const char *tags, tags_parser_utils *tpu,
271     splt_state *state, int *error)
272 {
273   splt_tp_look_for_all_tags_char(tags, tpu, state);
274 
275   splt_tp_tpu_reset_for_new_tags(state, tpu, error);
276   if (*error < 0) { return; }
277 
278   const char *end_paranthesis = splt_tp_look_for_end_paranthesis(tpu);
279   if (!end_paranthesis) { return; }
280 
281   tpu->position++;
282 
283   char *tag_start = NULL;
284   while ((tag_start = splt_tp_find_tag_start(tpu->position-1, end_paranthesis)))
285   {
286     if (tag_start >= end_paranthesis)
287     {
288       break;
289     }
290 
291     tpu->position = tag_start + 1;
292 
293     splt_tp_process_tag_variable(tpu->position, end_paranthesis, tpu, state, error);
294     if (*error < 0)
295     {
296       return;
297     }
298 
299     if (tpu->position == tag_start + 1)
300     {
301       tpu->position++;
302     }
303   }
304 
305   splt_tp_set_track_from_parsed_tracknumber(tpu, state, error);
306 
307   splt_tp_tpu_set_ambigous_if_more_than_one_variable(tpu);
308 }
309 
splt_tp_set_track_from_parsed_tracknumber(tags_parser_utils * tpu,splt_state * state,int * error)310 static void splt_tp_set_track_from_parsed_tracknumber(tags_parser_utils *tpu,
311     splt_state *state, int *error)
312 {
313   const char *tracknumber = splt_tp_tpu_get_tracknumber(tpu);
314 
315   if (tracknumber != NULL && strcmp(tracknumber, "-2") == 0)
316   {
317     int track = -2;
318     splt_tp_tpu_set_tags_value(tpu, SPLT_TAGS_TRACK, &track);
319     return;
320   }
321 
322   if (tracknumber)
323   {
324     int is_number = SPLT_TRUE;
325     int i = 0;
326     for (i = 0;i < strlen(tracknumber);i++)
327     {
328       if (!isdigit(tracknumber[i]))
329       {
330         is_number = SPLT_FALSE;
331         tpu->ambigous = SPLT_TRUE;
332       }
333     }
334 
335     int track = 1;
336     if (is_number)
337     {
338       track = atoi(tracknumber);
339     }
340 
341     splt_tp_tpu_set_tags_value(tpu, SPLT_TAGS_TRACK, &track);
342   }
343   else if (tpu->auto_increment_tracknumber)
344   {
345     splt_tags last_tags = splt_tu_get_last_tags(state);
346     int track = last_tags.track + 1;
347     splt_tp_tpu_set_tags_value(tpu, SPLT_TAGS_TRACK, &track);
348   }
349 }
350 
splt_tp_process_tag_variable(const char * tag_variable_start,const char * end_paranthesis,tags_parser_utils * tpu,splt_state * state,int * error)351 static void splt_tp_process_tag_variable(const char *tag_variable_start,
352     const char *end_paranthesis, tags_parser_utils *tpu, splt_state *state,
353     int *error)
354 {
355   char tag_variable = *tag_variable_start;
356   switch (tag_variable)
357   {
358     case 'o':
359       splt_tp_process_original_tags_variable(tpu, state, error, SPLT_TRUE);
360       if (*error < 0) { return; }
361       break;
362     case 'O':
363       splt_tp_process_original_tags_variable(tpu, state, error, SAME_BYTES_AS_TAGS);
364       if (*error < 0) { return; }
365       break;
366     case 'a':
367       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
368           SPLT_TAGS_ARTIST, tpu, state, error);
369       break;
370     case 'p':
371       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
372           SPLT_TAGS_PERFORMER, tpu, state, error);
373       break;
374     case 'b':
375       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
376           SPLT_TAGS_ALBUM, tpu, state, error);
377       break;
378     case 't':
379       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
380           SPLT_TAGS_TITLE, tpu, state, error);
381       break;
382     case 'c':
383       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
384           SPLT_TAGS_COMMENT, tpu, state, error);
385       break;
386     case 'g':
387       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
388           SPLT_TAGS_GENRE, tpu, state, error);
389       break;
390     case 'y':
391       splt_tp_process_str_tags_variable(tag_variable_start, end_paranthesis,
392           SPLT_TAGS_YEAR, tpu, state, error);
393       break;
394     case 'n':
395       splt_tp_process_tracknumber_variable(tag_variable_start,
396           end_paranthesis, tpu, state, error);
397       break;
398     case 'N':
399       splt_tp_process_auto_increment_tracknumber_variable(tag_variable_start,
400           end_paranthesis, tpu, state, error);
401       break;
402     default:
403       tpu->ambigous = SPLT_TRUE;
404       break;
405   }
406 
407   splt_tp_check_ambigous_next_position(tag_variable_start, tpu);
408 }
409 
splt_tp_process_tracknumber_variable(const char * tag_variable_start,const char * end_paranthesis,tags_parser_utils * tpu,splt_state * state,int * error)410 static void splt_tp_process_tracknumber_variable(const char *tag_variable_start,
411     const char *end_paranthesis, tags_parser_utils *tpu, splt_state *state,
412     int *error)
413 {
414   char *tag_value = splt_tp_parse_tag_word(tag_variable_start, end_paranthesis,
415       &tpu->ambigous, error);
416   if (*error < 0) { return; }
417 
418   if (tag_value)
419   {
420     tpu->position += strlen(tag_value) + 1;
421     splt_tp_tpu_increment_tags_field_counter(tpu, SPLT_TAGS_TRACK);
422     splt_tp_tpu_set_tracknumber(tpu, tag_value, error);
423     if (*error < 0) { return; }
424 
425     free(tag_value);
426     tag_value = NULL;
427   }
428 }
429 
splt_tp_process_auto_increment_tracknumber_variable(const char * tag_variable_start,const char * end_paranthesis,tags_parser_utils * tpu,splt_state * state,int * error)430 static void splt_tp_process_auto_increment_tracknumber_variable(
431     const char *tag_variable_start, const char *end_paranthesis,
432     tags_parser_utils *tpu, splt_state *state, int *error)
433 {
434   char *tag_value = splt_tp_parse_tag_word(tag_variable_start, end_paranthesis,
435       &tpu->ambigous, error);
436   if (*error < 0) { return; }
437 
438   splt_o_set_int_option(state, SPLT_OPT_AUTO_INCREMENT_TRACKNUMBER_TAGS, SPLT_TRUE);
439 
440   if (tag_value)
441   {
442     tpu->position += strlen(tag_value) + 1;
443     splt_tp_tpu_set_tracknumber(tpu, tag_value, error);
444     if (*error < 0) { return; }
445 
446     free(tag_value);
447     tag_value = NULL;
448   }
449 
450   if (tpu->set_all_tags)
451   {
452     tpu->auto_increment_tracknumber = SPLT_TRUE;
453   }
454 }
455 
splt_tp_tpu_get_tracknumber(tags_parser_utils * tpu)456 static const char *splt_tp_tpu_get_tracknumber(tags_parser_utils *tpu)
457 {
458   return tpu->current_tracknumber;
459 }
460 
splt_tp_tpu_set_tracknumber(tags_parser_utils * tpu,const char * tracknumber,int * error)461 static void splt_tp_tpu_set_tracknumber(tags_parser_utils *tpu,
462     const char *tracknumber, int *error)
463 {
464   int err = splt_su_copy(tracknumber, &tpu->current_tracknumber);
465   if (err < 0) { *error = err; return; }
466 }
467 
splt_tp_process_str_tags_variable(const char * tag_variable_start,const char * end_paranthesis,int tags_field,tags_parser_utils * tpu,splt_state * state,int * error)468 static void splt_tp_process_str_tags_variable(const char *tag_variable_start,
469     const char *end_paranthesis, int tags_field,
470     tags_parser_utils *tpu, splt_state *state, int *error)
471 {
472   char *tag_value = splt_tp_parse_tag_word(tag_variable_start, end_paranthesis,
473       &tpu->ambigous, error);
474   if (*error < 0) { return; }
475 
476   if (tag_value)
477   {
478     splt_tp_tpu_set_tags_value(tpu, tags_field, tag_value);
479 
480     tpu->position += strlen(tag_value) + 1;
481     splt_tp_tpu_increment_tags_field_counter(tpu, tags_field);
482 
483     free(tag_value);
484     tag_value = NULL;
485   }
486 }
487 
splt_tp_check_ambigous_next_position(const char * tag_variable_start,tags_parser_utils * tpu)488 static void splt_tp_check_ambigous_next_position(const char *tag_variable_start,
489     tags_parser_utils *tpu)
490 {
491   char next_position = *(tpu->position+1);
492   if ((next_position != ',') &&
493       (next_position != ']'))
494   {
495     tpu->ambigous = SPLT_TRUE;
496   }
497 }
498 
splt_tp_process_original_tags_variable(tags_parser_utils * tpu,splt_state * state,int * error,int set_original_tags)499 static void splt_tp_process_original_tags_variable(tags_parser_utils *tpu,
500     splt_state *state, int *error, int set_original_tags)
501 {
502   if (tpu->original_tags_found)
503   {
504     tpu->ambigous = SPLT_TRUE;
505   }
506 
507   if (splt_io_input_is_stdin(state))
508   {
509     return;
510   }
511 
512   splt_o_lock_messages(state);
513 
514   splt_tp_get_original_tags_and_append(state, error);
515   if (*error < 0) { goto end; }
516 
517   splt_tags appended_tags = splt_tu_get_last_tags(state);
518   splt_tu_set_field_on_tags(&appended_tags, SPLT_TAGS_ORIGINAL, &set_original_tags);
519 
520   if (tpu->set_all_tags)
521   {
522     splt_tu_copy_tags(&appended_tags, tpu->all_tags, error);
523     if (*error < 0) { goto end; }
524   }
525 
526   tpu->original_tags_found = SPLT_TRUE;
527   tpu->original_tags_value = set_original_tags;
528 
529   if (splt_tp_tpu_has_one_current_tag_set(tpu))
530   {
531     tpu->ambigous = SPLT_TRUE;
532   }
533 
534 end:
535   splt_o_unlock_messages(state);
536 }
537 
splt_tp_get_original_tags_and_append(splt_state * state,int * error)538 static void splt_tp_get_original_tags_and_append(splt_state *state, int *error)
539 {
540   splt_check_file_type_and_set_plugin(state, SPLT_FALSE, SPLT_FALSE, error);
541   if (*error < 0) { return; }
542 
543   splt_o_lock_messages(state);
544 
545   splt_p_init(state, error);
546   if (*error < 0) { return; }
547 
548   splt_tu_get_original_tags(state, error);
549 
550   int err = splt_tu_append_original_tags(state);
551   if (err < 0) { *error = err; }
552 
553   splt_p_end(state, error);
554 
555   return;
556 }
557 
splt_tp_look_for_end_paranthesis(tags_parser_utils * tpu)558 static char *splt_tp_look_for_end_paranthesis(tags_parser_utils *tpu)
559 {
560   char *end_paranthesis = strchr(tpu->position,']');
561   if (!end_paranthesis)
562   {
563     tpu->ambigous = SPLT_TRUE;
564   }
565   else
566   {
567     char after_end_paranthesis = *(end_paranthesis+1);
568     if ((after_end_paranthesis != '[') &&
569         (after_end_paranthesis != '%') &&
570         (after_end_paranthesis != '\0'))
571     {
572       tpu->ambigous = SPLT_TRUE;
573     }
574   }
575 
576   return end_paranthesis;
577 }
578 
splt_tp_look_for_all_tags_char(const char * tags,tags_parser_utils * tpu,splt_state * state)579 static void splt_tp_look_for_all_tags_char(const char *tags,
580     tags_parser_utils *tpu, splt_state *state)
581 {
582   if ((tpu->position != tags) && (*(tpu->position-1) == '%'))
583   {
584     splt_o_set_int_option(state,
585         SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X, tpu->tags_counter);
586     tpu->set_all_tags = SPLT_TRUE;
587 
588     splt_tu_free_one_tags_content(tpu->all_tags);
589   }
590 }
591 
splt_tp_tpu_new(splt_state * state,int * error)592 static tags_parser_utils *splt_tp_tpu_new(splt_state *state, int *error)
593 {
594   tags_parser_utils *tpu = NULL;
595 
596   tpu = malloc(sizeof(tags_parser_utils));
597   if (tpu == NULL)
598   {
599     goto mem_error;
600   }
601 
602   tpu->ambigous = SPLT_FALSE;
603   tpu->tags_counter = 0;
604   tpu->set_all_tags = SPLT_FALSE;
605   tpu->we_had_all_tags = SPLT_FALSE;
606 
607   tpu->all_tags = splt_tu_new_tags(error);
608   if (*error < 0) { goto mem_error; }
609 
610   tpu->current_tags = splt_tu_new_tags(error);
611   if (*error < 0) { goto mem_error; }
612 
613   tpu->current_tracknumber = NULL;
614 
615   splt_tp_tpu_reset_for_new_tags(state, tpu, error);
616   if (*error < 0) { goto mem_error; }
617 
618   tpu->auto_increment_tracknumber = SPLT_FALSE;
619 
620   tpu->position = NULL;
621 
622   return tpu;
623 
624 mem_error:
625   splt_tp_tpu_free(&tpu);
626   return NULL;
627 }
628 
splt_tp_tpu_reset_for_new_tags(splt_state * state,tags_parser_utils * tpu,int * error)629 static void splt_tp_tpu_reset_for_new_tags(splt_state *state, tags_parser_utils *tpu, int *error)
630 {
631   tpu->title_counter = 0;
632   tpu->artist_counter = 0;
633   tpu->album_counter = 0;
634   tpu->performer_counter = 0;
635   tpu->year_counter = 0;
636   tpu->comment_counter = 0;
637   tpu->tracknumber_counter = 0;
638   tpu->genre_counter = 0;
639 
640   splt_tu_free_one_tags_content(tpu->current_tags);
641 
642   tpu->original_tags_found = SPLT_FALSE;
643   tpu->original_tags_value = SPLT_FALSE;
644 
645   if (tpu->current_tracknumber)
646   {
647     free(tpu->current_tracknumber);
648     tpu->current_tracknumber = NULL;
649   }
650 }
651 
splt_tp_tpu_increment_tags_field_counter(tags_parser_utils * tpu,int tags_field)652 static void splt_tp_tpu_increment_tags_field_counter(tags_parser_utils *tpu,
653     int tags_field)
654 {
655   switch(tags_field)
656   {
657     case SPLT_TAGS_TITLE:
658       tpu->title_counter++;
659       break;
660     case SPLT_TAGS_ARTIST:
661       tpu->artist_counter++;
662       break;
663     case SPLT_TAGS_ALBUM:
664       tpu->album_counter++;
665       break;
666     case SPLT_TAGS_YEAR:
667       tpu->year_counter++;
668       break;
669     case SPLT_TAGS_COMMENT:
670       tpu->comment_counter++;
671       break;
672     case SPLT_TAGS_PERFORMER:
673       tpu->performer_counter++;
674       break;
675     case SPLT_TAGS_TRACK:
676       tpu->tracknumber_counter++;
677       break;
678     case SPLT_TAGS_VERSION:
679       ;
680       break;
681     case SPLT_TAGS_GENRE:
682       tpu->genre_counter++;
683       ;
684       break;
685   }
686 }
687 
splt_tp_tpu_set_all_tags_field(tags_parser_utils * tpu,int tags_field,const void * tag_value)688 static void splt_tp_tpu_set_all_tags_field(tags_parser_utils *tpu,
689     int tags_field, const void *tag_value)
690 {
691   if (tpu->set_all_tags)
692   {
693     splt_tu_set_field_on_tags(tpu->all_tags, tags_field, tag_value);
694   }
695 }
696 
splt_tp_tpu_set_current_tags_field(tags_parser_utils * tpu,int tags_field,const void * tag_value)697 static void splt_tp_tpu_set_current_tags_field(tags_parser_utils *tpu,
698     int tags_field, const void *tag_value)
699 {
700   splt_tu_set_field_on_tags(tpu->current_tags, tags_field, tag_value);
701 }
702 
splt_tp_tpu_set_tags_value(tags_parser_utils * tpu,int tags_field,const void * tag_value)703 static void splt_tp_tpu_set_tags_value(tags_parser_utils *tpu,
704     int tags_field, const void *tag_value)
705 {
706   splt_tp_tpu_set_all_tags_field(tpu, tags_field, tag_value);
707   splt_tp_tpu_set_current_tags_field(tpu, tags_field, tag_value);
708 }
709 
splt_tp_tpu_free(tags_parser_utils ** tpu)710 static void splt_tp_tpu_free(tags_parser_utils **tpu)
711 {
712   if (!tpu || !*tpu)
713   {
714     return;
715   }
716 
717   splt_tu_free_one_tags(&(*tpu)->current_tags);
718   splt_tu_free_one_tags(&(*tpu)->all_tags);
719 
720   if ((*tpu)->current_tracknumber)
721   {
722     free((*tpu)->current_tracknumber);
723     (*tpu)->current_tracknumber = NULL;
724   }
725 
726   free(*tpu);
727   *tpu = NULL;
728 }
729 
splt_tp_tpu_has_one_current_tag_set(tags_parser_utils * tpu)730 static int splt_tp_tpu_has_one_current_tag_set(tags_parser_utils *tpu)
731 {
732   return splt_tu_has_one_tag_set(tpu->current_tags);
733 }
734 
735