1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include <iso646.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
/* Variant Binary Tree */
/*---------------------------------------------------------------------------*/
/*
Each node may contain the following value types:
• Integer
• Floating Point Double
• Double-quoted string
(anything following a backslash '\' is treated literally).
*/
typedef enum { int_type, float_type, string_type } node_type;
typedef struct node_type
{
node_type type;
union
{
int _int;
double _float;
char* _string;
}
value;
struct node_type* left;
struct node_type* right;
}
Node;
/* not for use by user */
void Node_ClearNode(Node* node)
{
if (node)
{
switch (node->type)
{
case int_type:
case float_type:
break;
case string_type:
free( node->value._string );
node->value._string = NULL;
break;
}
}
}
/* not for use by user */
void Node_SetNode(Node* node, node_type type, const void* value)
{
if (node)
{
Node_ClearNode(node);
node->type = type;
switch (type)
{
case int_type: node->value._int = value ? *(int*) value : 0; break;
case float_type: node->value._float = value ? *(double*)value : 0.0; break;
case string_type: node->value._string = value ? strdup((const char*)value) : NULL; break;
}
}
}
/* not for use by user */
Node* Node_CreateNode(node_type type, const void* value, Node* left, Node* right)
{
Node* node = malloc(sizeof(Node));
node->type = int_type;
Node_SetNode(node, type, value);
node->left = left;
node->right = right;
return node;
}
/* USER API :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* Get and set a node's value */
void SetIntNode (Node* node, int n) { Node_SetNode(node, int_type, &n); }
void SetFloatNode (Node* node, double x) { Node_SetNode(node, float_type, &x); }
void SetStringNode(Node* node, const char* s) { Node_SetNode(node, string_type, s); }
node_type GetNodeType(Node* node) { return node ? node->type : 0; }
int GetIntNode (Node* node) { return GetNodeType(node) == int_type ? node->value._int : 0; }
float GetFloatNode (Node* node) { return GetNodeType(node) == float_type ? node->value._float : 0.0; }
char* GetStringNode(Node* node) { return GetNodeType(node) == string_type ? node->value._string : NULL; }
/* Create a new node or tree */
Node* CreateIntNode (int n) { return Node_CreateNode(int_type, &n, NULL, NULL); }
Node* CreateFloatNode (double x) { return Node_CreateNode(float_type, &x, NULL, NULL); }
Node* CreateStringNode(const char* s) { return Node_CreateNode(string_type, s, NULL, NULL); }
Node* CreateIntNodes (int n, Node* left, Node* right) { return Node_CreateNode(int_type, &n, left, right); }
Node* CreateFloatNodes (double x, Node* left, Node* right) { return Node_CreateNode(float_type, &x, left, right); }
Node* CreateStringNodes(const char* s, Node* left, Node* right) { return Node_CreateNode(string_type, s, left, right); }
/* Destroy a tree */
void DeleteNodes(Node* node)
{
if (node)
{
Node_ClearNode(node);
DeleteNodes(node->left);
DeleteNodes(node->right);
free(node);
}
}
|