NAME ^

src/misc.c - Miscellaneous functions

DESCRIPTION ^

Miscellaneous functions, mainly the Parrot_sprintf family.

Uses a generalized formatting algorithm (src/spf_render.c) with a specialized vtable (src/spf_vtable.c) to handle argument extraction.

Functions ^

The naming convention used is:

Parrot_v?n?sprintf

A (nearly) drop-in replacement for v?n?sprintf.

Parrot_v?sprintf_c

Takes a C-string format, returns a Parrot string.

Parrot_v?sprintf_s

Takes a Parrot string format, returns a Parrot string.

So the _ means "returns Parrot string" and the other letter indicates the type for the format.

*/

#define IN_SPF_SYSTEM

#include "parrot/parrot.h"

/* HEADERIZER HFILE: include/parrot/misc.h */

/*

FUNCDOC: Parrot_vsprintf_s

Almost all the other sprintf variants in this file are implemented in terms of this function (see Parrot_psprintf() for the exception). It in turn calls Parrot_sprintf_format() (see src/spf_render.c).

*/

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * Parrot_vsprintf_s(PARROT_INTERP, NOTNULL(STRING *pat), va_list args) { SPRINTF_OBJ obj = va_core; obj.data = PARROT_VA_TO_VAPTR(args);

    return Parrot_sprintf_format(interp, pat, &obj);
}

/*

FUNCDOC: Parrot_vsprintf_c

C string version of Parrot_vsprintf_s().

*/

PARROT_API PARROT_CANNOT_RETURN_NULL STRING * Parrot_vsprintf_c(PARROT_INTERP, NOTNULL(const char *pat), va_list args) { STRING * const realpat = string_make(interp, pat, strlen(pat), NULL, PObj_external_FLAG);

    STRING * const ret = Parrot_vsprintf_s(interp, realpat, args);

    return ret;
}

/*

FUNCDOC: Parrot_vsnprintf

Similar to Parrot_vsprintf() but with an option to specify the length (len) of the returned C string.

*/

PARROT_API void Parrot_vsnprintf(PARROT_INTERP, NOTNULL(char *targ), size_t len, NOTNULL(const char *pat), va_list args) { if (len == 0) return; len--; if (len) { const STRING * const ret = Parrot_vsprintf_c(interp, pat, args); /* string_transcode(interp, ret, NULL, NULL, &ret); */

        if (len > ret->bufused) {
            len = ret->bufused;
        }

        if (len)
            memcpy(targ, ret->strstart, len);
    }
    targ[len] = 0;
}

/*

FUNCDOC: Parrot_sprintf_s

Calls Parrot_vsprintf_s() with the va_list obtained from ....

*/

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * Parrot_sprintf_s(PARROT_INTERP, NOTNULL(STRING *pat), ...) { STRING *ret; va_list args;

    va_start(args, pat);

    ret = Parrot_vsprintf_s(interp, pat, args);

    va_end(args);

    return ret;
}

/*

FUNCDOC: Parrot_sprintf_c

C string version of Parrot_sprintf_s().

*/

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * Parrot_sprintf_c(PARROT_INTERP, NOTNULL(const char *pat), ...) { STRING *ret; va_list args;

    va_start(args, pat);

    ret = Parrot_vsprintf_c(interp, pat, args);

    va_end(args);

    return ret;
}

/*

FUNCDOC: Parrot_snprintf

Similar to Parrot_sprintf() but with an option to specify the length (len) of the returned C string.

*/

PARROT_API void Parrot_snprintf(PARROT_INTERP, NOTNULL(char *targ), size_t len, NOTNULL(const char *pat), ...) { va_list args;

    va_start(args, pat);

    Parrot_vsnprintf(interp, targ, len, pat, args);

    va_end(args);
}

/*

FUNCDOC: Parrot_psprintf

Calls Parrot_sprintf_format() with the insertion arguments in an Array PMC.

*/

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * Parrot_psprintf(PARROT_INTERP, NOTNULL(STRING *pat), NOTNULL(PMC *ary)) { SPRINTF_OBJ obj = pmc_core; obj.data = ary;

    return Parrot_sprintf_format(interp, pat, &obj);
}

/*

SEE ALSO ^

src/misc.h, src/spf_vtable.c, src/spf_render.c.

HISTORY ^

This was once a simple, vararg-based implementation that existed completely within this file. When the file grew to be nearly 1,000 lines long, I split it into three. --BD

*/

/* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */


parrot