68 lines
2.2 KiB
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;
|
|
}
|
|
}
|