[stat_cache] FAM: funcs to invalidate entries

--- src/stat_cache.c
+++ src/stat_cache.c
@@ -58,8 +58,9 @@
  * - a splay-tree is used as we can use the caching effect of it
  */

-/* we want to cleanup the stat-cache every few seconds, let's say 10
- *
+/* we want to cleanup the FAM stat-cache every few seconds, let's say 10
+ *
+ * - (NOT CURRENTLY DONE)
  * - remove entries which are outdated since 30s
  * - remove entries which are fresh but havn't been used since 60s
  * - if we don't have a stat-cache entry for a directory, release it from the monitor
@@ -102,6 +103,16 @@
 }

+static void * stat_cache_sptree_find(splay_tree ** const sptree,
+                                     const char * const name,
+                                     size_t len)
+{
+    const int ndx = hashme(name, len);
+    *sptree = splaytree_splay(*sptree, ndx);
+    return (*sptree && (*sptree)->key == ndx) ? (*sptree)->data : NULL;
+}
+
+
 #ifdef HAVE_FAM_H

 #include <fam.h>
@@ -146,25 +157,70 @@
 	free(fam_dir);
 }

+static void fam_dir_node_delete(stat_cache_fam *scf, const char *name, size_t len)
+{
+    splay_tree **sptree = &scf->dirs;
+    fam_dir_entry *fam_dir =
+      stat_cache_sptree_find(sptree, name, len);
+    if (fam_dir && buffer_is_equal_string(fam_dir->name, name, len)) {
+        fam_dir_entry_free(&scf->fam, fam_dir);
+        *sptree = splaytree_delete(*sptree, (*sptree)->key);
+    }
+}
+
+/*
+ * walk though splay_tree and collect contents of dir tree.
+ * remove tagged entries in a second loop
+ */
+
+static void fam_dir_tag_tree(splay_tree *t, const char *name, size_t len,
+                             int *keys, int *ndx)
+{
+    if (*ndx == 8192) return; /*(must match num array entries in keys[])*/
+    if (t->left)  fam_dir_tag_tree(t->left,  name, len, keys, ndx);
+    if (t->right) fam_dir_tag_tree(t->right, name, len, keys, ndx);
+    if (*ndx == 8192) return; /*(must match num array entries in keys[])*/
+
+    buffer *b = ((fam_dir_entry *)t->data)->name;
+    size_t blen = buffer_string_length(b);
+    if (blen > len && b->ptr[len] == '/' && 0 == memcmp(b->ptr, name, len))
+        keys[(*ndx)++] = t->key;
+}
+
+static void fam_dir_prune_tree(stat_cache_fam * const scf,
+                               const char *name, size_t len)
+{
+    int max_ndx, i;
+    int keys[8192]; /* 32k size on stack */
+    do {
+        if (!scf->dirs) return;
+        max_ndx = 0;
+        fam_dir_tag_tree(scf->dirs, name, len, keys, &max_ndx);
+        for (i = 0; i < max_ndx; ++i) {
+            const int ndx = keys[i];
+            splay_tree *node = scf->dirs = splaytree_splay(scf->dirs, ndx);
+            if (node && node->key == ndx) {
+                fam_dir_entry_free(&scf->fam, node->data);
+                scf->dirs = splaytree_delete(scf->dirs, ndx);
+            }
+        }
+    } while (max_ndx == sizeof(keys)/sizeof(int));
+}
+
 static handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
-	size_t i;
 	stat_cache_fam *scf = srv->stat_cache->scf;
-	size_t events;
-
 	UNUSED(_fce);
-	/* */

 	if (revent & FDEVENT_IN) {
-		events = FAMPending(&scf->fam);
-
-		for (i = 0; i < events; i++) {
+		for (int i = 0, ndx; i || (i = FAMPending(&scf->fam)) > 0; --i) {
 			FAMEvent fe;
 			if (FAMNextEvent(&scf->fam, &fe) < 0) break;

 			/* ignore events which may have been pending for
 			 * paths recently cancelled via FAMCancelMonitor() */
-			scf->dirs = splaytree_splay(scf->dirs, (int)(intptr_t)fe.userdata);
-			if (!scf->dirs || scf->dirs->key != (int)(intptr_t)fe.userdata) {
+			ndx = (int)(intptr_t)fe.userdata;
+			scf->dirs = splaytree_splay(scf->dirs, ndx);
+			if (!scf->dirs || scf->dirs->key != ndx) {
 				continue;
 			}
 			fam_dir_entry *fam_dir = scf->dirs->data;
@@ -195,14 +251,16 @@
 				continue;
 			}

+			/*expect: buffer_is_equal_string(fam_dir->name, fe.filename, strlen(fe.filename))*/
 			switch(fe.code) {
 			case FAMChanged:
 				++fam_dir->version;
 				break;
 			case FAMDeleted:
 			case FAMMoved:
+				scf->dirs = splaytree_delete(scf->dirs, ndx);
+				fam_dir_prune_tree(scf, CONST_BUF_LEN(fam_dir->name));
 				fam_dir_entry_free(&scf->fam, fam_dir);
-				scf->dirs = splaytree_delete(scf->dirs, scf->dirs->key);
 				break;
 			default:
 				break;
@@ -749,8 +807,8 @@
 }

 /**
- * remove stat() from cache which havn't been stat()ed for
- * more than 10 seconds
+ * remove stat() from cache which haven't been stat()ed for
+ * more than 2 seconds
  *
  *
  * walk though the stat-cache, collect the ids which are too old


link/ipip: Include own public header for function prototypes

Include the own public header in order to get function prototypes for
all public functions defined in this module.

This fixes GCC -Wmissing-prototype warnings.

Signed-off-by: Tobias Klauser <9249c549618448e4c699e8032ba6c7f0d7fd4b7f@distanz.ch>

--- lib/route/link/ipip.c
+++ lib/route/link/ipip.c
@@ -28,6 +28,7 @@
 #include <netlink/utils.h>
 #include <netlink/object.h>
 #include <netlink/route/rtnl.h>
+#include <netlink/route/link/ipip.h>
 #include <netlink-private/route/link/api.h>
 #include <linux/if_tunnel.h>


[core] attempt to quiet some coverity warnings

--- src/stat_cache.c
+++ src/stat_cache.c
@@ -374,6 +374,7 @@
             struct inotify_event * const in =
               (struct inotify_event *)((uintptr_t)buf + i);
             uint32_t len = in->len;
+            if (len > sizeof(buf)) break; /*(should not happen)*/
             i += sizeof(struct inotify_event) + len;
             if (i > rd) break; /*(should not happen (partial record))*/
             if (in->mask & IN_CREATE)


single nexthop flags bug

single nexthop flags bug

I ran into a bug today related to how Linux handles a route's nexthop
flags when there is just one nexthop.  Namely Linux expects the flags
to be OR'd into the rtm_flags field when there is only one nexthop and
so rtnl_route_build_msg needs to check the number of nexthops and
store the nexthops flags into this field prior to calling
nlmsg_append(...&rtmsg).

Conversely the rtnl_route_parse function needs to pull these lower
0xff bits when a single nexthop is detected.

Attached is my patch.  I don't like the slight duplication of doing
the rtnl_route_get_nnexthops check twice but it seemed to be the least
turmoil of any solution I thought of.

--- lib/route/route_obj.c
+++ lib/route/route_obj.c
@@ -986,6 +986,7 @@
 	}

 	if (old_nh) {
+		rtnl_route_nh_set_flags(old_nh, rtm->rtm_flags & 0xff);
 		if (route->rt_nr_nh == 0) {
 			/* If no nexthops have been provided via RTA_MULTIPATH
 			 * we add it as regular nexthop to maintain backwards
@@ -1045,9 +1046,14 @@
 	if (route->rt_src)
 		rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src);

-
 	if (rtmsg.rtm_scope == RT_SCOPE_NOWHERE)
 		rtmsg.rtm_scope = rtnl_route_guess_scope(route);
+
+	if (rtnl_route_get_nnexthops(route) == 1) {
+		struct rtnl_nexthop *nh;
+		nh = rtnl_route_nexthop_n(route, 0);
+		rtmsg.rtm_flags |= nh->rtnh_flags;
+	}

 	if (nlmsg_append(msg, &rtmsg, sizeof(rtmsg), NLMSG_ALIGNTO) < 0)
 		goto nla_put_failure;


ilong long story..

ilong long story..

--- src/stunserver.c
+++ src/stunserver.c
@@ -92,7 +92,7 @@
   struct timespec timer;
   struct timespec remaining;
   (void) ptr;
-  uint64_t a[5], b[5];
+  unsigned long long a[5], b[5];
   //char str[7];
   FILE *fp;

@@ -103,7 +103,7 @@
   {
     fp = fopen("/proc/stat","r");
     if(fp){
-    fscanf(fp,"%*s %llu %llu %llu %llu %llu",&a[0],&a[1],&a[2],&a[3], &a[4]);
+    fscanf(fp,"%*s %llu %llu %llu %llu",&a[1],&a[2],&a[3], &a[4]);
     fclose(fp);
     }
     nanosleep(&timer, &remaining);


Bug dans assertion d'alloc_bigarray

Bug dans assertion d'alloc_bigarray

git-svn-id: e7e61699ce1738538ffebb75374fbea0924bc775@4425 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02

--- otherlibs/bigarray/bigarray_stubs.c
+++ otherlibs/bigarray/bigarray_stubs.c
@@ -87,7 +87,7 @@
   struct caml_bigarray * b;

   Assert(num_dims >= 1 && num_dims <= MAX_NUM_DIMS);
-  Assert((flags & BIGARRAY_KIND_MASK) <= BIGARRAY_NATIVE_INT);
+  Assert((flags & BIGARRAY_KIND_MASK) <= BIGARRAY_COMPLEX64);
   size = 0;
   if (data == NULL) {
     num_elts = 1;


coming back konoha.regex

coming back konoha.regex

--- package/konoha.regexp/regexp_glue.c
+++ package/konoha.regexp/regexp_glue.c
@@ -1,61 +1,62 @@
-///****************************************************************************
-// * Copyright (c) 2012, the Konoha project authors. All rights reserved.
-// * Redistribution and use in source and binary forms, with or without
-// * modification, are permitted provided that the following conditions are met:
-// *
-// *  * Redistributions of source code must retain the above copyright notice,
-// *    this list of conditions and the following disclaimer.
-// *  * 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.
-// *
-// * 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 HOLDER 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.
-// ***************************************************************************/
-//
-//#define USE_STRINGLIB 1
-//
-//#include <minikonoha/minikonoha.h>
-//#include <minikonoha/sugar.h>
-//#include <minikonoha/klib.h>
-//#include <pcre.h>
-//
-//#ifdef __cplusplus
-//extern "C" {
-//#endif
-//
-//#define CT_StringArray0        CT_p0(kctx, CT_Array, TY_String)
-//
-///* ------------------------------------------------------------------------ */
-///* regexp module */
-////## @Immutable class RegExp Object;
-////## flag RegExp Global      1 - is set * *;
-////## flag RegExp IgnoreCase  2 - is set * *; // it is used only for RegExp_p
-////## flag RegExp Multiline   3 - is set * *; // it is used only for RegExp_p
-//
-//#define RegExp_isGlobal(o)        (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local1))
-//#define RegExp_setGlobal(o,b)     TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local1,b)
-//#define RegExp_isIgnoreCase(o)    (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local2))
-//#define RegExp_setIgnoreCase(o,b) TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local2,b)
-//#define RegExp_isMultiline(o)     (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local3))
-//#define RegExp_setMultiline(o,b)  TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local3,b)
-//
-//typedef void kregexp_t;
-//
-///* REGEXP_SPI */
-//#ifndef KREGEXP_MATCHSIZE
-//#define KREGEXP_MATCHSIZE    16
-//#endif
-//
+/****************************************************************************
+ * Copyright (c) 2012, the Konoha project authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * 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.
+ *
+ * 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 HOLDER 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.
+ ***************************************************************************/
+
+#define USE_STRINGLIB 1
+
+#include <minikonoha/minikonoha.h>
+#include <minikonoha/sugar.h>
+#include <minikonoha/klib.h>
+#include <pcre.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CT_StringArray0        CT_p0(kctx, CT_Array, TY_String)
+
+/* ------------------------------------------------------------------------ */
+/* regexp module */
+
+//## @Immutable class RegExp Object;
+//## flag RegExp Global      1 - is set * *;
+//## flag RegExp IgnoreCase  2 - is set * *; // it is used only for RegExp_p
+//## flag RegExp Multiline   3 - is set * *; // it is used only for RegExp_p
+
+#define RegExp_isGlobal(o)        (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local1))
+#define RegExp_setGlobal(o,b)     TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local1,b)
+#define RegExp_isIgnoreCase(o)    (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local2))
+#define RegExp_setIgnoreCase(o,b) TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local2,b)
+#define RegExp_isMultiline(o)     (TFLAG_is(uintptr_t,(o)->h.magicflag,kObject_Local3))
+#define RegExp_setMultiline(o,b)  TFLAG_set(uintptr_t,(o)->h.magicflag,kObject_Local3,b)
+
+typedef void kregexp_t;
+
+/* REGEXP_SPI */
+#ifndef KREGEXP_MATCHSIZE
+#define KREGEXP_MATCHSIZE    16
+#endif
+
 //typedef struct {
 //	size_t       len;
 //	union {
@@ -65,800 +66,720 @@
 //		//kchar_t *ubuf;
 //	};
 //} kbytes_t;
-//
-//static size_t knh_bytes_mlen(kbytes_t v)
-//{
-//#ifdef K_USING_UTF8
-//	size_t size = 0;
-//	const unsigned char *s = v.utext;
-//	const unsigned char *e = s + v.len;
-//	while (s < e) {
-//		size_t ulen = utf8len(s[0]);
-//		size ++;
-//		s += ulen;
-//	}
-//	return size;
-//#else
-//	return v.len;
-//#endif
-//}
-//
-//static kbytes_t knh_bytes_mofflen(kbytes_t v, size_t moff, size_t mlen)
-//{
-//#ifdef K_USING_UTF8
-//	size_t i;
-//	const unsigned char *s = v.utext;
-//	const unsigned char *e = s + v.len;
-//	for(i = 0; i < moff; i++) {
-//		s += utf8len(s[0]);
-//	}
-//	v.buf = (char*)s;
-//	for(i = 0; i < mlen; i++) {
-//		s += utf8len(s[0]);
-//	}
-//	KNH_ASSERT(s <= e);
-//	v.len = (const char*)s - v.text;
-//	return v;
-//#else
-//	return knh_bytes_subbytes(m, moff, mlen); /* if K_ENCODING is not set */
-//#endif
-//}
-//
-//#define _ALWAYS StringPolicy_POOL
-//#define _NEVER  StringPolicy_POOL
+
+static size_t utf8_strlen(const char *text, size_t len)
+{
+	size_t size = 0;
+	const unsigned char *s = (const unsigned char*)text;
+	const unsigned char *eos = s + len;
+	while (s < eos) {
+		size_t ulen = utf8len(s[0]);
+		size++;
+		s += ulen;
+	}
+	return size;
+}
+
+//#define _ALWAYS 0/*StringPolicy_POOL*/
+//#define _NEVER  0/*StringPolicy_POOL*/
 //#define _ASCII  StringPolicy_ASCII
 //#define _UTF8   StringPolicy_UTF8
 //#define _SUB(s0) (S_isASCII(s0) ? _ASCII|_ALWAYS : _ALWAYS)
 //#define _SUBCHAR(s0) (S_isASCII(s0) ? _ASCII : 0)
 //#define _CHARSIZE(len) (len==1 ? _ASCII : _UTF8)
-//
-//static kArray *kStringToCharArray(KonohaContext *kctx, kString *bs, int istrim, kint_t limit)
+
+typedef struct {
+	pcre *re;
+	const char *err;
+	int erroffset;
+} PCRE_regexp_t;
+
+/* ------------------------------------------------------------------------ */
+
+#define kregexpshare      ((kregexpshare_t*)kctx->modshare[MOD_REGEXP])
+#define CT_RegExp         kregexpshare->cRegExp
+#define TY_RegExp         kregexpshare->cRegExp->typeId
+
+#define IS_RegExp(O)      ((O)->h.ct == CT_RegExp)
+
+typedef struct {
+	KonohaModule h;
+	KonohaClass *cRegExp;
+} kregexpshare_t;
+
+typedef struct kRegExp kRegExp;
+struct kRegExp {
+	KonohaObjectHeader h;
+	kregexp_t *reg;
+	int eflags;      // regexp flag
+	kString *pattern;
+	size_t lastIndex; // last matched index
+};
+
+typedef struct {
+	int rm_so;   /* start of match */
+	int rm_eo;   /* end of match */
+	const unsigned char *rm_name;
+	size_t      rm_namelen;
+} kregmatch_t;
+
+/* ------------------------------------------------------------------------ */
+
+static kregexp_t* pcre_regmalloc(KonohaContext *kctx, kString* s)
+{
+	PCRE_regexp_t *preg = (PCRE_regexp_t*) KMalloc_UNTRACE(sizeof(PCRE_regexp_t));
+	return (kregexp_t *) preg;
+}
+
+static void pcre_regfree(KonohaContext *kctx, kregexp_t *reg)
+{
+	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
+	pcre_free(preg->re);
+	KFree(preg, sizeof(PCRE_regexp_t));
+}
+
+static int pcre_nmatchsize(KonohaContext *kctx, kregexp_t *reg)
+{
+	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
+	int capsize = 0;
+	if(pcre_fullinfo(preg->re, NULL, PCRE_INFO_CAPTURECOUNT, &capsize) != 0) {
+		return KREGEXP_MATCHSIZE;
+	}
+	return capsize + 1;
+}
+
+static int pcre_parsecflags(KonohaContext *kctx, const char *option)
+{
+	int i, cflags = 0;
+	int optlen = strlen(option);
+	for (i = 0; i < optlen; i++) {
+		switch(option[i]) {
+		case 'i': // caseless
+			cflags |= PCRE_CASELESS;
+			break;
+		case 'm': // multiline
+			cflags |= PCRE_MULTILINE;
+			break;
+		case 's': // dotall
+			cflags |= PCRE_DOTALL;
+			break;
+		case 'x': //extended
+			cflags |= PCRE_EXTENDED;
+			break;
+		case 'u': //utf
+			cflags |= PCRE_UTF8;
+			break;
+		default: break;
+		}
+	}
+	return cflags;
+}
+
+static int pcre_parseeflags(KonohaContext *kctx, const char *option)
+{
+	int i, eflags = 0;
+	int optlen = strlen(option);
+	for (i = 0; i < optlen; i++) {
+		switch(option[i]){
+		default: break;
+		}
+	}
+	return eflags;
+}
+
+//static size_t pcre_regerror(int res, kregexp_t *reg, char *ebuf, size_t ebufsize)
 //{
-//	kbytes_t base = {S_size(bs), {S_text(bs)}};
-//	size_t i, n = (S_isASCII(bs) ? base.len : knh_bytes_mlen(base));
-//	if(limit >= 0 && limit < n) {
-//		/* limit array size */
-//		n = limit;
-//	}
-//	kArray *a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 0);
-//	kString *s = NULL;
-//	for(i = 0; i < n; i++) {
-//		if(istrim && isspace(base.utext[i])) continue;
-//		if(S_isASCII(bs)) {
-//			s = KLIB new_kString(kctx, base.text+i, 1, _ALWAYS|_ASCII);
-//		}
-//		else {
-//			kbytes_t sub = knh_bytes_mofflen(base, i, 1);
-//			s = KLIB new_kString(kctx, sub.text, sub.len, _ALWAYS|((sub.len == 1) ? _ASCII:_UTF8));
-//		}
-//		KLIB kArray_add(kctx, a, s);
-//	}
-//	return a;
+//	PCRE_regexp_t *pcre = (PCRE_regexp_t*)reg;
+//	snprintf(ebuf, ebufsize, "[%d]: %s", pcre->erroffset, pcre->err);
+//	return (pcre->err != NULL) ? strlen(pcre->err) : 0;
 //}
-//
-//static kString *kwb_newString(KonohaContext *kctx, KGrowingBuffer *wb, int flg)
-//{
-//	return KLIB new_kString(kctx, KLIB Kwb_top(kctx, wb, flg), Kwb_bytesize(wb), StringPolicy_POOL);
-//}
-//
-//typedef struct {
-//	pcre *re;
-//	const char *err;
-//	int erroffset;
-//} PCRE_regexp_t;
-//
-///* ------------------------------------------------------------------------ */
-//#define kregexpshare      ((kregexpshare_t*)kctx->modshare[MOD_REGEXP])
-//#define CT_RegExp         kregexpshare->cRegExp
-//#define TY_RegExp         kregexpshare->cRegExp->typeId
-//
-//#define IS_RegExp(O)      ((O)->h.ct == CT_RegExp)
-//
-//typedef struct {
-//	KonohaModule h;
-//	KonohaClass *cRegExp;
-//} kregexpshare_t;
-//
-//typedef struct kRegExp kRegExp;
-//struct kRegExp {
-//	KonohaObjectHeader h;
-//	kregexp_t *reg;
-//	int eflags;      // regexp flag
-//	kString *pattern;
-//	size_t lastIndex; // last matched index
-//};
-//
-//typedef struct {
-//	int rm_so;   /* start of match */
-//	int rm_eo;   /* end of match */
-//	kbytes_t rm_name;  /* {NULL, 0}, if not NAMED */
-//} kregmatch_t;
-//
-///* ------------------------------------------------------------------------ */
-//
-//static kregexp_t* pcre_regmalloc(KonohaContext *kctx, kString* s)
-//{
-//	PCRE_regexp_t *preg = (PCRE_regexp_t*) KMalloc_UNTRACE(sizeof(PCRE_regexp_t));
-//	return (kregexp_t *) preg;
-//}
-//
-//static void pcre_regfree(KonohaContext *kctx, kregexp_t *reg)
-//{
-//	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
-//	pcre_free(preg->re);
-//	KFree(preg, sizeof(PCRE_regexp_t));
-//}
-//
-//static int pcre_nmatchsize(KonohaContext *kctx, kregexp_t *reg)
-//{
-//	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
-//	int capsize = 0;
-//	if(pcre_fullinfo(preg->re, NULL, PCRE_INFO_CAPTURECOUNT, &capsize) != 0) {
-//		return KREGEXP_MATCHSIZE;
-//	}
-//	return capsize + 1;
-//}
-//
-//static int pcre_parsecflags(KonohaContext *kctx, const char *option)
-//{
-//	int i, cflags = 0;
-//	int optlen = strlen(option);
-//	for (i = 0; i < optlen; i++) {
-//		switch(option[i]) {
-//		case 'i': // caseless
-//			cflags |= PCRE_CASELESS;
-//			break;
-//		case 'm': // multiline
-//			cflags |= PCRE_MULTILINE;
-//			break;
-//		case 's': // dotall
-//			cflags |= PCRE_DOTALL;
-//			break;
-//		case 'x': //extended
-//			cflags |= PCRE_EXTENDED;
-//			break;
-//		case 'u': //utf
-//			cflags |= PCRE_UTF8;
-//			break;
-//		default: break;
-//		}
-//	}
-//	return cflags;
-//}
-//
-//static int pcre_parseeflags(KonohaContext *kctx, const char *option)
-//{
-//	int i, eflags = 0;
-//	int optlen = strlen(option);
-//	for (i = 0; i < optlen; i++) {
-//		switch(option[i]){
-//		default: break;
-//		}
-//	}
-//	return eflags;
-//}
-//
-////static size_t pcre_regerror(int res, kregexp_t *reg, char *ebuf, size_t ebufsize)
-////{
-////	PCRE_regexp_t *pcre = (PCRE_regexp_t*)reg;
-////	snprintf(ebuf, ebufsize, "[%d]: %s", pcre->erroffset, pcre->err);
-////	return (pcre->err != NULL) ? strlen(pcre->err) : 0;
-////}
-//
-//static int pcre_regcomp(KonohaContext *kctx, kregexp_t *reg, const char *pattern, int cflags)
-//{
-//	PCRE_regexp_t* preg = (PCRE_regexp_t*)reg;
-//	preg->re = pcre_compile(pattern, cflags, &preg->err, &preg->erroffset, NULL);
-//	return (preg->re != NULL) ? 0 : -1;
-//}
-//
-//static int pcre_regexec(KonohaContext *kctx, kregexp_t *reg, const char *str, size_t nmatch, kregmatch_t p[], int eflags)
-//{
-//	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
-//	int res, nm_count, nvector[nmatch*3];
-//	nvector[0] = 0;
-//	size_t idx, matched = nmatch;
-//	if(strlen(str) == 0) return -1;
-//	if((res = pcre_exec(preg->re, NULL, str, strlen(str), 0, eflags, nvector, nmatch*3)) >= 0) {
-//		matched = (res > 0 && res < nmatch) ? res : nmatch;
-//		res = 0;
-//		for (idx = 0; idx < matched; idx++) {
-//			p[idx].rm_so = nvector[2*idx];
-//			p[idx].rm_eo = nvector[2*idx+1];
-//		}
-//		p[idx].rm_so = -1;
-//		nm_count = 0;
-//		pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMECOUNT, &nm_count);
-//		if(nm_count > 0) {
-//			unsigned char *nm_table;
-//			int nm_entry_size = 0;
-//			pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMETABLE, &nm_table);
-//			pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nm_entry_size);
-//			unsigned char *tbl_ptr = nm_table;
-//			for (idx = 0; idx < nm_count; idx++) {
-//				int n_idx = (tbl_ptr[0] << 8) | tbl_ptr[1];
-//				unsigned char *n_name = tbl_ptr + 2;
-//				p[n_idx].rm_name.utext = n_name;
-//				p[n_idx].rm_name.len = strlen((char*)n_name);
-//				tbl_ptr += nm_entry_size;
-//			}
-//		}
-//	}
-//	return res;
-//}
-//
-///* ------------------------------------------------------------------------ */
-//static void kregexpshare_setup(KonohaContext *kctx, struct KonohaModule *def, int newctx)
-//{
-//}
-//
-//static void kregexpshare_reftrace(KonohaContext *kctx, struct KonohaModule *baseh, KObjectVisitor *visitor)
-//{
-//}
-//
-//static void kregexpshare_free(KonohaContext *kctx, struct KonohaModule *baseh)
-//{
-//	KFree(baseh, sizeof(kregexpshare_t));
-//}
-//
-///* ------------------------------------------------------------------------ */
-//static void knh_RegExp_setOptions(kRegExp *re, const char *option)
-//{
-//	size_t i, optlen = strlen(option);
-//	for(i = 0; i < optlen; i++) {
-//		switch(option[i]) {
-//		case 'g':
-//			RegExp_setGlobal(re, 1);
-//			break;
-//		case 'i':
-//			RegExp_setIgnoreCase(re, 1);
-//			break;
-//		case 'm':
-//			RegExp_setMultiline(re, 1);
-//		default:
-//			break;
-//		}
-//	}
-//}
-//
-//static size_t knh_regexp_matched(kregmatch_t* r, size_t maxmatch)
-//{
-//	size_t n = 0;
-//	for (; n < maxmatch && r[n].rm_so != -1; n++) {}
-//	return n;
-//}
-//
-//static void WB_write_regexpfmt(KonohaContext *kctx, KGrowingBuffer *wb, kbytes_t *fmt, const char *base, kregmatch_t *r, size_t matched)
-//{
-//	const char *ch = fmt->text;
-//	const char *eof = ch + fmt->len; // end of fmt
-//	char buf[1];
-//	for (; ch < eof; ch++) {
-//		if(*ch == '\\') {
-//			buf[0] = *ch;
-//			KLIB Kwb_write(kctx, wb, buf, 1);
-//			ch++;
-//		} else if(*ch == '$' && isdigit(ch[1])) {
-//			size_t grpidx = (size_t)ch[1] - '0'; // get head of grourp_index
-//			if(grpidx < matched) {
-//				ch++;
-//				while (isdigit(ch[1])) {
-//					size_t nidx = grpidx * 10 + (ch[1] - '0');
-//					if(nidx < matched) {
-//						grpidx = nidx;
-//						ch++;
-//						if(ch < eof) {
-//							continue;
-//						}
-//					}
-//				}
-//				kregmatch_t *rp = &r[grpidx];
-//				KLIB Kwb_write(kctx, wb, base + rp->rm_so, rp->rm_eo - rp->rm_so);
-//				continue; // skip putc
-//			}
-//		}
-//		buf[0] = *ch;
-//		KLIB Kwb_write(kctx, wb, buf, 1);
-//	}
-//}
-//
-//static void RegExp_init(KonohaContext *kctx, kObject *o, void *conf)
-//{
-//	kRegExp *re = (kRegExp*)o;
-//	re->reg = NULL;
-//	re->eflags = 0;
-//	re->pattern = KNULL(String);
-//	re->lastIndex = 0;
-//}
-//
-//static void RegExp_free(KonohaContext *kctx, kObject *o)
-//{
-//	kRegExp *re = (kRegExp*)o;
-//	if(re->reg != NULL) {
-//		pcre_regfree(kctx, re->reg);
-//	}
-//}
-//
-//static void RegExp_p(KonohaContext *kctx, KonohaValue *v, int pos, KGrowingBuffer *wb)
-//{
-//	kRegExp *re = v[pos].asRegExp;
-//	KLIB Kwb_printf(kctx, wb, "/%s/%s%s%s", S_text(re->pattern),
-//			RegExp_isGlobal(re) ? "g" : "",
-//			RegExp_isIgnoreCase(re) ? "i" : "",
-//			RegExp_isMultiline(re) ? "m" : "");
-//}
-//
-//static void RegExp_set(KonohaContext *kctx, kRegExp *re, kString *ptns, kString *opts)
-//{
-//	const char *ptn = S_text(ptns);
-//	const char *opt = S_text(opts);
-//	knh_RegExp_setOptions(re, opt);
-//	KFieldSet(re, re->pattern, ptns);
-//	re->reg = pcre_regmalloc(kctx, ptns);
-//	int cflags = pcre_parsecflags(kctx, opt);
-//	if(!S_isASCII(ptns)) {
-//		/* Add 'u' option when the pattern is multibyte string. */
-//		cflags |= PCRE_UTF8;
-//	}
-//	pcre_regcomp(kctx, re->reg, ptn, cflags);
-//	re->eflags = pcre_parseeflags(kctx, opt);
-//}
-//
-//static kArray *RegExp_execute(KonohaContext *kctx, kRegExp *re, kString *s0)
-//{
-//	kArray *a = NULL;
-//	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
-//		const char *str = S_text(s0);  // necessary
-//		const char *base = str;
-//		const char *eos = base + S_size(s0);
-//		size_t nmatch = pcre_nmatchsize(kctx, re->reg);
-//		kregmatch_t *p, pmatch[nmatch+1];
-//		int i, isGlobalOption = RegExp_isGlobal(re);
-//		a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, nmatch);
-//		BEGIN_LOCAL(lsfp, 1);
-//		KUnsafeFieldSet(lsfp[0].asArray, a);
-//		do {
-//			int res = pcre_regexec(kctx, re->reg, str, nmatch, pmatch, re->eflags);
-//			if(res != 0) {
-//				// FIXME
-//				//LOG_regex(kctx, sfp, res, re, str);
-//				break;
-//			}
-//			for(p = pmatch, i = 0; i < nmatch; p++, i++) {
-//				if(p->rm_so == -1) break;
-//				//DBG_P("[%d], rm_so=%d, rm_eo=%d", i, p->rm_so, p->rm_eo);
-//				kbytes_t sub = {((p->rm_eo) - (p->rm_so)), {str + (p->rm_so)}};
-//				KLIB kArray_add(kctx, a, KLIB new_kString(kctx, sub.text, sub.len, _SUB(s0)));
-//			}
-//			if(isGlobalOption) {
-//				size_t eo = pmatch[0].rm_eo; // shift matched pattern
-//				str += (eo > 0) ? eo : 1;
-//				if(!(str < eos)) isGlobalOption = 0; // stop iteration
-//			}
-//		} while(isGlobalOption);
-//		END_LOCAL();
-//	}
-//	else {
-//		a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 0);
-//	}
-//	return a;
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Boolean RegExp.getglobal();
-//
-//static KMETHOD RegExp_getglobal(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RETURNb_(RegExp_isGlobal(sfp[0].asRegExp));
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Boolean RegExp.getignoreCase();
-//
-//static KMETHOD RegExp_getignoreCase(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RETURNb_(RegExp_isIgnoreCase(sfp[0].asRegExp));
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Boolean RegExp.getmultiline();
-//
-//static KMETHOD RegExp_getmultiline(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RETURNb_(RegExp_isMultiline(sfp[0].asRegExp));
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String RegExp.getsource();
-//
-//static KMETHOD RegExp_getsource(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RETURN_(sfp[0].asRegExp->pattern);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Int RegExp.getlastIndex();
-//
-//static KMETHOD RegExp_getlastIndex(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RETURNi_(sfp[0].asRegExp->lastIndex);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method RegExp RegExp.new(String pattern);
-//
-//static KMETHOD RegExp_new(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RegExp_set(kctx, sfp[0].asRegExp, sfp[1].asString, KNULL(String));
-//	RETURN_(sfp[0].asObject);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method RegExp RegExp.new(String pattern, String option);
-//
-//static KMETHOD RegExp_newwithOption(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	RegExp_set(kctx, sfp[0].asRegExp, sfp[1].asString, sfp[2].asString);
-//	RETURN_(sfp[0].asObject);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Int String.search(RegExp searchvalue);
-//
-//static KMETHOD String_search(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kRegExp *re = sfp[1].asRegExp;
-//	intptr_t loc = -1;
-//	if(!IS_NULL(re) && S_size(re->pattern) > 0) {
-//		kregmatch_t pmatch[2]; // modified by @utrhira
-//		const char *str = S_text(sfp[0].asString);  // necessary
-//		int res = pcre_regexec(kctx, re->reg, str, 1, pmatch, re->eflags);
-//		if(res == 0) {
-//			loc = pmatch[0].rm_so;
-//			if(loc != -1 && !S_isASCII(sfp[0].asString)) {
-//				kbytes_t base = {loc, {str}};
-//				loc = knh_bytes_mlen(base);
-//			}
-//		}
-//		else {
-//			//TODO
-//			//LOG_regex(kctx, sfp, res, re, str);
-//		}
-//	}
-//	RETURNi_(loc);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String[] String.match(RegExp regexp);
-//
-//static KMETHOD String_match(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[0].asString;
-//	kRegExp *re = sfp[1].asRegExp;
-//	RETURN_(RegExp_execute(kctx, re, s0));
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String String.replace(RegExp searchvalue, String newvalue);
-//
-//static KMETHOD String_replace(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[0].asString;
-//	kRegExp *re = sfp[1].asRegExp;
-//	kbytes_t fmt = {S_size(sfp[2].asString), {S_text(sfp[2].asString)}};
-//	kString *s = s0;
-//	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
-//		KGrowingBuffer wb;
-//		KLIB Kwb_init(&(kctx->stack->cwb), &wb);
-//		const char *str = S_text(s0);  // necessary
-//		const char *base = str;
-//		const char *eos = str + S_size(s0); // end of str
-//		kregmatch_t pmatch[KREGEXP_MATCHSIZE+1];
-//		int isGlobalOption = RegExp_isGlobal(re);
-//		do {
-//			if(str >= eos) break;
-//			int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags);
-//			if(res != 0) {
-//				// TODO
-//				//LOG_regex(kctx, sfp, res, re, str);
-//				break;
-//			}
-//			size_t len = pmatch[0].rm_eo;
-//			if(pmatch[0].rm_so > 0) {
-//				KLIB Kwb_write(kctx, &wb, str, pmatch[0].rm_so);
-//			}
-//			size_t matched = knh_regexp_matched(pmatch, KREGEXP_MATCHSIZE);
-//			if(len > 0) {
-//				WB_write_regexpfmt(kctx, &wb, &fmt, base, pmatch, matched);
-//				str += len;
-//			} else {
-//				if(str == base) { // 0-length match at head of string
-//					WB_write_regexpfmt(kctx, &wb, &fmt, base, pmatch, matched);
-//				}
-//				break;
-//			}
-//		} while(isGlobalOption);
-//		KLIB Kwb_write(kctx, &wb, str, strlen(str)); // write out remaining string
-//		s = kwb_newString(kctx, &wb, 0); // close cwb
-//	}
-//	RETURN_(s);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String[] String.split(RegExp separator);
-//
-//static KMETHOD String_split(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[0].asString;
-//	kRegExp *re = sfp[1].asRegExp;
-//	kArray *a = NULL;
-//	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
-//		const char *str = S_text(s0);  // necessary
-//		const char *eos = str + S_size(s0);
-//		kregmatch_t pmatch[KREGEXP_MATCHSIZE+1];
-//		if(str < eos) {
-//			a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 0);
-//			BEGIN_LOCAL(lsfp, 1);
-//			KUnsafeFieldSet(lsfp[0].asArray, a);
-//			while (str <= eos) {
-//				int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags);
-//				if(res == 0) {
-//					size_t len = pmatch[0].rm_eo;
-//					if(len > 0) {
-//						kbytes_t sub = {pmatch[0].rm_so, {str}};
-//						KLIB kArray_add(kctx, a, KLIB new_kString(kctx, sub.text, sub.len, _SUB(s0)));
-//						str += len;
-//						continue;
-//					}
-//				}
-//				KLIB kArray_add(kctx, a, KLIB new_kString(kctx, str, strlen(str), StringPolicy_POOL)); // append remaining string to array
-//				break;
-//			}
-//			END_LOCAL();
-//		} else { // for 0-length patterh
-//			a = kStringToCharArray(kctx, KLIB new_kString(kctx, str, S_size(s0), StringPolicy_POOL), 0, -1/* no limit */);
-//		}
-//	}
-//	else {
-//		a = kStringToCharArray(kctx, s0, 0, -1/* no limit */);
-//	}
-//	RETURN_(a);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String[] String.split(RegExp separator, Int limit);
-//
-//static KMETHOD String_splitwithSeparatorLimit(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[0].asString;
-//	kRegExp *re = sfp[1].asRegExp;
-//	kint_t limit = sfp[2].intValue;
-//	if(limit < 0) {
-//		/* ignore limit */
-//		limit = S_size(s0);
-//	}
-//	kArray *a = NULL;
-//	size_t asize = 0;
-//	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
-//		const char *str = S_text(s0);  // necessary
-//		const char *eos = str + S_size(s0);
-//		kregmatch_t pmatch[KREGEXP_MATCHSIZE+1];
-//		if(str < eos) {
-//			a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 0);
-//			BEGIN_LOCAL(lsfp, 1);
-//			KUnsafeFieldSet(lsfp[0].asArray, a);
-//			while (str <= eos && asize < limit) {
-//				int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags);
-//				if(res == 0) {
-//					size_t len = pmatch[0].rm_eo;
-//					if(len > 0) {
-//						kbytes_t sub = {pmatch[0].rm_so, {str}};
-//						KLIB kArray_add(kctx, a, KLIB new_kString(kctx, sub.text, sub.len, _SUB(s0)));
-//						asize++;
-//						str += len;
-//						continue;
-//					}
-//				}
-//				KLIB kArray_add(kctx, a, KLIB new_kString(kctx, str, strlen(str), StringPolicy_POOL)); // append remaining string to array
-//				asize++;
-//				break;
-//			}
-//			END_LOCAL();
-//		} else { // for 0-length patterh
-//			a = kStringToCharArray(kctx, KLIB new_kString(kctx, str, S_size(s0), StringPolicy_POOL), 0, limit);
-//		}
-//	}
-//	else {
-//		a = kStringToCharArray(kctx, s0, 0, limit);
-//	}
-//	RETURN_(a);
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method String[] RegExp.exec(String str);
-//
-//static KMETHOD RegExp_exec(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[1].asString;
-//	kRegExp *re = sfp[0].asRegExp;
-//	RETURN_(RegExp_execute(kctx, re, s0));
-//}
-//
-///* ------------------------------------------------------------------------ */
-////## @Const method Boolean RegExp.test(String str);
-//
-//static KMETHOD RegExp_test(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kString *s0 = sfp[1].asString;
-//	kRegExp *re = sfp[0].asRegExp;
-//	kbool_t matched = false;
-//	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
-//		const char *str = S_text(s0);  // necessary
-//		const char *base = str;
-//		const char *eos = base + S_size(s0);
-//		size_t nmatch = pcre_nmatchsize(kctx, re->reg);
-//		kregmatch_t *p, pmatch[nmatch+1];
-//		int i, isGlobalOption = RegExp_isGlobal(re);
-//		do {
-//			int res = pcre_regexec(kctx, re->reg, str, nmatch, pmatch, re->eflags);
-//			if(res != 0) {
-//				// FIXME
-//				//LOG_regex(kctx, sfp, res, re, str);
-//				break;
-//			}
-//			for(p = pmatch, i = 0; i < nmatch; p++, i++) {
-//				if(p->rm_so == -1) break;
-//				//DBG_P("[%d], rm_so=%d, rm_eo=%d", i, p->rm_so, p->rm_eo);
-//				kbytes_t sub = {p->rm_eo, {str}};
-//				re->lastIndex = knh_bytes_mlen(sub);
-//				matched = true;
-//			}
-//			if(isGlobalOption) {
-//				size_t eo = pmatch[0].rm_eo; // shift matched pattern
-//				str += (eo > 0) ? eo : 1;
-//				if(!(str < eos)) isGlobalOption = 0; // stop iteration
-//			}
-//		} while(isGlobalOption);
-//	}
-//	else {
-//		re->lastIndex = 0;
-//	}
-//	RETURNb_(matched);
-//}
-//
-//// --------------------------------------------------------------------------
-//
-//#define _Public   kMethod_Public
-//#define _Const    kMethod_Const
-//#define _Coercion kMethod_Coercion
-//#define _Im kMethod_Immutable
-//#define _F(F)   (intptr_t)(F)
-//
-//static kbool_t regexp_initPackage(KonohaContext *kctx, kNameSpace *ns, int argc, const char**args, kfileline_t pline)
-//{
-//	kregexpshare_t *base = (kregexpshare_t*)KCalloc_UNTRACE(sizeof(kregexpshare_t), 1);
-//	base->h.name     = "regexp";
-//	base->h.setup    = kregexpshare_setup;
-//	base->h.reftrace = kregexpshare_reftrace;
-//	base->h.free     = kregexpshare_free;
-//	KLIB KonohaRuntime_setModule(kctx, MOD_REGEXP, &base->h, pline);
-//
-//	KDEFINE_CLASS RegExpDef = {
-//		STRUCTNAME(RegExp),
-//		.cflag = 0,
-//		.init = RegExp_init,
-//		.free = RegExp_free,
-//		.p    = RegExp_p,
-//	};
-//	base->cRegExp = KLIB kNameSpace_defineClass(kctx, ns, NULL, &RegExpDef, pline);
-//
-//	ktype_t TY_StringArray0 = CT_StringArray0->typeId;
-//	KDEFINE_METHOD MethodData[] = {
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_getglobal), TY_boolean, TY_RegExp, MN_("getglobal"), 0,
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_getignoreCase), TY_boolean, TY_RegExp, MN_("getignoreCase"), 0,
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_getmultiline), TY_boolean, TY_RegExp, MN_("getmultiline"), 0,
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_getsource), TY_String, TY_RegExp, MN_("getsource"), 0,
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_getlastIndex), TY_int, TY_RegExp, MN_("getlastIndex"), 0,
-//		/*JS*/_Public|_Im, _F(String_match), TY_StringArray0, TY_String, MN_("match"), 1, TY_RegExp, FN_("regexp"),
-//		/*JS*/_Public|_Const|_Im, _F(String_replace), TY_String, TY_String, MN_("replace"), 2, TY_RegExp, FN_("searchvalue"), TY_String, FN_("newvalue"),
-//		/*JS*/_Public|_Const|_Im, _F(String_search), TY_int, TY_String, MN_("search"), 1, TY_RegExp, FN_("searchvalue"),
-//		/*JS*/_Public|_Im, _F(String_split), TY_StringArray0, TY_String, MN_("split"), 1, TY_RegExp, FN_("separator"),
-//		/*JS*/_Public|_Im, _F(String_splitwithSeparatorLimit), TY_StringArray0, TY_String, MN_("split"), 2, TY_RegExp, FN_("separator"), TY_int, FN_("limit"),
-//		/*JS*/_Public|_Const, _F(RegExp_new),     TY_RegExp,  TY_RegExp,  MN_("new"), 1, TY_String, FN_("pattern"),
-//		/*JS*/_Public|_Const, _F(RegExp_newwithOption),     TY_RegExp,  TY_RegExp,  MN_("new"), 2, TY_String, FN_("pattern"), TY_String, FN_("option"),
-//		/*JS*/_Public|_Const, _F(RegExp_exec),    TY_StringArray0, TY_RegExp,  MN_("exec"), 1, TY_String, FN_("str"),
-//		/*JS*/_Public|_Const|_Im, _F(RegExp_test),    TY_boolean, TY_RegExp,  MN_("test"), 1, TY_String, FN_("str"),
-//		DEND,
-//	};
-//	KLIB kNameSpace_loadMethodData(kctx, ns, MethodData);
-//	return true;
-//}
-//
-//static kbool_t regexp_setupPackage(KonohaContext *kctx, kNameSpace *ns, isFirstTime_t isFirstTime, kfileline_t pline)
-//{
-//	return true;
-//}
-//
-//static KMETHOD TokenFunc_JavaScriptRegExp(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	kTokenVar *tk = (kTokenVar *)sfp[1].asObject;
-//	int ch, prev = '/', pos = 1;
-//	const char *source = S_text(sfp[2].asString);
-//	if(source[pos] == '*' || source[pos] == '/') {
-//		RETURNi_(0);
-//	}
-//	/*FIXME: we need to care about context sensitive case*/
-//	//int tokenListize = kArray_size(tenv->tokenList);
-//	//if(tokenListize > 0) {
-//	//	kToken *tkPrev = tenv->tokenList->TokenItems[tokenListize - 1];
-//	//	if(tkPrev->unresolvedTokenType == TokenType_INT ||
-//	//		(tkPrev->topCharHint != '(' && tkPrev->unresolvedTokenType == TokenType_SYMBOL)) {
-//	//		RETURNi_(0);
-//	//	}
-//	//}
-//	while((ch = source[pos++]) != 0) {
-//		if(ch == '\n') {
-//			break;
-//		}
-//		if(ch == '/' && prev != '\\') {
-//			int pos0 = pos;
-//			while(isalpha(source[pos])) pos++;
-//			if(IS_NOTNULL(tk)) {
-//				kArray *a = (kArray*)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 2);
-//				KLIB kArray_add(kctx, a, KLIB new_kString(kctx, source + 1, (pos0-2), 0));
-//				KLIB kArray_add(kctx, a, KLIB new_kString(kctx, source + pos0, pos-pos0, 0));
-//				tk->subTokenList = a;  // FIXME: terrible bug!! who wrote this?
-//				tk->unresolvedTokenType = SYM_("$RegExp");
-//			}
-//			RETURNi_(pos);
-//		}
-//		prev = ch;
-//	}
-//	if(IS_NOTNULL(tk)) {
-//		kreportf(ErrTag, tk->uline, "must close with /");
-//	}
-//	RETURNi_(pos-1);
-//}
-//
-//static KMETHOD TypeCheck_RegExp(KonohaContext *kctx, KonohaStack *sfp)
-//{
-//	VAR_TypeCheck(stmt, expr, gma, reqty);
-//	kToken *tk = expr->termToken;
-//	kRegExp *r = new_(RegExp, NULL, OnGcStack);
-//	DBG_ASSERT(kArray_size(tk->subTokenList) == 2);
-//	RegExp_set(kctx, r, tk->subTokenList->stringItems[0], tk->subTokenList->stringItems[1]);
-//	RETURN_(SUGAR kExpr_setConstValue(kctx, expr, TY_RegExp, UPCAST(r)));
-//}
-//
-//static kbool_t regexp_initNameSpace(KonohaContext *kctx, kNameSpace *packageNS, kNameSpace *ns, kfileline_t pline)
-//{
-//	KDEFINE_SYNTAX SYNTAX[] = {
-//		{ .keyword = SYM_("$RegExp"),  TypeCheck_(RegExp), },
-//		{ .keyword = KW_END, },
-//	};
-//	SUGAR kNameSpace_defineSyntax(kctx, ns, SYNTAX, packageNS);
-//
-//	SUGAR kNameSpace_setTokenFunc(kctx, ns, SYM_("$RegExp"), KonohaChar_Slash, new_SugarFunc(ns, TokenFunc_JavaScriptRegExp));
-//	return true;
-//}
-//
-//static kbool_t regexp_setupNameSpace(KonohaContext *kctx, kNameSpace *packageNS, kNameSpace *ns, kfileline_t pline)
-//{
-//	return true;
-//}
-//
-//KDEFINE_PACKAGE* regexp_init(void)
-//{
-//	static KDEFINE_PACKAGE d = {
-//		KPACKNAME("regexp", "1.0"),
-//		.initPackage    = regexp_initPackage,
-//		.setupPackage   = regexp_setupPackage,
-//		.initNameSpace  = regexp_initNameSpace,
-//		.setupNameSpace = regexp_setupNameSpace,
-//	};
-//	return &d;
-//}
-//
-//#ifdef __cplusplus
-//}
-//#endif
+
+static int pcre_regcomp(KonohaContext *kctx, kregexp_t *reg, const char *pattern, int cflags)
+{
+	PCRE_regexp_t* preg = (PCRE_regexp_t*)reg;
+	preg->re = pcre_compile(pattern, cflags, &preg->err, &preg->erroffset, NULL);
+	return (preg->re != NULL) ? 0 : -1;
+}
+
+static int pcre_regexec(KonohaContext *kctx, kregexp_t *reg, const char *str, size_t nmatch, kregmatch_t p[], int eflags)
+{
+	PCRE_regexp_t *preg = (PCRE_regexp_t*)reg;
+	int res, nm_count, nvector[nmatch*3];
+	nvector[0] = 0;
+	size_t idx, matched = nmatch;
+	if(strlen(str) == 0) return -1;
+	if((res = pcre_exec(preg->re, NULL, str, strlen(str), 0, eflags, nvector, nmatch*3)) >= 0) {
+		matched = (res > 0 && res < nmatch) ? res : nmatch;
+		res = 0;
+		for (idx = 0; idx < matched; idx++) {
+			p[idx].rm_so = nvector[2*idx];
+			p[idx].rm_eo = nvector[2*idx+1];
+		}
+		p[idx].rm_so = -1;
+		nm_count = 0;
+		pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMECOUNT, &nm_count);
+		if(nm_count > 0) {
+			unsigned char *nm_table;
+			int nm_entry_size = 0;
+			pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMETABLE, &nm_table);
+			pcre_fullinfo(preg->re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nm_entry_size);
+			unsigned char *tbl_ptr = nm_table;
+			for (idx = 0; idx < nm_count; idx++) {
+				int n_idx = (tbl_ptr[0] << 8) | tbl_ptr[1];
+				unsigned char *n_name = tbl_ptr + 2;
+				p[n_idx].rm_name = n_name;
+				p[n_idx].rm_namelen = strlen((char*)n_name);
+				tbl_ptr += nm_entry_size;
+			}
+		}
+	}
+	return res;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void kregexpshare_setup(KonohaContext *kctx, struct KonohaModule *def, int newctx)
+{
+
+}
+
+static void kregexpshare_reftrace(KonohaContext *kctx, struct KonohaModule *baseh, KObjectVisitor *visitor)
+{
+
+}
+
+static void kregexpshare_free(KonohaContext *kctx, struct KonohaModule *baseh)
+{
+	KFree(baseh, sizeof(kregexpshare_t));
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void kRegExp_setOptions(kRegExp *re, const char *option)
+{
+	size_t i, optlen = strlen(option);
+	for(i = 0; i < optlen; i++) {
+		switch(option[i]) {
+		case 'g':
+			RegExp_setGlobal(re, 1);
+			break;
+		case 'i':
+			RegExp_setIgnoreCase(re, 1);
+			break;
+		case 'm':
+			RegExp_setMultiline(re, 1);
+		default:
+			break;
+		}
+	}
+}
+
+static size_t knh_regexp_matched(kregmatch_t* r, size_t maxmatch)
+{
+	size_t n = 0;
+	for (; n < maxmatch && r[n].rm_so != -1; n++) {}
+	return n;
+}
+
+static void Kwb_writeRegexFormat(KonohaContext *kctx, KGrowingBuffer *wb, const char *fmttext, size_t fmtlen, const char *base, kregmatch_t *r, size_t matched)
+{
+	const char *ch = fmttext;
+	const char *eof = ch + fmtlen; // end of fmt
+	char buf[1];
+	for (; ch < eof; ch++) {
+		if(*ch == '\\') {
+			buf[0] = *ch;
+			KLIB Kwb_write(kctx, wb, buf, 1);
+			ch++;
+		} else if(*ch == '$' && isdigit(ch[1])) {
+			size_t grpidx = (size_t)ch[1] - '0'; // get head of grourp_index
+			if(grpidx < matched) {
+				ch++;
+				while (isdigit(ch[1])) {
+					size_t nidx = grpidx * 10 + (ch[1] - '0');
+					if(nidx < matched) {
+						grpidx = nidx;
+						ch++;
+						if(ch < eof) {
+							continue;
+						}
+					}
+				}
+				kregmatch_t *rp = &r[grpidx];
+				KLIB Kwb_write(kctx, wb, base + rp->rm_so, rp->rm_eo - rp->rm_so);
+				continue; // skip putc
+			}
+		}
+		buf[0] = *ch;
+		KLIB Kwb_write(kctx, wb, buf, 1);
+	}
+}
+
+static void RegExp_init(KonohaContext *kctx, kObject *o, void *conf)
+{
+	kRegExp *re = (kRegExp*)o;
+	re->reg = NULL;
+	re->eflags = 0;
+	re->pattern = KNULL(String);
+	re->lastIndex = 0;
+}
+
+static void RegExp_free(KonohaContext *kctx, kObject *o)
+{
+	kRegExp *re = (kRegExp*)o;
+	if(re->reg != NULL) {
+		pcre_regfree(kctx, re->reg);
+	}
+}
+
+static void RegExp_p(KonohaContext *kctx, KonohaValue *v, int pos, KGrowingBuffer *wb)
+{
+	kRegExp *re = v[pos].asRegExp;
+	KLIB Kwb_printf(kctx, wb, "/%s/%s%s%s", S_text(re->pattern),
+			RegExp_isGlobal(re) ? "g" : "",
+			RegExp_isIgnoreCase(re) ? "i" : "",
+			RegExp_isMultiline(re) ? "m" : "");
+}
+
+static void RegExp_set(KonohaContext *kctx, kRegExp *re, kString *ptns, kString *opts)
+{
+	const char *ptn = S_text(ptns);
+	const char *opt = S_text(opts);
+	kRegExp_setOptions(re, opt);
+	KFieldSet(re, re->pattern, ptns);
+	re->reg = pcre_regmalloc(kctx, ptns);
+	int cflags = pcre_parsecflags(kctx, opt);
+	if(!S_isASCII(ptns)) {
+		/* Add 'u' option when the pattern is multibyte string. */
+		cflags |= PCRE_UTF8;
+	}
+	pcre_regcomp(kctx, re->reg, ptn, cflags);
+	re->eflags = pcre_parseeflags(kctx, opt);
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Boolean RegExp.getglobal();
+
+static KMETHOD RegExp_getglobal(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RETURNb_(RegExp_isGlobal(sfp[0].asRegExp));
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Boolean RegExp.getignoreCase();
+
+static KMETHOD RegExp_getignoreCase(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RETURNb_(RegExp_isIgnoreCase(sfp[0].asRegExp));
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Boolean RegExp.getmultiline();
+
+static KMETHOD RegExp_getmultiline(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RETURNb_(RegExp_isMultiline(sfp[0].asRegExp));
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method String RegExp.getsource();
+
+static KMETHOD RegExp_getsource(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RETURN_(sfp[0].asRegExp->pattern);
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Int RegExp.getlastIndex();
+
+static KMETHOD RegExp_getlastIndex(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RETURNi_(sfp[0].asRegExp->lastIndex);
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method RegExp RegExp.new(String pattern);
+
+static KMETHOD RegExp_new(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RegExp_set(kctx, sfp[0].asRegExp, sfp[1].asString, KNULL(String));
+	RETURN_(sfp[0].asObject);
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method RegExp RegExp.new(String pattern, String option);
+
+static KMETHOD RegExp_new2(KonohaContext *kctx, KonohaStack *sfp)
+{
+	RegExp_set(kctx, sfp[0].asRegExp, sfp[1].asString, sfp[2].asString);
+	RETURN_(sfp[0].asObject);
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Int String.search(RegExp searchvalue);
+
+static KMETHOD String_search(KonohaContext *kctx, KonohaStack *sfp)
+{
+	kRegExp *re = sfp[1].asRegExp;
+	intptr_t loc = -1;
+	if(!IS_NULL(re) && S_size(re->pattern) > 0) {
+		kregmatch_t pmatch[2]; // modified by @utrhira
+		const char *str = S_text(sfp[0].asString);  // necessary
+		int res = pcre_regexec(kctx, re->reg, str, 1, pmatch, re->eflags);
+		if(res == 0) {
+			loc = pmatch[0].rm_so;
+			if(loc != -1 && !S_isASCII(sfp[0].asString)) {
+				loc = utf8_strlen(str, loc);
+			}
+		}
+		else {
+			//TODO
+			//LOG_regex(kctx, sfp, res, re, str);
+		}
+	}
+	RETURNi_(loc);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void kArray_executeRegExp(KonohaContext *kctx, kArray *resultArray, kRegExp *regex, kString *s0)
+{
+	int stringPolicy = S_isASCII(s0) ? StringPolicy_ASCII : 0;
+	if(IS_NOTNULL(regex) && S_size(regex->pattern) > 0) {
+		const char *s = S_text(s0);  // necessary
+		const char *base = s;
+		const char *eos = base + S_size(s0);
+		size_t nmatch = pcre_nmatchsize(kctx, regex->reg);
+		kregmatch_t *p, pmatch[nmatch+1];
+		int i, isGlobalOption = RegExp_isGlobal(regex);
+		do {
+			int res = pcre_regexec(kctx, regex->reg, s, nmatch, pmatch, regex->eflags);
+			if(res != 0) {
+				// FIXME
+				//LOG_regex(kctx, sfp, res, regex, s);
+				break;
+			}
+			for(p = pmatch, i = 0; i < nmatch; p++, i++) {
+				if(p->rm_so == -1) break;
+				KLIB new_kString(kctx, resultArray, s + (p->rm_so), ((p->rm_eo) - (p->rm_so)), stringPolicy);
+			}
+			if(isGlobalOption) {
+				size_t eo = pmatch[0].rm_eo; // shift matched pattern
+				s += (eo > 0) ? eo : 1;
+				if(!(s < eos)) isGlobalOption = 0; // stop iteration
+			}
+		} while(isGlobalOption);
+	}
+}
+
+//## @Const String[] String.match(RegExp regexp);
+static KMETHOD String_match(KonohaContext *kctx, KonohaStack *sfp)
+{
+	INIT_GCSTACK();
+	kArray *resultArray = (kArray*)KLIB new_kObject(kctx, _GcStack, KReturnType(sfp), 0);
+	kArray_executeRegExp(kctx, resultArray, sfp[1].asRegExp, sfp[0].asString);
+	KReturnWith(resultArray, RESET_GCSTACK());
+}
+
+//## @Const String[] RegExp.exec(String str);
+static KMETHOD RegExp_exec(KonohaContext *kctx, KonohaStack *sfp)
+{
+	INIT_GCSTACK();
+	kArray *resultArray = (kArray*)KLIB new_kObject(kctx, _GcStack, KReturnType(sfp), 0);
+	kArray_executeRegExp(kctx, resultArray, sfp[0].asRegExp, sfp[1].asString);
+	KReturnWith(resultArray, RESET_GCSTACK());
+}
+
+/* ------------------------------------------------------------------------ */
+
+static kString *Kwb_newString(KonohaContext *kctx, kArray *gcstack, KGrowingBuffer *wb)
+{
+	return KLIB new_kString(kctx, gcstack, KLIB Kwb_top(kctx, wb, false), Kwb_bytesize(wb), 0);
+}
+
+//## @Const method String String.replace(RegExp searchvalue, String newvalue);
+static KMETHOD String_replace(KonohaContext *kctx, KonohaStack *sfp)
+{
+	kString *s0 = sfp[0].asString;
+	kRegExp *re = sfp[1].asRegExp;
+	const char* fmttext = S_text(sfp[2].asString);
+	size_t fmtlen = S_size(sfp[2].asString);
+	kString *s = s0;
+	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
+		KGrowingBuffer wb;
+		KLIB Kwb_init(&(kctx->stack->cwb), &wb);
+		const char *str = S_text(s0);  // necessary
+		const char *base = str;
+		const char *eos = str + S_size(s0); // end of str
+		kregmatch_t pmatch[KREGEXP_MATCHSIZE+1];
+		int isGlobalOption = RegExp_isGlobal(re);
+		do {
+			if(str >= eos) break;
+			int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags);
+			if(res != 0) {
+				// TODO
+				//LOG_regex(kctx, sfp, res, re, str);
+				break;
+			}
+			size_t len = pmatch[0].rm_eo;
+			if(pmatch[0].rm_so > 0) {
+				KLIB Kwb_write(kctx, &wb, str, pmatch[0].rm_so);
+			}
+			size_t matched = knh_regexp_matched(pmatch, KREGEXP_MATCHSIZE);
+			if(len > 0) {
+				Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched);
+				str += len;
+			} else {
+				if(str == base) { // 0-length match at head of string
+					Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched);
+				}
+				break;
+			}
+		} while(isGlobalOption);
+		KLIB Kwb_write(kctx, &wb, str, strlen(str)); // write out remaining string
+		s = Kwb_newString(kctx, OnStack, &wb); // close cwb
+		KLIB Kwb_free(&wb);
+	}
+	RETURN_(s);
+}
+
+/* ------------------------------------------------------------------------ */
+/* split */
+
+static void kArray_split(KonohaContext *kctx, kArray *resultArray, kString *str, kRegExp *regex, int limit)
+{
+	int stringPolicy = S_isASCII(str) ? StringPolicy_ASCII : 0;
+	if(IS_NOTNULL(regex) && S_size(regex->pattern) > 0) {
+		const char *s = S_text(str);  // necessary
+		const char *eos = s + S_size(str);
+		kregmatch_t pmatch[2];
+		int res = 0;
+		while (s < eos && res == 0) {
+			res = pcre_regexec(kctx, regex->reg, s, 1, pmatch, regex->eflags);
+			if(res != 0) break;
+			size_t len = pmatch[0].rm_eo;
+			if(len > 0) {
+				KLIB new_kString(kctx, resultArray, s, pmatch[0].rm_so, stringPolicy);
+				s += len;
+			}
+			if(!(kArray_size(resultArray) + 1 < limit)) {
+				return;
+			}
+		}
+		if(s < eos) {
+			KLIB new_kString(kctx, resultArray, s, eos - s, stringPolicy); // append remaining string to array
+		}
+	}
+	else {
+		const unsigned char *s = (const unsigned char*)S_text(str);
+		size_t i, n = S_size(str);
+		if(S_isASCII(str)) {
+			for(i = 0; i < n; i++) {
+				KLIB new_kString(kctx, resultArray, (const char*)s + i, 1, StringPolicy_ASCII);
+			}
+		}
+		else {
+			for(i = 0; i < n; i++) {
+				int len = utf8len(s[i]);
+				KLIB new_kString(kctx, resultArray, (const char*)s + i, len, len == 1 ? StringPolicy_ASCII: StringPolicy_UTF8);
+				i += len;
+			}
+		}
+	}
+}
+
+//## @Const method String[] String.split(RegExp regex);
+static KMETHOD String_split(KonohaContext *kctx, KonohaStack *sfp)
+{
+	INIT_GCSTACK();
+	kArray *resultArray = (kArray*)KLIB new_kObject(kctx, _GcStack, KReturnType(sfp), 0);
+	kArray_split(kctx, resultArray, sfp[0].asString, sfp[1].asRegExp, S_size(sfp[0].asString));
+	KReturnWith(resultArray, RESET_GCSTACK());
+}
+
+//## @Const method String[] String.split(RegExp regex, Int limit);
+static KMETHOD String_splitWithLimit(KonohaContext *kctx, KonohaStack *sfp)
+{
+	INIT_GCSTACK();
+	int limit = sfp[2].intValue < 0 ? S_size(sfp[0].asString) : sfp[2].intValue;
+	kArray *resultArray = (kArray*)KLIB new_kObject(kctx, _GcStack, KReturnType(sfp), 0);
+	kArray_split(kctx, resultArray, sfp[0].asString, sfp[1].asRegExp, limit);
+	KReturnWith(resultArray, RESET_GCSTACK());
+}
+
+/* ------------------------------------------------------------------------ */
+//## @Const method Boolean RegExp.test(String str);
+
+static KMETHOD RegExp_test(KonohaContext *kctx, KonohaStack *sfp)
+{
+	kString *s0 = sfp[1].asString;
+	kRegExp *re = sfp[0].asRegExp;
+	kbool_t matched = false;
+	if(IS_NOTNULL(re) && S_size(re->pattern) > 0) {
+		const char *str = S_text(s0);  // necessary
+		const char *base = str;
+		const char *eos = base + S_size(s0);
+		size_t nmatch = pcre_nmatchsize(kctx, re->reg);
+		kregmatch_t *p, pmatch[nmatch+1];
+		int i, isGlobalOption = RegExp_isGlobal(re);
+		do {
+			int res = pcre_regexec(kctx, re->reg, str, nmatch, pmatch, re->eflags);
+			if(res != 0) {
+				// FIXME
+				//LOG_regex(kctx, sfp, res, re, str);
+				break;
+			}
+			for(p = pmatch, i = 0; i < nmatch; p++, i++) {
+				if(p->rm_so == -1) break;
+				re->lastIndex = utf8_strlen(str, p->rm_eo);
+				matched = true;
+			}
+			if(isGlobalOption) {
+				size_t eo = pmatch[0].rm_eo; // shift matched pattern
+				str += (eo > 0) ? eo : 1;
+				if(!(str < eos)) isGlobalOption = 0; // stop iteration
+			}
+		} while(isGlobalOption);
+	}
+	else {
+		re->lastIndex = 0;
+	}
+	RETURNb_(matched);
+}
+
+// --------------------------------------------------------------------------
+
+#define _Public   kMethod_Public
+#define _Const    kMethod_Const
+#define _Coercion kMethod_Coercion
+#define _Im kMethod_Immutable
+#define _F(F)   (intptr_t)(F)
+
+static kbool_t regexp_initPackage(KonohaContext *kctx, kNameSpace *ns, int argc, const char**args, kfileline_t pline)
+{
+	kregexpshare_t *base = (kregexpshare_t*)KCalloc_UNTRACE(sizeof(kregexpshare_t), 1);
+	base->h.name     = "regexp";
+	base->h.setup    = kregexpshare_setup;
+	base->h.reftrace = kregexpshare_reftrace;
+	base->h.free     = kregexpshare_free;
+	KLIB KonohaRuntime_setModule(kctx, MOD_REGEXP, &base->h, pline);
+
+	KDEFINE_CLASS RegExpDef = {
+		STRUCTNAME(RegExp),
+		.cflag = 0,
+		.init = RegExp_init,
+		.free = RegExp_free,
+		.p    = RegExp_p,
+	};
+	base->cRegExp = KLIB kNameSpace_defineClass(kctx, ns, NULL, &RegExpDef, pline);
+
+	ktype_t TY_StringArray0 = CT_StringArray0->typeId;
+	KDEFINE_METHOD MethodData[] = {
+		/*JS*/_Public|_Const|_Im, _F(RegExp_getglobal), TY_boolean, TY_RegExp, MN_("getglobal"), 0,
+		/*JS*/_Public|_Const|_Im, _F(RegExp_getignoreCase), TY_boolean, TY_RegExp, MN_("getignoreCase"), 0,
+		/*JS*/_Public|_Const|_Im, _F(RegExp_getmultiline), TY_boolean, TY_RegExp, MN_("getmultiline"), 0,
+		/*JS*/_Public|_Const|_Im, _F(RegExp_getsource), TY_String, TY_RegExp, MN_("getsource"), 0,
+		/*JS*/_Public|_Const|_Im, _F(RegExp_getlastIndex), TY_int, TY_RegExp, MN_("getlastIndex"), 0,
+		/*JS*/_Public|_Im, _F(String_match), TY_StringArray0, TY_String, MN_("match"), 1, TY_RegExp, FN_("regexp"),
+		/*JS*/_Public|_Const|_Im, _F(String_replace), TY_String, TY_String, MN_("replace"), 2, TY_RegExp, FN_("searchvalue"), TY_String, FN_("newvalue"),
+		/*JS*/_Public|_Const|_Im, _F(String_search), TY_int, TY_String, MN_("search"), 1, TY_RegExp, FN_("searchvalue"),
+		/*JS*/_Public|_Im, _F(String_split), TY_StringArray0, TY_String, MN_("split"), 1, TY_RegExp, FN_("separator"),
+		/*JS*/_Public|_Im, _F(String_splitWithLimit), TY_StringArray0, TY_String, MN_("split"), 2, TY_RegExp, FN_("separator"), TY_int, FN_("limit"),
+		/*JS*/_Public|_Const, _F(RegExp_new),     TY_RegExp,  TY_RegExp,  MN_("new"), 1, TY_String, FN_("pattern"),
+		/*JS*/_Public|_Const, _F(RegExp_new2),     TY_RegExp,  TY_RegExp,  MN_("new"), 2, TY_String, FN_("pattern"), TY_String, FN_("option"),
+		/*JS*/_Public|_Const, _F(RegExp_exec),    TY_StringArray0, TY_RegExp,  MN_("exec"), 1, TY_String, FN_("str"),
+		/*JS*/_Public|_Const|_Im, _F(RegExp_test),    TY_boolean, TY_RegExp,  MN_("test"), 1, TY_String, FN_("str"),
+		DEND,
+	};
+	KLIB kNameSpace_loadMethodData(kctx, ns, MethodData);
+	return true;
+}
+
+static kbool_t regexp_setupPackage(KonohaContext *kctx, kNameSpace *ns, isFirstTime_t isFirstTime, kfileline_t pline)
+{
+	return true;
+}
+
+static KMETHOD TokenFunc_JavaScriptRegExp(KonohaContext *kctx, KonohaStack *sfp)
+{
+	kTokenVar *tk = (kTokenVar *)sfp[1].asObject;
+	int ch, prev = '/', pos = 1;
+	const char *source = S_text(sfp[2].asString);
+	if(source[pos] == '*' || source[pos] == '/') {
+		RETURNi_(0);
+	}
+	/*FIXME: we need to care about context sensitive case*/
+	//int tokenListize = kArray_size(tenv->tokenList);
+	//if(tokenListize > 0) {
+	//	kToken *tkPrev = tenv->tokenList->TokenItems[tokenListize - 1];
+	//	if(tkPrev->unresolvedTokenType == TokenType_INT ||
+	//		(tkPrev->topCharHint != '(' && tkPrev->unresolvedTokenType == TokenType_SYMBOL)) {
+	//		RETURNi_(0);
+	//	}
+	//}
+	while((ch = source[pos++]) != 0) {
+		if(ch == '\n') {
+			break;
+		}
+		if(ch == '/' && prev != '\\') {
+			int pos0 = pos;
+			while(isalpha(source[pos])) pos++;
+			if(IS_NOTNULL(tk)) {
+				kArray *a = (kArray*)KLIB new_kObject(kctx, OnField, CT_StringArray0, 2); // FIXME
+				KFieldSet(tk, tk->subTokenList, a);
+				KLIB new_kString(kctx, a, source + 1, (pos0-2), 0);
+				KLIB new_kString(kctx, a, source + pos0, pos-pos0, 0);
+				tk->unresolvedTokenType = SYM_("$RegExp");
+			}
+			RETURNi_(pos);
+		}
+		prev = ch;
+	}
+	if(IS_NOTNULL(tk)) {
+		kreportf(ErrTag, tk->uline, "must close with /");
+	}
+	RETURNi_(pos-1);
+}
+
+static KMETHOD TypeCheck_RegExp(KonohaContext *kctx, KonohaStack *sfp)
+{
+	VAR_TypeCheck(stmt, expr, gma, reqty);
+	kToken *tk = expr->termToken;
+	kRegExp *r = new_(RegExp, NULL, OnGcStack);
+	DBG_ASSERT(kArray_size(tk->subTokenList) == 2);
+	RegExp_set(kctx, r, tk->subTokenList->stringItems[0], tk->subTokenList->stringItems[1]);
+	RETURN_(SUGAR kExpr_setConstValue(kctx, expr, TY_RegExp, UPCAST(r)));
+}
+
+static kbool_t regexp_initNameSpace(KonohaContext *kctx, kNameSpace *packageNS, kNameSpace *ns, kfileline_t pline)
+{
+	KDEFINE_SYNTAX SYNTAX[] = {
+		{ .keyword = SYM_("$RegExp"),  TypeCheck_(RegExp), },
+		{ .keyword = KW_END, },
+	};
+	SUGAR kNameSpace_defineSyntax(kctx, ns, SYNTAX, packageNS);
+
+	SUGAR kNameSpace_setTokenFunc(kctx, ns, SYM_("$RegExp"), KonohaChar_Slash, new_SugarFunc(ns, TokenFunc_JavaScriptRegExp));
+	return true;
+}
+
+static kbool_t regexp_setupNameSpace(KonohaContext *kctx, kNameSpace *packageNS, kNameSpace *ns, kfileline_t pline)
+{
+	return true;
+}
+
+KDEFINE_PACKAGE* regexp_init(void)
+{
+	static KDEFINE_PACKAGE d = {
+		KPACKNAME("regexp", "1.0"),
+		.initPackage    = regexp_initPackage,
+		.setupPackage   = regexp_setupPackage,
+		.initNameSpace  = regexp_initNameSpace,
+		.setupNameSpace = regexp_setupNameSpace,
+	};
+	return &d;
+}
+
+#ifdef __cplusplus
+}
+#endif


fix acl chain cancel

fix acl chain cancel

--- gridftp/server/src/globus_i_gfs_acl.c
+++ gridftp/server/src/globus_i_gfs_acl.c
@@ -291,9 +291,11 @@
     /* if we fail here, cancel rest of acl chain */
     if(result != GLOBUS_SUCCESS)
     {
-  /*
-        globus_list_free(acl_handle->current_list);
-  */
+        while(!globus_list_empty(acl_handle->current_list))
+        {
+            globus_list_remove(
+                &acl_handle->current_list, acl_handle->current_list);
+        }
     }

     globus_callback_register_oneshot(


Fix compilation warning on gcc 4.4

Fix compilation warning on gcc 4.4

--- src/symtseries.c
+++ src/symtseries.c
@@ -763,9 +763,9 @@
     size_t n_runs = 250;
     double buf[STS_TEST_BUF_SIZE];
     srand((unsigned int)time(NULL));
-    sts_window win;
+    sts_window win = NULL;
     size_t n_values = 32;
-    size_t prev_fin, new_fin;
+    size_t prev_fin = 0, new_fin = 0;
     size_t w = 8;
     unsigned char c = 6;
     for (size_t i = 0; i < n_runs; ++i) {


[APPROVAL] OSS make-bdl-version-dependent-on-bsl to master

--- groups/bdl/bdlscm/bdlscm_versiontag.h
+++ groups/bdl/bdlscm/bdlscm_versiontag.h
@@ -41,29 +41,18 @@
 #include <bslscm_version.h>
 #endif

-#define BDL_VERSION_MAJOR     2
+#ifndef INCLUDED_BSLSCM_VERSIONTAG
+#include <bslscm_versiontag.h>
+#endif
+
+
+#define BDL_VERSION_MAJOR     BSL_VERSION_MAJOR
     // Provide the major version number of the current (latest) BDL release.

-#define BDL_VERSION_MINOR     22
+#define BDL_VERSION_MINOR     BSL_VERSION_MINOR
     // Provide the minor version number of the current (latest) BDL release.

-#define BDL_MAKE_VERSION(major, minor) ((major) * 10000 \
-                                      + (minor) *   100)
-    // Construct a composite version number in the range '[ 0 .. 999900 ]' from
-    // the specified 'major' and 'minor' version numbers.  The resulting value,
-    // when expressed as a 6-digit decimal string, has "00" as the two
-    // lowest-order decimal digits, 'minor' as the next two digits, and 'major'
-    // as the highest-order digits.  The result is unique for each combination
-    // of 'major' and 'minor', and is sortable such that a value composed from
-    // a given 'major' version number will compare larger than a value composed
-    // from a smaller 'major' version number (and similarly for 'minor' version
-    // numbers).  Note that if 'major' and 'minor' are both compile-time
-    // integral constants, then the resulting expression is also a compile-time
-    // integral constant.  Also note that the patch version number is
-    // intentionally not included.  The behavior is undefined unless 'major'
-    // and 'minor' are integral values in the range '[ 0 .. 99 ]'.
-
-#define BDL_VERSION BDL_MAKE_VERSION(BDL_VERSION_MAJOR, \
+#define BDL_VERSION BSL_MAKE_VERSION(BDL_VERSION_MAJOR, \
                                      BDL_VERSION_MINOR)
     // Construct a composite version number in the range '[ 0 .. 999900 ]' from
     // the specified 'BDL_VERSION_MAJOR' and 'BDL_VERSION_MINOR' numbers


bsltf: Henry Mike's feedback.

bsltf: Henry Mike's feedback.

--- groups/bsl/bslma/bslma_stdallocator.h
+++ groups/bsl/bslma/bslma_stdallocator.h
@@ -462,7 +462,7 @@
         // definition is compiler generated.

     // MANIPULATORS
-#if 201103L <= BSLS_COMPILERFEATURES_CPLUSPLUS
+#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
     allocator& operator=(const allocator& rhs) = default;
         // Assign to this object the value of the specified 'rhs'.
         // Postcondition: 'this->mechanism() == rhs->mechanism()'.  Note that


replace hard coded boot version by a constant defined in config.h. Update copyright

--- device/puf/bootloader/boot_iface.c
+++ device/puf/bootloader/boot_iface.c
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------
   boot_iface.c - Boot interface for applications

-             (c) 2006 Pierre Gaufillet <pierre.gaufillet@magic.fr>
+             (c) 2006-2009 Pierre Gaufillet <pierre.gaufillet@magic.fr>

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
@@ -20,12 +20,11 @@

 /* $Id$ */

+#include "config.h"
 #pragma code boot_goto_table 0x1c

 // This dummy function is in fact a table of goto exported to
 // the application
-
-// TODO The boot version should be a define from config.h

 void boot_goto_table(void) __naked
 {
@@ -62,7 +61,7 @@

 ;--------------------------------

-    DW 0x0120 ; Boot Version in BCD format
+    DW BOOTLOADER_VERSION ; Boot Version in BCD format

     goto _dispatch_usb_event
     goto _init_usb


again

again

--- src/tcp_client.c
+++ src/tcp_client.c
@@ -165,7 +165,7 @@
 	hints.ai_protocol = IPPROTO_TCP;
 	hints.ai_flags = 0;
 	narc_log(NARC_WARNING, "server resolving: %s", server.host);
-	// uv_getaddrinfo(server.loop, &resolver, handle_resolved, server.host, "80", &hints);
+	uv_getaddrinfo(server.loop, &resolver, handle_resolved, server.host, "80", &hints);
 }

 void


corrected function signature of TCS_LoadMaintenanceArchive

--- src/tcs/tcspbg.c
+++ src/tcs/tcspbg.c
@@ -2863,9 +2863,9 @@
 TCSP_LoadMaintenanceArchive_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
 				     UINT32 dataInSize,	/* in */
 				     BYTE * dataIn,	/* in */
+				     TPM_AUTH * ownerAuth,	/* in, out */
 				     UINT32 * dataOutSize,	/* out */
-				     BYTE ** dataOut,	/* out */
-				     TPM_AUTH * ownerAuth	/* in, out */
+				     BYTE ** dataOut	/* out */
     )
 {
 	TSS_RESULT result;


[CIFS] Fix missing entries in search results when very long file names and
more than 50 (or so) of such long search entries in the directory.  FindNext
could send corrupt last byte of resume name when resume key was a few hundred
bytes long file name or longer.

Fixes Samba Bug # 2932

Signed-off-by: f3a218851d1cd3953207b1e8afaa851cfe20bc7e@us.ibm.com)

--- fs/cifs/cifssmb.c
+++ fs/cifs/cifssmb.c
@@ -2628,6 +2628,9 @@
 	if(name_len < PATH_MAX) {
 		memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
 		byte_count += name_len;
+		/* 14 byte parm len above enough for 2 byte null terminator */
+		pSMB->ResumeFileName[name_len] = 0;
+		pSMB->ResumeFileName[name_len+1] = 0;
 	} else {
 		rc = -EINVAL;
 		goto FNext2_err_exit;


ext4: delete path dealloc code in ext4_ext_handle_uninitialized_extents

Code deallocating the extent path referenced by an argument to
ext4_ext_handle_uninitialized_extents was made redundant with identical
code in its one caller, ext4_ext_map_blocks, by commit 3779473246.
Allocating and deallocating the path in the same function also makes
the code clearer.

Signed-off-by: Eric Whitney <ba5ac80d1fb5812604686391b77cc69908a724fa@gmail.com>
Signed-off-by: "Theodore Ts'o" <4ed386e0495d3e109932df055831d9ec2f824927@mit.edu>

--- fs/ext4/extents.c
+++ fs/ext4/extents.c
@@ -4005,10 +4005,6 @@
 	map->m_pblk = newblock;
 	map->m_len = allocated;
 out2:
-	if (path) {
-		ext4_ext_drop_refs(path);
-		kfree(path);
-	}
 	return err ? err : allocated;
 }

@@ -4208,7 +4204,7 @@
 				err = ret;
 			else
 				allocated = ret;
-			goto out3;
+			goto out2;
 		}
 	}

@@ -4489,7 +4485,6 @@
 		kfree(path);
 	}

-out3:
 	trace_ext4_ext_map_blocks_exit(inode, flags, map,
 				       err ? err : allocated);
 	ext4_es_lru_add(inode);


librbd: add C api I/O tests

librbd: add C api I/O tests

--- src/testlibrbd.c
+++ src/testlibrbd.c
@@ -23,10 +23,12 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <time.h>
+#include <unistd.h>

 #define TEST_IMAGE "testimg"
 #define TEST_POOL "librbdtest"
 #define TEST_SNAP "testsnap"
+#define TEST_IO_SIZE 513
 #define MB_BYTES(mb) (mb << 20)

 void test_create_and_stat(rbd_pool_t pool, const char *name, size_t size)
@@ -148,6 +150,98 @@
   assert(rbd_remove_snap(image, name) == 0);
 }

+void simple_write_cb(rbd_completion_t cb, void *arg)
+{
+  //  printf("write completion cb called!\n");
+}
+
+void simple_read_cb(rbd_completion_t cb, void *arg)
+{
+  //  printf("read completion cb called!\n");
+}
+
+void aio_write_test_data(rbd_image_t image, const char *test_data, off_t off)
+{
+  rbd_completion_t comp;
+  rbd_aio_create_completion(NULL, (rbd_callback_t) simple_write_cb, &comp);
+  printf("created completion\n");
+  rbd_aio_write(image, off, strlen(test_data), test_data, comp);
+  printf("started write\n");
+  rbd_aio_wait_for_complete(comp);
+  printf("finished write\n");
+  rbd_aio_release(comp);
+}
+
+void write_test_data(rbd_image_t image, const char *test_data, off_t off)
+{
+  size_t written;
+  size_t len = strlen(test_data);
+  while (len > 0) {
+    written = rbd_write(image, off, len, test_data);
+    assert(written >= 0);
+    len -= written;
+    off += written;
+    printf("wrote: %u\n", (unsigned int) written);
+  }
+}
+
+void aio_read_test_data(rbd_image_t image, const char *expected, off_t off)
+{
+  rbd_completion_t comp;
+  char result[TEST_IO_SIZE];
+  rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp);
+  printf("created completion\n");
+  rbd_aio_read(image, off, strlen(expected), result, comp);
+  printf("started read\n");
+  rbd_aio_wait_for_complete(comp);
+  printf("finished read\n");
+  rbd_aio_release(comp);
+}
+
+void read_test_data(rbd_image_t image, const char *expected, off_t off)
+{
+  size_t read, total_read = 0;
+  size_t expected_len = strlen(expected);
+  size_t len = expected_len;
+  char result[TEST_IO_SIZE];
+  char *buf = result;
+  while (len > 0) {
+    read = rbd_read(image, off + total_read, len, buf);
+    assert(read >= 0);
+    total_read += read;
+    buf += read;
+    len -= read;
+    printf("read: %u\n", (unsigned int) read);
+  }
+  printf("read: %s\nexpected: %s\n", result, expected);
+  assert(strncmp(result, expected, expected_len) == 0);
+}
+
+void test_io(rbd_pool_t pool, rbd_image_t image)
+{
+  char test_data[TEST_IO_SIZE];
+  int i;
+
+  srand(time(0));
+  for (i = 0; i < TEST_IO_SIZE - 1; ++i) {
+    test_data[i] = (char) (rand() % (126 - 33) + 33);
+  }
+  test_data[TEST_IO_SIZE - 1] = '\0';
+
+  for (i = 0; i < 5; ++i)
+    write_test_data(image, test_data, strlen(test_data) * i);
+
+  for (i = 0; i < 5; ++i)
+    aio_write_test_data(image, test_data, strlen(test_data) * i);
+
+  for (i = 0; i < 5; ++i)
+    read_test_data(image, test_data, strlen(test_data) * i);
+
+  for (i = 0; i < 5; ++i)
+    aio_read_test_data(image, test_data, strlen(test_data) * i);
+
+}
+
 int main(int argc, const char **argv)
 {
   rbd_pool_t pool;
@@ -162,6 +256,7 @@
   test_create_snap(image, TEST_SNAP);
   test_ls_snaps(image, 1, TEST_SNAP, MB_BYTES(1));
   test_resize_and_stat(image, MB_BYTES(2));
+  test_io(pool, image);
   test_create_snap(image, TEST_SNAP "1");
   test_ls_snaps(image, 2, TEST_SNAP, MB_BYTES(1), TEST_SNAP "1", MB_BYTES(2));
   test_delete_snap(image, TEST_SNAP);


NFSv4: Don't loop forever on state recovery failure...

If the server is broken, then retrying forever won't fix it. We
should just give up after a while, and return an error to the user.
We set the number of retries to 10 for now...

Signed-off-by: Trond Myklebust <6a1f9db795c9fc44be97d66ab114c53193bd3d13@netapp.com>

--- fs/nfs/nfs4proc.c
+++ fs/nfs/nfs4proc.c
@@ -60,6 +60,8 @@

 #define NFS4_POLL_RETRY_MIN	(HZ/10)
 #define NFS4_POLL_RETRY_MAX	(15*HZ)
+
+#define NFS4_MAX_LOOP_ON_RECOVER (10)

 struct nfs4_opendata;
 static int _nfs4_proc_open(struct nfs4_opendata *data);
@@ -426,17 +428,19 @@
 static int nfs4_recover_session(struct nfs4_session *session)
 {
 	struct nfs_client *clp = session->clp;
+	unsigned int loop;
 	int ret;

-	for (;;) {
+	for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
 		ret = nfs4_wait_clnt_recover(clp);
 		if (ret != 0)
-				return ret;
+			break;
 		if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
 			break;
 		nfs4_schedule_state_manager(clp);
-	}
-	return 0;
+		ret = -EIO;
+	}
+	return ret;
 }

 static int nfs41_setup_sequence(struct nfs4_session *session,
@@ -1444,18 +1448,20 @@
 static int nfs4_recover_expired_lease(struct nfs_server *server)
 {
 	struct nfs_client *clp = server->nfs_client;
+	unsigned int loop;
 	int ret;

-	for (;;) {
+	for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
 		ret = nfs4_wait_clnt_recover(clp);
 		if (ret != 0)
-			return ret;
+			break;
 		if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
 		    !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
 			break;
 		nfs4_schedule_state_recovery(clp);
-	}
-	return 0;
+		ret = -EIO;
+	}
+	return ret;
 }

 /*


testlibrbd: fix printf args

testlibrbd: fix printf args

Stupid me!

Signed-off-by: Sage Weil <c5b6ff1fd4f0bde10db63d7a3e07166cf6c4229f@dreamhost.com>

--- src/testlibrbd.c
+++ src/testlibrbd.c
@@ -61,13 +61,10 @@
   va_list ap;
   size_t max_size = 1024;
   names = (char *) malloc(sizeof(char *) * 1024);
-  int r = printf("names is %x\n", names);
-  assert(r >= 0);
+  printf("names is %p\n", names);
   num_images = rbd_list(pool, names, &max_size);
-  r = printf("names is %x\n", names);
-  assert(r >= 0);
-  r = printf("num images is: %d\nexpected: %d\n", num_images, num_expected);
-  assert(r >= 0);
+  printf("names is %p\n", names);
+  printf("num images is: %d\nexpected: %d\n", num_images, (int)num_expected);
   assert(num_images >= 0);
   assert(num_images == num_expected);


librbd: initialize order in C API test

librbd: initialize order in C API test

--- src/testlibrbd.c
+++ src/testlibrbd.c
@@ -33,7 +33,7 @@
 {
   rbd_image_info_t info;
   rbd_image_t image;
-  int order;
+  int order = 0;
   assert(rbd_create(pool, name, size, &order) == 0);
   assert(rbd_open_image(pool, name, &image) == 0);
   assert(rbd_stat(image, &info) == 0);
@@ -179,4 +179,3 @@
   rbd_shutdown();
   return 0;
 }
-


gtk: undef DISABLE_DEPRECATED around including our own header

so we can see our own deprecated API and don't get warnings.

--- gtk/gtkviewport.c
+++ gtk/gtkviewport.c
@@ -25,11 +25,13 @@
  */

 #include "config.h"
-#include "gtkviewport.h"
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtktypeutils.h"
 #include "gtkscrollable.h"
+#undef GTK_DISABLE_DEPRECATED
+#include "gtkviewport.h"
+#define GTK_DISABLE_DEPRECATED
 #include "gtkprivate.h"


libasignify: databuf.c flattening (NFC)

libasignify: databuf.c flattening (NFC)

Signed-off-by: Kyle Evans <bdbb8922150f6bdb47902fe294c5e84994ac55b2@FreeBSD.org>

--- libasignify/databuf.c
+++ libasignify/databuf.c
@@ -182,15 +182,17 @@
 		return (NULL);
 	}

-	if ((p = strchr(p, ':')) != NULL) {
-		/* We have some aux data for this line */
-		p ++;
-		res->aux_len = strcspn(p, "\n\r");
-		if (res->aux_len > 0) {
-			res->aux = xmalloc(res->aux_len + 1);
-			memcpy(res->aux, p, res->aux_len);
-			res->aux[res->aux_len] = '\0';
-		}
+	if ((p = strchr(p, ':')) == NULL) {
+		return (res);
+	}
+
+	/* We have some aux data for this line */
+	p ++;
+	res->aux_len = strcspn(p, "\n\r");
+	if (res->aux_len > 0) {
+		res->aux = xmalloc(res->aux_len + 1);
+		memcpy(res->aux, p, res->aux_len);
+		res->aux[res->aux_len] = '\0';
 	}

 	return (res);
@@ -214,17 +216,19 @@
 static void
 asignify_privkey_cleanup(struct asignify_private_key *privk)
 {
-	if (privk != NULL) {
-		free(privk->checksum);
-		if (privk->encrypted_blob) {
-			explicit_memzero(privk->encrypted_blob, crypto_sign_SECRETKEYBYTES);
-		}
-		free(privk->encrypted_blob);
-		free(privk->id);
-		free(privk->pbkdf_alg);
-		free(privk->salt);
-		explicit_memzero(privk, sizeof(*privk));
-	}
+	if (privk == NULL) {
+		return;
+	}
+
+	free(privk->checksum);
+	if (privk->encrypted_blob) {
+		explicit_memzero(privk->encrypted_blob, crypto_sign_SECRETKEYBYTES);
+	}
+	free(privk->encrypted_blob);
+	free(privk->id);
+	free(privk->pbkdf_alg);
+	free(privk->salt);
+	explicit_memzero(privk, sizeof(*privk));
 }

 static bool
@@ -372,28 +376,20 @@
 static bool
 asignify_private_key_is_sane(struct asignify_private_key *privk)
 {
-	if (privk->pbkdf_alg && strcmp(privk->pbkdf_alg, PBKDF_ALG) == 0) {
-		if (privk->rounds >= PBKDF_MINROUNDS) {
-			if (privk->salt) {
-				if (privk->version == 1) {
-					if (privk->encrypted_blob != NULL &&
-									privk->checksum != NULL) {
-						return (true);
-					}
-				}
-			}
-		}
-	}
-	else {
+	if (!privk->pbkdf_alg || strcmp(privk->pbkdf_alg, PBKDF_ALG) != 0) {
 		/* Unencrypted key */
-		if (privk->version == 1) {
-			if (privk->encrypted_blob != NULL) {
-				return (true);
-			}
-		}
-	}
-
-	return (false);
+		return (privk->version == 1 && privk->encrypted_blob != NULL);
+	}
+
+	if (privk->rounds < PBKDF_MINROUNDS) {
+		return (false);
+	}
+
+	if (privk->salt == NULL || privk->version != 1) {
+		return (false);
+	}
+
+	return (privk->encrypted_blob != NULL && privk->checksum != NULL);
 }

 static void
@@ -423,66 +419,62 @@
 	unsigned char xorkey[crypto_sign_SECRETKEYBYTES];
 	unsigned char res_checksum[BLAKE2B_OUTBYTES];
 	int r;
+	bool ok = false;

 	priv = xmalloc(sizeof(*priv));
-
-	if (privk->pbkdf_alg) {
-		/* We need to derive key */
-		if (password_cb == NULL) {
-			free(priv);
-			asignify_privkey_cleanup(privk);
-			return (NULL);
-		}
-
-		/* Some buffer overflow protection */
-		randombytes(canary, sizeof(canary));
-		memcpy(password + sizeof(password) - sizeof(canary), canary,
-				sizeof(canary));
-		r = password_cb(password, sizeof(password) - sizeof(canary), d);
-		if (r <= 0 || r > sizeof(password) - sizeof(canary) ||
-			memcmp(password + sizeof(password) - sizeof(canary), canary, sizeof(canary)) != 0) {
-			free(priv);
-			explicit_memzero(password, sizeof(password));
-			asignify_privkey_cleanup(privk);
-			return (NULL);
-		}
-
-		if (pkcs5_pbkdf2(password, r, privk->salt, SALT_LEN, xorkey, sizeof(xorkey),
-			privk->rounds) == -1) {
-			free(priv);
-			explicit_memzero(password, sizeof(password));
-			asignify_privkey_cleanup(privk);
-			return (NULL);
-		}
-		explicit_memzero(password, sizeof(password));
-
-		for (r = 0; r < sizeof(xorkey); r ++) {
-			privk->encrypted_blob[r] ^= xorkey[r];
-		}
-
-		explicit_memzero(xorkey, sizeof(xorkey));
-		blake2b(res_checksum, privk->encrypted_blob, NULL, BLAKE2B_OUTBYTES,
-			sizeof(xorkey), 0);
-
-		if (memcmp(res_checksum, privk->checksum, sizeof(res_checksum)) != 0) {
-			explicit_memzero(privk->encrypted_blob, crypto_sign_SECRETKEYBYTES);
-			asignify_privkey_cleanup(privk);
-			free(priv);
-
-			if (error != NULL) {
-				*error = ASIGNIFY_ERROR_PASSWORD;
-			}
-
-			return (NULL);
-		}
-		asignify_pkey_to_private_data(privk, priv);
-	}
-	else {
-		asignify_pkey_to_private_data(privk, priv);
-	}
-
+	if (privk->pbkdf_alg == NULL) {
+		goto done;
+	}
+
+	/* We need to derive key */
+	if (password_cb == NULL) {
+		goto cleanup;
+	}
+
+	/* Some buffer overflow protection */
+	randombytes(canary, sizeof(canary));
+	memcpy(password + sizeof(password) - sizeof(canary), canary,
+			sizeof(canary));
+	r = password_cb(password, sizeof(password) - sizeof(canary), d);
+	if (r <= 0 || r > sizeof(password) - sizeof(canary) ||
+		memcmp(password + sizeof(password) - sizeof(canary), canary, sizeof(canary)) != 0) {
+		goto cleanup;
+	}
+
+	if (pkcs5_pbkdf2(password, r, privk->salt, SALT_LEN, xorkey, sizeof(xorkey),
+		privk->rounds) == -1) {
+		goto cleanup;
+	}
+
+	explicit_memzero(password, sizeof(password));
+
+	for (r = 0; r < sizeof(xorkey); r ++) {
+		privk->encrypted_blob[r] ^= xorkey[r];
+	}
+
+	explicit_memzero(xorkey, sizeof(xorkey));
+	blake2b(res_checksum, privk->encrypted_blob, NULL, BLAKE2B_OUTBYTES,
+		sizeof(xorkey), 0);
+
+	if (memcmp(res_checksum, privk->checksum, sizeof(res_checksum)) != 0) {
+		if (error != NULL) {
+			*error = ASIGNIFY_ERROR_PASSWORD;
+		}
+
+		goto cleanup;
+	}
+
+done:
+	ok = true;
+	asignify_pkey_to_private_data(privk, priv);
+
+cleanup:
+	explicit_memzero(password, sizeof(password));
 	asignify_privkey_cleanup(privk);
-
+	if (!ok) {
+		free(priv);
+		priv = NULL;
+	}
 	return (priv);
 }

@@ -492,51 +484,55 @@
 {
 	char *buf = NULL;
 	size_t buflen = 0;
+	struct asignify_private_data *pkeyd;
 	struct asignify_private_key privk;
 	bool first = true;
 	ssize_t r;

 	memset(&privk, 0, sizeof(privk));
+	pkeyd = NULL;

 	while ((r = getline(&buf, &buflen, f)) != -1) {
 		if (first) {
 			/* Check magic */
-			if (memcmp(buf, PRIVKEY_MAGIC, sizeof(PRIVKEY_MAGIC) - 1) == 0) {
-				first = false;
-			}
-			else {
+			if (memcmp(buf, PRIVKEY_MAGIC, sizeof(PRIVKEY_MAGIC) - 1) != 0) {
 				return (NULL);
 			}
-		}
-		else {
-			if (!asignify_private_data_parse_line(buf, r, &privk)) {
-				asignify_privkey_cleanup(&privk);
-				return (NULL);
-			}
+
+			first = false;
+			continue;
+		}
+
+		if (!asignify_private_data_parse_line(buf, r, &privk)) {
+			goto cleanup;
 		}
 	}

 	if (!asignify_private_key_is_sane(&privk)) {
-		asignify_privkey_cleanup(&privk);
-		return (NULL);
-	}
-
-	return (asignify_private_data_unpack_key(&privk, error, password_cb, d));
+		goto cleanup;
+	}
+
+	pkeyd = asignify_private_data_unpack_key(&privk, error, password_cb, d);
+cleanup:
+	asignify_privkey_cleanup(&privk);
+	return (pkeyd);
 }

 void
 asignify_private_data_free(struct asignify_private_data *d)
 {
-	if (d != NULL) {
-		free(d->id);
-		d->id = NULL;
-		explicit_memzero(d->data, d->data_len);
+	if (d == NULL) {
+		return;
+	}
+
+	free(d->id);
+	d->id = NULL;
+	explicit_memzero(d->data, d->data_len);
 #ifdef HAVE_MLOCK
-		munlock(d->data, d->data_len);
+	munlock(d->data, d->data_len);
 #endif
-		free(d->data);
-		free(d);
-	}
+	free(d->data);
+	free(d);
 }

 const unsigned char *


(linux / C pre-processor) use HAVE_* instead of HAS_* for consistency with Python source code

--- psutil/_psutil_linux.c
+++ psutil/_psutil_linux.c
@@ -23,11 +23,11 @@

  // Linux >= 2.6.13
-#define HAS_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
+#define HAVE_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
  // Linux >= 2.6.36 kernels, glibc >= 2.13
-#define HAS_PRLIMIT defined(prlimit)
-
-#if HAS_IOPRIO
+#define HAVE_PRLIMIT defined(prlimit)
+
+#if HAVE_IOPRIO
 enum {
     IOPRIO_WHO_PROCESS = 1,
 };
@@ -99,7 +99,7 @@
 #endif

-#ifdef HAS_PRLIMIT
+#ifdef HAVE_PRLIMIT
 /*
  * A wrapper around prlimit(2); sets process resource limits.
  * This can be used for both get and set, in which case extra
@@ -325,13 +325,13 @@
 {
       // --- per-process functions

-#if HAS_IOPRIO
+#if HAVE_IOPRIO
      {"ioprio_get", linux_ioprio_get, METH_VARARGS,
         "Get process I/O priority"},
      {"ioprio_set", linux_ioprio_set, METH_VARARGS,
         "Set process I/O priority"},
 #endif
-#ifdef HAS_PRLIMIT
+#ifdef HAVE_PRLIMIT
      {"prlimit", linux_prlimit, METH_VARARGS,
         "Get or set process resource limits."},
 #endif
@@ -408,7 +408,7 @@
 #endif

-#ifdef HAS_PRLIMIT
+#ifdef HAVE_PRLIMIT
     PyModule_AddIntConstant(module, "RLIM_INFINITY", RLIM_INFINITY);
     PyModule_AddIntConstant(module, "RLIMIT_AS", RLIMIT_AS);
     PyModule_AddIntConstant(module, "RLIMIT_CORE", RLIMIT_CORE);


Accept 0 length chunk as valid

Accept 0 length chunk as valid

In case en empty file is passed to ucl_parser_add_file, instead of
mmaping the file it set the chunk to "" and length to 0. But
ucl_parser_add_chunk rejects 0 length chunk as invalid chunk.

Change that behaviour to accept empty chunk, but continue rejecting NULL
chunks

--- src/ucl_parser.c
+++ src/ucl_parser.c
@@ -1941,9 +1941,12 @@
 {
 	struct ucl_chunk *chunk;

-	if (data == NULL || len == 0) {
+	if (data == NULL) {
 		ucl_create_err (&parser->err, "invalid chunk added");
 		return false;
+	}
+	if (len == 0) {
+		return true;
 	}
 	if (parser->state != UCL_STATE_ERROR) {
 		chunk = UCL_ALLOC (sizeof (struct ucl_chunk));


Fix public blobs loading.

Fix public blobs loading.

--- libasignify/databuf.c
+++ libasignify/databuf.c
@@ -138,8 +138,8 @@
 		return (NULL);
 	}

-	p += magiclen - 1;
-	remain -= magiclen - 1;
+	p += magiclen;
+	remain -= magiclen;

 	version = strtoul(p, &errstr, 10);
 	if (errstr == NULL || *errstr != ':'
@@ -149,11 +149,12 @@

 	res = xmalloc(sizeof(*res));
 	res->version = 1;
-	res->data_len = id_len;
-	res->id_len = data_len;
+	res->data_len = data_len;
+	res->id_len = id_len;
 	asignify_alloc_public_data_fields(res);

 	/* Read ID */
+	p = errstr + 1;
 	blen = b64_pton_stop(p, res->id, res->id_len, ":");
 	if (blen != res->id_len || (p = strchr(p, ':')) == NULL) {
 		asignify_public_data_free(res);


enable net_if_stats implem on OpenBSD too, examples/ifconfig.py works

--- psutil/_psutil_posix.c
+++ psutil/_psutil_posix.c
@@ -230,7 +230,7 @@
  * net_if_stats() implementation. This is here because it is common
  * to both OSX and FreeBSD and I didn't know where else to put it.
  */
-#if defined(__FreeBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)

 #include <sys/sockio.h>
 #include <net/if_media.h>
@@ -267,8 +267,8 @@
                 case(IFM_1000_SX):  // 1000BaseSX - multi-mode fiber
                 case(IFM_1000_LX):  // 1000baseLX - single-mode fiber
                 case(IFM_1000_CX):  // 1000baseCX - 150ohm STP
-#if defined(IFM_1000_TX) && !defined(OPENBSD)
-                // FreeBSD 4 and others (but NOT OpenBSD)?
+#if defined(IFM_1000_TX) && !defined(__OpenBSD__)
+                // FreeBSD 4 and others (but NOT OpenBSD) -> #define IFM_1000_T in net/if_media.h
                 case(IFM_1000_TX):
 #endif
 #ifdef IFM_1000_FX
@@ -460,7 +460,7 @@
      "Set process priority"},
     {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
      "Retrieve NICs information"},
-#if defined(__FreeBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
     {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
      "Return NIC stats."},
 #endif


ucm: CTL devices are only one per card (remove DEV from comments)

Signed-off-by: Jaroslav Kysela <72edd5e1a572f82f059ccbb83c92b74d6cb051ff@perex.cz>

--- src/ucm/parser.c
+++ src/ucm/parser.c
@@ -188,7 +188,7 @@
  *
  * Sequence controls elements  are in the following form:-
  *
- * cdev "hw:0,0"
+ * cdev "hw:0"
  * cset "element_id_syntax value_syntax"
  * usleep time
  * exec "any unix command with arguments"
@@ -942,8 +942,8 @@
  * # Define Value defaults
  *
  * ValueDefaults {
- *	PlaybackCTL "hw:CARD=0,DEV=0"
- *	CaptureCTL "hw:CARD=0,DEV=0"
+ *	PlaybackCTL "hw:CARD=0"
+ *	CaptureCTL "hw:CARD=0"
  * }
  *
  * # This file also stores the default sound card state.


sensless cast and ()

sensless cast and ()

git-svn-id: a4d7c1866f8397a4106e0b57fc4fbf792bbdaaaf@11118 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

--- libavcodec/resample.c
+++ libavcodec/resample.c
@@ -191,7 +191,7 @@
     }

     /* make some zoom to avoid round pb */
-    lenout= (int)(4*nb_samples * s->ratio) + 16;
+    lenout= 4*nb_samples * s->ratio + 16;
     bufout[0]= av_malloc( lenout * sizeof(short) );
     bufout[1]= av_malloc( lenout * sizeof(short) );


fixing udp resolve

fixing udp resolve

--- src/udp_client.c
+++ src/udp_client.c
@@ -101,7 +101,7 @@
 handle_udp_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res)
 {
 	if (status >= 0){
-		narc_log(NARC_WARNING, "server resolved: %s", server.host);
+		narc_log(NARC_WARNING, "server resolved: %s to %s", server.host,res->ai_addr->sa_data);
 		start_udp_bind(res);
 	}else{
 		narc_log(NARC_WARNING, "server did not resolve: %s", server.host);


More verbose error log message.

More verbose error log message.

git-svn-id: a4d7c1866f8397a4106e0b57fc4fbf792bbdaaaf@11556 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

--- libavdevice/x11grab.c
+++ libavdevice/x11grab.c
@@ -113,7 +113,7 @@
     }

     if (!ap || ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) {
-        av_log(s1, AV_LOG_ERROR, "AVParameters don't have any video size. Use -s.\n");
+        av_log(s1, AV_LOG_ERROR, "AVParameters don't have video size and/or rate. Use -s and -r.\n");
         return AVERROR(EIO);
     }


libbpf-tools: update fsdist for libbpf 1.0

Switch to libbpf 1.0 mode and adapt libbpf API usage accordingly.

Signed-off-by: Andrii Nakryiko <450886ab958931a1b640c5db7e55f3b50c4bb462@kernel.org>

--- libbpf-tools/fsdist.c
+++ libbpf-tools/fsdist.c
@@ -300,53 +300,44 @@

 	/* READ */
 	obj->links.file_read_entry = bpf_program__attach_kprobe(obj->progs.file_read_entry, false, cfg->op_funcs[READ]);
-	err = libbpf_get_error(obj->links.file_read_entry);
-	if (err)
+	if (!obj->links.file_read_entry)
 		goto errout;
 	obj->links.file_read_exit = bpf_program__attach_kprobe(obj->progs.file_read_exit, true, cfg->op_funcs[READ]);
-	err = libbpf_get_error(obj->links.file_read_exit);
-	if (err)
+	if (!obj->links.file_read_exit)
 		goto errout;
 	/* WRITE */
 	obj->links.file_write_entry = bpf_program__attach_kprobe(obj->progs.file_write_entry, false, cfg->op_funcs[WRITE]);
-	err = libbpf_get_error(obj->links.file_write_entry);
-	if (err)
+	if (!obj->links.file_write_entry)
 		goto errout;
 	obj->links.file_write_exit = bpf_program__attach_kprobe(obj->progs.file_write_exit, true, cfg->op_funcs[WRITE]);
-	err = libbpf_get_error(obj->links.file_write_exit);
-	if (err)
+	if (!obj->links.file_write_exit)
 		goto errout;
 	/* OPEN */
 	obj->links.file_open_entry = bpf_program__attach_kprobe(obj->progs.file_open_entry, false, cfg->op_funcs[OPEN]);
-	err = libbpf_get_error(obj->links.file_open_entry);
-	if (err)
+	if (!obj->links.file_open_entry)
 		goto errout;
 	obj->links.file_open_exit = bpf_program__attach_kprobe(obj->progs.file_open_exit, true, cfg->op_funcs[OPEN]);
-	err = libbpf_get_error(obj->links.file_open_exit);
-	if (err)
+	if (!obj->links.file_open_exit)
 		goto errout;
 	/* FSYNC */
 	obj->links.file_sync_entry = bpf_program__attach_kprobe(obj->progs.file_sync_entry, false, cfg->op_funcs[FSYNC]);
-	err = libbpf_get_error(obj->links.file_sync_entry);
-	if (err)
+	if (!obj->links.file_sync_entry)
 		goto errout;
 	obj->links.file_sync_exit = bpf_program__attach_kprobe(obj->progs.file_sync_exit, true, cfg->op_funcs[FSYNC]);
-	err = libbpf_get_error(obj->links.file_sync_exit);
-	if (err)
+	if (!obj->links.file_sync_exit)
 		goto errout;
 	/* GETATTR */
 	if (!cfg->op_funcs[GETATTR])
 		return 0;
 	obj->links.getattr_entry = bpf_program__attach_kprobe(obj->progs.getattr_entry, false, cfg->op_funcs[GETATTR]);
-	err = libbpf_get_error(obj->links.getattr_entry);
-	if (err)
+	if (!obj->links.getattr_entry)
 		goto errout;
 	obj->links.getattr_exit = bpf_program__attach_kprobe(obj->progs.getattr_exit, true, cfg->op_funcs[GETATTR]);
-	err = libbpf_get_error(obj->links.getattr_exit);
-	if (err)
+	if (!obj->links.getattr_exit)
 		goto errout;
 	return 0;
 errout:
+	err = -errno;
 	warn("failed to attach kprobe: %ld\n", err);
 	return err;
 }
@@ -374,13 +365,8 @@
 		return 1;
 	}

+	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
 	libbpf_set_print(libbpf_print_fn);
-
-	err = bump_memlock_rlimit();
-	if (err) {
-		warn("failed to increase rlimit: %d\n", err);
-		return 1;
-	}

 	skel = fsdist_bpf__open();
 	if (!skel) {


Fix nasty behavior difference from glibc -- also fixes getline()  -Erik

--- libc/stdio/getdelim.c
+++ libc/stdio/getdelim.c
@@ -41,13 +41,12 @@
 	int ch;
 	int idx = 0;

-	if ((file == NULL || linebuf==NULL || *linebuf == NULL || *linebufsz == 0)
-			&& !(*linebuf == NULL && *linebufsz ==0 )) {
+	if (file == NULL || linebuf==NULL || linebufsz == NULL) {
 	    __set_errno(EINVAL);
 	    return -1;
 	}

-	if (*linebuf == NULL && *linebufsz == 0){
+	if (*linebuf == NULL || *linebufsz < 2) {
 		*linebuf = malloc(GROWBY);
 		if (!*linebuf) {
 			__set_errno(ENOMEM);


fixes to compile with visual studio

fixes to compile with visual studio

--- src/ujo_endian.h
+++ src/ujo_endian.h
@@ -81,7 +81,9 @@
     union {
         uint32_t ui32;
         float32_t f32;
-    } union_swap = { .f32 = value};
+    } union_swap;
+
+	union_swap.f32  = value;

     union_swap.ui32 = _ujo_uint32_swap(union_swap.ui32);

@@ -93,8 +95,9 @@
     union {
         uint64_t ui64;
         float64_t f64;
-    } union_swap = { .f64 = value};
+    } union_swap;

+	union_swap.f64  = value;
     union_swap.ui64 = _ujo_uint64_swap(union_swap.ui64);

     return union_swap.f64;