From 528f486eeea2a2fa4cd3b0d4b0002e36babf2254 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 27 Apr 2011 19:52:53 +0200 Subject: [PATCH] Make code compatible with yajl 2.0 *and* 1.0 --- common.mk | 4 ++++ src/ipc.c | 40 ++++++++++++++++++++++++++++++- src/load_layout.c | 37 ++++++++++++++++++++++++---- src/util.c | 19 +++++++++++++-- yajl-fallback/yajl/yajl_version.h | 7 ++++++ 5 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 yajl-fallback/yajl/yajl_version.h diff --git a/common.mk b/common.mk index 182c12e5..86585e59 100644 --- a/common.mk +++ b/common.mk @@ -80,6 +80,10 @@ ifeq ($(UNAME),FreeBSD) LDFLAGS += -liconv endif +# Fallback for libyajl 1 which did not include yajl_version.h. We need +# YAJL_MAJOR from that file to decide which code path should be used. +CFLAGS += -idirafter yajl-fallback + ifneq (,$(filter Linux GNU GNU/%, $(UNAME))) CFLAGS += -D_GNU_SOURCE endif diff --git a/src/ipc.c b/src/ipc.c index 68d654da..27f89677 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -3,7 +3,7 @@ * * i3 - an improved dynamic tiling window manager * - * © 2009-2010 Michael Stapelberg and contributors + * © 2009-2011 Michael Stapelberg and contributors * * See file LICENSE for license information. * @@ -17,6 +17,7 @@ #include #include #include +#include #include "all.h" @@ -282,12 +283,20 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) { IPC_HANDLER(tree) { setlocale(LC_NUMERIC, "C"); +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif dump_node(gen, croot, false); setlocale(LC_NUMERIC, ""); const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else unsigned int length; +#endif y(get_buf, &payload, &length); ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_TREE, length); @@ -300,7 +309,11 @@ IPC_HANDLER(tree) { * */ IPC_HANDLER(get_workspaces) { +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif y(array_open); Con *focused_ws = con_get_workspace(focused); @@ -351,7 +364,11 @@ IPC_HANDLER(get_workspaces) { y(array_close); const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else unsigned int length; +#endif y(get_buf, &payload, &length); ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_WORKSPACES, length); @@ -364,7 +381,11 @@ IPC_HANDLER(get_workspaces) { * */ IPC_HANDLER(get_outputs) { +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif y(array_open); Output *output; @@ -401,7 +422,11 @@ IPC_HANDLER(get_outputs) { y(array_close); const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else unsigned int length; +#endif y(get_buf, &payload, &length); ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_OUTPUTS, length); @@ -412,8 +437,17 @@ IPC_HANDLER(get_outputs) { * Callback for the YAJL parser (will be called when a string is parsed). * */ +#if YAJL_MAJOR < 2 static int add_subscription(void *extra, const unsigned char *s, unsigned int len) { +#else +static int add_subscription(void *extra, const unsigned char *s, + size_t len) { + if (len < 0) { + DLOG("Invalid subscription with len %zd\n", len); + return 1; + } +#endif ipc_client *client = extra; DLOG("should add subscription to extra %p, sub %.*s\n", client, len, s); @@ -463,7 +497,11 @@ IPC_HANDLER(subscribe) { memset(&callbacks, 0, sizeof(yajl_callbacks)); callbacks.yajl_string = add_subscription; +#if YAJL_MAJOR >= 2 + p = yajl_alloc(&callbacks, NULL, (void*)client); +#else p = yajl_alloc(&callbacks, NULL, NULL, (void*)client); +#endif stat = yajl_parse(p, (const unsigned char*)message, message_size); if (stat != yajl_status_ok) { unsigned char *err; diff --git a/src/load_layout.c b/src/load_layout.c index 92cfecbd..c104ad2e 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "all.h" @@ -66,8 +67,16 @@ static int json_end_array(void *ctx) { return 1; } +#if YAJL_MAJOR < 2 static int json_key(void *ctx, const unsigned char *val, unsigned int len) { - LOG("key: %.*s\n", len, val); +#else +static int json_key(void *ctx, const unsigned char *val, size_t len) { + if (len < 0) { + LOG("Invalid key, len = %zd\n", len); + return 1; + } +#endif + LOG("key: %.*s\n", (int)len, val); FREE(last_key); last_key = scalloc((len+1) * sizeof(char)); memcpy(last_key, val, len); @@ -83,7 +92,15 @@ static int json_key(void *ctx, const unsigned char *val, unsigned int len) { return 1; } +#if YAJL_MAJOR >= 2 +static int json_string(void *ctx, const unsigned char *val, size_t len) { +#else static int json_string(void *ctx, const unsigned char *val, unsigned int len) { +#endif + if (len < 0) { + LOG("Invalid string for key %s\n", last_key); + return 1; + } LOG("string: %.*s for key %s\n", len, val, last_key); if (parsing_swallows) { /* TODO: the other swallowing keys */ @@ -102,7 +119,7 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { LOG("sticky_group of this container is %s\n", json_node->sticky_group); } else if (strcasecmp(last_key, "orientation") == 0) { char *buf = NULL; - asprintf(&buf, "%.*s", len, val); + asprintf(&buf, "%.*s", (int)len, val); if (strcasecmp(buf, "none") == 0) json_node->orientation = NO_ORIENTATION; else if (strcasecmp(buf, "horizontal") == 0) @@ -116,7 +133,11 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { return 1; } +#if YAJL_MAJOR >= 2 +static int json_int(void *ctx, long long val) { +#else static int json_int(void *ctx, long val) { +#endif LOG("int %d for key %s\n", val, last_key); if (strcasecmp(last_key, "layout") == 0) { json_node->layout = val; @@ -197,8 +218,13 @@ void tree_append_json(const char *filename) { callbacks.yajl_map_key = json_key; callbacks.yajl_integer = json_int; callbacks.yajl_double = json_double; +#if YAJL_MAJOR >= 2 + g = yajl_gen_alloc(NULL); + hand = yajl_alloc(&callbacks, NULL, (void*)g); +#else g = yajl_gen_alloc(NULL, NULL); hand = yajl_alloc(&callbacks, NULL, NULL, (void*)g); +#endif yajl_status stat; json_node = focused; to_focus = NULL; @@ -207,8 +233,7 @@ void tree_append_json(const char *filename) { parsing_geometry = false; setlocale(LC_NUMERIC, "C"); stat = yajl_parse(hand, (const unsigned char*)buf, n); - if (stat != yajl_status_ok && - stat != yajl_status_insufficient_data) + if (stat != yajl_status_ok) { unsigned char * str = yajl_get_error(hand, 1, (const unsigned char*)buf, n); fprintf(stderr, "%s\n", (const char *) str); @@ -216,7 +241,11 @@ void tree_append_json(const char *filename) { } setlocale(LC_NUMERIC, ""); +#if YAJL_MAJOR >= 2 + yajl_complete_parse(hand); +#else yajl_parse_complete(hand); +#endif fclose(f); if (to_focus) diff --git a/src/util.c b/src/util.c index a72b52d5..d9de98e8 100644 --- a/src/util.c +++ b/src/util.c @@ -3,7 +3,7 @@ * * i3 - an improved dynamic tiling window manager * - * © 2009-2010 Michael Stapelberg and contributors + * © 2009-2011 Michael Stapelberg and contributors * * See file LICENSE for license information. * @@ -18,6 +18,7 @@ #endif #include #include +#include #include "all.h" @@ -281,14 +282,22 @@ char *get_process_filename(const char *prefix) { char *store_restart_layout() { setlocale(LC_NUMERIC, "C"); +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif dump_node(gen, croot, true); setlocale(LC_NUMERIC, ""); const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else unsigned int length; +#endif y(get_buf, &payload, &length); /* create a temporary file if one hasn't been specified, or just @@ -324,11 +333,17 @@ char *store_restart_layout() { return NULL; } written += n; +#if YAJL_MAJOR >= 2 + printf("written: %d of %zd\n", written, length); +#else printf("written: %d of %d\n", written, length); +#endif } close(fd); - printf("layout: %.*s\n", length, payload); + if (length > 0) { + printf("layout: %.*s\n", (int)length, payload); + } y(free); diff --git a/yajl-fallback/yajl/yajl_version.h b/yajl-fallback/yajl/yajl_version.h new file mode 100644 index 00000000..c6da442e --- /dev/null +++ b/yajl-fallback/yajl/yajl_version.h @@ -0,0 +1,7 @@ +#ifndef YAJL_VERSION_H_ +#define YAJL_VERSION_H_ +/* Fallback for libyajl 1 which does not provide yajl_version.h */ +#define YAJL_MAJOR 1 +#define YAJL_MINOR 0 +#define YAJL_MICRO 0 +#endif -- 2.39.5