ao: fix crash after ao init failure (from recent 3a5fd15fa2)
[mplayer/greg.git] / bstr.c
blob68342fabfeb7983e451290b65a00503c8c387d5f
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <string.h>
20 #include <libavutil/avutil.h>
21 #include <assert.h>
22 #include <ctype.h>
24 #include "talloc.h"
26 #include "bstr.h"
28 int bstrcmp(struct bstr str1, struct bstr str2)
30 int ret = memcmp(str1.start, str2.start, FFMIN(str1.len, str2.len));
32 if (!ret) {
33 if (str1.len == str2.len)
34 return 0;
35 else if (str1.len > str2.len)
36 return 1;
37 else
38 return -1;
40 return ret;
43 int bstrcasecmp(struct bstr str1, struct bstr str2)
45 int ret = strncasecmp(str1.start, str2.start, FFMIN(str1.len, str2.len));
47 if (!ret) {
48 if (str1.len == str2.len)
49 return 0;
50 else if (str1.len > str2.len)
51 return 1;
52 else
53 return -1;
55 return ret;
58 int bstrchr(struct bstr str, int c)
60 for (int i = 0; i < str.len; i++)
61 if (str.start[i] == c)
62 return i;
63 return -1;
66 int bstrrchr(struct bstr str, int c)
68 for (int i = str.len - 1; i >= 0; i--)
69 if (str.start[i] == c)
70 return i;
71 return -1;
74 int bstr_find(struct bstr haystack, struct bstr needle)
76 for (int i = 0; i < haystack.len; i++)
77 if (bstr_startswith(bstr_splice(haystack, i, haystack.len), needle))
78 return i;
79 return -1;
82 struct bstr bstr_strip(struct bstr str)
84 while (str.len && isspace(*str.start)) {
85 str.start++;
86 str.len--;
88 while (str.len && isspace(str.start[str.len - 1]))
89 str.len--;
90 return str;
93 struct bstr bstr_split(struct bstr str, char *sep, struct bstr *rest)
95 int start, end;
96 for (start = 0; start < str.len; start++)
97 if (!strchr(sep, str.start[start]))
98 break;
99 for (end = start; end < str.len; end++)
100 if (strchr(sep, str.start[end]))
101 break;
102 if (rest) {
103 *rest = bstr_cut(str, end);
105 str.start += start;
106 str.len = end - start;
107 return str;
111 struct bstr bstr_splice(struct bstr str, int start, int end)
113 if (start < 0)
114 start += str.len;
115 if (end < 0)
116 end += str.len;
117 end = FFMIN(end, str.len);
118 start = FFMAX(start, 0);
119 if (start >= end)
120 return (struct bstr){NULL, 0};
121 str.start += start;
122 str.len = end - start;
123 return str;
126 long long bstrtoll(struct bstr str, struct bstr *rest, int base)
128 char buf[51];
129 int len = FFMIN(str.len, 50);
130 memcpy(buf, str.start, len);
131 buf[len] = 0;
132 char *endptr;
133 long long r = strtoll(buf, &endptr, base);
134 if (rest)
135 *rest = bstr_cut(str, endptr - buf);
136 return r;
139 struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str)
141 if (str.len == 0)
142 return NULL;
143 int count = 0;
144 for (int i = 0; i < str.len; i++)
145 if (str.start[i] == '\n')
146 count++;
147 if (str.start[str.len - 1] != '\n')
148 count++;
149 struct bstr *r = talloc_array_ptrtype(talloc_ctx, r, count);
150 unsigned char *p = str.start;
151 for (int i = 0; i < count - 1; i++) {
152 r[i].start = p;
153 while (*p++ != '\n');
154 r[i].len = p - r[i].start;
156 r[count - 1].start = p;
157 r[count - 1].len = str.start + str.len - p;
158 return r;
161 void bstr_lower(struct bstr str)
163 for (int i = 0; i < str.len; i++)
164 str.start[i] = tolower(str.start[i]);