531.md at tip

Login

File tip/531.md from the latest check-in


# TIP 531: Static Tcl Interpreter Creation Function
	Author:         Shannon Noe <[email protected]>
	State:          Rejected
	Type:           Project
	Vote:           Done
	Created:        14-Dec-2018
	Post-History:  
	Keywords:       Tcl, stubs
	Tcl-Version:    8.7
	Tcl-Branch:     tip-531
	Vote-Summary:	Rejected 0/4/1
	Votes-For:	none
	Votes-Against:	JN, KBK, KW, MC
	Votes-Present:	BG
----

# Abstract

This TIP adds a helper function to the tclstubs library for creating an interpreter.
The `Tcl_CreateInterp` function is dependent on the order defining `USE_TCL_STUBS` and inclusion of `tcl.h`.
When users get this wrong the error is a null pointer exception (NPE) on the stubs table.
For some TCLers/C users this takes a bit of digging to unravel the cause of the NPE.

Therefore, I propose a new function `Tcl_CreateInterpWithStubs` which is always fully independent of `USE_TCL_STUBS`. 
This function will be part of the libtclstub87.a library.

# Rationale

Users that are creating interpreters are often getting errors because they are getting the `Tcl_CreateInterp` macro.
This error is a runtime null pointer exception which several users find confusing.
The user as to be astute enough to follow instructions and see that `USE_TCL_STUBS` will replace a C function call with a macro.
By providing a plain function, the users can have a easier time embedded interperters and using stubs.

    /usr/local/include/tcl8.6/tclDecls.h:#define Tcl_CreateInterp \
    /usr/local/include/tcl8.6/tclDecls.h- (tclStubsPtr->tcl_CreateInterp) /* 94 */

# Specification

There will be a new function in `libtclstub??.a` that always performs interpreter initialization and stub table initialization.
The signature is **Tcl\_CreateInterpWithStubs**(const char \*_version_, int _exact_).
The _version_ and _exact_ parameters match `Tcl_InitStubs`.

On error NULL is returned instead of a TCL interpreter.
Without this pointer there is no way to obtain extended error codes, but the trade off is that it makes the API much easier to use.
(That could be an error, someone could clarify that for me.)

## Example Implementation

    /* must be compiled without stubs */

    #undef USE_TCL_STUBS
    #include <tcl.h>

    Tcl_Interp *
    Tcl_CreateInterpWithStubs(
        const char *version,
        int exact)
    {
        Tcl_Interp *interp = Tcl_CreateInterp();

        if (Tcl_Init(interp) == TCL_ERROR ||
                Tcl_InitStubs(interp, version, exact) == NULL ||
                Tcl_PkgRequire(interp, "Tcl", version, exact) == NULL) {
            return NULL;
        }

        return interp;
    }

## Example use

    #include <tcl.h>

    main()
    {
        Tcl_Interp *interp = Tcl_CreateInterpWithStubs("8.7", 0);
        if(interp) {
            Tcl_Eval(interp, "puts [clock format [clock seconds]]");
        } else {
            fprintf(stderr, "Tcl_CreateInterpWithStubs failed\n");
        }
    }


# Implementation

Please refer to the `tip-531` branch of the core Tcl repository.

# Backwards Compatibility

This is a new function in the TCL C API.

# Copyright

This document has been placed in the public domain.