1 /* -------------------------------------------------------------------------- *
2  *                            OpenSim:  About.cpp                             *
3  * -------------------------------------------------------------------------- *
4  * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
5  * See http://opensim.stanford.edu and the NOTICE file for more information.  *
6  * OpenSim is developed at Stanford University and supported by the US        *
7  * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
8  * through the Warrior Web program.                                           *
9  *                                                                            *
10  * Copyright (c) 2005-2017 Stanford University and the Authors                *
11  * Author(s): Ayman Habib                                                     *
12  *                                                                            *
13  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
14  * not use this file except in compliance with the License. You may obtain a  *
15  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
16  *                                                                            *
17  * Unless required by applicable law or agreed to in writing, software        *
18  * distributed under the License is distributed on an "AS IS" BASIS,          *
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
20  * See the License for the specific language governing permissions and        *
21  * limitations under the License.                                             *
22  * -------------------------------------------------------------------------- */
23 
24 /**
25  * Define the standard SimTK compliant "version" and "about" routines.
26  */
27 
28 #include "About.h"
29 #include <cstring>
30 #include <cstdio>
31 #include <stdio.h>
32 #include <stdlib.h>
33 
34 #define STR(var) #var
35 #define MAKE_VERSION_STRING(maj,min,build)  STR(maj.min.build)
36 #define MAKE_COPYRIGHT_STRING(y,a) \
37     "Copyright (c) " STR(y) " Stanford University, " STR(a)
38 #define MAKE_STRING(a) STR(a)
39 
40 #define GET_VERSION_STRING  \
41     MAKE_VERSION_STRING(OPENSIM_COMMON_MAJOR_VERSION,  \
42                         OPENSIM_COMMON_MINOR_VERSION,  \
43                         OPENSIM_COMMON_BUILD_VERSION)
44 
45 #define GET_COPYRIGHT_STRING \
46     MAKE_COPYRIGHT_STRING(OPENSIM_COMMON_COPYRIGHT_YEARS, \
47                           OPENSIM_COMMON_AUTHORS)
48 
49 #define GET_AUTHORS_STRING \
50     MAKE_STRING(OPENSIM_COMMON_AUTHORS)
51 
52 #define GET_LIBRARY_STRING \
53     MAKE_STRING(OPENSIM_COMMON_LIBRARY_NAME)
54 
55 #define GET_TYPE_STRING \
56     MAKE_STRING(OPENSIM_COMMON_TYPE)
57 
58 #define GET_SYSTEM_INFO \
59     MAKE_STRING(OSIM_SYS_INFO)
60 
61 #define GET_COMPILER_INFO \
62     MAKE_STRING(OSIM_COMPILER_INFO)
63 
64 #define GET_OS_NAME \
65     MAKE_STRING(OSIM_OS_NAME)
66 
67 #define GET_OSIM_VERSION \
68     MAKE_STRING(OSIM_VERSION)
69 
70 #ifndef NDEBUG
71     #define GET_DEBUG_STRING "debug"
72 #else
73     #define GET_DEBUG_STRING "release"
74 #endif
75 
76 using namespace std;
77 
78 extern "C" {
79 
opensim_version_common(int * major,int * minor,int * build)80 void opensim_version_common(int* major, int* minor, int* build) {
81     static const char* l = "OPENSIM library="   GET_LIBRARY_STRING;
82     static const char* t = "OPENSIM type="      GET_TYPE_STRING;
83     static const char* d = "OPENSIM debug="     GET_DEBUG_STRING;
84     static const char* v = "OPENSIM version="   GET_VERSION_STRING;
85     static const char* c = "OPENSIM copyright=" GET_COPYRIGHT_STRING;
86 
87     if (major) *major = OPENSIM_COMMON_MAJOR_VERSION;
88     if (minor) *minor = OPENSIM_COMMON_MINOR_VERSION;
89     if (build) *build = OPENSIM_COMMON_BUILD_VERSION;
90 
91     // Force statics to be present in the binary (Release mode otherwise
92     // optimizes them away).
93     volatile int i=0;
94     if (i) { // never true, but compiler doesn't know ...
95         *major = *l + *t + *d + *v + *c;
96     }
97 }
98 
opensim_about_common(const char * key,int maxlen,char * value)99 void opensim_about_common(const char* key, int maxlen, char* value) {
100     if (maxlen <= 0 || value==0) return;
101     value[0] = '\0'; // in case we don't find a match
102     if (key==0) return;
103 
104     // downshift the key
105     std::string skey(key);
106     for (size_t i=0; i<skey.size(); ++i)
107         skey[i] = tolower(skey[i]);
108 
109     const char* v = 0;
110     if      (skey == "version")   v = GET_VERSION_STRING;
111     else if (skey == "library")   v = GET_LIBRARY_STRING;
112     else if (skey == "type")      v = GET_TYPE_STRING;
113     else if (skey == "copyright") v = GET_COPYRIGHT_STRING;
114     else if (skey == "authors")   v = GET_AUTHORS_STRING;
115     else if (skey == "debug")     v = GET_DEBUG_STRING;
116 
117     if (v) {
118         strncpy(value,v,maxlen-1);
119         value[maxlen-1] = '\0'; // in case we ran out of room
120     }
121 }
122 
123 } // extern "C"
124 
125 namespace OpenSim {
126 
127 static const char* OpenSimVersion = GET_OSIM_VERSION;
128 
GetVersionAndDate()129 std::string GetVersionAndDate() {
130     char buffer[256];
131     sprintf(buffer,"version %s, build date %s %s",
132             OpenSimVersion, __TIME__, __DATE__);
133     return std::string(buffer);
134 }
135 
GetVersion()136 std::string GetVersion() {
137     return OpenSimVersion;
138 }
139 
GetOSInfoVerbose()140 std::string GetOSInfoVerbose() {
141     const char * str = GET_SYSTEM_INFO;
142     return str;
143 }
144 
GetOSInfo()145 std::string GetOSInfo() {
146     const char * str = GET_OS_NAME;
147     return str;
148 }
149 
GetCompilerVersion()150 std::string GetCompilerVersion() {
151     std::string os = GetOSInfo();
152     std::string str = "(Unknown)";
153 
154     if( 0 == os.compare("Windows")) {
155         const int MSVCVersion = atoi(GET_COMPILER_INFO);
156         if( MSVCVersion >= 1910 ) {
157             // With Visual Studio 2017, the versioning of the Visual C++
158             // compiler became more fine-grained, so we can no longer use
159             // a switch statement.
160             // Also, Visual Studio 2017 decouples the Visual Studio IDE
161             // from the C++ toolset (compiler), so providing the IDE year
162             // does not indicate the compiler version (it may be possible
163             // to use the Visual Studio 2019 IDE, or whatever is next,
164             // with the same C++ toolset that came with Visual Studio 2017.
165             // Therefore, we no longer provide the Visual Studio year.
166             // https://blogs.msdn.microsoft.com/vcblog/2016/10/05/visual-c-compiler-version/
167             // https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
168             if (1910 <= MSVCVersion && MSVCVersion < 2000) {
169                 str = "Microsoft Visual C++ 14.1";
170             }
171             str += " (MSC_VER " + std::to_string(MSVCVersion) + ")";
172         } else {
173             switch( MSVCVersion ) {
174                 case 1900:
175                     str = "Visual Studio 2015";
176                     break;
177                 case 1800:
178                     str = "Visual Studio 2013";
179                     break;
180                 case 1700:
181                     str = "Visual Studio 2011";
182                     break;
183                 case 1600:
184                     str = "Visual Studio 2010";
185                     break;
186                 case 1500:
187                     str = "Visual Studio 2008";
188                     break;
189                 case 1400:
190                     str = "Visual Studio 2005";
191                     break;
192                 case 1310:
193                     str = "Visual Studio 2003";
194                     break;
195                 case 1300:
196                     str = "Visual Studio 2002";
197                     break;
198             }
199         }
200     } else if( 0 == os.compare("Darwin")) {
201         str = "Mac OS X :";
202         str += GET_COMPILER_INFO;
203     } else if( 0 == os.compare("Linux")){
204         str = "Linux :";
205         str = GET_COMPILER_INFO;
206     } else {
207         str = GET_COMPILER_INFO;
208     }
209 
210     return str;
211 }
212 
213 }
214