#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: "" // 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(, ) // 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; } }