From 50ece95a69699f90862947ce0450c8f9360d3660 Mon Sep 17 00:00:00 2001 From: Yaakov Saxon Date: Thu, 9 May 2024 15:58:57 -0400 Subject: [PATCH] improve parsing of special chars in chars and strings --- main.c | 2 +- types_and_utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index a1b0396..f4b7cbe 100644 --- a/main.c +++ b/main.c @@ -46,7 +46,7 @@ #include "shims.h" const char* NAME = "cliffi"; -const char* VERSION = "v1.10.16"; +const char* VERSION = "v1.10.17"; const char* BASIC_USAGE_STRING = " [[-typeflag] .. [ ... ..] ]\n"; sigjmp_buf jmpBuffer; diff --git a/types_and_utils.c b/types_and_utils.c index 9d4a906..7c3dd95 100644 --- a/types_and_utils.c +++ b/types_and_utils.c @@ -11,6 +11,7 @@ #include #include + char* trim_whitespace(char* str) // https://stackoverflow.com/a/122974 { @@ -60,6 +61,81 @@ char* trim_whitespace(char* str) return str; } + +char interpret_special_char(const char* str) { + if (str[0] == '\\') { + if (str[1] == 'n') { + return '\n'; + } else if (str[1] == 't') { + return '\t'; + } else if (str[1] == '\\') { + return '\\'; + } else if (str[1] == '0') { + return '\0'; + } else if (str[1] == 'r') { + return '\r'; + } else if (str[1] == 'x' && isxdigit(str[2]) && isxdigit(str[3])) { + char hex[3] = {str[2], str[3], '\0'}; + return (char)strtoul(hex, NULL, 16); + } + } + return str[0]; +} + +char* interpret_special_chars(const char* str) { + size_t len = strlen(str); + char* result = malloc(len + 1); + + size_t i, j; + for (i = 0, j = 0; i < len; i++) { + if (str[i] == '\\') { + if (i + 1 < len) { + switch (str[i + 1]) { + case 'n': + result[j++] = '\n'; + i++; + break; + case 't': + result[j++] = '\t'; + i++; + break; + case '\\': + result[j++] = '\\'; + i++; + break; + // case '0': + // result[j++] = '\0'; + // i++; + // break; + case 'r': + result[j++] = '\r'; + i++; + break; + case 'x': + if (i + 3 < len && isxdigit(str[i + 2]) && isxdigit(str[i + 3])) { + char hex[3] = {str[i + 2], str[i + 3], '\0'}; + result[j++] = (char)strtoul(hex, NULL, 16); + i += 3; + } else { + result[j++] = str[i]; + } + break; + default: + result[j++] = str[i]; + break; + } + } else { + result[j++] = str[i]; + } + } else { + result[j++] = str[i]; + } + } + + result[j] = '\0'; + return realloc(result, j + 1); +} + void* makePointerLevel(void* value, int pointer_depth) { for (int i = 0; i < pointer_depth; i++) { void* temp = malloc(sizeof(void*)); // Allocate memory for each level of indirection @@ -258,7 +334,7 @@ void* convert_to_type(ArgType type, const char* argStr) { if (isHexFormat(argStr)) { *(char*)result = (char)strtoul(argStr, NULL, 0); } else { - *(char*)result = argStr[0]; + *(char*)result = interpret_special_char(argStr); } break; case TYPE_SHORT: @@ -283,7 +359,7 @@ void* convert_to_type(ArgType type, const char* argStr) { *(void**)result = getAddressFromAddressStringOrNameOfCoercableVariable(argStr); break; case TYPE_STRING: - *(char**)result = strdup(argStr); + *(char**)result = interpret_special_chars(argStr); break; default: free(result);