cutes/variant.c

68 lines
2.2 KiB
C

#include "variant.h"
#include "ctype.h"
#include "mirror.h"
#include "string.h"
#include "strutil.h"
#include "drop.h"
#include "debug.h"
Variant variant_from_str(const char* str) {
size_t length = strlen(str);
if(isdigit(str[0])) {
// variant is a number
// convert to double
return NumberVariant(atof(str));
} else if(str[0] == '"') {
// variant should be a string
// format: "<content>"
// copy the input string without the quotes
size_t result_length = strfirst(str+1, str+length, '"');
char* string = malloc(result_length);
strncpy(string, str+1, result_length-1);
string[result_length] = '\0';
return StringVariant(string, result_length);
} else if(strncmp(str, "Vector(", 7) == 0) {
// variant is a vector
// format: Vector(<x>, <y>)
// get the location of the brackets
long close_bracket = strfirst(str, str + length, ')');
if(close_bracket == -1) goto variant_from_str_err;
char buf[24]; buf[23] = '\0';
// copy what is within the brackets
// 7 is the number of characters in "Vector(", which should be skipped
strncpy(buf, str + 7, close_bracket - 7);
length = strlen(buf);
long comma_ind = strfirst(buf, buf+length, ',');
if(comma_ind == -1) goto variant_from_str_err;
// split the string at the comma by inserting a null terminator
buf[comma_ind] = '\0';
return VectorVariant(MakeVector(atof(buf), atof(buf + comma_ind + 1)));
}
variant_from_str_err:
return UndefinedVariant();
}
void destroy_variant(Variant* self) {
destroy_contained(self);
free(self);
}
void destroy_contained(Variant* self) {
switch(self->type) {
default: break;
case Variant_String:
if(self->as_string != NULL)
free(self->as_string);
self->as_string = NULL;
break;
case Variant_Object:
if(TC_MIRRORS(self->as_object, Drop)) {
Drop drop = TC_CAST(self->as_object, Drop);
drop.tc->drop(drop.data);
}
self->as_object.data = NULL;
self->as_object.tc = NULL;
break;
}
}