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(&REGEX_TRACK_FRAME_OFFSETS,
61                            "^#[[:blank:]]*Track frame offsets:[[:blank:]]*$");
62     rv = cddb_regex_init_1(&REGEX_TRACK_FRAME_OFFSET,
63                            "^#[[:blank:]]*([0-9]+)[[:blank:]]*$");
64     rv = cddb_regex_init_1(&REGEX_DISC_LENGTH,
65                            "^#[[:blank:]]*Disc length:[[:blank:]]+([0-9]+)( seconds)*[[:blank:]]*$");
66     rv = cddb_regex_init_1(&REGEX_DISC_REVISION,
67                            "^#[[:blank:]]*Revision:[[:blank:]]+([0-9]+)[[:blank:]]*$");
68     rv = cddb_regex_init_1(&REGEX_DISC_TITLE,
69                            "^DTITLE=((.*) / (.*)|(.*))$");
70     rv = cddb_regex_init_1(&REGEX_DISC_YEAR,
71                            "^DYEAR=([0-9]*)$");
72     rv = cddb_regex_init_1(&REGEX_DISC_GENRE,
73                            "^DGENRE=(.*)$");
74     rv = cddb_regex_init_1(&REGEX_DISC_EXT,
75                            "^EXTD=(.*)$");
76     rv = cddb_regex_init_1(&REGEX_TRACK_TITLE,
77                            "^TTITLE([0-9]+)=((.*) / (.*)|(.*))$");
78     rv = cddb_regex_init_1(&REGEX_TRACK_EXT,
79                            "^EXTT([0-9]+)=(.*)$");
80     rv = cddb_regex_init_1(&REGEX_PLAY_ORDER,
81                            "^PLAYORDER=(.*)$");
82     rv = cddb_regex_init_1(&REGEX_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(&REGEX_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(&REGEX_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