1 /*
2 $Id: cddb_regex.c,v 1.16 2007/08/07 03:12:53 jcaratzas Exp $
3
4 Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20 */
21
22 #include "cddb/cddb_ni.h"
23
24 #ifdef HAVE_REGEX_H
25 #include <stdlib.h>
26 #include <string.h>
27 #include "cddb/cddb_regex.h"
28
29
30 regex_t *REGEX_TRACK_FRAME_OFFSETS = NULL;
31 regex_t *REGEX_TRACK_FRAME_OFFSET = NULL;
32 regex_t *REGEX_DISC_LENGTH = NULL;
33 regex_t *REGEX_DISC_REVISION = NULL;
34 regex_t *REGEX_DISC_TITLE = NULL;
35 regex_t *REGEX_DISC_YEAR = NULL;
36 regex_t *REGEX_DISC_GENRE = NULL;
37 regex_t *REGEX_DISC_EXT = NULL;
38 regex_t *REGEX_TRACK_TITLE = NULL;
39 regex_t *REGEX_TRACK_EXT = NULL;
40 regex_t *REGEX_PLAY_ORDER = NULL;
41 regex_t *REGEX_QUERY_MATCH = NULL;
42 regex_t *REGEX_SITE = NULL;
43 regex_t *REGEX_TEXT_SEARCH = NULL;
44
45
cddb_regex_init_1(regex_t ** p,const char * regex)46 static int cddb_regex_init_1(regex_t **p, const char *regex)
47 {
48 if ((*p = (regex_t*)malloc(sizeof(regex_t))) == NULL) {
49 // XXX: check memory alloc
50 return -1;
51 }
52 return regcomp(*p, regex, REG_EXTENDED);
53 }
54
55
cddb_regex_init()56 void cddb_regex_init()
57 {
58 int rv;
59
60 rv = cddb_regex_init_1(®EX_TRACK_FRAME_OFFSETS,
61 "^#[[:blank:]]*Track frame offsets:[[:blank:]]*$");
62 rv = cddb_regex_init_1(®EX_TRACK_FRAME_OFFSET,
63 "^#[[:blank:]]*([0-9]+)[[:blank:]]*$");
64 rv = cddb_regex_init_1(®EX_DISC_LENGTH,
65 "^#[[:blank:]]*Disc length:[[:blank:]]+([0-9]+)( seconds)*[[:blank:]]*$");
66 rv = cddb_regex_init_1(®EX_DISC_REVISION,
67 "^#[[:blank:]]*Revision:[[:blank:]]+([0-9]+)[[:blank:]]*$");
68 rv = cddb_regex_init_1(®EX_DISC_TITLE,
69 "^DTITLE=((.*) / (.*)|(.*))$");
70 rv = cddb_regex_init_1(®EX_DISC_YEAR,
71 "^DYEAR=([0-9]*)$");
72 rv = cddb_regex_init_1(®EX_DISC_GENRE,
73 "^DGENRE=(.*)$");
74 rv = cddb_regex_init_1(®EX_DISC_EXT,
75 "^EXTD=(.*)$");
76 rv = cddb_regex_init_1(®EX_TRACK_TITLE,
77 "^TTITLE([0-9]+)=((.*) / (.*)|(.*))$");
78 rv = cddb_regex_init_1(®EX_TRACK_EXT,
79 "^EXTT([0-9]+)=(.*)$");
80 rv = cddb_regex_init_1(®EX_PLAY_ORDER,
81 "^PLAYORDER=(.*)$");
82 rv = cddb_regex_init_1(®EX_QUERY_MATCH,
83 "^([[:alpha:]]+)[[:blank:]]([[:xdigit:]]+)[[:blank:]]((.*) / (.*)|(.*))$");
84
85 /* example: freedb.freedb.org cddbp 8880 - N000.00 W000.00 Random freedb server */
86 /* <server> <proto> <port> <query-url> <latitude> <longitude> <description> */
87 rv = cddb_regex_init_1(®EX_SITE,
88 "^([[:graph:]]+)[[:blank:]]([[:alpha:]]+)[[:blank:]]([[:digit:]]+)[[:blank:]]([[:graph:]]+)[[:blank:]]([NS])([0-9.]+)[[:blank:]]([EW])([0-9.]+)[[:blank:]](.*)$");
89
90 /* example: ...<a href="http://www.freedb.org/freedb_search_fmt.php?cat=rock&id=8e0eee0b">Massive Attack / Mezzanine</a>... */
91 /* ...<a href="http://www.freedb.org/freedb_search_fmt.php?cat=soundtrack&id=b30ed30b"><font size=-1>3</font></a>... */
92 /* <1:greedy_remains> <2:category> <3:discid> <6:artist> <7:title> <8:artist_title> <10:duplicate_number> */
93 rv = cddb_regex_init_1(®EX_TEXT_SEARCH,
94 "^(.*)/freedb_search_fmt\\.php\\?cat=([[:alpha:]]+)&id=([[:xdigit:]]+)\">"
95 "((([^<]+) / ([^<]+))|([^<]+)|([^>]*>([[:digit:]]+)<.*))</a>.*$");
96 }
97
cddb_regfree(regex_t * regex)98 static inline void cddb_regfree(regex_t *regex)
99 {
100 if (regex) {
101 regfree(regex);
102 free(regex);
103 regex = NULL;
104 }
105 }
106
cddb_regex_destroy()107 void cddb_regex_destroy()
108 {
109 cddb_regfree(REGEX_TRACK_FRAME_OFFSETS);
110 cddb_regfree(REGEX_TRACK_FRAME_OFFSET);
111 cddb_regfree(REGEX_DISC_LENGTH);
112 cddb_regfree(REGEX_DISC_REVISION);
113 cddb_regfree(REGEX_DISC_TITLE);
114 cddb_regfree(REGEX_DISC_YEAR);
115 cddb_regfree(REGEX_DISC_GENRE);
116 cddb_regfree(REGEX_DISC_EXT);
117 cddb_regfree(REGEX_TRACK_TITLE);
118 cddb_regfree(REGEX_TRACK_EXT);
119 cddb_regfree(REGEX_PLAY_ORDER);
120 cddb_regfree(REGEX_QUERY_MATCH);
121 cddb_regfree(REGEX_SITE);
122 cddb_regfree(REGEX_TEXT_SEARCH);
123 }
124
cddb_regex_get_int(const char * s,regmatch_t matches[],int idx)125 int cddb_regex_get_int(const char *s, regmatch_t matches[], int idx)
126 {
127 char *buf;
128 int i;
129
130 buf = cddb_regex_get_string(s, matches, idx);
131 i = atoi(buf);
132 free(buf);
133 return i;
134 }
135
cddb_regex_get_hex(const char * s,regmatch_t matches[],int idx)136 unsigned long cddb_regex_get_hex(const char *s, regmatch_t matches[], int idx)
137 {
138 char *buf, *endp;
139 long long h;
140
141 buf = cddb_regex_get_string(s, matches, idx);
142 h = strtoll(buf, &endp, 16);
143 free(buf);
144 return (unsigned long)(h & 0xffffffff);
145 }
146
cddb_regex_get_float(const char * s,regmatch_t matches[],int idx)147 double cddb_regex_get_float(const char *s, regmatch_t matches[], int idx)
148 {
149 char *buf;
150 double f;
151
152 buf = cddb_regex_get_string(s, matches, idx);
153 f = atof(buf);
154 free(buf);
155 return f;
156 }
157
cddb_regex_get_string(const char * s,regmatch_t matches[],int idx)158 char *cddb_regex_get_string(const char *s, regmatch_t matches[], int idx)
159 {
160 char *result;
161 int start, end, len;
162
163 start = matches[idx].rm_so;
164 end = matches[idx].rm_eo;
165 len = end - start;
166 result = malloc(len + 1);
167 strncpy(result, s + start, len);
168 result[len] = '\0';
169 return result;
170 }
171
172
173 #endif /*HAVE_REGEX_H*/
174