Previous: Side Effects Operators, Up: Infix Binary Operators
For all its usefulness, the libx1f4i0 infix binary operators set does not provide the string attribution operator. That is due to the operator requirements: it needs to allocate memory to make a copy of its right side operand and just as well, it needs to free the memory reserved by its left side operand (just before setting it to the copy of the right side). And it needs to allocate and free memory with respect to the application memory management policies. In turn, the memory operations are due to the immediate character of the intrinsic string type: data of this type is exactly what it appears to be and no fancy management mechanism is tracking it.
See C Infix Binary Operators Set.
The intrinsic string attribution operator is to be defined much like any infix operator, with the necessary amendments.
See Infix Operator Definition Example.
See struct x1f4_operator_type.
The definition of operator:
const struct x1f4_operator_type tset = { "=", text_set, 0400, X1f4_E4_TEXT, text2, X1f4_E4_LEFT_XSET, 1, NULL, NULL };
The priority
field specifies the operator evaluation priority - it is
here set to match the priority of attribution operators in the libx1f4i0
infix binary operators set.
The args
field specifies the types of the operator arguments and is
assumed defined as:
int text2[] = { X1f4_E4_TEXT, X1f4_E4_TEXT };
The flags
field specifies this operator sets its left operand and thus
is set as X1f4_E4_LEFT_XSET
. Without this bit in flags
definition the attribution will fail.
The routine performing the operator logic may be something like:
static int text_set(void *context, void *output, void **input) { char *text_0, *text_1; int status; text_0 = *(X1f4_E4_TEXT *) input[0]; text_1 = *(X1f4_E4_TEXT *) input[1];
Some code around libx1f4i0 library uses a special definition for empty
string: x1f4_c1_empty_string
- a constant empty string.
See x1f4_c1_empty_string.
If the right side operand has this value there is no need to allocate a new string, just set the left side operand to this value. Set output as well.
if (text_1 == x1f4_c1_empty_string) { char **out; out = output; *out = text_1; out = input[0]; *out = text_1; if (text_0 != x1f4_c1_empty_string) { free left side operand and set the operation status accordingly status = ...; } else { status = 0; } } else {
Otherwise, make a copy of right side operand, free left side operand, set left side operand and output to the made copy.
unsigned length; void *string; length = strlen(text_1) + 1; allocate at least _length_ bytes for the copy, set operation status to indicate how it all went if (status) { } else { char **out; memcpy(string, text_1, length); out = output; *out = string; out = input[0]; *out = string; if (text_0 != x1f4_c1_empty_string) { free left side operand and set the operation status accordingly status = ...; } }
Copy made (or at least the failure is so indicated).
}
Indicate to the surrounding code how it all went, 0 for success, non zero for failure.
return status; }
If memory is to be allocated and free via malloc
and free
the
routine may be written as:
static int text_set(void *context, void *output, void **input) { char *text_0, *text_1; int status; text_0 = *(X1f4_E4_TEXT *) input[0]; text_1 = *(X1f4_E4_TEXT *) input[1]; if (text_1 == x1f4_c1_empty_string) { char **out; out = output; *out = text_1; out = input[0]; *out = text_1; status = 0; if (text_0 != x1f4_c1_empty_string) { free(text_0); } } else { unsigned length; void *string; length = strlen(text_1) + 1; string = malloc(length); if (!string) { status = -1; } else { char **out; memcpy(string, text_1, length); out = output; *out = string; out = input[0]; *out = string; status = 0; if (text_0 != x1f4_c1_empty_string) { free(text_0); } } } return status; }