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  *********************************************************/
10 
11 /**********************************************************
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25  * USA.
26  *********************************************************/
27 
28 #include <string.h>
29 
30 #include "splt.h"
31 #include "tags_utils.h"
32 
33 static void splt_tu_copy_tags_without_original_and_version(splt_tags *from, splt_tags *to,
34     int *error);
35 
splt_tu_free_original_tags(splt_state * state)36 void splt_tu_free_original_tags(splt_state *state)
37 {
38   splt_tags *tags = &state->original_tags.tags;
39   splt_tu_free_one_tags_content(tags);
40   int err = SPLT_OK;
41   splt_p_clear_original_tags(state, &err);
42 }
43 
splt_tu_get_tags_group(splt_state * state)44 splt_tags_group *splt_tu_get_tags_group(splt_state *state)
45 {
46   return state->split.tags_group;
47 }
48 
splt_tu_duplicate_tags(splt_state * state,splt_code * error,int * tags_number)49 static splt_tags *splt_tu_duplicate_tags(splt_state *state, splt_code *error, int *tags_number)
50 {
51   *tags_number = 0;
52 
53   if (state->split.tags_group == NULL) { return NULL; }
54 
55   int total_tags = state->split.tags_group->real_tagsnumber;
56   if (total_tags == 0) { return NULL; }
57 
58   splt_tags *tags = malloc(sizeof(splt_tags) * total_tags);
59   if (tags == NULL)
60   {
61     *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
62     return NULL;
63   }
64 
65   int i = 0;
66   for (i = 0;i < total_tags;i++)
67   {
68     splt_tu_reset_tags(&tags[i]);
69     splt_tu_copy_tags(&state->split.tags_group->tags[i], &tags[i], error);
70     (*tags_number)++;
71 
72     if (*error < 0)
73     {
74       int j = 0;
75       for (j = 0; i < i; j++) { splt_tu_free_one_tags_content(&tags[i]); }
76       *tags_number = 0;
77       return NULL;
78     }
79   }
80 
81   return tags;
82 }
83 
splt_tu_auto_increment_tracknumber(splt_state * state)84 void splt_tu_auto_increment_tracknumber(splt_state *state)
85 {
86   int current_split = splt_t_get_current_split_file_number(state) - 1;
87   int old_current_split = current_split;
88 
89   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
90   if (remaining_tags_like_x == -1)
91   {
92     return;
93   }
94 
95   int real_tags_number = 0;
96   if (state->split.tags_group)
97   {
98     real_tags_number = state->split.tags_group->real_tagsnumber;
99   }
100 
101   if (current_split >= real_tags_number)
102   {
103     current_split = remaining_tags_like_x;
104   }
105 
106   if (splt_o_get_int_option(state, SPLT_OPT_AUTO_INCREMENT_TRACKNUMBER_TAGS) <= 0)
107   {
108     return;
109   }
110 
111   if (current_split != remaining_tags_like_x)
112   {
113     return;
114   }
115 
116   if ((old_current_split > 0) &&
117       (old_current_split-1 < real_tags_number) &&
118       (old_current_split != remaining_tags_like_x))
119   {
120     const int *prev_track = splt_tu_get_tags_field(state, old_current_split - 1, SPLT_TAGS_TRACK);
121     int previous_track = 0;
122     if (prev_track != NULL)
123     {
124       previous_track = *prev_track;
125     }
126     splt_tu_set_tags_field(state, remaining_tags_like_x, SPLT_TAGS_TRACK, &previous_track);
127 
128     splt_tags *tags_like_x = splt_tu_get_tags_like_x(state);
129     tags_like_x->was_auto_incremented = SPLT_TRUE;
130   }
131 
132   if (old_current_split != current_split)
133   {
134     int tracknumber = 1;
135     if (splt_tu_tags_exists(state, current_split))
136     {
137       const int *track = splt_tu_get_tags_field(state, current_split, SPLT_TAGS_TRACK);
138       if (track != NULL)
139       {
140         tracknumber = *track;
141       }
142     }
143     int new_tracknumber = tracknumber + 1;
144     splt_tu_set_tags_field(state, current_split, SPLT_TAGS_TRACK, &new_tracknumber);
145     splt_tags *tags = splt_tu_get_tags_at(state, current_split);
146     tags->was_auto_incremented = SPLT_TRUE;
147 
148     splt_tu_set_like_x_tags_field(state, SPLT_TAGS_TRACK, &new_tracknumber);
149 
150     splt_tags *tags_like_x = splt_tu_get_tags_like_x(state);
151     tags_like_x->was_auto_incremented = SPLT_TRUE;
152   }
153 }
154 
splt_tu_get_original_tags(splt_state * state,int * err)155 void splt_tu_get_original_tags(splt_state *state, int *err)
156 {
157   if (! splt_io_input_is_stdin(state))
158   {
159     splt_tu_free_original_tags(state);
160     splt_p_set_original_tags(state, err);
161   }
162 }
163 
splt_tu_append_tags(splt_state * state,const char * title,const char * artist,const char * album,const char * performer,const char * year,const char * comment,int track,const char * genre,int set_original_tags)164 int splt_tu_append_tags(splt_state *state,
165     const char *title, const char *artist,
166     const char *album, const char *performer,
167     const char *year, const char *comment,
168     int track, const char *genre, int set_original_tags)
169 {
170   int error = SPLT_OK;
171   int old_tagsnumber = 0;
172   if (state->split.tags_group)
173   {
174     old_tagsnumber = state->split.tags_group->real_tagsnumber;
175   }
176 
177   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
178   if (error != SPLT_OK)
179     return error;
180 
181   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
182   if (error != SPLT_OK)
183     return error;
184 
185   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
186   if (error != SPLT_OK)
187     return error;
188 
189   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
190   if (error != SPLT_OK)
191     return error;
192 
193   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
194   if (error != SPLT_OK)
195     return error;
196 
197   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
198   if (error != SPLT_OK)
199     return error;
200 
201   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
202   if (error != SPLT_OK)
203     return error;
204 
205   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ORIGINAL, &set_original_tags);
206   if (error != SPLT_OK)
207     return error;
208 
209   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
210   return error;
211 }
212 
splt_tu_set_char_field_on_tag(splt_tags * tags,splt_tag_key key,const char * value)213 int splt_tu_set_char_field_on_tag(splt_tags *tags, splt_tag_key key, const char *value)
214 {
215   if (key == SPLT_TAGS_TRACK)
216   {
217     int track = atoi(value);
218     return splt_tu_set_field_on_tags(tags, key, &track);
219   }
220 
221   if (key == SPLT_TAGS_ORIGINAL)
222   {
223     if (strcmp("true", value) == 0)
224     {
225       int true_value = SPLT_TRUE;
226       return splt_tu_set_field_on_tags(tags, key, &true_value);
227     }
228 
229     int false_value = SPLT_FALSE;
230     return splt_tu_set_field_on_tags(tags, key, &false_value);
231   }
232 
233   return splt_tu_set_field_on_tags(tags, key, value);
234 }
235 
splt_tu_append_original_tags(splt_state * state)236 int splt_tu_append_original_tags(splt_state *state)
237 {
238   int err = SPLT_OK;
239 
240   char *new_title = NULL;
241   char *new_artist = NULL;
242   char *new_album = NULL;
243   char *new_year = NULL;
244   char *new_comment = NULL;
245   char *new_genre = NULL;
246 
247   splt_tags *tags = &state->original_tags.tags;
248 
249   new_title = splt_su_replace_all(tags->title, "@", "@@", &err);
250   if (err != SPLT_OK) { goto end; }
251 
252   new_artist = splt_su_replace_all(tags->artist, "@", "@@", &err);
253   if (err != SPLT_OK) { goto end; }
254 
255   new_album = splt_su_replace_all(tags->album, "@", "@@", &err);
256   if (err != SPLT_OK) { goto end; }
257 
258   new_year = splt_su_replace_all(tags->year, "@", "@@", &err);
259   if (err != SPLT_OK) { goto end; }
260 
261   new_comment = splt_su_replace_all(tags->comment, "@", "@@", &err);
262   if (err != SPLT_OK) { goto end; }
263 
264   new_genre = splt_su_replace_all(tags->genre, "@", "@@", &err);
265   if (err != SPLT_OK) { goto end; }
266 
267   err = splt_tu_append_tags(state, new_title, new_artist, new_album, NULL,
268       new_year, new_comment, tags->track, new_genre, SPLT_TRUE);
269 
270 end:
271   if (new_title) { free(new_title); }
272   if (new_artist) { free(new_artist); }
273   if (new_album) { free(new_album); }
274   if (new_year) { free(new_year); }
275   if (new_comment) { free(new_comment); }
276   if (new_genre) { free(new_genre); }
277 
278   return err;
279 }
280 
splt_tu_append_only_non_null_previous_tags(splt_state * state,const char * title,const char * artist,const char * album,const char * performer,const char * year,const char * comment,int track,const char * genre,int set_original_tags)281 int splt_tu_append_only_non_null_previous_tags(splt_state *state,
282     const char *title, const char *artist,
283     const char *album, const char *performer,
284     const char *year, const char *comment,
285     int track, const char *genre, int set_original_tags)
286 {
287   int error = SPLT_OK;
288   int old_tagsnumber = 0;
289   if (state->split.tags_group)
290   {
291     old_tagsnumber = state->split.tags_group->real_tagsnumber - 1;
292   }
293 
294   if (old_tagsnumber < 0)
295   {
296     return error;
297   }
298 
299   if (title != NULL)
300   {
301     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
302     if (error != SPLT_OK) { return error; }
303   }
304 
305   if (artist != NULL)
306   {
307     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
308     if (error != SPLT_OK) { return error; }
309   }
310 
311   if (album != NULL)
312   {
313     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
314     if (error != SPLT_OK) { return error; }
315   }
316 
317   if (performer != NULL)
318   {
319     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
320     if (error != SPLT_OK) { return error; }
321   }
322 
323   if (year != NULL)
324   {
325     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
326     if (error != SPLT_OK) { return error; }
327   }
328 
329   if (comment != NULL)
330   {
331     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
332     if (error != SPLT_OK) { return error; }
333   }
334 
335   if (track != -1)
336   {
337     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
338     if (error != SPLT_OK) { return error; }
339   }
340 
341   if (set_original_tags != -1)
342   {
343     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ORIGINAL, &set_original_tags);
344     if (error != SPLT_OK) { return error; }
345   }
346 
347   if (genre != NULL)
348   {
349     error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
350   }
351 
352   return error;
353 }
354 
splt_tu_reset_tags(splt_tags * tags)355 void splt_tu_reset_tags(splt_tags *tags)
356 {
357   tags->title = NULL;
358   tags->artist = NULL;
359   tags->album = NULL;
360   tags->performer = NULL;
361   tags->year = NULL;
362   tags->comment = NULL;
363   tags->track = -1;
364   tags->genre = NULL;
365   tags->tags_version = 0;
366   tags->set_original_tags = SPLT_FALSE;
367   tags->was_auto_incremented = SPLT_FALSE;
368 }
369 
splt_tu_new_tags(int * error)370 splt_tags *splt_tu_new_tags(int *error)
371 {
372   splt_tags *tags = malloc(sizeof(splt_tags));
373 
374   if (tags == NULL)
375   {
376     *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
377     return NULL;
378   }
379 
380   memset(tags, '\0', sizeof(splt_tags));
381 
382   splt_tu_reset_tags(tags);
383 
384   return tags;
385 }
386 
splt_tu_set_empty_tags(splt_state * state,int index)387 static void splt_tu_set_empty_tags(splt_state *state, int index)
388 {
389   splt_tu_reset_tags(&state->split.tags_group->tags[index]);
390 }
391 
splt_tu_new_tags_if_necessary(splt_state * state,int index)392 int splt_tu_new_tags_if_necessary(splt_state *state, int index)
393 {
394   int error = SPLT_OK;
395 
396   if (!state->split.tags_group)
397   {
398     if (index != 0)
399     {
400       splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
401     }
402     else
403     {
404       state->split.tags_group = malloc(sizeof(splt_tags_group));
405       if (state->split.tags_group == NULL)
406       {
407         return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
408       }
409 
410       state->split.tags_group->real_tagsnumber = 0;
411       state->split.tags_group->iterator_counter = 0;
412 
413       state->split.tags_group->tags = splt_tu_new_tags(&error);
414       if (error < 0)
415       {
416         free(state->split.tags_group);
417         state->split.tags_group = NULL;
418         return error;
419       }
420 
421       splt_tu_set_empty_tags(state, index);
422       state->split.tags_group->real_tagsnumber++;
423     }
424   }
425   else
426   {
427     if ((index > state->split.tags_group->real_tagsnumber) || (index < 0))
428     {
429       splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
430     }
431     else
432     {
433       if (index == state->split.tags_group->real_tagsnumber)
434       {
435         if ((state->split.tags_group->tags =
436               realloc(state->split.tags_group->tags, sizeof(splt_tags) * (index+1))) == NULL)
437         {
438           error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
439           return error;
440         }
441         else
442         {
443           splt_tu_set_empty_tags(state,index);
444           state->split.tags_group->real_tagsnumber++;
445         }
446       }
447     }
448   }
449 
450   return error;
451 }
452 
splt_tu_tags_exists(splt_state * state,int index)453 int splt_tu_tags_exists(splt_state *state, int index)
454 {
455   if (!state->split.tags_group)
456   {
457     return SPLT_FALSE;
458   }
459 
460   if ((index >= 0) && (index < state->split.tags_group->real_tagsnumber))
461   {
462     return SPLT_TRUE;
463   }
464 
465   return SPLT_FALSE;
466 }
467 
splt_tu_set_tags_field(splt_state * state,int index,int tags_field,const void * data)468 int splt_tu_set_tags_field(splt_state *state, int index,
469     int tags_field, const void *data)
470 {
471   int error = SPLT_OK;
472 
473   error = splt_tu_new_tags_if_necessary(state,index);
474   if (error != SPLT_OK) { return error; }
475 
476   if (!state->split.tags_group ||
477       (index >= state->split.tags_group->real_tagsnumber) ||
478       (index < 0))
479   {
480     error = SPLT_ERROR_INEXISTENT_SPLITPOINT;
481     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
482     return error;
483   }
484 
485   splt_tu_set_field_on_tags(&state->split.tags_group->tags[index], tags_field, data);
486   if (error != SPLT_OK)
487   {
488     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
489   }
490 
491   return error;
492 }
493 
splt_tu_set_like_x_tags_field(splt_state * state,int tags_field,const void * data)494 int splt_tu_set_like_x_tags_field(splt_state *state, int tags_field, const void *data)
495 {
496   return splt_tu_set_field_on_tags(&state->split.tags_like_x, tags_field, data);
497 }
498 
splt_tu_set_original_tags_field(splt_state * state,int tags_field,const void * data)499 int splt_tu_set_original_tags_field(splt_state *state, int tags_field, const void *data)
500 {
501   return splt_tu_set_field_on_tags(&state->original_tags.tags, tags_field, data);
502 }
503 
splt_tu_set_to_original_tags(splt_state * state,splt_tags * tags,int * error)504 void splt_tu_set_to_original_tags(splt_state *state, splt_tags *tags, int *error)
505 {
506   splt_tu_copy_tags_without_original_and_version(tags, &state->original_tags.tags, error);
507 }
508 
splt_tu_set_original_tags_data(splt_state * state,void * data)509 void splt_tu_set_original_tags_data(splt_state *state, void *data)
510 {
511   state->original_tags.all_original_tags = data;
512 }
513 
splt_tu_get_original_tags_data(splt_state * state)514 void *splt_tu_get_original_tags_data(splt_state *state)
515 {
516   return state->original_tags.all_original_tags;
517 }
518 
splt_tu_get_original_tags_last_plugin_used(splt_state * state)519 int splt_tu_get_original_tags_last_plugin_used(splt_state *state)
520 {
521   return state->original_tags.last_plugin_used;
522 }
523 
splt_tu_set_original_tags_last_plugin_used(splt_state * state,int plugin_used)524 void splt_tu_set_original_tags_last_plugin_used(splt_state *state, int plugin_used)
525 {
526   state->original_tags.last_plugin_used = plugin_used;
527 }
528 
splt_tu_get_original_tags_tags(splt_state * state)529 splt_tags *splt_tu_get_original_tags_tags(splt_state *state)
530 {
531   return &state->original_tags.tags;
532 }
533 
splt_tu_get_replaced_with_tags(const char * word,const splt_tags * tags,const splt_tags * original_tags,int track,int * error,int replace_tags_in_tags,int current_split,splt_state * state)534 static char *splt_tu_get_replaced_with_tags(const char *word,
535     const splt_tags *tags, const splt_tags *original_tags,
536     int track, int *error, int replace_tags_in_tags,
537     int current_split, splt_state *state)
538 {
539   int err = SPLT_OK;
540 
541   if (current_split == -1)
542   {
543     current_split = splt_t_get_current_split_file_number(state) - 1;
544   }
545 
546   long mins = -1; long secs = -1; long hundr = -1;
547   long point_value = splt_sp_get_splitpoint_value(state, current_split, &err);
548   splt_co_get_mins_secs_hundr(point_value, &mins, &secs, &hundr);
549   long next_mins = -1; long next_secs = -1; long next_hundr = -1;
550   long next_point_value = -1;
551   if (splt_sp_splitpoint_exists(state, current_split + 1))
552   {
553     next_point_value = splt_sp_get_splitpoint_value(state, current_split + 1, &err);
554     long total_time = splt_t_get_total_time(state);
555     if (total_time > 0 && next_point_value > total_time)
556     {
557       next_point_value = total_time;
558     }
559     splt_co_get_mins_secs_hundr(next_point_value, &next_mins, &next_secs, &next_hundr);
560   }
561   short write_eof = SPLT_FALSE;
562   if (next_point_value == LONG_MAX)
563   {
564     write_eof = SPLT_TRUE;
565   }
566 
567   long mMsShH_value = 1;
568   short eof_written = SPLT_FALSE;
569 
570   char *word_with_tags = NULL;
571 
572   if (!replace_tags_in_tags)
573   {
574     err = splt_su_copy(word, &word_with_tags);
575     if (err < 0) { *error = err; }
576     return word_with_tags;
577   }
578 
579   char buffer[256] = { '\0' };
580 
581   if (word == NULL)
582   {
583     return NULL;
584   }
585 
586   const splt_tags *tags_to_replace = tags;
587 
588   int counter = 0;
589   const char *ptr = NULL;
590   for (ptr = word; *ptr != '\0'; ptr++)
591   {
592     if (*ptr == '@')
593     {
594       tags_to_replace = tags;
595     }
596     else if (*ptr == '#')
597     {
598       tags_to_replace = original_tags;
599     }
600 
601     const char *title = tags_to_replace->title;
602     const char *artist = tags_to_replace->artist;
603     const char *album= tags_to_replace->album;
604     const char *performer = tags_to_replace->performer;
605     const char *year = tags_to_replace->year;
606     const char *comment = tags_to_replace->comment;
607     const char *genre = tags_to_replace->genre;
608     int real_track = tags_to_replace->track;
609 
610     if (*ptr == '@' || *ptr == '#')
611     {
612       err = splt_su_append(&word_with_tags, buffer, counter, NULL);
613       if (err != SPLT_OK) { goto error; }
614 
615       memset(buffer, '\0', 256);
616       counter = 0;
617 
618       ptr++;
619 
620       switch (*ptr)
621       {
622         case 's':
623           mMsShH_value = secs;
624           goto put_value;
625         case 'S':
626           mMsShH_value = next_secs;
627           goto put_value;
628         case 'm':
629           mMsShH_value = mins;
630           goto put_value;
631         case 'M':
632           mMsShH_value = next_mins;
633           goto put_value;
634         case 'h':
635           mMsShH_value = hundr;
636           goto put_value;
637         case 'H':
638           mMsShH_value = next_hundr;
639 put_value:
640           if (!eof_written)
641           {
642             if (write_eof &&
643                 (*ptr == 'S' || *ptr == 'M' || *ptr == 'H'))
644             {
645               write_eof = SPLT_FALSE;
646               eof_written = SPLT_TRUE;
647 
648               err = splt_su_append_str(&word_with_tags, "EOF", NULL);
649               if (err != SPLT_OK) { goto error; }
650             }
651             else if (mMsShH_value != -1)
652             {
653               char temp[6] = { '\0' };
654               temp[0] = '%';
655               temp[1] = '0';
656               char number_of_digits = '2';
657               if (*ptr == 'M' || *ptr == 'm')
658               {
659                 number_of_digits = splt_of_get_number_of_digits_from_total_time(state);
660               }
661               temp[2] = number_of_digits;
662               temp[3] = 'l';
663               temp[4] = 'd';
664 
665               char mMsShH_str[100] = { '\0' };
666               snprintf(mMsShH_str, 100, temp, mMsShH_value);
667 
668               err = splt_su_append_str(&word_with_tags, mMsShH_str, NULL);
669               if (err != SPLT_OK) { goto error; }
670             }
671           }
672           break;
673         case 'a':
674           if (artist != NULL)
675           {
676             err = splt_su_append_str(&word_with_tags, artist, NULL);
677             if (err != SPLT_OK) { goto error; }
678           }
679           break;
680         case 'p':
681           if (performer != NULL)
682           {
683             err = splt_su_append_str(&word_with_tags, performer, NULL);
684             if (err != SPLT_OK) { goto error; }
685           }
686           break;
687         case 'b':
688           if (album != NULL)
689           {
690             err = splt_su_append_str(&word_with_tags, album, NULL);
691             if (err != SPLT_OK) { goto error; }
692           }
693           break;
694         case 't':
695           if (title != NULL)
696           {
697             err = splt_su_append_str(&word_with_tags, title, NULL);
698             if (err != SPLT_OK) { goto error; }
699           }
700           break;
701         case 'c':
702           if (comment != NULL)
703           {
704             err = splt_su_append_str(&word_with_tags, comment, NULL);
705             if (err != SPLT_OK) { goto error; }
706           }
707           break;
708         case 'g':
709           if (genre != NULL)
710           {
711             err = splt_su_append_str(&word_with_tags, genre, NULL);
712             if (err != SPLT_OK) { goto error; }
713           }
714           break;
715         case 'y':
716           if (year != NULL)
717           {
718             err = splt_su_append(&word_with_tags, year, NULL);
719             if (err != SPLT_OK) { goto error; }
720           }
721           break;
722         case 'N':
723         case 'n':
724           ;
725           int track_to_set = track;
726 
727           if (*ptr == 'n')
728           {
729             track_to_set = real_track;
730           }
731 
732           char temp[5] = { '\0' };
733           temp[0] = '%';
734           temp[1] = '0';
735           temp[2] = splt_of_get_oformat_number_of_digits_as_char(state);
736           temp[3] = 'd';
737 
738           char track_str[10] = { '\0' };
739           snprintf(track_str, 10, temp, track_to_set);
740 
741           err = splt_su_append_str(&word_with_tags, track_str, NULL);
742           if (err != SPLT_OK) { goto error; }
743           break;
744         case '@':
745           err = splt_su_append_str(&word_with_tags, "@", NULL);
746           if (err != SPLT_OK) { goto error; }
747           break;
748         default:
749           err = splt_su_append(&word_with_tags, (ptr-1), 2, NULL);
750           if (err != SPLT_OK) { goto error; }
751           break;
752       }
753     }
754     else
755     {
756       buffer[counter] = *ptr;
757       counter++;
758 
759       if (counter == 255)
760       {
761         err = splt_su_append(&word_with_tags, buffer, counter, NULL);
762         if (err != SPLT_OK) { goto error; }
763         memset(buffer, '\0', 256);
764         counter = 0;
765       }
766     }
767   }
768 
769   err = splt_su_append(&word_with_tags, buffer, counter, NULL);
770   if (err != SPLT_OK) { goto error; }
771 
772   return word_with_tags;
773 
774 error:
775   if (word_with_tags)
776   {
777     free(word_with_tags);
778   }
779 
780   *error = err;
781 
782   return NULL;
783 }
784 
splt_tu_free_one_tags(splt_tags ** tags)785 void splt_tu_free_one_tags(splt_tags **tags)
786 {
787   if (!tags || !*tags)
788   {
789     return;
790   }
791 
792   splt_tu_free_one_tags_content(*tags);
793 
794   free(*tags);
795   *tags = NULL;
796 }
797 
splt_tu_free_one_tags_content(splt_tags * tags)798 void splt_tu_free_one_tags_content(splt_tags *tags)
799 {
800   if (tags)
801   {
802     if (tags->title)
803     {
804       free(tags->title);
805       tags->title = NULL;
806     }
807     if (tags->artist)
808     {
809       free(tags->artist);
810       tags->artist = NULL;
811     }
812     if (tags->album)
813     {
814       free(tags->album);
815       tags->album = NULL;
816     }
817     if (tags->performer)
818     {
819       free(tags->performer);
820       tags->performer = NULL;
821     }
822     if (tags->year)
823     {
824       free(tags->year);
825       tags->year = NULL;
826     }
827     if (tags->comment)
828     {
829       free(tags->comment);
830       tags->comment = NULL;
831     }
832     if (tags->genre)
833     {
834       free(tags->genre);
835       tags->genre = NULL;
836     }
837 
838     tags->track = -1;
839   }
840 }
841 
splt_tu_append_tags_to_state(splt_state * state,splt_tags * tags,int append_new_tags,int original_tags_value,int use_original_tags_set,int * error)842 void splt_tu_append_tags_to_state(splt_state *state, splt_tags *tags,
843     int append_new_tags, int original_tags_value, int use_original_tags_set, int *error)
844 {
845   int err = SPLT_OK;
846 
847   if (append_new_tags)
848   {
849     int original_tags = SPLT_FALSE;
850     if (use_original_tags_set) { original_tags = tags->set_original_tags; }
851 
852     err = splt_tu_append_tags(state, tags->title, tags->artist, tags->album,
853         tags->performer, tags->year, tags->comment, tags->track, tags->genre,
854         original_tags);
855   }
856   else
857   {
858     err = splt_tu_append_only_non_null_previous_tags(state, tags->title,
859         tags->artist, tags->album, tags->performer, tags->year,
860         tags->comment, tags->track, tags->genre,
861         original_tags_value);
862   }
863 
864   if (err < 0) { *error = err; }
865 }
866 
splt_tu_set_new_tags_where_current_tags_are_null(splt_state * state,splt_tags * current_tags,splt_tags * new_tags,int index,int * error)867 void splt_tu_set_new_tags_where_current_tags_are_null(splt_state *state,
868     splt_tags *current_tags, splt_tags *new_tags,
869     int index, int *error)
870 {
871   if (!current_tags->title)
872   {
873     splt_tu_set_tags_field(state, index, SPLT_TAGS_TITLE, new_tags->title);
874   }
875   if (!current_tags->artist)
876   {
877     splt_tu_set_tags_field(state, index, SPLT_TAGS_ARTIST, new_tags->artist);
878   }
879   if (!current_tags->album)
880   {
881     splt_tu_set_tags_field(state, index, SPLT_TAGS_ALBUM, new_tags->album);
882   }
883   if (!current_tags->performer)
884   {
885     splt_tu_set_tags_field(state, index, SPLT_TAGS_PERFORMER,
886         new_tags->performer);
887   }
888   if (!current_tags->year)
889   {
890     splt_tu_set_tags_field(state, index, SPLT_TAGS_YEAR, new_tags->year);
891   }
892   if (!current_tags->comment)
893   {
894     splt_tu_set_tags_field(state, index, SPLT_TAGS_COMMENT, new_tags->comment);
895   }
896   if (current_tags->track < 0)
897   {
898     splt_tu_set_tags_field(state, index, SPLT_TAGS_TRACK, &new_tags->track);
899   }
900   if (!current_tags->genre)
901   {
902     splt_tu_set_tags_field(state, index, SPLT_TAGS_GENRE, new_tags->genre);
903   }
904   splt_tu_set_tags_field(state, index, SPLT_TAGS_ORIGINAL, &new_tags->set_original_tags);
905 }
906 
splt_tu_has_one_tag_set(splt_tags * tags)907 int splt_tu_has_one_tag_set(splt_tags *tags)
908 {
909   if (tags->title != NULL ||
910       tags->artist != NULL ||
911       tags->album != NULL ||
912       tags->performer != NULL ||
913       tags->year != NULL ||
914       tags->comment != NULL ||
915       tags->track != -1 ||
916       tags->genre != NULL)
917   {
918     return SPLT_TRUE;
919   }
920 
921   return SPLT_FALSE;
922 }
923 
splt_tu_copy_all_tags(splt_tags * from,splt_tags * to,int * error,int copy_original_and_version)924 static void splt_tu_copy_all_tags(splt_tags *from, splt_tags *to, int *error,
925     int copy_original_and_version)
926 {
927   if (!from)
928   {
929     return;
930   }
931 
932   int err = SPLT_OK;
933 
934   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TITLE, from->title);
935   if (err < 0) { goto error; }
936 
937   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ARTIST, from->artist);
938   if (err < 0) { goto error; }
939 
940   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ALBUM, from->album);
941   if (err < 0) { goto error; }
942 
943   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_YEAR, from->year);
944   if (err < 0) { goto error; }
945 
946   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_COMMENT, from->comment);
947   if (err < 0) { goto error; }
948 
949   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_PERFORMER, from->performer);
950   if (err < 0) { goto error; }
951 
952   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TRACK, &from->track);
953   if (err < 0) { goto error; }
954 
955   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_GENRE, from->genre);
956   if (err < 0) { goto error; }
957 
958   if (copy_original_and_version)
959   {
960     err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ORIGINAL, &from->set_original_tags);
961     if (err < 0) { goto error; }
962 
963     err = splt_tu_set_field_on_tags(to, SPLT_TAGS_VERSION, &from->tags_version);
964     if (err < 0) { goto error; }
965   }
966 
967   return;
968 
969 error:
970   *error = err;
971 }
972 
splt_tu_copy_tags_without_original_and_version(splt_tags * from,splt_tags * to,int * error)973 static void splt_tu_copy_tags_without_original_and_version(splt_tags *from, splt_tags *to, int *error)
974 {
975   splt_tu_copy_all_tags(from, to, error, SPLT_FALSE);
976 }
977 
splt_tu_copy_tags(splt_tags * from,splt_tags * to,int * error)978 void splt_tu_copy_tags(splt_tags *from, splt_tags *to, int *error)
979 {
980   splt_tu_copy_all_tags(from, to, error, SPLT_TRUE);
981 }
982 
splt_tu_get_tags_to_replace_in_tags(splt_state * state)983 static splt_tags *splt_tu_get_tags_to_replace_in_tags(splt_state *state)
984 {
985   int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
986 
987   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
988 
989   int real_tags_number = 0;
990   if (state->split.tags_group)
991   {
992     real_tags_number = state->split.tags_group->real_tagsnumber;
993   }
994 
995   if ((current_tags_number >= real_tags_number) &&
996       (remaining_tags_like_x != -1))
997   {
998     return splt_tu_get_tags_like_x(state);
999   }
1000 
1001   return splt_tu_get_tags_at(state, current_tags_number);
1002 }
1003 
splt_tu_set_tags_in_tags(splt_state * state,int current_split)1004 int splt_tu_set_tags_in_tags(splt_state *state, int current_split)
1005 {
1006   int err = SPLT_OK;
1007 
1008   splt_tags *tags = splt_tu_get_tags_to_replace_in_tags(state);
1009   splt_tags *cur_tags = splt_tu_get_current_tags(state);
1010 
1011   if (!tags || !cur_tags)
1012   {
1013     return err;
1014   }
1015 
1016   int track = -1;
1017   if (tags->track > 0)
1018   {
1019     track = tags->track;
1020   }
1021   else if (tags->track == -2)
1022   {
1023     track = -2;
1024   }
1025   else if (splt_tu_has_one_tag_set(tags))
1026   {
1027     if (current_split != -1)
1028     {
1029       track = current_split + 1;
1030     }
1031     else
1032     {
1033       track = splt_t_get_current_split_file_number(state);
1034     }
1035   }
1036 
1037   cur_tags->track = track;
1038   cur_tags->tags_version = tags->tags_version;
1039 
1040   int replace_tags_in_tags = splt_o_get_int_option(state, SPLT_OPT_REPLACE_TAGS_IN_TAGS);
1041 
1042   splt_tags *original_tags = splt_tu_get_original_tags_tags(state);
1043 
1044   char *t = splt_tu_get_replaced_with_tags(tags->title, tags, original_tags,
1045       track, &err, replace_tags_in_tags, current_split, state);
1046   if (err != SPLT_OK) { return err; }
1047   char *y = splt_tu_get_replaced_with_tags(tags->year, tags, original_tags, track, &err, replace_tags_in_tags,
1048       current_split, state);
1049   if (err != SPLT_OK) { return err; }
1050   char *a = splt_tu_get_replaced_with_tags(tags->artist, tags, original_tags, track, &err, replace_tags_in_tags,
1051       current_split, state);
1052   if (err != SPLT_OK) { return err; }
1053   char *al = splt_tu_get_replaced_with_tags(tags->album, tags, original_tags, track, &err, replace_tags_in_tags,
1054       current_split, state);
1055   if (err != SPLT_OK) { return err; }
1056   char *c = splt_tu_get_replaced_with_tags(tags->comment, tags, original_tags, track, &err, replace_tags_in_tags,
1057       current_split, state);
1058   if (err != SPLT_OK) { return err; }
1059   char *g = splt_tu_get_replaced_with_tags(tags->genre, tags, original_tags, track, &err, replace_tags_in_tags,
1060       current_split, state);
1061   if (err != SPLT_OK) { return err; }
1062 
1063   splt_su_free_replace(&cur_tags->title, t);
1064   splt_su_free_replace(&cur_tags->year, y);
1065   splt_su_free_replace(&cur_tags->artist, a);
1066   splt_su_free_replace(&cur_tags->album, al);
1067   splt_su_free_replace(&cur_tags->comment, c);
1068   splt_su_free_replace(&cur_tags->genre, g);
1069 
1070   return err;
1071 }
1072 
splt_tu_get_tags_at(splt_state * state,int tags_index)1073 splt_tags *splt_tu_get_tags_at(splt_state *state, int tags_index)
1074 {
1075   if (!splt_tu_tags_exists(state, tags_index))
1076   {
1077     return NULL;
1078   }
1079 
1080   return &state->split.tags_group->tags[tags_index];
1081 }
1082 
splt_tu_get_last_tags(splt_state * state)1083 splt_tags splt_tu_get_last_tags(splt_state *state)
1084 {
1085   return state->split.tags_group->tags[state->split.tags_group->real_tagsnumber-1];
1086 }
1087 
splt_tu_get_tags_field(splt_state * state,int index,int tags_field)1088 const void *splt_tu_get_tags_field(splt_state *state, int index, int tags_field)
1089 {
1090   int real_tags_number = 0;
1091   if (state->split.tags_group)
1092   {
1093     real_tags_number = state->split.tags_group->real_tagsnumber;
1094   }
1095 
1096   if ((index >= real_tags_number) || (index < 0))
1097   {
1098     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
1099     return NULL;
1100   }
1101   else
1102   {
1103     return splt_tu_get_tags_value(&state->split.tags_group->tags[index], tags_field);
1104   }
1105 
1106   return NULL;
1107 }
1108 
splt_tu_get_tags_value(const splt_tags * tags,int tags_field)1109 const void *splt_tu_get_tags_value(const splt_tags *tags, int tags_field)
1110 {
1111   switch (tags_field)
1112   {
1113     case SPLT_TAGS_TITLE:
1114       return tags->title;
1115       break;
1116     case SPLT_TAGS_ARTIST:
1117       return tags->artist;
1118       break;
1119     case SPLT_TAGS_ALBUM:
1120       return tags->album;
1121       break;
1122     case SPLT_TAGS_YEAR:
1123       return tags->year;
1124       break;
1125     case SPLT_TAGS_COMMENT:
1126       return tags->comment;
1127       break;
1128     case SPLT_TAGS_PERFORMER:
1129       return tags->performer;
1130       break;
1131     case SPLT_TAGS_GENRE:
1132       return tags->genre;
1133       break;
1134     case SPLT_TAGS_TRACK:
1135       return &tags->track;
1136       break;
1137     case SPLT_TAGS_VERSION:
1138       return &tags->tags_version;
1139       break;
1140     case SPLT_TAGS_ORIGINAL:
1141       return &tags->set_original_tags;
1142       break;
1143     default:
1144       splt_e_error(SPLT_IERROR_INT, __func__, -1002, NULL);
1145       return NULL;
1146   }
1147 }
1148 
splt_tu_get_tags_like_x(splt_state * state)1149 splt_tags *splt_tu_get_tags_like_x(splt_state *state)
1150 {
1151   return &state->split.tags_like_x;
1152 }
1153 
splt_tu_free_tags_group(splt_tags_group ** tags_group)1154 void splt_tu_free_tags_group(splt_tags_group **tags_group)
1155 {
1156   if (!tags_group || !*tags_group)
1157   {
1158     return;
1159   }
1160 
1161   int i = 0;
1162   for (i = 0; i < (*tags_group)->real_tagsnumber; i++)
1163   {
1164     splt_tu_free_one_tags_content(&(*tags_group)->tags[i]);
1165   }
1166 
1167   free((*tags_group)->tags);
1168   (*tags_group)->tags = NULL;
1169 
1170   free(*tags_group);
1171   *tags_group = NULL;
1172 }
1173 
splt_tu_free_tags(splt_state * state)1174 void splt_tu_free_tags(splt_state *state)
1175 {
1176   splt_tu_free_tags_group(&state->split.tags_group);
1177   splt_tu_free_one_tags_content(splt_tu_get_tags_like_x(state));
1178 }
1179 
splt_tu_get_current_tags(splt_state * state)1180 splt_tags *splt_tu_get_current_tags(splt_state *state)
1181 {
1182   int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
1183   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
1184   int real_tags_number = 0;
1185   if (state->split.tags_group)
1186   {
1187     real_tags_number = state->split.tags_group->real_tagsnumber;
1188   }
1189 
1190   if ((current_tags_number >= real_tags_number) &&
1191       (remaining_tags_like_x != -1))
1192   {
1193     current_tags_number = remaining_tags_like_x;
1194   }
1195 
1196   return splt_tu_get_tags_at(state, current_tags_number);
1197 }
1198 
splt_tu_get_artist_or_performer_ptr(const splt_tags * tags)1199 char *splt_tu_get_artist_or_performer_ptr(const splt_tags *tags)
1200 {
1201   if (!tags)
1202   {
1203     return NULL;
1204   }
1205 
1206   char *artist_or_performer = tags->artist;
1207 
1208   if (tags->performer == NULL)
1209   {
1210     return artist_or_performer;
1211   }
1212 
1213   if (tags->performer[0] != '\0')
1214   {
1215     return tags->performer;
1216   }
1217 
1218   return artist_or_performer;
1219 }
1220 
splt_tu_copy_tags_on_all_tracks(splt_state * state,int tracks,const splt_tags * all_tags)1221 int splt_tu_copy_tags_on_all_tracks(splt_state *state, int tracks, const splt_tags *all_tags)
1222 {
1223   int err = SPLT_OK;
1224 
1225   const char *all_artist = splt_tu_get_tags_value(all_tags, SPLT_TAGS_ARTIST);
1226   const char *all_album = splt_tu_get_tags_value(all_tags, SPLT_TAGS_ALBUM);
1227   const char *all_year = splt_tu_get_tags_value(all_tags, SPLT_TAGS_YEAR);
1228   const char *all_genre = splt_tu_get_tags_value(all_tags, SPLT_TAGS_GENRE);
1229   const char *all_title = splt_tu_get_tags_value(all_tags, SPLT_TAGS_TITLE);
1230   const char *all_comment = splt_tu_get_tags_value(all_tags, SPLT_TAGS_COMMENT);
1231 
1232   int i = 0;
1233   for (i = 0; i < tracks;i++)
1234   {
1235     if (all_artist != NULL)
1236     {
1237       if (!splt_tu_tags_exists(state, i) ||
1238           splt_tu_get_tags_field(state, i, SPLT_TAGS_ARTIST) == NULL)
1239       {
1240         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ARTIST, all_artist);
1241         if (err != SPLT_OK) { break; }
1242       }
1243     }
1244 
1245     if (all_album != NULL)
1246     {
1247       if (!splt_tu_tags_exists(state, i) ||
1248           splt_tu_get_tags_field(state, i, SPLT_TAGS_ALBUM) == NULL)
1249       {
1250         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ALBUM, all_album);
1251         if (err != SPLT_OK) { break; }
1252       }
1253     }
1254 
1255     if (all_year != NULL)
1256     {
1257       if (!splt_tu_tags_exists(state, i) ||
1258           splt_tu_get_tags_field(state, i, SPLT_TAGS_YEAR) == NULL)
1259       {
1260         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_YEAR, all_year);
1261         if (err != SPLT_OK) { break; }
1262       }
1263     }
1264 
1265     if (all_genre != NULL)
1266     {
1267       if (!splt_tu_tags_exists(state, i) ||
1268           splt_tu_get_tags_field(state, i, SPLT_TAGS_GENRE) == NULL)
1269       {
1270         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_GENRE, all_genre);
1271         if (err != SPLT_OK) { break; }
1272       }
1273     }
1274 
1275     if (all_title != NULL)
1276     {
1277       if (!splt_tu_tags_exists(state, i) ||
1278           splt_tu_get_tags_field(state, i, SPLT_TAGS_TITLE) == NULL)
1279       {
1280         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_TITLE, all_title);
1281         if (err != SPLT_OK) { break; }
1282       }
1283     }
1284 
1285     if (all_comment != NULL)
1286     {
1287       if (!splt_tu_tags_exists(state, i) ||
1288           splt_tu_get_tags_field(state, i, SPLT_TAGS_COMMENT) == NULL)
1289       {
1290         err = splt_tu_set_tags_field(state, i, SPLT_TAGS_COMMENT, all_comment);
1291         if (err != SPLT_OK) { break; }
1292       }
1293     }
1294   }
1295 
1296   return err;
1297 }
1298 
splt_tu_set_field_on_tags(splt_tags * tags,int tags_field,const void * data)1299 int splt_tu_set_field_on_tags(splt_tags *tags, int tags_field, const void *data)
1300 {
1301   int err = SPLT_OK;
1302 
1303   switch (tags_field)
1304   {
1305     case SPLT_TAGS_TITLE:
1306       err = splt_su_copy((char *)data, &tags->title);
1307       break;
1308     case SPLT_TAGS_ARTIST:
1309       err = splt_su_copy((char *)data, &tags->artist);
1310       break;
1311     case SPLT_TAGS_ALBUM:
1312       err = splt_su_copy((char *)data, &tags->album);
1313       break;
1314     case SPLT_TAGS_YEAR:
1315       err = splt_su_copy((char *)data, &tags->year);
1316       break;
1317     case SPLT_TAGS_COMMENT:
1318       err = splt_su_copy((char *)data, &tags->comment);
1319       break;
1320     case SPLT_TAGS_PERFORMER:
1321       err = splt_su_copy((char *)data, &tags->performer);
1322       break;
1323     case SPLT_TAGS_TRACK:
1324       tags->track = *((int *)data);
1325       break;
1326     case SPLT_TAGS_GENRE:
1327       err = splt_su_copy((char *)data, &tags->genre);
1328       break;
1329     case SPLT_TAGS_VERSION:
1330       tags->tags_version = *((int *)data);
1331       break;
1332     case SPLT_TAGS_ORIGINAL:
1333       tags->set_original_tags = *((int *)data);
1334       break;
1335     default:
1336       splt_e_error(SPLT_IERROR_INT,__func__, -500, NULL);
1337       break;
1338   }
1339 
1340   return err;
1341 }
1342 
splt_tu_remove_tags_of_skippoints(splt_state * state)1343 splt_code splt_tu_remove_tags_of_skippoints(splt_state *state)
1344 {
1345   splt_code error = SPLT_OK;
1346 
1347   int number;
1348   splt_tags *tags = splt_tu_duplicate_tags(state, &error, &number);
1349   if (error < 0 || tags == NULL) { return error; }
1350 
1351   splt_tu_free_tags_group(&state->split.tags_group);
1352 
1353   int splitpoints_number = state->split.points->real_splitnumber;
1354   int i = 0;
1355   for (i = 0;i < splitpoints_number;i++)
1356   {
1357     if (i >= number) { continue; }
1358 
1359     if (splt_sp_get_splitpoint_type(state, i, &error) != SPLT_SKIPPOINT)
1360     {
1361       splt_tu_append_tags_to_state(state, &tags[i], SPLT_TRUE, SPLT_FALSE, SPLT_TRUE, &error);
1362     }
1363     if (error < 0) { goto end; }
1364   }
1365 
1366 end:
1367   for (i = 0;i < number;i++)
1368   {
1369     splt_tu_free_one_tags_content(&tags[i]);
1370   }
1371   free(tags);
1372 
1373   return error;
1374 }
1375 
1376