tests/README: Add url.t --json-file URL note
[quvi.git] / lib / util.c
blob9a4bf53cfe35178e7471a3464ae2ed71a8262692
1 /* quvi
2 * Copyright (C) 2009,2010,2011 Toni Gundogdu <legatvs@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
20 #include "config.h"
22 #include <string.h>
23 #include <errno.h>
24 #include <stdarg.h>
25 #include <libgen.h>
26 #include <assert.h>
28 #include <curl/curl.h>
30 #ifdef HAVE_ICONV
31 #include <iconv.h>
32 #endif
34 #include "quvi/quvi.h"
35 #include "internal.h"
36 #include "curl_wrap.h"
37 #include "util.h"
39 char *freprintf(char **dst, const char *fmt, ...)
41 va_list args;
43 _free(*dst);
45 va_start(args, fmt);
46 vasprintf(dst, fmt, args);
47 va_end(args);
49 return (*dst);
52 #ifdef HAVE_ICONV
53 QUVIcode to_utf8(_quvi_media_t video)
55 static const char to[] = "UTF-8";
56 size_t insize, avail, iconv_code;
57 char inbuf[1024], outbuf[1024];
58 ICONV_CONST char *inptr;
59 char *from, *wptr;
60 iconv_t cd;
62 assert(video != 0);
63 assert(video->quvi != 0);
64 assert(video->title != 0);
65 assert(video->charset != 0);
67 wptr = outbuf;
68 inptr = inbuf;
69 avail = sizeof(outbuf);
70 insize = strlen(video->title);
72 if (insize >= sizeof(inbuf))
73 insize = sizeof(inbuf);
75 memset(wptr, 0, sizeof(outbuf));
77 snprintf(inbuf, sizeof(inbuf), "%s", video->title);
79 /* Try with TRANSLIT first. */
80 asprintf(&from, "%s//TRANSLIT", video->charset);
81 cd = iconv_open(to, from);
83 /* If that fails, then without TRANSLIT. */
84 if (cd == (iconv_t) - 1)
86 _free(from);
87 asprintf(&from, "%s", video->charset);
88 cd = iconv_open(to, from);
91 if (cd == (iconv_t) - 1)
93 if (errno == EINVAL)
95 freprintf(&video->quvi->errmsg,
96 "conversion from %s to %s unavailable", from, to);
98 else
100 #ifdef HAVE_STRERROR
101 freprintf(&video->quvi->errmsg, "iconv_open: %s",
102 strerror(errno));
103 #else
104 perror("iconv_open");
105 #endif
108 _free(from);
110 return (QUVI_ICONV);
113 iconv_code = iconv(cd, &inptr, &insize, &wptr, &avail);
114 iconv_close(cd);
115 cd = 0;
117 if (iconv_code == (size_t) - 1)
119 freprintf(&video->quvi->errmsg,
120 "converting characters from '%s' to '%s' failed", from,
121 to);
122 _free(from);
123 return (QUVI_ICONV);
125 else
127 freprintf(&video->title, "%s", outbuf);
130 _free(from);
132 return (QUVI_OK);
134 #endif
136 char *unescape(_quvi_t quvi, char *s)
138 char *tmp, *ret;
140 assert(quvi != 0);
141 assert(quvi->curl != 0);
143 tmp = curl_easy_unescape(quvi->curl, s, 0, NULL);
144 assert(tmp != 0);
145 ret = strdup(tmp);
146 curl_free(tmp);
148 free(s);
150 return (ret);
153 char *from_html_entities(char *src)
155 struct lookup_s
157 const char *from;
158 const char *to;
161 static const struct lookup_s conv[] =
163 {"&quot;", "\""},
164 {"&#34;", "\""},
165 {"&#034;", "\""},
166 {"&amp;", "&"},
167 {"&#38;", "&"},
168 {"&#038;", "&"},
169 {"&apos;", "'"},
170 {"&#39;", "'"},
171 {"&#039;", "'"},
172 {"&lt;", "<"},
173 {"&#60;", "<"},
174 {"&#060;", "<"},
175 {"&gt;", ">"},
176 {"&#62;", ">"},
177 {"&#062;", ">"},
178 {0, 0}
181 int i;
183 for (i = 0; conv[i].from; ++i)
184 src = strepl(src, conv[i].from, conv[i].to);
186 return (src);
189 static int new_video_link(_quvi_video_link_t * dst)
191 struct _quvi_video_link_s *qvl;
193 qvl = calloc(1, sizeof(*qvl));
194 if (!qvl)
195 return (QUVI_MEM);
197 *dst = qvl;
199 return (QUVI_OK);
202 int add_video_link(llst_node_t * lst, const char *fmt, ...)
204 _quvi_video_link_t qvl;
205 va_list args;
206 int rc;
208 rc = new_video_link(&qvl);
209 if (rc != QUVI_OK)
210 return (rc);
212 va_start(args, fmt);
213 vasprintf((char **)&qvl->url, fmt, args);
214 va_end(args);
216 if (!qvl->url)
218 _free(qvl);
219 return (QUVI_MEM);
222 return (llst_add(lst, qvl));
225 char *dirname_from(const char *s)
227 char *t = strdup(s);
228 char *p = strdup(dirname(t));
229 _free(t);
230 return (p);
233 /* vim: set ts=2 sw=2 tw=72 expandtab: */