示例#1
0
文件: bat5.c 项目: sekcheong/monetdb
/*
 * BBP Management, IO
 */
static gdk_return
CMDrename(bit *retval, BAT *b, const char *s)
{
	int ret;
	int c;
	const char *t = s;

	for ( ; (c = *t) != 0; t++) {
		if (c != '_' && !GDKisalnum(c)) {
			GDKerror("CMDrename: identifier expected: %s\n", s);
			return GDK_FAIL;
		}
	}

	ret = BATname(b, s);
	*retval = FALSE;
	if (ret == 1) {
		GDKerror("CMDrename: identifier expected: %s\n", s);
		return GDK_FAIL;
	} else if (ret == BBPRENAME_ILLEGAL) {
		GDKerror("CMDrename: illegal temporary name: '%s'\n", s);
		return GDK_FAIL;
	} else if (ret == BBPRENAME_LONG) {
		GDKerror("CMDrename: name too long: '%s'\n", s);
		return GDK_FAIL;
	} else if (ret != BBPRENAME_ALREADY) {
		*retval = TRUE;
	}
	return GDK_SUCCEED;
}
示例#2
0
/*
 * @+ Atomic Type Interface
 * The collection of built-in types supported for BATs can be extended
 * easily.  In essence, the user should specify conversion routines
 * from values stored anywhere in memory to its equivalent in the BAT,
 * and vice verse.  Some routines are required for coercion and to
 * support the BAT administration.
 *
 * A new type is incrementally build using the routine
 * ATOMallocate(id).  The parameter id denotes the type name; an entry
 * is created if the type is so far unknown.
 *
 * The size describes the amount of space to be reserved in the BUN.
 *
 * The routine put takes a pointer to a memory resident copy and
 * prepares a persistent copy in the BAT passed.  The inverse
 * operation is get.  A new value can be directly included into the
 * BAT using new, which should prepare a null-value representation.  A
 * value is removed from the BAT store using del, which can take care
 * of garbage collection and BAT administration.
 *
 * The pair tostr and fromstr should convert a reference to a
 * persistent value to a memory resident string equivalent. FromStr
 * takes a string and applies a put to store it within a BAT.  They
 * are used to prepare for readable output/input and to support
 * coercion.
 *
 * The routines cmp and eq are comparison routines used to build
 * access structures. The null returns a reference to a null value
 * representation.
 *
 * The incremental atom construction uses hardwired properties.  This
 * should be improved later on.
 */
int
ATOMallocate(const char *id)
{
	int t;

	if (strlen(id) >= IDLENGTH) {
		GDKerror("ATOMallocate: name too long");
		return int_nil;
	}

	MT_lock_set(&GDKthreadLock);
	t = ATOMindex(id);
	if (t < 0) {
		t = -t;
		if (t == GDKatomcnt) {
			if (GDKatomcnt == MAXATOMS) {
				MT_lock_unset(&GDKthreadLock);
				GDKerror("ATOMallocate: too many types");
				return int_nil;
			}
			GDKatomcnt++;
		}
		BATatoms[t] = (atomDesc) {
			.size = sizeof(int),	/* default */
			.linear = true,		/* default */
			.storage = t,		/* default */
		};
		strcpy(BATatoms[t].name, id);
	}
	MT_lock_unset(&GDKthreadLock);
	return t;
}
示例#3
0
/*
 * The MonetDB server uses a startup script to boot the system.
 * This script is an ordinary MAL program, but will mostly
 * consist of include statements to load modules of general interest.
 * The startup script is run as user Admin.
 */
int
malBootstrap(void)
{
	Client c;
	str msg, bootfile = "mal_init", s;

	c = MCinitClient((oid) 0, 0, 0);
	assert(c != NULL);
	c->nspace = newModule(NULL, putName("user", 4));
	initLibraries();
	if ( (msg = defaultScenario(c)) ) {
		GDKfree(msg);
		GDKerror("Failed to initialise default scenario");
		return 0;
	}
	MSinitClientPrg(c, "user", "main");
	(void) MCinitClientThread(c);
	s = malInclude(c, bootfile, 0);
	if (s != NULL) {
		mnstr_printf(GDKout, "!%s\n", s);
		GDKfree(s);
		return 0;
	}
	pushEndInstruction(c->curprg->def);
	chkProgram(c->fdout, c->nspace, c->curprg->def);
	if (c->curprg->def->errors)
		showErrors(c);
	s = MALengine(c);
	if (s)
		GDKfree(s);
	return 1;
}
示例#4
0
/*
 * The emergency flag can be set to force a fatal error if needed.
 * Otherwise, the caller is able to deal with the lack of memory.
 */
void *
GDKmallocmax(size_t size, size_t *maxsize, int emergency)
{
	ssize_t *s = NULL;

	if (size == 0) {
#ifdef GDK_MEM_NULLALLOWED
		return NULL;
#else
		GDKfatal("GDKmallocmax: called with size " SZFMT "", size);
#endif
	}
	size = (size + 7) & ~7;	/* round up to a multiple of eight */
	GDKmalloc_prefixsize(s, size);
	if (s == NULL) {
		GDKmemfail("GDKmalloc", size);
		GDKmalloc_prefixsize(s, size);
		if (s == NULL) {
			if (emergency == 0) {
				GDKerror("GDKmallocmax: failed for " SZFMT " bytes", size);
				return NULL;
			}
			GDKfatal("GDKmallocmax: failed for " SZFMT " bytes", size);
		} else {
			THRprintf(GDKstdout, "#GDKmallocmax: recovery ok. Continuing..\n");
		}
	}
	*maxsize = size;
	heapinc(size + MALLOC_EXTRA_SPACE);
	return (void *) s;
}
示例#5
0
/*
 * Determine the variables being used and clear non-used onces.
 */
void
MSresetVariables(Client cntxt, MalBlkPtr mb, MalStkPtr glb, int start)
{
	int i;
	bit *used = GDKzalloc(mb->vtop * sizeof(bit));
	if( used == NULL){
		GDKerror("MSresetVariables" MAL_MALLOC_FAIL);
		return;
	}

	for (i = 0; i < start && start < mb->vtop; i++)
		used[i] = 1;
	if (mb->errors == 0)
		for (i = start; i < mb->vtop; i++) {
			if (used[i] || !isTmpVar(mb, i)) {
				assert(!mb->var[i]->value.vtype || isVarConstant(mb, i));
				used[i] = 1;
			}
			if (glb && !used[i]) {
				if (isVarConstant(mb, i))
					garbageElement(cntxt, &glb->stk[i]);
				/* clean stack entry */
				glb->stk[i].vtype = TYPE_int;
				glb->stk[i].len = 0;
				glb->stk[i].val.pval = 0;
			}
		}

	if (mb->errors == 0)
		trimMalVariables_(mb, used, glb);
	GDKfree(used);
}
示例#6
0
sht
PropertyIndex(str name)
{
	int i=0;
	for (i=0; i<nr_properties; i++) {
		if (strcmp(properties[i], name) == 0)
			return i;
	}
	MT_lock_set(&mal_contextLock, "propertyIndex");
	/* small change it's already added */
	for (i=0; i<nr_properties; i++) {
		if (strcmp(properties[i], name) == 0) {
			MT_lock_unset(&mal_contextLock, "propertyIndex");
			return i;
		}
	}
	if (i >= max_properties) {
		max_properties += 256;
		properties = GDKrealloc(properties, max_properties * sizeof(str));
		if( properties == NULL){
			GDKerror("PropertyIndex" MAL_MALLOC_FAIL);
			MT_lock_unset(&mal_contextLock, "propertyIndex");
			return nr_properties;
		}
	}
	properties[nr_properties] = GDKstrdup(name);
	MT_lock_unset(&mal_contextLock, "propertyIndex");
	return nr_properties++;
}
示例#7
0
/* Remote execution of MAL calls for more type/property information to be exchanged */
str
mal2str(MalBlkPtr mb, int first, int last)
{
	str ps = NULL, *txt;
	int i, *len, totlen = 0;

	txt = GDKmalloc(sizeof(str) * mb->stop);
	len = GDKmalloc(sizeof(int) * mb->stop);

	if( txt == NULL || len == NULL){
		GDKerror("mal2str: " MAL_MALLOC_FAIL);
		if( txt ) GDKfree(txt);
		if( len ) GDKfree(len);
		return NULL;
	}
	for (i = first; i < last; i++) {
		if( i == 0)
			txt[i] = instruction2str(mb, 0, getInstrPtr(mb, i), LIST_MAL_NAME | LIST_MAL_TYPE  | LIST_MAL_PROPS);
		else
			txt[i] = instruction2str(mb, 0, getInstrPtr(mb, i), LIST_MAL_CALL | LIST_MAL_PROPS | LIST_MAL_REMOTE);
#ifdef _DEBUG_LISTING_
		mnstr_printf(GDKout,"%s\n",txt[i]);
#endif

		if ( txt[i])
			totlen += len[i] = (int)strlen(txt[i]);
	}
	ps = GDKmalloc(totlen + mb->stop + 1);
	if( ps == NULL)
		GDKerror("mal2str: " MAL_MALLOC_FAIL);

	totlen = 0;
	for (i = first; i < last; i++) {
		if( txt[i]){
			if( ps){
				strncpy(ps + totlen, txt[i], len[i]);
				ps[totlen + len[i]] = '\n';
				ps[totlen + len[i] + 1] = 0;
				totlen += len[i] + 1;
			}
			GDKfree(txt[i]);
		}
	}
	GDKfree(len);
	GDKfree(txt);
	return ps;
}
示例#8
0
ptr
GDKreallocmax(void *blk, size_t size, size_t *maxsize, int emergency)
{
	void *oldblk = blk;
	ssize_t oldsize = 0;
	size_t newsize;

	if (blk == NULL) {
		return GDKmallocmax(size, maxsize, emergency);
	}
	if (size == 0) {
#ifdef GDK_MEM_NULLALLOWED
		GDKfree_(blk);
		*maxsize = 0;
		return NULL;
#else
		GDKfatal("GDKreallocmax: called with size 0");
#endif
	}
	size = (size + 7) & ~7;	/* round up to a multiple of eight */
	oldsize = GDK_MEM_BLKSIZE(blk);

	/* check against duplicate free */
	assert((oldsize & 2) == 0);

	newsize = size + MALLOC_EXTRA_SPACE;

	blk = realloc(((char *) blk) - MALLOC_EXTRA_SPACE,
		      newsize + GLIBC_BUG);
	if (blk == NULL) {
		GDKmemfail("GDKrealloc", newsize);
		blk = realloc(((char *) oldblk) - MALLOC_EXTRA_SPACE,
			      newsize);
		if (blk == NULL) {
			if (emergency == 0) {
				GDKerror("GDKreallocmax: failed for "
					 SZFMT " bytes", newsize);
				return NULL;
			}
			GDKfatal("GDKreallocmax: failed for "
				 SZFMT " bytes", newsize);
		} else {
			THRprintf(GDKstdout, "#GDKremallocmax: "
				  "recovery ok. Continuing..\n");
		}
	}
	/* place MALLOC_EXTRA_SPACE bytes before it */
	assert((((size_t) blk) & 4) == 0);
	blk = ((char *) blk) + MALLOC_EXTRA_SPACE;
	((ssize_t *) blk)[-1] = (ssize_t) newsize;

	/* adapt statistics */
	heapinc(newsize);
	heapdec(oldsize);
	*maxsize = size;
	return blk;
}
示例#9
0
ssize_t
ptrFromStr(const char *src, size_t *len, ptr **dst, bool external)
{
	size_t base = 0;
	const char *p = src;

	atommem(sizeof(ptr));

	**dst = ptr_nil;
	if (GDK_STRNIL(src))
		return 1;

	while (GDKisspace(*p))
		p++;
	if (external && strncmp(p, "nil", 3) == 0) {
		p += 3;
	} else {
		if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
			p += 2;
		}
		if (!num16(*p)) {
			GDKerror("not a number\n");
			return -1;
		}
		while (num16(*p)) {
			if (base >= ((size_t) 1 << (8 * sizeof(size_t) - 4))) {
				GDKerror("overflow\n");
				return -1;
			}
			base = mult16(base) + base16(*p);
			p++;
		}
		**dst = (ptr) base;
	}
	while (GDKisspace(*p))
		p++;
	return (ssize_t) (p - src);
}
示例#10
0
int
readConsole(Client cntxt)
{
	/* execute from stdin */
	struct stat statb;
	char *buf;

	if (cntxt->promptlength == 0 ||
	   !(fstat(fileno(stdin), &statb) == 0 && S_ISCHR(statb.st_mode))  )
		return -1;

	/* read lines and move string to client buffer. */
#ifdef HAVE_LIBREADLINE
	if( initReadline ==0){
		init_readline();
		using_history();
		stifle_history(1000);
		initReadline =1 ;
	}
#endif
	buf= getConsoleInput(cntxt, cntxt->prompt, 0, 1);
	if( buf) {
		size_t len= strlen(buf);
		if( len >= cntxt->fdin->size) {
			/* extremly dirty inplace buffer overwriting */
			cntxt->fdin->buf= realloc(cntxt->fdin->buf, len+1);
			if( cntxt->fdin->buf == NULL) {
				GDKerror("readConsole: " MAL_MALLOC_FAIL);
				free(buf);
				goto bailout;
			}
			cntxt->fdin->size = len;
		}
		strcpy(cntxt->fdin->buf, buf);
		cntxt->fdin->pos = 0;
		cntxt->fdin->len = len;
		free(buf);
		return 1;
	}
  bailout:
	cntxt->fdin->eof = 1;
#ifdef HAVE_LIBREADLINE
	if( initReadline ){
		deinit_readline();
		initReadline= 0;
	}
#endif
	return -1;
}
示例#11
0
/*
 * String conversion routines.
 */
ssize_t
OIDfromStr(const char *src, size_t *len, oid **dst, bool external)
{
#if SIZEOF_OID == SIZEOF_INT
	int ui = 0, *uip = &ui;
#else
	lng ui = 0, *uip = &ui;
#endif
	size_t l = sizeof(ui);
	ssize_t pos = 0;
	const char *p = src;

	atommem(sizeof(oid));

	**dst = oid_nil;
	if (GDK_STRNIL(src))
		return 1;

	while (GDKisspace(*p))
		p++;

	if (external && strncmp(p, "nil", 3) == 0)
		return (ssize_t) (p - src) + 3;

	if (GDKisdigit(*p)) {
#if SIZEOF_OID == SIZEOF_INT
		pos = intFromStr(p, &l, &uip, external);
#else
		pos = lngFromStr(p, &l, &uip, external);
#endif
		if (pos < 0)
			return pos;
		if (p[pos] == '@') {
			pos++;
			while (GDKisdigit(p[pos]))
				pos++;
		}
		if (ui >= 0) {
			**dst = ui;
		}
		p += pos;
	} else {
		GDKerror("not an OID\n");
		return -1;
	}
	while (GDKisspace(*p))
		p++;
	return (ssize_t) (p - src);
}
示例#12
0
/*
 * Really really get the lock. Now!!
 */
static int
GDKgetHome(void)
{
	if (MT_pagesize() == 0 || GDKlockFile)
		return 0;
	while ((GDKlockFile = fopen(GDKLOCK, "r+")) == NULL) {
		GDKerror("GDKgetHome: PANIC on open %s. sleep(1)\n", GDKLOCK);
		MT_sleep_ms(1000);
	}
	if (MT_lockf(GDKLOCK, F_TLOCK, 4, 1) < 0) {
		IODEBUG THRprintf(GDKstdout, "#GDKgetHome: blocking on lock '%s'.\n", GDKLOCK);
		MT_lockf(GDKLOCK, F_LOCK, 4, 1);
	}
	return 1;
}
示例#13
0
ssize_t
dblFromStr(const char *src, size_t *len, dbl **dst, bool external)
{
	const char *p = src;
	ssize_t n = 0;
	double d;

	/* alloc memory */
	atommem(sizeof(dbl));

	if (GDK_STRNIL(src)) {
		**dst = dbl_nil;
		return 1;
	}

	while (GDKisspace(*p))
		p++;
	if (external && strncmp(p, "nil", 3) == 0) {
		**dst = dbl_nil;
		p += 3;
		n = (ssize_t) (p - src);
	} else {
		/* on overflow, strtod returns HUGE_VAL and sets
		 * errno to ERANGE; on underflow, it returns a value
		 * whose magnitude is no greater than the smallest
		 * normalized double, and may or may not set errno to
		 * ERANGE.  We accept underflow, but not overflow. */
		char *pe;
		errno = 0;
		d = strtod(p, &pe);
		if (p == pe)
			p = src; /* nothing converted */
		else
			p = pe;
		n = (ssize_t) (p - src);
		if (n == 0 || (errno == ERANGE && (d < -1 || d > 1))
		    || !isfinite(d) /* no NaN or Infinte */
		    ) {
			GDKerror("overflow or not a number\n");
			return -1;
		} else {
			while (src[n] && GDKisspace(src[n]))
				n++;
			**dst = (dbl) d;
		}
	}
	return n;
}
示例#14
0
static int
dec_tostr(void *extra, char **Buf, int *len, int type, ptr a)
{
	/* support dec map to bte, sht, int and lng */
	if (type == TYPE_bte) {
		DEC_TOSTR(bte);
	} else if (type == TYPE_sht) {
		DEC_TOSTR(sht);
	} else if (type == TYPE_int) {
		DEC_TOSTR(int);
	} else if (type == TYPE_lng) {
		DEC_TOSTR(lng);
	} else {
		GDKerror("Decimal cannot be mapped to %s\n", ATOMname(type));
	}
	return 0;
}
示例#15
0
void
printSignature(stream *fd, Symbol s, int flg)
{
	InstrPtr p;
	str txt;

	if ( s->def == 0 ){
		mnstr_printf(fd, "missing definition of %s\n", s->name);
		return;
	}
	txt = GDKzalloc(MAXLISTING); /* some slack for large blocks */
	if( txt){
		p = getSignature(s);
		(void) fcnDefinition(s->def, p, txt, flg, txt, MAXLISTING);
		mnstr_printf(fd, "%s\n", txt);
		GDKfree(txt);
	} else GDKerror("printSignature"MAL_MALLOC_FAIL);
}
示例#16
0
ValPtr
VALinit(ValPtr d, int tpe, const void *s)
{
	if (ATOMextern(tpe) == 0) {
		d->vtype = tpe;
		memcpy(&d->val.ival, s, ATOMlen(tpe, s));
	} else if (s == 0) {
		GDKerror("VALinit:unsupported init\n");
		d->vtype = TYPE_int;
	} else if (tpe >= TYPE_str && ATOMstorage(tpe) == TYPE_str) {
		d->vtype = TYPE_str;
		d->val.sval = GDKstrdup(s);
		d->len = strLen(s);
	} else {
		d->vtype = tpe;
		d->len = ATOMlen(tpe, s);
		d->val.pval = GDKmalloc(d->len);
		memcpy(d->val.pval, s, d->len);
	}
	return d;
}
示例#17
0
/*
 * The remainder are utilities to manipulate the BAT view and not to
 * forget some details in the process.  It expects a position range in
 * the underlying BAT and compensates for outliers.
 */
void
VIEWbounds(BAT *b, BAT *view, BUN l, BUN h)
{
	BUN cnt;
	BATiter bi = bat_iterator(b);

	if (b == NULL || view == NULL) {
		GDKerror("VIEWbounds: bat argument missing");
		return;
	}
	if (h > BATcount(b))
		h = BATcount(b);
	if (h < l)
		h = l;
	l += BUNfirst(b);
	view->batFirst = view->batDeleted = view->batInserted = 0;
	cnt = h - l;
	view->H->heap.base = (view->htype) ? BUNhloc(bi, l) : NULL;
	view->T->heap.base = (view->ttype) ? BUNtloc(bi, l) : NULL;
	view->H->heap.size = headsize(view, cnt);
	view->T->heap.size = tailsize(view, cnt);
	BATsetcount(view, cnt);
	BATsetcapacity(view, cnt);
}
示例#18
0
static ssize_t
numFromStr(const char *src, size_t *len, void **dst, int tp, bool external)
{
	const char *p = src;
	size_t sz = ATOMsize(tp);
#ifdef HAVE_HGE
	hge base = 0;
#else
	lng base = 0;
#endif
	int sign = 1;

	/* a valid number has the following syntax:
	 * [-+]?[0-9]+([eE][0-9]+)?(LL)? -- PCRE syntax, or in other words
	 * optional sign, one or more digits, optional exponent, optional LL
	 * the exponent has the following syntax:
	 * lower or upper case letter E, one or more digits
	 * embedded spaces are not allowed
	 * the optional LL at the end are only allowed for lng and hge
	 * values */
	atommem(sz);

	if (GDK_STRNIL(src)) {
		memcpy(*dst, ATOMnilptr(tp), sz);
		return 1;
	}

	while (GDKisspace(*p))
		p++;
	if (!num10(*p)) {
		switch (*p) {
		case 'n':
			if (external) {
				memcpy(*dst, ATOMnilptr(tp), sz);
				if (p[1] == 'i' && p[2] == 'l') {
					p += 3;
					return (ssize_t) (p - src);
				}
			}
			GDKerror("not a number");
			goto bailout;
		case '-':
			sign = -1;
			p++;
			break;
		case '+':
			p++;
			break;
		}
		if (!num10(*p)) {
			GDKerror("not a number");
			goto bailout;
		}
	}
	do {
		int dig = base10(*p);
		if (base > maxdiv[1].maxval ||
		    (base == maxdiv[1].maxval && dig > maxmod10)) {
			/* overflow */
			goto overflow;
		}
		base = 10 * base + dig;
		p++;
	} while (num10(*p));
	if ((*p == 'e' || *p == 'E') && num10(p[1])) {
		p++;
		if (base == 0) {
			/* if base is 0, any exponent will do, the
			 * result is still 0 */
			while (num10(*p))
				p++;
		} else {
			int exp = 0;
			do {
				/* this calculation cannot overflow */
				exp = exp * 10 + base10(*p);
				if (exp >= (int) (sizeof(maxdiv) / sizeof(maxdiv[0]))) {
					/* overflow */
					goto overflow;
				}
				p++;
			} while (num10(*p));
			if (base > maxdiv[exp].maxval) {
				/* overflow */
				goto overflow;
			}
			base *= maxdiv[exp].scale;
		}
	}
	base *= sign;
	switch (sz) {
	case 1: {
		bte **dstbte = (bte **) dst;
		if (base < GDK_bte_min || base > GDK_bte_max) {
			goto overflow;
		}
		**dstbte = (bte) base;
		break;
	}
	case 2: {
		sht **dstsht = (sht **) dst;
		if (base < GDK_sht_min || base > GDK_sht_max) {
			goto overflow;
		}
		**dstsht = (sht) base;
		break;
	}
	case 4: {
		int **dstint = (int **) dst;
		if (base < GDK_int_min || base > GDK_int_max) {
			goto overflow;
		}
		**dstint = (int) base;
		break;
	}
	case 8: {
		lng **dstlng = (lng **) dst;
#ifdef HAVE_HGE
		if (base < GDK_lng_min || base > GDK_lng_max) {
			goto overflow;
		}
#endif
		**dstlng = (lng) base;
		if (p[0] == 'L' && p[1] == 'L')
			p += 2;
		break;
	}
#ifdef HAVE_HGE
	case 16: {
		hge **dsthge = (hge **) dst;
		**dsthge = (hge) base;
		if (p[0] == 'L' && p[1] == 'L')
			p += 2;
		break;
	}
#endif
	}
	while (GDKisspace(*p))
		p++;
	return (ssize_t) (p - src);

  overflow:
	while (num10(*p))
		p++;
	GDKerror("overflow: \"%.*s\" does not fit in %s\n",
		 (int) (p - src), src, ATOMname(tp));
  bailout:
	memcpy(*dst, ATOMnilptr(tp), sz);
	return -1;
}
示例#19
0
static str
renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg)
{
	char *buf =0;
	char *nme =0;
	int nameused= 0;
	size_t len = 0, maxlen = BUFSIZ;
	ValRecord *val = 0;
	char *cv =0;
	str tpe;
	int showtype = 0, closequote=0;
	int varid = getArg(p,idx);

	buf = GDKzalloc(maxlen);
	// show the name when required or is used
	if ((flg & LIST_MAL_NAME) && !isVarConstant(mb,varid) && !isVarTypedef(mb,varid)) {
		nme = getVarName(mb,varid);
		len +=snprintf(buf, maxlen, "%s", nme);
		nameused =1;
	} 
	// show the value when required or being a constant
	if( ((flg & LIST_MAL_VALUE) && stk != 0) || isVarConstant(mb,varid) ){
		if (nameused){
			strcat(buf + len,"=");
			len++;
		}

		// locate value record
		if (isVarConstant(mb,varid))
			val = &getVarConstant(mb, varid);
		else if( stk)
			val = &stk->stk[varid];

		VALformat(&cv, val);
		if (len + strlen(cv) >= maxlen)
			buf= GDKrealloc(buf, maxlen =len + strlen(cv) + BUFSIZ);

		if( buf == 0){
			GDKerror("renderTerm:Failed to allocate");
			return 0;
		}
		if( strcmp(cv,"nil") == 0){
			strcat(buf+len,cv);
			len += strlen(buf+len);
			if( cv) GDKfree(cv);
			showtype =getColumnType(getVarType(mb,varid)) > TYPE_str || 
				((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid)) && isVarConstant(mb,varid)) || isaBatType(getVarType(mb,varid)); 
		} else{
			if ( !isaBatType(getVarType(mb,varid)) && getColumnType(getVarType(mb,varid)) > TYPE_str ){
				closequote = 1;
				strcat(buf+len,"\"");
				len++;
			}
			strcat(buf+len,cv);
			len += strlen(buf+len);
			if( cv) GDKfree(cv);

			if( closequote ){
				strcat(buf+len,"\"");
				len++;
			}
			showtype =closequote > TYPE_str || ((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid) || (flg & LIST_MAL_REMOTE)) && isVarConstant(mb,varid)) ||
				(isaBatType(getVarType(mb,varid)) && idx < p->retc);

			if (stk && isaBatType(getVarType(mb,varid)) && abs(stk->stk[varid].val.ival) ){
				BAT *d= BBPquickdesc(abs(stk->stk[varid].val.ival),TRUE);
				if( d)
					len += snprintf(buf+len,maxlen-len,"[" BUNFMT "]", BATcount(d));
			}
		}
	}

	// show the type when required or frozen by the user
	// special care should be taken with constants, they may have been casted
	if ((flg & LIST_MAL_TYPE) || (isVarUDFtype(mb, varid) && idx < p->retc) || isVarTypedef(mb,varid) || showtype){
		strcat(buf + len,":");
		len++;
		tpe = getTypeName(getVarType(mb, varid));
		len += snprintf(buf+len,maxlen-len,"%s",tpe);
		GDKfree(tpe);
	}

	if( len >= maxlen)
		GDKerror("renderTerm:Value representation too large");
	return buf;
}
示例#20
0
char *
getConsoleInput(Client c, const char *prompt, int linemode, int exit_on_error)
{
	char *line = NULL;
	char *buf = NULL;
	size_t length;
	(void) exit_on_error;
	(void) linemode;

	do {
#ifdef HAVE_LIBREADLINE
		if (prompt) {

			if (buf)
				free(buf);
			buf = readline(prompt);
			/* add a newline to the end since that makes
			   further processing easier */
			if (buf) {
				add_history(buf);
				length = strlen(buf);
				buf = realloc(buf, length + 2);
				if( buf == NULL){
					GDKerror("getConsoleInput: " MAL_MALLOC_FAIL);
					return NULL;
				}
				buf[length++] = '\n';
				buf[length] = 0;
			}
			line = buf;
		} else
#endif
		{
#ifndef HAVE_LIBREADLINE
			if (prompt) {
				fputs(prompt, stdout);
				fflush(stdout);
			}
#endif
			if (buf == NULL) {
				buf= malloc(BUFSIZ);
				if( buf == NULL){
					GDKerror("getConsoleInput: " MAL_MALLOC_FAIL);
					return NULL;
				}
			}
			line = fgets(buf, BUFSIZ, stdin);
		}

		if (line == NULL) {
			/* end of file */
			if (buf)
				free(buf);
			return NULL;
		} else
			length = strlen(line);

		if (length > 0 ) {
			/* test for special commands */
			while (length > 0 &&
			       (*line & ~0x7F) == 0 &&
			       isspace((int) *line)) {
				line++;
				length--;
			}
			/* in the switch, use continue if the line was
			   processed, use break to send to parser */
			switch (*line) {
			case '\0':
				/* empty line */
				break;
			case '\\':
				switch (line[1]) {
				case 'q':
					free(buf);
					return NULL;
				default:
					break;
				}
				line= NULL;
				break;
			case '<':
				/* read commands from file */
				if (line[length - 1] == '\n')
					line[--length] = 0;
				if (line[length - 1] == '\r')
					line[--length] = 0;
				/* doFile(mid, line + 1, 0);*/
				line= NULL;
				continue;
			case '>':
				/* redirect output to file */
				line++;
				length--;
				if (line[length - 1] == '\n')
					line[--length] = 0;
				if (line[length - 1] == '\r')
					line[--length] = 0;

				if (c->fdout && c->fdout != GDKout && c->fdout != GDKerr){
					close_stream(c->fdout);
					c->fdout= 0;
				}
				if (length == 0 || strcmp(line, "stdout") == 0)
					c->fdout = GDKout;
				else if (strcmp(line, "stderr") == 0)
					c->fdout = GDKerr;
				else if ((c->fdout = open_wastream(line)) == NULL) {
					c->fdout = GDKout;
					mnstr_printf(GDKerr, "Cannot open %s\n", line);
				}
				line = NULL;
				continue;
#ifdef HAVE_LIBREADLINE
			case '!':
				{ char *nl;
				  int i;
					if(line[1]=='\n') {
						for(i=0; i< history_length; i++){
							nl= history_get(i)? history_get(i)->line:0;
							if( nl)
							mnstr_printf(c->fdout, "%d %s\n", i, nl);
						}
						line = NULL;
					} else
					if( history_expand(line,&nl) ==1  ) {
						mnstr_printf(c->fdout,"#%s",nl);
						line= nl;
					} else line= NULL;
				}
				continue;
#endif
			case '?':
				if( line[1] && line[1]!='\n'){
					showHelp( c->nspace,line+1, c->fdout);
				} else
					showCommands();
				line= NULL;
				continue;
			}
			/* make sure we return a pointer that can (and should) be freed by the caller */
			if (line)
				line = buf;
		}
	} while (line == NULL);
	return line;
}
示例#21
0
/* BATsample implements sampling for void headed BATs */
BAT *
BATsample(BAT *b, BUN n)
{
	BAT *bn;
	BUN cnt, slen;
	BUN rescnt;
	struct oidtreenode *tree = NULL;

	BATcheck(b, "BATsample", NULL);
	assert(BAThdense(b));
	ERRORcheck(n > BUN_MAX, "BATsample: sample size larger than BUN_MAX\n", NULL);
	ALGODEBUG
		fprintf(stderr, "#BATsample: sample " BUNFMT " elements.\n", n);

	cnt = BATcount(b);
	/* empty sample size */
	if (n == 0) {
		bn = BATnew(TYPE_void, TYPE_void, 0, TRANSIENT);
		if (bn == NULL) {
			GDKerror("BATsample: memory allocation error");
			return NULL;
		}
		BATsetcount(bn, 0);
		BATseqbase(bn, 0);
		BATseqbase(BATmirror(bn), 0);
	/* sample size is larger than the input BAT, return all oids */
	} else if (cnt <= n) {
		bn = BATnew(TYPE_void, TYPE_void, cnt, TRANSIENT);
		if (bn == NULL) {
			GDKerror("BATsample: memory allocation error");
			return NULL;
		}
		BATsetcount(bn, cnt);
		BATseqbase(bn, 0);
		BATseqbase(BATmirror(bn), b->H->seq);
	} else {
		oid minoid = b->hseqbase;
		oid maxoid = b->hseqbase + cnt;
		/* if someone samples more than half of our tree, we
		 * do the antiset */
		bit antiset = n > cnt / 2;
		slen = n;
		if (antiset)
			n = cnt - n;

		tree = GDKmalloc(n * sizeof(struct oidtreenode));
		if (tree == NULL) {
			GDKerror("#BATsample: memory allocation error");
			return NULL;
		}
		bn = BATnew(TYPE_void, TYPE_oid, slen, TRANSIENT);
		if (bn == NULL) {
			GDKfree(tree);
			GDKerror("#BATsample: memory allocation error");
			return NULL;
		}
		/* while we do not have enough sample OIDs yet */
		for (rescnt = 0; rescnt < n; rescnt++) {
			oid candoid;
			do {
				/* generate a new random OID */
				candoid = (oid) (minoid + DRAND * (maxoid - minoid));
				/* if that candidate OID was already
				 * generated, try again */
			} while (!OIDTreeMaybeInsert(tree, candoid, rescnt));
		}
		if (!antiset) {
			OIDTreeToBAT(tree, bn);
		} else {
			OIDTreeToBATAntiset(tree, bn, minoid, maxoid);
		}
		GDKfree(tree);

		BATsetcount(bn, slen);
		bn->trevsorted = bn->batCount <= 1;
		bn->tsorted = 1;
		bn->tkey = 1;
		bn->tdense = bn->batCount <= 1;
		if (bn->batCount == 1)
			bn->tseqbase = *(oid *) Tloc(bn, BUNfirst(bn));
		bn->hdense = 1;
		bn->hseqbase = 0;
		bn->hkey = 1;
		bn->hrevsorted = bn->batCount <= 1;
		bn->hsorted = 1;
	}
	return bn;
}
示例#22
0
static BAT *
ALGjoinPathBody(Client cntxt, int top, BAT **joins, int flag)
{
	BAT *b = NULL;
	BUN estimate, e = 0;
	int i, j, k;
	int *postpone= (int*) GDKzalloc(sizeof(int) *top);
	int postponed=0;

	if(postpone == NULL){
		GDKerror("joinPathBody" MAL_MALLOC_FAIL);
		return NULL;
	}


	/* solve the join by pairing the smallest first */
	while (top > 1) {
		j = 0;
		estimate = ALGjoinCost(cntxt,joins[0],joins[1],flag);
		ALGODEBUG
			fprintf(stderr,"#joinPath estimate join(%d,%d) %d cnt="BUNFMT" %s\n", joins[0]->batCacheid, 
				joins[1]->batCacheid,(int)estimate, BATcount(joins[0]), postpone[0]?"postpone":"");
		for (i = 1; i < top - 1; i++) {
			e = ALGjoinCost(cntxt,joins[i], joins[i + 1],flag);
			ALGODEBUG
				fprintf(stderr,"#joinPath estimate join(%d,%d) %d cnt="BUNFMT" %s\n", joins[i]->batCacheid, 
					joins[i+1]->batCacheid,(int)e,BATcount(joins[i]),  postpone[i]?"postpone":"");
			if (e < estimate &&  ( !(postpone[i] && postpone[i+1]) || postponed<top)) {
				estimate = e;
				j = i;
			}
		}
		/*
		 * BEWARE. you may not use a size estimation, because it
		 * may fire a BATproperty check in a few cases.
		 * In case a join fails, we may try another order first before
		 * abandoning the task. It can handle cases where a Cartesian product emerges.
		 *
		 * A left-join sequence only requires the result to be sorted
		 * against the first operand. For all others operand pairs, the cheapest join suffice.
		 */

		switch(flag){
		case 0:
			if ( j == 0) {
				b = BATleftjoin(joins[j], joins[j + 1], BATcount(joins[j]));
				ALGODEBUG{
					fprintf(stderr,"#joinpath step produces "BUNFMT"\n", BATcount(b));
				}
				break;
			}
		case 1:
			b = BATjoin(joins[j], joins[j + 1], (BATcount(joins[j]) < BATcount(joins[j + 1])? BATcount(joins[j]):BATcount(joins[ j + 1])));
			break;
		case 3:
			b = BATproject(joins[j], joins[j + 1]);
			ALGODEBUG{
				fprintf(stderr,"#joinpath step produces "BUNFMT"\n", BATcount(b));
			}
			break;
		}
		if (b==NULL){
			if ( postpone[j] && postpone[j+1]){
				for( --top; top>=0; top--)
					BBPunfix(joins[top]->batCacheid);
				GDKfree(postpone);
				return NULL;
			}
			postpone[j] = TRUE;
			postpone[j+1] = TRUE;
			postponed = 0;
			for( k=0; k<top; k++)
				postponed += postpone[k]== TRUE;
			if ( postponed == top){
				for( --top; top>=0; top--)
					BBPunfix(joins[top]->batCacheid);
				GDKfree(postpone);
				return NULL;
			}
			/* clear the GDKerrors and retry */
			if( cntxt->errbuf )
				cntxt->errbuf[0]=0;
			continue;
		} else {
			/* reset the postponed joins */
			for( k=0; k<top; k++)
				postpone[k]=FALSE;
			if (!(b->batDirty&2)) BATsetaccess(b, BAT_READ);
			postponed = 0;
		}
		ALGODEBUG{
			if (b ) {
				fprintf(stderr, "#joinPath %d:= join(%d,%d)"
				" arguments %d (cnt= "BUNFMT") against (cnt "BUNFMT") cost "BUNFMT"\n", 
					b->batCacheid, joins[j]->batCacheid, joins[j + 1]->batCacheid,
					j, BATcount(joins[j]),  BATcount(joins[j+1]), e);
			}
		}

		if ( b == 0 ){
			for( --top; top>=0; top--)
				BBPunfix(joins[top]->batCacheid);
			GDKfree(postpone);
			return 0;
		}
		BBPunfix(joins[j]->batCacheid);
		BBPunfix(joins[j+1]->batCacheid);
		joins[j] = b;
		top--;
		for (i = j + 1; i < top; i++)
			joins[i] = joins[i + 1];
	}