psxdma: Fix endian issue in gpuInterrupt()
[pcsx_rearmed.git] / deps / libretro-common / playlists / label_sanitization.c
CommitLineData
3719602c
PC
1/* Copyright (C) 2010-2020 The RetroArch team
2 *
3 * ---------------------------------------------------------------------------------------
4 * The following license statement only applies to this file (label_sanitization.c).
5 * ---------------------------------------------------------------------------------------
6 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 *
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.
21 */
22
23#include <playlists/label_sanitization.h>
24#include <compat/strl.h>
25#include <retro_miscellaneous.h>
26#include <string/stdstring.h>
27#include <string.h>
28
29#define DISC_STRINGS_LENGTH 3
30#define REGION_STRINGS_LENGTH 20
31
32const char *disc_strings[DISC_STRINGS_LENGTH] = {
33 "(CD",
34 "(Disc",
35 "(Disk"
36};
37
38/*
39 * We'll use the standard No-Intro regions for now.
40 */
41const char *region_strings[REGION_STRINGS_LENGTH] = {
42 "(Australia)", /* Don’t use with Europe */
43 "(Brazil)",
44 "(Canada)", /* Don’t use with USA */
45 "(China)",
46 "(France)",
47 "(Germany)",
48 "(Hong Kong)",
49 "(Italy)",
50 "(Japan)",
51 "(Korea)",
52 "(Netherlands)",
53 "(Spain)",
54 "(Sweden)",
55 "(USA)", /* Includes Canada */
56 "(World)",
57 "(Europe)", /* Includes Australia */
58 "(Asia)",
59 "(Japan, USA)",
60 "(Japan, Europe)",
61 "(USA, Europe)"
62};
63
64/**
65 * label_sanitize:
66 *
67 * NOTE: Does not work with nested blocks.
68 **/
69void label_sanitize(char *label, bool (*left)(char*), bool (*right)(char*))
70{
71 bool copy = true;
72 int rindex = 0;
73 int lindex = 0;
74 char new_label[PATH_MAX_LENGTH];
75
76 for (; lindex < PATH_MAX_LENGTH && label[lindex] != '\0'; lindex++)
77 {
78 if (copy)
79 {
80 /* check for the start of the range */
81 if ((*left)(&label[lindex]))
82 copy = false;
83 else
84 {
85 const bool whitespace = label[lindex] == ' ' && (rindex == 0 || new_label[rindex - 1] == ' ');
86
87 /* Simplify consecutive whitespaces */
88 if (!whitespace)
89 new_label[rindex++] = label[lindex];
90 }
91 }
92 else if ((*right)(&label[lindex]))
93 copy = true;
94 }
95
96 /* Trim trailing whitespace */
97 if (rindex > 0 && new_label[rindex - 1] == ' ')
98 new_label[rindex - 1] = '\0';
99 else
100 new_label[rindex] = '\0';
101
102 strlcpy(label, new_label, PATH_MAX_LENGTH);
103}
104
105static bool left_parens(char *left)
106{
107 return left[0] == '(';
108}
109
110static bool right_parens(char *right)
111{
112 return right[0] == ')';
113}
114
115static bool left_brackets(char *left)
116{
117 return left[0] == '[';
118}
119
120static bool right_brackets(char *right)
121{
122 return right[0] == ']';
123}
124
125static bool left_parens_or_brackets(char *left)
126{
127 return left[0] == '(' || left[0] == '[';
128}
129
130static bool right_parens_or_brackets(char *right)
131{
132 return right[0] == ')' || right[0] == ']';
133}
134
135static bool left_exclusion(char *left,
136 const char **strings, const size_t strings_count)
137{
138 unsigned i;
139 char exclusion_string[32];
140 char comparison_string[32];
141
142 strlcpy(exclusion_string, left, sizeof(exclusion_string));
143 string_to_upper(exclusion_string);
144
145 for (i = 0; i < (unsigned)strings_count; i++)
146 {
147 strlcpy(comparison_string, strings[i], sizeof(comparison_string));
148 string_to_upper(comparison_string);
149
150 if (string_starts_with(exclusion_string,
151 comparison_string))
152 return true;
153 }
154
155 return false;
156}
157
158static bool left_parens_or_brackets_excluding_region(char *left)
159{
160 return left_parens_or_brackets(left)
161 && !left_exclusion(left, region_strings, REGION_STRINGS_LENGTH);
162}
163
164static bool left_parens_or_brackets_excluding_disc(char *left)
165{
166 return left_parens_or_brackets(left)
167 && !left_exclusion(left, disc_strings, DISC_STRINGS_LENGTH);
168}
169
170static bool left_parens_or_brackets_excluding_region_or_disc(char *left)
171{
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);
175}
176
177void label_remove_parens(char *label)
178{
179 label_sanitize(label, left_parens, right_parens);
180}
181
182void label_remove_brackets(char *label)
183{
184 label_sanitize(label, left_brackets, right_brackets);
185}
186
187void label_remove_parens_and_brackets(char *label)
188{
189 label_sanitize(label, left_parens_or_brackets,
190 right_parens_or_brackets);
191}
192
193void label_keep_region(char *label)
194{
195 label_sanitize(label, left_parens_or_brackets_excluding_region,
196 right_parens_or_brackets);
197}
198
199void label_keep_disc(char *label)
200{
201 label_sanitize(label, left_parens_or_brackets_excluding_disc,
202 right_parens_or_brackets);
203}
204
205void label_keep_region_and_disc(char *label)
206{
207 label_sanitize(label, left_parens_or_brackets_excluding_region_or_disc,
208 right_parens_or_brackets);
209}