1 /* Copyright (C) 2010-2020 The RetroArch team
3 * ---------------------------------------------------------------------------------------
4 * The following license statement only applies to this file (label_sanitization.c).
5 * ---------------------------------------------------------------------------------------
7 * Permission is hereby granted, free of charge,
8 * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include <playlists/label_sanitization.h>
24 #include <compat/strl.h>
25 #include <retro_miscellaneous.h>
26 #include <string/stdstring.h>
29 #define DISC_STRINGS_LENGTH 3
30 #define REGION_STRINGS_LENGTH 20
32 const char *disc_strings[DISC_STRINGS_LENGTH] = {
39 * We'll use the standard No-Intro regions for now.
41 const char *region_strings[REGION_STRINGS_LENGTH] = {
42 "(Australia)", /* Don’t use with Europe */
44 "(Canada)", /* Don’t use with USA */
55 "(USA)", /* Includes Canada */
57 "(Europe)", /* Includes Australia */
67 * NOTE: Does not work with nested blocks.
69 void label_sanitize(char *label, bool (*left)(char*), bool (*right)(char*))
74 char new_label[PATH_MAX_LENGTH];
76 for (; lindex < PATH_MAX_LENGTH && label[lindex] != '\0'; lindex++)
80 /* check for the start of the range */
81 if ((*left)(&label[lindex]))
85 const bool whitespace = label[lindex] == ' ' && (rindex == 0 || new_label[rindex - 1] == ' ');
87 /* Simplify consecutive whitespaces */
89 new_label[rindex++] = label[lindex];
92 else if ((*right)(&label[lindex]))
96 /* Trim trailing whitespace */
97 if (rindex > 0 && new_label[rindex - 1] == ' ')
98 new_label[rindex - 1] = '\0';
100 new_label[rindex] = '\0';
102 strlcpy(label, new_label, PATH_MAX_LENGTH);
105 static bool left_parens(char *left)
107 return left[0] == '(';
110 static bool right_parens(char *right)
112 return right[0] == ')';
115 static bool left_brackets(char *left)
117 return left[0] == '[';
120 static bool right_brackets(char *right)
122 return right[0] == ']';
125 static bool left_parens_or_brackets(char *left)
127 return left[0] == '(' || left[0] == '[';
130 static bool right_parens_or_brackets(char *right)
132 return right[0] == ')' || right[0] == ']';
135 static bool left_exclusion(char *left,
136 const char **strings, const size_t strings_count)
139 char exclusion_string[32];
140 char comparison_string[32];
142 strlcpy(exclusion_string, left, sizeof(exclusion_string));
143 string_to_upper(exclusion_string);
145 for (i = 0; i < (unsigned)strings_count; i++)
147 strlcpy(comparison_string, strings[i], sizeof(comparison_string));
148 string_to_upper(comparison_string);
150 if (string_starts_with(exclusion_string,
158 static bool left_parens_or_brackets_excluding_region(char *left)
160 return left_parens_or_brackets(left)
161 && !left_exclusion(left, region_strings, REGION_STRINGS_LENGTH);
164 static bool left_parens_or_brackets_excluding_disc(char *left)
166 return left_parens_or_brackets(left)
167 && !left_exclusion(left, disc_strings, DISC_STRINGS_LENGTH);
170 static bool left_parens_or_brackets_excluding_region_or_disc(char *left)
172 return left_parens_or_brackets(left)
173 && !left_exclusion(left, region_strings, REGION_STRINGS_LENGTH)
174 && !left_exclusion(left, disc_strings, DISC_STRINGS_LENGTH);
177 void label_remove_parens(char *label)
179 label_sanitize(label, left_parens, right_parens);
182 void label_remove_brackets(char *label)
184 label_sanitize(label, left_brackets, right_brackets);
187 void label_remove_parens_and_brackets(char *label)
189 label_sanitize(label, left_parens_or_brackets,
190 right_parens_or_brackets);
193 void label_keep_region(char *label)
195 label_sanitize(label, left_parens_or_brackets_excluding_region,
196 right_parens_or_brackets);
199 void label_keep_disc(char *label)
201 label_sanitize(label, left_parens_or_brackets_excluding_disc,
202 right_parens_or_brackets);
205 void label_keep_region_and_disc(char *label)
207 label_sanitize(label, left_parens_or_brackets_excluding_region_or_disc,
208 right_parens_or_brackets);