#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum VTYPE {VSTRING, VINT, VFLOAT};
typedef enum VTYPE vtype;
struct Value {
   vtype typ;
   /*
   type=1  ==> get vstring
   type=2  ==> get int
   type=3  ==> get float
   */
   union {
   	char *vstring;
   	int   vint;
   	float  vfloat;
   };
};

void clear(struct Value* vall){
   if (vall->typ == VSTRING){
      free(vall->vstring);
   }
   memset(vall, 0, sizeof(*vall));
}

void print_value(struct Value *v)
{
	static const char *types[] = {"VSTRING", "VINT", "VFLOAT"};
	printf( "ValueType : %s\n", v->typ >= 0 && v->typ < 3 ? types[v->typ] : "ERROR");
	if (VSTRING == v->typ) {
    	printf( "ValueString : %s\n", v->vstring);
	}
	else if (VINT == v->typ) {
    	printf( "ValueInt : %d\n", v->vint);
	}
	else if (VFLOAT == v->typ) {
    	printf( "ValueFloat : %f\n", v->vfloat);
	}
}

void copy_value(struct Value *source, struct Value *dest) {
	if (VSTRING == source->typ) {
    	dest->vstring = malloc(strlen(source->vstring) + 1);
    	strcpy(dest->vstring, source->vstring);
	}
	else if (VINT == source->typ) {
    	dest->vint = source->vint;
	}
	else if (VFLOAT == source->typ) {
    	dest->vfloat = source->vfloat;
	}
	dest->typ = source->typ;
}

int main()
{
	const char *msg = "C Programming/may this a very big utf-8 string!";
   struct Value v;
   /////////////////////////////////////////////
   v.typ=VSTRING;
   v.vstring = malloc(strlen(msg) + 1);
   strcpy(v.vstring, msg);
   print_value(&v);
   

	struct Value copy;
	copy_value(&v, &copy);
	print_value(&copy);
   clear(&copy);
   copy.typ=VINT;
   copy.vint=5;
   print_value(&copy);
   
   clear(&v);
}
