=head1 SEATBELTS

DEFINITELY UNDER CONSTRUCTION

I'm trying to create as many seat belts and idiot lights as
possible. Using C macros and automatic function declaration generation
makes this much easier for me to do, and is far more maintainable.

Headerizer creates function declarations based on function
definitions. It scans the source files passed to it and extracts the
function declarations. Then it puts them into the appropriate .h file or,
in the case of static functions, back into the source file itself.

The headerizer also adds function attributes as specified by the
decorations on the source.

All of these macros are GCC-specific right now, but soon will have
equivalent semantics for lint added to them. This will make lint a far
more powerful tool. If/when we ever get splint going, too, we can add
semantics there as well.

Also, where it says "compiler", it could also mean "lint or any
other static analysis tool like splint."

=head1 What's a shim?

Think of "shim" as shorthand for "placeholder". It's 64% shorter.

GCC (and lint and splint) likes to complain (as well it should) if you
pass an argument into a function and don't use it. If we know that we're
not going to use an argument, we can either remove the argument from
the function declaration, or mark it as unused.

Throwing the argument away is not always possible. Usually, it's because
the function is one that gets referred to by a function pointer, and
all functions of this group must have the same, say, three args: Interp,
Foo and Bar. Maybe a given function doesn't use Foo, but we still have to
accept Foo. In this case, we can in the body of the func, C<UNUSED(Foo)>,
if we plan to use it in the future. Or, if we never will use it, mark
it as a C<SHIM(Foo)> in the declaration.

=head1 Function Decorators

=head2 PARROT_WARN_UNUSED_RESULT

Tells the compiler to warn if the function is called, but the result is ignored.

=head2 PARROT_IGNORABLE_RESULT

Tells the compiler that it's OK to ignore the function's return value

=head2 PARROT_MALLOC

Functions marked with this are flagged as having received C<malloc>ed
memory.  This lets the compiler do analysis on memory leaks.

=head2 PARROT_CONST_FUNCTION

The function is a deterministic one that will always return the
same value if given the same arguments, every time.  Examples include
functions like C<mod> or C<max>.  An anti-example is C<rand()> which
returns a different value every time.

=head2 PARROT_PURE_FUNCTION

Less stringent than PARROT_CONST_FUNCTION, these functions only
operate on their arguments and the data they point to.  Examples
include C<strlen()> or C<strchr()>.

=head2 PARROT_DOES_NOT_RETURN

For functions that can't return, like C<Parrot_exit()>.  This helps
the compiler's flow analysis.

=head2 PARROT_CANNOT_RETURN_NULL

For functions that return a pointer, but the pointer is guaranteed to not be NULL.

=head2 PARROT_CAN_RETURN_NULL

For functions that return a pointer that could be null.

=head1 ARGUMENT & VARIABLE DECORATORS

=head2 NOTNULL(x)

For function arguments and variables that must never have NULL
assigned to them, or passed into them.  For example, if we were
defining C<strlen()> in Parrot, we'd do it as C<strlen(NOTNULL(const char *p))>.

=head2 NULLOK(x)

For function arguments and variables where it's OK to pass in NULL.
For example, if we wrote C<free()> in Parrot, it would be
C<strlen(NULLOK(void *p))>.

=head2 SHIM(x)

=head1 PASSING AROUND INTERPRETERS

Most of the time, if you need an interpreter in your function,
define that argument as C<PARROT_INTERP>.  If your interpreter is
a shim, then use C<SHIM_INTERP>, not C<SHIM(PARROT_INTERP)>.

=head1 Examples

    PARROT_API
    PARROT_WARN_UNUSED_RESULT
    INTVAL
    string_str_index(PARROT_INTERP, NOTNULL(const STRING *s),
            NOTNULL(const STRING *s2), INTVAL start)


C<string_str_index> is part of the Parrot API, and returns an INTVAL. The
interpreter is used somewhere in the function. String C<s> and C<s2>
cannot be NULL. If the calling function ignores the return value,
it's an error, because you'd never want to call C<string_str_index()>
without wanting to know its value.

    PARROT_API
    PARROT_PURE_FUNCTION
    INTVAL
    parrot_hash_size(SHIM_INTERP, NOTNULL(const Hash *hash))
    {
        return hash->entries;
    }

This function is a pure function because it only looks at its parameters
or global memory. The interpreter doesn't get used, but needs to be
passed because all PARROT_API functions have interpreters passed, so is
flagged as a SHIM_INTERP.

We could put C<PARROT_WARN_UNUSED_RESULT> on this function, but since
all C<PARROT_PURE_FUNCTION>s and C<PARROT_CONST_FUNCTION>s get flagged
that way anyway, there's no need.

=head1 Splint to-do

Annotate functions with /*@only@*/ and /*@keep@*/

Figure out where /*@modifies@*/ is different from /*@out@*/

=head1 More safety stuff

Look at snprintf instead of sprintf

Use the return values from sprintf where we would be using strlen of the result

Make the VTABLE_type func take a const PMC, because hey, your type should never change, right?

Sync the specs in F<docs/pdds/pdd17_pmc.pod> with the function headers.

Hoist the repetitive iter_init() in src/encodings
