Esempio n. 1
0
//
//  Form_Int_Pad: C
//
// Form an integer string in the given buffer with a min
// width padded out with the given character. Len > 0 left
// aligned. Len < 0 is right aligned.
//
// If len = 0 and val = 0, a null string is formed.
// Make sure you have room in your buffer before calling this!
//
REBYTE *Form_Int_Pad(REBYTE *buf, REBI64 val, REBINT max, REBINT len, REBYTE pad)
{
    REBYTE tmp[MAX_NUM_LEN];
    REBINT n;

    n = Form_Int_Len(tmp, val, max + 1);
    if (n == 0) {
        strcpy(s_cast(buf), "??");
        return buf;  // too long
    }

    if (len >= 0) {
        strcpy(s_cast(buf), s_cast(tmp));
        buf += n;
        for (; n < len; n++) *buf++ = pad;
    }
    else { // len < 0
        for (; n < -len; len++) *buf++ = pad;
        strcpy(s_cast(buf), s_cast(tmp));
        buf += n;
    }

    *buf = 0;
    return buf;
}
Esempio n. 2
0
//
//  MF_Tuple: C
//
void MF_Tuple(REB_MOLD *mo, const REBCEL *v, bool form)
{
    UNUSED(form);

    // "Buffer must be large enough to hold longest tuple.
    //  Longest is: (3 digits + '.') * 11 nums + 1 term => 45"
    //
    // !!! ^-- Out of date comments; TUPLE! needs review and replacement.
    //
    REBYTE buf[60];

    REBCNT len = VAL_TUPLE_LEN(v);
    const REBYTE *tp = cast(const REBYTE *, VAL_TUPLE(v));

    REBYTE *out = buf;

    for (; len > 0; len--, tp++) {
        out = Form_Int(out, *tp);
        *out++ = '.';
    }

    len = VAL_TUPLE_LEN(v);
    while (len++ < 3) {
        *out++ = '0';
        *out++ = '.';
    }
    *--out = 0;

    Append_Ascii_Len(mo->series, s_cast(buf), out - buf);
}
Esempio n. 3
0
*/	DEVICE_CMD Read_DNS(REBREQ *sock)
/*
**		Initiate the GetHost request and return immediately.
**		Note the temporary results buffer (must be freed later).
**
***********************************************************************/
{
    char *host;
#ifdef HAS_ASYNC_DNS
	HANDLE handle;
#else
	HOSTENT *he;
#endif

	host = OS_ALLOC_ARRAY(char, MAXGETHOSTSTRUCT); // be sure to free it

#ifdef HAS_ASYNC_DNS
	if (!GET_FLAG(sock->modes, RST_REVERSE)) // hostname lookup
        handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, s_cast(sock->common.data), host, MAXGETHOSTSTRUCT);
	else
        handle = WSAAsyncGetHostByAddr(Event_Handle, WM_DNS, s_cast(&sock->special.net.remote_ip), 4, AF_INET, host, MAXGETHOSTSTRUCT);

	if (handle != 0) {
		sock->special.net.host_info = host;
		sock->requestee.handle = handle;
		return DR_PEND; // keep it on pending list
	}
#else
	// Use old-style blocking DNS (mainly for testing purposes):
	if (GET_FLAG(sock->modes, RST_REVERSE)) {
		he = gethostbyaddr(
			cast(char*, &sock->special.net.remote_ip), 4, AF_INET
		);
		if (he) {
			sock->special.net.host_info = host; //???
			sock->common.data = b_cast(he->h_name);
			SET_FLAG(sock->flags, RRF_DONE);
			return DR_DONE;
		}
	}
Esempio n. 4
0
//
//  Dump_Values: C
// 
// Print values in raw hex; If memory is corrupted this still needs to work.
//
void Dump_Values(RELVAL *vp, REBCNT count)
{
    REBYTE buf[2048];
    REBYTE *cp;
    REBCNT l, n;
    REBCNT *bp = (REBCNT*)vp;
    const REBYTE *type;

    cp = buf;
    for (l = 0; l < count; l++) {
        REBVAL *val = cast(REBVAL*, bp);
        cp = Form_Hex_Pad(cp, l, 8);

        *cp++ = ':';
        *cp++ = ' ';

        type = Get_Type_Name((REBVAL*)bp);
        for (n = 0; n < 11; n++) {
            if (*type) *cp++ = *type++;
            else *cp++ = ' ';
        }
        *cp++ = ' ';
        for (n = 0; n < sizeof(REBVAL) / sizeof(REBCNT); n++) {
            cp = Form_Hex_Pad(cp, *bp++, 8);
            *cp++ = ' ';
        }
        n = 0;
        if (IS_WORD(val) || IS_GET_WORD(val) || IS_SET_WORD(val)) {
            const REBYTE *name = STR_HEAD(VAL_WORD_SPELLING(val));
            n = snprintf(
                s_cast(cp), sizeof(buf) - (cp - buf), " (%s)", cs_cast(name)
            );
        }

        *(cp + n) = 0;
        Debug_Str(s_cast(buf));
        cp = buf;
    }
}
Esempio n. 5
0
*/	DEVICE_CMD Read_IO(REBREQ *req)
/*
**		Low level "raw" standard input function.
**
**		The request buffer must be long enough to hold result.
**
**		Result is NOT terminated (the actual field has length.)
**
***********************************************************************/
{
	long total = 0;
	int len = req->length;

	if (GET_FLAG(req->modes, RDM_NULL)) {
		req->common.data[0] = 0;
		return DR_DONE;
	}

	req->actual = 0;

	if (Std_Inp >= 0) {

		interrupted = 0;
		// Perform a processed read or a raw read?
#ifndef HAS_SMART_CONSOLE
		if (Term_IO)
			total = Read_Line(Term_IO, s_cast(req->common.data), len);
		else
#endif
			total = read(Std_Inp, req->common.data, len); /* will be restarted in case of signal */

		if (total < 0) {
			req->error = errno;
			return DR_ERROR;
		}
		if (interrupted) {
			char noop[] = "does[]\n";
			APPEND_BYTES_LIMIT(req->common.data, cb_cast(noop), len);
			total += sizeof(noop);
		}

		req->actual = total;
	}

	return DR_DONE;
}
Esempio n. 6
0
//
//  Dump_Bytes: C
//
void Dump_Bytes(REBYTE *bp, REBCNT limit)
{
    const REBCNT max_lines = 120;
    REBYTE buf[2048];
    REBYTE str[40];
    REBYTE *cp, *tp;
    REBYTE c;
    REBCNT l, n;
    REBCNT cnt = 0;

    cp = buf;
    for (l = 0; l < max_lines; l++) {
        cp = Form_Hex_Pad(cp, (REBUPT) bp, 8);

        *cp++ = ':';
        *cp++ = ' ';
        tp = str;

        for (n = 0; n < 16; n++) {
            if (cnt++ >= limit) break;
            c = *bp++;
            cp = Form_Hex2(cp, c);
            if ((n & 3) == 3) *cp++ = ' ';
            if ((c < 32) || (c > 126)) c = '.';
            *tp++ = c;
        }

        for (; n < 16; n++) {
            c = ' ';
            *cp++ = c;
            *cp++ = c;
            if ((n & 3) == 3) *cp++ = ' ';
            if ((c < 32) || (c > 126)) c = '.';
            *tp++ = c;
        }
        *tp++ = 0;

        for (tp = str; *tp;) *cp++ = *tp++;

        *cp = 0;
        Debug_Str(s_cast(buf));
        if (cnt >= limit) break;
        cp = buf;
    }
}
Esempio n. 7
0
File: d-print.c Progetto: mbk/ren-c
*/	void Debug_Series(const REBSER *ser)
/*
***********************************************************************/
{
	REBINT disabled = GC_Disabled;
	GC_Disabled = 1;

	// This routine is also a little catalog of the outlying series
	// types in terms of sizing, just to know what they are.

	if (BYTE_SIZE(ser))
		Debug_Str(s_cast(BIN_HEAD(ser)));
	else if (IS_BLOCK_SERIES(ser)) {
		REBVAL value;
		// May not actually be a REB_BLOCK, but we put it in a value
		// container for now saying it is so we can output it.  Because
		// it may be a frame or otherwise, we use a raw VAL_SET
		VAL_SET(&value, REB_BLOCK);
		VAL_SERIES(&value) = m_cast(REBSER *, ser); // not actually modifying
		VAL_INDEX(&value) = 0;
		Debug_Fmt("%r", &value);
	} else if (SERIES_WIDE(ser) == sizeof(REBUNI))
Esempio n. 8
0
//
//  Read_IO: C
//
// Low level "raw" standard input function.
//
// The request buffer must be long enough to hold result.
//
// Result is NOT terminated (the actual field has length.)
//
DEVICE_CMD Read_IO(REBREQ *req)
{
    long total = 0;
    int len = req->length;

    if (GET_FLAG(req->modes, RDM_NULL)) {
        req->common.data[0] = 0;
        return DR_DONE;
    }

    req->actual = 0;

    if (Std_Inp >= 0) {

        interrupted = 0;
        // Perform a processed read or a raw read?
#ifndef HAS_SMART_CONSOLE
        if (Term_IO)
            total = Read_Line(Term_IO, s_cast(req->common.data), len);
        else
#endif
            total = read(Std_Inp, req->common.data, len); /* will be restarted in case of signal */

        if (total < 0) {
            req->error = errno;
            return DR_ERROR;
        }
        if (interrupted) {
            char noop[] = "does[]\n";
            APPEND_BYTES_LIMIT(req->common.data, cb_cast(noop), len);
            total += sizeof(noop);
        }

        req->actual = total;
    }

    return DR_DONE;
}
Esempio n. 9
0
*/	void Debug_Series(const REBSER *ser)
/*
***********************************************************************/
{
	REBINT disabled = GC_Disabled;
	GC_Disabled = 1;

	// This routine is also a little catalog of the outlying series
	// types in terms of sizing, just to know what they are.

	if (BYTE_SIZE(ser))
		Debug_Str(s_cast(BIN_HEAD(ser)));
	else if (Is_Array_Series(ser)) {
		REBVAL value;
		// May not actually be a REB_BLOCK, but we put it in a value
		// container for now saying it is so we can output it.  It may be
		// a frame and we may not want to Manage_Series here, so we use a
		// raw VAL_SET instead of Val_Init_Block
		VAL_SET(&value, REB_BLOCK);
		VAL_SERIES(&value) = m_cast(REBSER *, ser); // not actually modifying
		VAL_INDEX(&value) = 0;
		Debug_Fmt("%r", &value);
	} else if (SERIES_WIDE(ser) == sizeof(REBUNI))
Esempio n. 10
0
/* parse struct attribute */
static void parse_attr (REBVAL *blk, REBINT *raw_size, REBUPT *raw_addr)
{
	REBVAL *attr = VAL_BLK_DATA(blk);

	*raw_size = -1;
	*raw_addr = 0;

	while (NOT_END(attr)) {
		if (IS_SET_WORD(attr)) {
			switch (VAL_WORD_CANON(attr)) {
				case SYM_RAW_SIZE:
					++ attr;
					if (IS_INTEGER(attr)) {
						if (*raw_size > 0) /* duplicate raw-size */
							raise Error_Invalid_Arg(attr);

						*raw_size = VAL_INT64(attr);
						if (*raw_size <= 0)
							raise Error_Invalid_Arg(attr);
					}
					else
						raise Error_Invalid_Arg(attr);
					break;

				case SYM_RAW_MEMORY:
					++ attr;
					if (IS_INTEGER(attr)) {
						if (*raw_addr != 0) /* duplicate raw-memory */
							raise Error_Invalid_Arg(attr);

						*raw_addr = VAL_UNT64(attr);
						if (*raw_addr == 0)
							raise Error_Invalid_Arg(attr);
					}
					else
						raise Error_Invalid_Arg(attr);
					break;

				case SYM_EXTERN:
					++ attr;

					if (*raw_addr != 0) /* raw-memory is exclusive with extern */
						raise Error_Invalid_Arg(attr);

					if (!IS_BLOCK(attr)
						|| VAL_LEN(attr) != 2) {
						raise Error_Invalid_Arg(attr);
					}
					else {
						REBVAL *lib;
						REBVAL *sym;
						CFUNC *addr;

						lib = VAL_BLK_SKIP(attr, 0);
						sym = VAL_BLK_SKIP(attr, 1);

						if (!IS_LIBRARY(lib))
							raise Error_Invalid_Arg(attr);
						if (IS_CLOSED_LIB(VAL_LIB_HANDLE(lib)))
							raise Error_0(RE_BAD_LIBRARY);
						if (!ANY_BINSTR(sym))
							raise Error_Invalid_Arg(sym);

						addr = OS_FIND_FUNCTION(
							LIB_FD(VAL_LIB_HANDLE(lib)), s_cast(VAL_DATA(sym))
						);
						if (!addr)
							raise Error_1(RE_SYMBOL_NOT_FOUND, sym);

						*raw_addr = cast(REBUPT, addr);
					}
					break;

					/*
					   case SYM_ALIGNMENT:
					   ++ attr;
					   if (IS_INTEGER(attr)) {
					   alignment = VAL_INT64(attr);
					   } else {
					   raise Error_Invalid_Arg(attr);
					   }
					   break;
					   */
				default:
					raise Error_Invalid_Arg(attr);
			}
		}
		else
			raise Error_Invalid_Arg(attr);

		++ attr;
	}
}
Esempio n. 11
0
File: t-date.c Progetto: mbk/ren-c
*/	void Emit_Date(REB_MOLD *mold, const REBVAL *value_orig)
/*
***********************************************************************/
{
	REBYTE buf[64];
	REBYTE *bp = &buf[0];
	REBINT tz;
	REBYTE dash = GET_MOPT(mold, MOPT_SLASH_DATE) ? '/' : '-';

	// We don't want to modify the incoming date value we are molding,
	// so we make a copy that we can tweak during the emit process

	REBVAL value_buffer = *value_orig;
	REBVAL *value = &value_buffer;

	if (
		VAL_MONTH(value) == 0
		|| VAL_MONTH(value) > 12
		|| VAL_DAY(value) == 0
		|| VAL_DAY(value) > 31
	) {
		Append_Unencoded(mold->series, "?date?");
		return;
	}

	if (VAL_TIME(value) != NO_TIME) Adjust_Date_Zone(value, FALSE);

//	Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT]

	bp = Form_Int(bp, (REBINT)VAL_DAY(value));
	*bp++ = dash;
	memcpy(bp, Month_Names[VAL_MONTH(value)-1], 3);
	bp += 3;
	*bp++ = dash;
	bp = Form_Int_Pad(bp, (REBINT)VAL_YEAR(value), 6, -4, '0');
	*bp = 0;

	Append_Unencoded(mold->series, s_cast(buf));

	if (VAL_TIME(value) != NO_TIME) {

		Append_Byte(mold->series, '/');
		Emit_Time(mold, value);

		if (VAL_ZONE(value) != 0) {

			bp = &buf[0];
			tz = VAL_ZONE(value);
			if (tz < 0) {
				*bp++ = '-';
				tz = -tz;
			}
			else
				*bp++ = '+';

			bp = Form_Int(bp, tz/4);
			*bp++ = ':';
			bp = Form_Int_Pad(bp, (tz&3) * 15, 2, 2, '0');
			*bp = 0;

			Append_Unencoded(mold->series, s_cast(buf));
		}
	}
}
Esempio n. 12
0
//
//  Call_Core: C
//
// flags:
//     1: wait, is implied when I/O redirection is enabled
//     2: console
//     4: shell
//     8: info
//     16: show
//
// Return -1 on error, otherwise the process return code.
//
// POSIX previous simple version was just 'return system(call);'
// This uses 'execvp' which is "POSIX.1 conforming, UNIX compatible"
//
REB_R Call_Core(REBFRM *frame_) {
    PROCESS_INCLUDE_PARAMS_OF_CALL_INTERNAL_P;

    UNUSED(REF(console));  // !!! actually not paid attention to, why?

    // SECURE was never actually done for R3-Alpha
    //
    Check_Security(Canon(SYM_CALL), POL_EXEC, ARG(command));

    // Make sure that if the output or error series are STRING! or BINARY!,
    // they are not read-only, before we try appending to them.
    //
    if (IS_TEXT(ARG(output)) or IS_BINARY(ARG(output)))
        FAIL_IF_READ_ONLY(ARG(output));
    if (IS_TEXT(ARG(error)) or IS_BINARY(ARG(error)))
        FAIL_IF_READ_ONLY(ARG(error));

    char *inbuf;
    size_t inbuf_size;

    if (not REF(input)) {
      null_input_buffer:
        inbuf = nullptr;
        inbuf_size = 0;
    }
    else switch (VAL_TYPE(ARG(input))) {
      case REB_LOGIC:
        goto null_input_buffer;

      case REB_TEXT: {
        inbuf_size = rebSpellIntoQ(nullptr, 0, ARG(input), rebEND);
        inbuf = rebAllocN(char, inbuf_size);
        size_t check;
        check = rebSpellIntoQ(inbuf, inbuf_size, ARG(input), rebEND);
        UNUSED(check);
        break; }

      case REB_FILE: {
        size_t size;
        inbuf = s_cast(rebBytes(  // !!! why fileNAME size passed in???
            &size,
            "file-to-local", ARG(input),
            rebEND
        ));
        inbuf_size = size;
        break; }

      case REB_BINARY: {
        inbuf = s_cast(rebBytes(&inbuf_size, ARG(input), rebEND));
        break; }

      default:
        panic (ARG(input));  // typechecking should not have allowed it
    }

    bool flag_wait;
    if (
        REF(wait)
        or (
            IS_TEXT(ARG(input)) or IS_BINARY(ARG(input))
            or IS_TEXT(ARG(output)) or IS_BINARY(ARG(output))
            or IS_TEXT(ARG(error)) or IS_BINARY(ARG(error))
        ) // I/O redirection implies /WAIT
    ){
        flag_wait = true;
    }
    else
        flag_wait = false;

    // We synthesize the argc and argv from the "command", and in the process
    // we do dynamic allocations of argc strings through the API.  These need
    // to be freed before we return.
    //
    char *cmd;
    int argc;
    const char **argv;

    if (IS_TEXT(ARG(command))) {
        //
        // !!! POSIX does not offer the ability to take a single command
        // line string when invoking a process.  You have to use an argv[]
        // array.  The only workaround to this is to run through a shell--
        // but that would give you a new environment.  We only parse the
        // command line if forced (Windows can call with a single command
        // line, but has the reverse problem: it has to make the command
        // line out of argv[] parts if you pass an array).
        //
        if (not REF(shell)) {
            REBVAL *block = rebValue(
                "parse-command-to-argv*", ARG(command), rebEND
            );
            Move_Value(ARG(command), block);
            rebRelease(block);
            goto block_command;
        }

        cmd = rebSpell(ARG(command), rebEND);

        argc = 1;
        argv = rebAllocN(const char*, (argc + 1));

        // !!! Make two copies because it frees cmd and all the argv.  Review.
        //
        argv[0] = rebSpell(ARG(command), rebEND);
        argv[1] = nullptr;
    }
    else if (IS_BLOCK(ARG(command))) {
Esempio n. 13
0
//
//  Emit_Decimal: C
//
REBINT Emit_Decimal(
    REBYTE *cp,
    REBDEC d,
    REBFLGS flags, // DEC_MOLD_PERCENT, DEC_MOLD_MINIMAL
    REBYTE point,
    REBINT decimal_digits
) {
    REBYTE *start = cp, *sig, *rve;
    int e, sgn;
    REBINT digits_obtained;

    /* sanity checks */
    if (decimal_digits < MIN_DIGITS) decimal_digits = MIN_DIGITS;
    else if (decimal_digits > MAX_DIGITS) decimal_digits = MAX_DIGITS;

    sig = (REBYTE *) dtoa (d, 0, decimal_digits, &e, &sgn, (char **) &rve);

    digits_obtained = rve - sig;

    /* handle sign */
    if (sgn) *cp++ = '-';

    if (flags & DEC_MOLD_PERCENT) e += 2;

    if ((e > decimal_digits) || (e <= -6)) {
        /* e-format */
        *cp++ = *sig++;

        /* insert the radix point */
        *cp++ = point;

        /* insert the rest */
        memcpy(cp, sig, digits_obtained - 1);
        cp += digits_obtained - 1;
    } else if (e > 0) {
        if (e <= digits_obtained) {
            /* insert digits preceding point */
            memcpy (cp, sig, e);
            cp += e;
            sig += e;

            *cp++ = point;

            /* insert digits following point */
            memcpy(cp, sig, digits_obtained -  e);
            cp += digits_obtained - e;
        } else {
            /* insert all digits obtained */
            memcpy (cp, sig, digits_obtained);
            cp += digits_obtained;

            /* insert zeros preceding point */
            memset (cp, '0', e - digits_obtained);
            cp += e - digits_obtained;

            *cp++ = point;
        }
        e = 0;
    } else {
        *cp++ = '0';

        *cp++ = point;

        memset(cp, '0', -e);
        cp -= e;

        memcpy(cp, sig, digits_obtained);
        cp += digits_obtained;

        e = 0;
    }

    // Add at least one zero after point (unless percent or pair):
    if (*(cp - 1) == point) {
        if ((flags & DEC_MOLD_PERCENT) || (flags & DEC_MOLD_MINIMAL))
            cp--;
        else
            *cp++ = '0';
    }

    // Add E part if needed:
    if (e) {
        *cp++ = 'e';
        INT_TO_STR(e - 1, cp);
        cp = b_cast(strchr(s_cast(cp), 0));
    }

    if (flags & DEC_MOLD_PERCENT) *cp++ = '%';
    *cp = 0;
    return cp - start;
}
Esempio n. 14
0
*/  void Mold_Value(REB_MOLD *mold, const REBVAL *value, REBFLG molded)
/*
**		Mold or form any value to string series tail.
**
***********************************************************************/
{
	REBYTE buf[60];
	REBINT len;
	REBSER *ser = mold->series;

	CHECK_C_STACK_OVERFLOW(&len);

	assert(SERIES_WIDE(mold->series) == sizeof(REBUNI));
	assert(ser);

	// Special handling of string series: {
	if (ANY_STR(value) && !IS_TAG(value)) {

		// Forming a string:
		if (!molded) {
			Insert_String(ser, -1, VAL_SERIES(value), VAL_INDEX(value), VAL_LEN(value), 0);
			return;
		}

		// Special format for ALL string series when not at head:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
	}

	switch (VAL_TYPE(value)) {
	case REB_NONE:
		Emit(mold, "+N", SYM_NONE);
		break;

	case REB_LOGIC:
//		if (!molded || !VAL_LOGIC_WORDS(value) || !GET_MOPT(mold, MOPT_MOLD_ALL))
			Emit(mold, "+N", VAL_LOGIC(value) ? SYM_TRUE : SYM_FALSE);
//		else
//			Mold_Logic(mold, value);
		break;

	case REB_INTEGER:
		len = Emit_Integer(buf, VAL_INT64(value));
		goto append;

	case REB_DECIMAL:
	case REB_PERCENT:
		len = Emit_Decimal(buf, VAL_DECIMAL(value), IS_PERCENT(value)?DEC_MOLD_PERCENT:0,
			Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT], mold->digits);
		goto append;

	case REB_MONEY:
		len = Emit_Money(value, buf, mold->opts);
		goto append;

	case REB_CHAR:
		Mold_Uni_Char(ser, VAL_CHAR(value), (REBOOL)molded, (REBOOL)GET_MOPT(mold, MOPT_MOLD_ALL));
		break;

	case REB_PAIR:
		len = Emit_Decimal(buf, VAL_PAIR_X(value), DEC_MOLD_MINIMAL, Punctuation[PUNCT_DOT], mold->digits/2);
		Append_Unencoded_Len(ser, s_cast(buf), len);
		Append_Byte(ser, 'x');
		len = Emit_Decimal(buf, VAL_PAIR_Y(value), DEC_MOLD_MINIMAL, Punctuation[PUNCT_DOT], mold->digits/2);
		Append_Unencoded_Len(ser, s_cast(buf), len);
		//Emit(mold, "IxI", VAL_PAIR_X(value), VAL_PAIR_Y(value));
		break;

	case REB_TUPLE:
		len = Emit_Tuple(value, buf);
		goto append;

	case REB_TIME:
		//len = Emit_Time(value, buf, Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT]);
		Emit_Time(mold, value);
		break;

	case REB_DATE:
		Emit_Date(mold, value);
		break;

	case REB_STRING:
		// FORM happens in top section.
		Mold_String_Series(value, mold);
		break;

	case REB_BINARY:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
		Mold_Binary(value, mold);
		break;

	case REB_FILE:
		if (VAL_LEN(value) == 0) {
			Append_Unencoded(ser, "%\"\"");
			break;
		}
		Mold_File(value, mold);
		break;

	case REB_EMAIL:
	case REB_URL:
		Mold_Url(value, mold);
		break;

	case REB_TAG:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
		Mold_Tag(value, mold);
		break;

//		Mold_Issue(value, mold);
//		break;

	case REB_BITSET:
		Pre_Mold(value, mold); // #[bitset! or make bitset!
		Mold_Bitset(value, mold);
		End_Mold(mold);
		break;

	case REB_IMAGE:
		Pre_Mold(value, mold);
		if (!GET_MOPT(mold, MOPT_MOLD_ALL)) {
			Append_Byte(ser, '[');
			Mold_Image_Data(value, mold);
			Append_Byte(ser, ']');
			End_Mold(mold);
		}
		else {
			REBVAL val = *value;
			VAL_INDEX(&val) = 0; // mold all of it
			Mold_Image_Data(&val, mold);
			Post_Mold(value, mold);
		}
		break;

	case REB_BLOCK:
	case REB_PAREN:
		if (!molded)
			Form_Block_Series(VAL_SERIES(value), VAL_INDEX(value), mold, 0);
		else
			Mold_Block(value, mold);
		break;

	case REB_PATH:
	case REB_SET_PATH:
	case REB_GET_PATH:
	case REB_LIT_PATH:
		Mold_Block(value, mold);
		break;

	case REB_VECTOR:
		Mold_Vector(value, mold, molded);
		break;

	case REB_DATATYPE:
		if (!molded)
			Emit(mold, "N", VAL_DATATYPE(value) + 1);
		else
			Emit(mold, "+DN", SYM_DATATYPE_TYPE, VAL_DATATYPE(value) + 1);
		break;

	case REB_TYPESET:
		Mold_Typeset(value, mold, molded);
		break;

	case REB_WORD:
		// This is a high frequency function, so it is optimized.
		Append_UTF8(ser, Get_Sym_Name(VAL_WORD_SYM(value)), -1);
		break;

	case REB_SET_WORD:
		Emit(mold, "W:", value);
		break;

	case REB_GET_WORD:
		Emit(mold, ":W", value);
		break;

	case REB_LIT_WORD:
		Emit(mold, "\'W", value);
		break;

	case REB_REFINEMENT:
		Emit(mold, "/W", value);
		break;

	case REB_ISSUE:
		Emit(mold, "#W", value);
		break;

	case REB_CLOSURE:
	case REB_FUNCTION:
	case REB_NATIVE:
	case REB_ACTION:
	case REB_COMMAND:
		Mold_Function(value, mold);
		break;

	case REB_OBJECT:
	case REB_MODULE:
	case REB_PORT:
		if (!molded) Form_Object(value, mold);
		else Mold_Object(value, mold);
		break;

	case REB_TASK:
		Mold_Object(value, mold); //// | (1<<MOPT_NO_NONE));
		break;

	case REB_ERROR:
		Mold_Error(value, mold, molded);
		break;

	case REB_MAP:
		Mold_Map(value, mold, molded);
		break;

	case REB_GOB:
	{
		REBSER *blk;
		Pre_Mold(value, mold);
		blk = Gob_To_Block(VAL_GOB(value));
		Mold_Block_Series(mold, blk, 0, 0);
		End_Mold(mold);
	}
		break;


	case REB_EVENT:
		Mold_Event(value, mold);
		break;

	case REB_STRUCT:
	{
		REBSER *blk;
		Pre_Mold(value, mold);
		blk = Struct_To_Block(&VAL_STRUCT(value));
		Mold_Block_Series(mold, blk, 0, 0);
		End_Mold(mold);
	}
		break;

	case REB_ROUTINE:
		Pre_Mold(value, mold);
		Mold_Block_Series(mold, VAL_ROUTINE_SPEC(value), 0, NULL);
		End_Mold(mold);
		break;
	case REB_LIBRARY:
		Pre_Mold(value, mold);

		DS_PUSH_NONE;
		*DS_TOP = *(REBVAL*)SERIES_DATA(VAL_LIB_SPEC(value));
		Mold_File(DS_TOP, mold);
		DS_DROP;

		End_Mold(mold);
		break;
	case REB_CALLBACK:
		Pre_Mold(value, mold);
		Mold_Block_Series(mold, VAL_ROUTINE_SPEC(value), 0, NULL);
		End_Mold(mold);
		break;
	case REB_REBCODE:
	case REB_OP:
	case REB_FRAME:
	case REB_HANDLE:
	case REB_UTYPE:
		// Value has no printable form, so just print its name.
		if (!molded) Emit(mold, "?T?", value);
		else Emit(mold, "+T", value);
		break;

	case REB_END:
	case REB_UNSET:
		if (molded) Emit(mold, "+T", value);
		break;

	default:
		assert(FALSE);
		Panic_Core(RP_DATATYPE+5, VAL_TYPE(value));
	}
	return;

append:
	Append_Unencoded_Len(ser, s_cast(buf), len);

}
Esempio n. 15
0
//
//  Mold_Vector: C
//
void Mold_Vector(const REBVAL *value, REB_MOLD *mold, REBOOL molded)
{
    REBSER *vect = VAL_SERIES(value);
    REBYTE *data = SER_DATA_RAW(vect);
    REBCNT bits  = VECT_TYPE(vect);
//  REBCNT dims  = vect->size >> 8;
    REBCNT len;
    REBCNT n;
    REBCNT c;
    union {REBU64 i; REBDEC d;} v;
    REBYTE buf[32];
    REBYTE l;

    if (GET_MOPT(mold, MOPT_MOLD_ALL)) {
        len = VAL_LEN_HEAD(value);
        n = 0;
    } else {
        len = VAL_LEN_AT(value);
        n = VAL_INDEX(value);
    }

    if (molded) {
        enum Reb_Kind kind = (bits >= VTSF08) ? REB_DECIMAL : REB_INTEGER;
        Pre_Mold(value, mold);
        if (!GET_MOPT(mold, MOPT_MOLD_ALL))
            Append_Codepoint_Raw(mold->series, '[');
        if (bits >= VTUI08 && bits <= VTUI64)
            Append_Unencoded(mold->series, "unsigned ");
        Emit(
            mold,
            "N I I [",
            Canon(SYM_FROM_KIND(kind)),
            bit_sizes[bits & 3],
            len
        );
        if (len)
            New_Indented_Line(mold);
    }

    c = 0;
    for (; n < SER_LEN(vect); n++) {
        v.i = get_vect(bits, data, n);
        if (bits < VTSF08) {
            l = Emit_Integer(buf, v.i);
        } else {
            l = Emit_Decimal(buf, v.d, 0, '.', mold->digits);
        }
        Append_Unencoded_Len(mold->series, s_cast(buf), l);

        if ((++c > 7) && (n + 1 < SER_LEN(vect))) {
            New_Indented_Line(mold);
            c = 0;
        }
        else
            Append_Codepoint_Raw(mold->series, ' ');
    }

    if (len) {
        //
        // remove final space (overwritten with terminator)
        //
        TERM_UNI_LEN(mold->series, UNI_LEN(mold->series) - 1);
    }

    if (molded) {
        if (len) New_Indented_Line(mold);
        Append_Codepoint_Raw(mold->series, ']');
        if (!GET_MOPT(mold, MOPT_MOLD_ALL)) {
            Append_Codepoint_Raw(mold->series, ']');
        }
        else {
            Post_Mold(value, mold);
        }
    }
}