tvm_preprocess: update *src after (re)allocating memory

During preprocessing, we find directives, and if they specify including
other source files, we remove the directive, allocate a new block of
memory, copy the first block, append the new source file, and append the
second block.

Previously, the value of the source pointer was passed into the
preprocessing function. When the memory would be (re)allocated, the
pointer value could change, but the original pointer would not be
updated.

Now, the pointer is passed by address, and updated when the memory it
points to changes.
This commit is contained in:
Joseph Kogut 2017-02-12 11:51:06 -08:00
parent b6ffbd9a4e
commit 488b88f867
3 changed files with 30 additions and 34 deletions

View file

@ -3,6 +3,6 @@
#include "tvm_htab.h" #include "tvm_htab.h"
int tvm_preprocess(char *src, int *src_len, struct tvm_htab_ctx *defines); int tvm_preprocess(char **src, int *src_len, struct tvm_htab_ctx *defines);
#endif #endif

View file

@ -45,7 +45,7 @@ int tvm_vm_interpret(struct tvm_ctx *vm, char *filename)
tvm_fcopy(source, source_length, filp); tvm_fcopy(source, source_length, filp);
fclose(filp); fclose(filp);
int err = tvm_preprocess(source, &source_length, vm->prog->defines); int err = tvm_preprocess(&source, &source_length, vm->prog->defines);
/* The preprocessor encountered a problem. */ /* The preprocessor encountered a problem. */
if (err < 0) if (err < 0)

View file

@ -1,27 +1,28 @@
#include <tvm/tvm_preprocessor.h> #include <tvm/tvm_preprocessor.h>
#include <tvm/tvm_tokens.h>
#include <tvm/tvm_file.h> #include <tvm/tvm_file.h>
#include <tvm/tvm_tokens.h>
#include <unistd.h>
#include <string.h> #include <string.h>
static int process_includes( static int process_includes(
char *src, int *src_len, struct tvm_htab_ctx *defines) char **src, int *src_len, struct tvm_htab_ctx *defines)
{ {
char *pp_directive_delimiter = strstr(src, TOK_INCLUDE); char *pp_directive_delimiter = strstr(*src, TOK_INCLUDE);
if (!pp_directive_delimiter) if (!pp_directive_delimiter)
return 0; return 0;
char *strbegin = pp_directive_delimiter, char *begin = pp_directive_delimiter,
*strend = strchr(strbegin, '\n'); *end = strchr(begin, '\n');
if (!strend || !strbegin) if (!end || !begin)
return 0; return 0;
int linelen = strend - strbegin; int linelen = end - begin;
char *temp_str = calloc(linelen + 1, sizeof(char)); char *temp_str = calloc(linelen + 1, sizeof(char));
memcpy(temp_str, strbegin, linelen); memcpy(temp_str, begin, linelen);
char *filename = (strchr(temp_str, ' ') + 1); char *filename = (strchr(temp_str, ' ') + 1);
FILE *filp = tvm_fopen(filename, ".vm", "r"); FILE *filp = tvm_fopen(filename, ".vm", "r");
@ -39,31 +40,26 @@ static int process_includes(
tvm_fcopy(addition_str, addition_len, filp); tvm_fcopy(addition_str, addition_len, filp);
fclose(filp); fclose(filp);
size_t first_block_len = (strbegin - src); size_t first_block_len = (begin - *src);
size_t second_block_len = ((src + *src_len) - strend); size_t second_block_len = ((*src + *src_len) - end);
size_t new_src_len = ( size_t new_src_len = (
first_block_len + addition_len + second_block_len); first_block_len + addition_len + second_block_len);
src = (char *)realloc((char *)src, sizeof(char) * new_src_len); char *new_src = (char *)calloc(sizeof(char), new_src_len);
src[new_src_len] = 0; strncpy(new_src, (*src), first_block_len);
strcat(new_src, addition_str);
strcat(new_src, end+1);
memmove(&src[first_block_len + addition_len], strend, second_block_len); free(*src);
memcpy(&src[first_block_len], addition_str, addition_len); *src = new_src;
*src_len = strlen(*src);
/* Fuckin' hack */
for (int i = 0; i < new_src_len; i++) {
if (src[i] == 0)
src[i] = ' ';
}
*src_len = strlen(src);
return 1; return 1;
} }
static int process_defines( static int process_defines(
char *src, int *src_len, struct tvm_htab_ctx *defines) char **src, int *src_len, struct tvm_htab_ctx *defines)
{ {
char *pp_directive_delimiter = strstr(src, TOK_DEFINE); char *pp_directive_delimiter = strstr(*src, TOK_DEFINE);
if (!pp_directive_delimiter) if (!pp_directive_delimiter)
return 0; return 0;
@ -111,20 +107,20 @@ static int process_defines(
} }
/* Remove the define line so it is not processed again. */ /* Remove the define line so it is not processed again. */
size_t new_length = *src_len - (end - begin); size_t new_src_len = *src_len - (end - begin);
size_t first_block_len = begin - src; size_t first_block_len = begin - *src;
size_t second_block_len = (src + *src_len) - end; size_t second_block_len = (*src + *src_len) - end;
memmove(&src[first_block_len], end, second_block_len); memmove(&(*src)[first_block_len], end, second_block_len);
src = realloc(src, sizeof(char) * new_length); *src = realloc(*src, sizeof(char) * new_src_len);
*src_len = new_length; *src_len = new_src_len;
return 1; return 1;
} }
static int preprocess_pass( static int preprocess_pass(
char *src, int *src_len, struct tvm_htab_ctx *defines) char **src, int *src_len, struct tvm_htab_ctx *defines)
{ {
int ret = 0; int ret = 0;
@ -134,7 +130,7 @@ static int preprocess_pass(
} }
int tvm_preprocess(char *src, int *src_len, struct tvm_htab_ctx *defines) int tvm_preprocess(char **src, int *src_len, struct tvm_htab_ctx *defines)
{ {
int ret = 1; int ret = 1;