Author: omote.masahito
Date: Sat Mar 29 20:48:52 2008
New Revision: 5367
Added:
trunk/uim/curl.c
Modified:
trunk/configure.ac
trunk/uim/Makefile.am
Log:
* New plugin curl. Just fetching contents by HTTP/FTP/..., you have to
prepare HTML/XML parser by yourself.
* uim/curl.c
- New file.
* configure.ac
- Add checking for cURL.
* uim/Makefile.am
- Add cURL support.
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Sat Mar 29 20:48:52 2008
@@ -238,6 +238,22 @@
PKG_CHECK_MODULES(PRIME, prime >= 0.8.5.2,
use_prime="yes",use_prime="no")
])
+# ***********************
+# *** Tests for cURL ***
+# ***********************
+AC_ARG_WITH(curl,
+ AS_HELP_STRING([--with-curl], [Build with libcurl
+ @<:@default=no@:>@]),
+ [
+ if test "x$with_curl" = "xyes"; then
+ PKG_CHECK_MODULES(CURL, libcurl >= 7.16.4, use_curl="yes",
use_curl="no")
+ else
+ use_curl="no"
+ fi
+ ],[
+ use_curl="no"
+])
+
PKG_CHECK_MODULES(X11, x11, x11_use_new_dir="yes", x11_use_new_dir="no")
AC_PATH_XTRA
@@ -983,6 +999,7 @@
AM_CONDITIONAL(MANA, test x$use_mana = xyes)
AM_CONDITIONAL(PRIME, test x$use_prime = xyes)
AM_CONDITIONAL(SKK, true)
+AM_CONDITIONAL(CURL, test x$use_curl = xyes)
AM_CONDITIONAL(GTK2, test x$use_gtk2 = xyes)
AM_CONDITIONAL(GTK2_4, test x$use_gtk2_4 = xyes)
AM_CONDITIONAL(DEFAULT_TOOLKIT_GTK, test x$default_toolkit = xgtk)
@@ -1554,6 +1571,7 @@
PRIME : ${use_prime}
m17n-lib : ${use_m17nlib}
SCIM : ${use_scim}
+ cURL : ${use_curl}
Gtk+ : ${use_gtk2}
Gnome Applet : ${use_applet_gnome}
Qt3 : ${use_qt}
Modified: trunk/uim/Makefile.am
==============================================================================
--- trunk/uim/Makefile.am (original)
+++ trunk/uim/Makefile.am Sat Mar 29 20:48:52 2008
@@ -138,6 +138,14 @@
libuim_prime_la_CPPFLAGS = -I$(top_srcdir)
endif
+if CURL
+uim_plugin_LTLIBRARIES += libuim-curl.la
+libuim_curl_la_SOURCES = curl.c
+libuim_curl_la_LIBADD = @CURL_LIBS@ libuim.la
+libuim_curl_la_LDFLAGS = -rpath $(uim_plugindir) -avoid-version -module
+libuim_curl_la_CPPFLAGS = -I$(top_srcdir) @CURL_CFLAGS@
+endif
+
uim_plugin_LTLIBRARIES += libuim-skk.la
libuim_skk_la_SOURCES = skk.c bsdlook.h
libuim_skk_la_LIBADD = libuim-scm.la libuim.la libuim-bsdlook.la @NETLIBS@
Added: trunk/uim/curl.c
==============================================================================
--- (empty file)
+++ trunk/uim/curl.c Sat Mar 29 20:48:52 2008
@@ -0,0 +1,358 @@
+/*
+ Copyright (c) 2008 uim Project http://uim.freedesktop.org/
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+#include "uim.h"
+#include "uim-scm.h"
+#include "uim-scm-abbrev.h"
+#include "gettext.h"
+#include "plugin.h"
+
+
+#ifdef DEBUG
+#define DPRINTFN(n,x) if ((n) <= verbose_level()) fprintf x;
+#else
+#define DPRINTFN(n,x)
+#endif
+
+struct curl_memory_struct {
+ char *str;
+ size_t size;
+};
+
+static size_t uim_curl_write_func(void *, size_t, size_t, void *);
+static uim_lisp uim_curl_fetch_simple(uim_lisp);
+static uim_lisp uim_curl_post(uim_lisp, uim_lisp);
+static uim_lisp uim_curl_url_escape(uim_lisp);
+static uim_lisp uim_curl_url_unescape(uim_lisp);
+void uim_plugin_instance_init(void);
+void uim_plugin_instance_quit(void);
+
+static size_t
+uim_curl_write_func(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ struct curl_memory_struct *mem = (struct curl_memory_struct *)data;
+ size_t realsize = size * nmemb;
+
+ if(mem->str != NULL)
+ mem->str = realloc(mem->str, mem->size + realsize + 1);
+ else
+ mem->str = malloc(realsize + 1);
+
+ if(mem->str != NULL) {
+ memcpy(&(mem->str[mem->size]), ptr, realsize);
+ mem->size += realsize;
+ mem->str[mem->size] = '\0';
+ }
+
+ return realsize;
+}
+
+static uim_lisp
+uim_curl_fetch_simple(uim_lisp url_)
+{
+ const char *url = REFER_C_STR(url_);
+ CURL *curl;
+ CURLcode res;
+ struct curl_memory_struct chunk;
+ uim_lisp fetched_str_;
+ char *ua;
+
+ curl = curl_easy_init();
+
+ if(curl == NULL)
+ return uim_scm_f();
+
+ memset(&chunk, 0, sizeof(struct curl_memory_struct));
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ ua = uim_scm_symbol_value_str("uim-curl-user-agent");
+
+ curl_easy_setopt(curl, CURLOPT_USERAGENT,
+ (ua != NULL) ? ua : "libcurl-agent/1.0");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ if(ua != NULL)
+ free(ua);
+
+ fetched_str_ = MAKE_STR(chunk.str);
+
+ if(chunk.str != NULL && chunk.size > 0) {
+ free(chunk.str);
+ return fetched_str_;
+ }
+
+ return uim_scm_f();
+}
+
+static uim_lisp
+uim_curl_post(uim_lisp url_, uim_lisp post_)
+{
+ uim_lisp post_car_, post_cdr_;
+ uim_lisp fetched_str_;
+ const char *url = REFER_C_STR(url_);
+ CURL *curl;
+ CURLcode res;
+ struct curl_memory_struct chunk;
+ struct curl_httppost* post_first = NULL;
+ struct curl_httppost* post_last = NULL;
+ char *ua;
+
+ curl = curl_easy_init();
+
+ if(curl == NULL)
+ return uim_scm_f();
+
+ memset(&chunk, 0, sizeof(struct curl_memory_struct));
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ ua = uim_scm_symbol_value_str("uim-curl-user-agent");
+
+ curl_easy_setopt(curl, CURLOPT_USERAGENT,
+ (ua != NULL) ? ua : "libcurl-agent/1.0");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ for(post_cdr_ = post_;
+ !NULLP(post_cdr_);
+ post_cdr_ = CDR(post_cdr_)) {
+ const char *name, *value;
+ post_car_ = CAR(post_cdr_);
+
+ name = REFER_C_STR(CAR(post_car_));
+ value = REFER_C_STR(CDR(post_car_));
+
+ curl_formadd(&post_first, &post_last,
+ CURLFORM_COPYNAME, name,
+ CURLFORM_COPYCONTENTS, value,
+ CURLFORM_END);
+ }
+
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, post_first);
+
+ res = curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+ curl_formfree(post_first);
+ curl_global_cleanup();
+ if(ua != NULL)
+ free(ua);
+
+ fetched_str_ = MAKE_STR(chunk.str);
+
+ if(chunk.str != NULL && chunk.size > 0) {
+ free(chunk.str);
+ return fetched_str_;
+ }
+
+ return uim_scm_f();
+}
+
+static uim_lisp
+uim_curl_url_escape(uim_lisp url_)
+{
+ uim_lisp escaped_url_;
+ const char *unescaped_url = REFER_C_STR(url_);
+ char *escaped_url;
+ CURL *curl;
+
+ curl = curl_easy_init();
+
+ if(curl == NULL)
+ return uim_scm_f();
+
+ escaped_url = curl_easy_escape(curl, unescaped_url, strlen(unescaped_url));
+ escaped_url_ = (escaped_url != NULL) ? MAKE_STR(escaped_url) : uim_scm_f();
+
+ curl_free(escaped_url);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return escaped_url_;
+}
+
+static uim_lisp
+uim_curl_url_unescape(uim_lisp url_)
+{
+ uim_lisp unescaped_url_;
+ const char *escaped_url = REFER_C_STR(url_);
+ char *unescaped_url;
+ int len; /* curl_easy_unescape uses int, not size_t */
+ CURL *curl;
+
+ curl = curl_easy_init();
+
+ if(curl == NULL)
+ return uim_scm_f();
+
+ unescaped_url = curl_easy_unescape(curl, escaped_url,
+ strlen(unescaped_url), &len);
+ unescaped_url_ = (len > 0) ? MAKE_STR(unescaped_url) : uim_scm_f();
+
+ curl_free(unescaped_url);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return unescaped_url_;
+}
+
+void uim_plugin_instance_init(void)
+{
+ uim_scm_init_proc1("curl-fetch-simple", uim_curl_fetch_simple);
+ uim_scm_init_proc1("curl-url-escape", uim_curl_url_escape);
+ uim_scm_init_proc1("curl-url-escape", uim_curl_url_unescape);
+ uim_scm_init_proc2("curl-post", uim_curl_post);
+}
+
+void uim_plugin_instance_quit(void)
+{
+ return;
+}
+
+#ifdef DEBUG
+void test1(void);
+void test2(void);
+void test3(void);
+void test4(void);
+void test5(void);
+
+int main(int argc, char *argv[])
+{
+
+ uim_init();
+ uim_plugin_instance_init();
+
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ uim_quit();
+}
+
+void test1(void)
+{
+ CURL *curl;
+ char urlbase[] = "http://d.hatena.ne.jp/keyword/";
+ char url[1000];
+ uim_lisp uim_curl_str;
+ struct curl_memory_struct chunk;
+
+ curl = curl_easy_init();
+
+ if(curl == NULL)
+ exit(-1);
+ memset(&chunk, 0, sizeof(struct curl_memory_struct));
+
+ snprintf(url, sizeof(url), "%s%s", urlbase, "テスト");
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ uim_curl_str = MAKE_STR(chunk.str);
+
+ printf("%s\n",chunk.str);
+}
+
+
+void test2(void)
+{
+ uim_lisp url, form, result;
+
+ url = MAKE_STR("http://d.hatena.ne.jp/keyword/テスト");
+ form = LIST2(MAKE_SYM("curl-fetch-simple"), url);
+ result = uim_scm_eval(form);
+
+ printf("%s\n", REFER_C_STR(result));
+}
+
+void test3(void)
+{
+ uim_lisp url, form, result;
+
+ url = MAKE_STR("http://ja.wikipedia.org/wiki/テスト");
+ form = LIST2(MAKE_SYM("curl-fetch-simple"), url);
+ result = uim_scm_eval(form);
+
+ printf("%s\n", REFER_C_STR(result));
+}
+
+void test4(void)
+{
+ uim_lisp url, form, result;
+ uim_lisp postdata;
+
+ url = MAKE_STR("http://search.hatena.ne.jp/search");
+ /* '((name . value) (name . value) (name . value) ...) */
+ postdata = QUOTE(LIST3(CONS(MAKE_STR("submit"), MAKE_STR("検索")),
+ CONS(MAKE_STR("ie"), MAKE_STR("utf8")),
+ CONS(MAKE_STR("word"), MAKE_STR("日本"))));
+
+ form = LIST3(MAKE_SYM("curl-post"), url, postdata);
+ result = uim_scm_eval(form);
+ printf("%s\n", REFER_C_STR(result));
+}
+
+void test5(void)
+{
+ uim_lisp url, form, result;
+ uim_lisp ua;
+ url = MAKE_STR("http://www.ugtop.com/spill.shtml");
+ form = LIST2(MAKE_SYM("curl-fetch-simple"), url);
+ result = uim_scm_eval(form);
+ printf("%s\n", REFER_C_STR(result));
+
+ ua = uim_scm_eval_c_string("(define uim-curl-user-agent \"Mozilla/5.0\")");
+ form = LIST2(MAKE_SYM("curl-fetch-simple"), url);
+ result = uim_scm_eval(form);
+ printf("%s\n", REFER_C_STR(result));
+}
+#endif