00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(VMDTKCON)
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <stdarg.h>
00029 #include <string.h>
00030 #include <errno.h>
00031
00032 #include "vmdconsole.h"
00033 #include "WKFThreads.h"
00034
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif
00038
00039
00040 struct vmdcon_msg
00041 {
00042 char *txt;
00043 int lvl;
00044 struct vmdcon_msg *next;
00045 };
00046
00047 static struct vmdcon_msg *vmdcon_pending=NULL;
00048 static struct vmdcon_msg *vmdcon_lastmsg=NULL;
00049
00050 static struct vmdcon_msg *vmdcon_logmsgs=NULL;
00051 static struct vmdcon_msg *vmdcon_lastlog=NULL;
00052 static int vmdcon_max_loglen=2000;
00053 static int vmdcon_loglen=0;
00054
00055
00056 static const int vmdcon_bufsz=4092;
00057
00058
00059 static char *vmdcon_wpath=NULL;
00060
00061
00062 static char *vmdcon_mark=NULL;
00063
00064
00065 static void *vmdcon_interp=NULL;
00066
00067
00068 static int vmdcon_status=VMDCON_UNDEF;
00069
00070
00071 static int vmdcon_loglvl=VMDCON_ALL;
00072
00073
00074 static wkf_mutex_t vmdcon_status_lock;
00075 static wkf_mutex_t vmdcon_output_lock;
00076
00077
00078 void vmdcon_init(void)
00079 {
00080 wkf_mutex_init(&vmdcon_status_lock);
00081 wkf_mutex_init(&vmdcon_output_lock);
00082 vmdcon_set_status(VMDCON_NONE, NULL);
00083 }
00084
00085
00086 int vmdcon_get_status(void)
00087 {
00088 return vmdcon_status;
00089 }
00090
00091
00092 void vmdcon_set_status(int status, void *interp)
00093 {
00094 wkf_mutex_lock(&vmdcon_status_lock);
00095 if (interp != NULL) vmdcon_interp=interp;
00096 vmdcon_status=status;
00097 tcl_vmdcon_set_status_var(vmdcon_interp, status);
00098 wkf_mutex_unlock(&vmdcon_status_lock);
00099 }
00100
00101
00102 void vmdcon_set_loglvl(int lvl)
00103 {
00104 wkf_mutex_lock(&vmdcon_status_lock);
00105 vmdcon_loglvl=lvl;
00106 wkf_mutex_unlock(&vmdcon_status_lock);
00107 }
00108
00109
00110 int vmdcon_get_loglvl(void)
00111 {
00112 return vmdcon_loglvl;
00113 }
00114
00115
00116 void vmdcon_use_text(void *interp)
00117 {
00118 vmdcon_set_status(VMDCON_TEXT, interp);
00119 }
00120
00121
00122 void vmdcon_use_widget(void *interp)
00123 {
00124 vmdcon_set_status(VMDCON_WIDGET, interp);
00125 }
00126
00127
00128
00129
00130
00131
00132 int vmdcon_register(const char *w_path, const char *mark, void *interp)
00133 {
00134 wkf_mutex_lock(&vmdcon_status_lock);
00135 vmdcon_interp=interp;
00136
00137
00138 if(w_path == NULL) {
00139 if (vmdcon_wpath != NULL) {
00140 free(vmdcon_wpath);
00141 free(vmdcon_mark);
00142 }
00143 vmdcon_wpath=NULL;
00144 vmdcon_mark=NULL;
00145
00146 if (vmdcon_status == VMDCON_WIDGET) vmdcon_status=VMDCON_NONE;
00147 } else {
00148 int len;
00149
00150 if (vmdcon_wpath != NULL) {
00151 free(vmdcon_wpath);
00152 free(vmdcon_mark);
00153 }
00154
00155 len=strlen(w_path);
00156 vmdcon_wpath=(char*)malloc(len+1);
00157 strcpy(vmdcon_wpath, w_path);
00158 len=strlen(mark);
00159 vmdcon_mark=(char*)malloc(len+1);
00160 strcpy(vmdcon_mark, mark);
00161 }
00162 wkf_mutex_unlock(&vmdcon_status_lock);
00163
00164
00165 return vmdcon_purge();
00166 }
00167
00168
00169 int vmdcon_showlog(void)
00170 {
00171 struct vmdcon_msg *log, *msg;
00172
00173 wkf_mutex_lock(&vmdcon_output_lock);
00174 log=vmdcon_logmsgs;
00175 do {
00176
00177 msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
00178 msg->txt=(char *) malloc(strlen(log->txt)+1);
00179 msg->lvl=VMDCON_ALWAYS;
00180 strcpy(msg->txt,log->txt);
00181 msg->next=NULL;
00182
00183 if (vmdcon_pending == NULL) {
00184 vmdcon_pending=msg;
00185 vmdcon_lastmsg=msg;
00186 } else {
00187 vmdcon_lastmsg->next=msg;
00188 vmdcon_lastmsg=msg;
00189 }
00190 log=log->next;
00191 } while (log->next != NULL);
00192
00193
00194 msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
00195 msg->txt=(char *) malloc(strlen("\n")+1);
00196 msg->lvl=VMDCON_ALWAYS;
00197 strcpy(msg->txt,"\n");
00198 msg->next=NULL;
00199
00200 if (vmdcon_pending == NULL) {
00201 vmdcon_pending=msg;
00202 vmdcon_lastmsg=msg;
00203 } else {
00204 vmdcon_lastmsg->next=msg;
00205 vmdcon_lastmsg=msg;
00206 }
00207 log=log->next;
00208
00209 wkf_mutex_unlock(&vmdcon_output_lock);
00210 return vmdcon_purge();
00211 }
00212
00213
00214
00215
00216 int vmdcon_append(int level, const char *txt, int len)
00217 {
00218 struct vmdcon_msg *msg;
00219 char *buf;
00220
00221
00222 if (len == 0 ) return 0;
00223 if (len < 0) {
00224 len=strlen(txt);
00225 }
00226
00227 wkf_mutex_lock(&vmdcon_output_lock);
00228
00229
00230
00231 if (level >= vmdcon_loglvl) {
00232
00233 buf=(char *)calloc(len+1,1);
00234 strncpy(buf,txt,len);
00235
00236 msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
00237 msg->txt=buf;
00238 msg->lvl=level;
00239 msg->next=NULL;
00240
00241 if (vmdcon_pending == NULL) {
00242 vmdcon_pending=msg;
00243 vmdcon_lastmsg=msg;
00244 } else {
00245 vmdcon_lastmsg->next=msg;
00246 vmdcon_lastmsg=msg;
00247 }
00248 }
00249
00250
00251
00252
00253 buf=(char *)calloc(len+1,1);
00254 strncpy(buf,txt,len);
00255
00256
00257 msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
00258 msg->txt=buf;
00259 msg->lvl=level;
00260 msg->next=NULL;
00261
00262 if (vmdcon_logmsgs == NULL) {
00263 vmdcon_logmsgs=msg;
00264 vmdcon_lastlog=msg;
00265 ++vmdcon_loglen;
00266 } else {
00267 vmdcon_lastlog->next=msg;
00268 vmdcon_lastlog=msg;
00269 ++vmdcon_loglen;
00270 }
00271
00272
00273
00274 while (vmdcon_loglen > vmdcon_max_loglen) {
00275 msg=vmdcon_logmsgs;
00276 vmdcon_logmsgs=msg->next;
00277 free(msg->txt);
00278 free(msg);
00279 --vmdcon_loglen;
00280 }
00281
00282 wkf_mutex_unlock(&vmdcon_output_lock);
00283
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292 int vmdcon_purge(void)
00293 {
00294 struct vmdcon_msg *msg;
00295 const char *res;
00296
00297 wkf_mutex_lock(&vmdcon_status_lock);
00298
00299 if ( ! ((vmdcon_status == VMDCON_UNDEF) || (vmdcon_status == VMDCON_NONE)
00300 || ((vmdcon_status == VMDCON_WIDGET) &&
00301 ((vmdcon_interp == NULL) || (vmdcon_wpath == NULL))) ) ) {
00302
00303 wkf_mutex_lock(&vmdcon_output_lock);
00304 while (vmdcon_pending != NULL) {
00305 msg=vmdcon_pending;
00306
00307 switch (vmdcon_status) {
00308 case VMDCON_TEXT:
00309 fputs(msg->txt,stdout);
00310 break;
00311
00312 case VMDCON_WIDGET:
00313 res = tcl_vmdcon_insert(vmdcon_interp, vmdcon_wpath,
00314 vmdcon_mark, msg->txt);
00315
00316
00317
00318 if (res) {
00319 wkf_mutex_unlock(&vmdcon_status_lock);
00320 vmdcon_register(NULL, NULL, vmdcon_interp);
00321 wkf_mutex_unlock(&vmdcon_output_lock);
00322 vmdcon_printf(VMDCON_ERROR,
00323 "Problem writing to text widget: %s\n", res);
00324 return 1;
00325 }
00326 break;
00327
00328 default:
00329
00330 return 1;
00331 }
00332 free(msg->txt);
00333 vmdcon_pending=msg->next;
00334 free(msg);
00335
00336 }
00337 if (vmdcon_status == VMDCON_TEXT)
00338 fflush(stdout);
00339
00340 wkf_mutex_unlock(&vmdcon_output_lock);
00341 }
00342 wkf_mutex_unlock(&vmdcon_status_lock);
00343 return 0;
00344 }
00345
00346
00347
00348
00349 int vmdcon_printf(const int lvl, const char *fmt, ...)
00350 {
00351 va_list ap;
00352 char *buf;
00353 int len;
00354
00355
00356 buf = (char *)malloc(vmdcon_bufsz);
00357 va_start(ap, fmt);
00358 len = vsprintf(buf, fmt, ap);
00359
00360
00361
00362 if (len >= vmdcon_bufsz) {
00363 fprintf(stderr,"WARNING! buffer overflow in vmdcon_printf. %d vs %d.\n",
00364 len, vmdcon_bufsz);
00365 free(buf);
00366 errno=ERANGE;
00367 return -1;
00368 }
00369
00370
00371 switch (lvl) {
00372 case VMDCON_INFO:
00373 vmdcon_append(lvl, "Info) ", 6);
00374 break;
00375
00376 case VMDCON_WARN:
00377 vmdcon_append(lvl, "Warning) ", 9);
00378 break;
00379
00380 case VMDCON_ERROR:
00381 vmdcon_append(lvl, "ERROR) ", 7);
00382 break;
00383
00384 default:
00385 break;
00386 }
00387
00388 vmdcon_append(lvl, buf, len);
00389 vmdcon_purge();
00390
00391 free(buf);
00392 return 0;
00393 }
00394
00395
00396 int vmdcon_fputs(const int lvl, const char *string)
00397 {
00398
00399 switch (lvl) {
00400 case VMDCON_INFO:
00401 vmdcon_append(lvl, "Info) ", 6);
00402 break;
00403
00404 case VMDCON_WARN:
00405 vmdcon_append(lvl, "Warning) ", 9);
00406 break;
00407
00408 case VMDCON_ERROR:
00409 vmdcon_append(lvl, "ERROR) ", 7);
00410 break;
00411
00412 default:
00413 break;
00414 }
00415
00416 vmdcon_append(lvl, string, -1);
00417 vmdcon_purge();
00418
00419 return 0;
00420 }
00421
00422 #ifdef __cplusplus
00423 }
00424 #endif
00425
00426 #endif