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.
int | jx_match_integer (struct jx *j, jx_int_t *v) __wur
| Unwrap an integer value.
int | jx_match_double (struct jx *j, double *v) __wur
| Unwrap a double value.
int | jx_match_string (struct jx *j, char **v) __wur
| Unwrap a string value.
int | jx_match_symbol (struct jx *j, char **v) __wur
| Unwrap a symbol value.
int | jx_match_array (struct jx *j,...) __wur __sentinel
| Destructure an array.

## 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");
}
jx_match_double
int jx_match_double(struct jx *j, double *v) __wur
Unwrap a double value.

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");
}
JX_INTEGER
@ JX_INTEGER
integer value
Definition jx.h:46
JX_DOUBLE
@ JX_DOUBLE
floating point value
Definition jx.h:47
jx_match_array
int jx_match_array(struct jx *j,...) __wur __sentinel
Destructure an array.

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;
}
}
jx_istype
int jx_istype(struct jx *j, jx_type_t type)
Test an expression's type.
JX_ARRAY
@ JX_ARRAY
array containing values
Definition jx.h:50
JX_STRING
@ JX_STRING
string value
Definition jx.h:48
jx_match_integer
int jx_match_integer(struct jx *j, jx_int_t *v) __wur
Unwrap an integer value.
jx
JX value representing any expression type.
Definition jx.h:117

## Function Documentation

## jx_match_boolean()

int jx_match_boolean | ( | struct jx * | j,
|  | int * | v )

Unwrap a boolean value.

Parameters

  j | The JX structure to match.
  v | An 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.

## jx_match_integer()

int jx_match_integer | ( | struct jx * | j,
|  | jx_int_t * | v )

Unwrap an integer value.

Parameters

  j | The JX structure to match.
  v | An 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.

## jx_match_double()

int jx_match_double | ( | struct jx * | j,
|  | double * | v )

Unwrap a double value.

Parameters

  j | The JX structure to match.
  v | An 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.

## jx_match_string()

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);
}
jx_match_string
int jx_match_string(struct jx *j, char **v) __wur
Unwrap a string value.

Parameters

  j | The JX structure to match.
  v | The 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.

## jx_match_symbol()

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

  j | The JX structure to match.
  v | The 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.

## jx_match_array()

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

  j | The JX structure to match.

Returns
  The number of elements successfully matched.