Set len to 0 if string is empty.
[lms] / lightmediascanner / src / lib / lightmediascanner_utils.c
1 /**
2  * Copyright (C) 2007 by INdT
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program 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.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  * @author Gustavo Sverzut Barbieri <gustavo.barbieri@openbossa.org>
19  */
20
21 #include <lightmediascanner_utils.h>
22 #include <ctype.h>
23 #include <alloca.h>
24
25 /**
26  * Strips string, in place.
27  *
28  * @param str string to be stripped.
29  * @param p_len string length to analyse, also the place where the final size
30  *        is stored.
31  */
32 void
33 lms_strstrip(char *str, unsigned int *p_len)
34 {
35     int i, len;
36     char *p;
37
38     len = *p_len;
39
40     if (len == 0)
41         return;
42
43     if (*str == '\0') {
44         *p_len = 0;
45         return;
46     }
47
48     p = str + len - 1;
49     for (i = len - 1; i >= 0; i--) {
50         if (isspace(*p) || *p == '\0') {
51             *p = '\0';
52             len--;
53             p--;
54         } else
55             break;
56     }
57     if (len == 0) {
58         *p_len = 0;
59         return;
60     }
61
62     p = str;
63     for (i = 0; i < len; i++) {
64         if (isspace(*p))
65             p++;
66         else
67             break;
68     }
69     len -= i;
70     if (len == 0) {
71         *str = '\0';
72         *p_len = 0;
73         return;
74     }
75
76     *p_len = len;
77
78     if (str < p)
79         for (; len > 0; len--, str++, p++)
80             *str = *p;
81 }
82
83 /**
84  * Find out which of the given extensions matches the given name.
85  *
86  * @param name string to analyse.
87  * @param name_len string length.
88  * @param exts array of extensions to be checked.
89  * @param exts_len number of items in array @p exts
90  *
91  * @return index in @p exts or -1 if it doesn't match none.
92  */
93 int
94 lms_which_extension(const char *name, unsigned int name_len, const struct lms_string_size *exts, unsigned int exts_len) {
95     int i;
96     unsigned int *exts_pos;
97     const char *s;
98
99     exts_pos = alloca(exts_len * sizeof(*exts_pos));
100     for (i = 0; i < exts_len; i++)
101         exts_pos[i] = exts[i].len;
102
103     for (s = name + name_len - 1; s >= name; s--) {
104         int i, match;
105         char c1, c2;
106
107         c1 = *s;
108         if (c1 >= 'a')
109             c2 = c1;
110         else
111             c2 = 'a' + c1 - 'A';
112
113         match = 0;
114         for (i = 0; i < exts_len; i++) {
115             if (exts_pos[i] > 0) {
116                 char ce;
117
118                 ce = exts[i].str[exts_pos[i] - 1];
119                 if (ce == c1 || ce == c2) {
120                     if (exts_pos[i] == 1)
121                         return i;
122                     exts_pos[i]--;
123                     match = 1;
124                 } else
125                     exts_pos[i] = 0;
126             }
127         }
128         if (!match)
129             return -1;
130     }
131
132     return -1;
133 }