From 3398729ab8ba5b208114fab6cf782ab7462c76c3 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Thu, 24 Mar 2022 23:07:34 -0400 Subject: [PATCH] Track length of stringObj(). Use this to simplify catObjects(). --- src/object.c | 77 ++++++++++++++++++++++++++++++++-------------------- src/object.h | 4 +-- src/plfunc.c | 14 ++++------ 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/object.c b/src/object.c index ebce459..e9251bc 100644 --- a/src/object.c +++ b/src/object.c @@ -262,51 +262,59 @@ static const char* errorText[] = {"MISMATCHED_PARENS", * @param dest The string to copy the list text into * @param obj The list Object to make a string from */ -void stringList(char* dest, const Object* obj) +int stringList(char* dest, const Object* obj) { if (!dest || !isListy(*obj)) { - return; + return 0; } dest[0] = '('; dest[1] = '\0'; + int length = 1; FOR_POINTER_IN_LIST(obj) { strcat(dest, " "); + length += 1; char tok[90] = ""; - stringObj(tok, POINTER); + length += stringObj(tok, POINTER); strcat(dest, tok); } strcat(dest, " )"); + length += 2; + return length; } /** * Creates a string from a given struct Object * Blocks out with curly braces */ -void stringStruct(char* dest, const Object* obj) +int stringStruct(char* dest, const Object* obj) { struct StructObject* so = obj->structObject; dest[0] = '{'; dest[1] = '\0'; + int length = 1; for (int i = 0; i < global()->structDefs[so->definition].fieldCount; i++) { strcat(dest, " "); strcat(dest, global()->structDefs[so->definition].names[i]); strcat(dest, ": "); + length += 3; int isString = so->fields[i].type == TYPE_STRING; if (isString) { strcat(dest, "\""); } char tok[90] = ""; - stringObj(tok, &so->fields[i]); + length += stringObj(tok, &so->fields[i]); strcat(dest, tok); if (isString) { strcat(dest, "\""); + length += 1; } strcat(dest, ","); + length += 1; } int i = 0; while (dest[i]) { @@ -314,7 +322,9 @@ void stringStruct(char* dest, const Object* obj) } dest[i - 1] = ' '; dest[i + 0] = '}'; + length += 2; dest[i + 1] = '\0'; + return length; } /** * Creates a string from a given Object @@ -338,79 +348,88 @@ void stringStruct(char* dest, const Object* obj) #define stringf(_dest, _len, _format, args...) snprintf(_dest, _len, _format, ## args) #endif -char* stringNObj(char* dest, const Object* obj, const size_t len) +int stringNObj(char* dest, const Object* obj, const size_t len) { + int size = 0; if (!dest || !obj) { - return NULL; + return 0; } switch (obj->type) { case TYPE_NUMBER: - stringf(dest, len, "%d", obj->number); + size += stringf(dest, len, "%d", obj->number); break; case TYPE_BOOL: - stringf(dest, len, "%s", obj->number ? "T" : "F"); + size += stringf(dest, len, "%s", obj->number ? "T" : "F"); break; case TYPE_STRING: - stringf(dest, len, "%s", obj->string); + size += stringf(dest, len, "%s", obj->string); break; case TYPE_SYMBOL: - stringf(dest, len, "`%s`", obj->string); + size += stringf(dest, len, "`%s`", obj->string); break; case TYPE_STRUCT: //snprintf(dest, len, "{%s}", obj->structObject->definition->names[0]); - stringStruct(dest, obj); + size += stringStruct(dest, obj); break; case TYPE_LIST: case TYPE_SLIST: - stringList(dest, obj); + size += stringList(dest, obj); break; case TYPE_ERROR: { int code = getErrorCode(*obj); #ifdef SIMPLE_ERRORS - stringf(dest, len, "E[%d]", (int)code); + size += stringf(dest, len, "E[%d]", (int)code); #else if (obj->error->context && obj->error->context[0] != '\0') { - stringf(dest, len, "'%s': %s", errorText[code], - obj->error->context); + size += stringf(dest, len, "'%s': %s", errorText[code], + obj->error->context); } else if (code >= 0 && code <= INDEX_PAST_END) { - stringf(dest, len, "%s", errorText[code]); + size += stringf(dest, len, "%s", errorText[code]); } else { - stringf(dest, len, "BROKEN ERROR CODE: %d", code); + size += stringf(dest, len, "BROKEN ERROR CODE: %d", code); } #endif break; } case TYPE_FUNC: - stringf(dest, len, "F%d", obj->number); + size += stringf(dest, len, "F%d", obj->number); break; - case TYPE_LAMBDA: + case TYPE_LAMBDA: { #ifdef STANDALONE - dest += stringf(dest, len, "\\x%d", obj->number); - stringNObj(dest, &obj->lambda->params, len); - dest += strlen(dest); + int n = stringf(dest, len, "\\x%d", obj->number); + dest += n; + size += n; + n = stringNObj(dest, &obj->lambda->params, len); + dest += n; + size += n; strcat(dest, " -> "); dest += 4; - stringNObj(dest, &obj->lambda->body, len); + size += 4; + n = stringNObj(dest, &obj->lambda->body, len); + size += n; + dest += n; dest += strlen(dest); strcat(dest, ">"); + size += 1; #else - stringf(dest, len, "\\x%d", obj->number); + size += stringf(dest, len, "\\x%d", obj->number); #endif break; + } case TYPE_OTHER: - stringf(dest, len, "%p", obj->other->data); + size += stringf(dest, len, "%p", obj->other->data); break; } if (!isValidType(*obj)) { - stringf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); + size += stringf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); } - return dest; + return size; } -char* stringObj(char* dest, const Object* obj) +int stringObj(char* dest, const Object* obj) { return stringNObj(dest, obj, RESULT_LENGTH); } diff --git a/src/object.h b/src/object.h index ea9059e..c19a04d 100644 --- a/src/object.h +++ b/src/object.h @@ -140,9 +140,9 @@ struct Other { void* data; }; -char* stringNObj(char* dest, const Object* obj, size_t len); +int stringNObj(char* dest, const Object* obj, size_t len); -char* stringObj(char* dest, const Object* obj); +int stringObj(char* dest, const Object* obj); void printList(const Object* list); diff --git a/src/plfunc.c b/src/plfunc.c index 295e50b..1577e48 100644 --- a/src/plfunc.c +++ b/src/plfunc.c @@ -194,22 +194,18 @@ Object _catObjects(Object obj1, Object obj2, struct Environment* env) { Object evalObj1 = eval(&obj1, env); Object evalObj2 = eval(&obj2, env); - if (isError(evalObj2, ONLY_ONE_ARGUMENT)) { - return evalObj1; - } char str1[CAT_MAX] = ""; char str2[CAT_MAX] = ""; - stringObj(str1, &evalObj1); - stringObj(str2, &evalObj2); + int length = stringObj(str1, &evalObj1); + length += stringObj(str2, &evalObj2); + cleanObject(&evalObj1); cleanObject(&evalObj2); - size_t strLength = strlen(str1) + strlen(str2) + 1; Object o = newObject(TYPE_STRING); - o.string = calloc(sizeof(char), strLength); - strcat(o.string, str1); - strcat(o.string, str2); + o.string = malloc(sizeof(char) * length + 1); + sprintf(o.string, "%s%s", str1, str2); return o; }