1 | #if WIN32 |
---|
2 | #include <windows.h> |
---|
3 | #include <share.h> |
---|
4 | #endif |
---|
5 | |
---|
6 | #include "muscle.h" |
---|
7 | #include <stdio.h> |
---|
8 | #include <stdlib.h> |
---|
9 | #include <stdarg.h> |
---|
10 | #include <string.h> |
---|
11 | #include <math.h> |
---|
12 | #include <assert.h> |
---|
13 | #include <time.h> |
---|
14 | #include <errno.h> |
---|
15 | |
---|
16 | #ifndef MAX_PATH |
---|
17 | #define MAX_PATH 260 |
---|
18 | #endif |
---|
19 | |
---|
20 | static char g_strListFileName[MAX_PATH]; |
---|
21 | static bool g_bListFileAppend = false; |
---|
22 | |
---|
23 | static SEQWEIGHT g_SeqWeight = SEQWEIGHT_Undefined; |
---|
24 | |
---|
25 | void SetSeqWeightMethod(SEQWEIGHT Method) |
---|
26 | { |
---|
27 | g_SeqWeight = Method; |
---|
28 | } |
---|
29 | |
---|
30 | SEQWEIGHT GetSeqWeightMethod() |
---|
31 | { |
---|
32 | return g_SeqWeight; |
---|
33 | } |
---|
34 | |
---|
35 | void SetListFileName(const char *ptrListFileName, bool bAppend) |
---|
36 | { |
---|
37 | assert(strlen(ptrListFileName) < MAX_PATH); |
---|
38 | strcpy(g_strListFileName, ptrListFileName); |
---|
39 | g_bListFileAppend = bAppend; |
---|
40 | } |
---|
41 | |
---|
42 | void Log(const char szFormat[], ...) |
---|
43 | { |
---|
44 | if (0 == g_strListFileName[0]) |
---|
45 | return; |
---|
46 | |
---|
47 | static FILE *f = NULL; |
---|
48 | const char *mode; |
---|
49 | if (g_bListFileAppend) |
---|
50 | mode = "a"; |
---|
51 | else |
---|
52 | mode = "w"; |
---|
53 | if (NULL == f) |
---|
54 | f = _fsopen(g_strListFileName, mode, _SH_DENYNO); |
---|
55 | if (NULL == f) |
---|
56 | { |
---|
57 | perror(g_strListFileName); |
---|
58 | exit(EXIT_NotStarted); |
---|
59 | } |
---|
60 | |
---|
61 | char szStr[4096]; |
---|
62 | va_list ArgList; |
---|
63 | va_start(ArgList, szFormat); |
---|
64 | vsprintf(szStr, szFormat, ArgList); |
---|
65 | fprintf(f, "%s", szStr); |
---|
66 | fflush(f); |
---|
67 | } |
---|
68 | |
---|
69 | const char *GetTimeAsStr() |
---|
70 | { |
---|
71 | static char szStr[32]; |
---|
72 | time_t t; |
---|
73 | time(&t); |
---|
74 | struct tm *ptmCurrentTime = localtime(&t); |
---|
75 | strcpy(szStr, asctime(ptmCurrentTime)); |
---|
76 | assert('\n' == szStr[24]); |
---|
77 | szStr[24] = 0; |
---|
78 | return szStr; |
---|
79 | } |
---|
80 | |
---|
81 | // Exit immediately with error message, printf-style. |
---|
82 | void Quit(const char szFormat[], ...) |
---|
83 | { |
---|
84 | va_list ArgList; |
---|
85 | char szStr[4096]; |
---|
86 | |
---|
87 | va_start(ArgList, szFormat); |
---|
88 | vsprintf(szStr, szFormat, ArgList); |
---|
89 | |
---|
90 | fprintf(stderr, "\n*** ERROR *** %s\n", szStr); |
---|
91 | |
---|
92 | Log("\n*** FATAL ERROR *** "); |
---|
93 | Log("%s\n", szStr); |
---|
94 | Log("Stopped %s\n", GetTimeAsStr()); |
---|
95 | |
---|
96 | #ifdef WIN32 |
---|
97 | if (IsDebuggerPresent()) |
---|
98 | { |
---|
99 | int iBtn = MessageBox(NULL, szStr, "muscle", MB_ICONERROR | MB_OKCANCEL); |
---|
100 | if (IDCANCEL == iBtn) |
---|
101 | Break(); |
---|
102 | } |
---|
103 | #endif |
---|
104 | exit(EXIT_FatalError); |
---|
105 | } |
---|
106 | |
---|
107 | void Warning(const char szFormat[], ...) |
---|
108 | { |
---|
109 | va_list ArgList; |
---|
110 | char szStr[4096]; |
---|
111 | |
---|
112 | va_start(ArgList, szFormat); |
---|
113 | vsprintf(szStr, szFormat, ArgList); |
---|
114 | |
---|
115 | fprintf(stderr, "\n*** WARNING *** %s\n", szStr); |
---|
116 | Log("\n*** WARNING *** %s\n", szStr); |
---|
117 | } |
---|
118 | |
---|
119 | // Remove leading and trailing blanks from string |
---|
120 | void TrimBlanks(char szStr[]) |
---|
121 | { |
---|
122 | TrimLeadingBlanks(szStr); |
---|
123 | TrimTrailingBlanks(szStr); |
---|
124 | } |
---|
125 | |
---|
126 | void TrimLeadingBlanks(char szStr[]) |
---|
127 | { |
---|
128 | size_t n = strlen(szStr); |
---|
129 | while (szStr[0] == ' ') |
---|
130 | { |
---|
131 | memmove(szStr, szStr+1, n); |
---|
132 | szStr[--n] = 0; |
---|
133 | } |
---|
134 | } |
---|
135 | |
---|
136 | void TrimTrailingBlanks(char szStr[]) |
---|
137 | { |
---|
138 | size_t n = strlen(szStr); |
---|
139 | while (n > 0 && szStr[n-1] == ' ') |
---|
140 | szStr[--n] = 0; |
---|
141 | } |
---|
142 | |
---|
143 | bool Verbose() |
---|
144 | { |
---|
145 | return true; |
---|
146 | } |
---|
147 | |
---|
148 | SCORE StrToScore(const char *pszStr) |
---|
149 | { |
---|
150 | return (SCORE) atof(pszStr); |
---|
151 | } |
---|
152 | |
---|
153 | void StripWhitespace(char szStr[]) |
---|
154 | { |
---|
155 | unsigned uOutPos = 0; |
---|
156 | unsigned uInPos = 0; |
---|
157 | while (char c = szStr[uInPos++]) |
---|
158 | if (' ' != c && '\t' != c && '\n' != c && '\r' != c) |
---|
159 | szStr[uOutPos++] = c; |
---|
160 | szStr[uOutPos] = 0; |
---|
161 | } |
---|
162 | |
---|
163 | void StripGaps(char szStr[]) |
---|
164 | { |
---|
165 | unsigned uOutPos = 0; |
---|
166 | unsigned uInPos = 0; |
---|
167 | while (char c = szStr[uInPos++]) |
---|
168 | if ('-' != c) |
---|
169 | szStr[uOutPos++] = c; |
---|
170 | szStr[uOutPos] = 0; |
---|
171 | } |
---|
172 | |
---|
173 | bool IsValidSignedInteger(const char *Str) |
---|
174 | { |
---|
175 | if (0 == strlen(Str)) |
---|
176 | return false; |
---|
177 | if ('+' == *Str || '-' == *Str) |
---|
178 | ++Str; |
---|
179 | while (char c = *Str++) |
---|
180 | if (!isdigit(c)) |
---|
181 | return false; |
---|
182 | return true; |
---|
183 | } |
---|
184 | |
---|
185 | bool IsValidInteger(const char *Str) |
---|
186 | { |
---|
187 | if (0 == strlen(Str)) |
---|
188 | return false; |
---|
189 | while (char c = *Str++) |
---|
190 | if (!isdigit(c)) |
---|
191 | return false; |
---|
192 | return true; |
---|
193 | } |
---|
194 | |
---|
195 | // Is c valid as first character in an identifier? |
---|
196 | bool isidentf(char c) |
---|
197 | { |
---|
198 | return isalpha(c) || '_' == c; |
---|
199 | } |
---|
200 | |
---|
201 | // Is c valid character in an identifier? |
---|
202 | bool isident(char c) |
---|
203 | { |
---|
204 | return isalpha(c) || isdigit(c) || '_' == c; |
---|
205 | } |
---|
206 | |
---|
207 | bool IsValidIdentifier(const char *Str) |
---|
208 | { |
---|
209 | if (!isidentf(Str[0])) |
---|
210 | return false; |
---|
211 | while (char c = *Str++) |
---|
212 | if (!isident(c)) |
---|
213 | return false; |
---|
214 | return true; |
---|
215 | } |
---|
216 | |
---|
217 | void SetLogFile() |
---|
218 | { |
---|
219 | const char *strFileName = ValueOpt("loga"); |
---|
220 | if (0 != strFileName) |
---|
221 | g_bListFileAppend = true; |
---|
222 | else |
---|
223 | strFileName = ValueOpt("log"); |
---|
224 | if (0 == strFileName) |
---|
225 | return; |
---|
226 | strcpy(g_strListFileName, strFileName); |
---|
227 | } |
---|
228 | |
---|
229 | // Get filename, stripping any extension and directory parts. |
---|
230 | void NameFromPath(const char szPath[], char szName[], unsigned uBytes) |
---|
231 | { |
---|
232 | if (0 == uBytes) |
---|
233 | return; |
---|
234 | const char *pstrLastSlash = strrchr(szPath, '/'); |
---|
235 | const char *pstrLastBackslash = strrchr(szPath, '\\'); |
---|
236 | const char *pstrLastDot = strrchr(szPath, '.'); |
---|
237 | const char *pstrLastSep = pstrLastSlash > pstrLastBackslash ? |
---|
238 | pstrLastSlash : pstrLastBackslash; |
---|
239 | const char *pstrBegin = pstrLastSep ? pstrLastSep + 1 : szPath; |
---|
240 | const char *pstrEnd = pstrLastDot ? pstrLastDot - 1 : szPath + strlen(szPath); |
---|
241 | unsigned uNameLength = (unsigned) (pstrEnd - pstrBegin + 1); |
---|
242 | if (uNameLength > uBytes - 1) |
---|
243 | uNameLength = uBytes - 1; |
---|
244 | memcpy(szName, pstrBegin, uNameLength); |
---|
245 | szName[uNameLength] = 0; |
---|
246 | } |
---|
247 | |
---|
248 | char *strsave(const char *s) |
---|
249 | { |
---|
250 | char *ptrCopy = strdup(s); |
---|
251 | if (0 == ptrCopy) |
---|
252 | Quit("Out of memory"); |
---|
253 | return ptrCopy; |
---|
254 | } |
---|
255 | |
---|
256 | bool IsValidFloatChar(char c) |
---|
257 | { |
---|
258 | return isdigit(c) || '.' == c || 'e' == c || 'E' == c || 'd' == c || |
---|
259 | 'D' == c || '.' == c || '+' == c || '-' == c; |
---|
260 | } |
---|
261 | |
---|
262 | void Call_MY_ASSERT(const char *file, int line, bool b, const char *msg) |
---|
263 | { |
---|
264 | if (b) |
---|
265 | return; |
---|
266 | Quit("%s(%d): MY_ASSERT(%s)", file, line, msg); |
---|
267 | } |
---|
268 | |
---|
269 | static size_t g_MemTotal; |
---|
270 | |
---|
271 | void MemPlus(size_t Bytes, char *Where) |
---|
272 | { |
---|
273 | g_MemTotal += Bytes; |
---|
274 | Log("+%10u %6u %6u %s\n", |
---|
275 | (unsigned) Bytes, |
---|
276 | (unsigned) GetMemUseMB(), |
---|
277 | (unsigned) (g_MemTotal/1000000), |
---|
278 | Where); |
---|
279 | } |
---|
280 | |
---|
281 | void MemMinus(size_t Bytes, char *Where) |
---|
282 | { |
---|
283 | g_MemTotal -= Bytes; |
---|
284 | Log("-%10u %6u %6u %s\n", |
---|
285 | (unsigned) Bytes, |
---|
286 | (unsigned) GetMemUseMB(), |
---|
287 | (unsigned) (g_MemTotal/1000000), |
---|
288 | Where); |
---|
289 | } |
---|