diff --git a/tcl-genomix/Makefile b/tcl-genomix/Makefile index b1435c00646435c3ea96920d750ea1f48f236706..9626e6bcd52a543432c4c2c22e0a1e5dff0ea046 100644 --- a/tcl-genomix/Makefile +++ b/tcl-genomix/Makefile @@ -2,8 +2,7 @@ # Created: Anthony Mallet on Fri, 19 Oct 2012 # -PKGREVISION= 1 -DISTNAME= tcl-genomix-1.3 +DISTNAME= tcl-genomix-1.4 CATEGORIES= supervision MASTER_SITES= ${MASTER_SITE_OPENROBOTS:=tcl-genomix/} MASTER_REPOSITORY= ${MASTER_REPOSITORY_OPENROBOTS}genomix/tcl-genomix diff --git a/tcl-genomix/distinfo b/tcl-genomix/distinfo index 2958c87955558709c6d2a997e0d672a6b0dd77b7..3d995f4406a72fdf489a0eb2b2034d03a2cee22e 100644 --- a/tcl-genomix/distinfo +++ b/tcl-genomix/distinfo @@ -1,4 +1,3 @@ -SHA1 (tcl-genomix-1.3.tar.gz) = 1928274c366173360c43b8f4267b282a8da6de01 -RMD160 (tcl-genomix-1.3.tar.gz) = 2cb6c5eddbd216d40c8684a54fc07b7fcc9d1f8b -Size (tcl-genomix-1.3.tar.gz) = 69678 bytes -SHA1 (patch-aa) = e05a8e9ab9fa250ffa1033d8a8c218ef4e7acbeb +SHA1 (tcl-genomix-1.4.tar.gz) = 1f59c9a4c786b703177fc2380240fd9756e44595 +RMD160 (tcl-genomix-1.4.tar.gz) = 4697cdd53bab8b60acb3808fef2bb8dd47fde1e6 +Size (tcl-genomix-1.4.tar.gz) = 307516 bytes diff --git a/tcl-genomix/patches/patch-aa b/tcl-genomix/patches/patch-aa deleted file mode 100644 index 1e371062b2b66458bd6e36f5a06d222ca7095ce8..0000000000000000000000000000000000000000 --- a/tcl-genomix/patches/patch-aa +++ /dev/null @@ -1,646 +0,0 @@ -From 22a5d059c7c0ece1cea676c07af259efdd24d11f Mon Sep 17 00:00:00 2001 -From: Anthony Mallet <anthony.mallet@laas.fr> -Date: Thu, 26 Jun 2014 17:19:40 +0200 -Subject: [PATCH] Reimplement the json to dictionary conversion in C - -Drop the pure TCL implementation (from TCLlib) of the json to dictionary -conversion, as it was not really efficient for big json strings, and implement -a custom C version. This improves the conversion speed by a factor of ~40, -noticeable for big data chunks. - -As a side effect, the package is installed under lib/ instead of shared/, as it -is not architecture independent anymore. ---- - configure.ac | 5 +- - src/Makefile.am | 13 ++- - src/json.c | 233 ++++++++++++++++++++++++++++++++++++++++ - src/json.tcl | 318 ------------------------------------------------------- - 5 files changed, 247 insertions(+), 324 deletions(-) - create mode 100644 src/json.c - delete mode 100644 src/json.tcl - -diff --git configure.ac configure.ac -index 0c101da..f149f91 100644 ---- configure.ac -+++ configure.ac -@@ -9,9 +9,10 @@ AC_INIT([tcl-genomix],[1.3],[openrobots@laas.fr]) - AC_CONFIG_AUX_DIR([autoconf]) - AC_CONFIG_MACRO_DIR([autoconf]) - AM_INIT_AUTOMAKE([foreign no-define]) -+LT_INIT - --# define sys directory (relative to datadir) --sysdir='${datadir}/${PACKAGE_NAME}' -+# define sys directory -+sysdir='${libdir}/${PACKAGE_NAME}' - AC_SUBST(sysdir) - - -diff --git src/Makefile.am src/Makefile.am -index 8832735..f18ddd9 100644 ---- src/Makefile.am -+++ src/Makefile.am -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2012 LAAS/CNRS -+# Copyright (c) 2012,2014 LAAS/CNRS - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without -@@ -31,13 +31,18 @@ dist_sys_DATA=\ - module.tcl \ - http.tcl \ - uri.tcl \ -- json.tcl \ - pmt.tcl - - nodist_sys_DATA=\ - version.tcl \ - pkgIndex.tcl - -+sys_LTLIBRARIES= json.la -+json_la_CPPFLAGS= $(TCL_INCLUDE_SPEC) -+json_la_CFLAGS= -shared -+json_la_LIBADD= $(TCL_LIB_SPEC) -+json_la_LDFLAGS= -shared -module -avoid-version -rpath $(sysdir) -+ - BUILT_SOURCES= version.tcl pkgIndex.tcl - CLEANFILES= version.tcl pkgIndex.tcl - -@@ -47,7 +52,9 @@ version.tcl: Makefile - $(ECHO) 'package provide genomix $(PACKAGE_VERSION)'; - - pkgIndex.tcl: Makefile -- l='[list source [file join $$dir version.tcl]]'; \ -+ l='[info sharedlibextension]'; \ -+ l='|[list load [file join $$dir json'"$$l"'] genomix]'; \ -+ l="$$l"'|[list source [file join $$dir version.tcl]]'; \ - for s in $(dist_sys_DATA); do \ - test -f $$s || ln -s $(srcdir)/$$s $$s; \ - l="$$l"'|[list source [file join $$dir '"$$s"']]'; \ -diff --git src/json.c src/json.c -new file mode 100644 -index 0000000..e1a9d19 ---- /dev/null -+++ src/json.c -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) 2014 LAAS/CNRS -+ * 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 and this list of conditions. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice and this list of conditions in the documentation and/or -+ * other materials provided with the distribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ * Anthony Mallet on Wed Jun 25 2014 -+ */ -+#include <string.h> -+#include <stdlib.h> -+ -+#include <tcl.h> -+ -+/* --- local data ---------------------------------------------------------- */ -+ -+#define json_skip_whitespace(json) (json) += strspn(json, " \t\n\r") -+ -+ -+/* --- j2d_tokerror -------------------------------------------------------- */ -+ -+/** Append an error message with the current token -+ */ -+static void * -+j2d_tokerror(Tcl_Interp *interp, const char *what, const char *json) -+{ -+ char tok[128]; -+ size_t s; -+ -+ s = strcspn(json, " \t\n\r{}[],:\""); -+ if (!s) s = 1; -+ if (s > sizeof(tok)-1) s = sizeof(tok)-1; -+ strncpy(tok, json, s); -+ -+ Tcl_AppendResult(interp, "unexpected ", what, " \"", tok, "\" ", NULL); -+ return NULL; -+} -+ -+ -+/* --- j2d_value ----------------------------------------------------------- */ -+ -+/** Parse a JSON value -+ */ -+static Tcl_Obj * -+j2d_value(Tcl_Interp *interp, const char **json) -+{ -+ static const char tok_null[] = "null"; -+ static const char tok_true[] = "true"; -+ static const char tok_false[] = "false"; -+ -+ json_skip_whitespace(*json); -+ switch(**json) { -+ case 0: -+ return NULL; -+ -+ case '{': /* object */ { -+ Tcl_Obj *dict = Tcl_NewDictObj(/*empty*/); -+ Tcl_Obj *k, *v; -+ -+ ++(*json); -+ json_skip_whitespace(*json); -+ while(**json != '}') { -+ /* key, string */ -+ if (**json != '"') -+ return j2d_tokerror(interp, "non-string key", *json); -+ if (!(k = j2d_value(interp, json))) return NULL; -+ -+ json_skip_whitespace(*json); -+ if (**json != ':') -+ return j2d_tokerror(interp, "element separator", *json); -+ ++(*json); -+ -+ /* value */ -+ if (!(v = j2d_value(interp, json))) return NULL; -+ if (Tcl_DictObjPut(interp, dict, k, v) != TCL_OK) return NULL; -+ -+ json_skip_whitespace(*json); -+ if (**json == ',') { -+ (*json)++; -+ json_skip_whitespace(*json); -+ } else if (**json != '}') -+ return j2d_tokerror(interp, "element", *json); -+ } -+ ++(*json); -+ -+ return dict; -+ } -+ -+ case '[': /* array */ { -+ Tcl_Obj *dict = Tcl_NewDictObj(/*empty*/); -+ Tcl_Obj *k, *v; -+ size_t i; -+ -+ ++(*json); -+ json_skip_whitespace(*json); -+ i = 0; -+ while(**json != ']') { -+ if (!(v = j2d_value(interp, json))) return NULL; -+ if (!(k = Tcl_NewIntObj(i))) return NULL; -+ if (Tcl_DictObjPut(interp, dict, k, v) != TCL_OK) return NULL; -+ -+ json_skip_whitespace(*json); -+ if (**json == ',') { -+ (*json)++; -+ json_skip_whitespace(*json); -+ } else if (**json != ']') -+ return j2d_tokerror(interp, "element", *json); -+ -+ i++; -+ } -+ ++(*json); -+ -+ return dict; -+ } -+ -+ case '"': /* string */ { -+ const char *start = ++(*json); -+ int quote = 0; -+ char *new, *p; -+ Tcl_Obj *v; -+ -+ while (**json != '"' && **json) { -+ if (**json == '\\') { -+ if (!*((*json)++)) break; -+ if (**json == '"') quote = 1; -+ } -+ (*json)++; -+ } -+ if (!**json) return j2d_tokerror(interp, "end of string", start); -+ (*json)++; -+ if (!quote) return Tcl_NewStringObj(start, *json - start - 1); -+ -+ new = malloc(*json - start); -+ if (!new) return NULL; -+ strncpy(new, start, *json - start - 1); -+ new[*json - start - 1] = 0; -+ -+ p = new; -+ while((p = strstr(p, "\\"))) { -+ if (*p == '"' || *p == '\\') -+ memmove(p, p+1, strlen(p)/*including final \0*/); -+ p++; -+ } -+ v = Tcl_NewStringObj(new, -1); -+ free(new); -+ return v; -+ } -+ -+ case 't': /* bare word: true, false, null */ -+ case 'f': -+ case 'n': -+ if (!strncmp(*json, tok_true, sizeof(tok_true)-1)) { -+ *json += sizeof(tok_true)-1; -+ return Tcl_NewStringObj(tok_true, -1); -+ } -+ if (!strncmp(*json, tok_false, sizeof(tok_false)-1)) { -+ *json += sizeof(tok_false)-1; -+ return Tcl_NewStringObj(tok_false, -1); -+ } -+ if (!strncmp(*json, tok_null, sizeof(tok_null)-1)) { -+ *json += sizeof(tok_null)-1; -+ return Tcl_NewDictObj(/*empty*/); -+ } -+ -+ return j2d_tokerror(interp, "value", *json); -+ -+ default: /* number or error */ { -+ const char *start = *json; -+ char *end; -+ -+ strtod(start, &end); -+ if (end == start) return j2d_tokerror(interp, "value", start); -+ *json = end; -+ -+ return Tcl_NewStringObj(start, *json - start); -+ } -+ } -+ -+ Tcl_AppendResult(interp, "internal error", NULL); -+ return NULL; -+} -+ -+ -+/* --- genomix::json::j2d -------------------------------------------------- */ -+ -+/** Implements the command converting a json string to a dictionary -+ */ -+static int -+j2d_cmd(ClientData d, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) -+{ -+ const char *json; -+ Tcl_Obj *v; -+ -+ if (objc != 2) { -+ Tcl_WrongNumArgs(interp, 1, objv, "json"); -+ return TCL_ERROR; -+ } -+ json = Tcl_GetString(objv[1]); -+ -+ v = j2d_value(interp, &json); -+ if (!v) return TCL_ERROR; -+ if (*json) { -+ j2d_tokerror(interp, "extra characters at", json); -+ return TCL_ERROR; -+ } -+ -+ Tcl_SetObjResult(interp, v); -+ return TCL_OK; -+} -+ -+int -+Genomix_Init(Tcl_Interp *interp) -+{ -+ if (!Tcl_CreateObjCommand( -+ interp, "genomix::json::json2dict", j2d_cmd, NULL, NULL)) -+ return TCL_ERROR; -+ -+ return TCL_OK; -+} -diff --git src/json.tcl src/json.tcl -deleted file mode 100644 -index fc8b2c3..0000000 ---- src/json.tcl -+++ /dev/null -@@ -1,318 +0,0 @@ --# --# JSON parser for Tcl (http://www.tcl.tk/software/tcllib/) --# --# See http://www.json.org/ && http://www.ietf.org/rfc/rfc4627.txt --# --# Total rework of the code published with version number 1.0 by --# Thomas Maeder, Glue Software Engineering AG --# Included here (and stripped down to just json2dict) by Anthony Mallet to --# avoid dealing with packaging issues on various unix distributions. --# --# $Id: json.tcl,v 1.7 2011/11/10 21:05:58 andreas_kupries Exp $ --# --# This software is copyrighted by Ajuba Solutions and other parties. --# --# The authors hereby grant permission to use, copy, modify, distribute, --# and license this software and its documentation for any purpose, provided --# that existing copyright notices are retained in all copies and that this --# notice is included verbatim in any distributions. No written agreement, --# license, or royalty fee is required for any of the authorized uses. --# Modifications to this software may be copyrighted by their authors --# and need not follow the licensing terms described here, provided that --# the new terms are clearly indicated on the first page of each file where --# they apply. --# --# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY --# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES --# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY --# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE --# POSSIBILITY OF SUCH DAMAGE. --# --# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, --# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, --# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE --# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE --# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR --# MODIFICATIONS. --# --# GOVERNMENT USE: If you are acquiring this software on behalf of the --# U.S. government, the Government shall have only "Restricted Rights" --# in the software and related documentation as defined in the Federal --# Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you --# are acquiring the software on behalf of the Department of Defense, the --# software shall be classified as "Commercial Computer Software" and the --# Government shall have only "Restricted Rights" as defined in Clause --# 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the --# authors grant the U.S. Government and others acting in its behalf --# permission to use and distribute the software in accordance with the --# terms specified in this license. -- --namespace eval genomix::json { -- # Regular expression for tokenizing a JSON text (cf. http://json.org/) -- -- # tokens consisting of a single character -- variable singleCharTokens { "{" "}" ":" "\\[" "\\]" "," } -- variable singleCharTokenRE "\[[join $singleCharTokens {}]\]" -- -- # quoted string tokens -- variable escapableREs { "[\\\"\\\\/bfnrt]" "u[[:xdigit:]]{4}" } -- variable escapedCharRE "\\\\(?:[join $escapableREs |])" -- variable unescapedCharRE {[^\\\"]} -- variable stringRE "\"(?:$escapedCharRE|$unescapedCharRE)*\"" -- -- # (unquoted) words -- variable wordTokens { "true" "false" "null" } -- variable wordTokenRE [join $wordTokens "|"] -- -- # number tokens -- # negative lookahead (?!0)[[:digit:]]+ might be more elegant, but -- # would slow down tokenizing by a factor of up to 3! -- variable positiveRE {[1-9][[:digit:]]*} -- variable cardinalRE "-?(?:$positiveRE|0)" -- variable fractionRE {[.][[:digit:]]+} -- variable exponentialRE {[eE][+-]?[[:digit:]]+} -- variable numberRE "${cardinalRE}(?:$fractionRE)?(?:$exponentialRE)?" -- -- # JSON token -- variable tokenRE "$singleCharTokenRE|$stringRE|$wordTokenRE|$numberRE" -- -- # 0..n white space characters -- set whiteSpaceRE {[[:space:]]*} -- -- # Regular expression for validating a JSON text -- variable validJsonRE "^(?:${whiteSpaceRE}(?:$tokenRE))*${whiteSpaceRE}$" -- -- -- # Parse JSON text into a dict -- # @param jsonText JSON text -- # @return dict (or list) containing the object represented by $jsonText -- proc json2dict {jsonText} { -- variable tokenRE -- -- set tokens [regexp -all -inline -- $tokenRE $jsonText] -- set nrTokens [llength $tokens] -- set tokenCursor 0 -- return [parseValue $tokens $nrTokens tokenCursor] -- } -- -- # Throw an exception signaling an unexpected token -- proc unexpected {tokenCursor token expected} { -- return -code error "unexpected token \"$token\" at position $tokenCursor; expecting $expected" -- } -- -- # Get rid of the quotes surrounding a string token and substitute the -- # real characters for escape sequences within it -- # @param token -- # @return unquoted unescaped value of the string contained in $token -- proc unquoteUnescapeString {token} { -- set unquoted [string range $token 1 end-1] -- return [subst -nocommands -novariables $unquoted] -- } -- -- # Parse an object member -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @param objectDictName name (in caller's context) of dict -- # representing the JSON object of which to -- # parse the next member -- proc parseObjectMember {tokens nrTokens tokenCursorName objectDictName} { -- upvar $tokenCursorName tokenCursor -- upvar $objectDictName objectDict -- -- set token [lindex $tokens $tokenCursor] -- incr tokenCursor -- -- set leadingChar [string index $token 0] -- if {$leadingChar eq "\""} { -- set memberName [unquoteUnescapeString $token] -- -- if {$tokenCursor == $nrTokens} { -- unexpected $tokenCursor "END" "\":\"" -- } else { -- set token [lindex $tokens $tokenCursor] -- incr tokenCursor -- -- if {$token eq ":"} { -- set memberValue [parseValue $tokens $nrTokens tokenCursor] -- dict set objectDict $memberName $memberValue -- } else { -- unexpected $tokenCursor $token "\":\"" -- } -- } -- } else { -- unexpected $tokenCursor $token "STRING" -- } -- } -- -- # Parse the members of an object -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @param objectDictName name (in caller's context) of dict -- # representing the JSON object of which to -- # parse the next member -- proc parseObjectMembers {tokens nrTokens tokenCursorName objectDictName} { -- upvar $tokenCursorName tokenCursor -- upvar $objectDictName objectDict -- -- while true { -- parseObjectMember $tokens $nrTokens tokenCursor objectDict -- -- set token [lindex $tokens $tokenCursor] -- incr tokenCursor -- -- switch -exact $token { -- "," { -- # continue -- } -- "\}" { -- break -- } -- default { -- unexpected $tokenCursor $token "\",\"|\"\}\"" -- } -- } -- } -- } -- -- # Parse an object -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @return parsed object (Tcl dict) -- proc parseObject {tokens nrTokens tokenCursorName} { -- upvar $tokenCursorName tokenCursor -- -- if {$tokenCursor == $nrTokens} { -- unexpected $tokenCursor "END" "OBJECT" -- } else { -- set result [dict create] -- -- set token [lindex $tokens $tokenCursor] -- -- if {$token eq "\}"} { -- # empty object -- incr tokenCursor -- } else { -- parseObjectMembers $tokens $nrTokens tokenCursor result -- } -- -- return $result -- } -- } -- -- # Parse the elements of an array -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @param resultName name (in caller's context) of the list -- # representing the JSON array -- proc parseArrayElements {tokens nrTokens tokenCursorName resultName} { -- upvar $tokenCursorName tokenCursor -- upvar $resultName result -- -- while true { -- lappend result [parseValue $tokens $nrTokens tokenCursor] -- -- if {$tokenCursor == $nrTokens} { -- unexpected $tokenCursor "END" "\",\"|\"\]\"" -- } else { -- set token [lindex $tokens $tokenCursor] -- incr tokenCursor -- -- switch -exact $token { -- "," { -- # continue -- } -- "\]" { -- break -- } -- default { -- unexpected $tokenCursor $token "\",\"|\"\]\"" -- } -- } -- } -- } -- } -- -- # Parse an array -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @return parsed array (Tcl list) -- proc parseArray {tokens nrTokens tokenCursorName} { -- upvar $tokenCursorName tokenCursor -- -- if {$tokenCursor == $nrTokens} { -- unexpected $tokenCursor "END" "ARRAY" -- } else { -- set result {} -- -- set token [lindex $tokens $tokenCursor] -- -- set leadingChar [string index $token 0] -- if {$leadingChar eq "\]"} { -- # empty array -- incr tokenCursor -- } else { -- parseArrayElements $tokens $nrTokens tokenCursor result -- } -- -- return $result -- } -- } -- -- # Parse a value -- # @param tokens list of tokens -- # @param nrTokens length of $tokens -- # @param tokenCursorName name (in caller's context) of variable -- # holding current position in $tokens -- # @return parsed value (dict, list, string, number) -- proc parseValue {tokens nrTokens tokenCursorName} { -- upvar $tokenCursorName tokenCursor -- -- if {$tokenCursor == $nrTokens} { -- unexpected $tokenCursor "END" "VALUE" -- } else { -- set token [lindex $tokens $tokenCursor] -- incr tokenCursor -- -- set leadingChar [string index $token 0] -- switch -exact -- $leadingChar { -- "\{" { -- return [parseObject $tokens $nrTokens tokenCursor] -- } -- "\[" { -- return [parseArray $tokens $nrTokens tokenCursor] -- } -- "\"" { -- # quoted string -- return [unquoteUnescapeString $token] -- } -- "t" - -- "f" { -- # bare word: true, false -- return $token -- } -- "n" { -- # bare word: null -- return [list] -- } -- default { -- # number? -- if {[string is double -strict $token]} { -- return $token -- } else { -- unexpected $tokenCursor $token "VALUE" -- } -- } -- } -- } -- } --} --- -1.7.9.5 -