2011-12-13 20:57:45 +01:00
|
|
|
/* -----------------------------------------------------------------
|
2019-11-27 02:59:56 +01:00
|
|
|
FILE: dstring.c
|
2010-03-25 23:44:37 +01:00
|
|
|
DESCRIPTION:This file contains the routines for manipulating dynamic strings.
|
|
|
|
|
----------------------------------------------------------------- */
|
2019-11-27 02:59:56 +01:00
|
|
|
#include <ctype.h>
|
2010-03-25 23:44:37 +01:00
|
|
|
#include <stdarg.h>
|
2019-11-27 02:59:56 +01:00
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/dstring.h"
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
#include "ngspice/alloc.h"
|
2010-03-25 23:44:37 +01:00
|
|
|
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
static int ds_reserve_internal(DSTRING *p_ds,
|
|
|
|
|
size_t n_byte_alloc_opt, size_t n_byte_alloc_min);
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Instantiations of dstring functions in case inlining is not performed */
|
|
|
|
|
int ds_cat_str(DSTRING *p_ds, const char *sz);
|
|
|
|
|
int ds_cat_char(DSTRING *p_ds, char c);
|
|
|
|
|
int ds_cat_ds(DSTRING *p_ds_dst, const DSTRING *p_ds_src);
|
|
|
|
|
int ds_cat_mem(DSTRING *p_ds, const char *p_src, size_t n_char);
|
|
|
|
|
int ds_set_length(DSTRING *p_ds, size_t length);
|
|
|
|
|
void ds_clear(DSTRING *p_ds);
|
|
|
|
|
char *ds_free_move(DSTRING *p_ds, unsigned int opt);
|
|
|
|
|
char *ds_get_buf(DSTRING *p_ds);
|
|
|
|
|
size_t ds_get_length(const DSTRING *p_ds);
|
|
|
|
|
size_t ds_get_buf_size(const DSTRING *p_ds);
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
/* This function initalizes a dstring using *p_buf as the initial backing
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Parameters
|
|
|
|
|
* p_buf: Inital buffer backing the dstring
|
|
|
|
|
* length_string: Length of string in the initial buffer
|
|
|
|
|
* n_byte_data: Length of initial buffer. Must be at least 1
|
|
|
|
|
* type_buffer: Type of buffer providing initial backing
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Return codes
|
|
|
|
|
* DS_E_OK: Init OK
|
|
|
|
|
* DS_E_INVALID: n_byte_data = 0 length_string too long,
|
|
|
|
|
* or unknown buffer type
|
2010-03-25 23:44:37 +01:00
|
|
|
*/
|
2019-11-27 02:59:56 +01:00
|
|
|
int ds_init(DSTRING *p_ds, char *p_buf, size_t length_string,
|
|
|
|
|
size_t n_byte_buf, ds_buf_type_t type_buffer)
|
2010-03-25 23:44:37 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Validate buffer size */
|
|
|
|
|
if (n_byte_buf == 0) {
|
|
|
|
|
return DS_E_INVALID;
|
|
|
|
|
}
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Set current buffer */
|
|
|
|
|
p_ds->p_buf = p_buf;
|
|
|
|
|
|
|
|
|
|
/* Set size of current string >= rather than > because this function
|
|
|
|
|
* adds a terminating null */
|
|
|
|
|
if (length_string >= n_byte_buf) {
|
|
|
|
|
return DS_E_INVALID;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
p_ds->n_byte_alloc = n_byte_buf;
|
|
|
|
|
p_ds->length = length_string;
|
|
|
|
|
p_ds->p_buf[length_string] = '\0';
|
|
|
|
|
|
|
|
|
|
/* Set stack buffer */
|
|
|
|
|
if (type_buffer == ds_buf_type_stack) {
|
|
|
|
|
p_ds->p_stack_buf = p_buf;
|
|
|
|
|
p_ds->n_byte_stack_buf = n_byte_buf;
|
|
|
|
|
}
|
|
|
|
|
else if (type_buffer == ds_buf_type_heap) {
|
|
|
|
|
p_ds->p_stack_buf = (char *) NULL;
|
|
|
|
|
p_ds->n_byte_stack_buf = 0;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
else { /* unknown buffer type */
|
|
|
|
|
return DS_E_INVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
} /* end of function ds_init */
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This function frees all memory used by the dstring. After calling this
|
|
|
|
|
* function, the dstring should not be used again. */
|
|
|
|
|
void ds_free(DSTRING *p_ds)
|
|
|
|
|
{
|
|
|
|
|
if (p_ds->p_buf != p_ds->p_stack_buf) {
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
txfree((void *) p_ds->p_buf);
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
} /* end of function ds_free */
|
2010-03-25 23:44:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Concatenate string */
|
|
|
|
|
int ds_cat_str_case(DSTRING *p_ds, const char *sz, ds_case_t case_type)
|
|
|
|
|
{
|
|
|
|
|
return ds_cat_mem_case(p_ds, sz, strlen(sz), case_type);
|
|
|
|
|
} /* end of function ds_cat_str_case */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Concatenate character */
|
|
|
|
|
int ds_cat_char_case(DSTRING *p_ds, char c, ds_case_t case_type)
|
|
|
|
|
{
|
|
|
|
|
return ds_cat_mem_case(p_ds, &c, 1, case_type);
|
|
|
|
|
} /* end of function ds_cat_char_case */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Concatenate another dstring */
|
|
|
|
|
int ds_cat_ds_case(DSTRING *p_ds_dst, const DSTRING *p_ds_src,
|
|
|
|
|
ds_case_t case_type)
|
|
|
|
|
{
|
|
|
|
|
return ds_cat_mem_case(p_ds_dst, p_ds_src->p_buf, p_ds_src->length,
|
|
|
|
|
case_type);
|
|
|
|
|
} /* end of function ds_cat_ds_case */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* General concatenation of a memory buffer. A terminating null is added. */
|
|
|
|
|
int ds_cat_mem_case(DSTRING *p_ds, const char *p_src, size_t n_char,
|
|
|
|
|
ds_case_t type_case)
|
2012-12-09 13:27:53 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Resize buffer if necessary. Double required size, if available,
|
|
|
|
|
* to reduce the number of allocations */
|
|
|
|
|
const size_t length_new = p_ds->length + n_char;
|
|
|
|
|
const size_t n_byte_needed = length_new + 1;
|
|
|
|
|
if (n_byte_needed > p_ds->n_byte_alloc) {
|
|
|
|
|
if (ds_reserve_internal(p_ds,
|
|
|
|
|
2 * n_byte_needed, n_byte_needed) == DS_E_NO_MEMORY) {
|
|
|
|
|
return DS_E_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-09 13:27:53 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* For "as-is" can simply memcpy */
|
|
|
|
|
if (type_case == ds_case_as_is) {
|
|
|
|
|
char *p_dst = p_ds->p_buf + p_ds->length;
|
|
|
|
|
(void) memcpy(p_dst, p_src, n_char);
|
|
|
|
|
p_dst += n_char;
|
|
|
|
|
*p_dst = '\0';
|
|
|
|
|
p_ds->length = length_new;
|
|
|
|
|
return DS_E_OK;
|
2012-12-09 13:27:53 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
/* For lowercasing, work char by char */
|
|
|
|
|
if (type_case == ds_case_lower) {
|
|
|
|
|
char *p_dst = p_ds->p_buf + p_ds->length;
|
|
|
|
|
char *p_dst_end = p_dst + n_char;
|
|
|
|
|
for ( ; p_dst < p_dst_end; p_dst++, p_src++) {
|
|
|
|
|
*p_dst = (char) tolower(*p_src);
|
2012-12-09 13:27:53 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
*p_dst_end = '\0';
|
|
|
|
|
p_ds->length = length_new;
|
|
|
|
|
return DS_E_OK;
|
2012-12-09 13:27:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Uppercasing done like lowercasing. Note that it would be possible to
|
|
|
|
|
* use a function pointer and select either tolower() or toupper() based
|
|
|
|
|
* on type_case, but doing so may degrade performance by inhibiting
|
|
|
|
|
* inlining. */
|
|
|
|
|
if (type_case == ds_case_upper) {
|
|
|
|
|
char *p_dst = p_ds->p_buf + p_ds->length;
|
|
|
|
|
char *p_dst_end = p_dst + n_char;
|
|
|
|
|
for ( ; p_dst < p_dst_end; p_dst++, p_src++) {
|
|
|
|
|
*p_dst = (char) toupper(*p_src);
|
2012-12-09 13:27:53 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
*p_dst_end = '\0';
|
|
|
|
|
p_ds->length = length_new;
|
|
|
|
|
return DS_E_OK;
|
2012-12-09 13:27:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
return DS_E_INVALID; /* unknown case type */
|
|
|
|
|
} /* end of function ds_cat_mem_case */
|
2012-12-09 13:27:53 +01:00
|
|
|
|
|
|
|
|
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Ensure minimum internal buffer size */
|
|
|
|
|
int ds_reserve(DSTRING *p_ds, size_t n_byte_alloc)
|
2010-03-25 23:44:37 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Return if buffer already large enough */
|
|
|
|
|
if (p_ds->n_byte_alloc >= n_byte_alloc) {
|
|
|
|
|
return DS_E_OK;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
return ds_reserve_internal(p_ds, n_byte_alloc, 0);
|
|
|
|
|
} /* end of function ds_reserve */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This function resizes the buffer for the string and handles freeing
|
|
|
|
|
* the original alloction, if necessary. It is assumed that the requested
|
|
|
|
|
* size or sizes are larger than the current size.
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Parameters
|
|
|
|
|
* p_ds: Dstring pointer
|
|
|
|
|
* n_byte_alloc_opt: Optimal alloction amount
|
|
|
|
|
* n_byte_alloc_min: Absolute minimum allocation amount or 0 if no
|
|
|
|
|
* smaller amount can be allocated
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Return codes
|
|
|
|
|
* DS_E_OK: At least the minimum allocation was performed
|
|
|
|
|
* DS_E_NO_MEMORY: Unable to resize the buffer */
|
|
|
|
|
static int ds_reserve_internal(DSTRING *p_ds,
|
|
|
|
|
size_t n_byte_alloc_opt, size_t n_byte_alloc_min)
|
|
|
|
|
{
|
|
|
|
|
size_t n_byte_alloc = n_byte_alloc_opt;
|
|
|
|
|
/* Allocate. First try (larger) optimal size, and gradually fall back
|
|
|
|
|
* to min size if that fails and one was provided. */
|
|
|
|
|
char * p_buf_new;
|
|
|
|
|
if (n_byte_alloc_min == 0) {
|
|
|
|
|
n_byte_alloc_min = n_byte_alloc_opt;
|
|
|
|
|
}
|
|
|
|
|
for ( ; ; ) {
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
if ((p_buf_new = (char *) tmalloc_raw(
|
|
|
|
|
n_byte_alloc)) != (char *) NULL) {
|
2019-11-27 02:59:56 +01:00
|
|
|
break; /* Allocated OK */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n_byte_alloc == n_byte_alloc_min) { /* min alloc failed */
|
|
|
|
|
return DS_E_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((n_byte_alloc /= 2) < n_byte_alloc_min) { /* last try */
|
|
|
|
|
n_byte_alloc = n_byte_alloc_min;
|
|
|
|
|
}
|
|
|
|
|
} /* end of loop trying smaller allocations */
|
|
|
|
|
|
|
|
|
|
/* Copy to the new buffer */
|
|
|
|
|
(void) memcpy(p_buf_new, p_ds->p_buf, p_ds->length + 1);
|
|
|
|
|
|
|
|
|
|
/* If there already was a dynamic allocation, free it */
|
|
|
|
|
if (p_ds->p_buf != p_ds->p_stack_buf) {
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
txfree((void *) p_ds->p_buf);
|
2019-11-27 02:59:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Assign new active buffer and its size */
|
|
|
|
|
p_ds->p_buf = p_buf_new;
|
|
|
|
|
p_ds->n_byte_alloc = n_byte_alloc;
|
|
|
|
|
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
} /* end of function ds_reserve_nocheck */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Concatenate the result of a printf-style format
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Return codes as for ds_cat_vprintf */
|
|
|
|
|
int ds_cat_printf(DSTRING *p_ds, const char *sz_fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list p_arg;
|
|
|
|
|
va_start(p_arg, sz_fmt);
|
|
|
|
|
const int xrc = ds_cat_vprintf(p_ds, sz_fmt, p_arg);
|
|
|
|
|
va_end(p_arg);
|
|
|
|
|
return xrc;
|
|
|
|
|
} /* end of function ds_cat_printf */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Concatenate the result of a printf-style format using va_list
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Return codes
|
|
|
|
|
* DS_E_OK: Formatted OK
|
|
|
|
|
* DS_E_NO_MEMORY: Unable to allocate memory to resize buffer
|
|
|
|
|
* DS_E_INVALID: Invalid formatter / data
|
2010-03-25 23:44:37 +01:00
|
|
|
*/
|
2019-11-27 02:59:56 +01:00
|
|
|
int ds_cat_vprintf(DSTRING *p_ds, const char *sz_fmt, va_list p_arg)
|
2010-03-25 23:44:37 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Make a copy of the argument list in case need to format more than
|
|
|
|
|
* once */
|
|
|
|
|
va_list p_arg2;
|
|
|
|
|
va_copy(p_arg2, p_arg);
|
|
|
|
|
const size_t n_byte_free = p_ds->n_byte_alloc - p_ds->length;
|
|
|
|
|
char * const p_dst = p_ds->p_buf + p_ds->length;
|
|
|
|
|
const int rc = vsnprintf(p_dst, n_byte_free, sz_fmt, p_arg);
|
|
|
|
|
if (rc < 0) { /* Check for formatting error */
|
|
|
|
|
return DS_E_INVALID;
|
|
|
|
|
}
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Else check for buffer large enough and set length if it is */
|
2020-01-13 03:06:51 +01:00
|
|
|
if ((size_t) rc < n_byte_free) {
|
2019-11-27 02:59:56 +01:00
|
|
|
p_ds->length += rc;
|
|
|
|
|
return DS_E_OK;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
/* Else buffer too small, so resize and format again */
|
|
|
|
|
{
|
|
|
|
|
/* Double required size to avoid excessive allocations +1 for
|
|
|
|
|
* null, which is not included in the count returned by snprintf */
|
|
|
|
|
const size_t n_byte_alloc_min = p_ds->length + rc + 1;
|
|
|
|
|
if (ds_reserve_internal(p_ds,
|
|
|
|
|
2 * n_byte_alloc_min, n_byte_alloc_min) == DS_E_NO_MEMORY) {
|
|
|
|
|
/* vsnprintf may have written bytes to the buffer.
|
|
|
|
|
* Ensure that dstring in a consistent state by writing
|
|
|
|
|
* a null at the length of the string */
|
|
|
|
|
p_ds->p_buf[p_ds->length] = '\0';
|
|
|
|
|
return DS_E_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
const size_t n_byte_free2 = p_ds->n_byte_alloc - p_ds->length;
|
|
|
|
|
char * const p_dst2 = p_ds->p_buf + p_ds->length;
|
|
|
|
|
const int rc2 = vsnprintf(p_dst2, n_byte_free2, sz_fmt, p_arg2);
|
|
|
|
|
if (rc2 < 0) { /* Check for formatting error */
|
|
|
|
|
/* vsnprintf may have written bytes to the buffer.
|
|
|
|
|
* Ensure that dstring in a consistent state by writing
|
|
|
|
|
* a null at the length of the string */
|
|
|
|
|
p_ds->p_buf[p_ds->length] = '\0';
|
|
|
|
|
return DS_E_INVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Else update length. No need to check buffer size since it was
|
|
|
|
|
* sized to fit the string. */
|
|
|
|
|
p_ds->length += rc2;
|
|
|
|
|
return DS_E_OK;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
} /* end of function ds_cat_vprintf */
|
2010-03-25 23:44:37 +01:00
|
|
|
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Reallocate/free to eliminate unused buffer space.
|
2010-03-25 23:44:37 +01:00
|
|
|
*
|
2019-11-27 02:59:56 +01:00
|
|
|
* Return codes
|
|
|
|
|
* DS_E_OK: Compacted OK
|
|
|
|
|
* DS_E_NO_MEMORY: Compaction failed, but dstring still valid */
|
|
|
|
|
int ds_compact(DSTRING *p_ds)
|
|
|
|
|
{
|
|
|
|
|
const size_t n_byte_alloc_min = p_ds->length + 1;
|
|
|
|
|
|
|
|
|
|
/* If the string is in the stack buffer, there is nothing to do */
|
|
|
|
|
if (p_ds->p_stack_buf == p_ds->p_buf) {
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Else if the string will fit in the stack buffer, copy it there and
|
|
|
|
|
* free the allocation. */
|
|
|
|
|
if (p_ds->n_byte_stack_buf >= n_byte_alloc_min) {
|
|
|
|
|
(void) memcpy(p_ds->p_stack_buf, p_ds->p_buf, n_byte_alloc_min);
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
txfree((void *) p_ds->p_buf);
|
2019-11-27 02:59:56 +01:00
|
|
|
p_ds->p_buf = p_ds->p_stack_buf;
|
|
|
|
|
p_ds->n_byte_alloc = p_ds->n_byte_stack_buf;
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Else if the heap buffer is the minimum size, there is nothng to do */
|
|
|
|
|
if (n_byte_alloc_min == p_ds->n_byte_alloc) {
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Else realloc the heap buffer */
|
|
|
|
|
{
|
Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
2020-01-29 05:56:07 +01:00
|
|
|
void * const p = trealloc_raw(p_ds->p_buf, n_byte_alloc_min);
|
2019-11-27 02:59:56 +01:00
|
|
|
if (p == NULL) {
|
|
|
|
|
return DS_E_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
p_ds->p_buf = (char *) p;
|
|
|
|
|
p_ds->n_byte_alloc = n_byte_alloc_min;
|
|
|
|
|
return DS_E_OK;
|
|
|
|
|
}
|
|
|
|
|
} /* end of function ds_compact */
|
|
|
|
|
|
|
|
|
|
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
#ifdef DSTRING_UNIT_TEST
|
|
|
|
|
#if defined (_WIN32) && !defined(CONSOLE)
|
|
|
|
|
#include "ngspice/wstdio.h"
|
|
|
|
|
#endif
|
|
|
|
|
static void ds_print_info(DSTRING *p_ds, FILE *fp, const char *sz_id);
|
|
|
|
|
static int ds_test_from_macro(FILE *fp);
|
|
|
|
|
static int ds_test_from_stack(FILE *fp);
|
|
|
|
|
static int ds_test_from_heap(FILE *fp);
|
|
|
|
|
static int ds_test1(DSTRING *p_ds, FILE *fp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ds_test(FILE *fp)
|
2010-03-25 23:44:37 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
if (ds_test_from_macro(fp) != 0) { /* create from macro and run test */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_test_from_stack(fp) != 0) { /* create from stack */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_test_from_heap(fp) != 0) { /* create from heap */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2010-03-25 23:44:37 +01:00
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
return 0;
|
|
|
|
|
} /* end of function ds_test */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Run tests from a macro-created dstring */
|
|
|
|
|
static int ds_test_from_macro(FILE *fp)
|
|
|
|
|
{
|
|
|
|
|
DS_CREATE(ds, 10);
|
|
|
|
|
(void) fprintf(fp, "Macro initialization\n");
|
|
|
|
|
return ds_test1(&ds, fp);
|
|
|
|
|
} /* end of function ds_test_from_macro */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Run tests from a manually created stack-backed dstring */
|
|
|
|
|
static int ds_test_from_stack(FILE *fp)
|
|
|
|
|
{
|
|
|
|
|
static char p_buf[30] = "Hello World";
|
|
|
|
|
DSTRING ds;
|
|
|
|
|
(void) fprintf(fp, "Stack initialization\n");
|
|
|
|
|
(void) ds_init(&ds, p_buf, 11, sizeof p_buf, ds_buf_type_stack);
|
|
|
|
|
return ds_test1(&ds, fp);
|
|
|
|
|
} /* end of function ds_test_from_stack */
|
2010-03-25 23:44:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-27 02:59:56 +01:00
|
|
|
/* Run tests from a heap-backed dstring */
|
|
|
|
|
static int ds_test_from_heap(FILE *fp)
|
2010-03-25 23:44:37 +01:00
|
|
|
{
|
2019-11-27 02:59:56 +01:00
|
|
|
char *p_buf = (char *) malloc(25);
|
|
|
|
|
if (p_buf == (char *) NULL) {
|
|
|
|
|
return -1;
|
2010-03-25 23:44:37 +01:00
|
|
|
}
|
2019-11-27 02:59:56 +01:00
|
|
|
(void) memcpy(p_buf, "Heap", 4);
|
|
|
|
|
DSTRING ds;
|
|
|
|
|
(void) ds_init(&ds, p_buf, 4, 25, ds_buf_type_heap);
|
|
|
|
|
(void) fprintf(fp, "Heap initialization\n");
|
|
|
|
|
return ds_test1(&ds, fp);
|
|
|
|
|
} /* end of function ds_test_from_heap */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int ds_test1(DSTRING *p_ds, FILE *fp)
|
|
|
|
|
{
|
|
|
|
|
/* Print info on entry */
|
|
|
|
|
ds_print_info(p_ds, fp, "On entry to ds_test1\n");
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
|
if (ds_cat_str(p_ds, "Abc") != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_str_case(p_ds, "Abc", ds_case_as_is) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string as-is %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_str_case(p_ds, "Abc", ds_case_upper) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string upper %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_str_case(p_ds, "Abc", ds_case_lower) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string lower %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_char(p_ds, 'z') != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat char %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_char_case(p_ds, 'z', ds_case_as_is) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat char as-is %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_char_case(p_ds, 'z', ds_case_upper) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat char upper %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_char_case(p_ds, 'Z', ds_case_lower) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat char lower %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ds_cat_mem(p_ds, "Zyxw", 4) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_mem_case(p_ds, "Zyxw", 4, ds_case_as_is) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string as-is %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_mem_case(p_ds, "Zyxw", 4, ds_case_upper) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string upper %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (ds_cat_mem_case(p_ds, "Zyxw", 4, ds_case_lower) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat string lower %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ds_cat_printf(p_ds, "--- And finally a formatted %s (%d)",
|
|
|
|
|
"string", i) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to cat formatted string %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print info after cats */
|
|
|
|
|
ds_print_info(p_ds, fp, "After appending strings");
|
|
|
|
|
|
|
|
|
|
/* Truncate the string */
|
|
|
|
|
if (ds_set_length(p_ds, i * (size_t) 10) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to set size %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print info after truncation */
|
|
|
|
|
ds_print_info(p_ds, fp, "After setting length");
|
|
|
|
|
|
|
|
|
|
/* Compact the string */
|
|
|
|
|
if (ds_compact(p_ds) != 0) {
|
|
|
|
|
(void) fprintf(fp, "Unable to compact %d.\n", i);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print info after compaction */
|
|
|
|
|
ds_print_info(p_ds, fp, "After compacting the string");
|
|
|
|
|
} /* end of loop over tests */
|
|
|
|
|
|
|
|
|
|
ds_free(p_ds); /* free buffer if allocated */
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
} /* end of funtion ds_test */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Print some info about the DSTRING */
|
|
|
|
|
static void ds_print_info(DSTRING *p_ds, FILE *fp, const char *sz_id)
|
|
|
|
|
{
|
|
|
|
|
(void) fprintf(fp, "%s: length = %zu; "
|
|
|
|
|
"allocated buffer size = %zu; value = \"%s\"; "
|
|
|
|
|
"address of active buffer = %p; "
|
|
|
|
|
"address of stack buffer = %p; "
|
|
|
|
|
"size of stack buffer = %zu\n",
|
|
|
|
|
sz_id,
|
|
|
|
|
ds_get_length(p_ds), ds_get_buf_size(p_ds),
|
|
|
|
|
ds_get_buf(p_ds), ds_get_buf(p_ds),
|
|
|
|
|
p_ds->p_stack_buf, p_ds->n_byte_stack_buf);
|
|
|
|
|
} /* end of function ds_print_info */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* DSTRING_UNIT_TEST */
|
|
|
|
|
|
|
|
|
|
|
2010-03-25 23:44:37 +01:00
|
|
|
|