Skip to content

Commit

Permalink
Use varargs for throwing assertions so we can produce better messages…
Browse files Browse the repository at this point in the history
… in the code generator

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15958 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed May 2, 2013
1 parent 0bf0af6 commit dfa6c26
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 76 deletions.
54 changes: 29 additions & 25 deletions Compiler/Template/CodegenC.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -1417,10 +1417,10 @@ template functionWhenReinitStatement(WhenOperator reinit, Text &varDecls /*BUFP*
<<
<%preExp%>
FILE_INFO info = {<%infoArgs(getElementSourceFileInfo(source))%>};
omc_terminate(<%msgVar%>, info);
omc_terminate(info, <%msgVar%>);
>>
case ASSERT(source=SOURCE(info=info)) then
assertCommon(condition, message, level, contextSimulationDiscrete, &varDecls, info)
assertCommon(condition, List.fill(message,1), level, contextSimulationDiscrete, &varDecls, info)
end match
end functionWhenReinitStatement;

Expand Down Expand Up @@ -1479,10 +1479,10 @@ template functionWhenReinitStatementThen(Boolean initialCall, list<WhenOperator>
<<
<%preExp%>
FILE_INFO info = {<%infoArgs(getElementSourceFileInfo(source))%>};
omc_terminate(<%msgVar%>, info);
omc_terminate(info, <%msgVar%>);
>>
case ASSERT(source=SOURCE(info=info)) then
assertCommon(condition, message, level, contextSimulationDiscrete, &varDecls, info)
assertCommon(condition, List.fill(message,1), level, contextSimulationDiscrete, &varDecls, info)
case NORETCALL(__) then
let &preExp = buffer "" /*BUFD*/
let argStr = (functionArgs |> exp => '<%daeExp(exp, contextSimulationDiscrete, &preExp /*BUFC*/, &varDecls /*BUFD*/)%>' ;separator=", ")
Expand Down Expand Up @@ -3158,9 +3158,9 @@ template functionsFile(String filePrefix,
<<
#include "<%filePrefix%>.h"
#include "modelica.h"
void (*omc_assert)(const char *msg, FILE_INFO info) = omc_assert_function;
void (*omc_assert_warning)(const char *msg, FILE_INFO info) = omc_assert_warning_function;
void (*omc_terminate)(const char *msg, FILE_INFO info) = omc_terminate_function;
void (*omc_assert)(FILE_INFO info,const char *msg,...) = omc_assert_function;
void (*omc_assert_warning)(FILE_INFO info,const char *msg,...) = omc_assert_warning_function;
void (*omc_terminate)(FILE_INFO info,const char *msg,...) = omc_terminate_function;
void (*omc_throw)() = omc_throw_function;

<%match mainFunction case SOME(fn) then functionBody(fn,true)%>
Expand Down Expand Up @@ -5168,7 +5168,7 @@ case EXTERNAL_FUNCTION(__) then
if(<%fname%>==NULL)
{
FILE_INFO info = {<%infoArgs(info)%>};
omc_terminate("dynamic external function <%extFunctionName(extName, language)%> not set!", info);
omc_terminate(info, "dynamic external function <%extFunctionName(extName, language)%> not set!");
} else
>>
else ''
Expand Down Expand Up @@ -6023,7 +6023,7 @@ case RANGE(__) then
if(!<%stepVar%>)
{
FILE_INFO info = omc_dummyFileInfo;
omc_assert("assertion range step != 0 failed", info);
omc_assert(info, "assertion range step != 0 failed");
}
else if(!(((<%stepVar%> > 0) && (<%startVar%> > <%stopVar%>)) || ((<%stepVar%> < 0) && (<%startVar%> < <%stopVar%>))))
{
Expand Down Expand Up @@ -6106,7 +6106,7 @@ template algStmtAssert(DAE.Statement stmt, Context context, Text &varDecls /*BUF
::=
match stmt
case STMT_ASSERT(source=SOURCE(info=info)) then
assertCommon(cond, msg, level, context, &varDecls, info)
assertCommon(cond, List.fill(msg,1), level, context, &varDecls, info)
end algStmtAssert;

template algStmtTerminate(DAE.Statement stmt, Context context, Text &varDecls /*BUFP*/)
Expand All @@ -6119,7 +6119,7 @@ case STMT_TERMINATE(__) then
<<
<%preExp%>
FILE_INFO info = {<%infoArgs(getElementSourceFileInfo(source))%>};
omc_terminate(<%msgVar%>, info);
omc_terminate(info, <%msgVar%>);
>>
end algStmtTerminate;

Expand Down Expand Up @@ -7261,7 +7261,8 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varD
'sqrt(<%argStr%>)'
else
let ass = '(<%argStr%> >= 0.0)'
let retPre = assertCommonVar(ass,createDAEString('Model error: Argument of sqrt(<%printExpStr(e1)%>) should be >= 0'), context, &varDecls, dummyInfo)
let &preExpMsg = buffer ""
let retPre = assertCommonVar(ass,'"Model error: Argument of sqrt(<%printExpStr(e1)%>) was %g should be >= 0", <%argStr%>', context, &preExpMsg, &varDecls, dummyInfo)
let &preExp += '<%retPre%>'
'sqrt(<%argStr%>)')

Expand Down Expand Up @@ -8720,20 +8721,20 @@ template infoArgs(Info info)
case INFO(__) then '"<%Util.escapeModelicaStringToCString(testsuiteFriendly(fileName))%>",<%lineNumberStart%>,<%columnNumberStart%>,<%lineNumberEnd%>,<%columnNumberEnd%>,<%if isReadOnly then 1 else 0%>'
end infoArgs;

template assertCommon(Exp condition, Exp message, Exp level, Context context, Text &varDecls, Info info)
template assertCommon(Exp condition, list<Exp> messages, Exp level, Context context, Text &varDecls, Info info)
::=
let &preExpCond = buffer ""
let condVar = daeExp(condition, context, &preExpCond, &varDecls)
let &preExpMsg = buffer ""
let msgVar = messages |> message => expToFormatString(message,context,&preExpMsg,&varDecls) ; separator = ", "
match level
case ENUM_LITERAL(index=1) then
<<
<%preExpCond%>
<%assertCommonVar(condVar,message,context,&varDecls,info)%>
<%assertCommonVar(condVar,msgVar,context,&preExpMsg,&varDecls,info)%>
>>
case ENUM_LITERAL(index=2) then
let warningTriggered = tempDeclZero("static int", &varDecls)
let &preExpMsg = buffer ""
let msgVar = daeExp(message, context, &preExpMsg, &varDecls)
<<
if(!<%warningTriggered%>)
{
Expand All @@ -8742,17 +8743,15 @@ template assertCommon(Exp condition, Exp message, Exp level, Context context, Te
{
<%preExpMsg%>
FILE_INFO info = {<%infoArgs(info)%>};
omc_assert_warning(<%if acceptMetaModelicaGrammar() then 'MMC_STRINGDATA(<%msgVar%>)' else msgVar%>, info);
omc_assert_warning(info, <%msgVar%>);
<%warningTriggered%> = 1;
}
}<%\n%>
>>
else
let warningTriggered = tempDeclZero("static int", &varDecls)
let &preExpLevel = buffer ""
let &preExpMsg = buffer ""
let levelVar = daeExp(level, context, &preExpMsg, &varDecls)
let msgVar = daeExp(message, context, &preExpMsg, &varDecls)
<<
<%preExpLevel%>
if(<%levelVar%> == 1 || !<%warningTriggered%>)
Expand All @@ -8763,25 +8762,30 @@ template assertCommon(Exp condition, Exp message, Exp level, Context context, Te
<%preExpMsg%>
FILE_INFO info = {<%infoArgs(info)%>};
if (<%levelVar%> == 1)
omc_assert(<%if acceptMetaModelicaGrammar() then 'MMC_STRINGDATA(<%msgVar%>)' else msgVar%>, info);
omc_assert(info, <%msgVar%>);
else
omc_assert_warning(<%if acceptMetaModelicaGrammar() then 'MMC_STRINGDATA(<%msgVar%>)' else msgVar%>, info);
omc_assert_warning(info, <%msgVar%>);
<%warningTriggered%> = 1;
}
}<%\n%>
>>
end assertCommon;

template assertCommonVar(Text condVar, Exp message, Context context, Text &varDecls, Info info)
template expToFormatString(Exp exp, Context context, Text &preExp, Text &varDecls)
::=
let pre = (match typeof(exp) case T_STRING(__) then (if acceptMetaModelicaGrammar() then "MMC_STRINGDATA("))
let post = (if pre then ")")
pre + daeExp(exp, context, &preExp, &varDecls) + post
end expToFormatString;

template assertCommonVar(Text condVar, Text msgVar, Context context, Text &preExpMsg, Text &varDecls, Info info)
::=
let &preExpMsg = buffer ""
let msgVar = daeExp(message, context, &preExpMsg, &varDecls)
<<
if(!<%condVar%>)
{
<%preExpMsg%>
FILE_INFO info = {<%infoArgs(info)%>};
omc_assert(<%if acceptMetaModelicaGrammar() then 'MMC_STRINGDATA(<%msgVar%>)' else msgVar%>, info);
omc_assert(info, <%msgVar%>);
}<%\n%>
>>
end assertCommonVar;
Expand Down
4 changes: 2 additions & 2 deletions Compiler/runtime/ModelicaExternalC_rml.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
#include "memory_pool.h"
#include "meta_modelica.h"

void (*omc_assert)(const char *msg, FILE_INFO info) = omc_assert_function;
void (*omc_terminate)(const char *msg, FILE_INFO info) = omc_terminate_function;
void (*omc_assert)(FILE_INFO info,const char *msg,...) = omc_assert_function;
void (*omc_terminate)(FILE_INFO info,const char *msg,...) = omc_terminate_function;
void (*omc_throw)() = omc_throw_function;

void ModelicaInternal_print(const char*,const char*);
Expand Down
70 changes: 35 additions & 35 deletions SimulationRuntime/c/simulation/simulation_runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <cassert>
#include <signal.h>
#include <fstream>
#include <stdarg.h>

#ifndef _MSC_VER
#include <regex.h>
Expand Down Expand Up @@ -117,33 +118,20 @@ int isInteractiveSimulation();
* prints all values as arguments it need data
* and which part of the ring should printed.
*/
void setTermMsg(const char *msg)
static void setTermMsg(const char *msg, va_list ap)
{
size_t i;
size_t length = strlen(msg);
if(length > 0)
{
if(TermMsg == NULL)
{
TermMsg = (char*)malloc((length+1)*sizeof(char));
}
else
{
if(strlen(msg) > strlen(TermMsg))
{
if(TermMsg != NULL)
{
free(TermMsg);
}
TermMsg = (char*)malloc((length+1)*sizeof(char));
}
}

for(i=0; i<length; i++)
TermMsg[i] = msg[i];

/* set the terminating 0 */
TermMsg[i] = '\0';
static size_t termMsgSize = 0;
if (TermMsg==NULL) {
termMsgSize = max(strlen(msg)*2+1,2048);
TermMsg = (char*) malloc(termMsgSize);
}
i = vsnprintf(TermMsg,termMsgSize,msg,ap);
if (i >= termMsgSize) {
free(TermMsg);
termMsgSize = 2*i+1;
TermMsg = (char*)malloc(termMsgSize);
vsnprintf(TermMsg,termMsgSize,msg,ap);
}
}

Expand Down Expand Up @@ -958,34 +946,46 @@ int _main_SimulationRuntime(int argc, char**argv, DATA *data)
EXIT(retVal);
}

static void omc_assert_simulation(const char *msg, FILE_INFO info)
static void omc_assert_simulation(FILE_INFO info, const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
terminationAssert = 1;
setTermMsg(msg);
setTermMsg(msg,ap);
va_end(ap);
TermInfo = info;
}

static void omc_assert_warning_simulation(const char *msg, FILE_INFO info)
static void omc_assert_warning_simulation(FILE_INFO info, const char *msg, ...)
{
fprintf(stderr, "Warning: %s\n", msg);
va_list ap;
va_start(ap,msg);
fputs("Warning: ",stderr);
vfprintf(stderr,msg,ap);
fputs("\n",stderr);
va_end(ap);
}

static void omc_terminate_simulation(const char *msg, FILE_INFO info)
static void omc_terminate_simulation(FILE_INFO info, const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
modelTermination=1;
terminationTerminate = 1;
setTermMsg(msg);
setTermMsg(msg,ap);
va_end(ap);
TermInfo = info;
}

static void omc_throw_simulation()
{
va_list ap;
terminationAssert = 1;
setTermMsg("Assertion triggered by external C function");
setTermMsg("Assertion triggered by external C function", ap);
set_struct(FILE_INFO, TermInfo, omc_dummyFileInfo);
}

void (*omc_assert)(const char *msg, FILE_INFO info) = omc_assert_simulation;
void (*omc_assert_warning)(const char *msg, FILE_INFO info) = omc_assert_warning_simulation;
void (*omc_terminate)(const char *msg, FILE_INFO info) = omc_terminate_simulation;
void (*omc_assert)(FILE_INFO info, const char *msg, ...) = omc_assert_simulation;
void (*omc_assert_warning)(FILE_INFO info, const char *msg, ...) = omc_assert_warning_simulation;
void (*omc_terminate)(FILE_INFO info, const char *msg, ...) = omc_terminate_simulation;
void (*omc_throw)() = omc_throw_simulation;
2 changes: 0 additions & 2 deletions SimulationRuntime/c/simulation/simulation_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ extern FILE_INFO TermInfo; /* message for termination. */

extern char* TermMsg; /* message for termination. */

void setTermMsg(const char *msg);

/* defined in model code. Used to get name of variable by investigating its pointer in the state or alg vectors. */
const char* getNameReal(double* ptr);
const char* getNameInt(modelica_integer* ptr);
Expand Down
27 changes: 21 additions & 6 deletions SimulationRuntime/c/util/omc_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,28 @@ void printInfo(FILE *stream, FILE_INFO info)
fprintf(stream, "[%s:%d:%d-%d:%d:%s]", info.filename, info.lineStart, info.colStart, info.lineEnd, info.colEnd, info.readonly ? "readonly" : "writable");
}

void omc_assert_function(const char *msg, FILE_INFO info)
void omc_assert_function(FILE_INFO info, const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
printInfo(stderr, info);
fprintf(stderr,"Modelica Assert: %s!\n", msg);
fputs("Modelica Assert: ", stderr);
vfprintf(stderr,msg,ap);
fputs("!\n", stderr);
va_end(ap);
fflush(NULL);
MMC_THROW();
}

void omc_assert_warning_function(const char *msg, FILE_INFO info)
void omc_assert_warning_function(FILE_INFO info, const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
printInfo(stderr, info);
fprintf(stderr,"Warning, assertion triggered: %s!\n", msg);
fputs("Warning, assertion triggered: ", stderr);
vfprintf(stderr,msg,ap);
fputs("!\n", stderr);
va_end(ap);
fflush(NULL);
}

Expand All @@ -150,10 +160,15 @@ void omc_throw_function()
MMC_THROW();
}

void omc_terminate_function(const char *msg, FILE_INFO info)
void omc_terminate_function(FILE_INFO info, const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
printInfo(stderr, info);
fprintf(stderr,"Modelica Terminate: %s!\n", msg);
fputs("Modelica Terminate: ", stderr);
vfprintf(stderr,msg,ap);
fputs("!\n", stderr);
va_end(ap);
fflush(NULL);
MMC_THROW();
}
Expand Down
12 changes: 6 additions & 6 deletions SimulationRuntime/c/util/omc_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ typedef struct _FILE_INFO
} FILE_INFO;

extern void printInfo(FILE *stream, FILE_INFO info);
extern void (*omc_assert)(const char*, FILE_INFO);
extern void (*omc_assert_warning)(const char*, FILE_INFO);
extern void (*omc_terminate)(const char*, FILE_INFO);
extern void (*omc_assert)(FILE_INFO,const char*,...);
extern void (*omc_assert_warning)(FILE_INFO,const char*,...);
extern void (*omc_terminate)(FILE_INFO,const char*,...);
extern void (*omc_throw)();
void initDumpSystem();
void omc_assert_function(const char *msg, FILE_INFO info);
void omc_assert_warning_function(const char *msg, FILE_INFO info);
void omc_terminate_function(const char *msg, FILE_INFO info);
void omc_assert_function(FILE_INFO info, const char *msg,...);
void omc_assert_warning_function(FILE_INFO info, const char *msg,...);
void omc_terminate_function(FILE_INFO info, const char *msg,...);
void omc_throw_function();

/* global JumpBuffer */
Expand Down

0 comments on commit dfa6c26

Please sign in to comment.