Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .CI/Test/Common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,37 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char* ModelicaAllocateString(size_t len) {
void *data = malloc(len + 1); /* Never free'd in the test programs */
assert(data);
if (NULL == data) {
ModelicaError("Failed to allocate string");
}
return data;
}

char* ModelicaAllocateStringWithErrorReturn(size_t len) {
return malloc(len + 1); /* Never free'd in the test programs */
}

char* ModelicaDuplicateString(const char* str) {
void *data = malloc(strlen(str) + 1); /* Never free'd in the test programs */
if (NULL == data) {
ModelicaError("Failed to duplicate string");
}
strcpy(data, str);
return data;
}

char* ModelicaDuplicateStringWithErrorReturn(const char* str) {
void *data = malloc(strlen(str) + 1); /* Never free'd in the test programs */
if (NULL != data) {
strcpy(data, str);
}
return data;
}

void ModelicaMessage(const char *string) {
printf("%s\n", string);
}
Expand Down
36 changes: 24 additions & 12 deletions .CI/Test/ModelicaUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,16 @@ void ModelicaMessage(const char *string);
Output the message string (no format control).
*/


void ModelicaFormatMessage(const char *string, ...) MODELICA_FORMATATTR_PRINTF;
void ModelicaFormatMessage(const char *format, ...) MODELICA_FORMATATTR_PRINTF;
/*
Output the message under the same format control as the C-function printf.
*/


void ModelicaVFormatMessage(const char *string, va_list args) MODELICA_FORMATATTR_VPRINTF;
void ModelicaVFormatMessage(const char *format, va_list args) MODELICA_FORMATATTR_VPRINTF;
/*
Output the message under the same format control as the C-function vprintf.
*/


MODELICA_NORETURN void ModelicaError(const char *string) MODELICA_NORETURNATTR;
/*
Output the error message string (no format control). This function
Expand All @@ -156,32 +153,30 @@ void ModelicaWarning(const char *string);
Output the warning message string (no format control).
*/

void ModelicaFormatWarning(const char *string, ...) MODELICA_FORMATATTR_PRINTF;
void ModelicaFormatWarning(const char *format, ...) MODELICA_FORMATATTR_PRINTF;
/*
Output the warning message under the same format control as the C-function printf.
*/

void ModelicaVFormatWarning(const char *string, va_list args) MODELICA_FORMATATTR_VPRINTF;
void ModelicaVFormatWarning(const char *format, va_list args) MODELICA_FORMATATTR_VPRINTF;
/*
Output the warning message under the same format control as the C-function vprintf.
*/

MODELICA_NORETURN void ModelicaFormatError(const char *string, ...) MODELICA_NORETURNATTR MODELICA_FORMATATTR_PRINTF;
MODELICA_NORETURN void ModelicaFormatError(const char *format, ...) MODELICA_NORETURNATTR MODELICA_FORMATATTR_PRINTF;
/*
Output the error message under the same format control as the C-function
printf. This function never returns to the calling function,
but handles the error similarly to an assert in the Modelica code.
*/


MODELICA_NORETURN void ModelicaVFormatError(const char *string, va_list args) MODELICA_NORETURNATTR MODELICA_FORMATATTR_VPRINTF;
MODELICA_NORETURN void ModelicaVFormatError(const char *format, va_list args) MODELICA_NORETURNATTR MODELICA_FORMATATTR_VPRINTF;
/*
Output the error message under the same format control as the C-function
vprintf. This function never returns to the calling function,
but handles the error similarly to an assert in the Modelica code.
*/


char* ModelicaAllocateString(size_t len);
/*
Allocate memory for a Modelica string which is used as return
Expand All @@ -191,7 +186,6 @@ calling program, as for any other array. If an error occurs, this
function does not return, but calls "ModelicaError".
*/


char* ModelicaAllocateStringWithErrorReturn(size_t len);
/*
Same as ModelicaAllocateString, except that in case of error, the
Expand All @@ -201,6 +195,24 @@ resources use ModelicaError or ModelicaFormatError to signal
the error.
*/

char* ModelicaDuplicateString(const char* str);
/*
Duplicate (= allocate memory and deep copy) a Modelica string which
is used as return argument of an external Modelica function. Note,
that the storage for string arrays (= pointer to string array) is still
provided by the calling program, as for any other array. If an error
occurs, this function does not return, but calls "ModelicaError".
*/

char* ModelicaDuplicateStringWithErrorReturn(const char* str);
/*
Same as ModelicaDuplicateString, except that in case of error, the
function returns 0. This allows the external function to close files
and free other open resources in case of error. After cleaning up
resources use, ModelicaError or ModelicaFormatError to signal
the error.
*/

#if defined(__cplusplus)
}
#endif
Expand Down
38 changes: 16 additions & 22 deletions Modelica/Resources/C-Sources/ModelicaInternal.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ModelicaInternal.c - External functions for Modelica.Utilities

Copyright (C) 2002-2023, Modelica Association and contributors
Copyright (C) 2002-2024, Modelica Association and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -30,6 +30,10 @@
*/

/* Changelog:
Jan. 15, 2024: by Thomas Beutlich
Utilized ModelicaDuplicateString and
ModelicaDuplicateStringWithErrorReturn (ticket #3686)

Nov. 17, 2020: by Thomas Beutlich
Fixed reading files with Unix-style line endings on Windows
for ModelicaInternal_readLine/_readFile (ticket #3631)
Expand Down Expand Up @@ -525,7 +529,7 @@ void ModelicaInternal_readDirectory(_In_z_ const char* directory, int nFiles,
}

/* Allocate Modelica memory for file/directory name and copy name */
pName = ModelicaAllocateStringWithErrorReturn(strlen(pinfo->d_name));
pName = ModelicaDuplicateStringWithErrorReturn(pinfo->d_name);
if ( pName == NULL ) {
errnoTemp = errno;
closedir(pdir);
Expand All @@ -538,7 +542,6 @@ void ModelicaInternal_readDirectory(_In_z_ const char* directory, int nFiles,
directory, strerror(errnoTemp));
}
}
strcpy(pName, pinfo->d_name);

/* Save pointer to file */
files[iFiles] = pName;
Expand Down Expand Up @@ -622,8 +625,7 @@ _Ret_z_ const char* ModelicaInternal_fullPathName(_In_z_ const char* name) {
name, strerror(errno));
return "";
}
fullName = ModelicaAllocateString(strlen(tempName));
strcpy(fullName, tempName);
fullName = ModelicaDuplicateString(tempName);
ModelicaConvertToUnixDirectorySeparator(fullName);
return fullName;
#elif (_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_VERSION >= 200112L)
Expand All @@ -635,8 +637,7 @@ _Ret_z_ const char* ModelicaInternal_fullPathName(_In_z_ const char* name) {
if (tempName == NULL) {
goto FALLBACK_getcwd;
}
fullName = ModelicaAllocateString(strlen(tempName) + 1);
strcpy(fullName, tempName);
fullName = ModelicaDuplicateString(tempName);
ModelicaConvertToUnixDirectorySeparator(fullName);
/* Retain trailing slash to match _fullpath behaviour */
len = strlen(name);
Expand Down Expand Up @@ -688,8 +689,7 @@ _Ret_z_ const char* ModelicaInternal_temporaryFileName(void) {
ModelicaFormatError("Not possible to get temporary filename\n%s", strerror(errno));
return "";
}
fullName = ModelicaAllocateString(strlen(tempName));
strcpy(fullName, tempName);
fullName = ModelicaDuplicateString(tempName);
ModelicaConvertToUnixDirectorySeparator(fullName);

return fullName;
Expand Down Expand Up @@ -1011,12 +1011,11 @@ void ModelicaInternal_readFile(_In_z_ const char* fileName,
while (iLines <= nLines) {
readLine(&buf, &bufLen, fp);

line = ModelicaAllocateStringWithErrorReturn(strlen(buf));
line = ModelicaDuplicateStringWithErrorReturn(buf);
if ( line == NULL ) {
goto Modelica_OOM_ERROR1;
}

strcpy(line, buf);
string[iLines - 1] = line;
iLines++;
}
Expand Down Expand Up @@ -1063,12 +1062,11 @@ _Ret_z_ const char* ModelicaInternal_readLine(_In_z_ const char* fileName,
}
}

line = ModelicaAllocateStringWithErrorReturn(strlen(buf));
line = ModelicaDuplicateStringWithErrorReturn(buf);
if (line == NULL) {
goto Modelica_OOM_ERROR2;
}

strcpy(line, buf);
CacheFileForReading(fp, fileName, lineNumber, buf, bufLen);
*endOfFile = 0;
return line;
Expand All @@ -1078,8 +1076,7 @@ _Ret_z_ const char* ModelicaInternal_readLine(_In_z_ const char* fileName,
fclose(fp);
CloseCachedFile(fileName);
*endOfFile = 1;
line = ModelicaAllocateString(0);
line[0] = '\0';
line = ModelicaDuplicateString("");
return line;

Modelica_OOM_ERROR2:
Expand Down Expand Up @@ -1134,8 +1131,7 @@ _Ret_z_ const char* ModelicaInternal_getcwd(int dummy) {
cwd = "";
}
#endif
directory = ModelicaAllocateString(strlen(cwd));
strcpy(directory, cwd);
directory = ModelicaDuplicateString(cwd);
ModelicaConvertToUnixDirectorySeparator(directory);
return directory;
}
Expand All @@ -1156,18 +1152,16 @@ void ModelicaInternal_getenv(_In_z_ const char* name, int convertToSlash,
#endif

if (value == NULL) {
result = ModelicaAllocateString(0);
result[0] = '\0';
result = ModelicaDuplicateString("");
*exist = 0;
}
else {
#if defined(_MSC_VER) && _MSC_VER >= 1400
result = ModelicaAllocateStringWithErrorReturn(len); /* (len - 1) actually is sufficient */
result = ModelicaDuplicateStringWithErrorReturn(value);
if (result) {
#else
result = ModelicaAllocateString(strlen(value));
result = ModelicaDuplicateString(value);
#endif
strcpy(result, value);
if ( convertToSlash == 1 ) {
ModelicaConvertToUnixDirectorySeparator(result);
}
Expand Down
14 changes: 7 additions & 7 deletions Modelica/Resources/C-Sources/ModelicaStrings.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ModelicaStrings.c - External functions for Modelica.Utilities.Strings

Copyright (C) 2002-2020, Modelica Association and contributors
Copyright (C) 2002-2024, Modelica Association and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -30,6 +30,10 @@
*/

/* Changelog:
Jan. 15, 2024: by Thomas Beutlich
Utilized ModelicaDuplicateString and
ModelicaDuplicateStringWithErrorReturn (ticket #3686)

Mar. 15, 2020: by Thomas Beutlich
Improved fault-tolerance of ModelicaStrings_substring w.r.t.
index arguments (ticket #3503)
Expand Down Expand Up @@ -231,9 +235,7 @@ void ModelicaStrings_scanIdentifier(_In_z_ const char* string,
/* Token missing or not identifier. */
*nextIndex = startIndex;
{
char* s = ModelicaAllocateString(0);
s[0] = '\0';
*identifier = s;
*identifier = ModelicaDuplicateString("");
}
return;
}
Expand Down Expand Up @@ -458,9 +460,7 @@ void ModelicaStrings_scanString(_In_z_ const char* string, int startIndex,

Modelica_ERROR:
{
char* s = ModelicaAllocateString(0);
s[0] = '\0';
*result = s;
*result = ModelicaDuplicateString("");
}
*nextIndex = startIndex;
return;
Expand Down