Esempio n. 1
0
*/  REBINT Emit_Tuple(REBVAL *value, REBYTE *out)
/*
**		The out array must be large enough to hold longest tuple.
**		Longest is: (3 digits + '.') * 11 nums + 1 term => 45
**
***********************************************************************/
{
	REBCNT len;
	REBYTE *tp;
	REBYTE *start = out;

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

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

	return out-start;
}
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
//
//  Emit_Tuple: C
//
// The out array must be large enough to hold longest tuple.
// Longest is: (3 digits + '.') * 11 nums + 1 term => 45
//
REBINT Emit_Tuple(const REBVAL *value, REBYTE *out)
{
    REBCNT len = VAL_TUPLE_LEN(value);
    const REBYTE *tp = cast(const REBYTE *, VAL_TUPLE(value));
    REBYTE *start = out;

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

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

    return out-start;
}
Esempio n. 4
0
//
//  Panic_Core: C
// 
// (va_list by pointer: http://stackoverflow.com/a/3369762/211160)
// 
// Print a failure message and abort.  The code adapts to several
// different load stages of the system, and uses simpler ways to
// report the error when the boot has not progressed enough to
// use the more advanced modes.  This allows the same interface
// to be used for `panic Error_XXX(...)` and `fail (Error_XXX(...))`.
//
ATTRIBUTE_NO_RETURN void Panic_Core(REBCNT id, REBSER *maybe_frame, va_list *args)
{
    char title[PANIC_TITLE_SIZE];
    char message[PANIC_MESSAGE_SIZE];

    title[0] = '\0';
    message[0] = '\0';

    if (maybe_frame) {
        assert(id == 0);
        id = ERR_NUM(maybe_frame);
    }

    // We are crashing, so a legitimate time to be disabling the garbage
    // collector.  (It won't be turned back on.)
    GC_Disabled++;

    if (Reb_Opts && Reb_Opts->crash_dump) {
        Dump_Info();
        Dump_Stack(0, 0);
    }

    strncat(title, "PANIC #", PANIC_TITLE_SIZE - 1);
    Form_Int(b_cast(title + strlen(title)), id); // !!! no bounding...

    strncat(message, Str_Panic_Directions, PANIC_MESSAGE_SIZE - 1);

#if !defined(NDEBUG)
    // In debug builds, we may have the file and line number to report if
    // the call to Panic_Core originated from the `panic` macro.  But we
    // will not if the panic is being called from a Make_Error call that
    // is earlier than errors can be made...

    if (TG_Erroring_C_File) {
        Form_Args(
            b_cast(message + strlen(message)),
            PANIC_MESSAGE_SIZE - 1 - strlen(message),
            "C Source File %s, Line %d\n",
            TG_Erroring_C_File,
            TG_Erroring_C_Line,
            NULL
        );
    }
#endif

    if (PG_Boot_Phase < BOOT_LOADED) {
        strncat(message, title, PANIC_MESSAGE_SIZE - 1);
        strncat(
            message,
            "\n** Boot Error: (string table not decompressed yet)",
            PANIC_MESSAGE_SIZE - 1
        );
    }
    else if (PG_Boot_Phase < BOOT_ERRORS && id < RE_INTERNAL_MAX) {
        // We are panic'ing on one of the errors that can occur during
        // boot (e.g. before Make_Error() be assured to run).  So we use
        // the C string constant that was formed by %make-boot.r and
        // compressed in the boot block.
        //
        // Note: These strings currently do not allow arguments.

        const char *format =
            cs_cast(BOOT_STR(RS_ERROR, id - RE_INTERNAL_FIRST));
        assert(args && !maybe_frame);
        strncat(message, "\n** Boot Error: ", PANIC_MESSAGE_SIZE - 1);
        Form_Args_Core(
            b_cast(message + strlen(message)),
            PANIC_MESSAGE_SIZE - 1 - strlen(message),
            format,
            args
        );
    }
    else if (PG_Boot_Phase < BOOT_ERRORS && id >= RE_INTERNAL_MAX) {
        strncat(message, title, PANIC_MESSAGE_SIZE - 1);
        strncat(
            message,
            "\n** Boot Error: (error object table not initialized yet)",
            PANIC_MESSAGE_SIZE - 1
        );
    }
    else {
        // The system should be theoretically able to make and mold errors.
        //
        // !!! If you're trying to panic *during* error molding this
        // is obviously not going to not work.  All errors pertaining to
        // molding errors should audited to be in the Boot: category.

        REBVAL error;

        if (maybe_frame) {
            assert(!args);
            Val_Init_Error(&error, maybe_frame);
        }
        else {
            // We aren't explicitly passed a Rebol ERROR! object, but we
            // consider it "safe" to make one since we're past BOOT_ERRORS

            Val_Init_Error(&error, Make_Error_Core(id, args));
        }

        Form_Args(
            b_cast(message + strlen(message)),
            PANIC_MESSAGE_SIZE - 1 - strlen(message),
            "%v",
            &error,
            NULL
        );
    }

    OS_CRASH(cb_cast(Str_Panic_Title), cb_cast(message));

    // Note that since we crash, we never return so that the caller can run
    // a va_end on the passed-in args.  This is illegal in the general case:
    //
    //    http://stackoverflow.com/a/587139/211160

    DEAD_END;
}
Esempio n. 5
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. 6
0
*/	void Crash(REBINT id, ...)
/*
**		Print a failure message and abort.
**
**		LATIN1 ONLY!! (For now)
**
**		The error is identified by id number, which can reference an
**		error message string in the boot strings block.
**
**		Note that lower level error messages should not attempt to
**		use the %r (mold value) format (uses higher level functions).
**
**		See panics.h for list of crash errors.
**
***********************************************************************/
{
	va_list args;
	REBYTE buf[CRASH_BUF_SIZE];
	REBYTE *msg;
	REBINT n = 0;

	va_start(args, id);

	DISABLE_GC;
	if (Reb_Opts->crash_dump) {
		Dump_Info();
		Dump_Stack(0, 0);
	}

	// "REBOL PANIC #nnn:"
	COPY_BYTES(buf, Crash_Msgs[CM_ERROR], CRASH_BUF_SIZE);
	APPEND_BYTES(buf, " #", CRASH_BUF_SIZE);
	Form_Int(buf + LEN_BYTES(buf), id);
	APPEND_BYTES(buf, ": ", CRASH_BUF_SIZE);

	// "REBOL PANIC #nnn: put error message here"
	// The first few error types only print general error message.
	// Those errors > RP_STR_BASE have specific error messages (from boot.r).
	if      (id < RP_BOOT_DATA) n = CM_DEBUG;
	else if (id < RP_INTERNAL) n = CM_BOOT;
	else if (id < RP_ASSERTS)  n = CM_INTERNAL;
	else if (id < RP_DATATYPE) n = CM_ASSERT;
	else if (id < RP_STR_BASE) n = CM_DATATYPE;
	else if (id > RP_STR_BASE + RS_MAX - RS_ERROR) n = CM_DEBUG;

	// Use the above string or the boot string for the error (in boot.r):
	msg = (REBYTE*)(n >= 0 ? Crash_Msgs[n] : BOOT_STR(RS_ERROR, id - RP_STR_BASE - 1));
	Form_Var_Args(buf + LEN_BYTES(buf), CRASH_BUF_SIZE - 1 - LEN_BYTES(buf), msg, args);

	n = LEN_BYTES(Crash_Msgs[CM_CONTACT]);
	if ((LEN_BYTES(buf) + n) < (CRASH_BUF_SIZE - 1))
		APPEND_BYTES(buf, Crash_Msgs[CM_CONTACT], n);

	// Convert to OS-specific char-type:
#ifdef disable_for_now //OS_WIDE_CHAR   /// win98 does not support it
	{
		REBCHR s1[512];
		REBCHR s2[2000];

		n = TO_OS_STR(s1, Crash_Msgs[CM_ERROR], LEN_BYTES(Crash_Msgs[CM_ERROR]));
		if (n > 0) s1[n] = 0; // terminate
		else OS_EXIT(200); // bad conversion

		n = TO_OS_STR(s2, buf, LEN_BYTES(buf));
		if (n > 0) s2[n] = 0;
		else OS_EXIT(200);

		OS_CRASH(s1, s2);
	}
#else
	OS_CRASH(Crash_Msgs[CM_ERROR], buf);
#endif
}