00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <string.h>
00024 #include <ctype.h>
00025 #include <math.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028
00029 #if defined(_MSC_VER)
00030 #include <windows.h>
00031 #include <conio.h>
00032 #else
00033 #include <unistd.h>
00034 #include <sys/time.h>
00035 #include <errno.h>
00036
00037 #if defined(ARCH_AIX4)
00038 #include <strings.h>
00039 #endif
00040
00041 #if defined(__irix)
00042 #include <bstring.h>
00043 #endif
00044
00045 #if defined(__hpux)
00046 #include <time.h>
00047 #endif // HPUX
00048 #endif // _MSC_VER
00049
00050 #if defined(AIXUSEPERFSTAT)
00051 #include <libperfstat.h>
00052 #endif
00053
00054 #if defined(__APPLE__)
00055 #include <sys/sysctl.h>
00056 #endif
00057
00058 #include "utilities.h"
00059
00060
00061
00062
00063 char *combine_arguments(int argc, const char **argv, int n) {
00064 char *newstr = NULL;
00065
00066 if(argc > 0 && n < argc && n >= 0) {
00067 int i, sl = 0;
00068
00069 for(i=n; i < argc; i++)
00070 sl += strlen(argv[i]);
00071
00072
00073 if(sl) {
00074 newstr = new char[sl + 8 + argc - n];
00075 *newstr = '\0';
00076 for(i=n; i < argc; i++) {
00077 if(i != n)
00078 strcat(newstr," ");
00079 strcat(newstr, argv[i]);
00080 }
00081 }
00082 }
00083
00084
00085 return newstr;
00086 }
00087
00088
00089
00090 char *stringdup(const char *s) {
00091 char *rs;
00092
00093 if(!s)
00094 return NULL;
00095
00096 rs = new char[strlen(s) + 1];
00097 strcpy(rs,s);
00098
00099 return rs;
00100 }
00101
00102
00103
00104 char *stringtoupper(char *s) {
00105 if (s != NULL) {
00106 int i;
00107 int sz = strlen(s);
00108 for(i=0; i<sz; i++)
00109 s[i] = toupper(s[i]);
00110 }
00111
00112 return s;
00113 }
00114
00115 void stripslashes(char *str) {
00116 while (strlen(str) > 0 && str[strlen(str) - 1] == '/') {
00117 str[strlen(str) - 1] = '\0';
00118 }
00119 }
00120
00121
00122 int strupcmp(const char *a, const char *b) {
00123 char *ua, *ub;
00124 int retval;
00125
00126 ua = stringtoupper(stringdup(a));
00127 ub = stringtoupper(stringdup(b));
00128
00129 retval = strcmp(ua,ub);
00130
00131 delete [] ub;
00132 delete [] ua;
00133
00134 return retval;
00135 }
00136
00137
00138
00139 int strupncmp(const char *a, const char *b, int n) {
00140 #if defined(ARCH_AIX3) || defined(ARCH_AIX4) || defined(_MSC_VER)
00141 while (n-- > 0) {
00142 if (toupper(*a) != toupper(*b)) {
00143 return toupper(*b) - toupper(*a);
00144 }
00145 if (*a == 0) return 0;
00146 a++; b++;
00147 }
00148 return 0;
00149 #else
00150 return strncasecmp(a, b, n);
00151 #endif
00152 }
00153
00154
00155
00156
00157
00158 void breakup_filename(const char *full, char **path, char **name) {
00159 const char *namestrt;
00160 int pathlen;
00161
00162 if(full == NULL) {
00163 *path = *name = NULL;
00164 return;
00165 } else if (strlen(full) == 0) {
00166 *path = new char[1];
00167 *name = new char[1];
00168 (*path)[0] = (*name)[0] = '\0';
00169 return;
00170 }
00171
00172
00173 if((namestrt = strrchr(full,'/')) != NULL && strlen(namestrt) > 0) {
00174 namestrt++;
00175 } else {
00176 namestrt = full;
00177 }
00178
00179
00180 *name = stringdup(namestrt);
00181
00182
00183 pathlen = strlen(full) - strlen(*name);
00184 *path = new char[pathlen + 1];
00185 strncpy(*path,full,pathlen);
00186 (*path)[pathlen] = '\0';
00187 }
00188
00189
00190 char *str_tokenize(const char *newcmd, int *argc, char *argv[]) {
00191 char *cmd;
00192 const char *cmdstart;
00193 cmdstart = newcmd;
00194
00195
00196
00197
00198 while (cmdstart != NULL &&
00199 (*cmdstart == ' ' ||
00200 *cmdstart == ',' ||
00201 *cmdstart == ';' ||
00202 *cmdstart == '\t' ||
00203 *cmdstart == '\n')) {
00204 cmdstart++;
00205 }
00206
00207 cmd = stringdup(cmdstart);
00208 *argc = 0;
00209
00210
00211 argv[*argc] = strtok(cmd, " ,;\t\n");
00212
00213
00214 while(argv[*argc] != NULL) {
00215
00216 if(argv[*argc][0] == '#') {
00217 break;
00218 } else {
00219 (*argc)++;
00220 }
00221
00222
00223 argv[*argc] = strtok(NULL," ,;\t\n");
00224 }
00225
00226 return (*argc > 0 ? argv[0] : (char *) NULL);
00227 }
00228
00229
00230
00231 double time_of_day(void) {
00232 #if defined(_MSC_VER)
00233 double t;
00234
00235 t = GetTickCount();
00236 t = t / 1000.0;
00237
00238 return t;
00239 #else
00240 struct timeval tm;
00241 struct timezone tz;
00242
00243 gettimeofday(&tm, &tz);
00244 return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
00245 #endif
00246 }
00247
00248
00249 int vmd_check_stdin(void) {
00250 #if defined(_MSC_VER)
00251 if (_kbhit() != 0)
00252 return TRUE;
00253 else
00254 return FALSE;
00255 #else
00256 fd_set readvec;
00257 struct timeval timeout;
00258 int ret, stdin_fd;
00259
00260 timeout.tv_sec = 0;
00261 timeout.tv_usec = 0;
00262 stdin_fd = 0;
00263 FD_ZERO(&readvec);
00264 FD_SET(stdin_fd, &readvec);
00265
00266 #if !defined(ARCH_AIX3)
00267 ret = select(16, &readvec, NULL, NULL, &timeout);
00268 #else
00269 ret = select(16, (int *)(&readvec), NULL, NULL, &timeout);
00270 #endif
00271
00272 if (ret == -1) {
00273 if (errno != EINTR)
00274 printf("select() error while attempting to read text input.\n");
00275 return FALSE;
00276 } else if (ret == 0) {
00277 return FALSE;
00278 }
00279 return TRUE;
00280 #endif
00281 }
00282
00283
00284
00285 char *vmd_username(void) {
00286 #if defined(_MSC_VER)
00287 char username[1024];
00288 unsigned long size = 1023;
00289
00290 if (GetUserName((char *) &username, &size)) {
00291 return stringdup(username);
00292 }
00293 else {
00294 return stringdup("Windows User");
00295 }
00296 #else
00297 #if defined(ARCH_FREEBSD) || defined(ARCH_FREEBSDAMD64) || defined(__APPLE__) || defined(__linux)
00298 return stringdup(getlogin());
00299 #else
00300 return stringdup(cuserid(NULL));
00301 #endif
00302 #endif
00303 }
00304
00305 int vmd_getuid(void) {
00306 #if defined(_MSC_VER)
00307 return 0;
00308 #else
00309 return getuid();
00310 #endif
00311 }
00312
00313
00314
00315
00316 float * cross_prod(float *x1, const float *x2, const float *x3)
00317 {
00318 x1[0] = x2[1]*x3[2] - x3[1]*x2[2];
00319 x1[1] = -x2[0]*x3[2] + x3[0]*x2[2];
00320 x1[2] = x2[0]*x3[1] - x3[0]*x2[1];
00321 return x1;
00322 }
00323
00324
00325
00326 float * vec_normalize(float *vect) {
00327 float len = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
00328
00329
00330 if (len > 0) {
00331 float rescale = 1.0f / sqrtf(len);
00332 vect[0] *= rescale;
00333 vect[1] *= rescale;
00334 vect[2] *= rescale;
00335 }
00336
00337 return vect;
00338 }
00339
00340
00341
00342 float norm(const float *vect) {
00343 return sqrtf(vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2]);
00344 }
00345
00346
00347
00348 int tri_degenerate(const float * v0, const float * v1, const float * v2) {
00349 float s1[3], s2[3], s1_length, s2_length;
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 s1[0] = v0[0] - v1[0];
00367 s1[1] = v0[1] - v1[1];
00368 s1[2] = v0[2] - v1[2];
00369
00370 s2[0] = v0[0] - v2[0];
00371 s2[1] = v0[1] - v2[1];
00372 s2[2] = v0[2] - v2[2];
00373
00374 s1_length = sqrtf(s1[0]*s1[0] + s1[1]*s1[1] + s1[2]*s1[2]);
00375 s2_length = sqrtf(s2[0]*s2[0] + s2[1]*s2[1] + s2[2]*s2[2]);
00376
00377
00378
00379
00380
00381
00382 s2_length = 1.0f / (s1_length*s2_length);
00383 s1_length = s2_length * (s1[0]*s2[0] + s1[1]*s2[1] + s1[2]*s2[2]);
00384
00385
00386 if ((s1_length >= 1.0 ) || (s1_length <= -1.0))
00387 return 1;
00388 else
00389 return 0;
00390 }
00391
00392
00393
00394 float angle(const float *a, const float *b) {
00395 float ab[3];
00396 cross_prod(ab, a, b);
00397 float psin = sqrtf(dot_prod(ab, ab));
00398 float pcos = dot_prod(a, b);
00399 return 57.2958f * (float) atan2(psin, pcos);
00400 }
00401
00402
00403
00404
00405
00406 float dihedral(const float *a1,const float *a2,const float *a3,const float *a4)
00407 {
00408 float r1[3], r2[3], r3[3], n1[3], n2[3];
00409 vec_sub(r1, a2, a1);
00410 vec_sub(r2, a3, a2);
00411 vec_sub(r3, a4, a3);
00412
00413 cross_prod(n1, r1, r2);
00414 cross_prod(n2, r2, r3);
00415
00416 float psin = dot_prod(n1, r3) * sqrtf(dot_prod(r2, r2));
00417 float pcos = dot_prod(n1, n2);
00418
00419
00420
00421 return 57.2958f * (float) atan2(psin, pcos);
00422 }
00423
00424
00425 float distance(const float *a, const float *b) {
00426 return sqrtf(distance2(a,b));
00427 }
00428
00429 char *vmd_tempfile(const char *s) {
00430 char *envtxt, *TempDir;
00431
00432 if((envtxt = getenv("VMDTMPDIR")) != NULL) {
00433 TempDir = stringdup(envtxt);
00434 } else {
00435 #if defined(_MSC_VER)
00436 if ((envtxt = getenv("TMP")) != NULL) {
00437 TempDir = stringdup(envtxt);
00438 }
00439 else if ((envtxt = getenv("TEMP")) != NULL) {
00440 TempDir = stringdup(envtxt);
00441 }
00442 else {
00443 TempDir = stringdup("c:\\\\");
00444 }
00445 #else
00446 TempDir = stringdup("/tmp");
00447 #endif
00448 }
00449 stripslashes(TempDir);
00450
00451 char *tmpfilebuf = new char[1024];
00452
00453
00454 strcpy(tmpfilebuf, TempDir);
00455
00456 #if defined(_MSC_VER)
00457 strcat(tmpfilebuf, "\\");
00458 strncat(tmpfilebuf, s, 1022 - strlen(TempDir));
00459 #else
00460 strcat(tmpfilebuf, "/");
00461 strncat(tmpfilebuf, s, 1022 - strlen(TempDir));
00462 #endif
00463
00464 tmpfilebuf[1023] = '\0';
00465
00466 delete [] TempDir;
00467
00468
00469 return tmpfilebuf;
00470 }
00471
00472
00473 int vmd_delete_file(const char * path) {
00474 #if defined(_MSC_VER)
00475 if (DeleteFile(path) == 0)
00476 return -1;
00477 else
00478 return 0;
00479 #else
00480 return unlink(path);
00481 #endif
00482 }
00483
00484 void vmd_sleep(int secs) {
00485 #if defined(_MSC_VER)
00486 Sleep(secs * 1000);
00487 #else
00488 sleep(secs);
00489 #endif
00490 }
00491
00492 void vmd_msleep(int msecs) {
00493 #if defined(_MSC_VER)
00494 Sleep(msecs);
00495 #else
00496 struct timeval timeout;
00497 timeout.tv_sec = 0;
00498 timeout.tv_usec = 1000 * msecs;
00499 select(0, NULL, NULL, NULL, &timeout);
00500 #endif // _MSC_VER
00501 }
00502
00503 int vmd_system(const char* cmd) {
00504 return system(cmd);
00505 }
00506
00507
00511 long vmd_random(void) {
00512 #ifdef _MSC_VER
00513 return rand();
00514 #else
00515 return random();
00516 #endif
00517 }
00518
00519 void vmd_srandom(unsigned int seed) {
00520 #ifdef _MSC_VER
00521 srand(seed);
00522 #else
00523 srandom(seed);
00524 #endif
00525 }
00526
00529 float vmd_random_gaussian() {
00530 static bool cache = false;
00531 static float cached_value;
00532 const float RAND_FACTOR = 2.f/VMD_RAND_MAX;
00533 float r, s, w;
00534
00535 if (cache) {
00536 cache = false;
00537 return cached_value;
00538 }
00539 do {
00540 r = RAND_FACTOR*vmd_random()-1.f;
00541 s = RAND_FACTOR*vmd_random()-1.f;
00542 w = r*r+s*s;
00543 } while (w >= 1.f);
00544 w = sqrtf(-2.f*logf(w)/w);
00545 cached_value = s * w;
00546 cache = true;
00547 return (r*w);
00548 }
00549
00550
00553 long vmd_get_total_physmem_mb(void) {
00554 #if defined(_MSC_VER)
00555 MEMORYSTATUS memstat;
00556 GlobalMemoryStatus(&memstat);
00557 if (memstat.dwLength != sizeof(memstat))
00558 return -1;
00559 return memstat.dwTotalPhys/(1024 * 1024);
00560 #elif defined(__linux)
00561 FILE *fp;
00562 char meminfobuf[1024], *pos;
00563 size_t len;
00564
00565 fp = fopen("/proc/meminfo", "r");
00566 if (fp != NULL) {
00567 len = fread(meminfobuf,1,1024, fp);
00568 meminfobuf[1023] = 0;
00569 fclose(fp);
00570 if (len > 0) {
00571 pos=strstr(meminfobuf,"MemTotal:");
00572 if (pos == NULL)
00573 return -1;
00574 pos += 9; ;
00575 return strtol(pos, (char **)NULL, 10)/1024L;
00576 }
00577 }
00578 return -1;
00579 #elif defined(AIXUSEPERFSTAT) && defined(_AIX)
00580 perfstat_memory_total_t minfo;
00581 perfstat_memory_total(NULL, &minfo, sizeof(perfstat_memory_total_t), 1);
00582 return minfo.real_total*(4096/1024)/1024;
00583 #elif defined(_AIX)
00584 return (sysconf(_SC_AIX_REALMEM) / 1024);
00585 #elif defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
00586
00587 long pgsz = sysconf(_SC_PAGESIZE);
00588 long physpgs = sysconf(_SC_PHYS_PAGES);
00589 return ((pgsz / 1024) * physpgs) / 1024;
00590 #elif defined(__APPLE__)
00591
00592
00593 int rc;
00594 uint64_t membytes;
00595 size_t len = sizeof(membytes);
00596 if (sysctlbyname("hw.memsize", &membytes, &len, NULL, 0))
00597 return -1;
00598 return (membytes / (1024*1024));
00599 #else
00600 return -1;
00601 #endif
00602 }
00603
00604
00605
00608 long vmd_get_avail_physmem_mb(void) {
00609 #if defined(_MSC_VER)
00610 MEMORYSTATUS memstat;
00611 GlobalMemoryStatus(&memstat);
00612 if (memstat.dwLength != sizeof(memstat))
00613 return -1;
00614 return memstat.dwAvailPhys / (1024 * 1024);
00615 #elif defined(__linux)
00616 FILE *fp;
00617 char meminfobuf[1024], *pos;
00618 size_t len;
00619 long val;
00620
00621 fp = fopen("/proc/meminfo", "r");
00622 if (fp != NULL) {
00623 len = fread(meminfobuf,1,1024, fp);
00624 meminfobuf[1023] = 0;
00625 fclose(fp);
00626 if (len > 0) {
00627 val = 0L;
00628 pos=strstr(meminfobuf,"MemFree:");
00629 if (pos != NULL) {
00630 pos += 8; ;
00631 val += strtol(pos, (char **)NULL, 10);
00632 }
00633 pos=strstr(meminfobuf,"Buffers:");
00634 if (pos != NULL) {
00635 pos += 8; ;
00636 val += strtol(pos, (char **)NULL, 10);
00637 }
00638 pos=strstr(meminfobuf,"Cached:");
00639 if (pos != NULL) {
00640 pos += 8; ;
00641 val += strtol(pos, (char **)NULL, 10);
00642 }
00643 return val/1024L;
00644 } else {
00645 return -1;
00646 }
00647 } else {
00648 return -1;
00649 }
00650 #elif defined(AIXUSEPERFSTAT) && defined(_AIX)
00651 perfstat_memory_total_t minfo;
00652 perfstat_memory_total(NULL, &minfo, sizeof(perfstat_memory_total_t), 1);
00653 return minfo.real_free*(4096/1024)/1024;
00654 #elif defined(_SC_PAGESIZE) && defined(_SC_AVPHYS_PAGES)
00655
00656 long pgsz = sysconf(_SC_PAGESIZE);
00657 long avphyspgs = sysconf(_SC_AVPHYS_PAGES);
00658 return ((pgsz / 1024) * avphyspgs) / 1024;
00659 #elif defined(__APPLE__)
00660 #if 0
00661
00662
00663
00664 int rc;
00665 int membytes;
00666 size_t len = sizeof(membytes);
00667 if (sysctlbyname("hw.usermem", &membytes, &len, NULL, 0))
00668 return -1;
00669 return (membytes / (1024*1024));
00670 #else
00671 return -1;
00672 #endif
00673 #else
00674 return -1;
00675 #endif
00676 }
00677
00678
00680 long vmd_get_avail_physmem_percent(void) {
00681 double total, avail;
00682 total = (double) vmd_get_total_physmem_mb();
00683 avail = (double) vmd_get_avail_physmem_mb();
00684 if (total > 0.0 && avail >= 0.0)
00685 return (long) (avail / (total / 100.0));
00686
00687 return -1;
00688 }
00689
00690