C API

This is the C API for smisk.core.

Types

byte
8 bits of data.
probably_call_cb

Callback signature for probably_call() callbacks:

int probably_call_cb ( void *userdata )

Members

PyObject* smisk_core_module

The module itself.

New in version 1.1.0.

PyObject* Error
General error
PyObject* IOError
Input/output error
PyObject* InvalidSessionError
Session-related error
PyObject* kString_http
The string "http"
PyObject* kString_https
The string "https"
int smisk_listensock_fileno
FastCGI connection fileno.

Functions

PyObject* smisk_bind(PyObject *self, PyObject *args)
PyObject* smisk_unbind(PyObject *self)

New in version 1.1.0.

PyObject* smisk_listening(PyObject *self, PyObject *args)
PyObject* smisk_uid(PyObject *self, PyObject *args)

New in version 1.1.0.

PyObject* smisk_pack(PyObject *self, PyObject *args)

New in version 1.1.0.

PyObject* SMISK_PyObject_GET(PyObject *object, char *attrname)

Macro for getting an arbitrary attribute from object.

This is the only way to set/get Type/Class properties. Based on the python interal function PyObject **_PyObject_GetDictPtr(PyObject *)

Returns:A PyObject or NULL if an exception was raised.

New in version 1.1.0.

int SMISK_PyObject_SET(PyObject *object, char *attrname, PyObject *value)

Macro for setting an arbitrary attribute of object.

This is the only way to set/get Type/Class properties. Based on the python interal function PyObject **_PyObject_GetDictPtr(PyObject *)

Returns:-1 is an error occured or 0 on success.

New in version 1.1.0.

void REPLACE_OBJ(destination, new_value, type)
Macro for replacing a value somewhere, releasing a reference to any previous value and retaining one reference to the new value.
void ENSURE_BY_GETTER(void *direct, cfunction *getter[, error_code...])
Macro used to ensure a lazy instance variable is available. error_code is executed if getter returns NULL.
int SMISK_STRING_CHECK(PyObject *object)

Macro for testing if object is a kind of string (either str or unicode). Workaround for a nasty bug in PyString_Check().

Returns:1 if object is a kind of string, otherwise 0.

Utilities

PyObject *smisk_format_exc(PyObject *type, PyObject *value, PyObject *tb)
Returns:PyStringObject (new reference). Does NOT clear exception.
int PyDict_assoc_val_with_key(PyObject *dict, PyObject *val, PyObject *key)
Associate value with key - if the key exists, the keys value is a list of values.
int smisk_parse_input_data(char *s, const char *separator, int is_cookie_data, PyObject *dict, const char *charset, int try_fallback_cs)

Parse input data (query string, post url-encoded, cookie, etc).

Returns:0 on success.
size_t smisk_stream_readline(char *str, int n, FCGX_Stream *stream)
Read a line from a FCGI stream
void smisk_frepr_bytes(FILE *f, const char *s, size_t len)
Print bytes - unsafe or outside ASCII characters are printed as \xXX The output looks like: bytes(4) 'm\x0dos'
double smisk_microtime(void)
Returns:Current time in microseconds
char smisk_size_unit(double *bytes)
KB, GB, etc
char *smisk_encode_bin(const byte *in, size_t inlen, char *out, char bits_per_byte)

Encode bytes into printable ASCII characters.

Returns a pointer to the byte after the last valid character in out:

nbits=4: out need to fit 40+1 bytes (base 16) (0-9, a-f)
nbits=5: out need to fit 32+1 bytes (base 32) (0-9, a-v)
nbits=6: out need to fit 27+1 bytes (base 64) (0-9, a-z, A-Z, "-", ",")
PyObject *smisk_util_pack(const byte *data, size_t size, int nbits)

Pack bytes into printable ASCII characters.

Returns:a PyString.
See:smisk_encode_bin for more information.
PyObject *smisk_find_string_by_prefix_in_dict(PyObject *list, PyObject *prefix)
Parameters:
  • list – list
  • prefix – string
Returns:

int

int probably_call(float probability, probably_call_cb *cb, void *cb_arg)

Calls cb depending on probability.

Parameters:
  • probability – float Likeliness of cb being called. A value between 0 and 1.
  • cb – Function to call.
  • cb_arg – Arbitrary argument to be passed on to cb when called.
Returns:

-1 on error (if so, a Python Error have been set) or 0 on success.

long smisk_object_hash(PyObject *obj)

Calculate a hash from any python object.

If obj support hash out-of-the-box, the equivalent of hash(obj) will be used. Otherwise obj will be marshalled and the resulting bytes are used for calculating the hash.

Logging

int log_error(char *fmt, ...)

Log an error to stderr.

The message actually being written has the following format:

<MOD_IDENT> [<PID>] ERROR <FILE>:<LINE>: <fmt % ...><LF>
Returns:Number of characters printed (not including the trailing \0 used to end output to strings) or a negative value if an output error occured.
int log_debug(char *fmt, ...)

Log something to stderr.

Enabled if SMISK_DEBUG evaluates to true, otherwise all instances of log_debug are removed a compile time.

The message actually being written has the following format:

<MOD_IDENT> [<PID>] DEBUG <FILE>:<LINE>: <fmt % ...><LF>
Returns:Number of characters printed (not including the trailing \0 used to end output to strings) or a negative value if an output error occured.
int log_trace(char *fmt, ...)

Log a trace message to stderr.

Enabled if SMISK_TRACE evaluates to true, otherwise all instances of log_trace are removed a compile time.

The message actually being written has the following format:

<MOD_IDENT> [<PID>] TRACE <FILE>:<LINE> in <FUNCTION> <fmt % ...><LF>
Returns:Number of characters printed (not including the trailing \0 used to end output to strings) or a negative value if an output error occured.
void assert_refcount(PyObject *object, count_test...)

Macro to assert refcount on object matches count_test.

Evaluated only if SMISK_DEBUG is true.

Asserting my_dict has 3 or less references:

assert_refcount(my_dict, <= 3)

Macros

XDIGIT_TO_NUM
Convert an ASCII hex digit to the corresponding number in the range [0-16).
X2DIGITS_TO_NUM
Convert two ASCII hex digits, representing one value, to the corresponding number between 0-255.
XNUM_TO_DIGIT
Convert a number in the [0, 16) range to the ASCII representation of the corresponding hexadecimal digit in the set 0-9A-F.
XNUM_TO_digit
Convert a number in the [0, 16) range to the ASCII representation of the corresponding hexadecimal digit in the set 0-9a-f.
MOD_IDENT
Module identifier used in logging. Might be redefined by submodules.
QUOTE

Wrap the value of another macro in double quotes.

Example:

MY_VERSION_MAJOR 2
puts("Program version " QUOTE(MY_VERSION_MAJOR))
// Is equivalent to:
puts("Program version 2")
PyErr_SET_FROM_ERRNO

Expands to:

PyErr_SetFromErrnoWithFilename(PyExc_IOError, __FILE__)

Debugging

SMISK_DEBUG

If defined and evaluates to true, enables Smisk debugging features, like log_debug() and setting SMISK_TRACE to true (thus in turn activating log_trace()).

Automatically enabled when passing --debug-smisk to setup.py build.

SMISK_TRACE
Activates log_trace() if defined and evaluates to true. Automatically defined as SMISK_TRACE 1 if SMISK_DEBUG is enabled.
IFDEBUG(x)
x is evaluated if SMISK_DEBUG is enabled.
DUMP_REFCOUNT(PyObject *object)

Evaluates only if SMISK_DEBUG is true and expands to:

log_debug(" *** %s: " PY_SSIZE_FMT, #o, (o) ? (Py_ssize_t)(o)->ob_refcnt : 0)
DUMP_REPR(PyObject *object)

Like repr() in interpreted Python or PyObject_Repr in CPython, but takes care of NULL values and refcounting.

Evaluates only if SMISK_DEBUG is true and expands to something like this:

log_debug("repr(%s) = %s", #o, PyObject_Repr(object));
IFTRACE(x)
x is evaluated if SMISK_TRACE is enabled.

Threading

EXTERN_OP_START
TODO
EXTERN_OP_END
TODO
EXTERN_OP(section)
TODO
EXTERN_OP2(section)
TODO
EXTERN_OP3(state_var, section)
TODO

String manipulation

STR_LTRIM_S
TODO

String comparison

Inspired by Igor Sysoev.

These macros evaluate to true if string equals, or starts with, abc....

Example:

char *string = "Help";
if (smisk_str4cmp(string, 'H', 'e', 'l', 'p'))
  fprint("Yes, string == \"Help\"");
// Output: Yes, string == "Help"
smisk_str3cmp(string, a, b, c)
smisk_str4cmp(string, a, b, c, d)
smisk_str5cmp(string, a, b, c, d, e)
smisk_str6cmp(string, a, b, c, d, e, f)
smisk_str7cmp(string, a, b, c, d, e, f, g)
smisk_str8cmp(string, a, b, c, d, e, f, g, h)
smisk_str9cmp(string, a, b, c, d, e, f, g, h, i)

Configuration

Macros defined in config.h.

SMISK_STREAM_READ_CHUNKSIZE
Chunk size for reading unknown length from a stream.
SMISK_STREAM_READLINE_LENGTH
Default readline length for smisk.Stream.readline().
SMISK_FILE_UPLOAD_DIR
Where uploaded files are saved before taken care of. If TMPDIR is not available in process env, the value of this macro is used to construct a temporary filename.
SMISK_FILE_UPLOAD_PREFIX
Prefix for temporary uploaded files.
SMISK_SESSION_NBITS

Session ID compactness.

New in version 1.1.0.