]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/Test/FMI1/fmi1_logger_test.c
Switch to full JavaSE-11+ compatibility
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / Test / FMI1 / fmi1_logger_test.c
1 /*\r
2     Copyright (C) 2012 Modelon AB\r
3 \r
4     This program is free software: you can redistribute it and/or modify\r
5     it under the terms of the BSD style license.\r
6 \r
7     This program is distributed in the hope that it will be useful,\r
8     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
10     FMILIB_License.txt file for more details.\r
11 \r
12     You should have received a copy of the FMILIB_License.txt file\r
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
14 */\r
15 \r
16 #include <stdio.h>\r
17 #include <stdlib.h>\r
18 #include <stdarg.h>\r
19 #include <assert.h>\r
20 \r
21 #include "config_test.h"\r
22 #include <fmilib.h>\r
23 #include <fmu_dummy/fmu1_model_defines.h>\r
24 #include <JM/jm_portability.h>\r
25 \r
26 FILE* logFile;\r
27 \r
28 void logger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message) {\r
29         char buf[10000];\r
30         const char* loadingstr = "Loading '";\r
31         /* need to replace platform specific message with a standard one */\r
32         if( (log_level == jm_log_level_info) && \r
33                 (strcmp(module, "FMILIB") == 0) &&\r
34                 (strncmp(message, "Loading '", strlen(loadingstr)) == 0)\r
35                 )\r
36         {\r
37                 jm_snprintf(buf, 10000, "[INFO][FMILIB] Loading '-----' binary with '------' platform types\n");\r
38         }\r
39         else\r
40                 jm_snprintf(buf, 10000, "[%s][%s] %s\n", jm_log_level_to_string(log_level), module, message);\r
41         printf("%s", buf);\r
42         fprintf(logFile, "%s", buf);\r
43 }\r
44 \r
45 void do_exit(int code)\r
46 {\r
47         /* getchar();*/\r
48         exit(code);\r
49 }\r
50            \r
51 int test_logger(fmi1_import_t* fmu)\r
52 {       \r
53         fmi1_status_t fmistatus; \r
54         jm_status_enu_t jmstatus;       \r
55 \r
56         jmstatus = fmi1_import_instantiate_model(fmu, "LoggerTesting");\r
57         if (jmstatus == jm_status_error) {\r
58                 printf("fmi1_import_instantiate_model failed\n");\r
59                 do_exit(CTEST_RETURN_FAIL);\r
60         }\r
61 \r
62         /* Logger message to print: */\r
63         {\r
64                 fmi1_value_reference_t* vr;\r
65                 size_t n;\r
66                 size_t k;\r
67                 const char* str[] = {\r
68                         "###### Reals ######",\r
69                         "OK HIGHT = #r0#", /* HIGHT */\r
70                         "OK HIGHT_SPEED = #r1#", /* HIGHT_SPEED */\r
71                         "OK GRAVITY = #r2#", /* GRAVITY */\r
72                         "OK BOUNCE_COF = #r3#", /* BOUNCE_COF */\r
73                         "Bad reference #r0",\r
74                         "Bad reference #r-0",\r
75                         "Bad reference #r-1",\r
76                         "Bad reference #r100#",\r
77                         "###### Integers ######",\r
78                         "OK LOGGER_TEST_INTEGER = #i0#", /* LOGGER_TEST_INTEGER */                      \r
79                         "Bad reference #i0",\r
80                         "Bad reference #i-0",\r
81                         "Bad reference #i-1",\r
82                         "Bad reference #i100#",\r
83                         "###### Booleans ######",\r
84                         "OK LOGGER_TEST_BOOLEAN = #b0#", /* LOGGER_TEST_BOOLEAN */      \r
85                         "Bad reference #b0",\r
86                         "Bad reference #b-0",\r
87                         "Bad reference #b-1",\r
88                         "Bad reference #b100#",\r
89                         "###### Strings ######",\r
90                         "OK LOGGER_TEST = #s0#", /* LOGGER_TEST */\r
91                         "Bad reference #s0",\r
92                         "Bad reference #s-0",\r
93                         "Bad reference #s-1",\r
94                         "Bad reference #s100#"\r
95                 };\r
96 \r
97                 n = sizeof(str)/sizeof(*str);   \r
98                 vr = calloc(n, sizeof(fmi1_value_reference_t));\r
99                 for (k = 0; k < n; k++) {\r
100                         vr[k] = VAR_S_LOGGER_TEST;\r
101                 }\r
102 \r
103                 fmistatus = fmi1_import_set_string(fmu, vr, n, str);\r
104         if(fmistatus != fmi1_status_ok) {\r
105             abort();\r
106         }               \r
107 \r
108                 { /* Print a really big message */\r
109 \r
110 #define MESSAGE_SIZE_TO_EXPAND_AND_PRINT 3000 /* Using fixed size since the log message is printed to a file and compared */\r
111 #if JM_MAX_ERROR_MESSAGE_SIZE + 200 > MESSAGE_SIZE_TO_EXPAND_AND_PRINT\r
112 #error This test triggers the logger function to allocate more memory than the default size JM_MAX_ERROR_MESSAGE_SIZE. If you change JM_MAX_ERROR_MESSAGE_SIZE, please update this test.\r
113 #endif\r
114                         char longmessage[MESSAGE_SIZE_TO_EXPAND_AND_PRINT];\r
115                         const char* str[1];\r
116 \r
117                         str[0] = (const char*)&longmessage;\r
118                         {
119                                 fmi1_value_reference_t vr = VAR_S_LOGGER_TEST;
120                                 int k;
121                                 char repmsg[] = "#r0# "; /* HIGHT */
122                                 for (k = 0; k < sizeof(longmessage)/sizeof(*longmessage) - 1; k++) {
123                                         longmessage[k] = repmsg[k%(sizeof(repmsg)/sizeof(*repmsg) - 1)];                                        
124                                 }
125                                 longmessage[k] = '\0';
126                                 
127                                 fmistatus = fmi1_import_set_string(fmu, &vr, 1, str);\r
128                                 if(fmistatus != fmi1_status_ok) {\r
129                                         abort();\r
130                                 }
131                         }\r
132                 }\r
133 \r
134                 free(vr);\r
135         }\r
136 \r
137 \r
138         fmi1_import_free_model_instance(fmu);\r
139         return 0;\r
140 }\r
141 \r
142 int main(int argc, char *argv[])\r
143 {\r
144         fmi1_callback_functions_t callBackFunctions;\r
145         const char* FMUPath;\r
146         const char* tmpPath;\r
147         jm_callbacks callbacks;\r
148         fmi_import_context_t* context;\r
149         fmi_version_enu_t version;\r
150         jm_status_enu_t status;\r
151         int register_active_fmu;\r
152         fmi1_import_t* fmu;     \r
153         char* outfile;\r
154 \r
155         if(argc < 4) {\r
156                 printf("Usage: %s <fmu_file> <temporary_dir> <output_file>\n", argv[0]);\r
157                 do_exit(CTEST_RETURN_FAIL);\r
158         }\r
159 \r
160         FMUPath = argv[1];\r
161         tmpPath = argv[2];\r
162         outfile = argv[3];\r
163 \r
164         logFile = fopen(outfile, "wb");\r
165 \r
166         if(!logFile) {\r
167                 printf("Could not open output file %s\n", outfile);\r
168                 do_exit(CTEST_RETURN_FAIL);\r
169         }\r
170 \r
171         callbacks.malloc = malloc;\r
172     callbacks.calloc = calloc;\r
173     callbacks.realloc = realloc;\r
174     callbacks.free = free;\r
175     callbacks.logger = logger;\r
176         callbacks.log_level = jm_log_level_info;\r
177     callbacks.context = 0;\r
178 \r
179         callBackFunctions.logger = fmi1_log_forwarding;\r
180         callBackFunctions.allocateMemory = calloc;\r
181         callBackFunctions.freeMemory = free;\r
182 \r
183 #ifdef FMILIB_GENERATE_BUILD_STAMP\r
184         printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());\r
185 #endif\r
186 \r
187         context = fmi_import_allocate_context(&callbacks);\r
188 \r
189         version = fmi_import_get_fmi_version(context, FMUPath, tmpPath);\r
190 \r
191         if(version != fmi_version_1_enu) {\r
192                 printf("Only version 1.0 is supported so far\n");\r
193                 do_exit(CTEST_RETURN_FAIL);\r
194         }\r
195 \r
196         fmu = fmi1_import_parse_xml(context, tmpPath);\r
197 \r
198         if(!fmu) {\r
199                 printf("Error parsing XML, exiting\n");\r
200                 do_exit(CTEST_RETURN_FAIL);\r
201         }       \r
202 \r
203         register_active_fmu = 1; /* Must be used to use our logger. (jm standard prints to strerr which does not generate out put test file)  */\r
204         status = fmi1_import_create_dllfmu(fmu, callBackFunctions, register_active_fmu);\r
205         if (status == jm_status_error) {\r
206                 printf("Could not create the DLL loading mechanism(C-API test).\n");\r
207                 do_exit(CTEST_RETURN_FAIL);\r
208         }\r
209         \r
210         test_logger(fmu);\r
211 \r
212         fmi1_import_destroy_dllfmu(fmu);\r
213 \r
214         fmi1_import_free(fmu);\r
215         fmi_import_free_context(context);\r
216         fclose(logFile);\r
217         return 0;\r
218 }\r
219 \r
220 \r