00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #ifndef lint
00050 static const char RCSlog[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/log.c,v 14.12 2006/09/03 15:14:07 lbutler Exp $ (ARL)";
00051 #endif
00052
00053 #include "common.h"
00054
00055 #include <stdio.h>
00056 #include <ctype.h>
00057 #if defined(HAVE_STDARG_H)
00058 # include <stdarg.h>
00059 #else
00060 # if defined(HAVE_VARARGS_H)
00061 # include <varargs.h>
00062 # endif
00063 #endif
00064 #ifdef HAVE_STRING_H
00065 # include <string.h>
00066 #endif
00067
00068 #include "machine.h"
00069 #include "bu.h"
00070
00071 #if defined(HAVE_VARARGS_H) || defined(HAVE_STDARG_H)
00072 BU_EXTERN(void bu_vls_vprintf, (struct bu_vls *vls, const char *fmt, va_list ap));
00073 #endif
00074
00075 static int bu_log_indent_cur_level = 0;
00076
00077
00078
00079
00080
00081
00082 void
00083 bu_log_indent_delta(int delta)
00084 {
00085 if( (bu_log_indent_cur_level += delta) < 0 )
00086 bu_log_indent_cur_level = 0;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 void
00097 bu_log_indent_vls(struct bu_vls *v)
00098 {
00099 bu_vls_spaces( v, bu_log_indent_cur_level );
00100 }
00101
00102 #if 1
00103 struct bu_hook_list bu_log_hook_list = {
00104 { BU_LIST_HEAD_MAGIC,
00105 &bu_log_hook_list.l,
00106 &bu_log_hook_list.l
00107 },
00108 BUHOOK_NULL,
00109 GENPTR_NULL
00110 };
00111 #else
00112 struct bu_hook_list bu_log_hook_list;
00113 #endif
00114
00115 static int bu_log_first_time = 1;
00116 static int bu_log_hooks_called = 0;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void
00130 bu_log_add_hook(bu_hook_t func, genptr_t clientdata)
00131 {
00132 #if 0
00133 struct bu_hook_list *toadd;
00134
00135
00136
00137
00138 BU_GETSTRUCT(toadd, bu_hook_list);
00139 toadd->hookfunc = func;
00140 toadd->clientdata = clientdata;
00141 toadd->l.magic = BUHOOK_LIST_MAGIC;
00142
00143 BU_LIST_APPEND( &(bu_log_hook_list.l), &(toadd->l) );
00144 #else
00145 bu_add_hook(&bu_log_hook_list, func, clientdata);
00146 #endif
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 void
00157 bu_log_delete_hook(bu_hook_t func, genptr_t clientdata)
00158 {
00159 #if 0
00160 struct bu_hook_list *cur = &bu_log_hook_list;
00161
00162 for ( BU_LIST_FOR( cur, bu_hook_list, &(bu_log_hook_list.l) ) ) {
00163 if ( cur->hookfunc == func && cur->clientdata == clientdata) {
00164 struct bu_hook_list *old = BU_LIST_PLAST(bu_hook_list, cur);
00165 BU_LIST_DEQUEUE( &(cur->l) );
00166 bu_free((genptr_t)cur, "bu_log hook");
00167 cur = old;
00168 }
00169 }
00170 #else
00171 bu_delete_hook(&bu_log_hook_list, func, clientdata);
00172 #endif
00173 }
00174
00175 #if 1
00176 HIDDEN void
00177 bu_log_call_hooks(genptr_t buf)
00178 {
00179 #if 0
00180 bu_hook_t hookfunc;
00181 genptr_t clientdata;
00182 #endif
00183
00184 bu_log_hooks_called = 1;
00185
00186 #if 0
00187 hookfunc = BU_LIST_FIRST(bu_hook_list, &(bu_log_hook_list.l))->hookfunc;
00188 clientdata = BU_LIST_FIRST(bu_hook_list, &(bu_log_hook_list.l))->clientdata;
00189
00190 (hookfunc)( clientdata, buf);
00191 #else
00192 bu_call_hook(&bu_log_hook_list, buf);
00193 #endif
00194
00195 bu_log_hooks_called = 0;
00196 }
00197 #endif
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 HIDDEN void
00211 bu_log_do_indent_level(struct bu_vls *new, register char *old)
00212 {
00213 register int i;
00214
00215 while (*old) {
00216 bu_vls_putc(new, (int)(*old));
00217 if (*old == '\n') {
00218 i = bu_log_indent_cur_level;
00219 while (i-- > 0)
00220 bu_vls_putc(new, ' ');
00221 }
00222 ++old;
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 void
00233 bu_putchar(int c)
00234 {
00235 if ( BU_LIST_IS_EMPTY( &(bu_log_hook_list.l) ) ) {
00236 fputc(c, stderr);
00237 } else {
00238 char buf[2];
00239 buf[0] = (char)c;
00240 buf[1] = '\0';
00241 #if 1
00242 bu_log_call_hooks(buf);
00243 #else
00244 bu_call_hook(&bu_log_hook_list, (genptr_t)buf);
00245 #endif
00246 }
00247
00248 if (bu_log_indent_cur_level > 0 && c == '\n') {
00249 int i;
00250
00251 i = bu_log_indent_cur_level;
00252 while (i-- > 0)
00253 bu_putchar(' ');
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262 void
00263 #if defined(HAVE_STDARG_H)
00264 bu_log(char *fmt, ...)
00265 {
00266 va_list ap;
00267 #else
00268 # if defined(HAVE_VARARGS_H)
00269 bu_log(va_alist)
00270 va_dcl
00271 {
00272 va_list ap;
00273 char *fmt;
00274 # else
00275 bu_log(fmt, a,b,c,d,e,f,g,h,i,j)
00276 char *fmt;
00277 {
00278 # endif
00279 #endif
00280
00281 struct bu_vls output;
00282
00283 bu_vls_init(&output);
00284
00285 #if defined(HAVE_STDARG_H)
00286 va_start(ap, fmt);
00287
00288 if (!fmt || strlen(fmt) == 0) {
00289 return;
00290 }
00291
00292 if (bu_log_indent_cur_level > 0) {
00293 struct bu_vls newfmt;
00294
00295 bu_vls_init(&newfmt);
00296 bu_log_do_indent_level(&newfmt, fmt);
00297 bu_vls_vprintf(&output, bu_vls_addr(&newfmt), ap);
00298 bu_vls_free(&newfmt);
00299 } else {
00300 bu_vls_vprintf(&output, fmt, ap);
00301 }
00302 #else
00303 # if defined(HAVE_VARARGS_H)
00304 va_start(ap);
00305 fmt = va_arg(ap, char *);
00306
00307 if (!fmt || strlen(fmt) == 0) {
00308 return;
00309 }
00310
00311 if (bu_log_indent_cur_level > 0) {
00312 struct bu_vls newfmt;
00313
00314 bu_vls_init(&newfmt);
00315 bu_log_do_indent_level(&newfmt, fmt);
00316 bu_vls_vprintf(&output, bu_vls_addr(&newfmt), ap);
00317 bu_vls_free(&newfmt);
00318 } else {
00319 bu_vls_vprintf(&output, fmt, ap);
00320 }
00321 # else
00322 if (!fmt || strlen(fmt) == 0) {
00323 return;
00324 }
00325
00326 if (bu_log_indent_cur_level > 0) {
00327 struct bu_vls newfmt;
00328
00329 bu_vls_init(&newfmt);
00330 bu_log_do_indent_level(&newfmt, fmt);
00331 bu_vls_printf(&output, bu_vls_addr(&newfmt), a,b,c,d,e,f,g,h,i,j);
00332 bu_vls_free(&newfmt);
00333 } else {
00334 bu_vls_printf(&output, fmt, a,b,c,d,e,f,g,h,i,j);
00335 }
00336 # endif
00337 #endif
00338
00339 if ( BU_LIST_IS_EMPTY( &(bu_log_hook_list.l) ) || bu_log_hooks_called) {
00340 int ret;
00341 size_t len;
00342
00343 if (bu_log_first_time) {
00344 bu_setlinebuf(stderr);
00345 bu_log_first_time = 0;
00346 }
00347
00348 len = bu_vls_strlen(&output);
00349 if(len){
00350 bu_semaphore_acquire(BU_SEM_SYSCALL);
00351 ret = fwrite( bu_vls_addr(&output), len, 1, stderr );
00352 (void)fflush(stderr);
00353 bu_semaphore_release(BU_SEM_SYSCALL);
00354 if( ret != 1 ) bu_bomb("bu_log: write error");
00355 }
00356
00357 } else {
00358 #if 1
00359 bu_log_call_hooks(bu_vls_addr(&output));
00360 #else
00361 bu_call_hook(&bu_log_hook_list, (genptr_t)bu_vls_addr(&output));
00362 #endif
00363 }
00364
00365 #if defined(HAVE_STDARG_H) || defined(HAVE_VARARGS_H)
00366 va_end(ap);
00367 #endif
00368
00369 bu_vls_free(&output);
00370 }
00371
00372
00373
00374
00375
00376
00377 void
00378 #if defined(HAVE_STDARG_H)
00379 bu_flog(FILE *fp, char *fmt, ...)
00380 {
00381 va_list ap;
00382 #else
00383 # if defined(HAVE_VARARGS_H)
00384 bu_flog(va_alist)
00385 va_dcl
00386 {
00387 va_list ap;
00388 FILE *fp;
00389 char *fmt;
00390 # else
00391 bu_flog(fp, fmt, a,b,c,d,e,f,g,h,i,j)
00392 FILE *fp;
00393 char *fmt;
00394 {
00395 # endif
00396 #endif
00397
00398 struct bu_vls output;
00399
00400 bu_vls_init(&output);
00401
00402 #if defined(HAVE_STDARG_H)
00403 va_start(ap, fmt);
00404 if (bu_log_indent_cur_level > 0) {
00405 struct bu_vls newfmt;
00406
00407 bu_vls_init(&newfmt);
00408 bu_log_do_indent_level(&newfmt, fmt);
00409 bu_vls_vprintf(&output, bu_vls_addr(&newfmt), ap);
00410 bu_vls_free(&newfmt);
00411 } else {
00412 bu_vls_vprintf(&output, fmt, ap);
00413 }
00414 #else
00415 # if defined(HAVE_VARARGS_H)
00416 va_start(ap);
00417 fp = va_arg(ap, FILE *);
00418 fmt = va_arg(ap, char *);
00419 if (bu_log_indent_cur_level > 0) {
00420 struct bu_vls newfmt;
00421
00422 bu_vls_init(&newfmt);
00423 bu_log_do_indent_level(&newfmt, fmt);
00424 bu_vls_vprintf(&output, bu_vls_addr(&newfmt), ap);
00425 bu_vls_free(&newfmt);
00426 } else {
00427 bu_vls_vprintf(&output, fmt, ap);
00428 }
00429 # else
00430 if (bu_log_indent_cur_level > 0) {
00431 struct bu_vls newfmt;
00432
00433 bu_vls_init(&newfmt);
00434 bu_log_do_indent_level(&newfmt, fmt);
00435 bu_vls_printf(&output, bu_vls_addr(&newfmt), a,b,c,d,e,f,g,h,i,j);
00436 bu_vls_free(&newfmt);
00437 } else {
00438 bu_vls_printf(&output, fmt, a,b,c,d,e,f,g,h,i,j);
00439 }
00440 # endif
00441 #endif
00442
00443 if ( BU_LIST_IS_EMPTY( &(bu_log_hook_list.l) ) || bu_log_hooks_called) {
00444 int ret;
00445 size_t len;
00446
00447 len = bu_vls_strlen(&output);
00448 if(len){
00449 bu_semaphore_acquire(BU_SEM_SYSCALL);
00450 ret = fwrite( bu_vls_addr(&output), len, 1, fp );
00451 bu_semaphore_release(BU_SEM_SYSCALL);
00452 if( ret != 1 ) bu_bomb("bu_flog: write error");
00453 }
00454
00455 } else {
00456 #if 1
00457 bu_log_call_hooks(bu_vls_addr(&output));
00458 #else
00459 bu_call_hook(&bu_log_hook_list, (genptr_t)bu_vls_addr(&output));
00460 #endif
00461 }
00462
00463 #if defined(HAVE_STDARG_H) || defined(HAVE_VARARGS_H)
00464 va_end(ap);
00465 #endif
00466
00467 bu_vls_free(&output);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480