2008/02/13


ShareOnTumblr
「CShellExt::QueryContextMenu」でやれば出来なく無いけどコストがデカイし別のシェルエクステンション混ぜると落ちたりするんですよね。
Gyazowin tumblr for Windowsにファイルのアップロード機能を追加して名前をGyamblr for Windowsに変更 « ZeroMemory
Windowsのコンテキストメニューのコピーとかにcopy to tumblrみたいなのを追加できないかなと思ったんだけど、標準のやつはともかくアプリケーションの右クリックはアプリケーション管轄で制御されていてWindowsシロウト同然の自分には外からいじれなそうだったのであきらめました。
本当は「CShellExt::QueryContextMenu」でやるのがいいんだろうけど、今回はコマンドラインユーザでも使える様にコマンド形式で「送る」に登録する方法にした。

続きを読む...

Posted at by



2008/02/08


まぁ、id:tokuhirom氏が作ったwassr-todo.plがあるんですが...
(いいんです。C言語が書きたいんです!)

でっかく記事いっぱいにコードだけ...


ちなみに、json-cというライブラリとcURLを使っています。
昨日のパッチを使えばVC6でもビルド出来ます。
よろしければどうぞ。

最新ソースはCodeReposのコノ辺におきました。

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <curl/curl.h>
#include <json.h>

#define APP_NAME                   "wassr_todo"

#ifdef _WIN32
# ifndef snprintf
#  define snprintf _snprintf
# endif
#endif

#define TODO_MODIFY_URL "http://api.wassr.jp/todo/"
#define TODO_JSON_EXT ".json"

static char* response_cond = NULL;  /* response condition */
static char* response_mime = NULL;  /* response content-type. ex: "text/html" */
static char* response_data = NULL;  /* response data from server. */
static size_t response_size = 0;    /* response size of data */

static void initialize_http_response() {
    response_cond = NULL;
    response_mime = NULL;
    response_data = NULL;
    response_size = 0;
}

static void terminate_http_response() {
    if (response_cond) free(response_cond);
    if (response_mime) free(response_mime);
    if (response_data) free(response_data);
    response_cond = NULL;
    response_mime = NULL;
    response_data = NULL;
    response_size = 0;
}

static size_t handle_returned_data(char* ptr, size_t size, size_t nmemb, void* stream) {
    if (!response_data)
        response_data = (char*)malloc(size*nmemb);
    else
        response_data = (char*)realloc(response_data, response_size+size*nmemb);
    if (response_data) {
        memcpy(response_data+response_size, ptr, size*nmemb);
        response_size += size*nmemb;
    }
    return size*nmemb;
}

static size_t handle_returned_header(void* ptr, size_t size, size_t nmemb, void* stream) {
    char* header = NULL;

    header = (char*)malloc(size*nmemb + 1);
    memcpy(header, ptr, size*nmemb);
    header[size*nmemb] = 0;
    if (strncmp(header, "Content-Type: ", 14) == 0) {
        char* stop = header + 14;
        stop = strpbrk(header + 14, "\r\n;");
        if (stop) *stop = 0;
        if (response_mime) free(response_mime);
        response_mime = strdup(header + 14);
    }
    if (strncmp(header, "Last-Modified: ", 15) == 0) {
        char* stop = strpbrk(header, "\r\n;");
        if (stop) *stop = 0;
        if (response_cond) free(response_cond);
        response_cond = strdup(header);
    }
    if (strncmp(header, "ETag: ", 6) == 0) {
        char* stop = strpbrk(header, "\r\n;");
        if (stop) *stop = 0;
        if (response_cond) free(response_cond);
        response_cond = strdup(header);
    }
    free(header);
    return size*nmemb;
}

char* get_http_data(char* url, char* user, char* pass) {
    CURLcode res;
    CURL* curl;
    char* ret = NULL;
    int status = 0;
    char auth[512];

    initialize_http_response();

    memset(auth, 0, sizeof(auth));
    snprintf(auth, sizeof(auth)-1, "%s:%s", user, pass);

    curl = curl_easy_init();
    if (!curl) return NULL;
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_USERPWD, auth);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, handle_returned_header);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, APP_NAME);
    res = curl_easy_perform(curl);
    res = res == CURLE_OK ? curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &status) : res;
    curl_easy_cleanup(curl);
    if (res == CURLE_OK && status == 200) {
        ret = (char*)malloc(response_size+1);
        memset(ret, 0, response_size+1);
        memcpy(ret, (char*)response_data, response_size);
    }

    terminate_http_response();

    return ret;
}

char* post_http_data(char* url, char* user, char* pass, char* data) {
    CURLcode res;
    CURL* curl;
    char* ret = NULL;
    int status = 0;
    char auth[512];

    initialize_http_response();

    memset(auth, 0, sizeof(auth));
    snprintf(auth, sizeof(auth)-1, "%s:%s", user, pass);

    curl = curl_easy_init();
    if (!curl) return NULL;
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_USERPWD, auth);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, handle_returned_header);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, APP_NAME);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*)data);
    res = curl_easy_perform(curl);
    res = res == CURLE_OK ? curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &status) : res;
    curl_easy_cleanup(curl);
    if (res == CURLE_OK && status == 200) {
        ret = (char*)malloc(response_size+1);
        memset(ret, 0, response_size+1);
        memcpy(ret, (char*)response_data, response_size);
    }

    terminate_http_response();

    return ret;
}

char* string_to_utf8_alloc(const char* str) {
    if (!str) return NULL;
#ifdef WIN32
    UINT codePage;
    size_t in_len = strlen(str);
    codePage = GetACP();
    size_t wcssize = MultiByteToWideChar(codePage, 0, str, in_len,  NULL, 0);
    wchar_t* pszStrWC = (wchar_t*)malloc(sizeof(wchar_t)*(wcssize + 1));
    wcssize = MultiByteToWideChar(codePage, 0, str, in_len, pszStrWC, wcssize + 1);
    pszStrWC[wcssize] = '\0';

    codePage = CP_UTF8;
    size_t mbssize = WideCharToMultiByte(codePage, 0, pszStrWC, -1, NULL, 0, NULL, NULL);
    char* pszStrMB = (char*)malloc(mbssize + 1);
    mbssize = WideCharToMultiByte(codePage, 0, pszStrWC, -1, pszStrMB, mbssize, NULL, NULL);
    pszStrMB[mbssize] = '\0';

    free(pszStrWC);

    return pszStrMB;
#else
    return strdup(str);
#endif
}

char* utf8_to_string_alloc(const char* str) {
    if (!str) return NULL;
#ifdef WIN32
    UINT codePage = CP_UTF8;
    const char* ptr = str;
    if (str[0] == (char)0xef && str[1] == (char)0xbb && str[2] == (char)0xbf)
        ptr += 3;
    size_t wcssize = MultiByteToWideChar(codePage, 0, ptr, -1,  NULL, 0);
    wchar_t* pszStrWC = (wchar_t*)malloc(sizeof(wchar_t)*(wcssize + 1));
    wcssize = MultiByteToWideChar(codePage, 0, ptr, -1, pszStrWC, wcssize + 1);
    pszStrWC[wcssize] = '\0';

    codePage = GetACP();
    size_t mbssize = WideCharToMultiByte(codePage, 0, pszStrWC,-1, NULL, 0, NULL, NULL);
    char* pszStrMB = (char*)malloc(mbssize + 1);
    mbssize = WideCharToMultiByte(codePage, 0, pszStrWC, -1, pszStrMB, mbssize, NULL, NULL);
    pszStrMB[mbssize] = '\0';

    free(pszStrWC);

    return pszStrMB;
#else
    return strdup(str);
#endif
}

static char* url_encode_alloc(const char* str) {
    static const int force_encode_all = TRUE;
    const char* hex = "0123456789abcdef";

    char* buf = NULL;
    unsigned char* pbuf = NULL;
    int len = 0;

    if (!str) return NULL;
    len = strlen(str)*3;
    buf = (char*)malloc(len+1);
    memset(buf, 0, len+1);
    pbuf = (unsigned char*)buf;
    while(*str) {
        unsigned char c = (unsigned char)*str;
        if (c == ' ')
            *pbuf++ = '+';
        else if (c & 0x80 || force_encode_all) {
            *pbuf++ = '%';
            *pbuf++ = hex[c >> 4];
            *pbuf++ = hex[c & 0x0f];
        } else
            *pbuf++ = c;
        str++;
    }
    return buf;
}

char* add_todo(char* user, char* pass, char* body) {
    int size;
    char* body_utf8;
    char* body_data;
    char* post;
    char* data;

    body_utf8 = string_to_utf8_alloc(body);
    if (!body_utf8) return NULL;
    body_data = url_encode_alloc(body_utf8);
    free(body_utf8);
    size = 5 + strlen(body_data);
    post = (char*)malloc(size + 1);
    memset(post, 0, size + 1);
    strcpy(post, "body=");
    strcat(post, body_data);
    free(body_data);

    data = post_http_data("http://api.wassr.jp/todo/add.json", user, pass, post);
    free(post);
    return data;
}

char* modify_todo(char* user, char* pass, char* command, char* todo_rid) {
    int size;
    char* url;
    char* post;
    char* data;

    size = 9 + strlen(todo_rid);
    post = (char*)malloc(size + 1);
    memset(post, 0, size + 1);
    strcpy(post, "todo_rid=");
    strcat(post, todo_rid);

    size = strlen(TODO_MODIFY_URL) + strlen(command) + strlen(TODO_JSON_EXT);
    url = (char*)malloc(size + 1);
    memset(url, 0, size + 1);
    strcpy(url, TODO_MODIFY_URL);
    strcat(url, command);
    strcat(url, TODO_JSON_EXT);

    data = post_http_data(url, user, pass, post);
    free(post);
    free(url);
    return data;
}

char* list_todo(char* user, char* pass, int done_fg) {
    char* data;

    if (done_fg)
        data = get_http_data("http://api.wassr.jp/todo/list.json?done_fg=1", user, pass);
    else
        data = get_http_data("http://api.wassr.jp/todo/list.json?done_fg=0", user, pass);
    if (!data) {
        perror("Unknown server response(server down or invalid authenticate?)");
        return NULL;
    }
    return data;
}

int main(int argc, char* argv[]) {
    FILE* fp = NULL;
    char* home = NULL;
    char* user = NULL;
    char* pass = NULL;
    char conf[_MAX_PATH];
    char buff[BUFSIZ];
    char* data = NULL;
    struct json_object* obj = NULL;
    struct json_object* res = NULL;
    int i;

    home = getenv("HOME");
    if (!home) home = getenv("USERPROFILE");
    snprintf(conf, sizeof(conf), "%s/.wassr-todo", home);
    fp = fopen(conf, "rt");
    if (!fp) {
        perror("404 ~/.wassr-todo NOT FOUND");
        goto error;
    }
    while(fgets(buff, sizeof(buff), fp)) {
        char *ptr = strpbrk(buff, "\r\n");
        if (*ptr) *ptr = 0;
        if (!strncmp(buff, "username: ", 10))
            user = strdup(buff + 10);
        if (!strncmp(buff, "password: ", 10))
            pass = strdup(buff + 10);
    }
    fclose(fp);

    if (argc == 1)
        data = list_todo(user, pass, FALSE);
    else {
        if (argc == 2 && !strcmp(argv[1], "list"))
            data = list_todo(user, pass, FALSE);
        else
        if (argc == 2 && !strcmp(argv[1], "listdone"))
            data = list_todo(user, pass, TRUE);
        else
        if (argc == 3 && !strcmp(argv[1], "add"))
            data = add_todo(user, pass, argv[2]);
        else
        if (argc == 3 && (
                !strcmp(argv[1], "delete") ||
                !strcmp(argv[1], "start") ||
                !strcmp(argv[1], "stop") ||
                !strcmp(argv[1], "done")))
            data = modify_todo(user, pass, argv[1], argv[2]);
        else {
            puts("usage: wassr_todo [command] [argument]");
            puts("\t* command");
            puts("\t\tlist\t\tlist todo.");
            puts("\t\tlistdone\tlist todo which is done.");
            puts("\t\tadd [body]\tpost new todo to wassr.");
            puts("\t\tdelete [rid]\tdelete the todo.");
            puts("\t\tstart [rid]\tstart the todo.");
            puts("\t\tstop [rid]\tstop the todo.");
            puts("\t\tdone [rid]\tdone the todo.");
            goto error;
        }
    }

    if (!data) {
        perror("Unknown server response(server down or invalid authenticate?)");
        goto error;
    }
    obj = json_tokener_parse(data);
    free(data);

    if (is_error(obj)) {
        perror("Unknown server response(not json?)");
        goto error;
    }

    if (json_object_is_type(obj, json_type_object)) {
        res = json_object_object_get(obj, "error");
        if (!is_error(res)) {
            char* _res = utf8_to_string_alloc(json_object_get_string(res));
            if (_res) {
                printf("error: %s\n", _res);
                free(_res);
                goto error;
            }
        }
        res = json_object_object_get(obj, "message");
        if (!is_error(res)) {
            char* _res = utf8_to_string_alloc(json_object_get_string(res));
            if (_res) {
                printf("message: %s\n", _res);
                free(_res);
            }
        }
    }

    if (json_object_is_type(obj, json_type_array)) {
        for(i = 0; i < json_object_array_length(obj); i++) {
            struct json_object *item = json_object_array_get_idx(obj, i);
            struct json_object* todo_rid = json_object_object_get(item, "todo_rid");
            struct json_object* body = json_object_object_get(item, "body");
            if (!is_error(todo_rid) && !is_error(body)) {
                char* _todo_rid = utf8_to_string_alloc(json_object_get_string(todo_rid));
                char* _body = utf8_to_string_alloc(json_object_get_string(body));
                printf("TODO-%03d [%s] %s\n", i+1, _todo_rid, _body);
                free(_todo_rid);
                free(_body);
            }
        }
    } else
    if (json_object_is_type(obj, json_type_object)) {
        struct json_object* todo_rid = json_object_object_get(obj, "todo_rid");
        if (!is_error(todo_rid)) {
            char* _todo_rid = utf8_to_string_alloc(json_object_get_string(todo_rid));
            if (_todo_rid) {
                printf("%s\n", _todo_rid);
                free(_todo_rid);
            }
        }
    }
    return 0;

error:
    if (user) free(user);
    if (pass) free(pass);
    return -1;
}
Posted at by



2008/02/07


JSON-Cという、C言語からJSONを扱う為のライブラリを見つけました。
Index of /json-c
C言語って言いながら、実際もともと/TPオプションでCPPビルドしてるし、それJSON-CPPちゃうんかいという気もしなくないですが...。
foreachなんかもあり、結構使い勝手は良さそうです。

ただ、同梱されている物の中には*.vcprojしか入っておらず、Makefileでゴニョゴニョするのが好きな私には絶えられないものであったり...
最近はMakefileを書く習慣って無くなってきたんですかねぇ...
で、VC6でビルドしようと思ったけどエラーがワンサカ。
どうやら
  • キャスト漏れ
  • 変数名に「this」を使用
  • C99の可変個引数マクロを使用
とはっきり言ってVC6を捨てているコードだったりしました。
なにくそーとパッチを書いたので、公開しておきます。
ただ大したパッチでもないので、オフィシャルに送るのはやめときます。
しかもトリッキーな事やってます。
デバッグ用の可変個引数マクロ #define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
#define MC_DEBUG if (0)
みたくして無理やり殺しています。
で、できたパッチは以下の通り。
Index: json_object.c
===================================================================
--- json_object.c   (revision 21)
+++ json_object.c   (working copy)
@@ -28,7 +28,9 @@
   char* strndup(const char* str, size_t n);
 #endif /* !HAVE_STRNDUP */
 
+#if _MSC_VER >= 1400
 #define REFCOUNT_DEBUG 1
+#endif
 
 char *json_number_chars = "0123456789.+-eE";
 char *json_hex_chars = "0123456789abcdef";
@@ -160,7 +162,7 @@
 
 static struct json_object* json_object_new(enum json_type o_type)
 {
-  struct json_object *this = calloc(sizeof(struct json_object), 1);
+  struct json_object *this = (struct json_object*)calloc(sizeof(struct json_object), 1);
   if(!this) return NULL;
   this->o_type = o_type;
   this->_ref_count = 1;
Index: json_tokener.c
===================================================================
--- json_tokener.c  (revision 21)
+++ json_tokener.c  (working copy)
@@ -57,7 +57,7 @@
 
 struct json_tokener* json_tokener_new()
 {
-  struct json_tokener *tok = calloc(1, sizeof(struct json_tokener));
+  struct json_tokener *tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
   tok->pb = printbuf_new();
   json_tokener_reset(tok);
   return tok;
@@ -97,7 +97,7 @@
   tok = json_tokener_new();
   obj = json_tokener_parse_ex(tok, str, -1);
   if(tok->err != json_tokener_success)
-    obj = error_ptr(-tok->err);
+    obj = (struct json_object*)error_ptr(-tok->err);
   json_tokener_free(tok);
   return obj;
 }
Index: linkhash.c
===================================================================
--- linkhash.c  (revision 21)
+++ linkhash.c  (working copy)
@@ -42,7 +42,7 @@
 unsigned long lh_char_hash(void *k)
 {
    unsigned int h = 0;
-   const char* data = k;
+   const char* data = (const char*)k;
  
    while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME;
 
@@ -62,12 +62,12 @@
    int i;
    struct lh_table *t;
 
-   t = calloc(1, sizeof(struct lh_table));
+   t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
    if(!t) lh_abort("lh_table_new: calloc failed\n");
    t->count = 0;
    t->size = size;
    t->name = name;
-   t->table = calloc(size, sizeof(struct lh_entry));
+   t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry));
    if(!t->table) lh_abort("lh_table_new: calloc failed\n");
    t->free_fn = free_fn;
    t->hash_fn = hash_fn;
Index: json_util.c
===================================================================
--- json_util.c (revision 21)
+++ json_util.c (working copy)
@@ -62,11 +62,11 @@
   if((fd = open(filename, O_RDONLY)) < 0) {
     MC_ERROR("json_object_from_file: error reading file %s: %s\n",
         filename, strerror(errno));
-    return error_ptr(-1);
+    return (struct json_object*)error_ptr(-1);
   }
   if(!(pb = printbuf_new())) {
     MC_ERROR("json_object_from_file: printbuf_new failed\n");
-    return error_ptr(-1);
+    return (struct json_object*)error_ptr(-1);
   }
   while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
     printbuf_memappend(pb, buf, ret);
@@ -76,7 +76,7 @@
     MC_ABORT("json_object_from_file: error reading file %s: %s\n",
         filename, strerror(errno));
     printbuf_free(pb);
-    return error_ptr(-1);
+    return (struct json_object*)error_ptr(-1);
   }
   obj = json_tokener_parse(pb->buf);
   printbuf_free(pb);
Index: debug.h
===================================================================
--- debug.h (revision 21)
+++ debug.h (working copy)
@@ -21,6 +21,7 @@
 extern void mc_error(const char *msg, ...);
 extern void mc_info(const char *msg, ...);
 
+#if _MSC_VER >= 1400
 #ifdef MC_MAINTAINER_MODE
 #define MC_SET_DEBUG(x) mc_set_debug(x)
 #define MC_GET_DEBUG() mc_get_debug()
@@ -38,5 +39,14 @@
 #define MC_ERROR(x, ...) if (0) mc_error(x, ##__VA_ARGS__)
 #define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
 #endif
+#else
+#define MC_SET_DEBUG(x)
+#define MC_GET_DEBUG()
+#define MC_SET_SYSLOG(x)
+#define MC_ABORT if (0)
+#define MC_DEBUG if (0)
+#define MC_ERROR if (0)
+#define MC_INFO if (0)
+#endif
 
 #endif
Index: arraylist.c
===================================================================
--- arraylist.c (revision 21)
+++ arraylist.c (working copy)
@@ -28,11 +28,11 @@
 {
   struct array_list *this;
 
-  if(!(this = calloc(1, sizeof(struct array_list)))) return NULL;
+  if(!(this = (struct array_list*)calloc(1, sizeof(struct array_list)))) return NULL;
   this->size = ARRAY_LIST_DEFAULT_SIZE;
   this->length = 0;
   this->free_fn = free_fn;
-  if(!(this->array = calloc(sizeof(void*), this->size))) {
+  if(!(this->array = (void**)calloc(sizeof(void*), this->size))) {
     free(this);
     return NULL;
   }
@@ -64,7 +64,7 @@
   if(max < this->size) return 0;
   new_size = max(this->size << 1, max);
   if(!(t = realloc(this->array, new_size*sizeof(void*)))) return -1;
-  this->array = t;
+  this->array = (void**)t;
   (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*));
   this->size = new_size;
   return 0;
Index: json.h
===================================================================
--- json.h  (revision 21)
+++ json.h  (working copy)
@@ -13,8 +13,10 @@
 #define _json_h_
 
 #ifdef __cplusplus
+#if _MSC_VER >= 1400
 extern "C" {
 #endif
+#endif
 
 #include "bits.h"
 #include "debug.h"
@@ -25,7 +27,9 @@
 #include "json_tokener.h"
 
 #ifdef __cplusplus
+#if _MSC_VER >= 1400
 }
 #endif
+#endif
 
 #endif
Index: printbuf.c
===================================================================
--- printbuf.c  (revision 21)
+++ printbuf.c  (working copy)
@@ -29,10 +29,10 @@
 {
   struct printbuf *p;
 
-  if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
+  if(!(p = (struct printbuf*)calloc(1, sizeof(struct printbuf)))) return NULL;
   p->size = 32;
   p->bpos = 0;
-  if(!(p->buf = malloc(p->size))) {
+  if(!(p->buf = (char*)malloc(p->size))) {
     free(p);
     return NULL;
   }
@@ -50,7 +50,7 @@
         "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
         p->bpos, size, p->size, new_size);
 #endif /* PRINTBUF_DEBUG */
-    if(!(t = realloc(p->buf, new_size))) return -1;
+    if(!(t = (char*)realloc(p->buf, new_size))) return -1;
     p->size = new_size;
     p->buf = t;
   }
@@ -70,7 +70,7 @@
 /* CAW: compliant version of vasprintf */
 static int vasprintf(char **buf, const char *fmt, va_list ap)
 {
-#ifndef WIN32
+#if !defined(WIN32) || _MSC_VER < 1400
    static char _T_emptybuffer = '\0';
 #endif /* !defined(WIN32) */
    int chars;
@@ -78,7 +78,7 @@
 
    if(!buf) { return -1; }
 
-#ifdef WIN32
+#if defined(WIN32) && _MSC_VER >= 1400
    chars = _vscprintf(fmt, ap)+1;
 #else /* !defined(WIN32) */
    /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
さらにVC6でビルドする為のMakefile CFLAGS = -DWIN32 -Dthis=o_this -O2 -MT -W3 -nologo -TP -EHsc
SRC = arraylist.c json_object.c json_tokener.c json_util.c linkhash.c printbuf.c
OBJ = $(SRC:.c=.obj)

all : json.lib

json.lib : $(OBJ)
    lib /out:json.lib $(OBJ)

hoge.exe : hoge.obj
    cl /Fohoge.exe hoge.obj json.lib

clean :
    del /Q *.obj *.lib
あと、サンプル「hoge.c」 #include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

#include "json.h"

int main(int argc, char **argv)
{
    struct json_object *obj;
    int i;

    obj = json_tokener_parse("[1,2,3]");
    for(i=0; i < json_object_array_length(obj); i++) {
        struct json_object *a = json_object_array_get_idx(obj, i);
        printf("\t[%d]=%s\n", i, json_object_to_json_string(a));
    }
    obj = json_tokener_parse("{'a':1,'b':2,'c':3}");
    json_object_object_foreach(obj, key, val) {
        printf("\t%s: %s\n", key, json_object_to_json_string(val));
    }

    return 0;
}
「hoge.c」の実行結果は     [0]=1
    [1]=2
    [2]=3
    a: 1
    b: 2
    c: 3
こんな感じ。
うむ。これでgtkwassrにTODO機能が付けれるかも...
Posted at by