cctools
Functions
jx_match.h File Reference

Unwrap JX types. More...

#include "jx.h"

Go to the source code of this file.

Functions

int jx_match_boolean (struct jx *j, int *v) __wur
 Unwrap a boolean value. More...
 
int jx_match_integer (struct jx *j, jx_int_t *v) __wur
 Unwrap an integer value. More...
 
int jx_match_double (struct jx *j, double *v) __wur
 Unwrap a double value. More...
 
int jx_match_string (struct jx *j, char **v) __wur
 Unwrap a string value. More...
 
int jx_match_symbol (struct jx *j, char **v) __wur
 Unwrap a symbol value. More...
 
int jx_match_array (struct jx *j,...) __wur __sentinel
 Destructure an array. More...
 

Detailed Description

Unwrap JX types.

The functions in this header are intended to make JX types more usable from C code. All unwrap JX values in some manner, allowing access to native C types. For the arrays, the match function can be used to destructure its arguments, extracting and type-checking components in a single call. The match functions for single values return an int indicating the result of the match. On match failure, 0 is returned, or 1 on success. The match functions can also give the caller a copy of the matched value. For heap-allocated types, the caller is responsible for free()ing/jx_delete()ing the copied values. In the case that the caller requested a heap-allocated copy but malloc() fails, the match as a whole will fail. This ensures that it is always safe to dereference the copy given back, but might falsely indicate an incorrect type. Code that needs to run in out of memory conditions must not request copies.

The common use case is that programs will have some stack allocated variables for local use, and would like to read the value in a JX struct.

double val;
if (jx_match_double(j, &val)) {
printf("got value %f\n", val);
} else {
printf("not a valid double\n");
}

Here, the return value is used to check that the given JX struct was in fact a double, and to copy the value onto the local function's stack. If a function needs to modify the JX structure, it must access the struct fields directly.

There is also a matching function to extract multiple positional values from an array and validate types in a single call. This function has a scanf()-like interface. The array matching function takes a JX struct and a sequence of item specifications. Each item spec includes a JX type and the location of a pointer that will reference the extracted value. The match function processes each specification in turn, stopping on an invalid spec, or NULL, and returning the number of items succesfully matched.

jx_int_t a;
double b;
switch (jx_match_array(j, &a, JX_INTEGER, &b, JX_DOUBLE, NULL)) {
case 1:
printf("got int %d\n", a);
case 2:
printf("got %d and %f\n", a, b)
default:
printf("bad match\n");
}

It's also possible to match on a position without looking at the type of the matched value. The pseudo-type JX_ANY is provided for this purpose. Since the type of the value matched by JX_ANY is unknown, the caller might want to use the other match functions to handle whatever cases they're interested in. The following example uses most of the matching functionality.

struct jx *a;
struct jx *b;
if (jx_match_array(j, &a, JX_ARRAY, &b, JX_ANY, NULL) == 2) {
printf("got JX_ARRAY at %p\n", a);
if (jx_istype(b, JX_STRING)) {
printf("no longer supported\n");
return 0;
}
jx_int_t val;
if (jx_match_integer(b, &val)) {
return val % 8;
}
}

Function Documentation

int jx_match_boolean ( struct jx j,
int *  v 
)

Unwrap a boolean value.

Parameters
jThe JX structure to match.
vAn address to copy the boolean value to, or NULL if copying the value is unnecessary.
Returns
A truth value indicating the result of the match.
int jx_match_integer ( struct jx j,
jx_int_t *  v 
)

Unwrap an integer value.

Parameters
jThe JX structure to match.
vAn address to copy the integer value to, or NULL if copying the value is unnecessary.
Returns
A truth value indicating the result of the match.
int jx_match_double ( struct jx j,
double *  v 
)

Unwrap a double value.

Parameters
jThe JX structure to match.
vAn address to copy the double value to, or NULL if copying the value is unnecessary.
Returns
A truth value indicating the result of the match.
int jx_match_string ( struct jx j,
char **  v 
)

Unwrap a string value.

Since C strings are just pointers to char arrays, the interface here is a little awkward. If the caller has a stack-allocated (char *), this function can allocate a copy of the string value and store the address in the caller's pointer variable, e.g.

char *val;
if (jx_match_string(j, &val)) {
printf("got value %s\n", val);
}
Parameters
jThe JX structure to match.
vThe address of a (char *) in which to store the address of the newly malloc()ed string, or NULL if copying the value is unnecessary.
Returns
A truth value indicating the result of the match.
int jx_match_symbol ( struct jx j,
char **  v 
)

Unwrap a symbol value.

This function accesses the symbol name as a string. See jx_match_string for details.

Parameters
jThe JX structure to match.
vThe address of a (char *) in which to store the address of the newly malloc()ed symbol name, or NULL if copying the value is unnecessary.
Returns
A truth value indicating the result of the match.
int jx_match_array ( struct jx j,
  ... 
)

Destructure an array.

This function accepts an arbitrary number of positional specifications to attempt to match. Each specification is of the form

`<address>`, `<jx type>`

where <jx type> is JX_INTEGER, JX_ANY, etc. and <address> is the address to store the matched value. The last argument must be NULL to mark the end of the specifications. The specifications will be matched in the order given, and matching ends on the first failure. If the JX value passed in was not an array, this is considered a failure before any matches succeed, so 0 is returned.

Parameters
jThe JX structure to match.
Returns
The number of elements successfully matched.