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