Allocate a string buffer as needed in the code generator and vvp display code
When sending a string to a system task/function allocate the space needed to avoid truncating the string vs using a large fixed buffer. In vvp allocate and use an exactly sized buffer for the MCD print routine if the fixed buffer is not large enough. Using a fixed buffer keeps normal printing fast.
This commit is contained in:
parent
f5aafc32f9
commit
faf456ee7e
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2012 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -332,11 +332,14 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
|||
case IVL_EX_STRING:
|
||||
if (( par = ivl_expr_parameter(expr) )) {
|
||||
snprintf(buffer, sizeof buffer, "P_%p", par);
|
||||
args[idx].text = strdup(buffer);
|
||||
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "\"%s\"", ivl_expr_string(expr));
|
||||
size_t needed_len = strlen(ivl_expr_string(expr)) + 3;
|
||||
args[idx].text = malloc(needed_len);
|
||||
snprintf(args[idx].text, needed_len, "\"%s\"",
|
||||
ivl_expr_string(expr));
|
||||
}
|
||||
args[idx].text = strdup(buffer);
|
||||
continue;
|
||||
|
||||
case IVL_EX_REALNUM:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2010 Stephen G. Tell <steve@telltronics.org>
|
||||
* Copyright (c) 2000-2012 Stephen G. Tell <steve@telltronics.org>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -178,7 +178,9 @@ extern "C" PLI_INT32
|
|||
vpi_mcd_vprintf(PLI_UINT32 mcd, const char*fmt, va_list ap)
|
||||
{
|
||||
char buffer[4096];
|
||||
char *buf_ptr = buffer;
|
||||
int rc = 0;
|
||||
bool need_free = false;
|
||||
|
||||
if (!IS_MCD(mcd)) return 0;
|
||||
|
||||
|
|
@ -196,19 +198,34 @@ vpi_mcd_vprintf(PLI_UINT32 mcd, const char*fmt, va_list ap)
|
|||
#else
|
||||
rc = vsnprintf(buffer, sizeof buffer, fmt, ap);
|
||||
#endif
|
||||
assert(rc >= 0);
|
||||
/*
|
||||
* If rc is greater than sizeof buffer then the result was truncated
|
||||
* so the print needs to be redone with a larger buffer (very rare).
|
||||
*/
|
||||
if ((unsigned) rc >= sizeof buffer) {
|
||||
buf_ptr = (char *)malloc(rc + 1);
|
||||
need_free = true;
|
||||
#ifdef __MINGW32__
|
||||
rc = _vsnprintf(buf_ptr, rc+1, fmt, ap);
|
||||
#else
|
||||
rc = vsnprintf(buf_ptr, rc+1, fmt, ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(int i = 0; i < 31; i++) {
|
||||
if((mcd>>i) & 1) {
|
||||
if(mcd_table[i].fp) {
|
||||
// echo to logfile
|
||||
if (i == 0 && logfile)
|
||||
fputs(buffer, logfile);
|
||||
fputs(buffer, mcd_table[i].fp);
|
||||
fputs(buf_ptr, logfile);
|
||||
fputs(buf_ptr, mcd_table[i].fp);
|
||||
} else {
|
||||
rc = EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (need_free) free(buf_ptr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue