Expressionist
Header-only C++20 evaluator of algebraic expressions embedded in JSON fields
Loading...
Searching...
No Matches
expressionist_c.h File Reference

Plain C ABI for Expressionist: JSON string in, JSON string out. More...

Go to the source code of this file.

Typedefs

typedef struct ExpressionistHandle ExpressionistHandle
 

Enumerations

enum  ExpressionistCMethod { EXPRESSIONIST_C_GRAPH = 0 , EXPRESSIONIST_C_RECURSIVE = 1 }
 

Functions

EXPRESSIONIST_C_API ExpressionistHandleexpressionist_create (void)
 
EXPRESSIONIST_C_API void expressionist_destroy (ExpressionistHandle *handle)
 
EXPRESSIONIST_C_API void expressionist_set_tag (ExpressionistHandle *handle, const char *tag)
 
EXPRESSIONIST_C_API void expressionist_set_disable_key (ExpressionistHandle *handle, const char *key)
 
EXPRESSIONIST_C_API void expressionist_set_eval_method (ExpressionistHandle *handle, int method)
 
EXPRESSIONIST_C_API int expressionist_evaluate (ExpressionistHandle *handle, const char *json_in, char **out_json, char **out_error)
 
EXPRESSIONIST_C_API void expressionist_free_string (char *s)
 
EXPRESSIONIST_C_API const char * expressionist_version (void)
 

Detailed Description

Plain C ABI for Expressionist: JSON string in, JSON string out.

Copyright 2026 Paolo Bosetti SPDX-License-Identifier: Apache-2.0

A minimal, language-agnostic wrapper around the header-only C++ library: every call takes/returns UTF-8 JSON text, so it can be consumed from any runtime with a C FFI (ctypes/cffi in Python, but also Ruby, Node, Rust...). No C++ type (std::string, nlohmann::json, exceptions) ever crosses this boundary.

#include <stdio.h>
int main(void) {
char *out_json = NULL, *out_error = NULL;
if (expressionist_evaluate(h, "{\"a\":1,\"b\":2,\"c\":\"$a + b\"}",
&out_json, &out_error) == 0) {
printf("%s\n", out_json); // {"a":1,"b":2,"c":3}
} else {
fprintf(stderr, "error: %s\n", out_error);
}
return 0;
}
Plain C ABI for Expressionist: JSON string in, JSON string out.
struct ExpressionistHandle ExpressionistHandle
Definition expressionist_c.h:58
EXPRESSIONIST_C_API ExpressionistHandle * expressionist_create(void)
EXPRESSIONIST_C_API void expressionist_free_string(char *s)
EXPRESSIONIST_C_API int expressionist_evaluate(ExpressionistHandle *handle, const char *json_in, char **out_json, char **out_error)
EXPRESSIONIST_C_API void expressionist_set_tag(ExpressionistHandle *handle, const char *tag)
EXPRESSIONIST_C_API void expressionist_destroy(ExpressionistHandle *handle)

Typedef Documentation

◆ ExpressionistHandle

Opaque handle bundling the tag, disable key and evaluation strategy; everything else (the JSON document being evaluated) is passed per call. Create with expressionist_create(), release with expressionist_destroy().

Enumeration Type Documentation

◆ ExpressionistCMethod

Mirrors Expressionist::EvalMethod for expressionist_set_eval_method().

Enumerator
EXPRESSIONIST_C_GRAPH 

Topological (Kahn's algorithm).

EXPRESSIONIST_C_RECURSIVE 

Lazy, memoized, with cycle detection.

Function Documentation

◆ expressionist_create()

EXPRESSIONIST_C_API ExpressionistHandle * expressionist_create ( void  )

Creates a handle configured with the library defaults (tag "$", disable key "expressionist", EXPRESSIONIST_C_RECURSIVE).

Returns
a new handle, or NULL only on allocation failure.

◆ expressionist_destroy()

EXPRESSIONIST_C_API void expressionist_destroy ( ExpressionistHandle handle)

Releases a handle created by expressionist_create(). Accepts NULL.

◆ expressionist_set_tag()

EXPRESSIONIST_C_API void expressionist_set_tag ( ExpressionistHandle handle,
const char *  tag 
)

Changes the prefix that marks a JSON string as an expression (see Expressionist::setTag()). Takes effect on the next expressionist_evaluate() call. A NULL handle or tag is a silent no-op.

◆ expressionist_set_disable_key()

EXPRESSIONIST_C_API void expressionist_set_disable_key ( ExpressionistHandle handle,
const char *  key 
)

Changes the opt-out key that disables evaluation for a subtree (see Expressionist::setDisableKey()). A NULL handle or key is a silent no-op.

◆ expressionist_set_eval_method()

EXPRESSIONIST_C_API void expressionist_set_eval_method ( ExpressionistHandle handle,
int  method 
)

Selects the resolution strategy; pass EXPRESSIONIST_C_GRAPH or EXPRESSIONIST_C_RECURSIVE (see Expressionist::setEvalMethod()). A NULL handle is a silent no-op.

◆ expressionist_evaluate()

EXPRESSIONIST_C_API int expressionist_evaluate ( ExpressionistHandle handle,
const char *  json_in,
char **  out_json,
char **  out_error 
)

Parses json_in, evaluates it and writes the result to *out_json, returning 0; on failure (malformed JSON, undefined variable, circular dependency, or a NULL handle/json_in), writes a diagnostic message to *out_error instead and returns nonzero. Exactly one of the two out-parameters is set on return, the other is left NULL.

Both are heap-allocated: free whichever was set with expressionist_free_string() once you are done with it.

Parameters
handlea handle from expressionist_create()
json_inUTF-8 JSON document to evaluate
out_jsonset to the evaluated JSON text on success
out_errorset to a diagnostic message on failure
Returns
0 on success, nonzero on failure

◆ expressionist_free_string()

EXPRESSIONIST_C_API void expressionist_free_string ( char *  s)

Frees a string returned via out_json/out_error by expressionist_evaluate(). Accepts NULL.

◆ expressionist_version()

EXPRESSIONIST_C_API const char * expressionist_version ( void  )
Returns
the library version, as a statically-allocated string (do not free it).